From: balajihands Date: Fri, 14 Jun 2019 15:55:14 +0000 (+0000) Subject: Initial commit X-Git-Tag: 1.0.1~9 X-Git-Url: https://gerrit.o-ran-sc.org/r/gitweb?a=commitdiff_plain;h=5625a52ad68f6ad93684e68bbbdbaef0d462cf9a;p=o-du%2Fl2.git Initial commit Change-Id: I79525d951a9e24d68e30ca6bc9e75562cb50df8b Signed-off-by: balajihands --- diff --git a/LICENSES.txt b/LICENSES.txt new file mode 100644 index 000000000..a9db3d030 --- /dev/null +++ b/LICENSES.txt @@ -0,0 +1,31 @@ +LICENSES.txt + + +Unless otherwise specified, all software contained herein is licensed +under the Apache License, Version 2.0 (the "Software License"); +you may not use this software except in compliance with the Software +License. You may obtain a copy of the Software License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the Software License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the Software License for the specific language governing permissions +and limitations under the Software License. + + + +Unless otherwise specified, all documentation contained herein is licensed +under the Creative Commons License, Attribution 4.0 Intl. (the +"Documentation License"); you may not use this documentation except in +compliance with the Documentation License. You may obtain a copy of the +Documentation License at + +https://creativecommons.org/licenses/by/4.0/ + +Unless required by applicable law or agreed to in writing, documentation +distributed under the Documentation License is distributed on an "AS IS" +BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the Documentation License for the specific language governing +permissions and limitations under the Documentation License. diff --git a/README b/README new file mode 100644 index 000000000..a681258e2 --- /dev/null +++ b/README @@ -0,0 +1,39 @@ +Directory Structure : + +1. 5gnr_opensource/lte_enb/build/ : contains files required to compile the code + a. common : contains individual module's makefile + b. scripts : contains scripts and final makefile used to compile all layers using makefiles in common directory + +2. 5gnr_opensource/lte_enb/src/ : contains layer specific source code + a. 5gnrpdcp : PDCP source code + b. 5gnrrlc : RLC source code + c. 5gnrmac : MAC source code + d. cm : common, environment and interface files + e. mt : wrapper functions over OS + f. rlog : logging module + + +Pre-requisite for Compilation : +1. Linux 32-bit/64-bit machine +2. GCC version 4.6.3 and above + + +How to Compile : +1. cd 5gnr_opensource/lte_enb/build/scripts/ +2. Run script to clean and compile: ./build_5gnr.sh +3. To clean only, run command : make clean_all + +Compilation Error : +Any compilation error will be reported in file : 5gnr_opensource/lte_enb/build/scripts/err + +Generated Libraries : +Path : 5gnr_opensource/lte_enb/libs/ +1. librg.a : MAC library +2. libkw.a : RLC library +3. libpj.a : PDCP library + +Generated Object Files : +Path : 5gnr_opensource/lte_enb/build/scripts/obj/ +1. rg* : Object files for MAC. The prefix 'rg' refers to MAC files and functions. +2. kw* : Object files for RLC. The prefix 'kw' refers to RLC files and functions. +3. pj* : Object files for PDCP. The prefix 'pj' refers to PDCP files and functions. diff --git a/build/common/compile.mak b/build/common/compile.mak new file mode 100644 index 000000000..de03d83c8 --- /dev/null +++ b/build/common/compile.mak @@ -0,0 +1,142 @@ +################################################################################ +# Copyright (c) [2017-2019] [Radisys] # +# # +# 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. # +################################################################################ + +#/********************************************************************16** +# +# Name: gNodeB Sample Application +# +# Type: make file +# +# Desc: Compile, assemble and link product software for +# various configurations. Further comments are +# embedded in the file. +# +# This file supports a variety of environments and +# build targets. The default build target will be the +# portable target for the Linu 2.4.x with GNU C(gcc) +# +# Env: Linux 2.4.x with GNU C (gcc) +# +# File: compile.mak +# +#********************************************************************21*/ +#======================================================================= + +STOPTS=-DENB + +Q= +S= +# Check for verbose build +ifneq ($(V),1) + Q:=@ + S:=-s +endif +export Q +export S + +#-DSSINT2 -DSS_TICKS_SEC=100 +# MTSS defines +SS_FLAGS=-DSS -DSS_MT -DSUNOS -DSS_LINUX -UCONRD -UNOFILESYS -USS_DEBG_MEM_CORRUP_LEVEL1 \ + -DSS_TICKS_SEC=100 -USSI_DEBUG_LEVEL1 -USS_LICENSE_CHECK -DANSI -D_GNU_SOURCE\ + -D_REENTRANT -D__EXTENSIONS__ -DDEBUGNOEXIT + +# Flags to be used if text logging is enabled +TEXT_LOGGING = -DRLOG_ENABLE_TEXT_LOGGING -DRLOG_DEBUG_MODE + +ifeq ($(INSTRUMENTATION), YES) +INSTRUMENTATION_FLAGS = -DSS_MEM_CORRUPTION_DETECTION +endif + +# Flags pertaining to the functionality of TeNB are included here +TENB_FLAGS=-DLTERRC_REL9 -DEGTP_U_REL_9 -UMAC_SCH_STATS -USCH_STATS \ + -DTENB_TTI_PERF -DAES -DLTE_RRC_DISSECTOR -DRSYS_WIRESHARK + +ifneq ($(PLTFRM), PAL) +TENB_FLAGS += -DIPV6_SUPPORTED +endif + +ifeq ($(RADIO_CLUSTER), YES) +TENB_FLAGS += -DRADIO_CLUSTER +endif +# Flags that define the broad level functioning of the binary +ENV_FLAGS=-DNO_ERRCLS -DNOERRCHK -DDEBUGP + +RVW_FLAGS=-DCM_PASN_DBG -DLTEMAC_MIMO -DWR_UL_PWR \ + -DREVIEW -DNL + +# Flags that can be removed when everything works. These flags are not included +# in the compilation at the moment. +DEL_FLAGS=-DSS_WL_REGION=1 -DVE_PERF_MEAS -UVE_SUPPORT_RLC_UM_MODE -ULTE_LNX_AFFINITY \ + -DKW_BG_DL_PROC -DKW_BG_UL_PROC -DWR_SB_SCTP -DPHY_ERROR_LOGGING -DWR_DETECT_RLF \ + -USS_MEM_CORRUPTION_DETECTION -DL2_LOGGING_ENABLED -DLTEMAC_DRX -UUSE_PURE \ + -DLTE_MULTIUE -DCMKV2 -DYS_ENB_CFG -DTA_NEW -DTENB_DISABLE_DL_ZBC + +ALL_FLAGS=$(SS_FLAGS) $(CMN_FLAGS) $(ENV_FLAGS) $(RVW_FLAGS) $(TENB_FLAGS) $(LNXENV) + +# compiler options: +#C_OPTS+=-g -O3 -pipe -pedantic -Wall -Werror -Wno-comment -Wshadow +C_OPTS+=-g -O3 -pipe -Wall -Wno-comment -Wshadow \ + -Wcast-qual -fno-strict-aliasing -fsigned-char --std=c99 + +COPTS_WO_PEDANTIC=-g -O3 -pipe -Wall -Werror -Wno-comment -Wshadow \ + -Wcast-qual -fno-strict-aliasing -fsigned-char --std=c99 + +COPTS_WO_WERROR=-g -O3 -pipe -pedantic -Wall -Wno-comment -Wshadow \ + -Wcast-qual -fno-strict-aliasing -fsigned-char --std=c99 + +xCPP_OPTS+=-g -pipe -pedantic -Wall -Werror -Wno-comment -Wshadow \ + -Wcast-qual -fno-strict-aliasing -fsigned-char -lstdc++ + +# Include path settings +I_OPTS+=-I$(SRC_DIR) -I$(ROOT_DIR)/src/cm -I$(ROOT_DIR)/src/mt -I$(ROOT_DIR)/src/rlog +I_OPTS+=$(PLTFRM_INCLUDES) +.SUFFIXES:.c .o + +$(C_OBJS):$(OBJ_DIR)/%.o: $(SRC_DIR)/%.c $(HDR_FILES) + @echo -e "Compiling $(COLOR_RED) $< $(REVERT_COLOR)" + $(Q)$(CC) -c -o $@ $(C_OPTS) $(I_OPTS) $(ALL_FLAGS) $(TEXT_LOGGING) $(MOD_FLAGS) \ + $(PLTFRM_FLAGS) $< + +$(C_WO_WERR_OBJS):$(OBJ_DIR)/%.o: $(SRC_DIR)/%.c $(HDR_FILES) + @echo -e "Compiling $(COLOR_RED) $< $(REVERT_COLOR)" + $(Q)$(CC) -c -o $@ $(COPTS_WO_WERROR) $(I_OPTS) $(ALL_FLAGS) $(TEXT_LOGGING) $(MOD_FLAGS) \ + $(PLTFRM_FLAGS) $< + +$(C_WO_PED_OBJS):$(OBJ_DIR)/%.o: $(SRC_DIR)/%.c $(HDR_FILES) + @echo -e "Compiling $(COLOR_RED) $< $(REVERT_COLOR)" + $(Q)$(CC) -c -o $@ $(COPTS_WO_PEDANTIC) $(I_OPTS) $(ALL_FLAGS) $(TEXT_LOGGING) $(MOD_FLAGS) \ + $(PLTFRM_FLAGS) $< + +$(CPP_OBJS):$(OBJ_DIR)/%.o: $(SRC_DIR)/%.cpp $(HDR_FILES) + @echo -e "Compiling $(COLOR_RED) $< $(REVERT_COLOR)" + $(Q)$(CC) -c -o $@ $(CPP_OPTS) $(I_OPTS) $(ALL_FLAGS) $(TEXT_LOGGING) $(MOD_FLAGS) \ + $(PLTFRM_FLAGS) $< + +$(C_OBJS_WO_LOG):$(OBJ_DIR)/%.o: $(SRC_DIR)/%.c $(HDR_FILES) + @echo -e "Compiling $(COLOR_RED) $< $(REVERT_COLOR)" + $(Q)$(CC) -c -o $@ $(C_OPTS) $(I_OPTS) $(ALL_FLAGS) $(TEXT_LOGGING) $(MOD_FLAGS) \ + $(PLTFRM_FLAGS) $< + +$(C_WO_PED_OBJS_WO_LOG):$(OBJ_DIR)/%.o: $(SRC_DIR)/%.c $(HDR_FILES) + @echo -e "Compiling $(COLOR_RED) $< $(REVERT_COLOR)" + $(Q)$(CC) -c -o $@ $(COPTS_WO_PEDANTIC) $(I_OPTS) $(ALL_FLAGS) $(TEXT_LOGGING) $(MOD_FLAGS) \ + $(PLTFRM_FLAGS) $< + +$(CPP_OBJS_WO_LOG):$(OBJ_DIR)/%.o: $(SRC_DIR)/%.cpp $(HDR_FILES) + @echo -e "Compiling $(COLOR_RED) $< $(REVERT_COLOR)" + $(Q)$(CC) -c -o $@ $(CPP_OPTS) $(I_OPTS) $(ALL_FLAGS) $(TEXT_LOGGING) $(MOD_FLAGS) \ + $(PLTFRM_FLAGS) $< + diff --git a/build/common/env.mak b/build/common/env.mak new file mode 100644 index 000000000..2af0a84db --- /dev/null +++ b/build/common/env.mak @@ -0,0 +1,80 @@ +################################################################################ +# Copyright (c) [2017-2019] [Radisys] # +# # +# 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. # +################################################################################ + +#*********************************************************************17*/ +# +# Name: gNodeB Sample Application +# +# Type: make file +# +# Desc: Compile, assemble and link product software for +# various configurations. Further comments are +# embedded in the file. +# +# This file supports a variety of environments and +# build targets. The default build target will be the +# portable target for the Linu 2.4.x with GNU C(gcc) +# +# Env: Linux 2.4.x with GNU C (gcc) +# +# File: env.mak +# +#********************************************************************21*/ +#======================================================================= + +STOPTS=-DENB + +Q= +S= +# Check for verbose build +ifneq ($(V),1) + Q:=@ + S:=-s +endif +export Q +export S + +# With the assumption that the make command is run from the directory +# where the makefile is located, PWD fetches the build directory and +# all other directories are generated using the build directory. +BUILD_DIR=$(PWD) +ROOT_DIR_SCRIPTS =$(patsubst %/build/scripts,%,$(BUILD_DIR)) +COM_BUILD_DIR=$(BUILD_DIR)/../common +export BUILD_DIR +export COM_BUILD_DIR + +# Path where the .o files or the directories with .o files are located +OBJ_ROOT =$(BUILD_DIR)/obj +export OBJ_ROOT +# Path where the binary logging related files are generated +LOG_ROOT =$(BUILD_DIR)/logdb +export LOG_ROOT +# Path where the libraries are created +LIB_ROOT =$(BUILD_DIR)/lib +export LIB_ROOT +# Path for the common files that are used across multiple layers +CM_DIR =$(ROOT_DIR)/src/cm +export CM_DIR +# Path where the final binaries are created +BIN_DIR =$(BUILD_DIR)/build/obj +export BIN_DIR +# Path where the libraries are packaged and these are used when not built from source +EXT_LIB_DIR =$(ROOT_DIR)/lib +export EXT_LIB_DIR + +CMENBE2EOPTS += $(RLOG_OPTS_TEXT) + +L_OPTS = -lrt -lm -lpthread -lpcap -lstdc++ -L $(LIB_ROOT) diff --git a/build/common/kw.mak b/build/common/kw.mak new file mode 100644 index 000000000..23207337a --- /dev/null +++ b/build/common/kw.mak @@ -0,0 +1,54 @@ +################################################################################ +# Copyright (c) [2017-2019] [Radisys] # +# # +# 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. # +################################################################################ + +##-------------------------------------------------------------# +##Makefile for product ib - script generated. +#Only the $(CCib) may be modified. +#-------------------------------------------------------------# +include ../common/rsys_fancy.mak +include ../common/env.mak + +SRC_DIR=$(ROOT_DIR)/src/5gnrrlc + +#Prepare source file list +C_SRCS=$(wildcard $(SRC_DIR)/*.c) + +#prepare the list of object files and RLOG related files +C_OBJS=$(patsubst $(SRC_DIR)/%.c,$(OBJ_DIR)/%.o,$(C_SRCS)) + +#-------------------------------------------------------------# +#User macros (to be modified) +#-------------------------------------------------------------# +MOD_FLAGS=-DRG -DYS -DKW -DPX -DLCRGU -DLCKWULUDX -DLCUDX -DLWLCKWULUDX + +#-------------------------------------------------------------# +#Linker macros +#-------------------------------------------------------------# + +lib: $(LIB_DIR)/libkw.a +include $(COM_BUILD_DIR)/compile.mak + +$(LIB_DIR)/libkw.a:$(C_OBJS) + @echo -e "Creating Archive $(COLOR) $@ $(REVERT_COLOR)" + $(Q)ar -cr $(LIB_DIR)/libkw.a $(C_OBJS) + +#-------------------------------------------------------------# +#Clean macros +#-------------------------------------------------------------# +clean: + @echo -e "$(COLOR_RED)Cleaning RLC$(REVERT_COLOR)" + $(Q)\rm -f $(LIB_DIR)/libkw.a $(C_OBJS) + diff --git a/build/common/pj.mak b/build/common/pj.mak new file mode 100644 index 000000000..7b8767c9e --- /dev/null +++ b/build/common/pj.mak @@ -0,0 +1,73 @@ +################################################################################ +# Copyright (c) [2017-2019] [Radisys] # +# # +# 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. # +################################################################################ + +#-------------------------------------------------------------# +#Makefile for product ib - script generated. +#Only the $(CCib) may be modified. +#-------------------------------------------------------------# + +include ../common/rsys_fancy.mak + +include ../common/env.mak + +SEC_ENG=SWLIB + +SRC_DIR=$(ROOT_DIR)/src/5gnrpdcp + +#Prepare source file list +C_SRCS=$(wildcard $(SRC_DIR)/*.c) + +#prepare the list of object files and RLOG related files +C_OBJS=$(patsubst $(SRC_DIR)/%.c,$(OBJ_DIR)/%.o,$(C_SRCS)) + +#prepare the header file list for this layer +# prepare the list of common header files +HDR_FILES+=$(wildcard $(CM_DIR)/env*.[hx]) +HDR_FILES+=$(wildcard $(CM_DIR)/gen*.[hx]) +HDR_FILES+=$(wildcard $(CM_DIR)/ssi*.[hx]) +HDR_FILES+=$(wildcard $(CM_DIR)/cm*.[hx]) +HDR_FILES+=$(wildcard $(CM_DIR)/lpj.[hx]) +HDR_FILES+=$(wildcard $(CM_DIR)/kwu.[hx]) +HDR_FILES+=$(wildcard $(CM_DIR)/pju.[hx]) +HDR_FILES+=$(wildcard $(CM_DIR)/cpj.[hx]) + +# Add the product specific header files +HDR_FILES+= $(wildcard $(SRC_DIR)/*.[hx]) + +#-------------------------------------------------------------# +#User macros (to be modified) +#-------------------------------------------------------------# +MOD_FLAGS= -UKW_PDCP -DKW -DPJ -DPTPJLIB + + +lib:$(LIB_DIR)/libpj.a +include $(COM_BUILD_DIR)/compile.mak + +#-------------------------------------------------------------# +#Linker macros +#-------------------------------------------------------------# +$(LIB_DIR)/libpj.a:$(C_OBJS) $(C_WO_WERR_OBJS) + @echo -e "Creating Archive $(COLOR) $@ $(REVERT_COLOR)" + $(Q)ar -cr $(LIB_DIR)/libpj.a $(C_OBJS) $(C_WO_WERR_OBJS) + +#-------------------------------------------------------------# +#Clean macros +#-------------------------------------------------------------# +clean: + @echo -e "$(COLOR_RED)Cleaning PDCP$(REVERT_COLOR)" + $(Q)\rm -f $(LIB_DIR)/libpj.a $(C_OBJS) $(C_WO_WERR_OBJS) + + diff --git a/build/common/rg.mak b/build/common/rg.mak new file mode 100644 index 000000000..6b8fac2a3 --- /dev/null +++ b/build/common/rg.mak @@ -0,0 +1,70 @@ +################################################################################ +# Copyright (c) [2017-2019] [Radisys] # +# # +# 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. # +################################################################################ + +##-------------------------------------------------------------# +#Makefile for product RG - script generated. +#-------------------------------------------------------------# +include ../common/rsys_fancy.mak +include ../common/env.mak +COLOR=$(COLOR_GREEN) + +SRC_DIR=$(ROOT_DIR)/src/5gnrmac + +# prepare the list of common header files +HDR_FILES+=$(wildcard $(CM_DIR)/env*.[hx]) +HDR_FILES+=$(wildcard $(CM_DIR)/gen*.[hx]) +HDR_FILES+=$(wildcard $(CM_DIR)/ssi*.[hx]) +HDR_FILES+=$(wildcard $(CM_DIR)/cm*.[hx]) +HDR_FILES+=$(wildcard $(CM_DIR)/crg.[hx]) +HDR_FILES+=$(wildcard $(CM_DIR)/lrg*.[hx]) +HDR_FILES+=$(wildcard $(CM_DIR)/rgr.[hx]) +HDR_FILES+=$(wildcard $(CM_DIR)/rgm.[hx]) + +# Add the product specific header files +HDR_FILES+= $(wildcard $(SRC_DIR)/*.[hx]) + +#prepare the list of source files +C_SRCS=$(wildcard $(SRC_DIR)/*.c) + +#prepare the list of object files and RLOG related files +C_OBJS=$(patsubst $(SRC_DIR)/%.c,$(OBJ_DIR)/%.o,$(C_SRCS)) + +#-------------------------------------------------------------# +#User macros (to be modified) +#-------------------------------------------------------------# +# Including RG_PHASE2_SCHED for supporting more than one schedulers +# supported by mac +# TODO: make it define for LTEMAC_MIMO and remove it from envopt.h +MOD_FLAGS=-DRGM_LC -DRGM_LWLC -USM -DTF -URG_DEBUG -DxRG_PHASE2_SCHED -DxRGR_V1 \ + -DRG_UL_DELTA=2 -ULTEMAC_DLUE_TMGOPTMZ -UTENB_SPLIT_ARCH -DRG -ULTEMAC_MIMO + +lib:$(LIB_DIR)/librg.a +include $(COM_BUILD_DIR)/compile.mak + +#-------------------------------------------------------------# +#Linker macros +#-------------------------------------------------------------# +$(LIB_DIR)/librg.a:$(C_OBJS) + @echo -e "Creating Archive $(COLOR) $@ $(REVERT_COLOR)" + $(Q)ar -cr $(LIB_DIR)/librg.a $(C_OBJS) + +#-------------------------------------------------------------# +#Clean macros +#-------------------------------------------------------------# +clean: + @echo -e "$(COLOR_RED)Cleaing MAC$(REVERT_COLOR)" + $(Q)\rm -f $(LIB_DIR)/librg.a $(C_OBJS) + diff --git a/build/common/rsys_fancy.mak b/build/common/rsys_fancy.mak new file mode 100644 index 000000000..8eb3a835c --- /dev/null +++ b/build/common/rsys_fancy.mak @@ -0,0 +1,49 @@ +################################################################################ +# Copyright (c) [2017-2019] [Radisys] # +# # +# 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. # +################################################################################ + +#********************************************************************20** +# +# Name: RSYS FANCY MAKE OUTOUT +# +# Type: Makefile +# +# Desc: To control fancy features in the build process +# +# +# File: rsys_fancy.mak +# +#********************************************************************21*/ + +#----------------------------------------------------------------------- +# FANCY STUFF... you can play around with this if you want to +COLOR_RED=\e[31m\e[1m +COLOR_GREEN=\e[32m\e[1m +COLOR_YELLOW=\e[33m\e[1m +COLOR_BLUE=\e[34m\e[1m +COLOR_MAG=\e[35m\e[1m +COLOR_CYAN=\e[36m\e[1m +REVERT_COLOR=\e[m + +#----------------------------------------------------------------------- +# DO NOT EDIT THIS SECTION +ifeq ($(VERBOSE),YES) +export QUIET= +MK_QUIET= +else +export QUIET=@ +MK_QUIET=-s # Make works in quite mode +endif + diff --git a/build/scripts/build_5gnr.sh b/build/scripts/build_5gnr.sh new file mode 100755 index 000000000..86197f7c3 --- /dev/null +++ b/build/scripts/build_5gnr.sh @@ -0,0 +1,19 @@ +################################################################################ +# Copyright (c) [2017-2019] [Radisys] # +# # +# 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. # +################################################################################ + +make clean_all +bash ./build_prereq -m FDD +make tenb MACHINE=BIT64 -j 12 2>err diff --git a/build/scripts/build_prereq b/build/scripts/build_prereq new file mode 100755 index 000000000..f266ab0f5 --- /dev/null +++ b/build/scripts/build_prereq @@ -0,0 +1,78 @@ +################################################################################ +# Copyright (c) [2017-2019] [Radisys] # +# # +# 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. # +################################################################################ + +#! /bin/sh + +function printUsageAndExit(){ + echo "Usage: $0 -m (TDD | FDD) " + echo "" + echo "Mandatory arguments" + echo "===================" + echo " -m, --mode (TDD | FDD) Mode has to be either TDD or FDD" + echo "Optional arguments" + echo "===================" + echo " Desitnation directory where compilation will be done" + echo " or Package or EVAL yes" + echo "" + exit 1; +} + +DIR=$PWD/../.. +MODE= +TARGET_DIRS_FOUND=0 +PKG="NO" +OLD_MODE="TDD" + +while [ "$1" != "" ]; do + case $1 in + -m | --mode ) shift + MODE=$1 + ;; + -PKG ) PKG="YES" + ;; + -h | --help ) printUsageAndExit + ;; + * ) DIR=$1 + TARGET_DIRS_FOUND=`expr $TARGET_DIRS_FOUND + 1` + esac +shift +done + +if [ "$MODE" != "FDD" ] && [ "$MODE" != "TDD" ] +then + echo "Invalid mode specified $MODE" + printUsageAndExit +fi + +SRC_PATH=$DIR/src +BIN_PATH=$DIR/bin + +echo $PWD $SRC_PATH $BIN_PATH + +#******************************************* Implemented Local Build Functionalities ****************************************** +BLD_PATH=$SRC_PATH/../build/ +BuildFileResult=$BLD_PATH/targetbuild.txt +rm -f $BuildFileResult +echo $MODE > $BuildFileResult +#******************************************************************************************************************************* + +#Remvoing unwanted files from the package +find $SRC_PATH -name "*.tmp" -exec rm -f {} \; +find $SRC_PATH -name "*.keep" -exec rm -f {} \; +find $SRC_PATH -name "*.contrib" -exec rm -f {} \; +find $SRC_PATH -name "*.contrib.1" -exec rm -f {} \; +find $SRC_PATH -name "*.contrib.2" -exec rm -f {} \; + diff --git a/build/scripts/makefile b/build/scripts/makefile new file mode 100755 index 000000000..4b276a801 --- /dev/null +++ b/build/scripts/makefile @@ -0,0 +1,185 @@ +################################################################################ +# Copyright (c) [2017-2019] [Radisys] # +# # +# 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. # +################################################################################ + +#********************************************************************20** +# +# Name: gNodeB Sample Application +# +# Type: make file +# +# Desc: Compile, assemble and link product software for +# various configurations. Further comments are +# embedded in the file. +# +# This file supports a variety of environments and +# build targets. The default build target will be the +# portable target for the Linu 2.4.x with GNU C(gcc) +# +# Env: Linux 2.4.x with GNU C (gcc) +# +# BUILD TARGETS: +# +# clean remove all object files +# +# File: makefile +# +#********************************************************************21*/ +#======================================================================= + +# Identify the location our software which is used by rest +# of the build scripts +include ../common/rsys_fancy.mak +include ../common/env.mak + +RULE=$(COLOR_RED) +OPTS=$(COLOR_GREEN) +NORM=$(REVERT_COLOR) + +ROOT_DIR=$(ROOT_DIR_SCRIPTS) +export ROOT_DIR + +# For improved speed +CPUINFO=`cat /proc/cpuinfo | grep processor| wc -l` +ifeq ($(CPUINFO), 1) + NUM_PARALLEL=1 +else + NUM_PARALLEL=$(shell echo $(CPUINFO) - 1 |bc) +endif + +ifeq ($(FAST), 1) + NUM_PARALLEL=$(shell echo $(CPUINFO) + 2 |bc) +endif + +PARALLEL_COMP=-j $(NUM_PARALLEL) +#PARALLEL_COMP=-j 1 + +# Different options to CPUH and CPUL builds +# Other apsects of tool chain set here +# These should be made available appropriately to the builds + +ifeq ($(MACHINE),BIT64) +CC =gcc -m64 +CC_STRIP =strip --strip-all +CC_LINKER =gcc -m64 +CCPP =g++ -m64 +CCPP_LINKER =g++ -m64 +else +CC =gcc -m32 +CC_STRIP =strip --strip-all +CC_LINKER =gcc -m32 +CCPP =g++ -m32 +CCPP_LINKER =g++ -m32 +endif + +CC1= $(CC) +CCPP1= $(CCPP) + +ifeq ($(MODE),TDD) +CNM_ENABLE = YES +else +CNM_ENABLE=NO +endif + +#----------------------------------------------------------------------- +# macro for output file name and makefile name +# +prepare_dirs: + $(Q)echo -e "Preparing directories for build..." + $(Q)mkdir -p $(BUILD_DIR)/obj + $(Q)mkdir -p $(LOG_ROOT) + $(Q)mkdir -p $(LIB_ROOT) + $(Q)echo -e "Directories are successfully prepared" + + +ifeq ($(CNM_ENABLE),YES) +CNM_OPT = -DxENABLE_CNM -DREM_ENABLE -DCNM_DEBUG +else +CNM_OPT = -UENABLE_CNM -UREM_ENABLE +endif + + PLTFRM_FLAGS= -UMSPD $(CNM_OPT) + +ifeq ($(MODE),TDD) + PLTFRM_FLAGS += -DMODE=TDD +endif +CA_ENABLE=YES +ifeq ($(CA_ENABLE),YES) + PLTFRM_FLAGS += -DCA_ENABLE=YES +endif + +# The include options get merged with the options needed by +# the called makefiles and hence we export these to make them +# available to them. +PLTFRM=PAL +BUILD=i686-linux + + +# The called makefiles depend on these macros and these need to be exported +export PLTFRM +export PLTFRM_FLAGS +export BUILD +export I_OPTS + +# Add to the linker options the platform specific components +L_OPTS+=-lnsl -lrt -lm -lpthread + + +# Export some of the flags expected from the command line. +# These macros are made available for the makefiles called from this makefile +export MACHINE +export MODE +export CNM_ENABLE +export CA_ENABLE + +################################################################################################### +# TeNB Compilation Options - Help Menu +################################################################################################### +help: + @echo -e "******************************************************************" + @echo -e "BUILD COMMAND DESCRIPTION " + @echo -e "------------------------------------------------------------------" + @echo -e "$(RULE)tenb - Builds all components of TeNB$(NORM)" + @echo -e "$(OPTS) options: $(NORM)" + @echo -e "$(OPTS) MACHINE=BIT64/BIT32 - Default is BIT32$(NORM)" + @echo -e "$(OPTS) MODE=TDD - If not specified, MODE=FDD$(NORM)" + @echo -e "$(RULE)clean_all tdd cleanup everything$(NORM)" + @echo -e "******************************************************************" + + +enb: + $(Q)$(MAKE) -f $(COM_BUILD_DIR)/kw.mak OBJ_DIR=$(OBJ_ROOT) LIB_DIR=$(LIB_ROOT) LOG_DIR=$(LOG_ROOT) CC='$(CC1)' + $(Q)$(MAKE) -f $(COM_BUILD_DIR)/pj.mak OBJ_DIR=$(OBJ_ROOT) LIB_DIR=$(LIB_ROOT) LOG_DIR=$(LOG_ROOT) CC='$(CC1)' + $(Q)$(MAKE) -f $(COM_BUILD_DIR)/rg.mak OBJ_DIR=$(OBJ_ROOT) LIB_DIR=$(LIB_ROOT) LOG_DIR=$(LOG_ROOT) CC='$(CC1)' + +clean_all: + $(Q)$(MAKE) -f $(COM_BUILD_DIR)/rg.mak clean OBJ_DIR=$(OBJ_ROOT) LIB_DIR=$(LIB_ROOT) LOG_DIR=$(LOG_ROOT) CC='$(CC2)' + $(Q)$(MAKE) -f $(COM_BUILD_DIR)/kw.mak clean OBJ_DIR=$(OBJ_ROOT) LIB_DIR=$(LIB_ROOT) LOG_DIR=$(LOG_ROOT) CC='$(CC2)' + $(Q)$(MAKE) -f $(COM_BUILD_DIR)/pj.mak clean OBJ_DIR=$(OBJ_ROOT) LIB_DIR=$(LIB_ROOT) LOG_DIR=$(LOG_ROOT) CC='$(CC2)' + + +################################################################################################### +# TeNB Compilation +################################################################################################### + +tenb: prepare_dirs copy_build + +copy_build: enb + $(Q)mkdir -p $(ROOT_DIR)/libs/ + $(Q)cp -f ./lib/*.a $(ROOT_DIR)/libs/ + +################################################################################################### +# END OF MAKEFILE +################################################################################################### diff --git a/src/5gnrmac/rg.h b/src/5gnrmac/rg.h new file mode 100755 index 000000000..6850884f4 --- /dev/null +++ b/src/5gnrmac/rg.h @@ -0,0 +1,762 @@ +/******************************************************************************* +################################################################################ +# Copyright (c) [2017-2019] [Radisys] # +# # +# 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. # +################################################################################ +*******************************************************************************/ + +/********************************************************************** + + Name: MAC layer + + Type: H include file + + Desc: Defines required by LTE-MAC + + File: rg.h + +**********************************************************************/ + +/** @file rg.h +@brief This file contains definitons for Mac. +*/ + + +#ifndef __RGH__ +#define __RGH__ + +#include "rl_interface.h" +#include "rl_common.h" + + +#ifdef L2_OPTMZ +#include "gen.x" /* general layer */ +#include "ssi.x" /* system service interface */ +#include "ss_strm.h" +#include "ss_strm.x" +#include "ss_queue.h" +#include "ss_queue.x" +#include "ss_task.x" +#include "ss_msg.x" + +#define RG_MAC_HDR_SIZE 250 +#define RG_MAC_CE_SIZE 250 +U32 MacPtrAddress; +U32 macHeader[2]; + +#define RG_ADD_DBuf(_dBuf,_size,_mBuf)\ +{ \ + SsMsgInfo *mInfo = NULLP; \ + mInfo = (SsMsgInfo *)_mBuf->b_rptr; \ + ssGetDBufOfSize(mInfo->region,_size, &_dBuf); \ + SUpdMsg(_mBuf, _dBuf,0);\ + _dBuf->b_wptr = _dBuf->b_rptr = (_dBuf->b_datap->db_base + 5);\ + MacPtrAddress = (U32)_dBuf->b_wptr;\ +} +#endif + + + +#define RGLAYERNAME "MAC" +#define RG_MAX_TB_PER_UE 2 +#define RG_MAX_BCCH_DLSCH 2 +#define RG_INVALID_RNTI 0x0000 + +#define RG_MAX_NUM_DED_LC 10 /* maximum dedicated logical channels in a UE */ +#define RG_MAX_NUM_CMN_LC 5 /* maximum number of common logical + channels in a cell */ +#define RG_MAX_LCG_PER_UE 4 +#define RG_CON_RES_ID_SZ 6 +#define RG_MAX_RA_RNTI 60 + +/* Added support for SPS*/ +#ifdef LTEMAC_SPS +#define RG_ADDL_SPS_OCC_FOR_EXP_REL 2 + +#define RG_SPS_SID_PACKET_SIZE 10 +#define RG_SPS_LCG_ID 1 + +#endif + +/* Well known RNTIS */ +#define RG_SI_RNTI 0xffff +#define RG_P_RNTI 0xfffe + +#define RG_MAX_UPPERSAP 3 +#define RG_MAX_LOWERSAP 1 +#define RG_TQ_SIZE 10 /* Timing Queue Size */ +#define RG_MAX_TIMER RG_MAX_LOWERSAP /* MAX number of MAC timers */ +#define RG_NMB_CELL_HASHBIN 10 /* Number of Hash Bins for cell hash + table */ +#define RG_NMB_UE_HASHBIN 10 /* Number of Hash Bins for UE hash + table */ +#define RG_BNDREQ_TMR 1 /* Bind Request timer event value */ +#define RG_MAX_BNDRETRY 2 /* Max number of Bind Retries for TFU SAP */ + + +#define RG_UE_TQ_SIZE 10 /* Timing Queue Size */ + +#define RG_INVALID_SCHD_TYPE 255 +#define RG_MAX_UE_PER_CELL 0xFFFF /*!< Maximum number of UEs per cell */ +#ifdef EIGHT_UE_PER_TTI_CHANGES +#define RG_MAX_UE_BIN_PER_CELL 1024 /*!< Maximum number of UE bins per cell */ +#else +#define RG_MAX_UE_BIN_PER_CELL 128 /*!< Maximum number of UE bins per cell */ +#endif +#define RG_MIN_DL_BW 6 /*!< Minimum Downlink bandwidth in RBs */ +#define RG_MAX_DL_BW 110 /*!< Maximum Downlink bandwidth in RBs */ +#define RG_MIN_UL_BW 6 /*!< Minimum Uplink bandwidth in RBs */ +#define RG_MAX_UL_BW 110 /*!< Maximum Uplink bandwidth in RBs */ +#define RG_MIN_CFI_VAL 1 /*!< Minimum value for CFI */ +#define RG_MAX_CFI_VAL 3 /*!< Maximum value for CFI */ +#define RG_QM_BPSK 2 /*!< Qm value for BPSK */ +#define RG_QM_QPSK 4 /*!< Qm value for QPSK */ +#define RG_QM_64QAM 6 /*!< Qm value for 64QAM */ +#define RG_MIN_SRS_SFCFG_IDX 0 /*!< Minimum value for SRS subframe + configurtion index */ +#define RG_MAX_SRS_SFCFG_IDX 15 /*!< Maximum value for SRS subframe + configurtion index */ +#define RG_MAX_SRS_TX_OFFSET 8 /*!< Maximum number of SRS transmission + offsets per cell */ +#define RG_MIN_MAC_RNTI 10 /*!< Minimum value of RNTI to be managed by + MAC */ + +/* HARQ related MACROs */ +#define RG_NUM_DL_HQ_PROC 8 +#define RG_NUM_UL_HQ_PROC 8 +#define RG_MIN_HQ_TX 1 + +/* Group power related MACROs */ +#define RG_MAX_GRP_PWR_FMT3_IDX 15 /*!< Maximum index value for group power format 3 */ +#define RG_MAX_GRP_PWR_FMT3A_IDX 31 /*!< Maximum index value for group power format 3A */ + +/* MACROs to indicate cell specific config for cell to be active */ +#define RG_BCCH_BCH_CFG_DONE (1<<0) +#define RG_BCCH_DLSCH_CFG1_DONE (1<<1) +#define RG_BCCH_DLSCH_CFG2_DONE (1<<2) +#define RG_PCCH_CFG_DONE (1<<3) +#define RG_UL_CCCH_CFG_DONE (1<<4) +#define RG_DL_CCCH_CFG_DONE (1<<5) +#define RG_SCHD_CFG_DONE (1<<6) +#define RG_CELL_ACTIVE (RG_BCCH_BCH_CFG_DONE | RG_BCCH_DLSCH_CFG1_DONE | RG_BCCH_DLSCH_CFG2_DONE | RG_PCCH_CFG_DONE | RG_UL_CCCH_CFG_DONE | RG_DL_CCCH_CFG_DONE) +/* Logical channel realated MACROs */ +#define RG_INVALID_LCG_ID 255 +#define RG_INVALID_LC_ID 255 +#define RG_BCCH_BCH_IDX 0 +#define RG_BCCH_DLSCH_IDX 1 +#define RG_PCCH_IDX 2 + +/* constants for MIN & MAX qci*/ +#define RG_QCI_MIN 1 +#define RG_QCI_MAX 9 + +/* PUCCH related macros */ +#define RG_PUCCH_MAXVAL_CS 7 /*!< Maximum value for cyclic shift of PUCCH */ +#define RG_PUCCH_MINVAL_DS 1 /*!< Mininmum value for delta shift of PUCCH */ +#define RG_PUCCH_MAXVAL_DS 3 /*!< Maximum value for delta shift of PUCCH */ + +/* DUX related macros */ +#define RG_LCID_MASK 0x3F + +#define RG_LCID_LEN 0x6 +#define RG_CCCH_LCID 0x00 +#define RG_DEDLC_MIN_LCID 0x01 +#define RG_DEDLC_MAX_LCID 0x0A +#define RG_RES_MIN_LCID 0x0B +#define RG_RES_MAX_LCID 0x18 +#define RG_EXT_PHR_LCID 0x19 +#define RG_PHR_LCID 0x1A +#define RG_CRNTI_LCID 0X1B +#define RG_TRUNC_BSR_LCID 0X1C +#define RG_SHORT_BSR_LCID 0X1D +#define RG_LONG_BSR_LCID 0X1E +#define RG_PAD_LCID 0x3F +#define RG_MAX_EXTN_PAD_SUBHDRS 0x02 +#define RG_REF_PCMAX 0xFF + +#define RG_CCCH_SDU_PRSNT (1<<0) +#define RG_CRNTI_CE_PRSNT (1<<1) +#define RG_PHR_CE_PRSNT (1<<2) +#define RG_TRUNC_BSR_CE_PRSNT (1<<3) +#define RG_SHORT_BSR_CE_PRSNT (1<<4) +#define RG_LONG_BSR_CE_PRSNT (1<<5) +/* L2_COUNTERS */ +#define RG_ACTIVE_LC_PRSNT (1<<6) + +#ifdef LTEMAC_SPS +#define RG_UL_SPS_ACT_PRSNT (1<<7) +#endif +#define RG_EXT_PHR_CE_PRSNT (1<<8) + +/* LOGICAL CHANNEL */ +#define RG_MAX_LC_PER_UE 10 +/* Maximum number of common logical channel control blocks */ +#define RG_MAX_CMN_LC_CB 3 +#define RG_MAX_BCCH 2 + +#ifdef LTE_ADV +#define RG_MAX_SCELL_PER_UE 7 /*!< MAX SCell can be Added per Cell */ +#endif /* LTE_ADV */ + +#define RG_OPTM_NUM_DED_LC 3 + +/* Random access related MACROs */ +#define RG_MAX_RA_PREAMBLE_FMT 3 /*!< Maximun value of Random access preamble + format */ +#define RG_MAX_RA_WINSIZE 10 /*!< Maximum size of Random access response + window in subframes */ +#define RG_MIN_RA_WINSIZE 2 /*!< Minimum size of Random access response + window in subframes */ +#define RG_MIN_NUM_RA_PREAMBLE 4 /*!< Minimum number of Random access + preambles */ +#define RG_MAX_NUM_RA_PREAMBLE 64 /*!< Maximim number of Random access + preambles */ +#define RG_NUM_RA_RB 6 + +#define RG_MAX_RA_RSP_ALLOC 4 /*!< Maximum number of Random access + allocations */ +#define RG_CRG_CFG 1 /* CRG configuration element */ +#define RG_RGR_CFG 2 /* RGR configuration element */ + +#define RG_NUM_ITBS 27 +#define RG_MAX_NUM_RB 110 + +#define RG_MAX_NUM_PAD_HDRS 2 + +/* Changes for MIMO feature addition */ +/* Removed dependency on MIMO compile-time flag */ +#define RG_MAX_LYR_PERCW 2 + +#ifdef LTE_TDD +#define RG_MAX_DL_HARQ_NUM 15 +#else +#define RG_MAX_DL_HARQ_NUM 8 +#endif + +#define RG_LCG_ISCFGD(lcg) ((lcg)->lcgId != RG_INVALID_LCG_ID) +/* Corrected the check for dlCcchId */ +#define RG_DLCCCH_ISCFGD(cell) ((cell)->dlCcchId != RG_INVALID_LC_ID) +#define RG_ULCCCH_ISCFGD(cell) ((cell)->ulCcchId != RG_INVALID_LC_ID) +/* After merging from 2.1 to 2.2 */ +#define RG_CALC_SF_DIFF(_time1, _time2)\ + (_time1.sfn*RG_NUM_SUB_FRAMES_5G+_time1.subframe) < (_time2.sfn*RG_NUM_SUB_FRAMES_5G+_time2.subframe)?\ + ((_time1.sfn+RG_MAX_SFN)*RG_NUM_SUB_FRAMES_5G+_time1.subframe) -\ + (_time2.sfn*RG_NUM_SUB_FRAMES_5G+_time2.subframe) : \ + (_time1.sfn*RG_NUM_SUB_FRAMES_5G+_time1.subframe) - (_time2.sfn*RG_NUM_SUB_FRAMES_5G+_time2.subframe) +/*LTE_L2_MEAS_PHASE2*/ +#define RG_CALC_SFN_SF_DIFF(_time1,_sfnCycle, _time2)\ +(((_time1.sfn+RG_MAX_SFN * _sfnCycle)*RG_NUM_SUB_FRAMES_5G) + _time1.subframe -\ +(_time2.sfn*RG_NUM_SUB_FRAMES_5G + _time2.subframe)) + +#define RG_EXT_LCID(_lcId, _byte) {\ + (_lcId) = (_byte) & RG_LCID_MASK; \ +} +#define RG_EXT_FORMT_BIT(_fmtBit, _byte) {\ + (_fmtBit) = ((_byte) >> RG_LCID_LEN) & 0x01; \ +} + +#define RG_EXT_EXTN_BIT(_extnBit, _byte) {\ + (_extnBit) = ((_byte) >> RG_LCID_LEN) & 0x01; \ +} + +#ifndef MS_MBUF_CORRUPTION +#define MS_BUF_ADD_ALLOC_CALLER() +#endif + +#define RG_PACK_PAD(_padBuf,_size,_sduBuf) { \ + Buffer *sduEnd = NULLP; \ + SsMsgInfo *mInfo = NULLP; \ + mInfo = (SsMsgInfo *)_sduBuf->b_rptr; \ + ssGetDBufOfSize(mInfo->region,_size, &_padBuf); \ + if (_padBuf == NULLP) \ + { \ + RLOG0(L_ERROR, "RGERR_MUX_BLD_CEHDR_FAIL");\ + RETVALUE(RFAILED);\ + } \ + if (mInfo->endptr == NULLP) { \ + sduEnd = _sduBuf; \ + }\ + else \ + { \ + sduEnd = mInfo->endptr; \ + } \ + sduEnd->b_cont = _padBuf; \ + padBuf->b_wptr += _size; \ + mInfo = (SsMsgInfo *)_sduBuf->b_rptr; \ + mInfo->endptr = _padBuf; \ + mInfo->len += _size; \ +} + +#define RG_PACK_SDU(_sdusBuf, _sduBuf, _ret) {\ + _ret = SCatMsg(_sdusBuf, _sduBuf, M1M2);\ +} + +#define RG_PACK_LAST_SDU_SHDR(_subHdr, _lcId, _mBuf, _ret) {\ + _ret = ROK;\ + _subHdr.shLen = 1;\ + _subHdr.shData[0] = (0x1F & _lcId);\ + MS_BUF_ADD_ALLOC_CALLER(); \ + _ret = SAddPstMsgMult(&_subHdr.shData[0], _subHdr.shLen, _mBuf);\ +} + +#define RGADDTOCRNTTIME(crntTime, toFill, incr) \ + if ((crntTime.subframe + incr) > (RG_NUM_SUB_FRAMES_5G - 1)) \ + toFill.sfn = (crntTime.sfn + 1); \ + else \ + toFill.sfn = crntTime.sfn; \ + toFill.subframe = (crntTime.subframe + incr) % RG_NUM_SUB_FRAMES_5G; \ + if (toFill.sfn >= RG_MAX_SFN) \ + { \ + toFill.hSfn = (crntTime.hSfn + 1)%RG_MAX_SFN; \ + toFill.sfn%=RG_MAX_SFN; \ + } \ + else \ + { \ + toFill.hSfn = crntTime.hSfn; \ + } + +#define RGSUBFRMCRNTTIME(crntTime, toFill, dcr) \ +{ \ + if (crntTime.sfn == 0) \ +{ \ + if ((crntTime.subframe - (dcr)) < 0) \ + { \ + toFill.sfn = RG_MAX_SFN - 1; \ + } \ + else \ + { \ + toFill.sfn = crntTime.sfn; \ + } \ +} \ +else \ +{ \ + if ((crntTime.subframe - (dcr)) < 0) \ + { \ + toFill.sfn = crntTime.sfn - 1; \ + } \ + else \ + toFill.sfn = crntTime.sfn; \ +} \ +toFill.subframe = (RG_NUM_SUB_FRAMES_5G + crntTime.subframe - (dcr)) % (RG_NUM_SUB_FRAMES_5G); \ +} + +#define RGCPYTIMEINFO(src, dst) \ + dst.hSfn = src.hSfn; \ + dst.sfn = src.sfn; \ + dst.subframe = src.subframe; +#define RG_TIMEINFO_SAME(x, y) ((x.sfn == y.sfn) && (x.subframe == y.subframe)) + + +#define rgPBuf(_inst) rgCb[_inst].rgInit.prntBuf + +/* Debug Prints for MAC */ +#ifdef DEBUGP +#define RGDBGERRNEW(_inst,_args) \ + DBGP(&rgCb[_inst].rgInit, RGLAYERNAME, DBGMASK_ERR, _args) +#define RGDBGINFONEW(_inst,_args) \ + DBGP(&rgCb[_inst].rgInit, RGLAYERNAME, DBGMASK_INFO, _args) +#else +#define RGDBGERRNEW(_inst,_args) +#define RGDBGINFONEW(_inst,_args) +#endif /* #ifdef DEBUGP */ +#define RGDBGPRM(_inst,_args) +#define RGDBGERR(_inst,_args) +#define RGDBGINFO(_inst,_args) + +#ifdef ERRCLS_KW +#define RG_NULL_CHECK(_inst, _ptr ) \ + if((_ptr) == NULLP) \ + { \ + RGDBGERRNEW(_inst, (rgPBuf(_inst),"Null Pointer detected"));\ + SExit();\ + } +#define RG_ARRAY_BOUND_CHECK(_inst, _array, _idxVal) \ + if((_idxVal) >= (sizeof(_array)/sizeof(_array[0]))) \ + { \ + RGDBGERRNEW(_inst, (rgPBuf(_inst),"Array Bound Check Failed"));\ + SExit();\ + } +#else +#define RG_NULL_CHECK(_inst, _ptr ) +#define RG_ARRAY_BOUND_CHECK(_inst, _array, _idxVal) +#endif + +/* Macro to free the message buffer and initialize it to zero */ +/*********************************************************** + * + * Name : RG_FREE_MSG + * + * Desc : Macro to free the message buffer and initialize it to zero + * + * Input : mBuf - message buffer pointer to be retunrned + * + * Output : None. + * + * Notes: None + * + **********************************************************/ +#define RG_FREE_MSG(_buf)\ +{\ + if (NULLP != (_buf)) \ + { \ + SPutMsg((_buf)); \ + _buf = NULLP; \ + } \ +} + +#define RG_FREE_MEM(_mem)\ +{\ + if (NULLP != (_mem)) \ + { \ + cmFreeMem((_mem)); \ + _mem = NULLP; \ + } \ +} + +#ifdef L2_OPTMZ +#define RG_FREE_TB(_tb)\ +{\ + U32 lchIdx, pduIdx;\ + SResetMBuf(_tb->macHdr);\ + SResetMBuf(_tb->macCes);\ + _tb->tbPres = FALSE;\ + _tb->tbSize = 0;\ + _tb->padSize = 0;\ + for(lchIdx = 0; lchIdx < _tb->numLch; lchIdx++) \ + {\ + for(pduIdx = 0; pduIdx < _tb->lchInfo[lchIdx].numPdu; pduIdx++)\ + {\ + if(_tb->lchInfo[lchIdx].mBuf[pduIdx] != NULL)\ + {\ + SPutMsg(_tb->lchInfo[lchIdx].mBuf[pduIdx]);\ + _tb->lchInfo[lchIdx].freeBuff = FALSE;\ + }\ + _tb->lchInfo[lchIdx].mBuf[pduIdx] = NULL;\ + }\ + _tb->lchInfo[lchIdx].numPdu = 0;\ + }\ + _tb->numLch = 0;\ +} + +#define RG_FREE_SAVED_TB(_tb)\ +{\ + U32 lchIdx, pduIdx;\ + RG_FREE_MSG(_tb->macHdr);\ + RG_FREE_MSG(_tb->macCes);\ + _tb->tbPres = FALSE;\ + _tb->tbSize = 0;\ + _tb->padSize = 0;\ + for(lchIdx = 0; lchIdx < 10; lchIdx++) \ + {\ + for(pduIdx = 0; pduIdx < 4; pduIdx++)\ + {\ + if(_tb->lchInfo[lchIdx].freeBuff == TRUE)\ + {\ + SPutMsg(_tb->lchInfo[lchIdx].mBuf[pduIdx]);\ + _tb->lchInfo[lchIdx].freeBuff = FALSE;\ + }\ + _tb->lchInfo[lchIdx].mBuf[pduIdx] = NULL;\ + }\ + _tb->lchInfo[lchIdx].numPdu = 0;\ + }\ + _tb->numLch = 0;\ +} + +#endif + +/*********************************************************** + * + * Name : RG_DROP_RGUDDATREQ_MBUF + * + * Desc : Macro to free the message buffers and initialize them to zero + * + * Input : _datreq - Dedicated Data Request pointer which has mBufs + * to be freed + * + * Output : None. + * + * Notes: None + * + **********************************************************/ +#define RG_DROP_RGUDDATREQ_MBUF(_datReq)\ +{\ + U32 idx5,idx6,idx7;\ + for (idx5=0; idx5 < _datReq.nmbOfTbs; idx5++)\ + {\ + for (idx6=0; idx6 < _datReq.datReqTb[idx5].nmbLch; idx6++)\ + {\ + for (idx7=0; \ + idx7 < _datReq.datReqTb[idx5].lchData[idx6].pdu.numPdu; \ + idx7++)\ + {\ + RG_FREE_MSG(_datReq.datReqTb[idx5].\ + lchData[idx6].pdu.mBuf[idx7]);\ + }\ + }\ + }\ +} + +/*********************************************************** + * + * Name : RG_DROP_RGUCDATREQ_MBUF + * + * Desc : Macro to free the message buffers and initialize them to zero + * + * Input : _datreq - Common Data Request pointer which has mBufs + * to be freed + * + * Output : None. + * + * Notes: None + * + **********************************************************/ +#define RG_DROP_RGUCDATREQ_MBUF(_datReq)\ +{\ + if (_datReq != NULLP)\ + {\ + RG_FREE_MSG(_datReq->pdu);\ + }\ +} + +/* RRM_SP1_START */ +#define RG_UPD_GBR_PRB(_cellCb, _qci, _prbUsed) {\ + if(_qci <= RG_MAX_QCI_REPORTS)\ + {\ + _cellCb->qcisUlPrbCnt[_qci-1] += _prbUsed;\ + }\ +} +/* RRM_SP1_END */ + +/* Macros for memory region and pool determination */ +#define RG_GET_MEM_REGION(rgCb) (rgCb.rgInit.region) +#define RG_GET_MEM_POOL(rgCb) (rgCb.rgInit.pool) + + +/* MUX related macros */ +#define RG_RAR_SHDR_LEN 1 +#define RG_RAR_ELEM_LEN 6 +#define RG_MAX_SDU_SUB_HDR_LEN 3 +#define RG_MAX_PAD_ARR_SZ 4096 /* Changing from 400 to 4096 */ +#define RG_PAD_BYTE 0x00 + +#define RG_HDR_TYPE_CRES 1 +#define RG_HDR_TYPE_TA 2 +#ifdef LTE_ADV +#define RG_HDR_TYPE_SCELL_ACT 3 +#endif + +#define RG_SDU_SHDR_LEN 1 +#define RG_FIXDSZ_CE_SHDR_LEN 1 +#define RG_PAD_SHDR_LEN 1 +#define RG_CRES_LEN 6 +#define RG_TA_LEN 1 +#ifdef LTE_ADV +#define RG_SCELL_ACT_CE_LEN 1 +#define RG_SCELL_CE_ELM_LEN (RG_FIXDSZ_CE_SHDR_LEN+RG_SCELL_ACT_CE_LEN) +#endif +#define RG_CRES_ELM_LEN (RG_FIXDSZ_CE_SHDR_LEN+RG_CRES_LEN) +#define RG_TA_ELM_LEN (RG_FIXDSZ_CE_SHDR_LEN+RG_TA_LEN) + + +/* Values of below macros not yet defined in 5G-NR hence using LTE values till + * They are defined + */ +#define RG_CRES_LCID_IDX 0x1C +#define RG_TA_LCID_IDX 0x1D +#ifdef LTE_ADV +#define RG_SCELL_LCID_IDX 0x1B +#endif +#define RG_PAD_LCID_IDX 0x3F + +/* Structure member offset computation macro */ +#define OffsetOf(type, field) \ + (PTR) (&(((type *) NULLP)->field)) + +#define RG_MAX_SUBFRAMES_IN_SFN 9 +#define RG_MAX_SFN 1024 +#ifdef RGAC_5GTF +#define RG_NUM_SUB_FRAMES 50 +#else +#define RG_NUM_SUB_FRAMES 10 +#endif +#define RG_NUM_SUB_FRAMES_5G 50 +/* RRM_SP1_START */ +#define RG_MAX_QCI_REPORTS 4 +/* RRM_SP1_END */ + +#ifdef LTE_L2_MEAS +#define RG_NUM_UL_SUB_FRAMES 16 +#define RG_MAX_QCI_VALUE 10 + +#ifdef EIGHT_UE_PER_TTI_CHANGES +/* Tuned according to TDD Cfg Mode2 and 2UE/TTI. + * * Need to tune if NumUE/TTI is increased */ +#define RG_MAX_DFRD_FREE_BUFS 64 /* 64 - 8UE/TTI */ +#define RG_MAX_FREE_BUFS_PERTTI 16 /* 16 - 8UE/TTI */ +#endif + +#define RG_CALC_SF_DIFF(_time1, _time2)\ + (_time1.sfn*RG_NUM_SUB_FRAMES_5G+_time1.subframe) < (_time2.sfn*RG_NUM_SUB_FRAMES_5G+_time2.subframe)?\ + ((_time1.sfn+RG_MAX_SFN)*RG_NUM_SUB_FRAMES_5G+_time1.subframe) -\ + (_time2.sfn*RG_NUM_SUB_FRAMES_5G+_time2.subframe) : \ + (_time1.sfn*RG_NUM_SUB_FRAMES_5G+_time1.subframe) - (_time2.sfn*RG_NUM_SUB_FRAMES_5G+_time2.subframe) + +#define RG_TTI_CYCLE_INVLD 0xFFFFFFFF +#define RG_CALC_TTI_CNT(_cellCb, _ttiCnt)\ + _ttiCnt = (RG_NUM_SUB_FRAMES_5G * (_cellCb->crntTime.sfn + (_cellCb->ttiCycle * 1024)) )+\ + _cellCb->crntTime.subframe; +#endif /* LTE_L2_MEAS */ + +/* Tuned according to TDD Cfg Mode2 and 2UE/TTI. + * Need to tune if NumUE/TTI is increased */ +#define RG_MAX_DFRD_FREE_BUFS 32 /* 16- 2 UE per TTI 32 - 4UE/TTI */ +#define RG_MAX_FREE_BUFS_PERTTI 8 /* 4 - 2 Ue per TTI, 8 - 4UE/TTI */ + + +/* Define for the block size for memory allocation */ +/* RG_BLKSZ changed from 2048 to 1500*/ +#define RG_BLKSZ 1500 + +/* Defines for RGU Statistics types */ +#define RG_RGU_SDU_DROP 1 +#define RG_RGU_SDU_RCVD 2 + +/* MACROS for General Statistics */ +#define RG_CFG_ADD 1 +#define RG_CFG_DEL 2 + +#define RG_HQ_FDB_IND_CB_TYPE_HQ_ENT 1 +#define RG_HQ_FDB_IND_CB_TYPE_RA_CB 2 + +/* MACRO for validating the mac instance id */ +#define RG_IS_INST_VALID(_inst)\ +{\ + if(_inst >= RG_MAX_INST)\ + {\ + RETVALUE(RFAILED);\ + }\ +} + +/* + * Removed unused hash-define which defines the + * index for releasing the subframe. + */ + +/* Value used to set nDmrs in uplink grant if nDmrs is not applicable */ +#define RG_INVALID_NDMRS 10 + +#define RG_SEND_TRC_IND(_inst,_mBuf, _event) rgLMMTrcInd(_inst,_mBuf, _event) + +/* Note: Any changes to these enums should reflect to */ +/** @details Enums for special argument + * +*/ +typedef enum +{ + RG_DIAG_NA +} RgDiagSplArg; + +#ifdef SS_DIAG +#define RG_DIAG_LVL0(_inst,_tknId, _splArgEnum, _splArg, _string, _arg1, _arg2, _arg3, _arg4) \ +{ \ + if(rgCb[_inst].rgInit.logMask & SS_DIAG_LVL0) \ + { \ + ssDiagFix(_tknId, _splArgEnum, ENTRG, rgCb[_inst].rgInit.inst, SS_DIAG_LVL0, SS_DIAG_MSG_TYPE_FIXED, _splArg, _arg1, _arg2, _arg3, _arg4, _string);\ + } \ +} + +/** @details Macro definition for LTE-MAC error logs + * +*/ +#define RG_DIAG_LVL1(_inst,_tknId, _splArgEnum, _splArg, _string, _arg1, _arg2, _arg3, _arg4) \ +{ \ + if(rgCb[_inst].rgInit.logMask & SS_DIAG_LVL1) \ + { \ + ssDiagFix(_tknId, _splArgEnum, ENTRG, rgCb[_inst].rgInit.inst, SS_DIAG_LVL1, SS_DIAG_MSG_TYPE_FIXED, _splArg, _arg1, _arg2, _arg3, _arg4, _string);\ + } \ +} + +/** @details Macro definition for LTE-MAC critical logs + * +*/ +#define RG_DIAG_LVL2(_inst,_tknId, _splArgEnum, _splArg, _string, _arg1, _arg2, _arg3, _arg4) \ +{ \ + if(rgCb[_inst].rgInit.logMask & SS_DIAG_LVL2) \ + { \ + ssDiagFix(_tknId, _splArgEnum, ENTRG, rgCb[_inst].rgInit.inst, SS_DIAG_LVL2, SS_DIAG_MSG_TYPE_FIXED, _splArg, _arg1, _arg2, _arg3, _arg4, _string);\ + } \ +} + +/** @details Macro definition for LTE-MAC logs + * +*/ +#define RG_DIAG_LVL3(_inst,_tknId, _splArgEnum, _splArg, _string, _arg1, _arg2, _arg3, _arg4) \ +{ \ + if(rgCb[_inst].rgInit.logMask & SS_DIAG_LVL3) \ + { \ + ssDiagFix(_tknId, _splArgEnum, ENTRG, rgCb[_inst].rgInit.inst, SS_DIAG_LVL3, SS_DIAG_MSG_TYPE_FIXED, _splArg, _arg1, _arg2, _arg3, _arg4, _string);\ + } \ +} + +/** @details Macro definition for LTE-MAC logs + * +*/ +#define RG_DIAG_LVL4(_inst,_tknId, _splArgEnum, _splArg, _string, _arg1, _arg2, _arg3, _arg4) \ +{ \ + if(rgCb[_inst].rgInit.logMask & SS_DIAG_LVL4) \ + { \ + ssDiagFix(_tknId, _splArgEnum, ENTRG, rgCb[_inst].rgInit.inst, SS_DIAG_LVL4, SS_DIAG_MSG_TYPE_FIXED, _splArg, _arg1, _arg2, _arg3, _arg4, _string);\ + } \ +} + +#else + +#define RG_DIAG_LVL0(_inst,_tknId, _splArgEnum, _splArg, _string, _arg1, _arg2, _arg3, _arg4) \ +{ \ +} + +/** @details Macro definition for LTE-MAC error logs + * +*/ +#define RG_DIAG_LVL1(_inst,_tknId, _splArgEnum, _splArg, _string, _arg1, _arg2, _arg3, _arg4) \ +{ \ +} + +/** @details Macro definition for LTE-MAC critical logs + * +*/ +#define RG_DIAG_LVL2(_inst,_tknId, _splArgEnum, _splArg, _string, _arg1, _arg2, _arg3, _arg4) \ +{ \ +} + +/** @details Macro definition for LTE-MAC logs + * +*/ +#define RG_DIAG_LVL3(_inst,_tknId, _splArgEnum, _splArg, _string, _arg1, _arg2, _arg3, _arg4) \ +{ \ +} + +/** @details Macro definition for LTE-MAC logs + * +*/ +#define RG_DIAG_LVL4(_inst,_tknId, _splArgEnum, _splArg, _string, _arg1, _arg2, _arg3, _arg4) \ +{ \ +} +#endif + +#endif /* __RGH__ */ + +/********************************************************************** + End of file +**********************************************************************/ diff --git a/src/5gnrmac/rg.x b/src/5gnrmac/rg.x new file mode 100755 index 000000000..73c0d9012 --- /dev/null +++ b/src/5gnrmac/rg.x @@ -0,0 +1,1050 @@ +/******************************************************************************* +################################################################################ +# Copyright (c) [2017-2019] [Radisys] # +# # +# 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. # +################################################################################ +*******************************************************************************/ + +/********************************************************************** + + Name: LTE MAC layer + + Type: X include file + + Desc: Defines required by LTE MAC + + File: rg.x + +**********************************************************************/ + +/** @file rg.x +@brief This file contains basic data structures for the Mac. +*/ + +#ifndef __RGX__ +#define __RGX__ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#ifdef EMTC_ENABLE +#include "rg_emtc.x" /* typedefs for MAC */ +#endif + +/** @brief Logical Channel Id */ +typedef RgPrgLteLcgId LteLcgId; +typedef RguDDatReqInfo RgRguDedDatReq; +typedef RguCDatReqInfo RgRguCmnDatReq; +typedef RguDStaRspInfo RgRguDedStaRsp; +typedef RguCStaRspInfo RgRguCmnStaRsp; +typedef RguDStaIndInfo RgRguDedStaInd; +typedef RguCStaIndInfo RgRguCmnStaInd; +typedef RguDDatIndInfo RgRguDedDatInd; +typedef RguCDatIndInfo RgRguCmnDatInd; +typedef RguLchStaInd RgRguLcStaInd; +typedef TfuPdschDciInfo RgTfuPdschDciInfo; +typedef TfuDatReqInfo RgTfuDatReqInfo; +typedef TfuDatReqPduInfo RgTfuDatReqPduInfo; +typedef RguDDatReqPerUe RgRguDDatReqPerUe; +#ifdef L2_OPTMZ +typedef TfuDatReqTbInfo RgTfuDatReqTbInfo; +#endif + +#ifdef LTE_L2_MEAS +typedef struct rgL2MeasCb RgL2MeasCb; +typedef struct rgQciCb RgQciCb; + +typedef RguL2MUlThrpMeasReqInfo RgRguL2MUlThrpMeasReq; + +#endif /* LTE_L2_MEAS */ +/* Forward declarations for some structures */ +typedef struct rgUeCb RgUeCb; +typedef struct rgErrInfo RgErrInfo; +typedef struct rgCellCb RgCellCb; +typedef struct rgUlHqProcCb RgUlHqProcCb; +typedef struct rgDlHqProcCb RgDlHqProcCb; +typedef struct rgLcgCb RgLcgCb; +typedef struct rgDlHqEnt RgDlHqEnt; +typedef struct _rgCb RgCb; +typedef RgPrgUlLcInfo RgUlLcCb; +typedef RgPrgDlLcInfo RgDlLcCb; + + +#ifdef LTE_L2_MEAS +/* @brief UE Specific Uplink allocation info needed for measurements */ +typedef struct rgUeUlAlloc +{ + CmLteRnti rnti; /*!< Ue Id */ + U8 numPrb; /*!< Number of total PRB's allocated for this UE */ +} RgUeUlAlloc; +/** + * @brief Structure hold uplink allocation information for sub frames. + * */ +typedef struct rgUlSf +{ + CmLteTimingInfo schdTime; /*!< scheduled frame and subframe number */ + U8 numUe; /*!< Number of UE's allocated in this uplink + subframe */ + RgUeUlAlloc *ueUlAllocInfo; /*!< Uplink alloc infor for this subframe */ +} RgUlSf; + +/** @brief + * L2 measurement control block. + * */ +struct rgL2MeasCb +{ + CmLList measLnk; /*!< MeasCb node */ + RgInfL2MeasReq measReq; /*!< Request received for measurement */ + CmLteTimingInfo startTime; /*!< Time at which measurement started */ + U32 sfnCycle; /*!< Count of Num of SFN wraps */ +}; +/** @brief + * Control block to store Logical Channels with Qci. + * */ +struct rgQciCb +{ + U8 qci; /*< QCI for measurement */ + U32 prbCount; /*!< Cummulative PRB count */ + U8 mask; /*!< Measurement Active or Not*/ + CmLteTimingInfo startTime;/*!< Time at which measurement started */ +}; +#endif /* LTE_L2_MEAS */ +/** + * @brief + * Information about one PDCCH. + */ +typedef struct rgPdcch { + CmLteRnti rnti; /*!< RNTI to who the PDCCH is allocated */ + RgTfuPdschDciInfo dci; /*!< PDCCH format */ +} RgPdcch; + +typedef struct rgBcchTb +{ + RgPdcch pdcch; + Buffer *tb; + U16 txPwrOffset; /*!< PDSCH Tx Pwr offset */ +} RgBcchTb; + +typedef struct rgPcchTb +{ + RgPdcch pdcch; + Buffer *tb; + U16 txPwrOffset; /*!< PDSCH Tx Pwr offset */ +} RgPcchTb; + +typedef struct rgRaRspAlloc +{ + RgPdcch pdcch; /*!< NULLP if no Rsp allocation done for raRnti*/ + Buffer *rar; + U16 txPwrOffset; /*!< PDSCH Tx Pwr offset */ +}RgRaRspAlloc; + +typedef struct rgBchTb +{ + Buffer *tb; /*!< BCH data for this frame */ +}RgBchTb; + + +typedef struct rgDlSf +{ + CmLteTimingInfo schdTime; /*!< scheduled frame and subframe number */ + Bool txDone; /*!< Flag to indicate transmission done */ +/* ADD Changes for Downlink UE Timing Optimization */ +#ifdef LTEMAC_DLUE_TMGOPTMZ + U8 remDatReqCnt; /*!< Counter to maintain count of Ded data received.*/ + /* Fix [ccpu00126310]: Tracks Data Requests from RLC for both loosely and tight coupled + RLC-MAC */ + Bool statIndDone; /*!< Marks sending of all status indication done */ +#endif + RgBchTb bch; /*!< BCH data for this frame */ + RgBcchTb bcch; /*!< BCCH allocation for this frame */ +#ifdef EMTC_ENABLE + RgEmtcBcchTb emtcBcch; /*!< EMTC BCCH allocation for this frame */ +#endif + RgPcchTb pcch; /*!< PCCH allocation for this frame */ + CmLListCp tbs; /*!< TBs or DL HARQ processes */ + U8 numRaRsp; /*!< No.of RaRsp */ + RgRaRspAlloc raRsp[RG_MAX_RA_RNTI]; /* Array of list of Ra Rsp + Allocations for each rarnti */ + U8 numTbReqsSent; /*!< Number of TB requests sent towards SMAC. + Total numTbReqsSent will be equal to maximum secondary cells */ +} RgDlSf; + +/** + * @brief + * Logical channel control block for BCCH and PCCH channels. + */ +typedef struct rgBcchDlschLcCb +{ + CmLteLcId lcId; /*!< Logical channel ID */ + Buffer *tb; +} RgBcchDlschLcCb; + +typedef struct rgBcchBchLcCb +{ + CmLteLcId lcId; /*!< Logical channel ID */ +} RgBcchBchLcCb; + +typedef struct rgPcchLcCb +{ + CmLteLcId lcId; /*!< Logical channel ID */ +} RgPcchLcCb; + +/** + * @brief + * Random access information per cell. + */ +typedef struct rgRaInfoCb +{ + CmLListCp ueRachLst; /*!< List of RaCbs */ +} RgRaInfoCb; + +typedef struct rgSchInstMap +{ + S16 cellSapId; /*!< SAP ID of the cell in scheduler instance */ + Inst schInst; /*!< Scheduler instance that is serving this cell*/ +} RgSchInstMap; + +/** + * @brief + * Configuration Information for Upper SAPs at RGU,CRG and RGR interfaces. + */ +typedef struct rgUpSapCfgInfo +{ + Pst sapPst; /*!< Post information associated with SAP */ + SpId spId; /*!< SpId associated with SAP */ + SuId suId; /*!< SuId associated with SAP */ +}RgUpSapCfgInfo; + +/** + * @brief + * Configuration Information for Lower SAP at TFU interface + */ +typedef struct rgLowSapCfgInfo +{ + Pst sapPst; /*!< Post information associated with SAP */ + SpId spId; /*!< SpId associated with SAP */ + SuId suId; /*!< SuId associated with SAP */ + TmrCfg bndTmr; /*!< Bind Timer Value */ +}RgLowSapCfgInfo; + +/** + * @brief + * Control Block structure for Upper SAPs at RGU,CRG and RGR interfaces. + */ +typedef struct rgUpSapCb +{ + RgUpSapCfgInfo sapCfg; /*!< Configuration information */ + RgSapSts sapSts; /*!< Statistics related to SAP */ + RgSapSta sapSta; /*!< SAP Status */ +}RgUpSapCb; + +/** + * @brief + * Control Block structure for Lower SAP at TFU interface. + */ +typedef struct rgLowSapCb +{ + RgLowSapCfgInfo sapCfg; /*!< SAP configuration information */ + RgSapSts sapSts; /*!< Statistics related to SAP */ + RgSapSta sapSta; /*!< SAP Status */ + U8 numBndRetries; /*!< Number of Bind Retries */ +}RgLowSapCb; + +/** + * @brief + * MAC sub-header control block for 5G-NR MAC + * sub-hdr for fixed size MAC CE - 1 octat(R/R/LCID) + * sub-hdr for variable size MAC CE or MAC SDU -2/3 octat(R/F/LCID/L(8/16 bits)) + * + */ +typedef struct RgMUXSubHdr +{ + U8 shLen; + U8 shData[RG_MAX_SDU_SUB_HDR_LEN]; /* RRLCID/RFLCID + F-L (O) + L (O) */ +} RgMUXSubHdr; + + +/** + * @brief + * Cell Control block per cell + */ +struct rgCellCb +{ + CmHashListEnt cellLstEnt; /*!< Hash list Entity for cell list */ + RgSchInstMap schInstMap; /*!< Sch Inst Info */ + CmLteCellId cellId; /*!< Cell ID */ + CmLteTimingInfo crntTime; + U8 maxDlHqProcPerUe; /*!< Store based on FDD/TDD(UL/DL Index) */ + CrgBwCfg bwCfg; /*!< Bandwidth Configuration */ + CrgRachCfg rachCfg; /*!< RACH Configuration */ + + RgUpSapCb *rguDlSap; /*!< RGU SAP Control Block for RLC DL */ + RgUpSapCb *rguUlSap; /*!< RGU SAP Control Block for RLC UL*/ + Inst macInst; /*!< MAC Instance id for this cell */ + U8 cellActvState; /*!< Bitmask indicating if cell is active: + Cell is active only after BCCH, PCCH, DL + CCCH, UL CCCH and scheduler config */ + CmLteLcId ulCcchId; /*!< LcId for uplink CCCH */ + CmLteLcId dlCcchId; /*!< LcId for downlink CCCH */ + RgBcchBchLcCb bcchBchInfo; /*!< BCCH mapped on BCH + logical channel control block */ + RgPcchLcCb pcchInfo; /*!< PCCH logical channel control block */ + U8 numBcchDlschInfo; + RgBcchDlschLcCb bcchDlschInfo[RG_MAX_BCCH_DLSCH]; /*!< BCCH mapped on DLSCH + logical channel control block */ + CmHashListCp ueLst; /*!< Hash list of UE control + blocks: RgUeCb */ + /*Added support for SPS*/ +#ifdef LTEMAC_SPS + CmHashListCp spsUeLst; /*!< Hash list of UECbs with SPS-Rnti + : Element is RgUeCb */ +#endif + RgRaInfoCb raInfo; /*!< Random access related information for + cell */ + RgDlSf subFrms[RG_NUM_SUB_FRAMES]; +#ifdef LTE_L2_MEAS + CmLListCp l2mList; /*!< List of all L2M requests + rgSchL2MeasCb */ + RgQciCb qciArray[LRG_MAX_QCI]; /*!< List of all qci's configured + rgQciCb */ + RgUlSf ulSf[RG_NUM_UL_SUB_FRAMES]; /*!< UL Sub frame */ + Bool sndL2Meas; /*!< Send L2 Meas when No L2 Measuremnt timer is running*/ + + U32 ttiCycle; /*!< Count of Number of 10240 Cycles + completed */ + +#endif /* LTE_L2_MEAS */ + RguFlowCntrlInd *flowCntrlInd; /*!
errCause = RGERR_CFG_INVALID_CRG_CELL_CFG;
+   if ((rgCb[inst].cell != NULLP)
+         || rgCb[inst].inactiveCell != NULLP)
+   {
+      RLOG_ARG0(L_ERROR,DBG_CELLID,cellCfg->cellId,"Cell already exists");
+      RETVALUE(RFAILED);
+   }
+   if ((cellCfg->bwCfg.dlTotalBw < RG_MIN_DL_BW
+            || cellCfg->bwCfg.dlTotalBw > RG_MAX_DL_BW)
+         || (cellCfg->bwCfg.ulTotalBw < RG_MIN_UL_BW
+            || cellCfg->bwCfg.ulTotalBw > RG_MAX_UL_BW))
+   {
+      RLOG_ARG2(L_ERROR,DBG_CELLID,cellCfg->cellId, 
+            "Invalid Bandwidth configuration: ul %d dl %d",
+            cellCfg->bwCfg.ulTotalBw, cellCfg->bwCfg.dlTotalBw);
+      RETVALUE(RFAILED);
+   }
+   if (cellCfg->rachCfg.maxMsg3Tx < RG_MIN_HQ_TX)
+   {
+      RLOG_ARG1(L_ERROR,DBG_CELLID,cellCfg->cellId,
+                "Invalid RACH configuration: maxMsg3Tx %d",cellCfg->rachCfg.maxMsg3Tx);
+      RETVALUE(RFAILED);
+   }
+#ifdef TENB_MULT_CELL_SUPPRT
+   if((cellCfg->rguDlSapId > rgCb[inst].numRguSaps) ||
+      (cellCfg->rguUlSapId > rgCb[inst].numRguSaps))
+   {
+      RGDBGERRNEW(inst,(rgPBuf(inst), "Invald Sap Id: DL %d UL %d for CellId %d failed\n",
+               cellCfg->rguDlSapId,
+               cellCfg->rguUlSapId,
+               cellCfg->cellId));
+      RETVALUE(RFAILED);
+   }
+#endif
+   errInfo->errCause = RGERR_NONE;
+   RETVALUE(ROK);
+}  /* rgCFGVldtCrgCellCfg */
+
+
+/**
+ * @brief Validates the UE configuration request from RRC to MAC.
+ *
+ * @details
+ *
+ *     Function : rgCFGVldtCrgUeCfg
+ *
+ *     Processing Steps:
+ *      - Validate the UE configuration request from RRC to MAC at CFG:
+ *        validate the value range for the configured values.
+ *      - If validated successfully,
+ *        - Return ROK and pointer to the cell of UE.
+ *      - Else 
+ *        - Return RFAILED.
+ *
+ *  @param[in]  Inst        inst
+ *  @param[in]  CrgUeCfg  *ueCfg
+ *  @param[out] RgCellCb  **cell
+ *  @param[out] RgErrInfo *errInfo
+ *  @return  S16
+ *      -# ROK
+ *      -# RFAILED
+ **/
+#ifdef ANSI
+PUBLIC S16 rgCFGVldtCrgUeCfg
+(
+Inst      inst,
+CrgUeCfg  *ueCfg,
+RgCellCb  **cell,
+RgErrInfo *errInfo
+)
+#else
+PUBLIC S16 rgCFGVldtCrgUeCfg(inst,ueCfg, cell, errInfo)
+Inst      inst;
+CrgUeCfg  *ueCfg;
+RgCellCb  **cell;
+RgErrInfo *errInfo;
+#endif
+{
+   TRC2(rgCFGVldtCrgUeCfg);
+
+   errInfo->errCause = RGERR_CFG_INVALID_CRG_UE_CFG;
+   if ((ueCfg->txMode.pres == PRSNT_NODEF) && 
+       (ueCfg->txMode.tm == CRG_UE_TM_5))
+   {
+      RLOG_ARG1(L_ERROR,DBG_CRNTI,ueCfg->crnti,"Transmission Mode=%d not supported",
+            ueCfg->txMode.tm);
+      RETVALUE(RFAILED);
+   }
+   
+   /* Fetch the Active cell */
+   if(((*cell = rgCb[inst].cell) == NULLP) ||
+       ((*cell)->cellId != ueCfg->cellId))
+   {
+      RLOG_ARG1(L_ERROR,DBG_CRNTI,ueCfg->crnti,"Active Cell does not exist for cellId%d",
+            ueCfg->cellId);
+      RETVALUE(RFAILED);
+   }
+   /* Check if Ue already configured */
+   if (rgDBMGetUeCb(*cell, ueCfg->crnti) != NULLP)
+   {
+      RLOG_ARG0(L_ERROR,DBG_CRNTI,ueCfg->crnti,"Ue already exists");
+      RETVALUE(RFAILED);
+   }
+
+   if (ueCfg->ueUlHqCfg.maxUlHqTx < RG_MIN_HQ_TX)
+   {
+      RLOG_ARG1(L_ERROR,DBG_CRNTI,ueCfg->crnti, "Invalid Uplink HARQ config %d ",
+            ueCfg->ueUlHqCfg.maxUlHqTx);
+      RETVALUE(RFAILED);
+   }
+#ifdef TENB_MULT_CELL_SUPPRT
+   if((ueCfg->rguDlSapId > rgCb[inst].numRguSaps) ||
+      (ueCfg->rguUlSapId > rgCb[inst].numRguSaps))
+   {
+      RGDBGERRNEW(inst,(rgPBuf(inst), "Invald Sap Id: DL %d UL %d for ueId %d failed\n",
+               ueCfg->rguDlSapId,
+               ueCfg->rguUlSapId,
+               ueCfg->crnti));
+      RETVALUE(RFAILED);
+   }
+#endif
+
+   errInfo->errCause = RGERR_NONE;
+   RETVALUE(ROK);
+}  /* rgCFGVldtCrgUeCfg */
+
+
+/**
+ * @brief Validates the logical channel configuration request from RRC to MAC.
+ *
+ * @details
+ *
+ *     Function : rgCFGVldtCrgLcCfg
+ *
+ *     Processing Steps:
+ *      - Validate the logical channel configuration request from RRC to
+ *        MAC at CFG: validate if configured values are within the range.
+ *      - If validated successfully,
+ *        - Return ROK and pointer to the cell for common channels. Return
+ *          pointer to cell and UE for dedicated logical channels.
+ *      - Else 
+ *        - Return RFAILED.
+ *
+ *  @param[in]  CrgLchCfg  *lcCfg
+ *  @param[in]  Inst        inst
+ *  @param[out] RgCellCb   **cell
+ *  @param[out] RgUeCb     **ue
+ *  @param[out] RgErrInfo  *errInfo
+ *  @return  S16
+ *      -# ROK
+ *      -# RFAILED
+ **/
+#ifdef ANSI
+PUBLIC S16 rgCFGVldtCrgLcCfg
+(
+Inst       inst, 
+CrgLchCfg  *lcCfg,
+RgCellCb   **cell,
+RgUeCb     **ue,
+RgErrInfo  *errInfo
+)
+#else
+PUBLIC S16 rgCFGVldtCrgLcCfg(inst,lcCfg, cell, ue, errInfo)
+Inst       inst;
+CrgLchCfg  *lcCfg;
+RgCellCb   **cell;
+RgUeCb     **ue;
+RgErrInfo  *errInfo;
+#endif
+{
+
+   TRC2(rgCFGVldtCrgLcCfg);
+
+   if (lcCfg->lcType == CM_LTE_LCH_DTCH || lcCfg->lcType == CM_LTE_LCH_DCCH)
+   {
+      /* Dedicated logical channels */
+      if ((rgCFGVldtCrgDedLcCfg(inst,lcCfg, cell, ue, errInfo)) != ROK)
+      {
+         RLOG_ARG0(L_ERROR,DBG_CRNTI,lcCfg->crnti,"Validation for dedicated LC failed");
+         RETVALUE(RFAILED);
+      }
+   }
+   else if (lcCfg->lcType == CM_LTE_LCH_BCCH
+         || lcCfg->lcType == CM_LTE_LCH_PCCH
+         || lcCfg->lcType == CM_LTE_LCH_CCCH)
+   {
+      if ((rgCFGVldtCrgCmnLcCfg(inst,lcCfg, cell, errInfo)) != ROK)
+      {
+         RLOG_ARG0(L_ERROR,DBG_CRNTI,lcCfg->crnti,"Validation for common logical channels failed");
+         RETVALUE(RFAILED);
+      }
+   }
+   else
+   {
+      RLOG_ARG1(L_ERROR,DBG_CRNTI,lcCfg->crnti,"Invalid logical channel type %d",
+                lcCfg->lcType);
+      RETVALUE(RFAILED);
+   }
+#ifdef LTE_L2_MEAS
+   if ( lcCfg->qci <  RG_QCI_MIN ||
+        lcCfg->qci >  RG_QCI_MAX
+      )
+   {
+      RLOG_ARG1(L_ERROR,DBG_CRNTI,lcCfg->crnti,"Invalid qci %x",lcCfg->qci);
+      RETVALUE(RFAILED);
+   }
+   /*validate qci */
+#endif /*LTE_L2_MEAS */
+
+   errInfo->errCause = RGERR_NONE;
+   RETVALUE(ROK);
+}  /* rgCFGVldtCrgLcCfg */
+
+
+/**
+ * @brief Validates the cell re-configuration request from RRC to MAC.
+ *
+ * @details
+ *
+ *     Function : rgCFGVldtCrgCellRecfg
+ *
+ *     Processing Steps:
+ *      - Retrieve the cell control block.
+ *      - If successful,
+ *        - Validate the range of re-configured values recieved in
+ *          re-configuration request.
+ *        - If validated successfully,
+ *          - Return ROK and pointer to the cell.
+ *        - Else 
+ *          - Return RFAILED.
+ *      - Else return RFAILED.
+ *
+ *  @param[in]  Inst        inst
+ *  @param[in]  CrgCellRecfg  *cellRecfg
+ *  @param[out] RgCellCb      **cell
+ *  @param[out] RgErrInfo     *errInfo
+ *  @return  S16
+ *      -# ROK
+ *      -# RFAILED
+ **/
+#ifdef ANSI
+PUBLIC S16 rgCFGVldtCrgCellRecfg
+(
+Inst          inst,
+CrgCellRecfg  *cellRecfg,
+RgCellCb      **cell,
+RgErrInfo     *errInfo
+)
+#else
+PUBLIC S16 rgCFGVldtCrgCellRecfg(inst,cellRecfg, cell, errInfo)
+Inst          inst;
+CrgCellRecfg  *cellRecfg;
+RgCellCb      **cell;
+RgErrInfo     *errInfo;
+#endif
+{
+   TRC2(rgCFGVldtCrgCellRecfg);
+
+   errInfo->errCause = RGERR_CFG_INVALID_CRG_CELL_RECFG;
+   
+   if (((*cell = rgCb[inst].cell) == NULLP)
+         && ((*cell = rgCb[inst].inactiveCell) == NULLP))
+   {
+      RLOG_ARG0(L_ERROR,DBG_CELLID,cellRecfg->cellId,"Cell does not exist");
+      RETVALUE(RFAILED);
+   }
+
+   if((*cell)->cellId != cellRecfg->cellId)
+   {
+      RLOG_ARG1(L_ERROR,DBG_CELLID,cellRecfg->cellId, "Cell does not exist %d\n",cellRecfg->cellId);
+      RETVALUE(RFAILED);
+   }
+   if (cellRecfg->rachRecfg.maxMsg3Tx < RG_MIN_HQ_TX)
+   {
+      RLOG_ARG1(L_ERROR,DBG_CELLID,cellRecfg->cellId,
+                "Invalid RACH configuration: maxMsg3Tx %d",cellRecfg->rachRecfg.maxMsg3Tx);
+      RETVALUE(RFAILED);
+   }
+   errInfo->errCause = RGERR_NONE;
+   RETVALUE(ROK);
+}  /* rgCFGVldtCrgCellRecfg */
+
+
+/**
+ * @brief Validates the UE re-configuration request from RRC to MAC.
+ *
+ * @details
+ *
+ *     Function : rgCFGVldtCrgUeRecfg
+ *
+ *     Processing Steps:
+ *      - Retrieve the UE control block.
+ *      - If successful,
+ *        - Validate the range of re-configured values recieved in
+ *          re-configuration request.
+ *        - If validated successfully,
+ *          - Return ROK and pointer to the cell and ue.
+ *        - Else 
+ *          - Return RFAILED.
+ *      - Else return RFAILED.
+ *
+ *  @param[in]  Inst        inst
+ *  @param[in]  CrgUeRecfg *ueRecfg
+ *  @param[out] RgCellCb   **cell
+ *  @param[out] RgUeCb     **ue
+ *  @param[out] RgErrInfo *errInfo
+ *  @return  S16
+ *      -# ROK
+ *      -# RFAILED
+ **/
+#ifdef ANSI
+PUBLIC S16 rgCFGVldtCrgUeRecfg
+(
+Inst        inst,
+CrgUeRecfg  *ueRecfg,
+RgCellCb    **cell,
+RgUeCb      **ue,
+RgErrInfo   *errInfo
+)
+#else
+PUBLIC S16 rgCFGVldtCrgUeRecfg(inst,ueRecfg, cell, ue, errInfo)
+Inst        inst;
+CrgUeRecfg  *ueRecfg;
+RgCellCb    **cell;
+RgUeCb      **ue;
+RgErrInfo   *errInfo;
+#endif
+{
+   TRC2(rgCFGVldtCrgUeRecfg);
+
+   errInfo->errCause = RGERR_CFG_INVALID_CRG_UE_RECFG;
+   
+   if ((ueRecfg->txMode.pres == PRSNT_NODEF) && 
+       (ueRecfg->txMode.tm == CRG_UE_TM_5))
+   {
+      RLOG_ARG1(L_ERROR,DBG_CELLID,ueRecfg->cellId,"Transmission Mode=%d not supported",
+                ueRecfg->txMode.tm);
+      RETVALUE(RFAILED);
+   }
+
+    /* Fetch the Active cell */
+   if (((*cell = rgCb[inst].cell) == NULLP) 
+        || ((*cell)->cellId != ueRecfg->cellId))
+   {
+      RLOG_ARG0(L_ERROR,DBG_CELLID,ueRecfg->cellId, "Active Cell does not exist\n");
+      RETVALUE(RFAILED);
+   }
+ 
+   /* Fix : syed UE ID change at MAC will now be controlled
+    * by SCH. */
+   if ((*ue = rgDBMGetUeCb(*cell, ueRecfg->oldCrnti)) == NULLP)
+   {
+      RLOG_ARG1(L_ERROR,DBG_CELLID,ueRecfg->cellId,"[%d]Old Ue does not exist", ueRecfg->oldCrnti);
+      RETVALUE(RFAILED);
+   }
+   if (ueRecfg->ueUlHqRecfg.maxUlHqTx < RG_MIN_HQ_TX)
+   {
+      RLOG_ARG1(L_ERROR,DBG_CELLID,ueRecfg->cellId,"Invalid Uplink HARQ config for UE %d",
+            ueRecfg->ueUlHqRecfg.maxUlHqTx);
+      RETVALUE(RFAILED);
+   }
+   errInfo->errCause = RGERR_NONE;
+   RETVALUE(ROK);
+}  /* rgCFGVldtCrgUeRecfg */
+
+
+/**
+ * @brief Validates the logical channel re-configuration request from
+ * RRC to MAC.
+ *
+ * @details
+ *
+ *     Function : rgCFGVldtCrgLcRecfg
+ *
+ *     Processing Steps:
+ *      - Retrieve the uplink and downlink logical channel control block.
+ *      - If successful,
+ *        - Validate the range of re-configured values recieved in
+ *          re-configuration request.
+ *        - If validated successfully,
+ *          - Return ROK and pointer to the cell, UE and logical channel.
+ *        - Else 
+ *          - Return RFAILED.
+ *      - Else return RFAILED.
+ *
+ *  @param[in]  Inst        inst
+ *  @param[in]  CrgLchRecfg  *lcRecfg
+ *  @param[out] RgCellCb     **cell
+ *  @param[out] RgUeCb       **ue
+ *  @param[out] RgUlLcCb     **ulLc
+ *  @param[out] RgDlLcCb     **dlLc
+ *  @param[out] RgErrInfo    *errInfo
+ *  @return  S16
+ *      -# ROK
+ *      -# RFAILED
+ **/
+#ifdef ANSI
+PUBLIC S16 rgCFGVldtCrgLcRecfg
+(
+Inst        inst,
+CrgLchRecfg *lcRecfg,
+RgCellCb    **cell,
+RgUeCb      **ue,
+RgUlLcCb    **ulLc,
+RgErrInfo   *errInfo
+)
+#else
+PUBLIC S16 rgCFGVldtCrgLcRecfg(inst,lcRecfg, cell, ue, ulLc, errInfo)
+Inst        inst;
+CrgLchRecfg  *lcRecfg;
+RgCellCb     **cell;
+RgUeCb       **ue;
+RgUlLcCb     **ulLc;
+RgErrInfo    *errInfo;
+#endif
+{
+   TRC2(rgCFGVldtCrgLcRecfg);
+
+   errInfo->errCause = RGERR_CFG_INVALID_CRG_LC_RECFG;
+
+   /* Fetch the cell */
+   if ((((*cell = rgCb[inst].cell)) == NULLP)
+      || ((*cell)->cellId != lcRecfg->cellId))
+   {
+      RLOG_ARG2(L_ERROR,DBG_CRNTI,lcRecfg->crnti,"Active Cell %u does not exist for UE %u", lcRecfg->cellId, lcRecfg->crnti);
+      RETVALUE(RFAILED);
+   }
+   /* Fetch the Ue for dedicated channels */
+   if ((*ue = rgDBMGetUeCb(*cell, lcRecfg->crnti)) == NULLP)
+   {
+      RLOG_ARG0(L_ERROR,DBG_CRNTI,lcRecfg->crnti,"Ue does not exist for dedicated logical channel");
+      RETVALUE(RFAILED);
+   }
+
+   if ((*ulLc = rgDBMGetUlDedLcCb((*ue), lcRecfg->lcId)) == NULLP)
+   {
+      RLOG_ARG1(L_ERROR, DBG_CRNTI,lcRecfg->crnti,"Dedicated UL LC does not exist %d",lcRecfg->lcId);
+      RETVALUE(RFAILED);
+   }
+
+   if (lcRecfg->ulRecfg.lcgId > (RG_MAX_LCG_PER_UE - 1))
+   {
+      RLOG_ARG2(L_ERROR,DBG_CRNTI,lcRecfg->crnti,"Invalid lcgId for uplink logical channel lcg %d lc %d",
+                lcRecfg->ulRecfg.lcgId, lcRecfg->lcId);
+      RETVALUE(RFAILED);
+   }
+
+   errInfo->errCause = RGERR_NONE;
+   RETVALUE(ROK);
+}  /* rgCFGVldtCrgLcRecfg */
+
+/* Start: LTEMAC_2.1_DEV_CFG */
+/**
+ * @brief Validates the UE Reset request from RRC to MAC.
+ *
+ * @details
+ *
+ *     Function : rgCFGVldtCrgUeReset
+ *
+ *     Processing Steps:
+ *      - Retrieve the CELL control block.
+ *      - If Failue,
+ *          - Return RFAILED.
+ *      - Retrieve the UE control block.
+ *      - If Failue,
+ *          - Return RFAILED.
+ *
+ *  @param[in]  Inst        inst
+ *  @param[in]  CrgRst     *reset,
+ *  @param[out] RgCellCb   **cell
+ *  @param[out] RgUeCb     **ue
+ *  @param[out] RgErrInfo *errInfo
+ *  @return  S16
+ *      -# ROK
+ *      -# RFAILED
+ **/
+#ifdef ANSI
+PUBLIC S16 rgCFGVldtCrgUeReset
+(
+Inst       inst,
+CrgRst     *reset,
+RgCellCb    **cell,
+RgUeCb      **ue,
+RgErrInfo   *errInfo
+)
+#else
+PUBLIC S16 rgCFGVldtCrgUeReset(inst,reset, cell, ue, errInfo)
+Inst       inst;
+CrgRst     *reset;
+RgCellCb    **cell;
+RgUeCb      **ue;
+RgErrInfo   *errInfo;
+#endif
+{
+   TRC2(rgCFGVldtCrgUeReset);
+
+   errInfo->errCause = RGERR_CFG_INVALID_CRG_UE_RESET;
+   
+   /* Fetch the Active cell */
+   if (((*cell = rgCb[inst].cell) == NULLP)
+      || ((*cell)->cellId != reset->cellId))
+   {
+      RGDBGERRNEW(inst,(rgPBuf(inst), "[%d]Active Cell does not exist %d\n",reset->crnti, reset->cellId));
+      RLOG_ARG1(L_ERROR,DBG_CRNTI,reset->crnti,"Active Cell does not exist %d",reset->cellId);
+      RETVALUE(RFAILED);
+   }
+
+   /* Fetch the Ue */
+   if ((*ue = rgDBMGetUeCb(*cell, reset->crnti)) == NULLP)
+   {
+      RLOG_ARG0(L_ERROR,DBG_CRNTI,reset->crnti,"UE does not exist");
+      RETVALUE(RFAILED);
+   }
+
+   errInfo->errCause = RGERR_NONE;
+   RETVALUE(ROK);
+}  /* rgCFGVldtCrgUeReset*/
+/* End: LTEMAC_2.1_DEV_CFG */
+
+
+
+/**
+ * @brief Handler for the cell configuration request from RRC to MAC.
+ *
+ * @details
+ *
+ *     Function : rgCFGCrgCellCfg
+ *
+ *     Processing Steps:
+ *      - Allocate and create cell control block.
+ *      - Update cell control block with the values recieved in the
+ *        configuration.
+ *      - Add the control block to hash list of cells.
+ *      - Update the statistics.
+ *      - If successful, return ROK else return RFAILED.
+ *
+ *  @param[in]  Inst        inst
+ *  @param[in]  CrgCellCfg  *cellCfg
+ *  @param[out] RgErrInfo   *errInfo
+ *  @return  S16
+ *      -# ROK
+ *      -# RFAILED
+ **/
+#ifdef ANSI
+PUBLIC S16 rgCFGCrgCellCfg
+(
+Inst        inst,
+CrgCellCfg  *cellCfg,
+RgErrInfo   *errInfo
+)
+#else
+PUBLIC S16 rgCFGCrgCellCfg(inst,cellCfg, errInfo)
+Inst        inst;
+CrgCellCfg  *cellCfg;
+RgErrInfo   *errInfo;
+#endif
+{
+   S16        ret;
+   RgCellCb   *cell = NULLP;
+   U8         idx;
+   SuId       rguUlSapId = 0;
+   SuId       rguDlSapId = 0;
+   /* RLC SAP to allocate flowCntrlInd buffer*/
+   Pst        *pst ;
+
+   TRC2(rgCFGCrgCellCfg);
+
+   errInfo->errCause = RGERR_CFG_CRG_CELL_CFG;
+   
+   /* Allocate the cell control block */
+   if((ret = rgAllocSBuf(inst,(Data**)&cell, sizeof(RgCellCb))) != ROK)
+   {
+      RLOG_ARG0(L_ERROR,DBG_CELLID,cellCfg->cellId,"Memory allocation FAILED for cell");
+      RETVALUE(RFAILED);
+   }
+   if (cell == NULLP)
+   {
+      RLOG_ARG0(L_ERROR,DBG_CELLID,cellCfg->cellId, "Memory allocation FAILED for cell");
+      RETVALUE(RFAILED);
+   }
+
+   /* Initialize the cell */
+   cell->cellId  = cellCfg->cellId;
+   cell->rachCfg = cellCfg->rachCfg;
+   cell->bwCfg   = cellCfg->bwCfg;
+#ifdef EMTC_ENABLE
+   if(cellCfg->emtcEnable)
+    {  
+     cell->emtcEnable = cellCfg->emtcEnable;
+    }
+#endif
+   /* Initialize UL and DL CCCH logical channels */
+   cell->ulCcchId = RG_INVALID_LC_ID;
+   cell->dlCcchId = RG_INVALID_LC_ID;
+
+   
+   /* Initialize the lists of the cell */
+   ret = rgDBMInitCell(cell);
+   if (ret != ROK)
+   {
+      RLOG_ARG0(L_ERROR,DBG_CELLID,cellCfg->cellId,"DBM initialization for cell failed");
+      rgCFGFreeInactvCellCb(cell);
+      RETVALUE(RFAILED);
+   }
+
+#ifdef LTE_ADV
+   if (RFAILED == RgLaaCellCbInit(cell))
+   {
+      rgCFGFreeInactvCellCb(cell);
+      RETVALUE(RFAILED);
+   }
+#endif
+
+   for(idx=0;idx < RG_NUM_SUB_FRAMES; idx++)
+   {
+      cell->subFrms[idx].txDone = TRUE;
+   }
+  
+   cell->macInst           = inst + RG_INST_START; 
+   /* Insert cell in the incative cell list */
+   rgCb[inst].inactiveCell = cell;
+   rgCb[inst].cell         = NULLP;
+#ifdef TENB_MULT_CELL_SUPPRT
+   rguDlSapId              = cellCfg->rguDlSapId;
+   rguUlSapId              = cellCfg->rguUlSapId;
+#else
+   if(rgCb[inst].numRguSaps > 1)
+   {
+      rguDlSapId              = 1;
+   }
+#endif
+   cell->rguDlSap          = &(rgCb[inst].rguSap[rguDlSapId]);
+   cell->rguUlSap          = &(rgCb[inst].rguSap[rguUlSapId]);
+
+
+#ifdef LTE_L2_MEAS
+   cmLListInit(&cell->l2mList);
+   for(idx = 0; idx < RG_NUM_UL_SUB_FRAMES; idx++)
+   {
+      cmMemset((U8 *)&cell->ulSf[idx], 0, sizeof(RgUlSf));
+   }
+
+   cell->ttiCycle = (U32)RG_TTI_CYCLE_INVLD;   
+#endif
+   /* Update Statistics */
+   rgUpdtCellCnt(inst,RG_CFG_ADD);
+   errInfo->errCause = RGERR_NONE;
+  
+   pst = &rgCb[inst].rguSap[rguDlSapId].sapCfg.sapPst;
+   /* Allocate a buffer for flowCntrlInd.*/
+   SGetSBuf(pst->region, pst->pool, (Data **)&cell->flowCntrlInd, 
+              sizeof(RguFlowCntrlInd));
+   RETVALUE(ROK);
+}  /* rgCFGCrgCellCfg */
+
+#ifdef LTE_ADV
+/**
+ * @brief Add SCell Cfg recvd from primary MAC instance.
+ *
+ * @details
+ *
+ *     Function : rgCfgAddUeSCellCfg
+ *
+ *     Processing Steps:
+ *      - Allocate and create UE control block.
+ *      - Update UE control block with the values recieved in the
+ *        configuration.
+ *      - If successful, add the control block to hash list of UEs for the cell
+ *        else Rollback and FAIL.
+ *
+ *  @param[in]  Inst                 dstMacInst
+ *  @param[in]  RgPrgUeSCellCfgInfo  *ueSCellCb
+ *  @param[in]  RgCellCb              cell
+
+ *  @return  S16
+ *      -# ROK
+ *      -# RFAILED
+ **/
+#ifdef ANSI
+PUBLIC S16 rgCfgAddUeSCellCfg
+(
+Inst        dstMacInst,    
+RgPrgUeSCellCfgInfo *ueSCellCb,
+RgCellCb    *cell
+)
+#else
+PUBLIC S16 rgCfgAddUeSCellCfg(dstMacInst, ueSCellCb, cell)
+Inst        dstMacInst;    
+RgPrgUeSCellCfgInfo *ueSCellCb;
+RgCellCb    *cell;
+#endif
+{
+   RgUeCb     *ueCb = NULLP;
+   SuId       rguUlSapId = 0;
+   SuId       rguDlSapId = 0;
+   U8 	     idx;
+   RgErrInfo  errInfo;
+
+   TRC2(rgCfgAddUeSCellCfg);
+   
+#ifdef LTE_ADV
+   rguDlSapId              = ueSCellCb->rguDlSapId;
+   rguUlSapId              = ueSCellCb->rguUlSapId;
+#endif
+#ifndef TENB_MULT_CELL_SUPPRT
+   if(rgCb[dstMacInst].numRguSaps > 1)
+   {
+      rguDlSapId              = 1;
+   }
+#endif
+
+   if ((ueCb = rgDBMGetUeCb(cell, ueSCellCb->ueId)) != NULLP)
+   {
+      RGDBGERRNEW(dstMacInst,(rgPBuf(dstMacInst), 
+               "[%d]Ue already exist in scell %d during scell addition\n", 
+               ueSCellCb->ueId,
+               cell->cellId));
+      RETVALUE(RFAILED);
+   }
+
+   /* Create UeCb */
+   if((ueCb = rgRAMCreateUeCb(cell, ueSCellCb->ueId,
+               FALSE, &errInfo)) == NULLP)
+   {
+      RGDBGERRNEW(dstMacInst, (rgPBuf(dstMacInst),
+               "[%d]UeCb creation failed\n", ueSCellCb->ueId));
+      RETVALUE(RFAILED);
+   }
+
+   if(rgDHMHqEntInit(dstMacInst, &ueCb->dl.hqEnt, 
+            (rgCb[dstMacInst].cell)->maxDlHqProcPerUe) != ROK)
+   {
+      RGDBGERRNEW(dstMacInst,(rgPBuf(dstMacInst), 
+               "[%d]UeCb Harq Entity Initialization failed\n", ueSCellCb->ueId));
+      RETVALUE(RFAILED);
+   }
+   rgDBMInsUeCb(cell, ueCb);
+
+
+   ueCb->rguDlSap          = &(rgCb[dstMacInst].rguSap[rguDlSapId]);
+   ueCb->rguUlSap          = &(rgCb[dstMacInst].rguSap[rguUlSapId]);
+
+   /* Update satistics */
+   rgUpdtUeCnt(dstMacInst, RG_CFG_ADD);
+   /*Commit Added SCell info to UeCb */
+   /*
+   ueCb->sCelAddInfo[idx].isSCellAdded = TRUE;
+   ueCb->sCelAddInfo[idx].macInst = dstMacInst;
+   ueCb->sCelAddInfo[idx].sCellId = ueSCellCb->cellId;
+   */
+
+   ueCb->txMode = ueSCellCb->txMode;
+   ueCb->ul.hqEnt.maxHqRetx = ueSCellCb->maxUlHqRetx;
+
+   for (idx =0; idx ul.lcCb[idx] = ueSCellCb->ulLcInfo[idx];
+      ueCb->dl.lcCb[idx] = ueSCellCb->dlLcInfo[idx];
+   }
+
+   for (idx =0; idx < RG_MAX_LCG_PER_UE; idx++)
+   {
+      ueCb->ul.lcgArr[idx].lcgId = ueSCellCb->lcgInfo[idx].lcgId;
+      ueCb->ul.lcgArr[idx].lcCount = ueSCellCb->lcgInfo[idx].lcCount;
+      ueCb->ul.lcgArr[idx].isGbr = ueSCellCb->lcgInfo[idx].isGbr;
+   }
+   RETVALUE(ROK);
+}/* rgCfgAddUeSCellCfg */
+
+/**
+ * @brief SCell Config Filling for added cell from RRC to MAC.
+ *
+ * @details
+ *
+ *     Function : rgFillAndAddSCellCfg 
+ *
+ *     Processing Steps:
+ *      - Update UE control block with the values recieved in the
+ *        configuration.
+ *      - Update UE control block with the values present in the
+ *        CellCb
+ *      - If successful, add the control block to hash list of UEs for the cell
+ *        else Rollback and FAIL.
+ *
+ *  @param[in]  Inst          inst
+ *  @param[in]  RgCellCb      *cell
+ *  @param[in]  CrgUeCfg      *ueCfg
+ *  @param[in]  CrgCfgTransId transId
+ *  @return  S16
+ *      -# ROK
+ *      -# RFAILED
+ **/
+#ifdef ANSI
+PUBLIC S16 rgFillAndAddSCellCfg
+(
+Inst            inst,
+RgCellCb        *cell,
+CrgUeRecfg      *ueRecfg,
+CrgCfgTransId   transId,
+Bool            *isCfmRqrd
+)
+#else
+PUBLIC S16 rgFillAndAddSCellCfg(inst, cell, ueRecfg, transId, isCfmRqrd)
+Inst            inst;
+RgCellCb        *cell;
+CrgUeRecfg      *ueRecfg;
+CrgCfgTransId   transId;
+Bool            *isCfmRqrd;
+#endif
+{
+   RgUeCb     *ue = NULLP;
+   U8          idx = 0;
+   Inst        dstMacInst;
+   RgPrgUeSCellCfgInfo ueSCellCb;
+   Pst          dstInstPst;
+
+   TRC2(rgFillAndAddSCellCfg);
+  
+  /* Fetch the Active cell */
+   if(((cell = rgCb[inst].cell) == NULLP) ||
+       (cell->cellId != ueRecfg->cellId))
+   {
+      RGDBGERRNEW(inst,(rgPBuf(inst), 
+                       "[%d]Active Cell does not exist %d\n",
+                                  ueRecfg->oldCrnti, ueRecfg->cellId));
+      RETVALUE(RFAILED);
+   }
+
+   RGDBGPRM(inst,(rgPBuf(inst), 
+            "Filling SCell Config : cellId %d ueId %d\n",
+            cell->cellId, cell->ueId));
+
+   if ((ue = rgDBMGetUeCb(cell, ueRecfg->oldCrnti)) == NULLP)
+   {
+      RGDBGERRNEW(inst,(rgPBuf(inst), 
+               "[%d]Ue does not exist\n", ueRecfg->oldCrnti));
+      RETVALUE(RFAILED);
+   }
+
+   /* Initialize cfgCfmInfo in the ueCb. This is used while processing SCellAdd
+    *confirmation*/
+   ue->cfgCfmInfo.numSCells = ueRecfg->crgSCellCfg.numSCells;
+   ue->cfgCfmInfo.cfgCfgCount = 0;
+   ue->cfgCfmInfo.mask = 0x0;
+
+   cmMemcpy( (U8*)&(ue->cfgCfmInfo.transId), (U8*)&transId,
+         sizeof(CrgCfgTransId));
+   ueSCellCb.ueId = ueRecfg->oldCrnti;
+   ueSCellCb.txMode = ue->txMode;
+   ueSCellCb.maxUlHqRetx = ue->ul.hqEnt.maxHqRetx;
+   cmMemcpy((U8 *)ueSCellCb.ulLcInfo, (U8 *)ue->ul.lcCb, sizeof(ue->ul.lcCb));
+   cmMemcpy((U8 *)ueSCellCb.dlLcInfo, (U8 *)ue->dl.lcCb, sizeof(ue->dl.lcCb));
+   for (idx =0; idx < RG_MAX_LCG_PER_UE; idx++)
+   {
+      ueSCellCb.lcgInfo[idx].lcgId = ue->ul.lcgArr[idx].lcgId;
+      ueSCellCb.lcgInfo[idx].lcCount = ue->ul.lcgArr[idx].lcCount;
+      ueSCellCb.lcgInfo[idx].isGbr = ue->ul.lcgArr[idx].isGbr;
+   }
+
+   for(idx = 0; 
+         idx < ueRecfg->crgSCellCfg.numSCells; idx++)
+   {
+      dstMacInst = ueRecfg->crgSCellCfg.ueSCellCfg[idx].macInst - RG_INST_START;
+      ueSCellCb.cellId = ueRecfg->crgSCellCfg.ueSCellCfg[idx].sCellId;
+      ueSCellCb.rguDlSapId = ueRecfg->crgSCellCfg.ueSCellCfg[idx].rguDlSapId;
+      ueSCellCb.rguUlSapId = ueRecfg->crgSCellCfg.ueSCellCfg[idx].rguUlSapId;
+
+      /* Get post structure of the cell to whom ueSCellCb needs to be sent
+       * And then send the sCell Add based on Mac instances */
+      rgGetPstToInst(&dstInstPst, inst, dstMacInst);
+      RgPrgPMacSMacUeSCellCfg(&dstInstPst, &ueSCellCb);
+
+      /*Commit Added SCell info to UeCb is moved to config confirm*/
+   } /*end of for loop */
+   *isCfmRqrd = FALSE;
+
+   RETVALUE(ROK);
+}  /* rgFillAndAddSCellCfg */
+#endif /* LTE_ADV */
+
+/**
+ * @brief Handler for the UE configuration request from RRC to MAC.
+ *
+ * @details
+ *
+ *     Function : rgCFGCrgUeCfg
+ *
+ *     Processing Steps:
+ *      - Allocate and create UE control block.
+ *      - Update UE control block with the values recieved in the
+ *        configuration.
+ *      - Invoke RAM, SCH, UHM and DHM with created UE control block, to
+ *        update random access, scheduler, uplink harq and downlink harq
+ *        specific information respectively.
+ *      - If successful, add the control block to hash list of UEs for the cell
+ *        else Rollback and FAIL.
+ *
+ *  @param[in]  Inst        inst
+ *  @param[in]  RgCellCb  *cell
+ *  @param[in]  CrgUeCfg  *ueCfg
+ *  @param[out] RgErrInfo *errInfo
+ *  @return  S16
+ *      -# ROK
+ *      -# RFAILED
+ **/
+#ifdef ANSI
+PUBLIC S16 rgCFGCrgUeCfg
+(
+Inst      inst,
+RgCellCb  *cell,
+CrgUeCfg  *ueCfg,
+RgErrInfo *errInfo
+)
+#else
+PUBLIC S16 rgCFGCrgUeCfg(inst,cell, ueCfg, errInfo)
+Inst      inst;
+RgCellCb  *cell;
+CrgUeCfg  *ueCfg;
+RgErrInfo *errInfo;
+#endif
+{
+   RgUeCb    *ue = NULLP;
+   Bool      handover = FALSE;
+   SuId       rguUlSapId = 0;
+   SuId       rguDlSapId = 0;
+
+   TRC2(rgCFGCrgUeCfg);
+
+   errInfo->errCause = RGERR_CFG_CRG_UE_CFG;
+
+/* Start: LTEMAC_2.1_DEV_CFG */
+   if ((ue = rgDBMGetUeCbFromRachLst(cell, ueCfg->crnti)) == NULLP)
+   {
+      /* Create UeCb and Insert in Rach List */
+      if((ue=rgRAMCreateUeCb(cell, ueCfg->crnti, FALSE, errInfo)) == NULLP)
+      {
+         RLOG_ARG0(L_ERROR,DBG_CRNTI,ueCfg->crnti,"UeCb creation failed");
+         RETVALUE(RFAILED);
+      }
+      if(rgDHMHqEntInit(inst,&ue->dl.hqEnt, cell->maxDlHqProcPerUe) != ROK)
+      {
+         RLOG_ARG0(L_ERROR,DBG_CRNTI,ueCfg->crnti,"UeCb Harq Entity Initialization failed");
+         RETVALUE(RFAILED);
+      }
+      handover = TRUE;
+   }
+/* End: LTEMAC_2.1_DEV_CFG */
+
+   if(handover == FALSE)
+   {
+      /* Remove from the rachLst */
+      rgDBMDelUeCbFromRachLst(cell, ue);
+   }
+
+
+   /* Initialize uplink HARQ related information for UE */
+   rgUHMCrgUeCfg(cell, ue, ueCfg);
+
+   rgDBMInsUeCb(cell, ue);
+
+#ifdef TENB_MULT_CELL_SUPPRT
+   rguDlSapId              = ueCfg->rguDlSapId;
+   rguUlSapId              = ueCfg->rguUlSapId;
+#else
+   if(rgCb[inst].numRguSaps > 1)
+   {
+      rguDlSapId              = 1;
+   }
+#endif
+
+   ue->rguDlSap          = &(rgCb[inst].rguSap[rguDlSapId]);
+   ue->rguUlSap          = &(rgCb[inst].rguSap[rguUlSapId]);
+
+
+   /* Update satistics */
+   rgUpdtUeCnt(inst,RG_CFG_ADD);
+   errInfo->errCause = RGERR_NONE;
+   RETVALUE(ROK);
+}  /* rgCFGCrgUeCfg */
+
+
+/**
+ * @brief Handler for the logical channel configuration request from
+ * RRC to MAC.
+ *
+ * @details
+ *
+ *     Function : rgCFGCrgLcCfg
+ *
+ *     Processing Steps:
+ *      - Check if the configuration is for dedicated or common logical channel.
+ *      - For Dedicated logical channels:
+ *        - Update the dedicated logical channel Cb with the configured values.
+ *        - Invoke SCH will cell, UE and logical channel Cb to update scheduler
+ *          specific information.
+ *      - For Common logical channels:
+ *        - Update the common logical channel Cb with the configured values.
+ *        - Move cell to active list of cells if cell becomes ACTIVE.
+ *      - If successful, return ROK else RFAILED.
+ *
+ *  @param[in]  Inst        inst
+ *  @param[in]  RgCellCb    *cell
+ *  @param[in]  RgUeCb      *ue
+ *  @param[in]  CrgLchCfg   *lcCfg
+ *  @param[out] RgErrInfo   *errInfo
+ *  @param[in]  Bool        *isCfmRqrd
+ *  @return  S16
+ *      -# ROK
+ *      -# RFAILED
+ **/
+#ifdef ANSI
+PUBLIC S16 rgCFGCrgLcCfg
+(
+Inst            inst,
+RgCellCb        *cell,
+RgUeCb          *ue,
+CrgLchCfg       *lcCfg,
+RgErrInfo       *errInfo,
+Bool            *isCfmRqrd,
+CrgCfgTransId   transId
+)
+#else
+PUBLIC S16 rgCFGCrgLcCfg(inst,cell, ue, lcCfg, errInfo, isCfmRqrd,transId)
+Inst        inst;
+RgCellCb    *cell;
+RgUeCb      *ue;
+CrgLchCfg   *lcCfg;
+RgErrInfo   *errInfo;
+Bool        *isCfmRqrd;
+CrgCfgTransId   transId;
+#endif
+{
+
+   TRC2(rgCFGCrgLcCfg);
+   
+   /* Handle Config for dedicated/common logical channels */
+   if (lcCfg->lcType == CM_LTE_LCH_DTCH || lcCfg->lcType == CM_LTE_LCH_DCCH)
+   {
+
+      if ((rgCFGCrgDedLcCfg(cell, ue, lcCfg, errInfo)) != ROK)
+      {
+         RLOG_ARG1(L_ERROR,DBG_CRNTI,lcCfg->crnti,
+               "Dedicated logical channel configuration failed %d",lcCfg->lcId);
+         RETVALUE(RFAILED);
+      }
+#ifdef LTE_ADV
+      /*ERAB Multl Cell fix*/
+       cmMemcpy( (U8*)&(ue->cfgCfmInfo.transId), (U8*)&transId,
+            sizeof(CrgCfgTransId));
+       rgPomSndUeSCellLchAddToSmac(inst, cell, ue, lcCfg,isCfmRqrd);
+#endif
+   }
+   else
+   {
+      if ((rgCFGCrgCmnLcCfg(inst,cell, lcCfg, errInfo)) != ROK)
+      {
+         RLOG_ARG1(L_ERROR, DBG_CRNTI, lcCfg->crnti, "Common logical channel configuration"
+                  "failed %d\n", lcCfg->lcId);
+         RETVALUE(RFAILED);
+      }
+   }
+
+   errInfo->errCause = RGERR_NONE;
+   RLOG_ARG1(L_INFO, DBG_CRNTI,lcCfg->crnti, "CRG LC config done for UE: lcId %d\n", lcCfg->lcId);
+   RETVALUE(ROK);
+}  /* rgCFGCrgLcCfg */
+
+
+/**
+ * @brief Handler for the cell re-configuration request from RRC to MAC.
+ *
+ * @details
+ *
+ *     Function : rgCFGCrgCellRecfg
+ *
+ *     Processing Steps:
+ *      - Invoke SCH with updated Cell Cb to update scheduler specific
+ *        parameters.
+ *      - Update the cell Cb with the reconfigured values.
+ *      - If successful, return ROK else RFAILED.
+ *
+ *  @param[in]  Inst        inst
+ *  @param[in]  RgCellCb      *cell
+ *  @param[in]  CrgCellRecfg  *cellRecfg
+ *  @param[out] RgErrInfo     *errInfo
+ *  @return  S16
+ *      -# ROK
+ *      -# RFAILED
+ **/
+#ifdef ANSI
+PUBLIC S16 rgCFGCrgCellRecfg
+(
+Inst          inst,
+RgCellCb      *cell,
+CrgCellRecfg  *cellRecfg,
+RgErrInfo     *errInfo
+)
+#else
+PUBLIC S16 rgCFGCrgCellRecfg(inst,cell, cellRecfg, errInfo)
+Inst          inst;
+RgCellCb      *cell;
+CrgCellRecfg  *cellRecfg;
+RgErrInfo     *errInfo;
+#endif
+{
+   TRC2(rgCFGCrgCellRecfg);
+
+   /* Store the given rachCfg */
+   cell->rachCfg = cellRecfg->rachRecfg;
+
+   errInfo->errCause = RGERR_NONE;
+   RETVALUE(ROK);
+}  /* rgCFGCrgCellRecfg */
+
+
+/**
+ * @brief Handler for the UE re-configuration request from RRC to MAC.
+ *
+ * @details
+ *
+ *     Function : rgCFGCrgUeRecfg
+ *
+ *     Processing Steps:
+ *      - If rnti changes,
+ *        - Invoke RAM for UE reconfiguration.
+ *        - Delete old UE from the list.
+ *        - Update the new rnti and re-insert the UE in the list.
+ *      - Update the UE control block with the reconfigured values.
+ *      - Invoke SCH, UHM and DHM with updated UE control block to 
+ *        update scheduler, uplink HARQ and downlink HARQ specific
+ *        parameters.
+ *      - If successful, return ROK else RFAILED.
+ *
+ *  @param[in]  Inst        inst
+ *  @param[in]  RgCellCb    *cell
+ *  @param[in]  RgUeCb      *ue
+ *  @param[in]  CrgUeRecfg  *ueRecfg
+ *  @param[out] RgErrInfo   *errInfo
+ *  @return  S16
+ *      -# ROK
+ *      -# RFAILED
+ **/
+#ifdef ANSI
+PUBLIC S16 rgCFGCrgUeRecfg
+(
+Inst        inst,
+RgCellCb    *cell,
+RgUeCb      *ue,
+CrgUeRecfg  *ueRecfg,
+RgErrInfo   *errInfo
+)
+#else
+PUBLIC S16 rgCFGCrgUeRecfg(inst,cell, ue, ueRecfg, errInfo)
+Inst        inst;
+RgCellCb    *cell;
+RgUeCb      *ue;
+CrgUeRecfg  *ueRecfg;
+RgErrInfo   *errInfo;
+#endif
+{
+   TRC2(rgCFGCrgUeRecfg);
+
+   errInfo->errCause = RGERR_CFG_CRG_UE_RECFG;
+
+   /* Fix : syed UE ID change at MAC will now be controlled
+    * by SCH. */
+
+   /* Update uplink HARQ related information for UE */
+   rgUHMCrgUeRecfg(cell, ue, ueRecfg);
+
+   errInfo->errCause = RGERR_NONE;
+   RETVALUE(ROK);
+}  /* rgCFGCrgUeRecfg */
+
+
+/**
+ * @brief Handler for the logical channel re-configuration request from
+ * RRC to MAC.
+ *
+ * @details
+ *
+ *     Function : rgCFGCrgLcRecfg
+ *
+ *     Processing Steps:
+ *      - Invoke scheduler to update scheduler specific information.
+ *      - Update the dedicated logical channel Cb with the re-configured
+ *        values.
+ *      - If successful, return ROK else RFAILED.
+ *
+ *  @param[in]  Inst        inst
+ *  @param[in]  RgUlCellCb  *cell
+ *  @param[in]  RgUlUeCb    *ue
+ *  @param[in]  RgUlLcCb    *ulLc
+ *  @param[in]  RgDlLcCb    *dlLc
+ *  @param[in]  CrgLchRecfg *lcRecfg
+ *  @param[out] RgErrInfo   *errInfo
+ *  @return  S16
+ *      -# ROK
+ *      -# RFAILED
+ **/
+#ifdef ANSI
+PUBLIC S16 rgCFGCrgLcRecfg
+(
+Inst        inst,
+RgCellCb    *cell,
+RgUeCb      *ue,
+RgUlLcCb    *ulLc,
+CrgLchRecfg *lcRecfg,
+RgErrInfo   *errInfo,
+Bool        *isCfmRqrd
+)
+#else
+PUBLIC S16 rgCFGCrgLcRecfg(inst,cell, ue, ulLc, lcRecfg, errInfo, isCfmRqrd)
+Inst        inst;
+RgCellCb    *cell;
+RgUeCb      *ue;
+RgUlLcCb    *ulLc;
+CrgLchRecfg *lcRecfg;
+RgErrInfo   *errInfo;
+Bool        *isCfmRqrd;
+#endif
+{
+   TRC2(rgCFGCrgLcRecfg);
+
+   if (ulLc->lcgId != lcRecfg->ulRecfg.lcgId)
+   {
+      rgDBMUpdUlDedLcCb(ue, ulLc, lcRecfg->ulRecfg.lcgId);
+#ifdef LTE_ADV
+      rgPomSndUeSCellLchModToSmac(inst, cell, ue,  lcRecfg,isCfmRqrd);
+#endif
+   }
+
+   errInfo->errCause = RGERR_NONE;
+   RETVALUE(ROK);
+}  /* rgCFGCrgLcRecfg */
+
+/* Start: LTEMAC_2.1_DEV_CFG */
+/**
+ * @brief Handler for the logical channel re-configuration request from
+ * RRC to MAC.
+ *
+ * @details
+ *
+ *     Function : rgCFGCrgUeReset
+ *
+ *     Processing Steps:
+ *
+ *  @param[in]  RgUlCellCb  *cell
+ *  @param[in]  RgUlUeCb    *ue
+ *  @param[in]  CrgRst     *reset
+ *  @param[out] RgErrInfo   *errInfo
+ *  @return  S16
+ *      -# ROK
+ *      -# RFAILED
+ **/
+#ifdef ANSI
+PUBLIC S16 rgCFGCrgUeReset
+(
+RgCellCb    *cell,
+RgUeCb      *ue,
+CrgRst     *reset,
+RgErrInfo   *errInfo
+)
+#else
+PUBLIC S16 rgCFGCrgUeReset(cell, ue, reset, errInfo)
+RgCellCb    *cell;
+RgUeCb      *ue;
+CrgRst     *reset;
+RgErrInfo   *errInfo;
+#endif
+{
+   TRC2(rgCFGCrgUeReset);
+
+   RLOG_ARG1(L_DEBUG, DBG_CRNTI, ue->ueId, "UE: of cell %d Reset\n", cell->cellId);
+   rgDHMUeReset(cell, &ue->dl.hqEnt);
+
+   errInfo->errCause = RGERR_NONE;
+
+   RETVALUE(ROK);
+}  /* rgCFGCrgUeReset */
+/* End: LTEMAC_2.1_DEV_CFG */
+
+/**
+ * @brief Handler for the cell delete request from RRC to MAC.
+ *
+ * @details
+ *
+ *     Function : rgCFGCrgCellDel
+ *
+ *     Processing Steps:
+ *      - Fetch the cell control block.
+ *      - Remove the cell control block from the hash list of cells.
+ *      - Free the cell control block.
+ *      - If successful, return ROK else return RFAILED.
+ *
+ *  @param[in]  Inst        inst
+ *  @param[in]  CrgDel      *cellDelInfo
+ *  @param[out] RgErrInfo   *errInfo
+ *  @return  S16
+ *      -# ROK
+ *      -# RFAILED
+ **/
+#ifdef ANSI
+PUBLIC S16 rgCFGCrgCellDel
+(
+Inst        inst,
+CrgDel      *cellDelInfo,
+RgErrInfo   *errInfo
+)
+#else
+PUBLIC S16 rgCFGCrgCellDel(inst,cellDelInfo, errInfo)
+Inst        inst,
+CrgDel      *cellDelInfo;
+RgErrInfo   *errInfo;
+#endif
+{
+   RgCellCb      *cell;
+   U8 idx;
+
+   TRC2(rgCFGCrgCellDel);
+
+   errInfo->errCause = RGERR_CFG_CRG_CELL_DEL;
+   if (((cell = rgCb[inst].cell) == NULLP)
+       ||(cell->cellId != cellDelInfo->u.cellDel.cellId))  
+   {
+      if(((cell = rgCb[inst].inactiveCell) == NULLP)
+          ||(cell->cellId != cellDelInfo->u.cellDel.cellId))  
+      {
+
+         
+         RLOG_ARG0(L_ERROR,DBG_CELLID,cellDelInfo->u.cellDel.cellId,"Cell does not exist");
+         RETVALUE(RFAILED);
+      }
+
+      /* Delete cell from inactive list */
+      rgCb[inst].inactiveCell = NULLP ;
+
+      /* Free the inactive cell */
+      rgCFGFreeInactvCellCb(cell);
+
+      errInfo->errCause = RGERR_NONE;
+      RETVALUE(ROK);
+   }
+
+   /* Delete from the cell list */
+   //rgDBMDelCellCb(cell);
+   for(idx=0;idx < RG_NUM_SUB_FRAMES; idx++)
+   {
+      rgTOMRlsSf(inst,&cell->subFrms[idx]);
+   }
+
+   /* Free the active cell */
+   rgCFGFreeCellCb(cell);
+
+   rgCb[inst].cell = NULLP;
+
+   errInfo->errCause    = RGERR_NONE;
+   RGDBGINFO(inst,(rgPBuf(inst), "Cell %d deleted\n", cellDelInfo->u.cellDel.cellId));
+   RETVALUE(ROK);
+}  /* rgCFGCrgCellDel */
+
+
+/**
+ * @brief Handler for the UE delete request from RRC to MAC.
+ *
+ * @details
+ *
+ *     Function : rgCFGCrgUeDel
+ *
+ *     Processing Steps:
+ *      - Fetch the UE control block.
+ *      - Remove the UE control block from the hash list of UEs for the cell.
+ *      - Free the UE control block.
+ *      - If successful, return ROK else return RFAILED.
+ *
+ *  @param[in]  Inst        inst
+ *  @param[in]  CrgDel      *ueDelInfo
+ *  @param[out] RgErrInfo   *errInfo
+ *  @return  S16
+ *      -# ROK
+ *      -# RFAILED
+ **/
+#ifdef ANSI
+PUBLIC S16 rgCFGCrgUeDel
+(
+Inst        inst,
+CrgDel      *ueDelInfo,
+RgErrInfo   *errInfo
+)
+#else
+PUBLIC S16 rgCFGCrgUeDel(inst,ueDelInfo, errInfo)
+Inst        inst;
+CrgDel      *ueDelInfo;
+RgErrInfo   *errInfo;
+#endif
+{
+   TRC2(rgCFGCrgUeDel);
+
+   errInfo->errCause = RGERR_CFG_CRG_UE_DEL;
+
+   RLOG_ARG1(L_DEBUG, DBG_CRNTI, ueDelInfo->u.ueDel.crnti, "UE %d Deletion Req at MAC\n", \
+            ueDelInfo->u.ueDel.crnti);
+   if ((rgCb[inst].cell == NULLP)
+       || (rgCb[inst].cell->cellId != ueDelInfo->u.ueDel.cellId))
+   {
+      RLOG_ARG1(L_ERROR,DBG_CRNTI,ueDelInfo->u.ueDel.crnti,"Cell does not exist %d",
+                ueDelInfo->u.ueDel.cellId);
+      RETVALUE(RFAILED);
+   }
+
+   errInfo->errCause = RGERR_NONE;
+   /* Fix: syed Context Deletion is relied upon SCH indication */
+   RETVALUE(ROK);
+}  /* rgCFGCrgUeDel */
+
+
+/**
+ * @brief Handler for the logical channel delete request from
+ * RRC to MAC.
+ *
+ * @details
+ *
+ *     Function : rgCFGCrgLcDel
+ *
+ *     Processing Steps:
+ *      - Fetch the logical channel control block.
+ *      - Free the logical channel control block.
+ *      - If successful, return ROK else return RFAILED.
+ *
+ *  @param[in]  Inst        inst
+ *  @param[in]  CrgDel      *lcDelInfo
+ *  @param[out] RgErrInfo   *errInfo
+ *  @return  S16
+ *      -# ROK
+ *      -# RFAILED
+ **/
+#ifdef ANSI
+PUBLIC S16 rgCFGCrgLcDel
+(
+Inst        inst,
+CrgDel      *lcDelInfo,
+RgErrInfo   *errInfo,
+Bool        *isCfmRqrd,
+CrgCfgTransId transId
+)
+#else
+PUBLIC S16 rgCFGCrgLcDel(inst,lcDelInfo, errInfo,isCfmRqrd,transId)
+Inst        inst;
+CrgDel      *lcDelInfo;
+RgErrInfo   *errInfo;
+CrgCfgTransId transId;
+#endif
+{
+   Bool      dirVld = FALSE;
+   RgCellCb  *cell;
+   RgUeCb    *ue;
+   RgUlLcCb  *ulLc;
+   RgDlLcCb  *dlLc;
+
+   TRC2(rgCFGCrgLcDel);
+
+   errInfo->errCause = RGERR_CFG_CRG_LC_DEL;
+
+   /* Fetch the Active cell */
+   if (((cell = rgCb[inst].cell) == NULLP) ||
+       (rgCb[inst].cell->cellId != lcDelInfo->u.lchDel.cellId))
+   {
+      RLOG_ARG1(L_ERROR,DBG_CRNTI,lcDelInfo->u.lchDel.crnti,"Cell does not exist %d",
+                lcDelInfo->u.lchDel.cellId);
+      RETVALUE(RFAILED);
+   }
+
+   /* Fetch the Ue */
+   if ((ue = rgDBMGetUeCb(cell, lcDelInfo->u.lchDel.crnti)) == NULLP)
+   {
+      RLOG_ARG0(L_ERROR,DBG_CRNTI,lcDelInfo->u.lchDel.crnti,
+                "UE does not exist for dedicated logical channel");
+      RETVALUE(RFAILED);
+   }
+
+   /* Validate downlink info */
+   if (lcDelInfo->u.lchDel.dir & CRG_DIR_TX)
+   {
+      if ((dlLc = rgDBMGetDlDedLcCb(ue, lcDelInfo->u.lchDel.lcId))
+            == NULLP)
+      {
+         RLOG_ARG1(L_ERROR,DBG_CRNTI,lcDelInfo->u.lchDel.crnti,"DL LC %d does not exist",
+                   lcDelInfo->u.lchDel.lcId);
+         RETVALUE(RFAILED);
+      }
+      rgDBMDelDlDedLcCb(ue, dlLc);
+      dirVld = TRUE;
+   }
+
+   /* Validate uplink info */
+   if (lcDelInfo->u.lchDel.dir & CRG_DIR_RX)
+   {
+      if ((ulLc = rgDBMGetUlDedLcCb(ue, lcDelInfo->u.lchDel.lcId))
+            == NULLP)
+      {
+         RLOG_ARG1(L_ERROR,DBG_CRNTI,lcDelInfo->u.lchDel.crnti,"UL LC %d does not exist",
+                   lcDelInfo->u.lchDel.lcId);
+         RETVALUE(RFAILED);
+      }
+      rgDBMDelUlDedLcCb(ue, ulLc);
+      dirVld = TRUE;
+   }
+
+   if (!dirVld)
+   {
+      RLOG_ARG1(L_ERROR,DBG_CRNTI,lcDelInfo->u.lchDel.crnti,"Invalid direction %d for LC Delete",
+            lcDelInfo->u.lchDel.dir);
+      RETVALUE(RFAILED);
+   }
+#ifdef LTE_ADV
+   /*ERAB - multicell fix*/
+   cmMemcpy( (U8*)&(ue->cfgCfmInfo.transId), (U8*)&transId,
+         sizeof(CrgCfgTransId));
+   rgPomSndUeSCellLchDelToSmac(inst, lcDelInfo, isCfmRqrd);
+#endif
+   errInfo->errCause = RGERR_NONE;
+   RETVALUE(ROK);
+}  /* rgCFGCrgLcDel */
+
+/***********************************************************
+ *
+ *     Func : rgCFGVldtCrgDedLcCfg
+ *
+ *
+ *     Desc : Validates dedicated logical channel configuration recieved from RRC.
+ *
+ *     Ret  : S16
+ *            ROK - Success
+ *            RFAILED - Failed
+ *
+ *     Notes:
+ *
+ *     File :
+ *
+ **********************************************************/
+#ifdef ANSI
+PRIVATE S16 rgCFGVldtCrgDedLcCfg
+(
+Inst          inst, 
+CrgLchCfg     *lcCfg,
+RgCellCb      **cell,
+RgUeCb        **ue,
+RgErrInfo     *errInfo
+)
+#else
+PRIVATE S16 rgCFGVldtCrgDedLcCfg(inst,lcCfg, cell, ue, errInfo)
+Inst          inst;
+CrgLchCfg     *lcCfg;
+RgCellCb      **cell;
+RgUeCb        **ue;
+RgErrInfo     *errInfo;
+#endif
+{
+   U8         dirVld   = FALSE;
+   TRC2(rgCFGVldtCrgDedLcCfg);
+
+   errInfo->errCause = RGERR_CFG_INVALID_CRG_DED_LC_CFG;
+
+   /* Fetch the Active cell */
+   if (((*cell = rgCb[inst].cell) == NULLP)
+      || ((*cell)->cellId != lcCfg->cellId))
+   {
+      RLOG_ARG1(L_ERROR,DBG_CRNTI,lcCfg->crnti,"Active Cell does not exist: Cell %d",
+                lcCfg->cellId);
+      RETVALUE(RFAILED);
+   }
+
+   /* Fetch the Ue */
+   if ((*ue = rgDBMGetUeCb(*cell, lcCfg->crnti)) == NULLP)
+   {
+      RLOG_ARG1(L_ERROR,DBG_CRNTI,lcCfg->crnti,"UE  does not exist for dedicated logical channel %d",
+                lcCfg->lcId);
+      RETVALUE(RFAILED);
+   }
+
+   /* Validate logical channel Id */
+   if ((lcCfg->lcId < RG_DEDLC_MIN_LCID)
+            ||(lcCfg->lcId > RG_DEDLC_MAX_LCID))
+   {
+      RLOG_ARG1(L_ERROR,DBG_CRNTI,lcCfg->crnti,"Invalid logical channel Id %d",
+                lcCfg->lcId);
+      RETVALUE(RFAILED);
+   }
+
+   /* Validate downlink info */
+   if (lcCfg->dir & CRG_DIR_TX)
+   {
+      if (rgDBMGetDlDedLcCb((*ue), lcCfg->lcId) != NULLP)
+      {
+         RLOG_ARG1(L_ERROR,DBG_CRNTI,lcCfg->crnti,"UE: Dedicated DL LC %d already configured",
+                    lcCfg->lcId);
+         RETVALUE(RFAILED);
+      }
+      dirVld = TRUE;
+   }
+
+   /* Validate uplink info */
+   if (lcCfg->dir & CRG_DIR_RX)
+   {
+      if (lcCfg->ulInfo.lcgId > (RG_MAX_LCG_PER_UE - 1))
+      {
+         RLOG_ARG1(L_ERROR,DBG_CRNTI,lcCfg->crnti,"UE: Invalid lcgId for uplink logical channel %d",
+                   lcCfg->ulInfo.lcgId);
+         RETVALUE(RFAILED);
+      }
+      if (rgDBMGetUlDedLcCb((*ue), lcCfg->lcId) != NULLP)
+      {
+         RLOG_ARG1(L_ERROR,DBG_CRNTI,lcCfg->crnti,"UE: Dedicated UL LC %d already configured",
+                   lcCfg->lcId);
+         RETVALUE(RFAILED);
+      }
+      dirVld = TRUE;
+   }
+
+   if (!dirVld)
+   {
+      RLOG_ARG1(L_ERROR,DBG_CRNTI,lcCfg->crnti,"Invalid Direction %d",
+               lcCfg->dir);
+      RETVALUE(RFAILED);
+   }
+
+   RETVALUE(ROK);
+}  /* rgCFGVldtCrgDedLcCfg */
+
+
+/***********************************************************
+ *
+ *     Func : rgCFGVldtCrgCmnLcCfg
+ *
+ *
+ *     Desc : Validates common logical channel configuration recieved from RRC.
+ *
+ *     Ret  : S16
+ *            ROK - Success
+ *            RFAILED - Failed
+ *
+ *     Notes:
+ *
+ *     File :
+ *
+ **********************************************************/
+#ifdef ANSI
+PRIVATE S16 rgCFGVldtCrgCmnLcCfg
+(
+Inst          inst,
+CrgLchCfg     *lcCfg,
+RgCellCb      **cell,
+RgErrInfo     *errInfo
+)
+#else
+PRIVATE S16 rgCFGVldtCrgCmnLcCfg(inst,lcCfg, cell, errInfo)
+Inst          inst;
+CrgLchCfg     *lcCfg;
+RgCellCb      **cell;
+RgErrInfo     *errInfo;
+#endif
+{
+   U8         dirVld  = FALSE;
+
+   TRC2(rgCFGVldtCrgCmnLcCfg);
+
+   errInfo->errCause = RGERR_CFG_INVALID_CRG_CMN_LC_CFG;
+
+   /* Ensure cell is not in the active list */
+   if (((*cell = rgCb[inst].cell) != NULLP)
+      && ((*cell)->cellId != lcCfg->cellId))
+   {
+      RLOG_ARG0(L_ERROR,DBG_CELLID,lcCfg->cellId,"Active Cell exists for common channels");
+      RETVALUE(RFAILED);
+   }
+
+   /* Fetch the inactive cell for common logical channels */
+   if (((*cell = rgCb[inst].inactiveCell) == NULLP)
+        || ((*cell)->cellId != lcCfg->cellId))
+   {
+      
+      RLOG_ARG0(L_ERROR,DBG_CELLID,lcCfg->cellId,"Inactive Cell does not exist for common channels");
+      RETVALUE(RFAILED);
+   }
+   /* Validate downlink info */
+   if (lcCfg->dir & CRG_DIR_TX)
+   {
+      if (lcCfg->lcType == CM_LTE_LCH_BCCH)
+      {
+         if (lcCfg->dlInfo.dlTrchType == CM_LTE_TRCH_DL_SCH)
+         {
+            if (rgDBMGetBcchOnDlsch(*cell,lcCfg->lcId) != NULLP)
+            {
+               RLOG_ARG0(L_ERROR,DBG_CELLID,lcCfg->cellId,"BCCH on DLSCH already configured for cell");
+               RETVALUE(RFAILED);
+            }
+         }
+         else if (lcCfg->dlInfo.dlTrchType == CM_LTE_TRCH_BCH)
+         {
+            if (rgDBMGetBcchOnBch(*cell) != NULLP)
+            {
+               RLOG_ARG0(L_ERROR,DBG_CELLID,lcCfg->cellId,"BCCH on BCH already configured for cell %d");
+               RETVALUE(RFAILED);
+            }
+         }
+         else
+         {
+            RLOG_ARG1(L_ERROR,DBG_CELLID,lcCfg->cellId,"Invalid transport channel %d for cell",
+                  lcCfg->dlInfo.dlTrchType);
+            RETVALUE(RFAILED);
+         }
+      }
+      else if (lcCfg->lcType == CM_LTE_LCH_PCCH)
+      {
+         if (rgDBMGetPcch(*cell) != NULLP)
+         {
+            RLOG_ARG0(L_ERROR,DBG_CELLID,lcCfg->cellId,"PCCH already configured for cell");
+            RETVALUE(RFAILED);
+         }
+      }
+      else if (RG_DLCCCH_ISCFGD(*cell))
+      {
+         RLOG_ARG0(L_ERROR,DBG_CELLID,lcCfg->cellId,"DL CCCH already configured for cell %d");
+         RETVALUE(RFAILED);
+      }
+      dirVld = TRUE;
+   }
+
+   /* Validate uplink info */
+   if (lcCfg->dir & CRG_DIR_RX)
+   {
+      /* Uplink CCCH */
+      if (lcCfg->lcType != CM_LTE_LCH_CCCH)
+      {
+         RLOG_ARG1(L_ERROR,DBG_CELLID,lcCfg->cellId,"Invalid UL common lcType %d for cell ",
+                  lcCfg->lcType);
+         RETVALUE(RFAILED);
+      }
+      if (RG_ULCCCH_ISCFGD(*cell))
+      {
+         RLOG_ARG0(L_ERROR,DBG_CELLID,lcCfg->cellId,"UL CCCH already configured for cell ");
+         RETVALUE(RFAILED);
+      }
+      dirVld = TRUE;
+   }
+
+   /* Invalid direction */
+   if (!dirVld)
+   {
+      RLOG_ARG1(L_ERROR,DBG_CELLID,lcCfg->cellId,"Invalid Direction %d", lcCfg->dir);
+      RETVALUE(RFAILED);
+   }
+
+   RETVALUE(ROK);
+}  /* rgCFGVldtCrgCmnLcCfg */
+
+/***********************************************************
+ *
+ *     Func : rgCFGCrgDedLcCfg
+ *
+ *
+ *     Desc : Handles dedicated logical channel configuration 
+ *     recieved from RRC.
+ *
+ *     Ret  : S16
+ *            ROK - Success
+ *            RFAILED - Failed
+ *
+ *     Notes:
+ *
+ *     File :
+ *
+ **********************************************************/
+#ifdef ANSI
+PRIVATE S16 rgCFGCrgDedLcCfg
+(
+RgCellCb      *cell,
+RgUeCb        *ue,
+CrgLchCfg     *lcCfg,
+RgErrInfo     *errInfo
+)
+#else
+PRIVATE S16 rgCFGCrgDedLcCfg(cell, ue, lcCfg, errInfo)
+RgCellCb      *cell;
+RgUeCb        *ue;
+CrgLchCfg     *lcCfg;
+RgErrInfo     *errInfo;
+#endif
+{
+   //Inst     inst = cell->macInst - RG_INST_START;
+   TRC2(rgCFGCrgDedLcCfg);
+
+   errInfo->errCause = RGERR_CFG_CRG_DED_LC_CFG;
+
+   /* Uplink/Bi-directional logical channel */
+   if (lcCfg->dir & CRG_DIR_RX)
+   {
+#ifdef LTE_L2_MEAS
+      rgDBMInsUlDedLcCb(ue, lcCfg->lcId, lcCfg->ulInfo.lcgId, lcCfg->qci);
+      cell->qciArray[lcCfg->qci].qci = lcCfg->qci;
+      if(lcCfg->lcType == CM_LTE_LCH_DTCH)
+      {
+        rgAddToL2MeasPerQci(cell,lcCfg->qci);/*LTE_L2_MEAS_PHASE2*/ 
+      }
+#else
+      rgDBMInsUlDedLcCb(ue, lcCfg->lcId, lcCfg->ulInfo.lcgId);
+#endif
+   }
+
+   /* Downlink/Bi-directional logical channel */
+   if (lcCfg->dir & CRG_DIR_TX)
+   {
+      rgDBMInsDlDedLcCb(ue, lcCfg->lcId);
+   }
+   RETVALUE(ROK);
+}  /* rgCFGCrgDedLcCfg */
+
+
+/***********************************************************
+ *
+ *     Func : rgCFGCrgCmnLcCfg
+ *
+ *
+ *     Desc : Handles dedicated logical channel configuration 
+ *     recieved from RRC.
+ *
+ *     Ret  : S16
+ *            ROK - Success
+ *            RFAILED - Failed
+ *
+ *     Notes:
+ *
+ *     File :
+ *
+ **********************************************************/
+#ifdef ANSI
+PRIVATE S16 rgCFGCrgCmnLcCfg
+(
+Inst          inst,
+RgCellCb      *cell,
+CrgLchCfg     *lcCfg,
+RgErrInfo     *errInfo
+)
+#else
+PRIVATE S16 rgCFGCrgCmnLcCfg(inst,cell, lcCfg, errInfo)
+Inst          inst;
+RgCellCb      *cell;
+CrgLchCfg     *lcCfg;
+RgErrInfo     *errInfo;
+#endif
+{
+   TRC2(rgCFGCrgCmnLcCfg);
+
+   errInfo->errCause = RGERR_CFG_CRG_CMN_LC_CFG;
+
+   /* Handle configuration for CCCH/BCCH/PCCH */
+   if (lcCfg->lcType == CM_LTE_LCH_CCCH)
+   {
+      /* UL and DL CCCH configuration */
+      if (lcCfg->dir & CRG_DIR_TX)
+      {
+         cell->dlCcchId = lcCfg->lcId;
+         cell->cellActvState |= RG_DL_CCCH_CFG_DONE;
+      }
+
+      if (lcCfg->dir & CRG_DIR_RX)
+      {
+         cell->ulCcchId = lcCfg->lcId;
+         cell->cellActvState |= RG_UL_CCCH_CFG_DONE;
+      }
+   }
+   else
+   {
+      if (lcCfg->lcType == CM_LTE_LCH_BCCH)
+      {
+         /* BCCH on BCH and DLSCH configuration */
+         if (lcCfg->dlInfo.dlTrchType == CM_LTE_TRCH_DL_SCH)
+         {
+            rgDBMInsBcchOnDlsch(cell, lcCfg->lcId);
+            
+            if(cell->cellActvState & RG_BCCH_DLSCH_CFG1_DONE)
+            {
+               cell->cellActvState |= RG_BCCH_DLSCH_CFG2_DONE;
+            }
+            else
+            {
+               cell->cellActvState |= RG_BCCH_DLSCH_CFG1_DONE;
+            }
+         }
+         else
+         {
+            rgDBMInsBcchOnBch(cell, lcCfg->lcId);
+            cell->cellActvState |= RG_BCCH_BCH_CFG_DONE;
+         }
+      }
+      else  /* PCCH configuration */
+      {
+         rgDBMInsPcch(cell, lcCfg->lcId);
+         cell->cellActvState |= RG_PCCH_CFG_DONE;
+      }
+   }
+
+   /* Add to active cell list if cell is active */
+   if (cell->cellActvState == RG_CELL_ACTIVE)
+   {
+      rgCb[inst].cell = cell;
+      rgCb[inst].inactiveCell = NULLP;
+      RLOG_ARG1(L_DEBUG, DBG_CELLID, cell->cellId, "Cell %d added to active list after common LC %d\
+               config\n", lcCfg->lcId);
+   }
+
+   RETVALUE(ROK);
+}  /* rgCFGCrgCmnLcCfg */
+#ifdef LTE_L2_MEAS
+/***********************************************************
+ *
+ *     Func : rgCFGFreeUeUlAlloc 
+ *
+ *
+ *     Desc :
+ *     - Processing Steps:
+ *        - Frees cell control block.
+ *
+ *     Ret  : Void
+ *
+ *     Notes:
+ *
+ *     File :
+ *
+ **********************************************************/
+#ifdef ANSI
+PRIVATE Void rgCFGFreeUeUlAlloc
+(
+RgCellCb      *cell
+)
+#else
+PRIVATE Void rgCFGFreeUeUlAlloc(cell)
+RgCellCb      *cell;
+#endif
+{
+   U8    sfIdx;
+   Inst inst = cell->macInst - RG_INST_START;
+   
+   TRC2(rgCFGFreeUeUlAlloc);
+
+   for(sfIdx = 0; sfIdx < RG_NUM_UL_SUB_FRAMES; sfIdx++)
+   {
+      if(cell->ulSf[sfIdx].ueUlAllocInfo != NULLP)
+      {
+         /*ccpu00117052 - MOD- Passing double pointer for proper
+          *                    NULLP assignment */
+         rgFreeSBuf(inst,(Data **)&(cell->ulSf[sfIdx].ueUlAllocInfo), 
+               (cell->ulSf[sfIdx].numUe * sizeof(RgUeUlAlloc)));
+      }
+   }
+}/* rgCFGFreeUeUlAlloc */
+#endif
+/***********************************************************
+ *
+ *     Func : rgCFGFreeCellCb
+ *
+ *
+ *     Desc :
+ *     - Processing Steps:
+ *        - Frees cell control block.
+ *
+ *     Ret  : Void
+ *
+ *     Notes:
+ *
+ *     File :
+ *
+ **********************************************************/
+#ifdef ANSI
+PUBLIC Void rgCFGFreeCellCb
+(
+RgCellCb      *cell
+)
+#else
+PUBLIC Void rgCFGFreeCellCb(cell)
+RgCellCb      *cell;
+#endif
+{
+   Inst inst = cell->macInst - RG_INST_START;
+   TRC2(rgCFGFreeCellCb);
+
+#ifdef LTE_ADV
+   RgLaaCellCbDeInit(cell);
+#endif
+   /* Free lists of the cell */
+#ifdef LTEMAC_SPS
+   rgCFGFreeSpsUeLst(cell);
+#endif /* LTEMAC_SPS */
+   rgCFGFreeUeLst(cell);
+   rgRAMFreeCell(cell);
+   rgCFGFreeCmnLcLst(cell);
+#ifdef LTE_L2_MEAS
+   rgCFGFreeUeUlAlloc(cell);
+#endif
+   /* ccpu00117052 - MOD - Passing double pointer for proper NULLP 
+                           assignment */
+   /* Update satistics */
+   rgUpdtCellCnt(inst,RG_CFG_DEL);
+   rgDHMFreeAllTbBufs(inst);
+
+   rgFreeSBuf(inst,(Data **)&cell->flowCntrlInd, sizeof(RguFlowCntrlInd));
+
+   /* De-allocate the Cell */
+   rgFreeSBuf(inst,(Data **)&cell, sizeof(*cell));
+ 
+
+   RGDBGINFO(inst,(rgPBuf(inst), "Cell freed\n"));
+
+  /* Stack Crash Problem for TRACE5 Changes. Added return below */
+  RETVOID; 
+}  /* rgCFGFreeCellCb */
+
+
+/***********************************************************
+ *
+ *     Func : rgCFGFreeInactvCellCb
+ *
+ *
+ *     Desc :
+ *     - Processing Steps:
+ *        - Frees inactive cell control block.
+ *
+ *     Ret  : Void
+ *
+ *     Notes:
+ *
+ *     File :
+ *
+ **********************************************************/
+#ifdef ANSI
+PUBLIC Void rgCFGFreeInactvCellCb
+(
+RgCellCb      *cell
+)
+#else
+PUBLIC Void rgCFGFreeInactvCellCb(cell)
+RgCellCb      *cell;
+#endif
+{
+   Inst      inst = cell->macInst - RG_INST_START;
+   TRC2(rgCFGFreeInactvCellCb);
+   
+   /* De-initialize the Ue list */
+   rgDBMDeInitUeCbLst(cell);
+#ifdef LTEMAC_SPS
+   rgDBMDeInitSpsUeCbLst(cell);
+#endif
+
+   rgCFGFreeCmnLcLst(cell);
+
+   rgFreeSBuf(inst, (Data **)&cell->flowCntrlInd, sizeof(RguFlowCntrlInd));
+   /*ccpu00117052 - MOD- Passing double pointer for proper
+                        NULLP assignment */
+   /* De-allocate the Cell */
+   rgFreeSBuf(inst,(Data **)&cell, sizeof(*cell));
+
+   /* Update satistics */
+   rgUpdtCellCnt(inst,RG_CFG_DEL);
+
+
+  /* Stack Crash Problem for TRACE5 Changes. Added return below */
+  RETVOID; 
+}  /* rgCFGFreeInactvCellCb */
+
+
+/***********************************************************
+ *
+ *     Func : rgCFGFreeUeCb
+ *
+ *
+ *     Desc :
+ *     - Processing Steps:
+ *        - Frees UE control block.
+ *
+ *     Ret  : Void
+ *
+ *     Notes:
+ *
+ *     File :
+ *
+ **********************************************************/
+#ifdef ANSI
+PUBLIC Void rgCFGFreeUeCb
+(
+RgCellCb    *cell,
+RgUeCb      *ue
+)
+#else
+PUBLIC Void rgCFGFreeUeCb(cell, ue)
+RgCellCb    *cell;
+RgUeCb      *ue;
+#endif
+{
+   Inst inst = cell->macInst - RG_INST_START;
+
+   TRC2(rgCFGFreeUeCb);
+
+   rgDHMFreeUe(inst,&ue->dl.hqEnt);
+
+   /* ccpu00117052 - MOD - Passing double pointer for proper NULLP
+                          assignment */
+   /* De-allocate the Ue */
+   rgFreeSBuf(inst,(Data **)&ue, sizeof(*ue));
+
+   /* Update Statistics */
+   rgUpdtUeCnt(inst,RG_CFG_DEL);
+
+
+  /* Stack Crash Problem for TRACE5 Changes. Added return below */
+  RETVOID; 
+}  /* rgCFGFreeUeCb */
+
+/***********************************************************
+ *
+ *     Func : rgCFGFreeCmnLcLst
+ *
+ *
+ *     Desc :
+ *     - Processing Steps:
+ *        - Frees common logical channels in cell control block.
+ *
+ *     Ret  : Void
+ *
+ *     Notes:
+ *
+ *     File :
+ *
+ **********************************************************/
+#ifdef ANSI
+PRIVATE Void rgCFGFreeCmnLcLst
+(
+RgCellCb      *cell
+)
+#else
+PRIVATE Void rgCFGFreeCmnLcLst(cell)
+RgCellCb      *cell;
+#endif
+{
+   TRC2(rgCFGFreeCmnLcLst);
+
+   rgDBMFreeCmnLcLst(cell);
+
+
+  /* Stack Crash Problem for TRACE5 Changes. Added return below */
+  RETVOID; 
+}  /* rgCFGFreeCmnLcLst */
+
+
+/***********************************************************
+ *
+ *     Func : rgCFGFreeUeLst
+ *
+ *
+ *     Desc :
+ *     - Processing Steps:
+ *        - Frees UE list in cell control block.
+ *
+ *     Ret  : Void
+ *
+ *     Notes:
+ *
+ *     File :
+ *
+ **********************************************************/
+#ifdef ANSI
+PRIVATE Void rgCFGFreeUeLst
+(
+RgCellCb      *cell
+)
+#else
+PRIVATE Void rgCFGFreeUeLst(cell)
+RgCellCb      *cell;
+#endif
+{
+   RgUeCb     *ue;
+
+   TRC2(rgCFGFreeUeLst);
+
+   /* Free Ues in the list */
+   while ((ue = rgDBMGetNextUeCb(cell, NULLP)) != NULLP)
+   {
+#ifdef LTE_ADV
+      rgDelUeFrmAllSCell(cell,ue);
+#endif
+      rgDBMDelUeCb(cell, ue);
+      rgCFGFreeUeCb(cell, ue);
+   }
+
+   /* De-initialize the Ue list */
+   rgDBMDeInitUeCbLst(cell);
+
+
+  /* Stack Crash Problem for TRACE5 Changes. Added return below */
+  RETVOID; 
+}  /* rgCFGFreeUeLst */
+
+#ifdef LTEMAC_SPS
+/***********************************************************
+ *
+ *     Func : rgCFGFreeSpsUeLst
+ *
+ *
+ *     Desc :
+ *     - Processing Steps:
+ *        - Frees Sps UE list in cell control block.
+ *
+ *     Ret  : Void
+ *
+ *     Notes:
+ *
+ *     File :
+ *
+ **********************************************************/
+#ifdef ANSI
+PRIVATE Void rgCFGFreeSpsUeLst
+(
+RgCellCb      *cell
+)
+#else
+PRIVATE Void rgCFGFreeSpsUeLst(cell)
+RgCellCb      *cell;
+#endif
+{
+   RgUeCb     *ue;
+
+   TRC2(rgCFGFreeSpsUeLst);
+
+   /* Free Ues in the list */
+   while ((ue = rgDBMGetNextSpsUeCb(cell, NULLP)))
+   {
+      rgDBMDelSpsUeCb(cell, ue);
+   }
+
+   /* De-initialize the Ue list */
+   rgDBMDeInitSpsUeCbLst(cell);
+
+}  /* rgCFGFreeSpsUeLst */
+
+#endif /* LTEMAC_SPS */
+
+/**
+ * @brief Function for registering cell- scheduler instance mapping
+ *
+ * @details
+ *
+ *     Function : RgSchMacCellRegReq
+ *     
+ *     This function shall be invoked whenever scheduler is done with the
+ *     cell configuration successfully.
+ *     This shall create a mapping of the cell, scheduler instance that
+ *     is serving the cell and the unique identifier of the cell on the 
+ *     scheduler at MAC. This mapping shall be used for further 
+ *     communication to the scheduler instance for this cell.
+ *     
+ *           
+ *  @param[in] Pst*                pst,
+ *  @param[in] CmLteCellId         cellId,
+ *  @param[in] RaRespReqInfo       raRespReq
+ *  @return  S16
+ *      -# ROK 
+ **/
+#ifdef ANSI
+PUBLIC S16 RgSchMacCellRegReq
+(
+Pst*                pst,
+RgInfCellReg*       regReq 
+)
+#else
+PUBLIC S16 RgSchMacCellRegReq(pst, regReq)
+Pst*                pst;
+RgInfCellReg*       regReq;
+#endif
+{
+   Inst      inst;
+   RgCellCb *cell = NULLP;
+
+   TRC3(RgSchMacCellRegReq)
+
+   RG_IS_INST_VALID(pst->dstInst);
+   inst = pst->dstInst - RG_INST_START;
+   cell = rgCb[inst].cell;
+
+   if(NULLP == regReq)
+   {
+      RETVALUE(RFAILED);
+   }
+      
+   if((cell  == NULLP) || (cell->cellId != regReq->cellId))
+   {
+      RETVALUE(RFAILED);
+   }
+   if(regReq->maxDlHqProcPerUe > RG_MAX_DL_HARQ_NUM) 
+   {
+      RETVALUE(RFAILED);
+   }
+   /* Initialize */
+   cell->schInstMap.cellSapId = regReq->cellSapId;
+   cell->schInstMap.schInst   = pst->srcInst;
+   cell->maxDlHqProcPerUe = regReq->maxDlHqProcPerUe;
+
+   RETVALUE(ROK);
+
+} /* end of RgSchMacCellRegReq */
+
+/*Added Ue for Onging L2 Meas*/
+#ifdef LTE_L2_MEAS
+/*LTE_L2_MEAS_PHASE2*/
+PUBLIC S16 rgAddToL2MeasPerQci(RgCellCb  *cell,U8 qci)
+{
+ S16      ret = ROK;	
+ CmLList   *lnk;
+ RgL2MeasCb  *measCb;
+ U16          idx;
+ 
+ lnk = cell->l2mList.first;
+  while(lnk != NULLP )
+   {
+      measCb = (RgL2MeasCb *)lnk->node;
+      if(measCb->measReq.measType & LRG_L2MEAS_AVG_PRB_PER_QCI_UL)
+      {
+	      for(idx = 0;idx< measCb->measReq.t.prbReq.numQci;idx++)
+	      {
+		      if(measCb->measReq.t.prbReq.qci[idx] == qci)
+		      {
+			      break; /*exit from for loop*/
+		      } 
+	      }	
+	      if(idx == measCb->measReq.t.prbReq.numQci)
+	      {
+		      cell->qciArray[qci].mask = TRUE; 
+		      measCb->measReq.t.prbReq.qci[measCb->measReq.t.prbReq.numQci++] = qci;
+	      }		
+      } 	  
+      lnk = lnk->next;
+   }  /* End of While*/
+ 
+		 
+       
+ RETVALUE(ret);
+}
+
+
+#endif
+
+/**********************************************************************
+ 
+         End of file
+**********************************************************************/
diff --git a/src/5gnrmac/rg_com.c b/src/5gnrmac/rg_com.c
new file mode 100755
index 000000000..9d95fecfa
--- /dev/null
+++ b/src/5gnrmac/rg_com.c
@@ -0,0 +1,838 @@
+/*******************************************************************************
+################################################################################
+#   Copyright (c) [2017-2019] [Radisys]                                        #
+#                                                                              #
+#   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.                                             #
+################################################################################
+*******************************************************************************/
+
+/************************************************************************
+ 
+     Name:     LTE-MAC layer
+  
+     Type:     C source file
+  
+     Desc:     C source code for Entry point functions
+  
+     File:     rg_com.c 
+  
+**********************************************************************/
+
+/** @file rg_com.c
+@brief This module does processing related to handling of upper interface APIs 
+invoked by RRC towards MAC.
+*/
+
+static const char* RLOG_MODULE_NAME="MAC";
+static int RLOG_FILE_ID=181;
+static int RLOG_MODULE_ID=4096;
+/* header include files -- defines (.h) */
+#include "envopt.h"        /* environment options */
+#include "envdep.h"        /* environment dependent */
+#include "envind.h"        /* environment independent */
+#include "gen.h"           /* general layer */
+#include "ssi.h"           /* system service interface */
+#include "cm_hash.h"       /* common hash list */
+#include "cm_mblk.h"       /* common memory link list library */
+#include "cm_llist.h"      /* common linked list library */
+#include "cm_err.h"        /* common error */
+#include "cm_lte.h"        /* common LTE */
+#include "lrg.h"
+#include "crg.h"
+#include "rgu.h"
+#include "tfu.h"
+#include "rg_sch_inf.h"
+#include "rg_prg.h"       /* PRG interface includes*/
+#include "rg_env.h"
+#include "rg.h"
+#include "rg_err.h"
+
+/* header/extern include files (.x) */
+#include "gen.x"           /* general layer */
+#include "ssi.x"           /* system service interface */
+#include "cm5.x"           /* common timers */
+#include "cm_lib.x"        /* common library */
+#include "cm_hash.x"       /* common hash list */
+#include "cm_mblk.x"       /* common memory link list library */
+#include "cm_llist.x"      /* common linked list library */
+#include "cm_tkns.x"       /* common tokens */
+#include "cm_lte.x"        /* common LTE */
+#include "lrg.x"
+#include "crg.x"
+#include "rgu.x"
+#include "tfu.x"
+#include "rg_sch_inf.x"
+#include "rg_prg.x"       /* PRG interface typedefs*/
+#include "rg.x"
+#ifdef LTE_ADV
+#include "rg_pom_scell.x"
+#endif
+/* local defines */
+PRIVATE S16 rgCOMHndlCfgReq ARGS((Inst inst,CrgCfg  *cfg, RgErrInfo *errInfo,Bool *isCfmRqrd,CrgCfgTransId transId));
+PRIVATE S16 rgCOMHndlRecfgReq ARGS((Inst inst,CrgRecfg *recfg, RgErrInfo *errInfo, \
+         CrgCfgTransId transId,Bool *isCfmRqrd));
+PRIVATE S16 rgCOMHndlDelReq ARGS((Inst inst,CrgDel *del, RgErrInfo *errInfo, Bool *isCfmRqrd, CrgCfgTransId transId));
+PRIVATE S16 rgCOMHndlResetReq ARGS((Inst inst,CrgRst *reset,RgErrInfo *errInfo));
+/* local typedefs */
+ 
+/* local externs */
+ 
+/* forward references */
+
+/**
+ * @brief Handler to handle config request from RRC to MAC.
+ *
+ * @details
+ *
+ *     Function: rgCOMCfgReq
+ *     
+ *     This API handles processing for config request from RRC to MAC. 
+ *     
+ *     Processing Steps:
+ *      - If configuration, process configuration request. Call rgCOMHndlCfgReq.
+ *      - else If re-configuration, process re-configuration request. 
+ *        Call rgCOMHndlRecfgReq.
+ *      - else If reset, process reset request. Call rgCOMHndlResetReq.
+ *      - else If delete, process delete request. Call rgCOMHndlDelReq.
+ *      - If successful, send confirmation to RRC. Call rgUIMCrgCfgCfm.
+ *      - If failed, FAIL.
+ *
+ *  @param[in]  Inst        inst
+ *  @param[in]  CrgCfgTransId transId
+ *  @param[in]  CrgCfgReqInfo *crgCfgReq
+ *  @return  S16
+ *      -# ROK 
+ *      -# RFAILED 
+ **/
+#ifdef ANSI
+PUBLIC S16 rgCOMCfgReq
+(
+Inst          inst,
+CrgCfgTransId transId,
+CrgCfgReqInfo *crgCfgReq
+)
+#else
+PUBLIC S16 rgCOMCfgReq(inst,transId, crgCfgReq)
+Inst          inst;
+CrgCfgTransId transId;
+CrgCfgReqInfo *crgCfgReq;
+#endif
+{
+   S16             ret;
+   U8              cfmStatus = CRG_CFG_CFM_OK;
+   RgErrInfo       errInfo;
+   Bool            isCfmRqrd = TRUE;
+
+   TRC2(rgCOMCfgReq);
+
+   /* Process Config/Reconfig/Delete request from RRC */
+   switch (crgCfgReq->action)
+   {
+      case CRG_CONFIG:
+         {
+            ret = rgCOMHndlCfgReq(inst,&crgCfgReq->u.cfgInfo, &errInfo,&isCfmRqrd, transId);
+            break;
+         }
+      case CRG_RECONFIG:
+         {
+            ret = rgCOMHndlRecfgReq(inst,&crgCfgReq->u.recfgInfo, &errInfo, transId, &isCfmRqrd);
+            break;
+         }
+         /* Start: LTEMAC_2.1_DEV_CFG */
+      case CRG_RESET:
+         {
+            ret = rgCOMHndlResetReq(inst,&crgCfgReq->u.rstInfo, &errInfo);
+            break;
+         }
+         /* End: LTEMAC_2.1_DEV_CFG */
+      case CRG_DELETE:
+         {
+            ret = rgCOMHndlDelReq(inst,&crgCfgReq->u.delInfo, &errInfo, &isCfmRqrd, transId);
+            break;
+         }
+      default:
+         {
+            RLOG1(L_ERROR, "Invalid configuration action %d",
+                     crgCfgReq->action);
+
+            ret = RFAILED;
+         }
+   }
+
+   if (ret != ROK)
+   {
+      cfmStatus = CRG_CFG_CFM_NOK;
+   }
+
+   /* When UeSCellCfg is present then confirmation will be sent later once
+      confirm from all SMAC are recved at PMAC. PMAC will send a consolidated
+      confirm to RRC.Handling the failure of PMAC for Ue Scell add*/
+#ifdef LTE_ADV
+if(TRUE == isCfmRqrd)
+   {
+#endif
+      /* Send back confirmation status to RRC */
+      rgUIMCrgCfgCfm(inst,transId, cfmStatus); 
+#ifdef LTE_ADV
+   }
+#endif
+   RGDBGINFO(inst,(rgPBuf(inst), "CRG Configuration request processed\n"));
+   RETVALUE(ret);
+}  /* rgCOMCfgReq */
+/**
+ * @brief Handler for processing Cell/Ue/Logical channel configuration request
+ * recieved from RRC.
+ *
+ * @details
+ *
+ *     Function: rgCOMHndlCfgReq
+ *     
+ *     This API handles processing of configuration request from RRC to MAC. 
+ *     
+ *     Processing Steps:
+ *        - Validate configuration request parameters at CFG module. 
+ *          Call rgCFGVldtCrgCellCfg, rgCFGVldtCrgUeCfg, rgCFGVldtCrgLcCfg 
+ *          for Cell, UE and Logical channel configuration respectively.
+ *        - If validated successfully, Call rgCFGCrgCellCfg, rgCFGCrgUeCfg, 
+ *          rgCFGCrgLcCfg for Cell, UE and Logical channel configuration 
+ *          respectively, else FAIL.
+ *
+ *  @param[in]  Inst        inst
+ *  @param[in]  CrgCfg    *cfg
+ *  @param[out] RgErrInfo *errInfo
+ *  @return  S16
+ *      -# ROK 
+ *      -# RFAILED 
+ **/
+#ifdef ANSI
+PRIVATE S16 rgCOMHndlCfgReq
+(
+Inst             inst,
+CrgCfg           *cfg,
+RgErrInfo        *errInfo,
+Bool             *isCfmRqrd,
+CrgCfgTransId    transId
+)
+#else
+PRIVATE S16 rgCOMHndlCfgReq(inst,cfg, errInfo,isCfmRqrd,transId)
+Inst            inst;
+CrgCfg          *cfg;
+RgErrInfo       *errInfo;
+Bool            *isCfmRqrd;
+CrgCfgTransId   transId;
+#endif
+{
+   S16       ret;
+   RgCellCb  *cell = NULLP;
+   RgUeCb    *ue   = NULLP;
+
+   TRC2(rgCOMHndlCfgReq);
+
+   errInfo->errType = RGERR_COM_CFG_REQ;
+
+   /* Validate and process the configuration request */ 
+   switch (cfg->cfgType)
+   {
+      case CRG_CELL_CFG:
+      {
+         ret = rgCFGVldtCrgCellCfg(inst,&cfg->u.cellCfg,errInfo);
+         if (ret != ROK)
+         {
+              RLOG_ARG0(L_ERROR,DBG_CELLID,cfg->u.cellCfg.cellId, "Cell configuration validation FAILED\n");
+              RETVALUE(RFAILED);
+         }
+         ret = rgCFGCrgCellCfg(inst,&cfg->u.cellCfg, errInfo);
+         break;
+      }
+      case CRG_UE_CFG:
+      {
+         {
+            ret = rgCFGVldtCrgUeCfg(inst,&cfg->u.ueCfg, &cell, errInfo);
+            if (ret != ROK)
+            {
+               RLOG_ARG0(L_ERROR,DBG_CRNTI,cfg->u.ueCfg.crnti, "Ue configuration validation FAILED\n");
+               RETVALUE(RFAILED);
+            }
+            ret = rgCFGCrgUeCfg(inst,cell, &cfg->u.ueCfg, errInfo);
+         }
+         break;
+      }
+      case CRG_LCH_CFG:
+      {
+
+         ret = rgCFGVldtCrgLcCfg(inst,&cfg->u.lchCfg, &cell, &ue,errInfo);
+         if (ret != ROK)
+         {
+            
+            RLOG_ARG1(L_ERROR,DBG_CELLID,cfg->u.cellCfg.cellId,
+                         "LC configuration validation FAILED: LC %d\n", cfg->u.lchCfg.lcId);
+            RETVALUE(RFAILED);
+         }
+         ret = rgCFGCrgLcCfg(inst,cell, ue, &cfg->u.lchCfg, errInfo,isCfmRqrd,transId);
+         break;
+      }
+      default:
+      {
+         RLOG1(L_ERROR, "Should never come here: cfgType %d",cfg->cfgType);
+         RETVALUE(RFAILED);
+      }
+   }
+
+   RETVALUE(ret);
+}  /* rgCOMHndlCfgReq */
+
+
+/**
+ * @brief Handler for processing Cell/Ue/Logical channel re-configuration request
+ * recieved from RRC.
+ *
+ * @details
+ *
+ *     Function: rgCOMHndlRecfgReq
+ *     
+ *     This API handles processing of reconfiguration request from RRC to MAC. 
+ *     
+ *     Processing Steps:
+ *      - Validate reconfiguration request parameters at CFG module. Call 
+ *        rgCFGVldtCrgCellRecfg, rgCFGVldtCrgUeRecfg, rgCFGVldtCrgLchRecfg for 
+ *        Cell, UE and logical channel reconfiguration respectively.
+ *      - If validated, Call rgCFGCrgCellRecfg, rgCFGCrgUeRecfg, 
+ *        rgCFGCrgLchRecfg for Cell, UE and Logical channel re-configuration 
+ *        respectively else FAIL.
+ *
+ *  @param[in]  Inst        inst
+ *  @param[in]  CrgRecfg   *recfg
+ *  @param[out] RgErrInfo  *errInfo
+ *  @return  S16
+ *      -# ROK 
+ *      -# RFAILED 
+ **/
+#ifdef ANSI
+PRIVATE S16 rgCOMHndlRecfgReq
+(
+Inst             inst,
+CrgRecfg         *recfg,
+RgErrInfo        *errInfo,
+CrgCfgTransId    transId,
+Bool             *isCfmRqrd
+)
+#else
+PRIVATE S16 rgCOMHndlRecfgReq(inst,recfg, errInfo, transId, isCfmRqrd)
+Inst            inst;
+CrgRecfg        *recfg;
+RgErrInfo       *errInfo;
+CrgCfgTransId   transId;
+Bool            *isCfmRqrd;
+#endif
+{
+   S16       ret;
+   RgCellCb  *cell = rgCb[inst].cell;
+   RgUeCb    *ue   = NULLP;
+   RgUlLcCb  *ulLc = NULLP;
+
+   TRC2(rgCOMHndlRecfgReq);
+
+   errInfo->errType = RGERR_COM_RECFG_REQ;
+   
+   /* Validate and process the re-configuration request */ 
+   switch (recfg->recfgType)
+   {
+      case CRG_CELL_CFG:
+      {
+         ret = rgCFGVldtCrgCellRecfg(inst,&recfg->u.cellRecfg, &cell, errInfo);
+            if (ret != ROK) 
+            {
+               RLOG_ARG0(L_ERROR,DBG_CELLID,recfg->u.cellRecfg.cellId,
+                         "Cell Recfg Validation FAILED");
+               RETVALUE(RFAILED);
+            }
+         ret = rgCFGCrgCellRecfg(inst,cell, &recfg->u.cellRecfg, errInfo);
+         break;
+      }
+      case CRG_UE_CFG:
+      {
+         /*ccpu00126865 - Added as a part of RRC Reestablishment issue with MAC
+          * having a possibility of sending NOK */
+         if (recfg->u.ueRecfg.oldCrnti != recfg->u.ueRecfg.newCrnti)
+         {
+            errInfo->errCause = RGERR_CFG_INVALID_CRG_UE_RECFG;
+            ret = ROK;
+         }    
+         else
+         {
+#ifdef LTE_ADV
+         /* Check for isSCellCfgPres */
+         if(TRUE == recfg->u.ueRecfg.crgSCellCfg.isSCellCfgPres)
+         {
+            ret = rgFillAndAddSCellCfg(inst, cell, &recfg->u.ueRecfg, transId, isCfmRqrd);
+            if (ret != ROK)
+            {
+               RGDBGERRNEW(inst,(rgPBuf(inst), "[%d]Ue SCell configuration FAILED for inst [%d]\n",
+                        recfg->u.ueRecfg.oldCrnti, inst));
+               RETVALUE(RFAILED);
+            }
+
+         }
+         else
+         {
+#endif /* LTE_ADV */
+            ret = rgCFGVldtCrgUeRecfg(inst,&recfg->u.ueRecfg, &cell, &ue, errInfo);
+            if ( ret != ROK)
+            {
+               RLOG_ARG1(L_ERROR,DBG_CELLID,recfg->u.ueRecfg.cellId,
+                      "Ue Re-configuration validation FAILED OLD CRNTI:%d",
+                      recfg->u.ueRecfg.oldCrnti);
+               RETVALUE(RFAILED);
+            }
+            ret = rgCFGCrgUeRecfg(inst,cell, ue, &recfg->u.ueRecfg, errInfo);
+         }
+#ifdef LTE_ADV
+         }
+#endif
+         break;
+      }
+      case CRG_LCH_CFG:
+      {
+         ret = rgCFGVldtCrgLcRecfg(inst,&recfg->u.lchRecfg, &cell, &ue, 
+               &ulLc, errInfo);
+         if (ret != ROK)
+         {
+            RLOG_ARG2(L_ERROR,DBG_CELLID,recfg->u.lchRecfg.cellId,
+                      "LC Re-configuration validation FAILED LCID:%d CRNTI:%d",
+                      recfg->u.lchRecfg.lcId,recfg->u.lchRecfg.crnti);
+            RETVALUE(RFAILED);
+         }
+
+#ifdef LTE_ADV
+         /*ERAB- multicell fix*/
+         cmMemcpy( (U8*)&(ue->cfgCfmInfo.transId), (U8*)&transId,
+               sizeof(CrgCfgTransId));
+#endif
+         ret = rgCFGCrgLcRecfg(inst,cell, ue, ulLc,
+               &recfg->u.lchRecfg, errInfo,isCfmRqrd);
+
+         break;
+      }
+      default:
+      {
+         RLOG1(L_ERROR, "Should never come here: recfgType %d",
+                  recfg->recfgType);
+         RETVALUE(RFAILED);
+      }
+   }
+
+   RETVALUE(ret);
+}  /* rgCOMHndlRecfgReq */
+
+/*Start: LTEMAC_2.1_DEV_CFG */
+/**
+ * @brief Handler for processing UE Reset request recieved from RRC.
+ *
+ * @details
+ *
+ *     Function: rgCOMHndlResetReq
+ *     
+ *     This API handles processing of Reset request from RRC to MAC. 
+ *     
+ *     Processing Steps:
+ *      - Validate reset request parameters at CFG module. Call 
+ *        rgCFGVldtCrgUeReset for UE reset.
+ *      - If validated, Call rgCFGCrgUeReset for UE reset, else FAIL.
+ *
+ *  @param[in]  Inst        inst
+ *  @param[in]  CrgRst     *reset
+ *  @param[out] RgErrInfo  *errInfo
+ *  @return  S16
+ *      -# ROK 
+ *      -# RFAILED 
+ **/
+#ifdef ANSI
+PRIVATE S16 rgCOMHndlResetReq
+(
+Inst       inst,
+CrgRst     *reset,
+RgErrInfo  *errInfo
+)
+#else
+PRIVATE S16 rgCOMHndlResetReq(inst,reset, errInfo)
+Inst       inst;
+CrgRst     *reset;
+RgErrInfo  *errInfo;
+#endif
+{
+   TRC2(rgCOMHndlResetReq);
+
+   /* Fix : ccpu00126865: ignore CRG reset. Let SCH trigger it. */
+   
+   errInfo->errCause = RGERR_NONE;
+   RGDBGINFO(inst,(rgPBuf(inst), "CRG UE Reset processed \n"));
+   RETVALUE(ROK);
+}  /* rgCOMHndlResetReq */
+/*End: LTEMAC_2.1_DEV_CFG */
+
+/**
+ * @brief Handler for processing Cell/UE/Logical channel delete request
+ * recieved from RRC.
+ *
+ * @details
+ *
+ *     Function: rgCOMHndlDelReq
+ *     
+ *     This API handles processing of delete request from RRC to MAC. 
+ *     
+ *     Processing Steps:
+ *        - Fetch corresponding control block and pass it to CFG module.
+ *        - If control block does not exist, FAIL.
+ *
+ *  @param[in]  Inst        inst
+ *  @param[in]  CrgDel    *del
+ *  @param[out] RgErrInfo *errInfo
+    @param[out] Bool      *isCfmRqrd
+ *  @return  S16
+ *      -# ROK 
+ *      -# RFAILED 
+ **/
+#ifdef ANSI
+PRIVATE S16 rgCOMHndlDelReq
+(
+Inst        inst,
+CrgDel      *del,
+RgErrInfo   *errInfo,
+Bool        *isCfmRqrd,
+CrgCfgTransId transId
+)
+#else
+PRIVATE S16 rgCOMHndlDelReq(inst,del, errInfo,isCfmRqrd,transId)
+Inst        inst;
+CrgDel      *del;
+RgErrInfo   *errInfo;
+Bool        *isCfmRqrd;
+CrgCfgTransId transId;
+#endif
+{
+
+   S16            ret;
+   VOLATILE U32   startTime=0;
+
+   TRC2(rgCOMHndlDelReq);
+   
+   errInfo->errType = RGERR_COM_DEL_REQ;
+   
+   /* Process the delete request */ 
+   switch (del->delType)
+   {
+      case CRG_CELL_CFG:
+      {
+         ret = rgCFGCrgCellDel(inst,del, errInfo);
+         break;
+      }
+      case CRG_UE_CFG:
+      {
+         /*starting Task*/ 
+         SStartTask(&startTime,PID_MAC_UE_DEL);
+
+
+         ret = rgCFGCrgUeDel(inst,del, errInfo);
+         RGDBGINFONEW(inst,(rgPBuf(inst),"[%d] Delete UE Done \n", del->u.ueDel.crnti));
+
+         /*stoping Task*/ 
+         SStopTask(startTime,PID_MAC_UE_DEL);
+
+         break;
+      }
+      case CRG_LCH_CFG:
+      {
+         ret = rgCFGCrgLcDel(inst,del, errInfo,isCfmRqrd, transId);
+         break;
+      }
+      default:
+      {
+         RLOG1(L_ERROR, "Should never come here: delType %d",
+                  del->delType);
+         RETVALUE(RFAILED);
+      }
+   }
+
+   RETVALUE(ret);
+}  /* rgCOMHndlDelReq */
+
+#ifdef LTE_ADV
+/**
+ * @brief Handler for the SCell configuration request from RRC to MAC.
+ *
+ * @details
+ *
+ *     Function : RgPrgPMacSMacUeSCellCfgReq
+ *
+ *     Processing Steps:
+ *      - Allocate and create UE control block.
+ *      - Update UE control block with the values recieved in the
+ *        configuration.
+ *      - If successful, add the control block to hash list of UEs for the cell
+ *        else Rollback and FAIL.
+ *
+ *  @param[in]  Pst          *pst
+ *  @param[in]  RgPrgUeSCellCfgInfo *ueSCellCb
+ *  @return  S16
+ *      -# ROK
+ *      -# RFAILED
+ **/
+#ifdef ANSI
+PUBLIC S16 RgPrgPMacSMacUeSCellCfgReq
+(
+Pst         *pst,    
+RgPrgUeSCellCfgInfo *ueSCellCb
+)
+#else
+PUBLIC S16 RgPrgPMacSMacUeSCellCfgReq(pst, ueSCellCb)
+Pst         *pst;    
+RgPrgUeSCellCfgInfo *ueSCellCb;
+#endif
+{
+   RgPrgCfgCfmInfo  cfgCfm;
+   Inst             inst = pst->dstInst;
+   RgCellCb         *cell = rgCb[inst].cell;
+   S16              ret;
+   Pst              cfmPst;    
+
+   TRC2(RgPrgPMacSMacUeSCellCfgReq);
+   
+   RGDBGPRM(inst,(rgPBuf(inst),
+            "APPLYING CRG UE SCELL CONFIG: cellId %d ueId %d\n",
+            ueSCellCb->cellId, ueSCellCb->ueId));
+
+   cfgCfm.ueId = ueSCellCb->ueId;
+   cfgCfm.sCellId = ueSCellCb->cellId;
+   cfgCfm.status = PRG_CFG_CFM_OK;
+   cfgCfm.event = EVTPRGUESCELLCFGCFM;
+   rgGetPstToInst(&cfmPst, inst, pst->srcInst);
+
+  ret = rgUtlVltdAddSCellCfg(ueSCellCb, cell, inst);
+  if(ret != ROK)
+  {
+     RGDBGERRNEW(inst,(rgPBuf(inst), "[%d]Crg Ue SCell failed:\
+              cellId %d\n", ueSCellCb->ueId, ueSCellCb->cellId));
+     /* Set status as Not OK*/
+     cfgCfm.status = PRG_CFG_CFM_NOK;
+  }
+  else
+  {
+     ret = rgCfgAddUeSCellCfg(inst, ueSCellCb, cell);
+     if(ret != ROK)
+     {
+        RGDBGERRNEW(inst,(rgPBuf(inst), "[%d]Crg Ue SCell failed:\
+                 cellId %d\n", ueSCellCb->ueId, ueSCellCb->cellId));
+        /* Set status as Not OK*/
+        cfgCfm.status = PRG_CFG_CFM_NOK;
+     }
+  }
+  
+  RGDBGINFONEW(inst,(rgPBuf(inst), "[%d]Crg Ue SCell Config done:\
+           cellId %d\n", ueSCellCb->ueId, ueSCellCb->cellId));
+
+  /* Send positive confirmation to primary cell*/
+  RgPrgSMacPMacCfg(&cfmPst, &cfgCfm);
+  RETVALUE(ROK);
+}  /* RgPrgPMacSMacUeSCellCfgReq */
+
+/**
+ * @brief Hander for config confim from sec MAC to Pri mac for Add Scell Cfg.
+ *
+ * @details
+ *
+ *     Function : RgPrgSMacPMacCfgCfm
+ *
+ *     Processing Steps:
+ *      - Allocate and create UE control block.
+ *      - If cfm event is lch recfg then send the confirmation to RRC for
+ *        that event.
+ *      - If cfm event is Scell addition then send the confirmation to RRC for
+ *        the same.
+ *         - Update UE control block with the values received in the
+ *           configuration.
+ *         - If successful, add the control block to hash list of UEs for the cell
+ *           else Rollback and FAIL.
+ *
+ *  @param[in]  Inst        dstMacInst
+ *  @param[in]  RgUrSCellCb  *ueSCellCb
+ *  @return  S16
+ *      -# ROK
+ *      -# RFAILED
+ **/
+#ifdef ANSI
+PUBLIC S16 RgPrgSMacPMacCfgCfm
+(
+Pst             *pst,    
+RgPrgCfgCfmInfo *cfgCfm
+)
+#else
+PUBLIC S16 RgPrgSMacPMacCfgCfm(pst, cfgCfm)
+Pst             *pst;    
+RgPrgCfgCfmInfo *cfgCfm;
+#endif
+{
+   Inst      inst = pst->dstInst;
+   RgCellCb *cell;
+   RgUeCb   *ue;
+   TRC2(RgPrgSMacPMacCfgCfm);
+
+
+   RG_IS_INST_VALID(inst);
+
+   RGDBGPRM(pst->dstInst,(rgPBuf(pst->dstInst),
+            "Config Confirm Rcvd from Inst %d ueId %d cellId %d\n",
+            pst->srcInst, cfgCfm->ueId, cfgCfm->cellId));
+
+   cell = rgCb[inst].cell;
+
+   if ((ue = rgDBMGetUeCb(cell, cfgCfm->ueId)) == NULLP)
+   {
+      RGDBGERRNEW(inst,(rgPBuf(inst), 
+               "[%d]Ue does not exist\n", cfgCfm->ueId));
+      RETVALUE(RFAILED);
+   }
+   switch(cfgCfm->event)
+   {
+      /* cfgCount increment for all cases */
+      case EVTPRGUESCELLLCHMODCFM:
+      case EVTPRGUESCELLLCHDELCFM:
+      case EVTPRGUESCELLLCHADDCFM:
+         {
+            ue->cfgCfmInfo.cfgCfgCount++;
+            ue->cfgCfmInfo.mask |= cfgCfm->status;
+            if(ue->cfgCfmInfo.numSCells == ue->cfgCfmInfo.cfgCfgCount)
+            {
+               ue->cfgCfmInfo.cfgCfgCount = 0;
+               /* Send back confirmation status to RRC */
+               rgUIMCrgCfgCfm(inst, ue->cfgCfmInfo.transId, ue->cfgCfmInfo.mask);
+               ue->cfgCfmInfo.mask = 0;
+               RGDBGINFO(inst,(rgPBuf(inst), "CRG Configuration request processed\n"));
+            }
+         }
+         break;
+      case EVTPRGUESCELLCFGCFM:
+         {
+            /*Commit Added SCell info to UeCb as we confirmation received */
+            if(PRG_CFG_CFM_OK == cfgCfm->status)
+            {
+               ue->sCelInfo[pst->srcInst].isSCellAdded = TRUE;
+               ue->sCelInfo[pst->srcInst].macInst = pst->srcInst;
+               ue->sCelInfo[pst->srcInst].sCellId = cfgCfm->sCellId;
+            }
+
+            ue->cfgCfmInfo.cfgCfgCount++;
+            ue->cfgCfmInfo.mask |= cfgCfm->status;
+            if(ue->cfgCfmInfo.numSCells == ue->cfgCfmInfo.cfgCfgCount)
+            {
+               ue->cfgCfmInfo.cfgCfgCount = 0;
+               /* Send back confirmation status to RRC */
+               rgUIMCrgCfgCfm(inst, ue->cfgCfmInfo.transId, ue->cfgCfmInfo.mask);
+               ue->cfgCfmInfo.mask = 0;
+               RGDBGINFO(inst,(rgPBuf(inst), "CRG Configuration request processed\n"));
+            }
+         }
+         break;
+      default:
+         {
+            RGDBGERRNEW(inst,(rgPBuf(inst), "Invalid configuration confirm event %d\n",
+                     cfgCfm->event));
+
+            RETVALUE(RFAILED);
+         }
+
+   }
+   RETVALUE(ROK);
+}  /* RgPrgSMacPMacCfgCfm */
+
+/**
+ * @brief Function for handling UE release for SCELL
+ * triggered from Primary Cell
+ *
+ * @details
+ *
+ *     Function : RgPrgPMacSMacUeSCellDelReq
+ *     
+ *        - This Function should be invoked by PCell of UE
+ *        - Remove the UE context from SCELL corresponding to rnti.
+ *           
+ *  @param[in] Pst                 *pst
+ *  @param[in] RgPrgUeSCellDelInfo *ueSCellDelInfo
+ *  @return  ROK is SUCCESS 
+ **/
+#ifdef ANSI
+PUBLIC S16 RgPrgPMacSMacUeSCellDelReq
+(
+Pst                 *pst,
+RgPrgUeSCellDelInfo *ueSCellDelInfo
+)
+#else
+PUBLIC S16 RgPrgPMacSMacUeSCellDelReq(pst, ueSCellDelInfo)
+Pst                 *pst;
+RgPrgUeSCellDelInfo *ueSCellDelInfo;
+#endif
+{
+   Inst        inst     = pst->dstInst - RG_INST_START;
+   RgCellCb    *sCell   = rgCb[inst].cell;
+   RgUeCb      *sCellUe = NULLP;
+
+   TRC2(RgPrgPMacSMacUeSCellDelReq)
+
+   /* Checking for cell Cb because in case of shutdownReq it is possible that
+    * cell is already deleted for this cell*/
+   if(sCell == NULLP)
+   {
+      RETVALUE(ROK);
+   }
+   /* Retrive the UeCb from sec cell*/
+   if ((sCellUe = rgDBMGetUeCb(sCell, ueSCellDelInfo->ueId)) == NULLP)
+   {
+      RGDBGERRNEW(inst, (rgPBuf(inst), "[%d]UE:does not exist in sCell(%d)\n",
+               ueSCellDelInfo->ueId, sCell->cellId));
+      RETVALUE(RFAILED);
+   }
+   
+   /*PMAC_Reest: ueId and newRnti is different that means its a UeId change
+    *request from PMAC to SMAC during PCell reestablishment
+    */
+  if(ueSCellDelInfo->ueId != ueSCellDelInfo->newRnti)
+  {
+     /* Retrive the UeCb from sec cell*/
+     if ((rgDBMGetUeCb(sCell, ueSCellDelInfo->newRnti)) != NULLP)
+     {
+        RGDBGERRNEW(inst, (rgPBuf(inst), "[%d]UE:UE context already exist in\
+                 sCell(%d)",ueSCellDelInfo->newRnti, sCell->cellId));
+        RETVALUE(RFAILED);
+     }
+
+     rgDBMDelUeCb(sCell, sCellUe);
+
+     sCellUe->ueId = ueSCellDelInfo->newRnti;
+
+     /* Reset harq procs*/
+     rgDHMUeReset(sCell, &sCellUe->dl.hqEnt);
+
+     rgDBMInsUeCb(sCell, sCellUe);
+  }
+  else
+  {
+     rgDBMDelUeCb(sCell, sCellUe);
+     rgCFGFreeUeCb(sCell, sCellUe);
+  }
+
+   RETVALUE(ROK);
+} /* RgPrgPMacSMacUeSCellDelReq */
+#endif /*LTE_ADV */
+/**********************************************************************
+ 
+         End of file
+**********************************************************************/
diff --git a/src/5gnrmac/rg_dbm.c b/src/5gnrmac/rg_dbm.c
new file mode 100755
index 000000000..936d4d0f3
--- /dev/null
+++ b/src/5gnrmac/rg_dbm.c
@@ -0,0 +1,1433 @@
+/*******************************************************************************
+################################################################################
+#   Copyright (c) [2017-2019] [Radisys]                                        #
+#                                                                              #
+#   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.                                             #
+################################################################################
+*******************************************************************************/
+
+/************************************************************************
+ 
+     Name:     LTE-MAC layer
+  
+     Type:     C source file
+  
+     Desc:     C source code for Entry point fucntions
+  
+     File:     rg_dbm.c
+  
+**********************************************************************/
+
+/** @file rg_dbm.c
+@brief This file contains the APIs exposed for the insertion/fetching/deletion of cellCb/ueCb and traversal of LcCbLst.
+*/
+
+/* header include files -- defines (.h) */
+#include "envopt.h"        /* environment options */
+#include "envdep.h"        /* environment dependent */
+#include "envind.h"        /* environment independent */
+#include "gen.h"           /* general layer */
+#include "ssi.h"           /* system service interface */
+#include "cm_hash.h"       /* common hash list */
+#include "cm_mblk.h"       /* common memory link list library */
+#include "cm_llist.h"      /* common linked list library */
+#include "cm_err.h"        /* common error */
+#include "cm_lte.h"        /* common LTE */
+#include "lrg.h"
+#include "crg.h"
+#include "rgu.h"
+#include "tfu.h"
+#include "rg_sch_inf.h"
+#include "rg_env.h"
+#include "rg.h"
+
+/* header/extern include files (.x) */
+#include "gen.x"           /* general layer */
+#include "ssi.x"           /* system service interface */
+#include "cm5.x"           /* common timers */
+#include "cm_lib.x"        /* common library */
+#include "cm_hash.x"       /* common hash list */
+#include "cm_mblk.x"       /* common memory link list library */
+#include "cm_llist.x"      /* common linked list library */
+#include "cm_tkns.x"       /* common tokens */
+#include "cm_lte.x"        /* common LTE */
+#include "lrg.x"
+#include "crg.x"
+#include "rgu.x"
+#include "tfu.x"
+#include "rg_sch_inf.x"
+#include "rg_prg.x"       /* PRG interface typedefs*/
+#include "rg.x"
+
+
+/* local defines */
+PRIVATE S16 rgDBMInitUeCbLst ARGS(( RgCellCb *cellCb, U16 numBins));
+PRIVATE Void rgDBMInitDedLcLst ARGS((RgUeCb *ueCb));
+PRIVATE Void rgDBMInitCmnLcLst ARGS((RgCellCb *cellCb));
+PRIVATE Void rgDBMInitRachLst ARGS((RgCellCb *cellCb));
+#ifdef LTEMAC_SPS
+PRIVATE S16 rgDBMInitSpsUeCbLst ARGS((
+RgCellCb       *cellCb,
+U16            numBins
+));
+#endif
+
+/* local typedefs */
+ 
+/* local externs */
+ 
+/* forward references */
+
+/**
+ * @brief Handler for Initializing the cell.
+ *
+ * @details
+ *
+ *     Function : rgDBMInitCell
+ *     
+ *   Initializes the lists belonging to the cell.
+ *     
+ *           
+ *  @param[in]  RgCellCb *cellCb
+ *  @return  S16
+ *      -# ROK 
+ *      -# RFAILED
+ **/
+#ifdef ANSI
+PUBLIC S16 rgDBMInitCell
+(
+RgCellCb       *cellCb
+)
+#else
+PUBLIC S16 rgDBMInitCell(cellCb)
+RgCellCb       *cellCb;
+#endif
+{
+   S16 ret;
+   
+   TRC2(rgDBMInitCell);
+
+   /* Initialize ue list */
+   if ((ret = rgDBMInitUeCbLst(cellCb, RG_MAX_UE_BIN_PER_CELL)) != ROK)
+      RETVALUE(ret);
+
+#ifdef LTEMAC_SPS
+   /* Initialize SPS Ue list */
+   if ((ret = rgDBMInitSpsUeCbLst(cellCb, RG_MAX_UE_BIN_PER_CELL)) != ROK)
+      RETVALUE(ret);
+#endif /* LTEMAC_SPS */
+
+   /* Initialize BCCH/PCCH logical channels */
+   rgDBMInitCmnLcLst(cellCb);
+
+
+   /* Initialize rach ue list */
+   rgDBMInitRachLst(cellCb);
+
+   RETVALUE(ret);
+
+} /* rgDBMInitCell */
+
+/**
+ * @brief Handler for initializing the ueCbLst under the cellCb.
+ *
+ * @details
+ *
+ *     Function : rgDBMInitUeCbLst
+ *     
+ *           
+ *  @param[in] *cellCb 
+ *  @param[in] numBins 
+ *  @return  S16
+ *      -# ROK 
+ *      -# RFAILED 
+ **/
+#ifdef ANSI
+PRIVATE S16 rgDBMInitUeCbLst
+(
+RgCellCb       *cellCb,
+U16            numBins
+)
+#else
+PRIVATE S16 rgDBMInitUeCbLst(cellCb, numBins)
+RgCellCb       *cellCb;
+U16            numBins;
+#endif
+{
+   Inst inst = cellCb->macInst - RG_INST_START;
+   RgUeCb ue;  
+   TRC2(rgDBMInitUeCbLst)
+
+   RETVALUE(cmHashListInit(&cellCb->ueLst, numBins, (U16)((PTR)&(ue.ueLstEnt) - (PTR)&ue), FALSE, 
+               CM_HASH_KEYTYPE_CONID, rgCb[inst].rgInit.region, rgCb[inst].rgInit.pool));
+
+}  /* rgDBMInitUeCbLst */
+
+/**
+ * @brief Handler for de-initializing the ueCbLst under the cellCb.
+ *
+ * @details
+ *
+ *     Function : rgDBMDeInitUeCbLst
+ *     
+ *           
+ *  @param[in] *cellCb 
+ *  @return  S16
+ *      -# ROK 
+ *      -# RFAILED 
+ **/
+#ifdef ANSI
+PUBLIC S16 rgDBMDeInitUeCbLst
+(
+RgCellCb       *cellCb
+)
+#else
+PUBLIC S16 rgDBMDeInitUeCbLst(cellCb)
+RgCellCb       *cellCb;
+#endif
+{
+   TRC2(rgDBMDeInitUeCbLst)
+
+   RETVALUE(cmHashListDeinit(&cellCb->ueLst));
+
+}  /* rgDBMDeInitUeCbLst */
+
+#ifdef LTEMAC_SPS
+/**
+ * @brief Handler for initializing the spsUeCbLst under the cellCb.
+ *
+ * @details
+ *
+ *     Function : rgDBMInitSpsUeCbLst
+ *     
+ *           
+ *  @param[in] *cellCb 
+ *  @param[in] numBins 
+ *  @return  S16
+ *      -# ROK 
+ *      -# RFAILED 
+ **/
+#ifdef ANSI
+PRIVATE S16 rgDBMInitSpsUeCbLst
+(
+RgCellCb       *cellCb,
+U16            numBins
+)
+#else
+PRIVATE S16 rgDBMInitSpsUeCbLst(cellCb, numBins)
+RgCellCb       *cellCb;
+U16            numBins;
+#endif
+{
+   Inst inst = cellCb->macInst - RG_INST_START;
+   RgUeCb ue;
+   TRC2(rgDBMInitSpsUeCbLst)
+
+   RETVALUE(cmHashListInit(&cellCb->spsUeLst, numBins, (U16) ((PTR) &(ue.spsUeLstEnt) - (PTR) &ue), FALSE, 
+               CM_HASH_KEYTYPE_CONID, rgCb[inst].rgInit.region, rgCb[inst].rgInit.pool));
+
+}  /* rgDBMInitSpsUeCbLst */
+
+/**
+ * @brief Handler for de-initializing the spsUeCbLst under the cellCb.
+ *
+ * @details
+ *
+ *     Function : rgDBMDeInitSpsUeCbLst
+ *     
+ *           
+ *  @param[in] *cellCb 
+ *  @return  S16
+ *      -# ROK 
+ *      -# RFAILED 
+ **/
+#ifdef ANSI
+PUBLIC S16 rgDBMDeInitSpsUeCbLst
+(
+RgCellCb       *cellCb
+)
+#else
+PUBLIC S16 rgDBMDeInitSpsUeCbLst(cellCb)
+RgCellCb       *cellCb;
+#endif
+{
+   TRC2(rgDBMDeInitSpsUeCbLst)
+
+   RETVALUE(cmHashListDeinit(&cellCb->spsUeLst));
+
+}  /* rgDBMDeInitSpsUeCbLst */
+
+#endif /* LTEMAC_SPS */
+
+/**
+ * @brief Handler for inserting the ueCb in to the ueCbLst under the cellCb.
+ *
+ * @details
+ *
+ *     Function : rgDBMInsUeCb
+ *     
+ *           
+ *  @param[in] *cellCb 
+ *  @param[in] *ueCb 
+ *  @return  S16
+ *      -# ROK 
+ *      -# RFAILED 
+ **/
+#ifdef ANSI
+PUBLIC S16 rgDBMInsUeCb
+(
+RgCellCb       *cellCb,
+RgUeCb         *ueCb
+)
+#else
+PUBLIC S16 rgDBMInsUeCb(cellCb, ueCb)
+RgCellCb       *cellCb;
+RgUeCb         *ueCb;
+#endif
+{
+   TRC2(rgDBMInsUeCb)
+
+   RETVALUE(cmHashListInsert(&cellCb->ueLst, (PTR)ueCb, 
+      (U8 *)&ueCb->ueId, (U16)sizeof(ueCb->ueId)));
+
+}  /* rgDBMInsUeCb */
+
+#ifdef LTEMAC_SPS
+/**
+ * @brief Handler for inserting the ueCb in to the spsUeCbLst under the cellCb.
+ *
+ * @details
+ *
+ *     Function : rgDBMInsSpsUeCb
+ *     
+ *           
+ *  @param[in] *cellCb 
+ *  @param[in] *ueCb 
+ *  @return  S16
+ *      -# ROK 
+ *      -# RFAILED 
+ **/
+#ifdef ANSI
+PUBLIC S16 rgDBMInsSpsUeCb
+(
+RgCellCb       *cellCb,
+RgUeCb         *ueCb
+)
+#else
+PUBLIC S16 rgDBMInsSpsUeCb(cellCb, ueCb)
+RgCellCb       *cellCb;
+RgUeCb         *ueCb;
+#endif
+{
+   TRC2(rgDBMInsSpsUeCb)
+
+   RETVALUE(cmHashListInsert(&cellCb->spsUeLst, (PTR)ueCb, 
+      (U8 *)&ueCb->spsRnti, (U16)sizeof(ueCb->spsRnti)));
+
+}  /* end of rgDBMInsSpsUeCb */
+
+#endif /* LTEMAC_SPS */
+
+/**
+ * @brief Handler for accessing the existing ueCb identified by the key ueId
+ * in the ueCbLst under the cellCb.
+ *
+ * @details
+ *
+ *     Function : rgDBMGetUeCb
+ *     
+ *           
+ *  @param[in]  *cellCb
+ *  @param[in]  ueId
+ *  @return  RgUeCb*
+ **/
+#ifdef ANSI
+PUBLIC RgUeCb* rgDBMGetUeCb
+(
+RgCellCb       *cellCb, 
+CmLteRnti      ueId
+)
+#else
+PUBLIC RgUeCb* rgDBMGetUeCb(cellCb, ueId)
+RgCellCb       *cellCb;
+CmLteRnti      ueId;
+#endif
+{
+   RgUeCb *ueCb = NULLP; 
+
+   TRC2(rgDBMGetUeCb)
+
+   cmHashListFind(&cellCb->ueLst, (U8 *)&ueId,
+      sizeof(ueId), 0, (PTR *)&ueCb);
+   RETVALUE(ueCb);
+}  /* rgDBMGetUeCb */
+
+#ifdef LTEMAC_SPS
+/**
+ * @brief Handler for accessing the ueCb identified by the key sps-rnti
+ * in the spsUeLst under the cellCb.
+ *
+ * @details
+ *
+ *     Function : rgDBMGetSpsUeCb
+ *     
+ *           
+ *  @param[in]  *cellCb
+ *  @param[in]  ueId
+ *  @return  RgUeCb*
+ **/
+#ifdef ANSI
+PUBLIC RgUeCb* rgDBMGetSpsUeCb
+(
+RgCellCb       *cellCb, 
+CmLteRnti      spsRnti
+)
+#else
+PUBLIC RgUeCb* rgDBMGetSpsUeCb(cellCb, spsRnti)
+RgCellCb       *cellCb;
+CmLteRnti      spsRnti;
+#endif
+{
+   RgUeCb *ueCb = NULLP; 
+
+   TRC2(rgDBMGetSpsUeCb)
+
+   cmHashListFind(&cellCb->spsUeLst, (U8 *)&spsRnti,
+      sizeof(spsRnti), 0, (PTR *)&ueCb);
+   RETVALUE(ueCb);
+}  /* rgDBMGetSpsUeCb */
+
+#endif /* LTEMAC_SPS */
+
+/**
+ * @brief Handler for accessing the existing next ueCb in the ueCbLst under the
+ *  cellCb.
+ *
+ * @details
+ *
+ *     Function : rgDBMGetNextUeCb
+ *     
+ *           
+ *  @param[in]  *cellCb
+ *  @param[in]  *ueCb
+ *  @return  RgUeCb*
+ **/
+#ifdef ANSI
+PUBLIC RgUeCb* rgDBMGetNextUeCb
+(
+RgCellCb       *cellCb, 
+RgUeCb         *ueCb
+)
+#else
+PUBLIC RgUeCb* rgDBMGetNextUeCb(cellCb, ueCb)
+RgCellCb       *cellCb;
+RgUeCb         *ueCb;
+#endif
+{
+   RgUeCb *nextUeCb = NULLP; 
+
+   TRC2(rgDBMGetNextUeCb)
+
+   cmHashListGetNext(&cellCb->ueLst, (PTR) ueCb, (PTR *)&nextUeCb);
+   RETVALUE(nextUeCb);
+}  /* rgDBMGetNextUeCb */
+
+#ifdef LTEMAC_SPS
+/**
+ * @brief Handler for accessing the existing next ueCb stored in the spsUeCbLst
+ *         using SPS-Rnti under the cellCb.
+ *
+ * @details
+ *
+ *     Function : rgDBMGetNextSpsUeCb
+ *     
+ *           
+ *  @param[in]  *cellCb
+ *  @param[in]  *ueCb
+ *  @return  RgUeCb*
+ **/
+#ifdef ANSI
+PUBLIC RgUeCb* rgDBMGetNextSpsUeCb
+(
+RgCellCb       *cellCb, 
+RgUeCb         *ueCb
+)
+#else
+PUBLIC RgUeCb* rgDBMGetNextSpsUeCb(cellCb, ueCb)
+RgCellCb       *cellCb;
+RgUeCb         *ueCb;
+#endif
+{
+   RgUeCb *nextUeCb = NULLP; 
+
+   TRC2(rgDBMGetNextSpsUeCb)
+
+   cmHashListGetNext(&cellCb->spsUeLst, (PTR) ueCb, (PTR *)&nextUeCb);
+   RETVALUE(nextUeCb);
+}  /* end of rgDBMGetNextSpsUeCb */
+
+#endif /* LTEMAC_SPS */
+
+
+/**
+ * @brief Handler for deleting the existing ueCb from the ueCbLst under the
+ * cellCb.
+ *
+ * @details
+ *
+ *     Function : rgDBMDelUeCb
+ *     
+ *           
+ *  @param[in]  *cellCb 
+ *  @param[in]  *ueCb 
+ *  @return  S16
+ *      -# ROK 
+ *      -# RFAILED 
+ **/
+#ifdef ANSI
+PUBLIC S16 rgDBMDelUeCb
+(
+RgCellCb       *cellCb,
+RgUeCb         *ueCb
+)
+#else
+PUBLIC S16 rgDBMDelUeCb(cellCb, ueCb)
+RgCellCb       *cellCb;
+RgUeCb         *ueCb;
+#endif
+{
+   TRC2(rgDBMDelUeCb)
+
+   RETVALUE(cmHashListDelete(&cellCb->ueLst, (PTR)ueCb));
+}  /* rgDBMDelUeCb */
+
+#ifdef LTEMAC_SPS
+/**
+ * @brief Handler for deleting the existing ueCb from the spsUeCbLst under the
+ * cellCb.
+ *
+ * @details
+ *
+ *     Function : rgDBMDelSpsUeCb
+ *     
+ *           
+ *  @param[in]  *cellCb 
+ *  @param[in]  *ueCb 
+ *  @return  S16
+ *      -# ROK 
+ *      -# RFAILED 
+ **/
+#ifdef ANSI
+PUBLIC S16 rgDBMDelSpsUeCb
+(
+RgCellCb       *cellCb,
+RgUeCb         *ueCb
+)
+#else
+PUBLIC S16 rgDBMDelSpsUeCb(cellCb, ueCb)
+RgCellCb       *cellCb;
+RgUeCb         *ueCb;
+#endif
+{
+   TRC2(rgDBMDelSpsUeCb)
+
+   RETVALUE(cmHashListDelete(&cellCb->spsUeLst, (PTR)ueCb));
+}  /* end of rgDBMDelSpsUeCb */
+
+#endif /* LTEMAC_SPS */
+
+/**
+ * @brief Handler for Initializing the UE.
+ *
+ * @details
+ *
+ *     Function : rgDBMInitUe
+ *     
+ *   Initializes the lists belonging to the UE.
+ *     
+ *           
+ *  @param[in]  RgUeCb  *ueCb
+ *  @return  S16
+ *      -# ROK 
+ *      -# RFAILED
+ **/
+#ifdef ANSI
+PUBLIC Void rgDBMInitUe
+(
+RgUeCb       *ueCb
+)
+#else
+PUBLIC Void rgDBMInitUe(ueCb)
+RgUeCb       *ueCb;
+#endif
+{
+#ifdef LTEMAC_SPS
+   U8        idx;
+#endif
+
+   TRC2(rgDBMInitUe);
+
+   /* Initialize Dedicated logical channels */
+   rgDBMInitDedLcLst(ueCb);
+
+#ifdef LTEMAC_SPS
+   /* Initialize the SPS LC Ids */
+   for (idx=0; idx < RG_MAX_LC_PER_UE; idx++)
+   {
+      ueCb->ul.spsLcId[idx] = FALSE;
+   }
+#endif
+
+
+   RETVOID;
+} /* rgDBMInitUe */
+
+/**
+ * @brief Handler for Initializing the dedicated logical channels.
+ *
+ * @details
+ *
+ *     Function : rgDBMInitDedLcLst
+ *     
+ *   Initializes dedicated logical channels.
+ *           
+ *  @param[in]  RgUeCb *ueCb
+ *  @return     Void 
+ **/
+#ifdef ANSI
+PRIVATE Void rgDBMInitDedLcLst
+(
+RgUeCb       *ueCb
+)
+#else
+PRIVATE Void rgDBMInitDedLcLst(ueCb)
+RgUeCb       *ueCb;
+#endif
+{
+   U8 idx;
+   
+   TRC2(rgDBMInitDedLcLst);
+
+   for (idx = 0; idx < RG_MAX_LC_PER_UE; ++idx)
+   {
+      /* Set Dedicated LCs as not configured */
+      ueCb->ul.lcCb[idx].lcId = RG_INVALID_LC_ID;
+      ueCb->ul.lcCb[idx].lcgId = RG_INVALID_LCG_ID;
+      ueCb->dl.lcCb[idx].lcId = RG_INVALID_LC_ID;
+   }
+
+   for (idx = 0; idx < RG_MAX_LCG_PER_UE; ++idx)
+   {
+      /* Set LCGs as not configured */
+      ueCb->ul.lcgArr[idx].lcgId = RG_INVALID_LCG_ID;
+      ueCb->ul.lcgArr[idx].lcCount = 0;
+   }
+
+   /* Stack Crash problem for TRACE5 Changes. Added the return below */
+  RETVOID;
+} /* rgDBMInitDedLcLst */
+
+/**
+ * @brief Handler for Initializing the common logical channel list of the cell.
+ *
+ * @details
+ *
+ *     Function : rgDBMInitCmnLcLst
+ *     
+ *   Initializes following common logical channels belonging to the cell.
+ *     - BCCH on BCH
+ *     - BCCH on DLSCH
+ *     - PCCH
+ *           
+ *  @param[in]  RgCellCb *cellCb
+ *  @return  Void
+ **/
+#ifdef ANSI
+PRIVATE Void rgDBMInitCmnLcLst
+(
+RgCellCb       *cellCb
+)
+#else
+PRIVATE Void rgDBMInitCmnLcLst(cellCb)
+RgCellCb       *cellCb;
+#endif
+{
+   U8 idx;
+   
+   TRC2(rgDBMInitCmnLcLst);
+   
+   cellCb->bcchBchInfo.lcId = RG_INVALID_LC_ID;
+   cellCb->pcchInfo.lcId = RG_INVALID_LC_ID;
+
+   cellCb->numBcchDlschInfo = 0;
+   for (idx = 0; idx < RG_MAX_BCCH_DLSCH; idx++)
+   {
+      cellCb->bcchDlschInfo[idx].lcId = RG_INVALID_LC_ID;
+      cellCb->bcchDlschInfo[idx].tb = NULLP;
+   }
+
+   /* Stack Crash problem for TRACE5 Changes. Added the return below */
+  RETVOID;
+} /* rgDBMInitCmnLcLst */
+
+/**
+ * @brief Handler for Initializing the common logical channel list of the cell.
+ *
+ * @details
+ *
+ *     Function : rgDBMFreeCmnLcLst
+ *     
+ *   Initializes following common logical channels belonging to the cell.
+ *     - BCCH on BCH
+ *     - BCCH on DLSCH
+ *     - PCCH
+ *           
+ *  @param[in]  RgCellCb *cellCb
+ *  @return  Void
+ **/
+#ifdef ANSI
+PUBLIC Void rgDBMFreeCmnLcLst
+(
+RgCellCb       *cellCb
+)
+#else
+PUBLIC Void rgDBMFreeCmnLcLst(cellCb)
+RgCellCb       *cellCb;
+#endif
+{
+   U8 idx;
+   
+   TRC2(rgDBMFreeCmnLcLst);
+   
+   cellCb->bcchBchInfo.lcId = RG_INVALID_LC_ID;
+   cellCb->pcchInfo.lcId = RG_INVALID_LC_ID;
+
+   for (idx = 0; idx < cellCb->numBcchDlschInfo; idx++)
+   {
+      cellCb->bcchDlschInfo[idx].lcId = RG_INVALID_LC_ID;
+      RG_FREE_MSG(cellCb->bcchDlschInfo[idx].tb);
+   }
+   cellCb->numBcchDlschInfo = 0;
+
+   /* Stack Crash problem for TRACE5 Changes. Added the return below */
+  RETVOID;
+} /* rgDBMFreeCmnLcLst */
+
+/**
+ * @brief Handler for inserting dedicated DL logical channel.
+ *
+ * @details
+ *
+ *     Function : rgDBMInsDlDedLcCb
+ *     
+ *  @param[in]  RgUeCb *ueCb
+ *  @param[in]  RgDlLcCb* dlLcCb
+ *  @return  Void
+ **/
+#ifdef ANSI
+PUBLIC Void rgDBMInsDlDedLcCb
+(
+RgUeCb         *ueCb, 
+CmLteLcId        idx
+)
+#else
+PUBLIC Void rgDBMInsDlDedLcCb(ueCb, idx)
+RgUeCb         *ueCb; 
+CmLteLcId        idx;
+#endif
+{
+   TRC2(rgDBMInsDlDedLcCb);
+   if( idx >= RG_DEDLC_MIN_LCID )
+   {
+      ueCb->dl.lcCb[idx-1].lcId = idx;
+   }
+  /* Stack Crash problem for TRACE5 Changes. Added the return below */
+  RETVOID;
+}  /* rgDBMInsDlDedLcCb */
+
+/**
+ * @brief Handler for deleting dedicated DL logical channel.
+ *
+ * @details
+ *
+ *     Function : rgDBMDelDlDedLcCb
+ *     
+ *  @param[in]  RgUeCb *ueCb
+ *  @param[in]  RgDlLcCb* dlLcCb
+ *  @return  Void
+ **/
+#ifdef ANSI
+PUBLIC Void rgDBMDelDlDedLcCb
+(
+RgUeCb         *ueCb, 
+RgDlLcCb       *dlLcCb 
+)
+#else
+PUBLIC Void rgDBMDelDlDedLcCb(ueCb, dlLcCb)
+RgUeCb         *ueCb; 
+RgDlLcCb       *dlLcCb; 
+#endif
+{
+   TRC2(rgDBMDelDlDedLcCb);
+
+   ueCb->dl.lcCb[dlLcCb->lcId - 1].lcId = RG_INVALID_LC_ID;
+
+  /* Stack Crash problem for TRACE5 Changes. Added the return below */
+  RETVOID;
+  
+}  /* rgDBMDelDlDedLcCb */
+
+/**
+ * @brief Handler for accessing the existing DL dedicated lcCb at idx in the 
+ * lcCbLst of the ueCb.
+ *
+ * @details
+ *
+ *     Function : rgDBMGetDlDedLcCb
+ *     
+ *  @param[in]  *ueCb
+ *  @param[in]  idx
+ *  @return  RgDlLcCb*
+ **/
+#ifdef ANSI
+PUBLIC RgDlLcCb* rgDBMGetDlDedLcCb
+(
+RgUeCb         *ueCb, 
+CmLteLcId        idx
+)
+#else
+PUBLIC RgDlLcCb* rgDBMGetDlDedLcCb(ueCb, idx)
+RgUeCb         *ueCb; 
+CmLteLcId        idx;
+#endif
+{
+   TRC2(rgDBMGetDlDedLcCb);
+
+   if (idx > RG_DEDLC_MAX_LCID || idx <= 0)
+   {
+      RETVALUE(NULLP);
+   }
+   if(ueCb->dl.lcCb[idx-1].lcId == RG_INVALID_LC_ID)
+   {
+      RETVALUE(NULLP);
+   }
+
+   RETVALUE(&ueCb->dl.lcCb[idx-1]);
+
+}  /* rgDBMGetDlDedLcCb */
+
+/**
+ * @brief Handler for inserting dedicated UL logical channel.
+ *
+ * @details
+ *
+ *     Function : rgDBMInsUlDedLcCb
+ *     
+ *           
+ *  @param[in]  RgUeCb *ueCb
+ *  @param[in]  CmLteLcId idx
+ *  @param[in]  LteLcgId gId
+ *  @return  Void
+ **/
+#ifdef LTE_L2_MEAS
+#ifdef ANSI
+PUBLIC Void rgDBMInsUlDedLcCb
+(
+RgUeCb         *ueCb, 
+CmLteLcId      idx,
+LteLcgId       gId,
+U8             qci
+)
+#else
+PUBLIC Void rgDBMInsUlDedLcCb(ueCb, idx, gId, qci)
+RgUeCb         *ueCb; 
+CmLteLcId      idx;
+LteLcgId       gId;
+U8             qci;
+#endif
+#else
+#ifdef ANSI
+PUBLIC Void rgDBMInsUlDedLcCb
+(
+RgUeCb         *ueCb, 
+CmLteLcId      idx,
+LteLcgId       gId
+)
+#else
+PUBLIC Void rgDBMInsUlDedLcCb(ueCb, idx, gId)
+RgUeCb         *ueCb; 
+CmLteLcId      idx;
+LteLcgId       gId;
+#endif
+#endif
+{
+   TRC2(rgDBMInsUlDedLcCb);
+   if ( idx >= RG_DEDLC_MIN_LCID)
+   {
+      ueCb->ul.lcCb[idx - 1].lcId = idx;
+      ueCb->ul.lcCb[idx - 1].lcgId = gId;
+#ifdef LTE_L2_MEAS
+      ueCb->ul.lcCb[idx - 1].qci = qci;
+#endif
+   }
+   if(ueCb->ul.lcgArr[gId].lcgId == RG_INVALID_LCG_ID)
+   {
+      ueCb->ul.lcgArr[gId].lcgId = gId;
+   }
+   ueCb->ul.lcgArr[gId].lcCount = ueCb->ul.lcgArr[gId].lcCount + 1;
+
+
+  /* Stack Crash problem for TRACE5 Changes. Added the return below */
+  RETVOID;
+
+}  /* rgDBMInsUlDedLcCb */
+
+/**
+ * @brief Handler for deleting the dedicated UL logical channel.
+ *
+ * @details
+ *
+ *     Function : rgDBMUpdUlDedLcCb
+ *     
+ *           
+ *  @param[in]  RgUeCb *ueCb
+ *  @param[in]  RgUlLcCb* ulLcCb
+ *  @param[in]  LteLcgId gId
+ *  @return  Void
+ **/
+#ifdef ANSI
+PUBLIC Void rgDBMUpdUlDedLcCb
+(
+RgUeCb         *ueCb, 
+RgUlLcCb       *ulLcCb,
+LteLcgId       gId
+)
+#else
+PUBLIC Void rgDBMUpdUlDedLcCb(ueCb, ulLcCb, gId)
+RgUeCb         *ueCb; 
+RgUlLcCb       *ulLcCb; 
+LteLcgId       gId;
+#endif
+{
+   TRC2(rgDBMUpdUlDedLcCb);
+
+   ueCb->ul.lcgArr[ulLcCb->lcgId].lcCount = 
+               ueCb->ul.lcgArr[ulLcCb->lcgId].lcCount - 1;
+   if(ueCb->ul.lcgArr[ulLcCb->lcgId].lcCount == 0)
+   {
+      ueCb->ul.lcgArr[ulLcCb->lcgId].lcgId = RG_INVALID_LCG_ID;
+   }
+   ueCb->ul.lcCb[ulLcCb->lcId - 1].lcgId = gId;
+
+   if(ueCb->ul.lcgArr[gId].lcgId == RG_INVALID_LCG_ID)
+   {
+      ueCb->ul.lcgArr[gId].lcgId = gId;
+   }
+   ueCb->ul.lcgArr[gId].lcCount = ueCb->ul.lcgArr[gId].lcCount + 1;
+
+  /* Stack Crash problem for TRACE5 Changes. Added the return below */
+  RETVOID;
+}  /* rgDBMUpdUlDedLcCb */
+
+/**
+ * @brief Handler for updating the dedicated UL logical channel.
+ *
+ * @details
+ *
+ *     Function : rgDBMDelUlDedLcCb
+ *     
+ *           
+ *  @param[in]  RgUeCb *ueCb
+ *  @param[in]  RgUlLcCb* ulLcCb
+ *  @return  Void
+ **/
+#ifdef ANSI
+PUBLIC Void rgDBMDelUlDedLcCb
+(
+RgUeCb         *ueCb, 
+RgUlLcCb       *ulLcCb 
+)
+#else
+PUBLIC Void rgDBMDelUlDedLcCb(ueCb, ulLcCb)
+RgUeCb         *ueCb; 
+RgUlLcCb       *ulLcCb; 
+#endif
+{
+   TRC2(rgDBMDelUlDedLcCb);
+
+   ueCb->ul.lcgArr[ulLcCb->lcgId].lcCount = 
+               ueCb->ul.lcgArr[ulLcCb->lcgId].lcCount - 1;
+   if(ueCb->ul.lcgArr[ulLcCb->lcgId].lcCount == 0)
+   {
+      ueCb->ul.lcgArr[ulLcCb->lcgId].lcgId = RG_INVALID_LCG_ID;
+   }
+   ueCb->ul.lcCb[ulLcCb->lcId - 1].lcgId = RG_INVALID_LCG_ID;
+   ueCb->ul.lcCb[ulLcCb->lcId - 1].lcId = RG_INVALID_LC_ID;
+
+  /* Stack Crash problem for TRACE5 Changes. Added the return below */
+  RETVOID;
+}  /* rgDBMDelUlDedLcCb */
+
+/**
+ * @brief Handler for accessing the existing UL dedicated lcCb at idx in the
+ * lcCbLst of the ueCb.
+ *
+ * @details
+ *
+ *     Function : rgDBMGetUlDedLcCb
+ *     
+ *           
+ *  @param[in]  *ueCb
+ *  @param[in]  idx
+ *  @return  RgUlLcCb*
+ **/
+#ifdef ANSI
+PUBLIC RgUlLcCb* rgDBMGetUlDedLcCb
+(
+RgUeCb         *ueCb, 
+CmLteLcId        idx
+)
+#else
+PUBLIC RgUlLcCb* rgDBMGetUlDedLcCb(ueCb, idx)
+RgUeCb         *ueCb; 
+CmLteLcId        idx;
+#endif
+{
+   TRC2(rgDBMGetUlDedLcCb)
+
+   if (idx > RG_DEDLC_MAX_LCID || idx < RG_DEDLC_MIN_LCID)
+   {
+      RETVALUE(NULLP);
+   }
+   if(ueCb->ul.lcCb[idx-1].lcId == RG_INVALID_LC_ID)
+   {
+      RETVALUE(NULLP);
+   }
+
+   RETVALUE(&ueCb->ul.lcCb[idx-1]);
+}  /* rgDBMGetDlDedLcCb */
+
+/**
+ * @brief Handler for accessing the existing DL common lcCb identified by the key lcId
+ * in the lcCbLst of the ueCb.
+ *
+ * @details
+ *
+ *     Function : rgDBMChkCmnLcCb
+ *     
+ *           
+ *  @param[in]  *cellCb
+ *  @param[in]  lcId
+ *  @return  S16
+ *      -# ROK
+ *      -# RFAILED
+ **/
+#ifdef ANSI
+PUBLIC S16 rgDBMChkCmnLcCb
+(
+RgCellCb       *cellCb, 
+CmLteLcId        lcId
+)
+#else
+PUBLIC S16 rgDBMChkCmnLcCb(cellCb, lcId)
+RgCellCb       *cellCb;
+CmLteLcId        lcId;
+#endif
+{
+   U8 idx;
+
+   TRC2(rgDBMChkCmnLcCb)
+
+   if(cellCb->bcchBchInfo.lcId == lcId)
+   {
+      RETVALUE(ROK);
+   } 
+   if(cellCb->pcchInfo.lcId == lcId)
+   {
+      RETVALUE(ROK);
+   }
+
+   for (idx = 0; idx < cellCb->numBcchDlschInfo; idx++)
+   {
+      if(cellCb->bcchDlschInfo[idx].lcId == lcId)
+      {
+         RETVALUE(ROK);
+      } 
+   }
+   RETVALUE(RFAILED);
+}  /* rgDBMChkCmnLcCb */
+
+/**
+ * @brief Handler for accessing the existing BCCH mapped on to BCH in the 
+ * lcCbLst of the ueCb.
+ *
+ * @details
+ *
+ *     Function : rgDBMGetBcchOnBch
+ *     
+ *           
+ *  @param[in]  *cellCb
+ *  @return  RgBcchBchLcCb*
+ **/
+#ifdef ANSI
+PUBLIC RgBcchBchLcCb* rgDBMGetBcchOnBch
+(
+RgCellCb       *cellCb 
+)
+#else
+PUBLIC RgBcchBchLcCb* rgDBMGetBcchOnBch(cellCb)
+RgCellCb       *cellCb;
+#endif
+{
+   TRC2(rgDBMGetBcchOnBch)
+
+   if(cellCb->bcchBchInfo.lcId != RG_INVALID_LC_ID)
+   {
+      RETVALUE(&(cellCb->bcchBchInfo));
+   }
+   RETVALUE(NULLP);
+}  /* rgDBMGetBcchOnBch */
+
+/**
+ * @brief Handler for accessing the existing BCCH mapped on to DLSCH in the 
+ * lcCbLst of the ueCb.
+ *
+ * @details
+ *
+ *     Function : rgDBMGetBcchOnDlsch
+ *     
+ *           
+ *  @param[in]  *cellCb
+ *  @param[in]  lcId
+ *  @return  RgBcchDlschLcCb*
+ **/
+#ifdef ANSI
+PUBLIC RgBcchDlschLcCb* rgDBMGetBcchOnDlsch
+(
+RgCellCb       *cellCb,
+CmLteLcId      lcId
+)
+#else
+PUBLIC RgBcchDlschLcCb* rgDBMGetBcchOnDlsch(cellCb,lcId)
+RgCellCb       *cellCb;
+CmLteLcId      lcId;
+#endif
+{
+   U8 idx;
+
+   TRC2(rgDBMGetBcchOnDlsch)
+
+   for (idx = 0; idx < RG_MAX_BCCH_DLSCH; idx++)
+   {
+      if(cellCb->bcchDlschInfo[idx].lcId == lcId)
+      {
+         RETVALUE(&(cellCb->bcchDlschInfo[idx]));
+      }
+   }
+   RETVALUE(NULLP);
+}  /* rgDBMGetBcchOnDlsch */
+
+/**
+ * @brief Handler for accessing the existing PCCH in the lcCbLst of the ueCb.
+ *
+ * @details
+ *
+ *     Function : rgDBMGetPcch
+ *     
+ *           
+ *  @param[in]  *cellCb
+ *  @return  RgPcchLcCb*
+ **/
+#ifdef ANSI
+PUBLIC RgPcchLcCb* rgDBMGetPcch
+(
+RgCellCb       *cellCb
+)
+#else
+PUBLIC RgPcchLcCb* rgDBMGetPcch(cellCb)
+RgCellCb       *cellCb;
+#endif
+{
+   TRC2(rgDBMGetPcch)
+ 
+   if(cellCb->pcchInfo.lcId != RG_INVALID_LC_ID)
+   {
+      RETVALUE(&(cellCb->pcchInfo));
+   }
+   RETVALUE(NULLP);
+}  /* rgDBMGetPcch */
+
+/**
+ * @brief Handler for inserting the BCCH mapped on to BCH in the 
+ * lcCbLst of the ueCb.
+ *
+ * @details
+ *
+ *     Function : rgDBMInsBcchOnBch
+ *     
+ *           
+ *  @param[in]  *cellCb
+ *  @return  Void
+ **/
+#ifdef ANSI
+PUBLIC Void rgDBMInsBcchOnBch
+(
+RgCellCb       *cellCb, 
+CmLteLcId      idx
+)
+#else
+PUBLIC Void rgDBMInsBcchOnBch(cellCb, idx)
+RgCellCb       *cellCb;
+CmLteLcId      idx;
+#endif
+{
+   TRC2(rgDBMInsBcchOnBch)
+
+   cellCb->bcchBchInfo.lcId = idx;
+
+  /* Stack Crash problem for TRACE5 Changes. Added the return below */
+  RETVOID;
+}  /* rgDBMInsBcchOnBch */
+
+/**
+ * @brief Handler for inserting the BCCH mapped on to DLSCH in the 
+ * lcCbLst of the ueCb.
+ *
+ * @details
+ *
+ *     Function : rgDBMInsBcchOnDlsch
+ *     
+ *           
+ *  @param[in]  *cellCb
+ *  @return  Void
+ **/
+#ifdef ANSI
+PUBLIC Void rgDBMInsBcchOnDlsch
+(
+RgCellCb       *cellCb, 
+CmLteLcId      idx
+)
+#else
+PUBLIC Void rgDBMInsBcchOnDlsch(cellCb, idx)
+RgCellCb       *cellCb;
+CmLteLcId      idx;
+#endif
+{
+   TRC2(rgDBMInsBcchOnDlsch)
+
+   cellCb->bcchDlschInfo[cellCb->numBcchDlschInfo].lcId = idx;
+   cellCb->numBcchDlschInfo++;
+
+  /* Stack Crash problem for TRACE5 Changes. Added the return below */
+  RETVOID;
+}  /* rgDBMInsBcchOnDlsch */
+
+
+/**
+ * @brief Handler for inserting the PCCH in the lcCbLst of the ueCb.
+ *
+ * @details
+ *
+ *     Function : rgDBMInsPcch
+ *     
+ *           
+ *  @param[in]  *cellCb
+ *  @return  Void
+ **/
+#ifdef ANSI
+PUBLIC Void rgDBMInsPcch
+(
+RgCellCb       *cellCb, 
+CmLteLcId      idx
+)
+#else
+PUBLIC Void rgDBMInsPcch(cellCb, idx)
+RgCellCb       *cellCb;
+CmLteLcId      idx;
+#endif
+{
+   TRC2(rgDBMInsPcch)
+
+   cellCb->pcchInfo.lcId = idx;
+
+  /* Stack Crash problem for TRACE5 Changes. Added the return below */
+  RETVOID;
+}  /* rgDBMInsPcch */
+
+/**
+ * @brief Handler for initializing the rachLst
+ *
+ * @details
+ *
+ *     Function : rgDBMInitRachLst
+ *     
+ *           
+ *  @param[in] *cellCb 
+ *  @return  Void
+ **/
+#ifdef ANSI
+PRIVATE Void rgDBMInitRachLst
+(
+RgCellCb       *cellCb
+)
+#else
+PRIVATE Void rgDBMInitRachLst(cellCb)
+RgCellCb       *cellCb;
+#endif
+{
+   TRC2(rgDBMInitRachLst)
+
+   cmLListInit(&cellCb->raInfo.ueRachLst);
+   RETVOID;
+}  /* rgDBMInitRachLst */
+
+/**
+ * @brief Handler for inserting the ueCb in the rachLst.
+ *
+ * @details
+ *
+ *     Function : rgDBMInsUeCbInRachLst
+ *     
+ *           
+ *  @param[in]  *cellCb
+ *  @param[in]  *ueCb
+ *  @return  Void
+ **/
+#ifdef ANSI
+PUBLIC Void rgDBMInsUeCbInRachLst
+(
+RgCellCb       *cellCb, 
+RgUeCb         *ueCb
+)
+#else
+PUBLIC Void rgDBMInsUeCbInRachLst(cellCb, ueCb)
+RgCellCb       *cellCb; 
+RgUeCb         *ueCb;
+#endif
+{
+   TRC2(rgDBMInsUeCbInRachLst)
+
+   cmLListAdd2Tail(&cellCb->raInfo.ueRachLst,&ueCb->rachLstEnt);
+
+   RETVOID;
+}  /* rgDBMInsUeCbInRachLst */
+
+/**
+ * @brief Handler for accessing the existing raCb in the rachLst.
+ *
+ * @details
+ *
+ *     Function : rgDBMGetUeCbFromRachLst
+ *     
+ *           
+ *  @param[in]  *cellCb
+ *  @param[in]  key
+ *  @return  RgUeCb*
+ **/
+#ifdef ANSI
+PUBLIC RgUeCb* rgDBMGetUeCbFromRachLst
+(
+RgCellCb       *cellCb, 
+CmLteRnti      key
+)
+#else
+PUBLIC RgUeCb* rgDBMGetUeCbFromRachLst(cellCb, key)
+RgCellCb       *cellCb; 
+CmLteRnti      key;
+#endif
+{
+   CmLList *tmpNode;
+
+   TRC2(rgDBMGetUeCbFromRachLst)
+
+   CM_LLIST_FIRST_NODE(&cellCb->raInfo.ueRachLst,tmpNode);
+   while(tmpNode)
+   {
+      if(((RgUeCb *)tmpNode->node)->ueId == key)
+      {
+         RETVALUE((RgUeCb *)(tmpNode->node));
+      }
+      CM_LLIST_NEXT_NODE(&cellCb->raInfo.ueRachLst,tmpNode);
+   }
+   RETVALUE(NULLP);
+}  /* rgDBMGetUeCbFromRachLst */
+
+/**
+ * @brief Handler for accessing the existing ueCb from rachLst.
+ *
+ * @details
+ *
+ *     Function : rgDBMGetNextUeCbFromRachLst
+ *     
+ *           
+ *  @param[in]  *cellCb
+ *  @param[in]  *ueCb
+ *  @return  RgUeCb*
+ **/
+#ifdef ANSI
+PUBLIC RgUeCb* rgDBMGetNextUeCbFromRachLst
+(
+RgCellCb       *cellCb,
+RgUeCb         *ueCb
+)
+#else
+PUBLIC RgUeCb* rgDBMGetNextUeCbFromRachLst(cellCb, ueCb)
+RgCellCb       *cellCb; 
+RgUeCb         *ueCb;
+#endif
+{
+   TRC2(rgDBMGetNextUeCbFromRachLst)
+
+   if(!ueCb)
+   {
+      RETVALUE( cellCb->raInfo.ueRachLst.first ? 
+               (RgUeCb *)(cellCb->raInfo.ueRachLst.first->node) : NULLP );
+   }
+   RETVALUE( ueCb->rachLstEnt.next ? 
+               (RgUeCb *)(ueCb->rachLstEnt.next->node) : NULLP );
+}  /* rgDBMGetNextUeCbFromRachLst */
+
+/**
+ * @brief Handler for deleting the existing ueCb in the rachLst.
+ *
+ * @details
+ *
+ *     Function : rgDBMDelUeCbFromRachLst
+ *     
+ *           
+ *  @param[in]  *cellCb
+ *  @param[in]  key
+ *  @return  RgUeCb*
+ **/
+#ifdef ANSI
+PUBLIC Void rgDBMDelUeCbFromRachLst
+(
+RgCellCb       *cellCb, 
+RgUeCb         *ueCb 
+)
+#else
+PUBLIC Void rgDBMDelUeCbFromRachLst(cellCb, ueCb)
+RgCellCb       *cellCb; 
+RgUeCb         *ueCb;
+#endif
+{
+   TRC2(rgDBMDelUeCbFromRachLst)
+
+   cmLListDelFrm(&cellCb->raInfo.ueRachLst, &ueCb->rachLstEnt);
+   RETVOID;
+}  /* rgDBMDelUeCbFromRachLst */
+
+/**********************************************************************
+ 
+         End of file
+**********************************************************************/
diff --git a/src/5gnrmac/rg_dhm.c b/src/5gnrmac/rg_dhm.c
new file mode 100755
index 000000000..d77c3b428
--- /dev/null
+++ b/src/5gnrmac/rg_dhm.c
@@ -0,0 +1,1811 @@
+/*******************************************************************************
+################################################################################
+#   Copyright (c) [2017-2019] [Radisys]                                        #
+#                                                                              #
+#   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.                                             #
+################################################################################
+*******************************************************************************/
+
+/************************************************************************
+ 
+     Name:     LTE-MAC layer
+  
+     Type:     C source file
+  
+     Desc:     C source code for Entry point fucntions
+  
+     File:     rg_dhm.c
+  
+**********************************************************************/
+
+/** @file rg_dhm.c
+@brief APIs related to Downlink HARQ.
+*/
+
+static const char* RLOG_MODULE_NAME="MAC";
+static int RLOG_FILE_ID=279;
+static int RLOG_MODULE_ID=4096;
+/* header include files -- defines (.h) */
+#include "envopt.h"        /* environment options */
+#include "envdep.h"        /* environment dependent */
+#include "envind.h"        /* environment independent */
+#include "gen.h"           /* general layer */
+#include "ssi.h"           /* system service interface */
+#ifdef L2_OPTMZ
+#include "ss_strm.h"
+#endif
+#include "cm5.h"           /* common timers */
+#include "cm_hash.h"       /* common hash list */
+#include "cm_mblk.h"       /* common memory link list library */
+#include "cm_llist.h"      /* common linked list library */
+#include "cm_err.h"        /* common error */
+#include "cm_lte.h"        /* common LTE */
+#include "lrg.h"
+#include "crg.h"
+#include "rgu.h"
+#include "tfu.h"
+#include "rg_sch_inf.h"
+#include "rg_env.h"
+#include "rg_err.h"
+#include "rg.h"
+
+/* header/extern include files (.x) */
+#include "gen.x"           /* general layer */
+#include "ssi.x"           /* system service interface */
+#ifdef L2_OPTMZ
+#include "ss_strm.x"
+#endif
+#include "cm5.x"           /* common timers */
+#include "cm_lib.x"        /* common library */
+#include "cm_hash.x"       /* common hash list */
+#include "cm_llist.x"      /* common linked list library */
+#include "cm_mblk.x"       /* memory management */
+#include "cm_tkns.x"       /* common tokens */
+#include "cm_lte.x"        /* common LTE */
+#include "lrg.x"
+#include "crg.x"
+#include "rgu.x"
+#include "tfu.x"
+#include "rg_sch_inf.x"
+#include "rg_prg.x"        /* PRG interface typedefs */
+#include "rg.x"
+
+#ifdef L2_OPTMZ
+#include "ss_queue.h"
+#include "ss_queue.x"
+#include "ss_task.x"
+#include "ss_msg.x"            /* MAC includes */
+/* local defines */
+//EXTERN  S16 ssGetDBufOfSize(Region region,Size size,Buffer **dBuf);
+//void prc_trace_format_string(UINT32 group_mask, UINT16 level, const char *format, ...);
+#endif
+
+/* local typedefs */
+ 
+/* local externs */
+EXTERN S16 SIncMsgRef(Buffer *srcBuf,Region dstRegion, Pool dstPool,Buffer **dstBuf);
+
+PRIVATE Void rgDHMBldTfuDatReq ARGS((RgCellCb *cellCb, RgDlSf *dlSf, RgDlHqProcCb *hqP,
+                           RgTfuDatReqPduInfo *datReq));
+
+#ifdef L2_OPTMZ
+PUBLIC S16 rgDHMFreeHqProcTB
+(
+RgDlHqProcCb         *hqP,
+U8                   tbIndex
+);
+
+#endif
+
+/* forward references */
+
+/**
+ * @brief This function initializes the DL HARQ Entity of UE
+ *
+ * @details
+ *
+ *     Function: rgDHMHqEntInit
+ *     Purpose:  This function initializes the DL HARQ entity of 
+ *               UE control block. This is performed at the time
+ *               of creating UE control block.
+ *     
+ *     Invoked by: configuration module
+ *     
+ *  @param[in]  Inst        inst
+ *  @param[in]  RgCellCb*  cell
+ *  @param[in]  RgUeCb*    ue
+ *  @return  S16
+ *           -# ROK
+ *           -# RFAILED
+ *
+ **/
+#ifdef ANSI
+PUBLIC S16 rgDHMHqEntInit
+(
+Inst               inst,
+RgDlHqEnt          *hqE,
+U8                 maxHqProcs
+)
+#else
+PUBLIC S16 rgDHMHqEntInit(inst,hqE, maxHqProcs)
+Inst               inst,
+RgDlHqEnt          *hqE;
+U8                 maxHqProcs;
+#endif
+{
+   U8 idx1,idx2;
+#ifdef L2_OPTMZ
+   Buffer  *hdrDBuf = NULLP;
+   Buffer  *ceDBuf = NULLP;
+#endif
+
+   TRC2(rgDHMHqEntInit)
+
+   hqE->numHqProcs = maxHqProcs;
+   /* for each harq process */
+   for (idx1 = 0; idx1 < hqE->numHqProcs; idx1++)
+   {
+      if (rgAllocSBuf(inst,(Data **)&(hqE->procs[idx1]),sizeof(RgDlHqProcCb)) != ROK) 
+      {
+         while(idx1--)
+         {
+            rgFreeSBuf(inst,(Data **)&(hqE->procs[idx1]), sizeof(RgDlHqProcCb));
+         }
+         RLOG0(L_ERROR, "Memory Alloc Failure for RgDlHqProcCb");        
+         RETVALUE(RFAILED);
+      }
+
+      hqE->procs[idx1]->procId      = idx1;
+      for(idx2 = 0; idx2 < RG_MAX_TB_PER_UE; idx2++)
+      {
+#ifndef L2_OPTMZ
+         hqE->procs[idx1]->tbInfo[idx2].tb = NULLP;
+#else
+         Buffer *tmpMBuf;
+         /* L2 optimization for mUe/Tti: Allocating buffers for macHdr, macCes
+          * and macPadding. These buffers shall not be released by MAC/CL.
+          * However, Only rPtr and wPtr will be reset while release of hq proc
+          */
+         tmpMBuf = hqE->procs[idx1]->tbInfo[idx2].tb.macHdr;
+         rgGetMsg(inst, &tmpMBuf);
+         RG_ADD_DBuf(hdrDBuf, RG_MAC_HDR_SIZE, tmpMBuf);
+         hqE->procs[idx1]->tbInfo[idx2].tb.macHdr = tmpMBuf;
+         macHeader[idx2] = MacPtrAddress;
+
+         tmpMBuf = hqE->procs[idx1]->tbInfo[idx2].tb.macCes;
+         rgGetMsg(inst, &tmpMBuf);
+         RG_ADD_DBuf(ceDBuf, RG_MAC_CE_SIZE, tmpMBuf);
+         hqE->procs[idx1]->tbInfo[idx2].tb.macCes = tmpMBuf;
+
+         hqE->procs[idx1]->tbInfo[idx2].tb.padSize = 0;
+#endif
+#ifdef LTE_L2_MEAS
+         hqE->procs[idx1]->tbId[idx2] = RGU_INVALID_TBID;
+#endif
+      }
+
+      cmLListInit(&hqE->savedProcLst[idx1]);
+   }
+
+
+   RETVALUE(ROK);
+} /* rgDHMHqEntInit */
+
+/**
+ * @brief This function releases a HARQ process
+ *
+ * @details
+ *
+ *     Function: rgDHMUeReset
+ *     Purpose:  This function resets TB in each HarqProc.
+ *     
+ *     Invoked by: CFG UE Reset 
+ *     
+ *  @param[in]  RgDlHqProc    *hqP
+ *  @return  Void      
+ *
+ **/
+#ifdef ANSI
+PUBLIC Void rgDHMUeReset
+(
+RgCellCb *cell,
+RgDlHqEnt          *hqE
+)
+#else
+PUBLIC Void rgDHMUeReset(cell, hqE)
+RgCellCb *cell;
+RgDlHqEnt          *hqE;
+#endif
+{
+   U8       i = 0;
+
+   TRC2(rgDHMUeReset)
+
+   if(hqE->procs[0])
+   {
+      /* Free all the TB memory associated with HARQ */
+      for (i=0; i < hqE->numHqProcs; i++)
+      {
+         rgDHMRlsHqProcTB(cell, hqE->procs[i], 1);
+         rgDHMRlsHqProcTB(cell, hqE->procs[i], 2);
+
+#ifdef LTE_ADV
+         rgDHMFreeSavedHqP((cell->macInst - RG_INST_START), hqE, i);
+#endif
+      }
+   }
+   RETVOID;
+} /* rgDHMUeReset*/
+
+/**
+ * @brief This function defers shared memory buffer
+ *        freeing out of the critical RT path.
+ *
+ * @details
+ *
+ *     Function: rgDHMHdlBufFree
+ *     Purpose: To defer shared memory freeing post 
+ *              critical path. Defer as many if defer queue 
+ *              is full then release instantly.
+ *     
+ *     Invoked by: HARQ TB Release. 
+ *     
+ *  @return  Void      
+ *
+ **/
+#ifdef ANSI
+PUBLIC Void rgDHMHdlBufFree
+(
+Inst inst,
+Buffer **mBuf
+)
+#else
+PUBLIC Void rgDHMHdlBufFree(Inst inst, Buffer **mBuf)
+Inst inst;
+#endif
+{
+   RgCb *rgCbP = &rgCb[inst];
+   TRC2(rgDHMHdlBufFree)
+
+   if (rgCbP->bufCnt < RG_MAX_DFRD_FREE_BUFS)
+   {
+      if (*mBuf)
+      {
+         rgCbP->bufToFree[rgCbP->bufCnt] = *mBuf;
+         rgCbP->bufCnt++;
+         *mBuf = NULLP;
+      }
+   }
+   else
+   {
+      RG_FREE_MSG(*mBuf);
+   }
+   RETVOID;
+}
+/**
+ * @brief This function is called to release the 
+ *        shared memory of the HARQ TBs outside 
+ *        the critical RT path.
+ *
+ * @details
+ *
+ *     Function: rgDHMFreeTbBufs
+ *     Purpose: This function is called to release the 
+ *        shared memory of the HARQ TBs outside 
+ *        the critical RT path.
+ *     
+ *     1. Job of releasing TBs is shared across TTIs
+ *     Invoked by: MAC every TTI 
+ *     
+ *  @return  Void      
+ *
+ **/
+#ifdef ANSI
+PUBLIC Void rgDHMFreeTbBufs
+(
+Inst inst
+)
+#else
+PUBLIC Void rgDHMFreeTbBufs(inst)
+Inst inst;
+#endif
+{
+   RgCb *rgCbP = &rgCb[inst];
+   U8 start = rgCbP->bufCnt;
+   U8 end = 0;
+
+   TRC2(rgDHMFreeTbBufs)
+
+   if (rgCbP->bufCnt < RG_MAX_FREE_BUFS_PERTTI)
+   {
+      end = 0;
+   }
+   else
+   {
+      end = rgCbP->bufCnt - RG_MAX_FREE_BUFS_PERTTI;
+   }
+   while (start != end)
+   {
+      start--;
+      SPutMsg(rgCbP->bufToFree[start]);
+   }
+   rgCbP->bufCnt = end;
+   RETVOID;
+} /* rgDHMFreeTbBufs */
+
+#ifdef ANSI
+PUBLIC Void rgDHMFreeAllTbBufs
+(
+Inst inst
+)
+#else
+PUBLIC Void rgDHMFreeAllTbBufs(inst)
+Inst inst;
+#endif
+{
+   RgCb *rgCbP = &rgCb[inst];
+   U8 start = rgCbP->bufCnt;
+   U8 end = 0;
+
+   TRC2(rgDHMFreeAllTbBufs)
+
+   while (start != end)
+   {
+      start--;
+      SPutMsg(rgCbP->bufToFree[start]);
+   }
+   rgCbP->bufCnt = end;
+   RETVOID;
+} /* rgDHMFreeTbBufs */
+
+
+/**
+ * @brief This function releases a HARQ process
+ *
+ * @details
+ *
+ *     Function: rgDHMRlsHqProcTB
+ *     Purpose:  This function returns a HARQ process to HARQ Entity 
+ *               in the DL direction.
+ *     
+ *               1. Add the HARQ process to the free queue.
+ *     Invoked by: scheduler and HARQ processing
+ *     
+ *  @param[in]  RgDlHqProc    *hqP
+ *  @return  Void      
+ *
+ **/
+#ifdef ANSI
+PUBLIC S16 rgDHMRlsHqProcTB
+(
+RgCellCb             *cell,
+RgDlHqProcCb         *hqP,
+U8                   tbIndex
+)
+#else
+PUBLIC S16 rgDHMRlsHqProcTB(cell, hqP, tbIndex)
+RgCellCb             *cell;
+RgDlHqProcCb         *hqP;
+U8                   tbIndex;
+#endif
+{
+    U8                    idx;
+#ifdef L2_OPTMZ
+    RgTfuDatReqTbInfo     *tb;   /* TB to be sent to CL/PHY*/
+   // U32 lchIdx, pduIdx;
+#endif
+
+   TRC2(rgDHMRlsHqProcTB)
+
+   if((tbIndex > RG_MAX_TB_PER_UE) ||
+      (tbIndex == 0))
+   {
+      RETVALUE(RFAILED);
+   }
+
+   hqP->tbInfo[tbIndex-1].numSchLch = 0;
+#ifndef L2_OPTMZ
+   if (hqP->tbInfo[tbIndex-1].tb)
+   {
+      rgDHMHdlBufFree(cell->macInst - RG_INST_START, &hqP->tbInfo[tbIndex-1].tb);
+   }
+#else
+   /* L2 Optimization for mUe/Tti:  macHdr, macCes and macPad mBuf pointers
+    * shall not be released. However, Inorder to release harq info/TB info,
+    * just Resetting rPtr and wPtr of these mbufs to db_base
+    */
+   tb = &(hqP->tbInfo[tbIndex-1].tb);
+   if (tb->tbPres == TRUE)
+   {
+      RG_FREE_TB(tb);
+   }
+#endif
+   hqP->tbInfo[tbIndex-1].schdTa.pres = FALSE;
+#ifdef LTE_ADV
+   hqP->tbInfo[tbIndex -1].sCellActCe.pres = FALSE;
+#endif
+
+   /* Decrementing might lead to roundoff error in case of say UE reset
+    * where all the HqProcs irrespective whether in use are called for rls.
+    * Hence to avoid the same shift operator is being used. */
+   hqP->numOfTBs = hqP->numOfTBs >> 1;
+   for(idx = 0; idx < 2; idx++)
+   {
+      if (hqP->tbInfo[tbIndex-1].sfLnkInfo[idx].sfLnk.node != NULLP)
+   {
+         cmLListDelFrm(&hqP->tbInfo[tbIndex-1].sfLnkInfo[idx].sf->tbs,
+               &(hqP->tbInfo[tbIndex-1].sfLnkInfo[idx].sfLnk));
+         hqP->tbInfo[tbIndex-1].sfLnkInfo[idx].sfLnk.node  = (PTR)NULLP;
+      printf("\nrgDHMRlsHqProcTB:: hqP %p \n", (Void *)hqP);
+   }
+      hqP->tbInfo[tbIndex-1].sfLnkInfo[idx].sf = NULLP;
+   }
+   /* Fix : syed It is better to reset these feilds
+    * corruption avoidance */
+   hqP->tbInfo[tbIndex-1].tbSz = 0;
+   hqP->tbInfo[tbIndex-1].contResCe = NOTPRSNT;
+   hqP->tbInfo[tbIndex-1].contResId = NULLP;
+
+   RETVALUE(ROK);
+} /* rgDHMRlsHqProc */
+
+/**
+ * @brief This function gets HARQ process with the given Id
+ *
+ * @details
+ *
+ *     Function: rgDHMGetHqProcFrmId
+ *     Purpose:  This function returns the HARQ process with the given ID.
+ *     Invoked by: ROM
+ *     
+ *  @param[in]  RgUeCb        *ue
+ *  @param[in]  U8            idx
+ *  @param[in]  RgDlHqProc    **hqP
+ *  @return  S16       
+ *         -#   ROK     if successful
+ *         -#   RFAILED otherwise
+ *
+ **/
+#ifdef ANSI
+PUBLIC S16 rgDHMGetHqProcFrmId
+(
+RgUeCb               *ue,
+U8                   idx,
+RgDlHqProcCb         **hqP
+)
+#else
+PUBLIC S16 rgDHMGetHqProcFrmId(ue, idx, hqP)
+RgUeCb               *ue;
+U8                   idx;
+RgDlHqProcCb         **hqP;
+#endif
+{
+   TRC2(rgDHMGetHqProcFrmId)
+
+   /* Pick the proc based on the index provided */
+   *hqP = (ue->dl.hqEnt.procs[idx]);
+
+   RETVALUE(ROK);
+} /* rgDHMGetHqProcFrmId */
+
+/*PRIVATE U32 dataAvl; */
+/**
+ * @brief Handler for sending data to PHY
+ *
+ * @details
+ *
+ *     Function : rgDHMSndDatReq
+ *     
+ *     This function shall send the MAC PDU built for the UE to TOM
+ *     when invoked as part of TTI processing and keep track of the number of
+ *     transmissions for this TB.
+ *     
+ *           
+ *  @param[in]  RgCellCb      *cell
+ *  @param[in]  RgDlHqProcCb  *hqE 
+ *  @param[out] RgErrInfo     *err 
+ *  @return     S16
+ *      -#ROK 
+ *      -#RFAILED 
+ **/
+#ifdef ANSI
+PUBLIC S16 rgDHMSndDatReq
+(
+RgCellCb        *cellCb,
+RgDlSf          *dlSf,
+RgTfuDatReqInfo *datInfo,
+RgDlHqProcCb   *hqP,
+RgErrInfo      *err 
+)
+#else
+PUBLIC S16 rgDHMSndDatReq(cellCb, dlSf, datInfo, hqP, err)
+RgCellCb        *cellCb;
+RgDlSf          *dlSf;
+RgTfuDatReqInfo *datInfo;
+RgDlHqProcCb    *hqP;
+RgErrInfo       *err;
+#endif
+{
+   U8 i;
+   Inst               inst = cellCb->macInst - RG_INST_START;
+   RgTfuDatReqPduInfo   *datReq;
+   RgBldPduInfo      bldPdu;
+   /*Added this variable to figure out that whether this UE data
+     has to be inclueded in the TFU Data request.*/
+   Bool  dataAvlblUe;
+
+   TRC2(rgDHMSndDatReq)
+  
+   dataAvlblUe = TRUE;
+   for(i=0;i< RG_MAX_TB_PER_UE;i++)
+   {
+         /* printf("\nDHMSndDatReq1: Rnti %d dlSfSchdTime(sfn sf) : (%d %d)\n"
+                "macCell(sfn sf): (%d %d) tbTimingInfo(sfn sf): (%d %d)\n"
+                "dlSf %p dlSf->tbs.count %d hqp %p tb %p\n",
+                             hqP->tbInfo[i].pdcch.rnti,
+                             dlSf->schdTime.sfn, dlSf->schdTime.subframe,
+                             cellCb->crntTime.sfn, cellCb->crntTime.subframe,
+                             hqP->tbInfo[i].timingInfo.sfn, 
+                             hqP->tbInfo[i].timingInfo.subframe,
+                             (Void *)dlSf, dlSf->tbs.count,
+                             (Void *)hqP,
+                             (Void *)hqP->tbInfo[i].tb);*/
+      /* Mukesh :: in case of rpepetiton this is not rerd*/
+      if (hqP->tbInfo[i].sfLnkInfo[dlSf->schdTime.subframe % 2].sf == dlSf)
+      {
+         /* Check if data from RLC had been received and got muxed. */
+#ifndef L2_OPTMZ
+         if (hqP->tbInfo[i].tb == NULLP) 
+#else
+         if (!(hqP->tbInfo[i].tb.tbPres)) 
+#endif
+         {
+#ifndef LTE_ADV
+            if (hqP->tbInfo[i].schdTa.pres == TRUE ||
+                  hqP->tbInfo[i].contResCe == PRSNT_NODEF)
+#else
+            if ((hqP->tbInfo[i].schdTa.pres == TRUE) ||
+                 (hqP->tbInfo[i].contResCe == PRSNT_NODEF) ||
+                 (hqP->tbInfo[i].sCellActCe.pres == TRUE))
+#endif
+            {
+               /* Data not received but ta needs to be sent. */
+               /* MUX TA and send it */
+               bldPdu.datReq    =  NULLP;
+               bldPdu.reqType   =  EVTTFUTTIIND;
+               bldPdu.schdTbSz  =  hqP->tbInfo[i].tbSz;
+               bldPdu.ta        =  hqP->tbInfo[i].schdTa;
+#ifdef LTE_ADV
+               bldPdu.sCellActCe= hqP->tbInfo[i].sCellActCe;
+#endif
+               /* changes for CR timer implementation*/
+               bldPdu.contResId =  hqP->tbInfo[i].contResId;
+               if (ROK != rgMUXBldPdu(inst,&bldPdu, &(hqP->tbInfo[i].tb), err))  
+               {
+                  RLOG1(L_ERROR, "MUXing failed for:  MacInst %d", inst);
+                  RLOG4(L_ERROR, "MUXing failed for:  time: %d/%d\
+                  procId %d ueId %d", hqP->tbInfo[i].timingInfo.sfn,
+                  hqP->tbInfo[i].timingInfo.subframe, hqP->procId, 
+                  hqP->tbInfo[i].pdcch.rnti);
+
+                  RETVALUE(RFAILED);
+               }
+            }
+            else   
+            {
+#ifdef LTEMAC_RGU_PAD
+               /* Data not received from RLC. Padding at MAC */
+               bldPdu.datReq    =  NULLP;
+               bldPdu.reqType   =  EVTTFUTTIIND;
+               bldPdu.schdTbSz  =  hqP->tbInfo[i].tbSz;
+               bldPdu.ta        =  hqP->tbInfo[i].schdTa;
+#ifdef LTE_ADV
+               bldPdu.sCellActCe= hqP->tbInfo[i].sCellActCe;
+#endif
+               bldPdu.ta.val    =  0;
+               bldPdu.contResId =  NULLP;
+
+               if (ROK != rgMUXBldPdu(inst,&bldPdu, &(hqP->tbInfo[i].tb), err))  
+               {
+                  RLOG1(L_ERROR, "MUXing failed for:  MacInst %d", inst);
+                  RLOG4(L_ERROR, "MUXing failed for:  time: %d/%d\
+                  procId %d ueId %d", hqP->tbInfo[i].timingInfo.sfn,
+                  hqP->tbInfo[i].timingInfo.subframe, hqP->procId, 
+                  hqP->tbInfo[i].pdcch.rnti);
+                  
+                  RETVALUE(RFAILED);
+               }
+#else
+               /*Padding is not done so data for this UE will not be
+                 included.*/
+               dataAvlblUe = FALSE;
+#endif
+            }
+         }
+         else
+         {
+         }
+      }
+      //else
+      {
+      }
+   }
+
+   /*If Data/Padding is not available for UE, then we can not include
+     any Data for this UE in TFU Data Request.*/
+   if(!dataAvlblUe)
+   {
+      /*Free up the HARQ process for this allocation.*/
+      /* Release First TB, as this would be anyway there*/
+      rgDHMRlsHqProcTB(cellCb, hqP, 1);
+      if(2 == hqP->numOfTBs)
+      {
+         rgDHMRlsHqProcTB(cellCb, hqP, 2);
+      }
+      
+      RETVALUE(ROK);
+   }
+
+   if (rgGetEventMem(inst,(Ptr *)&datReq, sizeof(TfuDatReqPduInfo),
+            &(datInfo->memCp)) != ROK)
+   {
+      RETVALUE(RFAILED);
+   }
+   /* Fill the TFU Dat Req with information from Harq Proc */
+  
+   rgDHMBldTfuDatReq(cellCb, dlSf, hqP, datReq);
+
+   /* MS_WORKAROUND for ccpu00122894 */
+   for(i=0;i< RG_MAX_TB_PER_UE;i++)
+   {
+      if (hqP->tbInfo[i].sfLnkInfo[dlSf->schdTime.subframe % 2].sf == dlSf)
+      {
+         cmLListDelFrm(&dlSf->tbs, &(hqP->tbInfo[i].sfLnkInfo[dlSf->schdTime.subframe % 2].sfLnk));
+         hqP->tbInfo[i].sfLnkInfo[dlSf->schdTime.subframe % 2].sfLnk.node = NULLP;
+         
+        
+        hqP->tbInfo[i].sfLnkInfo[dlSf->schdTime.subframe % 2].sf = NULLP;
+      }
+   }
+   cmLListAdd2Tail(&datInfo->pdus, &(datReq->lnk));
+   datReq->lnk.node = (PTR)datReq;
+
+   RETVALUE(ROK);
+}  /* rgDHMSndDatReq */
+
+/**
+ * @brief Function to handle RGU datReq received from ROM
+ *
+ * @details
+ *
+ *     Function : rgDHMHndlDedDatReq
+ *     
+ *     This function shall act on the datReq received on RGU. It shall 
+ *     store the data IDs for all the logical channels and get the MAC 
+ *     PDU built.
+ *     
+ *           
+ *  @param[in]  Inst        inst
+ *  @param[in]  RgDlHqProcCb   *hqProc 
+ *  @param[in]  RgRguDedDatReq *datReq
+ *  @param[out] RgErrInfo      *err
+ *  @return     S16
+ *      -# ROK 
+ *      -# RFAILED 
+ **/
+#ifdef ANSI
+PUBLIC S16 rgDHMHndlDedDatReq
+(
+Inst           inst,
+RgDlHqProcCb   *hqProc,
+RgRguDDatReqPerUe *datReq,
+RgDlSf            *dlSf,
+RgErrInfo      *err
+)
+#else
+PUBLIC S16 rgDHMHndlDedDatReq(inst,hqProc, datReq, dlSf, err)
+Inst           inst;
+RgDlHqProcCb   *hqProc;
+RgRguDDatReqPerUe *datReq;
+RgDlSf            *dlSf;
+RgErrInfo      *err;
+#endif
+{
+//   U32            len;
+   U8             i;
+   U8             j;
+   RgBldPduInfo   bldPdu;
+   U8             tbIndex;
+#ifdef L2_OPTMZ
+   RgTfuDatReqTbInfo     *tb;
+#endif
+
+   TRC2(rgDHMHndlDedDatReq);
+
+   tbIndex = (U8)(datReq->transId & 0x03);
+   /* Accept all the data requests even if delayed in case nothing
+    * has been sent earlier on the harq proc.
+    */
+   if((datReq->nmbOfTbs > RG_MAX_TB_PER_UE) ||
+         (tbIndex == 0))
+   {
+      /* release corresponding TBs from SF tbs List */
+      for(j=0;jnmbOfTbs;j++)
+      {
+         if (!(tbIndex & (j+1)))
+         {
+            j++;
+         } 
+         rgDHMRlsHqProcTB(rgCb[inst].cell, hqProc, (U8)(j+1));
+      }
+      RETVALUE(RFAILED);
+   }
+
+   for(i=0;inmbOfTbs;i++)
+   {
+      /* tbIndex 01 corresponds to presence of 1st TB
+       * 10 corresponds 2nd TB
+       * 11 corresponds two TBs of UE */
+      if (!(tbIndex & (i+1)))
+      {
+          continue;
+      }
+      if (hqProc->tbInfo[i].sfLnkInfo[dlSf->schdTime.subframe % 2].sfLnk.node == NULLP)
+      {
+         /* release corresponding TBs from SF tbs List */
+         for(j=0;jnmbOfTbs;j++)
+         {
+            if (!(tbIndex & (j+1)))
+            {
+               j++;
+            }
+            rgDHMRlsHqProcTB(rgCb[inst].cell, hqProc, (U8)(j+1));
+            printf("\nrgDHMHndlDedDatReq:: hqP %p \n", (Void *)hqProc);
+         }
+         RETVALUE(RFAILED);
+
+      }
+#ifndef L2_OPTMZ
+      RG_FREE_MSG(hqProc->tbInfo[i].tb);
+      /* L2 optimization for mUe/Tti: Pre-allocated mBuf pointers(macHdr, 
+       * macCes and MacPad) of harq TB need to be reset to db_base
+       */
+#else
+      tb = &hqProc->tbInfo[i].tb;
+      if (tb->tbPres == TRUE)
+      {
+         RG_FREE_TB(tb);
+      }
+#endif
+      bldPdu.datReq    =  datReq;
+      bldPdu.reqType   =  EVTRGUDDATREQ;
+      bldPdu.schdTbSz  =  hqProc->tbInfo[i].tbSz;
+      bldPdu.tbIndex   =  i+1;
+      bldPdu.ta        =  hqProc->tbInfo[i].schdTa;
+#ifdef LTE_ADV
+      bldPdu.sCellActCe= hqProc->tbInfo[i].sCellActCe;
+#endif
+      bldPdu.contResId =  NULLP;
+#ifdef LTE_L2_MEAS
+      /* Store tbId from RLC in DDatRequest */
+      hqProc->tbId[i] = datReq->datReqTb[i].tbId;
+
+
+      hqProc->status[i] =  FALSE;
+#endif 
+      if(rgMUXBldPdu(inst,&bldPdu, &(hqProc->tbInfo[i].tb), err) != ROK)
+      {
+         RLOG1(L_ERROR, "MUXing failed for:  MacInst %d", inst);
+         RLOG4(L_ERROR, "MUXing failed for:  time: %d/%d\
+               procId %d ueId %d", hqProc->tbInfo[i].timingInfo.sfn,
+               hqProc->tbInfo[i].timingInfo.subframe, hqProc->procId, 
+               hqProc->tbInfo[i].pdcch.rnti);
+
+         /* release corresponding TBs from SF tbs List */
+         for(j=0;jnmbOfTbs;j++)
+         {
+            if (!(tbIndex & (j+1)))
+            {
+               j++;
+            }
+            rgDHMRlsHqProcTB(rgCb[inst].cell, hqProc, (U8)(j+1));
+         }
+         RETVALUE(RFAILED);
+      }
+      /*
+      SFndLenMsg(hqProc->tbInfo[i].tb, &len);
+      */
+   }
+   RETVALUE(ROK);
+}  /* rgDHMHndlDedDatReq */
+
+/**
+ * @brief Function to handle RGU datReq received from ROM
+ *
+ * @details
+ *
+ *     Function : rgDHMHndlCmnDatReq
+ *     
+ *     This function shall act on the datReq received on RGU. It shall 
+ *     store the data IDs for all the logical channels and get the MAC 
+ *     PDU built.
+ *     
+ *           
+ *  @param[in]  Inst        inst
+ *  @param[in]  RgDlHqProcCb   *hqProc 
+ *  @param[in]  RgRguCmnDatReq *datReq
+ *  @param[out] RgErrInfo      *err
+ *  @return     S16
+ *      -# ROK 
+ *      -# RFAILED 
+ **/
+#ifdef ANSI
+PUBLIC S16 rgDHMHndlCmnDatReq
+(
+Inst           inst,
+RgDlHqProcCb   *hqProc,
+RgRguCmnDatReq *datReq,
+RgErrInfo      *err
+)
+#else
+PUBLIC S16 rgDHMHndlCmnDatReq(inst,hqProc, datReq, err)
+Inst           inst;
+RgDlHqProcCb   *hqProc;
+RgRguCmnDatReq *datReq;
+RgErrInfo      *err;
+#endif
+{
+   RgUstaDgn      dgn;
+   RgBldPduInfo   bldPdu;
+
+   TRC2(rgDHMHndlCmnDatReq)
+
+#ifndef L2_OPTMZ
+      if (hqProc->tbInfo[0].tb != NULLP)
+#else
+      /* If numLch is non zero means HQ Proc is busy*/
+      if (hqProc->tbInfo[0].tb.tbPres)
+#endif
+      {
+         /* datReq discarded. Generate an alarm */
+         rgFillDgnParams(inst,&dgn, LRG_USTA_DGNVAL_HARQ); 
+         rgLMMStaInd(inst,LCM_CATEGORY_PROTOCOL, LCM_EVENT_UI_INV_EVT,
+               LRG_CAUSE_HQ_PROC_BUSY, &dgn);
+         RETVALUE(RFAILED);
+      }
+
+   bldPdu.datReq    =  datReq;
+   bldPdu.reqType   =  EVTRGUCDATREQ;
+   bldPdu.schdTbSz  =  hqProc->tbInfo[0].tbSz;
+   bldPdu.ta        =  hqProc->tbInfo[0].schdTa;
+#ifdef LTE_ADV
+   bldPdu.sCellActCe= hqProc->tbInfo[0].sCellActCe;
+#endif
+
+   bldPdu.contResId  =  hqProc->tbInfo[0].contResId;
+
+   if(rgMUXBldPdu(inst,&bldPdu, &(hqProc->tbInfo[0].tb), err) != ROK)
+   {
+      RLOG1(L_ERROR, "MUXing failed for:  MacInst %d", inst); 
+      RLOG4(L_ERROR, "MUXing failed for: time: %d/%d\
+               procId %d ueId %d", hqProc->tbInfo[0].timingInfo.sfn,
+            hqProc->tbInfo[0].timingInfo.subframe, hqProc->procId, 
+            hqProc->tbInfo[0].pdcch.rnti);
+
+      RG_FREE_MSG(datReq->pdu);
+      RETVALUE(RFAILED);
+   }
+
+   RETVALUE(ROK);
+}  /* rgDHMHndlCmnDatReq */
+
+/**
+ * @brief Function to get consolidate grants and send consolidated grant to RLC
+ *
+ * @details
+ *
+ *     Function : rgDHMSndConsolidatedStaInd
+ *     
+ *     This function shall be invoked by Scheduler to trigger DHM to send a
+ *     consolidated status indication of all UE scheduled in a TTI as well as
+ *     send consolidated CStaInd for MSG4 and for all common channels(PCCH,
+ *     if RGR_SI_SCH is not defined then it includes BCH and BCCH also)
+ *     
+ *           
+ *  @param[in]  RgCellCb       *cell
+ *  @param[in]  RgInfUeInfo   *ueInfo,
+ *  @param[in]  CmLteTimingInfo timingInfo,
+ *  @param[out] RgErrInfo      err
+ *  @param[in]  RguCStaIndInfo   *cStaInd
+ *  @return     S16
+ *      -# ROK 
+ *      -# RFAILED 
+ **/
+ RgUeCb  *gUe =NULLP;
+#ifdef ANSI
+PUBLIC S16 rgDHMSndConsolidatedStaInd
+(
+RgCellCb        *cell,
+RgInfUeInfo     *ueInfo,
+CmLteTimingInfo timingInfo,
+RgErrInfo       *err
+)
+#else
+PUBLIC S16 rgDHMSndConsolidatedStaInd(cell, ueInfo, timingInfo, err)
+RgCellCb        *cell;
+RgInfUeInfo     *ueInfo;
+CmLteTimingInfo timingInfo;
+RgErrInfo       *err;
+#endif
+{
+   SuId            rguDlSpId;/*need to use spID instead of suID*/
+   U8              idx;
+   U8              ueIdx;
+   U8              lcIdx;
+   U8              tbIndex=0,idx1;
+   RgDlSf          *dlSf = &cell->subFrms[(timingInfo.subframe % RG_NUM_SUB_FRAMES)];
+   Inst            inst = cell->macInst - RG_INST_START;
+//   Bool            isDStaReqrd = FALSE;
+   RgRguDedStaInd  *dStaInd[rgCb[inst].numRguSaps] ;
+   RgUpSapCb      *rguDlSap[rgCb[inst].numRguSaps];
+
+   int lchBufSize =0;
+   RgUeCb         *ue;
+   RgDlHqProcCb   *hqP;
+   RgInfUeAlloc   *allocInfo;
+   U8             activeSapCnt = 0;
+   U8             staIndCnt    = 0;
+#ifdef LTE_ADV
+   Bool           hqPAdded     = FALSE;
+#endif
+#ifdef L2_OPTMZ
+   RgTfuDatReqTbInfo     *tb;   /* TB to be sent to CL/PHY*/
+#endif
+
+   TRC2(rgDHMSndConsolidatedStaInd)
+   cmMemset ((U8 *)dStaInd, 0, (sizeof(RgRguDedStaInd *) * rgCb[inst].numRguSaps));
+   cmMemset ((U8 *)rguDlSap, 0, (sizeof(RgUpSapCb  *) * rgCb[inst].numRguSaps));
+
+   /* Send StaInd for the scheduled UEs */
+   for(ueIdx = 0; ueIdx < ueInfo->numUes; ueIdx++)
+   {
+#ifdef LTE_ADV
+      hqPAdded = FALSE;
+#endif
+      if((ue=rgDBMGetUeCb (cell, ueInfo->allocInfo[ueIdx].rnti)) == NULLP)
+      {
+         /* Check in RachLst */
+         if((ue=rgDBMGetUeCbFromRachLst (cell, 
+                     ueInfo->allocInfo[ueIdx].rnti)) == NULLP)
+         {
+            RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,"CRNTI:%d No ueCb found", 
+                      ueInfo->allocInfo[ueIdx].rnti);
+            /*Fix: If one UE is not present dont return, look for the next.*/
+            continue;
+         }
+      }
+
+
+      rgDHMGetHqProcFrmId(ue,ueInfo->allocInfo[ueIdx].hqProcId,&hqP);
+      allocInfo = &ueInfo->allocInfo[ueIdx];
+      gUe = ue;
+
+      /* Fix : syed Avoid sending data for a RETX
+       * if initial TX data processing was unsuccessful */
+      if((allocInfo->tbInfo[0].isReTx == TRUE) &&
+            (hqP->tbInfo[0].tbSz == 0)) 
+      {
+         RLOG_ARG2(L_ERROR,DBG_CELLID,cell->cellId,
+               "CRNTI:%d RETX hqP(%d) tb(0) for a failed New Tx", 
+                  allocInfo->rnti, hqP->procId);        
+         continue;
+      }
+      if((allocInfo->tbInfo[1].isReTx == TRUE) &&
+            (hqP->tbInfo[1].tbSz == 0)) 
+      {
+         RLOG_ARG2(L_ERROR,DBG_CELLID,cell->cellId,
+                   "CRNTI:%d RETX hqP(%d) tb(1) for a failed New Tx", 
+                  allocInfo->rnti, hqP->procId);        
+         continue;
+      }
+
+      if(ue->rguDlSap != NULLP)
+      {
+          rguDlSpId = ue->rguDlSap->sapCfg.spId;
+      }else
+      {/* UeCb is from rachList */
+          rguDlSpId = cell->rguDlSap->sapCfg.spId;
+      }
+
+
+      for(idx=allocInfo->tbStrtIdx;((idx-allocInfo->tbStrtIdx) <\
+               allocInfo->nmbOfTBs); idx++)
+      {
+         RguCStaIndInfo  *cStaInd;
+#ifdef TFU_UPGRADE
+         /* LTE_ADV_FLAG_REMOVED_START */
+         hqP->tbInfo[idx].isEnbSFR = allocInfo->isEnbSFR;
+         /* update pA value */
+         hqP->tbInfo[idx].pa = allocInfo->pa;
+         /* LTE_ADV_FLAG_REMOVED_END */
+#endif
+
+         hqP->numOfTBs =  allocInfo->nmbOfTBs;
+         hqP->tbInfo[idx].sfLnkInfo[dlSf->schdTime.subframe % 2].sfLnk.node = (PTR)hqP;
+         hqP->tbInfo[idx].sfLnkInfo[dlSf->schdTime.subframe % 2].sf = dlSf;
+         cmLListAdd2Tail(&dlSf->tbs,&(hqP->tbInfo[idx].sfLnkInfo[dlSf->schdTime.subframe % 2].sfLnk));
+         /* Changes as part of performance testing*/
+         /*   hqP->numOfTBs++;*/
+         hqP->tbInfo[idx].doa = allocInfo->doa;
+         hqP->tbInfo[idx].txMode = allocInfo->txMode;
+         hqP->tbInfo[idx].puschRptUsd = allocInfo->puschRptUsd;
+         hqP->tbInfo[idx].puschPmiInfo = allocInfo->puschPmiInfo;
+#ifdef LTEMAC_SPS
+         hqP->tbInfo[idx].pdcch.rnti = allocInfo->pdcchRnti;
+#else
+         hqP->tbInfo[idx].pdcch.rnti = allocInfo->rnti;
+#endif
+         if(allocInfo->tbInfo[idx].isReTx == TRUE)
+         {
+            hqP->tbInfo[idx].pdcch.dci = allocInfo->dciInfo;
+            continue;
+         }
+
+         hqP->tbInfo[idx].timingInfo = timingInfo;
+         hqP->tbInfo[idx].pdcch.dci = allocInfo->dciInfo;
+#ifndef L2_OPTMZ
+         RG_FREE_MSG(hqP->tbInfo[idx].tb);
+#else
+         /* L2 optimization for mUe/Tti: Pre-allocated mBuf pointers(macHdr, 
+          * macCes and MacPad) of harq TB need to be reset to db_base
+          */
+         tb = &(hqP->tbInfo[idx].tb);
+         if (tb->tbPres == TRUE)
+         {
+            RG_FREE_TB(tb);
+         }
+#endif
+         hqP->tbInfo[idx].tbSz = allocInfo->tbInfo[idx].schdTbSz; 
+
+         hqP->tbInfo[idx].schdTa.pres = allocInfo->tbInfo[idx].ta.pres;
+         hqP->tbInfo[idx].schdTa.val  = allocInfo->tbInfo[idx].ta.val;
+
+#ifdef LTE_ADV
+         hqP->tbInfo[idx].sCellActCe.pres = allocInfo->tbInfo[idx].sCellActCe.pres;
+         hqP->tbInfo[idx].sCellActCe.val  = allocInfo->tbInfo[idx].sCellActCe.val;
+#endif
+
+#ifdef LTE_ADV 
+         if(( hqPAdded == TRUE) || (ROK == rgLaaPushHqPToScellLst(allocInfo,cell,timingInfo)))
+         {
+            hqPAdded = TRUE;
+            continue;
+         }
+#endif
+         if (allocInfo->tbInfo[idx].schdDat[0].lcId == RG_CCCH_LCID)        
+         {
+#ifndef L2_OPTMZ
+            RG_FREE_MSG(hqP->tbInfo[idx].tb);
+#else
+           /* L2 optimization for mUe/Tti: Pre-allocated mBuf pointers(macHdr, 
+            * macCes and MacPad) of harq TB need to be reset to db_base
+            */
+           tb = &(hqP->tbInfo[idx].tb);
+
+           if (tb->tbPres == TRUE)
+           {
+              RG_FREE_TB(tb);
+           }
+#endif
+            hqP->tbInfo[0].contResCe  = allocInfo->tbInfo[0].contResCe;
+            if(allocInfo->tbInfo[0].contResCe)
+            {
+               hqP->tbInfo[0].contResId = &ue->contResId;
+            }
+
+
+            if(allocInfo->tbInfo[idx].numSchLch == 0)
+            {
+               RLOG_ARG2(L_DEBUG,DBG_CELLID,cell->cellId,
+                        "UEID:%d MSG4 with only contResId hqP(%d)",
+               			allocInfo->rnti,
+                     	hqP->procId);
+               hqP->tbInfo[idx].numSchLch = 0;
+               continue;
+            }
+
+            /* Increamenting the tbIndex instead of
+               assigning it to constant */
+            tbIndex++;
+
+
+            hqP->tbInfo[idx].numSchLch = 1;
+            hqP->tbInfo[idx].schdData[0].lcId = 
+               allocInfo->tbInfo[idx].schdDat[0].lcId;
+            hqP->tbInfo[idx].schdData[0].schdSz = 
+               allocInfo->tbInfo[idx].schdDat[0].numBytes;
+
+           // if(cStaInd == NULLP)
+            {
+               if ((rgAllocShrablSBuf(inst,(Data**)&cStaInd, sizeof(RguCStaIndInfo))) != ROK)
+               {
+                  err->errType  = RGERR_DHM_SND_STA_IND;
+                  err->errCause = RG_DHM_MEM_ALLOC_FAIL;
+                  RETVALUE(RFAILED); 
+               }
+            }
+
+            idx1 = (hqP->procId << 2) | tbIndex;
+            
+            cStaInd->cellId    = cell->cellId;
+            cStaInd->rnti      = allocInfo->rnti;
+            cStaInd->lcId      = cell->dlCcchId;
+            cStaInd->transId   = (timingInfo.sfn << 16) | 
+                                 (timingInfo.subframe << 8) | idx1;
+               /* ADD Changes for Downlink UE Timing Optimization */
+#ifdef LTEMAC_DLUE_TMGOPTMZ
+            dlSf->remDatReqCnt++;
+#endif
+            RLOG_ARG3(L_DEBUG,DBG_CELLID,cell->cellId,
+		               "RNTI:%d UE:MSG4 grant for CCCH hqP(%d) LCID:%d",
+                     allocInfo->rnti, 
+                     hqP->procId,
+		               cStaInd->lcId);       
+            /* Fix : syed Avoid return param for interface prim and
+             * proceed for other UEs. For the failed UE, MAC shall
+             * do padding. */
+            rgUIMSndCmnStaInd(cell->macInst,cell->rguDlSap,cStaInd);
+            break;
+         }
+         else
+         {
+            tbIndex+=idx+1;
+#ifndef L2_OPTMZ
+            RG_FREE_MSG(hqP->tbInfo[idx].tb);
+#else
+            /* L2 optimization for mUe/Tti: Pre-allocated mBuf pointers(macHdr, 
+             * macCes and MacPad) of harq TB need to be reset to db_base
+             */
+            tb = &(hqP->tbInfo[idx].tb);
+            if (tb->tbPres == TRUE)
+            {  
+               RG_FREE_TB(tb);
+            }
+#endif
+
+            if((NULLP == dStaInd[rguDlSpId]) && (allocInfo->tbInfo[idx].numSchLch))
+            {
+               if ((rgAllocShrablSBuf (inst,(Data**)&dStaInd[rguDlSpId], sizeof(RguDStaIndInfo))) != ROK)
+               {
+                  err->errType  = RGERR_DHM_SND_STA_IND;
+                  err->errCause = RG_DHM_MEM_ALLOC_FAIL;
+                  /* Need to return as memory allocation will fail for other UEs also*/
+                  RETVALUE(RFAILED);
+               }
+               dStaInd[rguDlSpId]->nmbOfUeGrantPerTti = 0;
+               rguDlSap[rguDlSpId] = ue->rguDlSap;
+               activeSapCnt++;
+            }
+
+            for (lcIdx = 0; 
+                  lcIdx < allocInfo->tbInfo[idx].numSchLch; lcIdx++)
+            {
+               hqP->tbInfo[idx].schdData[lcIdx].lcId = 
+                  allocInfo->tbInfo[idx].schdDat[lcIdx].lcId;
+               if (hqP->tbInfo[idx].schdData[lcIdx].lcId == 0)
+               {
+                  RLOG_ARG2(L_ERROR,DBG_CELLID,cell->cellId, 
+                        "CCCH grant in DStaInd for LCID:%d CRNTI:%d",
+                        hqP->tbInfo[idx].schdData[lcIdx].lcId,allocInfo->rnti);
+               }
+               hqP->tbInfo[idx].schdData[lcIdx].schdSz = 
+                  allocInfo->tbInfo[idx].schdDat[lcIdx].numBytes;
+               if(dStaInd[rguDlSpId])
+               {
+                  dStaInd[rguDlSpId]->staInd[dStaInd[rguDlSpId]->nmbOfUeGrantPerTti].staIndTb[idx].\
+                  lchStaInd[lcIdx].lcId = allocInfo->tbInfo[idx].\
+                  schdDat[lcIdx].lcId;
+                  dStaInd[rguDlSpId]->staInd[dStaInd[rguDlSpId]->nmbOfUeGrantPerTti].staIndTb[idx].\
+                  lchStaInd[lcIdx].totBufSize = allocInfo->tbInfo[idx].\
+                  schdDat[lcIdx].numBytes;
+               }
+
+               lchBufSize+=allocInfo->tbInfo[idx].schdDat[lcIdx].numBytes;
+            }
+            hqP->tbInfo[idx].numSchLch = 
+               allocInfo->tbInfo[idx].numSchLch;
+            if(dStaInd[rguDlSpId])
+            {
+               dStaInd[rguDlSpId]->staInd[dStaInd[rguDlSpId]->nmbOfUeGrantPerTti].staIndTb[idx].nmbLch =
+                  allocInfo->tbInfo[idx].numSchLch;
+#ifdef LTE_L2_MEAS
+               dStaInd[rguDlSpId]->staInd[dStaInd[rguDlSpId]->nmbOfUeGrantPerTti].staIndTb[idx].tbId =
+                  hqP->tbId[idx]; 
+#endif
+            }
+            lchBufSize=0;
+         }
+      }
+      //if((dStaInd) && (tbIndex) && (isDStaReqrd == TRUE))
+      if((dStaInd[rguDlSpId]) && (tbIndex))
+      {
+         idx1 = (hqP->procId << 2) | tbIndex;
+         /* Create RguDStaInd struct and send to UIM */
+         dStaInd[rguDlSpId]->staInd[dStaInd[rguDlSpId]->nmbOfUeGrantPerTti].rnti    = allocInfo->rnti;
+         /*
+            dStaInd->transId = (hqP->timingInfo.sfn << 16) | 
+            (hqP->timingInfo.subframe << 8) | hqP->procId;
+          */
+         dStaInd[rguDlSpId]->staInd[dStaInd[rguDlSpId]->nmbOfUeGrantPerTti].transId = (timingInfo.sfn << 16) | 
+            (timingInfo.subframe << 8) | idx1;
+         dStaInd[rguDlSpId]->staInd[dStaInd[rguDlSpId]->nmbOfUeGrantPerTti].nmbOfTbs = hqP->numOfTBs;
+#ifdef LTE_ADV
+         dStaInd[rguDlSpId]->staInd[dStaInd[rguDlSpId]->nmbOfUeGrantPerTti].fillCtrlPdu = allocInfo->fillCtrlPdu;
+#endif        
+         /*increment num of UE as staInd is prepared for it */
+         dStaInd[rguDlSpId]->nmbOfUeGrantPerTti++;
+         /* ADD Changes for Downlink UE Timing Optimization */
+#ifdef LTEMAC_DLUE_TMGOPTMZ
+         dlSf->remDatReqCnt++;
+#endif
+      }
+      //isDStaReqrd = FALSE;
+      tbIndex = 0;
+   }
+
+   for(idx = 0; idx < rgCb[inst].numRguSaps ; idx++)
+   {
+      if(dStaInd[idx] != NULLP)
+      {
+         dStaInd[idx]->cellId  = cell->cellId;
+         /* Fix : syed Avoid return param for interface prim and
+          * proceed for other UEs. For the failed UE, MAC shall
+          * do padding. */
+         rgUIMSndDedStaInd(inst,rguDlSap[idx],dStaInd[idx]);
+   
+         staIndCnt++;
+         if(staIndCnt == activeSapCnt)
+            break;/* all valid staind are considered */
+      }
+
+   }
+   RETVALUE(ROK);
+}  /* rgDHMSndConsolidatedStaInd */
+
+
+/**
+ * @brief Function to handle building the TFU Data Request
+ *
+ * @details
+ *
+ *     Function : rgDHMBldTfuDatReq
+ *     
+ *     This function builds the TFU Data Request with the details 
+ *     present in HARQ Process.
+ *           
+ *  @param[in]  RgDlHqProcCb     *hqP 
+ *  @param[out] TfuDatReqPduInfo  *datReq 
+ *  @return     Void
+ *              None 
+ **/
+//U8 crashFlag = 0;
+#ifdef ANSI
+PRIVATE Void rgDHMBldTfuDatReq
+(
+RgCellCb           *cellCb,
+RgDlSf             *dlSf,
+RgDlHqProcCb       *hqP,
+RgTfuDatReqPduInfo *datReq
+)
+#else
+PRIVATE Void rgDHMBldTfuDatReq(cellCb, dlSf, hqP, datReq)
+RgCellCb           *cellCb;
+RgDlSf             *dlSf;
+RgDlHqProcCb       *hqP;
+RgTfuDatReqPduInfo *datReq;
+#endif
+{
+
+#ifndef L2_OPTMZ
+#if !(!(defined TENB_ACC) && !(defined LTE_PAL_ENB))
+   Inst inst;
+#elif defined(TENB_T2K3K_SPECIFIC_CHANGES) && defined(LTE_TDD)
+   Inst inst;
+#endif
+#endif
+
+   U8 i;
+
+#ifdef L2_OPTMZ
+   U32 lchIdx, pduIdx;
+#endif
+   TRC2(rgDHMBldTfuDatReq)
+ 
+   datReq->nmbOfTBs = 0;
+#ifndef L2_OPTMZ
+#if !(!(defined TENB_ACC) && !(defined LTE_PAL_ENB))
+   inst = cellCb->macInst - RG_INST_START;
+#elif defined(TENB_T2K3K_SPECIFIC_CHANGES) && defined(LTE_TDD)
+   inst = cellCb->macInst - RG_INST_START;
+#endif
+#endif
+   /*MS_WORKAROUND  for ccpu00123904*/
+   datReq->isTApres = FALSE;
+#ifdef TFU_ALLOC_EVENT_NO_INIT
+#ifndef L2_OPTMZ   
+   datReq->mBuf[0] = 0;
+   datReq->mBuf[1] = 0;
+#endif    
+#endif
+ 
+   for(i=0;itbInfo[i].sfLnkInfo[dlSf->schdTime.subframe % 2].sf == dlSf) &&
+          (hqP->tbInfo[i].tb != NULLP))
+#else
+      if ((hqP->tbInfo[i].sfLnkInfo[dlSf->schdTime.subframe % 2].sf == dlSf) &&
+           RgUtlIsTbMuxed(&(hqP->tbInfo[i].tb)))
+#endif
+      {
+
+         datReq->rnti           =  hqP->tbInfo[i].pdcch.rnti;
+         datReq->dciInfo        =  hqP->tbInfo[i].pdcch.dci;
+         datReq->doa            =  hqP->tbInfo[i].doa;
+         datReq->transMode      =  hqP->tbInfo[i].txMode;
+         datReq->puschRptUsd    =  hqP->tbInfo[i].puschRptUsd;
+         datReq->puschPmiInfo   =  hqP->tbInfo[i].puschPmiInfo;
+         /*MS_WORKAROUND  for ccpu00123904*/
+         if (hqP->tbInfo[i].schdTa.pres)
+         {
+            datReq->isTApres       =  TRUE; 
+         }
+#ifdef   TFU_UPGRADE
+         /* update pA value */
+         datReq->pa             =  hqP->tbInfo[i].pa;
+#endif
+         /* LTE_ADV_FLAG_REMOVED_START */
+         datReq->isEnbSFR       =  hqP->tbInfo[i].isEnbSFR;
+         /* LTE_ADV_FLAG_REMOVED_END */
+#ifndef L2_OPTMZ
+#if (!(defined TENB_ACC) && !(defined LTE_PAL_ENB))  /* ABHI */ /* This is only temp fix. It needs to be removed
+                                after rebasing to MAC CCB */
+#ifdef BRDCM
+         datReq->mBuf[i] = hqP->tbInfo[i].tb;
+#else
+         /* Intel Tdd- Commenting out the Optimization for direct Access of 
+          * mBuf Index */
+         /*Proper clean-up needed as this needs long stability tests
+          * in all SoCs*/
+#if defined(TENB_T2K3K_SPECIFIC_CHANGES) && defined(LTE_TDD)
+         SIncMsgRef(hqP->tbInfo[i].tb, RG_GET_MEM_REGION(rgCb[inst]),
+               RG_GET_MEM_POOL(rgCb[inst]), &datReq->mBuf[i]); 
+#else
+         datReq->mBuf[i] = hqP->tbInfo[i].tb;
+#endif
+#endif/*BRDCM*/
+#else
+         SIncMsgRef(hqP->tbInfo[i].tb, RG_GET_MEM_REGION(rgCb[inst]),
+               RG_GET_MEM_POOL(rgCb[inst]), &datReq->mBuf[i]);
+#endif
+         {
+            MsgLen   dbgBufLen;
+            if(SFndLenMsg(datReq->mBuf[i], &dbgBufLen))
+            {
+               if(dbgBufLen == 0)
+               {              
+                  RLOG_ARG4(L_ERROR,DBG_CELLID,cellCb->cellId,
+			                  "RNTI:%d SFN:%d subframe:%d tbIdx:%d Sdu Length 0 ",
+                    	      datReq->rnti,
+            			      hqP->tbInfo[i].timingInfo.sfn,
+			                  hqP->tbInfo[i].timingInfo.subframe,i);
+                  RLOG_ARG3(L_ERROR,DBG_CELLID,cellCb->cellId,
+                   	      "taPres [%d] numOfTbs [%d] format[%d]",
+                   	      datReq->isTApres, 
+                           hqP->numOfTBs, 
+                           datReq->dciInfo.format);  
+               }              
+            }  
+         }
+#else
+         /* L2 optimization for mUe/Tti: Removing SIncMsgRef to avoid additional
+          * mBuf allocation. MAC header, MAC Ces, MAC PDU per LCH per TB Per UE
+          * and MAC padding Mbufs are being sent to CL. Populating these Ptrs
+          * From TB Info to TfuDatReq
+          */
+         datReq->tbInfo[i].tbPres =  TRUE;
+         datReq->tbInfo[i].tbSize =  hqP->tbInfo[i].tbSz;
+         datReq->tbInfo[i].macHdr =  hqP->tbInfo[i].tb.macHdr;
+         datReq->tbInfo[i].macCes =  hqP->tbInfo[i].tb.macCes;
+         datReq->tbInfo[i].numLch =  hqP->tbInfo[i].tb.numLch;
+         for(lchIdx = 0; lchIdx < hqP->tbInfo[i].tb.numLch; lchIdx++)
+         {
+            datReq->tbInfo[i].lchInfo[lchIdx].numPdu = hqP->tbInfo[i].tb.\
+                                                       lchInfo[lchIdx].numPdu;
+            for(pduIdx = 0; pduIdx < hqP->tbInfo[i].tb.lchInfo[lchIdx].numPdu;\
+                  pduIdx++)
+            {
+               datReq->tbInfo[i].lchInfo[lchIdx].mBuf[pduIdx] =
+                  hqP->tbInfo[i].tb.lchInfo[lchIdx].mBuf[pduIdx];
+            }
+         }
+        // datReq->tbInfo[i].macPad  =  hqP->tbInfo[i].tb.macPad;
+         datReq->tbInfo[i].padSize =  hqP->tbInfo[i].tb.padSize;
+        // prc_trace_format_string(0x40,3,"TfuDatReq:RNTI=%d TbIdx=%d TbSize=%d PdSz=(%d) macHdraddr: (%p) macCEAddr: (%p) noLch=(%d)",datReq->rnti, i,
+          //     hqP->tbInfo[i].tbSz, datReq->tbInfo[i].padSize, datReq->tbInfo[i].macHdr, datReq->tbInfo[i].macCes, datReq->tbInfo[i].numLch);
+
+#endif
+         datReq->nmbOfTBs++;
+      }
+   }
+   RETVOID;
+}  /* rgDHMBldTfuDatReq */
+
+
+#ifdef L2_OPTMZ
+/**
+ * @brief This function releases a HARQ process
+ *
+ * @details
+ *
+ *     Function: rgDHMFreeHqProcTB
+ *     Purpose:  This function returns a HARQ process to HARQ Entity 
+ *               in the DL direction.
+ *     
+ *               1. Add the HARQ process to the free queue.
+ *     Invoked by: scheduler and HARQ processing
+ *     
+ *  @param[in]  RgDlHqProc    *hqP
+ *  @return  Void      
+ *
+ **/
+#ifdef ANSI
+PUBLIC S16 rgDHMFreeHqProcTB
+(
+RgDlHqProcCb         *hqP,
+U8                   tbIndex
+)
+#else
+PUBLIC S16 rgDHMFreeHqProcTB(hqP, tbIndex)
+RgDlHqProcCb         *hqP;
+U8                   tbIndex;
+#endif
+{
+   RgTfuDatReqTbInfo     *tb;   /* TB to be sent to CL/PHY*/
+   U8                    idx;
+
+   TRC2(rgDHMFreeHqProcTB)
+
+   if((tbIndex > RG_MAX_TB_PER_UE) ||
+      (tbIndex == 0))
+   {
+      RETVALUE(RFAILED);
+   }
+
+   tb = &(hqP->tbInfo[tbIndex-1].tb);
+   RG_FREE_MSG(tb->macHdr);
+   RG_FREE_MSG(tb->macCes);
+
+   for(idx = 0; idx < 2; idx++)
+   {
+      if (hqP->tbInfo[tbIndex-1].sfLnkInfo[idx].sfLnk.node != NULLP)
+   {
+         cmLListDelFrm(&hqP->tbInfo[tbIndex-1].sfLnkInfo[idx].sf->tbs,
+               &(hqP->tbInfo[tbIndex-1].sfLnkInfo[idx].sfLnk));
+         hqP->tbInfo[tbIndex-1].sfLnkInfo[idx].sfLnk.node  = (PTR)NULLP;
+      printf("\nrgDHMFreeHqProcTB:: hqP %p \n", (Void *)hqP);
+   }
+      hqP->tbInfo[tbIndex-1].sfLnkInfo[idx].sf = NULLP;
+   }
+   RETVALUE(ROK);
+}
+#endif
+
+
+
+/**
+ * @brief Handler for freeing up the harq related information from ueCb
+ *
+ * @details
+ *
+ *     Function : rgDHMFreeUe
+ *     
+ *     This function shall free up the HARQ specific information from ueCb.
+ *           
+ *  @param[in]  Inst        inst
+ *  @param[in]  RgDlHqEnt     *hqE 
+ *
+ *  @return     None.
+ *
+ **/
+#ifdef ANSI
+PUBLIC Void rgDHMFreeUe
+(
+Inst               inst,
+RgDlHqEnt          *hqE
+)
+#else
+PUBLIC Void rgDHMFreeUe(inst,hqE)
+Inst               inst;
+RgDlHqEnt          *hqE;
+#endif
+{
+   U8             i;
+   TRC2(rgDHMFreeUe)
+
+   if(hqE->procs)
+   {
+      /* Free all the memory associated with HARQ */
+      for (i=0; i < hqE->numHqProcs; i++)
+      {
+#ifndef L2_OPTMZ
+         rgDHMRlsHqProcTB(rgCb[inst].cell, hqE->procs[i], 1);
+         rgDHMRlsHqProcTB(rgCb[inst].cell, hqE->procs[i], 2);
+#else
+         rgDHMFreeHqProcTB(hqE->procs[i], 1);
+         rgDHMFreeHqProcTB(hqE->procs[i], 2);
+#endif
+         
+         rgFreeSBuf(inst,(Data **)&(hqE->procs[i]), sizeof(RgDlHqProcCb));
+#ifdef LTE_ADV
+         rgDHMFreeSavedHqP(inst,hqE,i);
+#endif
+      }
+
+      /*ccpu00117052 - MOD - Passing double pointer for proper NULLP
+                            assignment */
+   }
+
+   RETVOID;
+
+}  /* rgDHMFreeUe */
+/**
+ * @brief Function for handling RaResp request received from scheduler to MAC
+ *
+ * @details
+ *
+ *     Function : RgSchMacRstHqEntReq
+ *     
+ *     This function shall be invoked whenever a sec cell of an ue
+ *     is deactivated. MAC needs to reset the harqentity associated 
+ *     with the deactivated scell of the ue
+ *     
+ *           
+ *  @param[in] Pst             *pst
+ *  @param[in] RgInfResetHqEnt *hqEntInfo
+ *  @return  S16
+ *      -# ROK 
+ **/
+#ifdef ANSI
+PUBLIC S16 RgSchMacRstHqEntReq
+(
+Pst*                 pst,    
+RgInfResetHqEnt*     hqEntInfo
+)
+#else
+PUBLIC S16 RgSchMacRstHqEntReq(pst, hqEntInfo)
+Pst*                 pst;
+RgInfResetHqEnt*     hqEntInfo;
+#endif
+{
+   Inst      inst;
+   RgCellCb  *cell;
+   RgUeCb    *ue;
+
+   inst = pst->dstInst - RG_INST_START;
+
+   if (((cell = rgCb[inst].cell) == NULLP) ||
+       (rgCb[inst].cell->cellId != hqEntInfo->cellId))
+   {
+      RGDBGERRNEW(inst,(rgPBuf(inst), "For user [%d]Cell does not exist %d\n",
+                hqEntInfo->crnti,hqEntInfo->cellId));
+      RETVALUE(RFAILED);
+   }
+
+   if ((ue = rgDBMGetUeCb(cell, hqEntInfo->crnti)) == NULLP)
+   {
+      RGDBGERRNEW(inst,(rgPBuf(inst), "[%d]UE does not exist for this hqEntInfo\n",
+                       hqEntInfo->crnti));
+      RETVALUE(RFAILED);
+   }
+
+   rgDHMUeReset(cell, &ue->dl.hqEnt);
+
+   RETVALUE(ROK);
+}
+U32 gSaveVal;
+
+/**
+ * @brief Function for handling RaResp request received from scheduler to MAC
+ *
+ * @details
+ *
+ *     Function : RgSchMacRlsHqReq
+ *     
+ *     This function shall be invoked whenever scheduler is done with the
+ *     allocations of random access responses for a subframe.
+ *     This shall invoke RAM to create ueCbs for all the rapIds allocated and 
+ *     shall invoke MUX to create RAR PDUs for raRntis allocated.
+ *     
+ *           
+ *  @param[in] CmLteCellId         cellId,
+ *  @param[in] CmLteTimingInfo     timingInfo,
+ *  @param[in] RaRespInfo          *rarInfo
+ *  @return  S16
+ *      -# ROK 
+ **/
+#ifdef ANSI
+PUBLIC S16 RgSchMacRlsHqReq
+(
+Pst                 *pst,
+RgInfRlsHqInfo      *rlshqUeInfo
+)
+#else
+PUBLIC S16 RgSchMacRlsHqReq(pst, rlshqUeInfo)
+Pst                 *pst;
+RgInfRlsHqInfo      *rlshqUeInfo;
+#endif
+{
+   Inst           inst;
+   RgCellCb       *cell = NULLP;
+   RgUeCb         *ue;
+   RgDlHqProcCb   *hqP;
+   U8             idx1,idx2;
+#ifdef LTE_L2_MEAS
+   U8                tbId;
+   RguHarqStatusInd  hqStaInd;
+   Bool              isValidTbId = FALSE;
+#endif
+   U32        startTime=0;
+   
+   TRC2(RgSchMacRlsHqReq)
+
+   RG_IS_INST_VALID(pst->dstInst);
+   inst = pst->dstInst - RG_INST_START;
+   cell  = rgCb[inst].cell;
+   /*starting Task*/
+   SStartTask(&startTime, PID_MAC_AM_HARQ_RLS);
+
+   if(NULLP == rlshqUeInfo)
+   {
+      RETVALUE(RFAILED);
+   }
+
+   if((cell  == NULLP)
+      ||( cell->cellId != rlshqUeInfo->cellId))
+   {
+       
+      RLOG_ARG0(L_ERROR,DBG_CELLID,rlshqUeInfo->cellId,
+                "No cellCb found with cellId");
+      RETVALUE(RFAILED);
+   }
+
+   if(NULLP == rlshqUeInfo->ueHqInfo)
+   {
+      RETVALUE(RFAILED);
+   }
+
+   for(idx1 = 0; idx1 < rlshqUeInfo->numUes; idx1++)
+   {
+      if((ue=rgDBMGetUeCb (cell, rlshqUeInfo->ueHqInfo[idx1].rnti)) == NULLP)
+      {
+         /* Check in RachLst */
+         if((ue=rgDBMGetUeCbFromRachLst (cell, 
+                     rlshqUeInfo->ueHqInfo[idx1].rnti)) == NULLP)
+         {
+            RLOG_ARG1(L_ERROR,DBG_CELLID,rlshqUeInfo->cellId, "CRNTI:%d No ueCb found",
+                     rlshqUeInfo->ueHqInfo[idx1].rnti);
+            continue;
+         }
+      }
+#ifdef LTE_ADV
+#ifdef LAA_DBG
+     if ((rlshqUeInfo->ueHqInfo[idx1].rlsOperationType && !gSaveVal) || (rlshqUeInfo->ueHqInfo[idx1].hqProcId > 8))
+      {
+         int *p = NULL;
+         RLOG_ARG1(L_INFO," SPURIOUS CALLL !!!! procId %d \n", rlshqUeInfo->ueHqInfo[idx1].hqProcId);
+
+
+       printf ("RgSchMacRlsHqReq cell %d : numUes %d idx %d rnti %d hqProc %d numTbs %d tbid[0] %d tbid[1] %d rlsopr %d \n",
+      cell->cellId,
+       rlshqUeInfo->numUes,
+       idx1,
+       rlshqUeInfo->ueHqInfo[idx1].rnti,
+       rlshqUeInfo->ueHqInfo[idx1].hqProcId,
+       rlshqUeInfo->ueHqInfo[idx1].numOfTBs,
+       rlshqUeInfo->ueHqInfo[idx1].tbId[0],
+       rlshqUeInfo->ueHqInfo[idx1].tbId[1],
+       rlshqUeInfo->ueHqInfo[idx1].rlsOperationType);
+      
+         *p = 10; 
+      }
+#endif
+      gSaveVal = 0;
+
+
+      RgSchMacHndlRelReq(cell, ue, &rlshqUeInfo->ueHqInfo[idx1]);
+
+      if (RGINF_RLS_HQ_DEL_TB == rlshqUeInfo->ueHqInfo[idx1].rlsOperationType)
+      {
+         /* If REQ is to DEL the saved TBs no need to free the HqP as it's already
+            freed up earlier */
+         continue;
+      }
+#endif /* LTE_ADV */
+      rgDHMGetHqProcFrmId(ue,rlshqUeInfo->ueHqInfo[idx1].hqProcId,&hqP);
+      if(rlshqUeInfo->ueHqInfo[idx1].status[0] != TRUE)
+      {
+         rgCb[inst].genSts.numHarqFail++;
+      }
+     
+#ifdef LTE_L2_MEAS
+      hqStaInd.cellId = cell->cellId;
+      hqStaInd.ueId = rlshqUeInfo->ueHqInfo[idx1].rnti;
+      hqStaInd.numTbs = rlshqUeInfo->ueHqInfo[idx1].numOfTBs;
+#endif
+
+      for(idx2=0; idx2 < rlshqUeInfo->ueHqInfo[idx1].numOfTBs; idx2++)
+      {
+#ifdef LTE_L2_MEAS
+         /* Fill the hq sta Ind stucture. Need to send the Status Ind for only
+          those TBID's reported by Scheduler*/
+            tbId = rlshqUeInfo->ueHqInfo[idx1].tbId[idx2];
+            if (hqP->tbId[tbId-1] != RGU_INVALID_TBID)
+            {
+            /* Fill the correct Sn Map corresponding to the TBID */
+            hqStaInd.tbId[idx2] = hqP->tbId[tbId-1];
+            hqStaInd.status[idx2] = rlshqUeInfo->ueHqInfo[idx1].status[idx2];
+               isValidTbId = TRUE;
+            }
+#endif
+         if(rgDHMRlsHqProcTB(cell, hqP, 
+               rlshqUeInfo->ueHqInfo[idx1].tbId[idx2]) != ROK)
+         {
+            RLOG_ARG1(L_ERROR,DBG_CELLID,rlshqUeInfo->cellId,
+                  "CRNTI:%d Failure in releasing hq TB",
+                  rlshqUeInfo->ueHqInfo[idx1].rnti);
+            continue;
+         }
+      }
+
+#ifdef LTE_L2_MEAS
+
+         if (isValidTbId)
+         {
+            if(ue->rguDlSap)
+            {
+               RgUiRguHqStaInd(&(ue->rguDlSap->sapCfg.sapPst),
+                     ue->rguDlSap->sapCfg.suId,
+                     &hqStaInd);
+            }
+            else
+            {/* Ue is from rach list*/
+               RgUiRguHqStaInd(&(cell->rguDlSap->sapCfg.sapPst),
+                     cell->rguDlSap->sapCfg.suId,
+                     &hqStaInd);
+            }
+         }
+#endif
+   } /* end of ues loop */
+
+   /*starting Task*/
+   SStopTask(startTime,PID_MAC_AM_HARQ_RLS);
+
+   RETVALUE(ROK);
+} /* end of RgSchMacRlsHqReq */
+
+
+/**********************************************************************
+ 
+         End of file
+**********************************************************************/
diff --git a/src/5gnrmac/rg_dux.c b/src/5gnrmac/rg_dux.c
new file mode 100755
index 000000000..2498f8170
--- /dev/null
+++ b/src/5gnrmac/rg_dux.c
@@ -0,0 +1,682 @@
+/*******************************************************************************
+################################################################################
+#   Copyright (c) [2017-2019] [Radisys]                                        #
+#                                                                              #
+#   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.                                             #
+################################################################################
+*******************************************************************************/
+
+/************************************************************************
+ 
+     Name:     LTE-MAC layer
+  
+     Type:     C source file
+  
+     Desc:     C source code for Entry point fucntions
+  
+     File:    rg_dux.c 
+  
+**********************************************************************/
+
+/** @file rg_dux.c
+@brief This module handles de-multiplexing of the data recieved at MAC.
+*/
+
+static const char* RLOG_MODULE_NAME="MAC";
+static int RLOG_FILE_ID=176;
+static int RLOG_MODULE_ID=4096;
+/* header include files -- defines (.h) */
+#include "envopt.h"        /* environment options */
+#include "envdep.h"        /* environment dependent */
+#include "envind.h"        /* environment independent */
+  
+#include "gen.h"           /* general */
+#include "ssi.h"           /* system services */
+
+#include "cm_lte.h"        /* Common LTE */
+#include "cm_tkns.h"       /* Common Token Defines */
+#include "cm_llist.h"      /* Common Link List Defines */
+#include "cm_hash.h"       /* Common Hash List Defines */
+#include "cm_mblk.h"       /* common memory link list library */
+
+#include "rg_env.h"        /* MAC Environment Defines */
+#include "tfu.h"           /* CRG Interface defines */
+#include "crg.h"           /* CRG Interface defines */
+#include "rg_sch_inf.h"           /* RGR Interface defines */
+#include "rgu.h"           /* RGU Interface defines */
+#include "lrg.h"           /* LRG Interface defines */
+
+#include "rg.h"            /* MAC defines */
+#include "rg_err.h"        /* MAC error defines */
+
+/* header/extern include files (.x) */
+#include "gen.x"           /* general */
+#include "ssi.x"           /* system services */
+#include "cm5.x"           /* common timers */
+#include "cm_lib.x"        /* common library */
+#include "cm_lte.x"        /* Common LTE */
+#include "cm_tkns.x"       /* Common Token Definitions */
+#include "cm_llist.x"      /* Common Link List Definitions */
+#include "cm_lib.x"        /* Common Library Definitions */
+#include "cm_hash.x"       /* Common Hash List Definitions */
+#include "cm_mblk.x"       /* common memory link list library */
+
+#include "rgu.x"           /* RGU types */
+#include "tfu.x"           /* CRG Interface includes */
+#include "crg.x"           /* CRG Interface includes */
+#include "rg_sch_inf.x"    /* SCH Interface includes */
+#include "rg_prg.x"        /* PRG interface includes */
+#include "rgu.x"           /* RGU Interface includes */
+#include "lrg.x"           /* LRG Interface includes */
+
+#include "rg.x"            /* MAC includes */
+
+/* local defines */
+
+/* local typedefs */
+ 
+/* local externs */
+ 
+/* forward references */
+
+#define RG_DUX_ALLOC(_pdu, _size, _dataPtr, _ret) {\
+   _ret = cmGetMem((Ptr)&_pdu->memCp, _size, (Ptr *)&_dataPtr); \
+}
+
+#define RG_INIT_SDU(_sdu, _lcId, _len) {\
+   (_sdu)->lcId = (_lcId); \
+   (_sdu)->len = (_len); \
+   (_sdu)->mBuf = NULLP; \
+   (_sdu)->sduLstEnt.next = NULLP; \
+   (_sdu)->sduLstEnt.prev = NULLP; \
+   (_sdu)->sduLstEnt.node = (PTR)(_sdu); \
+}
+
+#define RG_EXT_BS(_bsr, _bs1, _bs2, _bs3, _bs4)  {\
+   _bs1 = _bsr[0] >> 2; \
+   _bs2 = (((_bsr[0] & 0x3) << 4) | (_bsr[1] >> 4)); \
+   _bs3 = (((_bsr[1] & 0x0F) << 2) | (_bsr[2] >> 6)); \
+   _bs4 = _bsr[2] & 0x3F; \
+}
+
+#define RG_UNPACK_LONG_BSR(_bsr, _mBuf, _ret) {\
+   _ret = SRemPreMsgMult((_bsr), 3, (_mBuf)); \
+}
+
+#define RG_UNPACK_SHORT_BSR(_bsr, _mBuf, _ret) {\
+   _ret = SUnpkU8((_bsr), (_mBuf)); \
+}
+
+#define RG_UNPACK_TRUNC_BSR(_bsr, _mBuf, _ret) {\
+   _ret = SUnpkU8((_bsr), (_mBuf)); \
+}
+
+#define RG_UNPACK_PHR(_phr, _mBuf, _ret) {\
+   _ret = SUnpkU8((_phr), (_mBuf)); \
+}
+
+#define RG_UNPACK_CRNTI(_rnti, _mBuf, _ret) {\
+   Data _unpkArray[2];\
+   *_rnti = 0;\
+   _ret = SRemPreMsgMult(_unpkArray, (MsgLen) 2, _mBuf);\
+   if (_ret == ROK)\
+   {\
+      *_rnti = (U16) PutHiByte(*_rnti, (U8) _unpkArray[0]);\
+      *_rnti = (U16) PutLoByte(*_rnti, (U8) _unpkArray[1]);\
+   }\
+}
+
+/* For EXT PHR DEMUX */
+#define RG_UNPACK_EXT_PHR_CI(_ci, _mBuf, _ret) {\
+   _ret = SUnpkU8((_ci), (_mBuf)); \
+}
+
+#define RG_UNPACK_EXT_PHR(_extPhr, _mBuf, _ret) {\
+   _ret = SUnpkU8((_extPhr), (_mBuf)); \
+}
+
+
+
+/**
+ * @brief Handles the insertion of SDU in to PDU.
+ *
+ * @details
+ *
+ *     Function: rgDUXInsSdu
+ *     
+ *     This API handles the insertion of SDU in to PDU.
+ *     
+ *     Processing Steps: 
+ *      - Append the sdu to the sduLst of pdu.
+ *
+ *  @param[in]  Inst        inst
+ *  @param[out] *pdu
+ *  @param[in]  lcId
+ *  @param[in]  sduLen
+ *  @param[out] *err
+ *  @return  S16
+ *      -# ROK 
+ *      -# RFAILED 
+ **/
+#ifdef ANSI
+PRIVATE S16 rgDUXInsSdu
+(
+Inst        inst,
+RgMacPdu    *pdu,
+RgMacSdu    **sdu,
+U8          lcId,
+U16         sduLen,
+RgErrInfo   *err
+)
+#else
+PRIVATE S16 rgDUXInsSdu(inst,pdu, sdu, lcId, sduLen, err)
+Inst        inst;
+RgMacPdu    *pdu;
+RgMacSdu    **sdu,
+U8          lcId;
+U16         sduLen;
+RgErrInfo   *err;
+#endif
+{
+   S16         ret;
+   RgMacSdu    *sduAloc = NULLP;
+
+   TRC2(rgDUXInsSdu)
+
+   RG_DUX_ALLOC(pdu, sizeof(RgMacSdu), sduAloc, ret);
+   if(ret != ROK)
+   {
+      RLOG1(L_ERROR, "Allocation of RgSubHdr failed for LCID:%d",lcId);
+      err->errCause = RGERR_DUX_MEM_EXHAUST;
+      RETVALUE(RFAILED);
+   }
+   *sdu = sduAloc; 
+   RG_INIT_SDU(sduAloc, lcId, sduLen);
+   cmLListAdd2Tail(&pdu->sduLst, &sduAloc->sduLstEnt);
+   RETVALUE(ROK);
+}
+
+/**
+ * @brief Handles extracting the CE sub headers from the MAC PDU.
+ *
+ * @details
+ *
+ *     Function: rgDUXExtSubHdr
+ *     
+ *     This API handles extracting the  sub headers from the MAC PDU.
+ *     
+ *     Processing Steps: 
+ *      - Extract the each sub header.
+ *
+ *  @param[in]  Inst        inst
+ *  @param[out]  *pdu
+ *  @param[in]  *mBuf
+ *  @param[out] *lcId
+ *  @param[out] *len
+ *  @param[out] *err
+ *  @return  S16
+ *      -# ROK 
+ *      -# RFAILED 
+ **/
+#ifdef ANSI
+PRIVATE S16 rgDUXExtSubHdr
+(
+Inst        inst,
+RgMacPdu    *pdu,
+Buffer      *mBuf,
+U8          *lcId,
+U16         *len,
+RgErrInfo   *err
+)
+#else
+PRIVATE S16 rgDUXExtSubHdr(inst,pdu, mBuf, lcId,
+len, err)
+Inst        inst;
+RgMacPdu    *pdu;
+Buffer      *mBuf;
+U8          *lcId;
+U16         *len;
+RgErrInfo   *err;
+#endif
+{
+   U8             byte;
+   U8             fmt=0;
+ 
+   TRC2(rgDUXExtSubHdr)
+
+   *len = 0;   
+   if(SUnpkU8(&byte,mBuf) != ROK)
+   {
+      RLOG0(L_ERROR, "SUnpkU8 failed");
+      err->errCause = RGERR_DUX_UNPACK_FAILURE;
+      RETVALUE(RFAILED);
+   }
+   /* Extract the lcid */
+   RG_EXT_LCID(*lcId, byte);
+
+   /*note: RG_EXT_PHR_LCID currently not considered */
+   if(*lcId <= RG_DEDLC_MAX_LCID)
+   {  /* variable size MAC Sub PDU */
+      RG_EXT_FORMT_BIT(fmt,byte);
+      if(SUnpkU8(&byte, mBuf) != ROK)
+      {
+         RLOG0(L_ERROR, "SUnpkU8 failed");
+         err->errCause = RGERR_DUX_UNPACK_FAILURE;
+         RETVALUE(RFAILED);
+      }
+      *len = byte;
+      if(fmt)
+      {
+         if(SUnpkU8(&byte,mBuf) != ROK)
+         {
+            RLOG0(L_ERROR, "SUnpkU8 failed");
+            err->errCause = RGERR_DUX_UNPACK_FAILURE;
+            RETVALUE(RFAILED);
+         }
+         *len = (*len << 8) | byte;
+      }
+   }
+   RETVALUE(ROK);
+} /* rgDUXExtSubHdr */
+
+/**
+ * @brief Handles extracting the CEs from the MAC PDU.
+ *
+ * @details
+ *
+ *     Function: rgDUXExtCe
+ *     
+ *     This API handles extracting the CEs from the MAC PDU.
+ *     
+ *     Processing Steps: 
+ *      - Based on the ce sub header extract the ce.
+ *
+ *  @param[in]  Inst        inst
+ *  @param[in,out]  *pdu
+ *  @param[out] *ceInfo
+ *  @param[in]  *mBuf
+ *  @param[in] lcId
+ *  @param[in] subPduLen
+ *  @param[out] *err
+ *  @return  S16
+ *      -# ROK 
+ *      -# RFAILED 
+ **/
+#ifdef ANSI
+PRIVATE S16 rgDUXExtCe
+(
+Inst        inst,
+RgMacPdu    *pdu,
+RgInfCeInfo  *ceInfo,
+Buffer       *mBuf,
+U8          lcId,
+U16         subPduLen,
+RgErrInfo    *err
+)
+#else
+PRIVATE S16 rgDUXExtCe(inst,pdu, ceInfo, mBuf,lcId,subPduLen, err)
+Inst        inst;
+RgMacPdu    *pdu;
+RgInfCeInfo  *ceInfo;
+Buffer       *mBuf;
+U8          lcId;
+U16         subPduLen;
+RgErrInfo    *err;
+#endif
+{
+   S16            ret;
+
+   TRC2(rgDUXExtCe);
+
+   switch(lcId)
+   {
+      case RG_EXT_PHR_LCID:
+         {
+            U8 Ci;
+            U8 sCellIdx;
+            U8 extPhrOctet;
+            U8 extPhrPCmax;
+            RgInfExtPhrCEInfo *extPhr;
+
+            RG_UNPACK_EXT_PHR_CI(&Ci,mBuf,ret);
+            if(ret != ROK)
+            {
+               RLOG1(L_ERROR,"Unpacking of EXT PHR failed LCID:%d",lcId);
+               err->errCause = RGERR_DUX_UNPACK_FAILURE;
+               RETVALUE(RFAILED);
+            }
+
+            /* Not handling Type 2 PHR report as simultaneous PUSCH/PUCCH
+               is not supported as of now */
+            extPhr = &ceInfo->ces.extPhr;
+            extPhr->numServCells = 0;
+
+            /* Setting first BIT as PCELL field even though reserved is always
+               reported by UE */
+            Ci |= 0x1;
+            for (sCellIdx = 0; (Ci && sCellIdx < CM_LTE_MAX_CELLS); sCellIdx++)
+            {
+               if (Ci & 0x1)
+               {
+                  extPhr->servCellPhr[extPhr->numServCells].sCellIdx = sCellIdx;
+                  RG_UNPACK_EXT_PHR(&extPhrOctet,mBuf,ret);
+                  if(ret != ROK)
+                  {
+                     RLOG1(L_ERROR,"Unpacking of EXT PHR failed LCID:%d",lcId);
+                     err->errCause = RGERR_DUX_UNPACK_FAILURE;
+                     RETVALUE(RFAILED);
+                  }
+
+                  /* extPhrOctet: Bits : 7 6 5 4 3 2 1 0
+                   *                     P V x x x x x x
+                   *                         <6x Bit phr>
+                   */
+                  /* P : P Back off applied or not */
+                  extPhr->servCellPhr[extPhr->numServCells].phr = (extPhrOctet & 0x3F);
+                  extPhr->servCellPhr[extPhr->numServCells].pBackOff = 
+                     ((extPhrOctet >> 7) & 0x01);
+
+                  /* V: Virtual PCMAX or Real Tx PCMAX */
+                  if (extPhrOctet & 0x40)
+                  {
+                     extPhr->servCellPhr[extPhr->numServCells].pCmax = RG_REF_PCMAX;
+                  }
+                  else
+                  {
+                     RG_UNPACK_EXT_PHR(&extPhrPCmax,mBuf,ret);
+                     if(ret != ROK)
+                     {
+                        RLOG1(L_ERROR,"Unpacking of EXT PHR failed LCID:%d",lcId);
+                        err->errCause = RGERR_DUX_UNPACK_FAILURE;
+                        RETVALUE(RFAILED);
+                     }
+                     extPhr->servCellPhr[extPhr->numServCells].pCmax = (extPhrPCmax & 0x3F);
+                  }
+                  extPhr->numServCells++;
+               }
+               Ci >>= 1;
+            }
+
+            ceInfo->bitMask |= RG_EXT_PHR_CE_PRSNT;
+         }
+         break;
+
+      case RG_PHR_LCID:
+         {
+            RG_UNPACK_PHR(&ceInfo->ces.phr,mBuf,ret);
+            if(ret != ROK)
+            {
+               RLOG1(L_ERROR,"Unpacking of PHR failed LCID:%d",lcId);
+               err->errCause = RGERR_DUX_UNPACK_FAILURE;
+               RETVALUE(RFAILED);
+            }
+            ceInfo->bitMask |= RG_PHR_CE_PRSNT;
+         }
+         break;
+      case RG_TRUNC_BSR_LCID:
+         {
+            RG_UNPACK_TRUNC_BSR(&ceInfo->ces.bsr.truncBsr,mBuf,ret);
+            if(ret != ROK)
+            {
+               RLOG1(L_ERROR,"Unpacking of Trunc BSR failed LCID:%d",lcId);
+               err->errCause = RGERR_DUX_UNPACK_FAILURE;
+               RETVALUE(RFAILED);
+            }
+            ceInfo->bitMask |= RG_TRUNC_BSR_CE_PRSNT;
+         }
+         break;
+      case RG_SHORT_BSR_LCID:
+         {
+            RG_UNPACK_SHORT_BSR(&ceInfo->ces.bsr.shortBsr,mBuf,ret);
+            if(ret != ROK)
+            {
+               RLOG1(L_ERROR,"Unpacking of Short BSR failed LCID:%d",lcId);
+               err->errCause = RGERR_DUX_UNPACK_FAILURE;
+               RETVALUE(RFAILED);
+            }
+            ceInfo->bitMask |= RG_SHORT_BSR_CE_PRSNT;
+         }
+         break;
+      case RG_LONG_BSR_LCID:
+         {
+            U8 longBsr[3] = {0}; /* KW_FIXX */
+            RG_UNPACK_LONG_BSR(longBsr,mBuf,ret);
+            if(ret != ROK)
+            {
+               RLOG1(L_ERROR,"Unpacking of Long BSR failed LCID:%d",lcId);
+               err->errCause = RGERR_DUX_UNPACK_FAILURE;
+               RETVALUE(RFAILED);
+            }
+            RG_EXT_BS(longBsr, 
+                  ceInfo->ces.bsr.longBsr.bs1, 
+                  ceInfo->ces.bsr.longBsr.bs2, 
+                  ceInfo->ces.bsr.longBsr.bs3, 
+                  ceInfo->ces.bsr.longBsr.bs4);
+            ceInfo->bitMask |= RG_LONG_BSR_CE_PRSNT;
+         }
+         break;
+      case RG_CRNTI_LCID:
+         {
+            RG_UNPACK_CRNTI(&ceInfo->ces.cRnti,mBuf,ret);
+            if(ret != ROK)
+            {
+               RLOG1(L_ERROR,"Unpacking of C-RNTI failed LCID:%d",lcId);
+               err->errCause = RGERR_DUX_UNPACK_FAILURE;
+               RETVALUE(RFAILED);
+            }
+            ceInfo->bitMask |= RG_CRNTI_CE_PRSNT;
+         }
+         break;
+      default:
+         RLOG1(L_ERROR, "Invalid LCID:%u received",lcId); 
+         err->errCause = RGERR_DUX_INV_LCID_RX;
+         RETVALUE(RFAILED);
+   }
+   RETVALUE(ROK);
+} /* rgDUXExtCe  */
+
+
+/**
+ * @brief Handles extracting the SDU from the MAC PDU.
+ *
+ * @details
+ *
+ *     Function: rgDUXExtSdu
+ *     
+ *     This API handles extracting the SDU corresponding to a logical channel.
+ *     
+ *     Processing Steps: 
+ *      - Based on the length stored in the sub header extract the SDU.
+ *
+ *  @param[in]  Inst        inst
+ *  @param[in,out]  *pdu
+ *  @param[out] *ceInfo
+ *  @param[in]  *mBuf
+ *  @param[in] lcId
+ *  @param[in] subPduLen
+ *  @param[out] *err
+ *  @return  S16
+ *      -# ROK 
+ *      -# RFAILED 
+ **/
+#ifdef ANSI
+PRIVATE S16 rgDUXExtSdu
+(
+Inst        inst,
+RgMacPdu    *pdu,
+RgInfCeInfo  *ceInfo,
+Buffer      **mBuf,
+U8          lcId,
+U16         subPduLen,
+RgErrInfo   *err
+)
+#else
+PRIVATE S16 rgDUXExtSdu(inst,pdu, ceInfo,mBuf,lcId,subPduLen,err)
+Inst        inst;
+RgMacPdu    *pdu;
+RgInfCeInfo  *ceInfo;
+Buffer      **mBuf;
+U8          lcId;
+U16         subPduLen;
+RgErrInfo   *err;
+#endif
+{
+   S16         ret;
+   Buffer      *tmpBuf1;
+   Buffer      *tmpBuf2 = NULLP;
+   RgMacSdu    *sdu;
+
+   TRC2(rgDUXExtSdu)
+
+   if(lcId == RG_CCCH_LCID)
+   {
+      ceInfo->bitMask |= RG_CCCH_SDU_PRSNT;
+   }
+
+   if(rgDUXInsSdu(inst,pdu, &sdu,lcId, subPduLen, err) != ROK)
+   {
+      RG_FREE_MSG(*mBuf);
+      RETVALUE(RFAILED);
+   }
+
+   tmpBuf1 = *mBuf;
+   {
+      ret = SSegMsg(tmpBuf1,subPduLen,&tmpBuf2);
+      if((ret != ROK) && (!((ret == ROKDNA) )))
+      {
+         RG_FREE_MSG(tmpBuf1);
+         RLOG0(L_ERROR,"SSegMsg failed");
+         err->errCause = RGERR_DUX_RLC_PDU_CREAT_FAIL;
+         RETVALUE(RFAILED);
+      }
+      sdu->mBuf = tmpBuf1;
+      *mBuf = tmpBuf2;
+   }
+   RETVALUE(ROK);
+}   /* rgDUXExtSdu */
+
+/**
+ * @brief Handles de-multiplexing of the data recieved at MAC.
+ *
+ * @details
+ *
+ *     Function: rgDUXDemuxData
+ *     
+ *     This API handles de-multiplexing of the data recieved at MAC.
+ *     
+ *     Invoked by: rgTOMTfuDatInd of TOM 
+ *     
+ *     Processing Steps: 
+ *      - De-multiplex the mBuf
+ *
+ *  @param[in]  Inst        inst
+ *  @param[in]  *pdu 
+ *  @param[in]  *mBuf 
+ *  @param[out] *err 
+ *  @return  S16
+ *      -# ROK 
+ *      -# RFAILED 
+ **/
+#ifdef ANSI
+PUBLIC S16 rgDUXDemuxData
+(
+Inst          inst,
+RgMacPdu      *pdu,
+RgInfCeInfo   *ceInfo,
+Buffer        **mBuf,
+RgErrInfo     *err
+)
+#else
+PUBLIC S16 rgDUXDemuxData(inst,pdu, ceInfo, mBuf, err)
+Inst          inst;
+RgMacPdu      *pdu;
+RgInfCeInfo   *ceInfo;
+Buffer        **mBuf;
+RgErrInfo     *err;
+#endif
+{
+   U8          lcId;
+   U16          subPduLen;
+   MsgLen      len;  
+   TRC2(rgDUXDemuxData)
+
+   ceInfo->bitMask = 0x0000;
+
+   /* Initialize the sdu list */
+   cmLListInit(&pdu->sduLst);
+
+   if(*mBuf == NULLP) 
+   {
+      RLOG0(L_ERROR, "Null Buffer Recevived");
+      RETVALUE(RFAILED);
+   }
+   do
+   {
+      /* UL Message format  order : 
+           PduSubHdr+SubPDU,PduSubHdr+SubPDU,...CeSubHdr+Ce,CeSubPdu+Ce,...,PADSubHdr+PAD */
+      /* Extract the Sub headers */
+      if(rgDUXExtSubHdr(inst,pdu, *mBuf, &lcId, 
+               &subPduLen, err) != ROK)
+      {
+         RG_FREE_MSG(*mBuf);	      
+         RLOG0(L_ERROR, "Failed to extract pad sub headers");
+         RETVALUE(RFAILED);
+      }
+      if(lcId == RG_PAD_LCID)
+      { /*at end of MAC PDU,  Padding started */ 
+         RG_FREE_MSG(*mBuf);	      
+         RETVALUE(ROK);
+      }
+      if(lcId <= RG_DEDLC_MAX_LCID)
+      {
+         /* Extract the sdus */
+         if(rgDUXExtSdu(inst,pdu,ceInfo, mBuf,lcId,subPduLen, err) != ROK)
+         {
+            /* Fix : syed rgDUXExtSdu would have segmented mBuf and hence
+             * will be responsible for freeing mBuf */
+            *mBuf = NULLP;
+            RLOG0(L_ERROR, "failed to Extract the sdus");
+            RETVALUE(RFAILED);
+         }
+         if(*mBuf == NULLP) /* if message read completes then return */
+         {
+            RETVALUE(ROK);
+         }
+      }
+      else
+      {
+         /* Extract the ces */
+         if(rgDUXExtCe(inst,pdu,ceInfo,*mBuf, lcId,subPduLen, err) != ROK)
+         {
+            RG_FREE_MSG(*mBuf);	      
+            RLOG0(L_ERROR, " failed to Extract the ces");
+            RETVALUE(RFAILED);
+         }
+      }
+      if(SFndLenMsg(*mBuf,&len) != ROK)
+      {
+         RG_FREE_MSG(*mBuf);
+         RLOG0(L_ERROR,"mBuf length check failed");
+         err->errCause = RGERR_DUX_UNPACK_FAILURE;
+         RETVALUE(RFAILED);
+      }
+   }while(len);
+
+   RG_FREE_MSG(*mBuf);
+   RETVALUE(ROK);
+}  /* rgDUXDemuxData */
+
+/**********************************************************************
+ 
+         End of file
+**********************************************************************/
diff --git a/src/5gnrmac/rg_env.h b/src/5gnrmac/rg_env.h
new file mode 100755
index 000000000..e015438fb
--- /dev/null
+++ b/src/5gnrmac/rg_env.h
@@ -0,0 +1,386 @@
+/*******************************************************************************
+################################################################################
+#   Copyright (c) [2017-2019] [Radisys]                                        #
+#                                                                              #
+#   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.                                             #
+################################################################################
+*******************************************************************************/
+
+/**********************************************************************
+ 
+    Name:   LTE MAC layer
+ 
+    Type:   H include file
+ 
+    Desc:   Defines required by LTE MAC
+ 
+    File:   rg_env.h
+ 
+**********************************************************************/
+ 
+#ifndef __RGENVH__
+#define __RGENVH__
+
+/* Number of Unserved UE's Facotr for BI value calculation */
+/* R8 Upgrade */
+#define RG_SCH_CMN_BI_NUMUE_FACTOR    1
+#define RGSCH_MAX_RNTI_PER_RARNTI    10
+/* The number of schedulers supported currently */ 
+#ifdef RG_PHASE2_SCHED
+#define RGSCH_NUM_SCHEDULERS    4
+#ifdef EMTC_ENABLE
+#define RGSCH_NUM_EMTC_SCHEDULERS    1
+#endif
+#define RGSCH_NUM_DLFS_SCHEDULERS    1
+#else
+#define RGSCH_NUM_SCHEDULERS    1
+#ifdef EMTC_ENABLE
+#define RGSCH_NUM_EMTC_SCHEDULERS    0
+#endif
+#define RGSCH_NUM_DLFS_SCHEDULERS    0
+#endif
+/* Added support for SPS*/
+
+#ifdef LTEMAC_SPS
+#define RG_SCH_NUM_SPS_OCC_AFTR_EXP_REL 6 /* Number of empty SPS Occasions
+                                             after sending explicit release after
+                                             which SPS resources of the UE shall 
+                                             be deallocated */
+#define RGSCH_SPS_CQI_SCALE_FACTOR 1
+#endif
+
+
+/* List of scheduler init functions to initialise rgSchSchdInits[] array with */
+#ifdef RG_PHASE2_SCHED
+#define RGSCH_ULSCHED_INITS  {rgSCHSc1UlInit, rgSCHPfsUlInit, rgSCHRrUlInit, rgSCHMaxciUlInit}
+#define RGSCH_DLSCHED_INITS  {rgSCHSc1DlInit, rgSCHPfsDlInit, rgSCHRrDlInit, rgSCHMaxciDlInit}
+#ifdef EMTC_ENABLE
+#define RGSCH_EMTC_ULSCHED_INITS  {rgSCHEmtcRrUlInit}
+#define RGSCH_EMTC_DLSCHED_INITS  {rgSCHEmtcRrDlInit}
+#endif
+#ifdef TFU_UPGRADE
+#define RGSCH_DLFSSCHED_INITS {rgSCHDlfsInit}
+#endif
+#else
+#define RGSCH_ULSCHED_INITS  {rgSCHSc1UlInit}
+#define RGSCH_DLSCHED_INITS  {rgSCHSc1DlInit}
+#define RGSCH_DLFSSCHED_INITS {}
+#ifdef EMTC_ENABLE
+#define RGSCH_EMTC_ULSCHED_INITS  {}
+#define RGSCH_EMTC_DLSCHED_INITS  {}
+#endif
+#endif
+
+
+
+/* Common Scheduler Tunable Parameters */
+#define RG_SCH_CMN_UE_IDLETIME_FCTR        3
+#define RG_SCH_CMN_MAX_BITS_RATIO          16
+#define RG_SCH_CMN_UL_COM_DENOM            16 
+#define RG_SCH_CMN_UL_NUM_CQI              16
+#define RG_SCH_CMN_MAX_UE_PER_UL_SF        1 /* If more than 1 is required it can be controlled from configuration*/
+/* Fix: MUE_PERTTI_DL*/
+#define RG_SCH_CMN_MAX_UE_PER_DL_SF       4
+/* mapping RG_MAX_NUM_UE_PER_TTI to RGU Interface define to use it in MAC code */
+#ifdef XEON_SPECIFIC_CHANGES
+#define RG_MAX_NUM_UE_PER_TTI             16
+#else
+#define RG_MAX_NUM_UE_PER_TTI             8
+#endif
+/* Added configuration for maximum number of MSG3s */
+#define RG_SCH_CMN_MAX_MSG3_PER_UL_SF      1 /* If more than 1 is required it can be controlled from configuration*/
+#define RG_SCH_CMN_MAX_UL_BW_PER_UE        100
+#define RG_SCH_CMN_MAX_DL_RETX_BW          100 
+#define RG_SCH_CMN_MAX_DL_BW_PERUE         100 
+#define RG_SCH_CMN_DEF_BCCHPCCH_CODERATE   512
+#define RG_SCH_CMN_MAX_DL_AMBR             0xFFFFFFFF 
+#define RG_SCH_CMN_MAX_UL_UEBR             0xFFFFFFFF 
+#define RG_SCH_CMN_DED_MAX_HDRSIZE         3
+#define RG_SCH_CMN_MAX_DED_SDU             5
+
+#ifdef MAC_SCH_STATS
+#define RG_SCH_CMN_CMNDL_DELTA             1
+#endif /* MAC_SCH_STATS */
+
+/* ccpu00126002 introduced buffer to track cqi allocation and RI allocation
+   for a particular UE. As the allocation is stored in UeCb, if the 
+   occasion between cqi and ri are short cqi is overwritten. To avoid that
+   this buffer is introduced.*/
+#define MAX_CQI_RI_RPT_BUFF           (TFU_DELTA * 2)
+
+/* GBR priorities occupy a set of contiguous priorities      */
+/* starting always at 1.                                     */
+/* RG_SCH_CMN_MAX_PRIO is the total number of priority queues    */
+/* defined in the scheduler. This variable can have affect   */
+/* on the performance of the scheduler and should be chosen  */
+/* based on the same.                                        */
+#define RG_SCH_CMN_MAX_PRIO              8
+
+#ifdef RG_SC1
+/* UL Scheduler1 tunable params */
+#define RG_SC1_BSR_BS         4
+#define RG_SC1_SR_BS          RG_SC1_BSR_BS
+#define RG_SC1_UL_RATIO       14  /* UL_RATIO/COM_DENOM of bs for LCGs other than */
+                                /* highest priority LCG used */
+
+/* Priority 0 is used as a FIFO service where the priority   */
+/* of UEs within the priority Q is based purely on time at   */
+/* which the service is reported to the scheduler. This      */
+/* priority queue is suitable for DCCH services.             */
+
+
+/* This is the maximum known QCIs to the scheduler.          */
+/* RG_SC1_QCI_TO_PRIO maps QCIs to respective priorities and */
+/* there by behavior of the service                          */
+
+/* This table is used to translate a CQI to an applicable */
+/* aggregation level to be used for a UE when allocating  */
+/* a PDCCH.                                               */
+/* This table is used to translate a CQI to an applicable  */
+/* coding rate for dedicated PDSCH allocation. The number  */
+/* in the table represents the number of bits to allocated */
+/* per 1024 REs.                                           */
+
+#endif
+EXTERN U32 wrSmDfltNumCells;
+#define RGSCH_MAX_UE_PER_DL_SF 32
+#define RGSCH_MAX_RARNTI_PER_DL_SF 4
+#define RGSCH_INST_START wrSmDfltNumCells
+#define RGSCH_MAX_INST 2
+/*MCELL changes*/
+#define RG_MAX_INST 4
+#define RG_INST_START 0
+/* Twice of difference in power levels between successive uplink
+ * CQIs (in dB) */
+#define RG_SCH_UL_CQI_DB_STEP_2   2
+
+#define RG_SCH_CMN_MAX_NUM_TPC_PUCCH_RNTI 100
+#define RG_SCH_CMN_MAX_NUM_TPC_PUSCH_RNTI 100
+
+/* [ccpu00138532]-DEL-Removed the Guard timer macro. Moved
+   it into CellCb and value is configured based the maxMsg4Tx */
+
+/* moving rgSchCmnUlCqiTbl values here to enable customer to 
+ * fine tune these values 
+ */
+/* Adding modulation order & efficiency hash defines for
+ * UL. This can be tuned by customer. These values are used
+ * in rgSchCmnUlCqiTbl in rg_sch_cmn.c
+ */
+
+/* for CQI 1 */
+#define RGSCH_CMN_QM_CQI_1      RGSCH_QM_BPSK
+#define RGSCH_CMN_UL_EFF_CQI_1      156
+
+/* for CQI 2 */
+#define RGSCH_CMN_QM_CQI_2      RGSCH_QM_BPSK
+#define RGSCH_CMN_UL_EFF_CQI_2      240 
+
+/* for CQI 3 */
+#define RGSCH_CMN_QM_CQI_3      RGSCH_QM_BPSK
+#define RGSCH_CMN_UL_EFF_CQI_3      386 
+
+/* for CQI 4 */
+#define RGSCH_CMN_QM_CQI_4      RGSCH_QM_BPSK
+#define RGSCH_CMN_UL_EFF_CQI_4      616
+
+/* for CQI 5 */
+#define RGSCH_CMN_QM_CQI_5      RGSCH_QM_BPSK
+#define RGSCH_CMN_UL_EFF_CQI_5      898
+
+/* for CQI 6 */
+#define RGSCH_CMN_QM_CQI_6      RGSCH_QM_BPSK
+#define RGSCH_CMN_UL_EFF_CQI_6      1204 
+
+/* for CQI 7 */
+#define RGSCH_CMN_QM_CQI_7      RGSCH_QM_QPSK
+#define RGSCH_CMN_UL_EFF_CQI_7      1512 
+
+/* for CQI 8 */
+#define RGSCH_CMN_QM_CQI_8      RGSCH_QM_QPSK
+#define RGSCH_CMN_UL_EFF_CQI_8      1960 
+
+/* for CQI 9 */
+#define RGSCH_CMN_QM_CQI_9      RGSCH_QM_QPSK
+#define RGSCH_CMN_UL_EFF_CQI_9      2464 
+
+/* for CQI 10 */
+#define RGSCH_CMN_QM_CQI_10      RGSCH_QM_64QAM
+#define RGSCH_CMN_UL_EFF_CQI_10      3402
+
+/* for CQI 11 */
+#define RGSCH_CMN_QM_CQI_11      RGSCH_QM_64QAM
+#define RGSCH_CMN_UL_EFF_CQI_11      3996 
+
+/* for CQI 12 */
+#define RGSCH_CMN_QM_CQI_12      RGSCH_QM_64QAM
+#define RGSCH_CMN_UL_EFF_CQI_12      4102 
+
+/* for CQI 13 */
+#define RGSCH_CMN_QM_CQI_13      RGSCH_QM_64QAM
+#define RGSCH_CMN_UL_EFF_CQI_13      4342
+
+/* for CQI 14 */
+#define RGSCH_CMN_QM_CQI_14      RGSCH_QM_64QAM
+#define RGSCH_CMN_UL_EFF_CQI_14      5238 
+
+/* for CQI 15 */
+#define RGSCH_CMN_QM_CQI_15      RGSCH_QM_64QAM
+#define RGSCH_CMN_UL_EFF_CQI_15      5728 
+
+/* Freeing up the HARQ proc blocked for
+ * indefinite time in case of Retx */
+#define RG_SCH_MAX_RETX_ALLOC_FAIL  10 
+
+/* Window Size within which buffering paging and Broadcast BO is done */
+#define RGSCH_PCCHBCCH_WIN 5120
+#define RGSCH_MAX_SUBFRM         10240
+#define RGSCH_MAX_SUBFRM_5G      51200
+#define RGSCH_UL_SYM_DMRS_SRS      2
+#define RGSCH_UL_16QAM_MAX_ITBS    20
+#ifdef LTE_TDD
+/* Itbs Adjustment for DwPts scheduling. Only 
+ * Spl Sf cfg 7 is currently supported. The adjustment 
+ * is based on test results */
+#define RG_SCH_DWPTS_ITBS_ADJ {0,0,0,0,0,0,0,-1,0}
+#endif
+
+
+/* The below MACROs are used by the BLER based LA algorithm to 
+ * maintain the iTbs delta based on the HARQ feedback. For the first 
+ * HARQ Ack received, the delta itbs value is incremented by the STEP_UP value.
+ * For the first HARQ Nack received, the delta iTbs value is decreased by
+ * the STEP_DOWN value 
+ */ 
+#ifdef DL_LA
+#define DL_LA_STEPDOWN           30 
+#define DL_LA_STEPUP              3
+#endif
+
+#ifdef UL_LA
+#define UL_LA_STEPDOWN           30 
+#define UL_LA_STEPUP              3
+#endif
+
+#define RGSCH_CFI_TTI_MON_INTRVL        1000 /* In TTI, Max value 10240 */  
+#define RGSCH_CFI_STEP_UP_TTI_PRCNTG    10  /* Percentage of CCE failures */
+#define RGSCH_CFI_STEP_DOWN_TTI_PERCNTG 90  /* Percentage of TTI in which CCE usage is less than the
+                                               next lower CFI */
+#define RGSCH_CFI_CCE_PERCNTG           90  /* Percentage of total CCE used/total CCE available 
+                                               in the next lower CFI */
+
+/* Following tunable Macros are applied in APerCQI
+ * trigger determination */
+#define RG_APER_CQI_ACK_WGT       25   /*Weight Associated with each HARQ ACK*/
+#define RG_APER_CQI_NACK_WGT      125  /*Weight Associated with each HARQ ACK*/
+#define RG_APER_CQI_THRESHOLD_WGT 1000 /*Threshold against which the accumulated
+                                         aCqiTrigWt is compared to */
+
+#define RG_SCH_ITBS_STEP_DOWN_PCQI_RI_HQ 1   /* iTbs will be reduced by this value 
+                                              for UL with PCQIi/RI/HQ */
+#define RG_SCH_ITBS_STEP_DOWN_ACQI       1   /* iTbs will be reduced by this value 
+                                                for ACQI report*/
+#define RG_SCH_PCQI_RI_HQ_EFF_TGT        930 /* Target efficeincy for 
+                                                UL with PCQI/RI/HQ  */
+#define RG_SCH_ACQI_EFF_TGT              530 /* Target efficeincy for UL with ACQI */ 
+
+
+/* Following #defines are used in calculating the cqi to TBS mapping 
+ * In 36.213 table 7.1.7.1-1 defines mapping b/w Itbs and mcs and table 
+ * 7.2.3-1 defines mapping b/w CQI to mcs and code rate.
+ * The values of these tables are chosen such that average of tbs value for 
+ * different nprbs with code rate nearest to the code rate defined in table
+ * 7.2.3-1 for particular CQI value.We should also take care of the fact that 
+ * mapping defined in table 7.1.7.1-1 is not overruled.*/
+/* ADD fix for CFI0*/
+#define RG_SCH_CMN_CQI_TO_PDSCH_EFF_CFI0 \
+    {207, 271, 333, 431, 648, 899, 1161, 1482, 1889, 2103,\
+        2905, 3412, 3956, 4474, 4655, 5397}
+
+/* The below tables are defined to fix the BLER issue
+   for CFI 2, 3, 4 */
+#define RG_SCH_CMN_CQI_TO_PDSCH_EFF_CFI1 \
+    {226, 226, 226, 364, 471, 708, 983, 1411, 1833, 2299, 2612,\
+        3177, 3731, 4326, 4893, 5090}
+
+#define RG_SCH_CMN_CQI_TO_PDSCH_EFF_CFI2 \
+    {248, 248, 248, 326, 519, 780, 1084, 1399, 1786, 2278, 2714, 3194,\
+        3810, 4442, 5069, 5398}
+
+#define RG_SCH_CMN_CQI_TO_PDSCH_EFF_CFI3 \
+    {276, 276, 276, 276, 446, 708, 1052, 1382, 1734, 2254, 2827,\
+        3212, 3908, 4590, 4953, 5653}
+
+    
+#ifdef EMTC_ENABLE
+#define RG_SCH_EMTC_CMN_CQI_TO_PDSCH_EFF_CFI0 \
+    {104, 136, 271, 333, 431, 648, 899, 1161, 1973, 2111, 2240}
+
+#define RG_SCH_EMTC_CMN_CQI_TO_PDSCH_EFF_CFI1 \
+    {115, 115, 226, 226, 364, 471, 708, 983, 2143, 2293, 2433}
+
+#define RG_SCH_EMTC_CMN_CQI_TO_PDSCH_EFF_CFI2 \
+    {125, 125, 248, 248, 326, 519, 780, 1084, 2345, 2509, 2663}
+
+#define RG_SCH_EMTC_CMN_CQI_TO_PDSCH_EFF_CFI3 \
+    {139, 139, 276, 276, 276, 446, 708, 1052, 2590, 2771, 2941}
+    
+#define RG_SCH_EMTC_CMN_2LYR_CQI_TO_PDSCH_EFF_CFI0 \
+    {95, 114, 226, 309, 366, 412, 539, 662, 859, 1052, 1293}
+
+#define RG_SCH_EMTC_CMN_2LYR_CQI_TO_PDSCH_EFF_CFI1 \
+    {99, 117, 232, 306, 322, 408, 450, 588, 723, 938, 1150}
+
+#define RG_SCH_EMTC_CMN_2LYR_CQI_TO_PDSCH_EFF_CFI2 \
+    {84, 104, 207, 233, 307, 343, 408, 422, 495, 586, 648}
+
+#define RG_SCH_EMTC_CMN_2LYR_CQI_TO_PDSCH_EFF_CFI3 \
+    {89, 100, 200, 221, 287, 323, 386, 433, 497, 522, 676}
+
+#define RGSCH_MPDCCH_PDSCH_DL_DELTA 2
+
+#endif       
+     
+/* Number of information bits per 1024 Phy bits for PDCCH */
+/* This is a customer tunable */
+#define RG_SCH_CMN_CQI_TO_PDCCH_EFF \
+       {  400,  100,  150,  200,  250,  280, 340, 365,\
+         380, 400, 500, 600, 700, 800, 900, 1000}
+
+#define RG_SCH_CMN_2LYR_CQI_TO_PDSCH_EFF_CFI0 \
+    {188, 226, 309, 366, 412, 539, 662, 859, 1052, \
+        1293, 1535, 2585, 2957, 3340, 4775, 5300}
+
+#define RG_SCH_CMN_2LYR_CQI_TO_PDSCH_EFF_CFI1 \
+    {197, 232, 306, 322, 408, 450, 588, 723, 938,\
+        1150, 1413, 1679, 2826, 3233, 5222, 5796}
+
+#define RG_SCH_CMN_2LYR_CQI_TO_PDSCH_EFF_CFI2 \
+    {166, 207, 233, 307, 343, 408, 422, 495, 586,\
+        648, 797, 1035, 1268, 1558, 3117, 3567}
+
+#define RG_SCH_CMN_2LYR_CQI_TO_PDSCH_EFF_CFI3 \
+    {177, 200, 221, 287, 323, 386, 433, 497, 522, 676,\
+        722, 888, 1153, 1413, 1737, 3476}
+
+#define RG_SCH_LAA_ITBS_THRESHOLD     20   /* Threshold iTBS for considering for scheduling
+                                            on LAA Cell*/
+#define RG_SCH_DEFAULT_HQP_SHIFT_TIME 8    /* The Timer for the Harq Proc to be shifted to 
+                                            PCell if SCell Transmissionfail */
+
+#endif /* __RGENVH__ */
+
+
+/**********************************************************************
+         End of file
+**********************************************************************/
diff --git a/src/5gnrmac/rg_err.h b/src/5gnrmac/rg_err.h
new file mode 100755
index 000000000..b75b732cc
--- /dev/null
+++ b/src/5gnrmac/rg_err.h
@@ -0,0 +1,226 @@
+/*******************************************************************************
+################################################################################
+#   Copyright (c) [2017-2019] [Radisys]                                        #
+#                                                                              #
+#   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.                                             #
+################################################################################
+*******************************************************************************/
+
+/**********************************************************************
+ 
+     Name:    LTEMAC - Error File
+  
+     Type:    C include file 
+  
+     Desc:    Error defines required by LTEMAC layer
+ 
+     File:    rg_err.h
+
+*********************************************************************21*/
+ 
+#ifndef __RGERRH__
+#define __RGERRH__
+
+/* defines */
+
+
+/* Macro definitions */
+#define RGLOGERROR(_inst,errCls, errCode, errVal, errDesc) \
+   SLogError(rgCb[_inst].rgInit.ent, rgCb[_inst].rgInit.inst, rgCb[inst].rgInit.procId, \
+             (Txt *) __FILE__,    \
+             (S32) __LINE__,      \
+             (ErrCls) (errCls),   \
+             (ErrCode) (errCode), \
+             (ErrVal) (errVal),   \
+             (Txt *) errDesc)
+
+/* error codes */
+#define   ERGBASE 0
+
+#define   ERGXXX        (ERGBASE + 0)   /* reserved */
+#define   ERRRG         (ERGBASE + 0)   /* reserved */
+
+#define   RGERR_NONE    ERGBASE
+
+#define   ERG001      (ERRRG +    1)    /*     gk_rom.c: 221 */
+#define   ERG002      (ERRRG +    2)    /*     gk_rom.c: 235 */
+#define   ERG003      (ERRRG +    3)    /*     gk_rom.c: 365 */
+#define   ERG004      (ERRRG +    4)    /*     gk_rom.c: 476 */
+#define   ERG005      (ERRRG +    5)    /*     gk_rom.c: 623 */
+#define   ERG006      (ERRRG +    6)    /*     gk_rom.c: 738 */
+#define   ERG007      (ERRRG +    7)    /*     gk_rom.c: 933 */
+
+#define   ERG008      (ERRRG +    8)    /*     gk_uim.c: 227 */
+#define   ERG009      (ERRRG +    9)    /*     gk_uim.c: 237 */
+#define   ERG010      (ERRRG +   10)    /*     gk_uim.c: 293 */
+#define   ERG011      (ERRRG +   11)    /*     gk_uim.c: 302 */
+#define   ERG012      (ERRRG +   12)    /*     gk_uim.c: 413 */
+#define   ERG013      (ERRRG +   13)    /*     gk_uim.c: 423 */
+#define   ERG014      (ERRRG +   14)    /*     gk_uim.c: 520 */
+#define   ERG015      (ERRRG +   15)    /*     gk_uim.c: 529 */
+#define   ERG016      (ERRRG +   16)    /*     gk_uim.c: 612 */
+#define   ERG017      (ERRRG +   17)    /*     gk_uim.c: 621 */
+#define   ERG018      (ERRRG +   18)    /*     gk_uim.c: 695 */
+#define   ERG019      (ERRRG +   19)    /*     gk_uim.c: 704 */
+#define   ERG020      (ERRRG +   20)    /*     gk_uim.c: 777 */
+#define   ERG021      (ERRRG +   21)    /*     gk_uim.c: 786 */
+#define   ERG022      (ERRRG +   22)    /*     gk_uim.c:1061 */
+#define   ERG023      (ERRRG +   23)    /*     gk_uim.c:1071 */
+#define   ERG024      (ERRRG +   24)    /*     gk_uim.c:1128 */
+#define   ERG025      (ERRRG +   25)    /*     gk_uim.c:1137 */
+#define   ERG026      (ERRRG +   26)    /*     gk_uim.c:1253 */
+#define   ERG027      (ERRRG +   27)    /*     gk_uim.c:1266 */
+
+#define   ERG028      (ERRRG +   28)    /*     gk_utl.c: 196 */
+#define   ERG029      (ERRRG +   29)    /*     gk_utl.c: 267 */
+#define   ERG030      (ERRRG +   30)    /*     gk_utl.c: 320 */
+#define   ERG031      (ERRRG +   31)    /*     gk_utl.c: 605 */
+
+
+/* ***********************************************************
+ *                       Error Type 
+ *************************************************************/
+#define RGERR_TYPE_BASE                0
+#define RGERR_CAUSE_BASE               0
+
+/* ErrType defines for MUX */
+#define RG_MUX_ERRTYPE_BASE            RGERR_TYPE_BASE
+#define RGERR_MUX_BLD_PDU              (RG_MUX_ERRTYPE_BASE + 1)
+#define RGERR_MUX_BLD_CEHDR_FAIL       (RG_MUX_ERRTYPE_BASE + 2)
+#define RGERR_MUX_BLD_CE_FAIL          (RG_MUX_ERRTYPE_BASE + 3)
+#define RGERR_MUX_BLD_SDUHDR_FAIL      (RG_MUX_ERRTYPE_BASE + 4)
+#define RGERR_MUX_BLD_SDU_FAIL         (RG_MUX_ERRTYPE_BASE + 5)
+#define RGERR_MUX_BLD_PADHDR_FAIL      (RG_MUX_ERRTYPE_BASE + 6)
+#define RGERR_MUX_BLD_PAD_FAIL         (RG_MUX_ERRTYPE_BASE + 7)
+#define RGERR_MUX_BLD_BI_FAIL          (RG_MUX_ERRTYPE_BASE + 8)
+#define RGERR_MUX_BLD_RAPIDHDR_FAIL    (RG_MUX_ERRTYPE_BASE + 9)
+#define RGERR_MUX_BLD_RAPID_FAIL       (RG_MUX_ERRTYPE_BASE + 10)
+#define RGERR_MUX_BLD_RAR_PDU          (RG_MUX_ERRTYPE_BASE + 11)
+/* ErrType defines for DHM */
+#define RG_DHM_ERRTYPE_BASE            (RGERR_MUX_BLD_RAR_PDU + 1)
+#define RGERR_DHM_SND_DAT_REQ           RG_DHM_ERRTYPE_BASE 
+#define RGERR_DHM_FDBK_IND             (RG_DHM_ERRTYPE_BASE + 1)
+#define RGERR_DHM_SND_STA_IND          (RG_DHM_ERRTYPE_BASE + 2)
+/* ErrType defines for L2Measurement */
+#ifdef LTE_L2_MEAS
+#define RGERR_L2M_ERRTYPE_BASE         RG_DHM_ERRTYPE_BASE
+#define RGERR_L2M_MEASREQ              (RGERR_L2M_ERRTYPE_BASE + 1)   
+#define RGERR_DHM_SND_HARQ_STA_IND     (RGERR_L2M_ERRTYPE_BASE + 2)
+#define RGERR_L2M_INV_PARAM            (RGERR_L2M_ERRTYPE_BASE + 3)
+#define RGERR_L2M_INV_CELL_ID          (RGERR_L2M_ERRTYPE_BASE + 4)
+#endif /* LTE_L2_MEAS */
+#define RGERR_DHM_SND_HQ_FDB_REQ       (RG_DHM_ERRTYPE_BASE + 3)
+/* ErrType defines for ROM */
+#define RG_ROM_ERRTYPE_BASE            (RGERR_DHM_FDBK_IND + 1)
+#define RGERR_ROM_DEDDATREQ            RG_ROM_ERRTYPE_BASE 
+#define RGERR_ROM_CMNDATREQ            (RG_ROM_ERRTYPE_BASE + 1)
+#define RGERR_ROM_DEDSTARSP            (RG_ROM_ERRTYPE_BASE + 2)
+#define RGERR_ROM_CMNSTARSP            (RG_ROM_ERRTYPE_BASE + 3)
+/* ErrType defines for TOM */
+#define RG_TOM_ERRTYPE_BASE            (RGERR_ROM_CMNSTARSP + 1)
+#define RGERR_TOM_RAREQIND             (RG_TOM_ERRTYPE_BASE)
+#define RGERR_TOM_HARQACKIND           (RG_TOM_ERRTYPE_BASE + 1)
+#define RGERR_TOM_SRIND                (RG_TOM_ERRTYPE_BASE + 2)
+#define RGERR_TOM_DLCQIIND             (RG_TOM_ERRTYPE_BASE + 3)
+#define RGERR_TOM_DATIND               (RG_TOM_ERRTYPE_BASE + 4)
+#define RGERR_TOM_DECFAILIND           (RG_TOM_ERRTYPE_BASE + 5)
+#define RGERR_TOM_TTIIND               (RG_TOM_ERRTYPE_BASE + 6)
+/* COM Module related error MACROs for error type */
+#define RG_COM_ERRTYPE_BASE            (RGERR_TOM_TTIIND + 1)
+#define RGERR_COM_CFG_REQ              RG_COM_ERRTYPE_BASE 
+#define RGERR_COM_RECFG_REQ            (RG_COM_ERRTYPE_BASE + 1)
+#define RGERR_COM_DEL_REQ              (RG_COM_ERRTYPE_BASE + 2)
+#define RGERR_COM_RESET_REQ            (RG_COM_ERRTYPE_BASE + 3)
+/* GOM Module related error MACROs for error type */
+#define RG_GOM_ERRTYPE_BASE            (RGERR_COM_DEL_REQ + 1)
+#define RGERR_GOM_CFG_REQ              RG_GOM_ERRTYPE_BASE 
+#define RGERR_GOM_RECFG_REQ            (RG_GOM_ERRTYPE_BASE + 1)
+
+/* ***********************************************************
+ *                       Error Cause 
+ *************************************************************/
+/* Errcause defines for MUX */
+#define RG_MUX_ERR_CAUSE_BASE          RGERR_CAUSE_BASE
+#define RGERR_MUX_MEM_ALLOC_FAIL       RG_MUX_ERR_CAUSE_BASE + 1
+#define RGERR_MUX_BLD_HDR_FAIL         RG_MUX_ERR_CAUSE_BASE + 2
+#define RGERR_FDBK_IND_INVALID_CB      RG_MUX_ERR_CAUSE_BASE + 3
+/* Errcause defines for DHM */
+#define RG_DHM_ERRCAUSE_BASE           RGERR_FDBK_IND_INVALID_CB + 1
+#define RG_DHM_MEM_ALLOC_FAIL          RG_DHM_ERRCAUSE_BASE 
+/* Errcause defines for RAM */
+#define RG_RAM_ERRCAUSE_BASE           RGERR_FDBK_IND_INVALID_CB + 1
+#define RGERR_RAM_MEM_EXHAUST          RG_RAM_ERRCAUSE_BASE 
+#define RGERR_RAM_NO_MSG3_RCVD         RG_RAM_ERRCAUSE_BASE + 1
+#define RGERR_RAM_RNTI_EXHAUST         RG_RAM_ERRCAUSE_BASE + 2
+/* Errcause defines for ROM */
+#define RG_ROM_ERRCAUSE_BASE           RGERR_RAM_RNTI_EXHAUST + 1
+#define RGERR_ROM_INV_CELL_ID          RG_ROM_ERRCAUSE_BASE 
+#define RGERR_ROM_DELAYED_DATREQ       RG_ROM_ERRCAUSE_BASE + 1
+#define RGERR_ROM_INV_UE_ID            RG_ROM_ERRCAUSE_BASE + 2
+#define RGERR_ROM_INV_LC_ID            RG_ROM_ERRCAUSE_BASE + 3
+#define RGERR_ROM_INV_RNTI             RG_ROM_ERRCAUSE_BASE + 4
+#define RGERR_ROM_MEM_EXHAUST          RG_ROM_ERRCAUSE_BASE + 5
+#define RGERR_ROM_INV_DAT_LEN          RG_ROM_ERRCAUSE_BASE + 6
+/* Errcause defines for RAM */
+#define RG_TOM_ERRCAUSE_BASE           RGERR_ROM_INV_DAT_LEN + 1
+#define RGERR_TOM_INV_CELL_ID          RG_TOM_ERRCAUSE_BASE 
+#define RGERR_TOM_MEM_EXHAUST          RG_TOM_ERRCAUSE_BASE + 1
+/* Errcause defines for DUX */
+#define RG_DUX_ERRCAUSE_BASE           RGERR_TOM_MEM_EXHAUST + 1
+#define RGERR_DUX_INV_LCID_RX          RG_DUX_ERRCAUSE_BASE 
+#define RGERR_DUX_MEM_EXHAUST          RG_DUX_ERRCAUSE_BASE + 1
+#define RGERR_DUX_UNPACK_FAILURE       RG_DUX_ERRCAUSE_BASE + 2
+#define RGERR_DUX_RLC_PDU_CREAT_FAIL   RG_DUX_ERRCAUSE_BASE + 3
+#define RGERR_DUX_RLC_DATIND_FAIL      RG_DUX_ERRCAUSE_BASE + 4
+#define RGERR_DUX_DBM_FAILURE          RG_DUX_ERRCAUSE_BASE + 5
+#define RGERR_DUX_INV_PDU_RX           RG_DUX_ERRCAUSE_BASE + 6
+/* CFG Module related error MACROs for error cause */
+#define RG_CFG_ERRCAUSE_BASE               RGERR_DUX_INV_PDU_RX + 1
+#define RGERR_CFG_INVALID_CRG_CELL_CFG     RG_CFG_ERRCAUSE_BASE 
+#define RGERR_CFG_INVALID_CRG_UE_CFG       RG_CFG_ERRCAUSE_BASE + 1
+#define RGERR_CFG_INVALID_CRG_DED_LC_CFG   RG_CFG_ERRCAUSE_BASE + 2
+#define RGERR_CFG_INVALID_CRG_CMN_LC_CFG   RG_CFG_ERRCAUSE_BASE + 3
+#define RGERR_CFG_INVALID_CRG_CELL_RECFG   RG_CFG_ERRCAUSE_BASE + 4
+#define RGERR_CFG_INVALID_CRG_UE_RECFG     RG_CFG_ERRCAUSE_BASE + 5
+#define RGERR_CFG_INVALID_CRG_LC_RECFG     RG_CFG_ERRCAUSE_BASE + 6
+#define RGERR_CFG_INVALID_RGR_CELL_CFG     RG_CFG_ERRCAUSE_BASE + 7
+#define RGERR_CFG_INVALID_RGR_CELL_RECFG   RG_CFG_ERRCAUSE_BASE + 8
+#define RGERR_CFG_CRG_CELL_CFG             RG_CFG_ERRCAUSE_BASE + 9
+#define RGERR_CFG_CRG_UE_CFG               RG_CFG_ERRCAUSE_BASE + 10
+#define RGERR_CFG_CRG_DED_LC_CFG           RG_CFG_ERRCAUSE_BASE + 11
+#define RGERR_CFG_CRG_CMN_LC_CFG           RG_CFG_ERRCAUSE_BASE + 12
+#define RGERR_CFG_CRG_CELL_RECFG           RG_CFG_ERRCAUSE_BASE + 13
+#define RGERR_CFG_CRG_UE_RECFG             RG_CFG_ERRCAUSE_BASE + 14
+#define RGERR_CFG_CRG_LC_RECFG             RG_CFG_ERRCAUSE_BASE + 15
+#define RGERR_CFG_RGR_CELL_CFG             RG_CFG_ERRCAUSE_BASE + 16
+#define RGERR_CFG_RGR_CELL_RECFG           RG_CFG_ERRCAUSE_BASE + 17
+#define RGERR_CFG_CRG_CELL_DEL             RG_CFG_ERRCAUSE_BASE + 18
+#define RGERR_CFG_CRG_UE_DEL               RG_CFG_ERRCAUSE_BASE + 19
+#define RGERR_CFG_CRG_LC_DEL               RG_CFG_ERRCAUSE_BASE + 20
+#define RGERR_CFG_INVALID_CRG_UE_RESET     RG_CFG_ERRCAUSE_BASE + 21
+#ifdef LTE_ADV
+#define RGERR_CFG_CRG_UE_SCELL_CFG           RG_CFG_ERRCAUSE_BASE + 22
+#endif /* LTE_ADV */
+/* Scheduler related error causes */
+#define RG_SCH_ERRCAUSE_BASE               RGERR_CFG_CRG_LC_DEL + 1
+#define RGERR_SCH_CFG                      RG_SCH_ERRCAUSE_BASE 
+#define RGERR_SCH_LCG_NOT_CFGD             RG_SCH_ERRCAUSE_BASE + 1
+#define RGERR_SCH_NO_LCG_CFGD              RG_SCH_ERRCAUSE_BASE + 2
+
+   
+
+#endif /* __RGERRH__ */
+/********************************************************************30**
+  
+         End of file
+**********************************************************************/
diff --git a/src/5gnrmac/rg_ex_ms.c b/src/5gnrmac/rg_ex_ms.c
new file mode 100755
index 000000000..0c8eb8a2e
--- /dev/null
+++ b/src/5gnrmac/rg_ex_ms.c
@@ -0,0 +1,479 @@
+/*******************************************************************************
+################################################################################
+#   Copyright (c) [2017-2019] [Radisys]                                        #
+#                                                                              #
+#   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.                                             #
+################################################################################
+*******************************************************************************/
+
+/************************************************************************
+ 
+     Name:     LTE-MAC layer
+  
+     Type:     C source file
+  
+     Desc:     C source code SSI Interface Implementation
+  
+     File:     rg_ex_ms.c 
+  
+**********************************************************************/
+
+/** @file rg_ex_ms.c
+@brief This file contains the implementation of callback functions 
+registered with SSI during the LTE MAC Task initialization.
+*/
+/* header include files -- defines (.h) */
+#include "envopt.h"        /* environment options */
+#include "envdep.h"        /* environment dependent */
+#include "envind.h"        /* environment independent */
+#include "gen.h"           /* general layer */
+#include "ssi.h"           /* system services */
+#include "cm5.h"           /* common timers defines */
+#include "cm_hash.h"       /* common hash list defines */
+#include "cm_llist.h"      /* common linked list defines */
+#include "cm_mblk.h"       /* memory management */
+#include "cm_tkns.h"       /* common tokens */
+#include "cm_lte.h"        /* common tokens */
+#include "rgu.h"           /* RGU defines */
+#include "tfu.h"           /* RGU defines */
+#include "lrg.h"           /* layer management defines for LTE-MAC */
+#include "crg.h"           /* CRG interface includes */
+#include "rg_sch_inf.h"    /* SCH interface includes */
+#include "rg_prg.h"        /* PRG interface includes */
+#include "rg_env.h"        /* customisable defines and macros for LTE-MAC */
+#include "rg.h"            /* defines and macros for MAC */
+
+
+/* header/extern include files (.x) */
+#include "gen.x"           /* general layer typedefs */
+#include "ssi.x"           /* system services typedefs */
+#include "cm5.x"           /* common timers */
+#include "cm_hash.x"       /* common hash list */
+#include "cm_lib.x"        /* common library */
+#include "cm_llist.x"      /* common linked list */
+#include "cm_mblk.x"       /* memory management */
+#include "cm_tkns.x"       /* common tokens */
+#include "cm_lte.x"        /* common tokens */
+#include "rgu.x"           /* RGU types */
+#include "tfu.x"           /* RGU types */
+#include "lrg.x"           /* layer management typedefs for MAC */
+#include "crg.x"           /* CRG interface typedes */
+#include "rg_sch_inf.x"    /* SCH interface typedefs */
+#include "rg_prg.x"        /*PRG interface includes*/
+#include "rg.x"            /* typedefs for MAC */
+
+
+/**
+ * @brief Task Activation callback function Entity SM. 
+ *
+ * @details
+ *
+ *     Function : rgHdlSMEvents
+ *     
+ *     Process Messages received from Entity SM
+ *     
+ *  @param[in]  Pst     *pst, Post structure of the primitive.     
+ *  @param[in]  Buffer *mBuf, Packed primitive parameters in the buffer.
+ *  @param[in]  Reason reason.
+ *  @return  void
+ **/
+#ifdef ANSI
+PRIVATE INLINE void rgHdlSMEvents
+(
+Pst     *pst,                       /* post structure       */
+Buffer  *mBuf                       /* message buffer       */
+)
+#else
+PRIVATE INLINE void rgHdlSMEvents(pst, mBuf)
+Pst     *pst;                       /* post structure       */
+Buffer  *mBuf;                      /* message buffer       */
+#endif
+{
+   TRC2(rgHdlSMEvents)
+
+   switch(pst->event)
+   {
+#ifdef LCRGMILRG
+      case EVTLRGCFGREQ:
+         /* Process a config. request */
+         cmUnpkLrgCfgReq(RgMiLrgCfgReq, pst, mBuf);
+         break;
+      case EVTLRGCNTRLREQ:
+         /* Process a control request */
+         cmUnpkLrgCntrlReq(RgMiLrgCntrlReq, pst, mBuf);
+         break;
+      case EVTLRGSSTAREQ:
+         /* Process a status request  */
+         cmUnpkLrgStaReq(RgMiLrgStaReq, pst, mBuf);
+         break;
+      case EVTLRGSTSREQ:
+         /* Process a statistics request */
+         cmUnpkLrgStsReq(RgMiLrgStsReq, pst, mBuf);
+         break;
+#endif /* LCRGMILRG */
+      default:
+         RG_FREE_MSG(mBuf);
+         break;
+   }
+}
+
+
+/**
+ * @brief Task Activation callback function Entity NH. 
+ *
+ * @details
+ *
+ *     Function : rgHdlNHEvents
+ *     
+ *     Process Messages received from Entity NH
+ *     
+ *  @param[in]  Pst     *pst, Post structure of the primitive.     
+ *  @param[in]  Buffer *mBuf, Packed primitive parameters in the buffer.
+ *  @param[in]  Reason reason.
+ *  @return  void
+ **/
+#ifdef ANSI
+PRIVATE INLINE void rgHdlNHEvents
+(
+Pst     *pst,                       /* post structure       */
+Buffer  *mBuf                       /* message buffer       */
+)
+#else
+PRIVATE INLINE void rgHdlNHEvents(pst, mBuf)
+Pst     *pst;                       /* post structure       */
+Buffer  *mBuf;                      /* message buffer       */
+#endif
+{
+   TRC2(rgHdlNHEvents)
+
+   switch(pst->event)
+   {
+#ifdef LCRGUICRG
+      case EVTCRGBNDREQ:
+         cmUnpkCrgBndReq(RgUiCrgBndReq, pst, mBuf);
+         break;
+      case EVTCRGUBNDREQ:
+         cmUnpkCrgUbndReq(RgUiCrgUbndReq, pst, mBuf);
+         break;
+      case EVTCRGCFGREQ:
+         cmUnpkCrgCfgReq(RgUiCrgCfgReq, pst, mBuf);
+         break;
+#endif            
+      default:
+         RG_FREE_MSG(mBuf);
+         break;
+   }
+}
+
+/**
+ * @brief Task Activation callback function Entity KW. 
+ *
+ * @details
+ *
+ *     Function : rgHdlKWEvents
+ *     
+ *     Process Messages received from Entity KW
+ *     
+ *  @param[in]  Pst     *pst, Post structure of the primitive.     
+ *  @param[in]  Buffer *mBuf, Packed primitive parameters in the buffer.
+ *  @param[in]  Reason reason.
+ *  @return  void
+ **/
+#ifdef ANSI
+PRIVATE INLINE void rgHdlKWEvents
+(
+Pst     *pst,                       /* post structure       */
+Buffer  *mBuf                       /* message buffer       */
+)
+#else
+PRIVATE INLINE void rgHdlKWEvents(pst, mBuf)
+Pst     *pst;                       /* post structure       */
+Buffer  *mBuf;                      /* message buffer       */
+#endif
+{
+   TRC2(rgHdlKWEvents)
+
+   switch(pst->event)
+   {
+#ifdef LCRGUIRGU
+      case EVTRGUBNDREQ:
+         cmUnpkRguBndReq(RgUiRguBndReq, pst, mBuf);
+         break;
+      case EVTRGUUBNDREQ:
+         cmUnpkRguUbndReq(RgUiRguUbndReq, pst, mBuf);
+         break;
+      case EVTRGUCDATREQ:
+         cmUnpkRguCDatReq(RgUiRguCDatReq, pst, mBuf);
+         break;
+      case EVTRGUDDATREQ:
+         cmUnpkRguDDatReq(RgUiRguDDatReq, pst, mBuf);
+         break;
+      case EVTRGUCSTARSP:
+         cmUnpkRguCStaRsp(RgUiRguCStaRsp, pst, mBuf);
+         break;
+      case EVTRGUDSTARSP:
+         cmUnpkRguDStaRsp(RgUiRguDStaRsp, pst, mBuf);
+         break;
+#ifdef LTE_L2_MEAS
+
+      case EVTRGUL2MULTHRPMEASREQ:
+         cmUnpkRguL2MUlThrpMeasReq(RgUiRguL2MUlThrpMeasReq, pst,mBuf);
+         break;
+
+#endif
+#endif            
+      default:
+         RG_FREE_MSG(mBuf);
+         break;
+   }
+}
+
+/**
+ * @brief Task Activation callback function Entity TF. 
+ *
+ * @details
+ *
+ *     Function : rgHdlTFEvents
+ *     
+ *     Process Messages received from Entity TF
+ *     
+ *  @param[in]  Pst     *pst, Post structure of the primitive.     
+ *  @param[in]  Buffer *mBuf, Packed primitive parameters in the buffer.
+ *  @param[in]  Reason reason.
+ *  @return  void
+ **/
+#ifdef ANSI
+PRIVATE INLINE void rgHdlTFEvents
+(
+Pst     *pst,                       /* post structure       */
+Buffer  *mBuf                       /* message buffer       */
+)
+#else
+PRIVATE INLINE void rgHdlTFEvents(pst, mBuf)
+Pst     *pst;                       /* post structure       */
+Buffer  *mBuf;                      /* message buffer       */
+#endif
+{
+   TRC2(rgHdlTFEvents)
+
+   switch(pst->event)
+   {
+#if  (defined(LCRGLITFU) || defined(LWLCRGLITFU))
+      case EVTTFUBNDCFM:
+         cmUnpkTfuBndCfm(RgLiTfuBndCfm, pst, mBuf);
+         break;
+      case EVTTFUDATIND:
+         cmUnpkTfuDatInd(RgLiTfuDatInd, pst, mBuf);
+         break;
+      case EVTTFUTTIIND:
+         cmUnpkTfuTtiInd(RgLiTfuTtiInd, pst, mBuf);
+         break;
+#if defined(TENB_T2K3K_SPECIFIC_CHANGES) && defined(LTE_TDD)
+      case EVTTFUNONRTIND:
+         cmUnpkTfuNonRtInd(RgLiTfuNonRtInd, pst, mBuf);
+         break;
+#endif
+#endif            
+      default:
+         RG_FREE_MSG(mBuf);
+         break;
+   }
+}
+
+
+/**
+ * @brief Task Activation callback function Entity RG SCH. 
+ *
+ * @details
+ *
+ *     Function : rgHdlRGEvents
+ *     
+ *     Process Messages received from Entity RG SCH
+ *     
+ *  @param[in]  Pst     *pst, Post structure of the primitive.     
+ *  @param[in]  Buffer *mBuf, Packed primitive parameters in the buffer.
+ *  @param[in]  Reason reason.
+ *  @return  void
+ **/
+#ifdef ANSI
+PRIVATE INLINE void rgHdlRGEvents
+(
+Pst     *pst,                       /* post structure       */
+Buffer  *mBuf                       /* message buffer       */
+)
+#else
+PRIVATE INLINE void rgHdlRGEvents(pst, mBuf)
+Pst     *pst;                       /* post structure       */
+Buffer  *mBuf;                      /* message buffer       */
+#endif
+{
+   TRC2(rgHdlRGEvents)
+
+   switch(pst->event)
+   {
+#ifdef LCRG
+      case EVTINFCELLREGREQ:
+         cmUnpkSchMacCellRegReq(RgSchMacCellRegReq, pst, mBuf);
+         break;
+      case EVTINFSFALLOCREQ:
+         cmUnpkSchMacSfAllocReq(RgSchMacSfAllocReq, pst, mBuf);
+         break;
+      case EVTINFRLSHQREQ:
+         cmUnpkSchMacRlsHqReq(RgSchMacRlsHqReq, pst, mBuf);
+         break;
+      case EVTINFHQENTRESET:
+         cmUnpkSchMacRstHqEntReq(RgSchMacRstHqEntReq, pst, mBuf);
+         break;
+      case EVTINFRLSRNTIREQ:
+         cmUnpkSchMacRlsRntiReq(RgSchMacRlsRntiReq, pst, mBuf);
+         break;
+#ifdef LTEMAC_SPS
+      case EVTINFSPSLCREG:
+         cmUnpkSchMacSpsLcRegReq(RgSchMacSpsLcRegReq, pst, mBuf);
+         break;
+      case EVTINFSPSLCDEREG:
+         cmUnpkSchMacSpsLcDeregReq(RgSchMacSpsLcDeregReq, pst, mBuf);
+         break;
+      case EVTINFSPSRESET:
+         cmUnpkSchMacUlSpsResetReq(RgSchMacUlSpsResetReq, pst, mBuf);
+         break;
+#endif /* LTEMAC_SPS */
+#ifdef LTE_L2_MEAS
+      case EVTINFL2MEASREQ:
+         cmUnpkSchMacL2MeasReq(RgSchMacL2MeasReq, pst, mBuf);
+         break;
+      case EVTINFL2MEASSENDREQ :
+         cmUnpkSchMacL2MeasSendReq(RgSchMacL2MeasSendReq, pst , mBuf);
+         break;
+      case EVTINFL2MEASSTOPREQ:
+         cmUnpkSchMacL2MeasStopReq(RgSchMacL2MeasStopReq, pst , mBuf);
+         break;
+#endif/* LTE_L2_MEAS */
+      case EVTINFLCGREG:
+         cmUnpkSchMacLcgRegReq(RgSchMacLcgRegReq, pst, mBuf);
+         break;
+#endif            
+#if defined(LTE_ADV) && defined(LCPRG)
+      case EVTPRGUESCELLCFGREQ:
+      {
+         cmUnpkPrgPMacSMacUeSCellCfgReq(RgPrgPMacSMacUeSCellCfgReq, pst, mBuf);
+      }
+      break;
+      case EVTPRGUESCELLCFGCFM:
+      case EVTPRGUESCELLLCHMODCFM:
+      case EVTPRGUESCELLLCHDELCFMDEL:
+      case EVTPRGUESCELLLCHADDCFM:
+      {
+         cmUnpkPrgSMacPMacCfgCfm(RgPrgSMacPMacCfgCfm, pst, mBuf);
+      }
+      break;
+      case EVTPRGUESCELLDELREQ:
+      {
+         cmUnpkPrgPMacSMacUeSCellDelReq(RgPrgPMacSMacUeSCellDelReq, pst, mBuf);
+      }
+      break;
+      case EVTPRGUESCELLLCHMODREQ:
+      {
+         cmUnpkPrgPMacSMacUeSCellLchModReq(RgPrgPMacSMacUeSCellLchModReq, pst,
+                                           mBuf);
+      }
+      break;
+      case EVTPRGUESCELLLCHDELREQ:
+      {
+         cmUnpkPrgPMacSMacUeSCellLchDelReq(RgPrgPMacSMacUeSCellLchDelReq, pst,
+                                           mBuf);
+      }
+      break;
+      case EVTPRGUESCELLLCHADDREQ:
+      {
+         cmUnpkPrgPMacSMacUeSCellLchAddReq(RgPrgPMacSMacUeSCellLchAddReq, pst,
+                                           mBuf);
+      }
+      break;
+
+#endif
+      default:
+      {
+         RG_FREE_MSG(mBuf);
+         break;
+      }
+
+   }
+}
+
+
+
+/**
+ * @brief Task Activation callback function. 
+ *
+ * @details
+ *
+ *     Function : rgActvTsk
+ *     
+ *     Primitives invoked by MAC's users/providers through
+ *     a loosely coupled interface arrive here by means of 
+ *     SSI's message handling. This API is registered with
+ *     SSI during the Task Registration of MAC.
+ *     
+ *  @param[in]  Pst     *pst, Post structure of the primitive.     
+ *  @param[in]  Buffer *mBuf, Packed primitive parameters in the buffer.
+ *  @param[in]  Reason reason.
+ *  @return  S16
+ *      -# ROK
+ **/
+#ifdef ANSI
+PUBLIC S16 rgActvTsk
+(
+Pst     *pst,                       /* post structure       */
+Buffer  *mBuf                       /* message buffer       */
+)
+#else
+PUBLIC S16 rgActvTsk(pst, mBuf)
+Pst     *pst;                       /* post structure       */
+Buffer  *mBuf;                      /* message buffer       */
+#endif
+{
+   TRC2(rgActvTsk)
+
+   switch(pst->srcEnt)
+   {
+      /* The originator of this message is the stack manager,
+       * unpack and go to the respective primitive processing function */
+      case ENTSM:
+          rgHdlSMEvents(pst, mBuf);
+           break;
+      case ENTNH:
+          rgHdlNHEvents(pst, mBuf);
+          break;
+      case ENTKW:
+          rgHdlKWEvents(pst, mBuf);
+          break;
+      case ENTTF:
+          rgHdlTFEvents(pst, mBuf);
+          break;
+      case ENTRG: /* When scheduler instance sends msg to MAC */
+          rgHdlRGEvents(pst, mBuf);
+          break;
+       default:
+          RG_FREE_MSG(mBuf);
+          break;
+   }
+   SExitTsk();
+   RETVALUE(ROK);
+}/* end of rgActvTsk */
+
+
+/**********************************************************************
+ 
+         End of file
+**********************************************************************/
diff --git a/src/5gnrmac/rg_id.c b/src/5gnrmac/rg_id.c
new file mode 100755
index 000000000..8b4f52daa
--- /dev/null
+++ b/src/5gnrmac/rg_id.c
@@ -0,0 +1,134 @@
+/*******************************************************************************
+################################################################################
+#   Copyright (c) [2017-2019] [Radisys]                                        #
+#                                                                              #
+#   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.                                             #
+################################################################################
+*******************************************************************************/
+
+/************************************************************************
+ 
+     Name:     LTE-MAC layer
+  
+     Type:     C source file
+  
+     Desc:     C source code to provide software part number, version and
+               revision. 
+  
+     File:     rg_id.c 
+  
+**********************************************************************/
+
+/** @file rg_id.c
+@brief This file contains the definition of this software's part number, 
+       version and revision. Also provides an API to access the same.
+*/
+
+/* header include files (.h) */
+#include "envopt.h"           /* environment options */  
+#include "envdep.h"           /* environment dependent */
+#include "envind.h"           /* environment independent */
+#include "gen.h"              /* general layer */
+#include "ssi.h"              /* system services */
+#include "lrg.h"              /* layer manager */
+   
+/* header/extern include files (.x) */
+#include "gen.x"              /* general layer */
+#include "ssi.x"              /* system services */
+#include "cm_lib.x"           /* common library */
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+EXTERN Void rgGetSId ARGS((SystemId *s));
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+/* defines */
+#define RGSWMV 3             /* LTE MAC- main version */
+#define RGSWMR 1             /* LTE MAC - main revision */
+#define RGSWBV 0             /* LTE MAC - branch version */
+/* Updated the branch revision Number */
+#define RGSWBR 2             /* LTE MAC - branch revision */
+#define RGSWPN "1000372"     /* LTE MAC - part number */
+
+/* system id */
+PRIVATE CONSTANT SystemId sId ={
+   RGSWMV,              /* LTE MAC - main version */
+   RGSWMR,              /* LTE MAC - main revision */
+   RGSWBV,              /* LTE MAC - branch version */
+   RGSWBR,              /* LTE MAC - branch revision */
+   (Txt *)RGSWPN               /* LTE MAC - part number */
+};
+
+
+/**
+ * @brief Retrieve system id. 
+ *
+ * @details
+ *
+ *     Function : rgGetSId 
+ *    
+ *     Get system id consisting of part number, main version and
+ *     revision and branch version and branch.
+ *     
+ *     
+ *  @param[out] SystemId *s  
+ *  @return  void
+ **/
+/*
+*
+*       Fun:   get system id
+*
+*       Desc:  Get system id consisting of part number, main version and
+*              revision and branch version and branch.
+*
+*       Ret:   TRUE      - ok
+*
+*       Notes: None
+*
+*       File:  rg_id.c
+*
+*/
+ 
+#ifdef ANSI
+PUBLIC Void rgGetSId
+(
+SystemId *s                 /* system id */
+)
+#else
+PUBLIC Void rgGetSId(s)
+SystemId *s;                /* system id */
+#endif
+{
+   TRC2(rgGetSId);
+
+   s->mVer = sId.mVer;
+   s->mRev = sId.mRev;
+   s->bVer = sId.bVer;
+   s->bRev = sId.bRev;
+   cmMemcpy((U8 *)s->ptNmb, (U8 *)sId.ptNmb, LRG_MAX_PT_NUM_SIZE); 
+
+   /* Stack Crash Problem for TRACE5 Changes. Added the return below */
+  RETVOID; 
+  
+} /* end of rgGetSid */
+
+
+
+/**********************************************************************
+ 
+         End of file
+**********************************************************************/
diff --git a/src/5gnrmac/rg_l2m.c b/src/5gnrmac/rg_l2m.c
new file mode 100755
index 000000000..2018b9b1b
--- /dev/null
+++ b/src/5gnrmac/rg_l2m.c
@@ -0,0 +1,678 @@
+/*******************************************************************************
+################################################################################
+#   Copyright (c) [2017-2019] [Radisys]                                        #
+#                                                                              #
+#   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.                                             #
+################################################################################
+*******************************************************************************/
+
+/************************************************************************
+ 
+     Name:     LTE-MAC layer
+  
+     Type:     C source file
+  
+     Desc:     C source code for  L2 Measurements in MAC
+  
+     File:     rg_l2m.c
+  
+**********************************************************************/
+
+/** @file rg_l2m.c
+@brief This file implements the schedulers main access to MAC layer code.
+*/
+
+/* header include files -- defines (.h) */
+#include "envopt.h"        /* environment options */
+#include "envdep.h"        /* environment dependent */
+#include "envind.h"        /* environment independent */
+#include "gen.h"           /* general layer */
+#include "ssi.h"           /* system service interface */
+#include "cm_hash.h"       /* common hash list */
+#include "cm_llist.h"      /* common linked list library */
+#include "cm_err.h"        /* common error */
+#include "cm_lte.h"        /* common LTE */
+#include "lrg.h"
+#include "crg.h"        
+#include "rgr.h"
+#include "rgu.h"           
+#include "tfu.h"
+#include "rg_env.h"
+#include "rg_err.h"
+#include "rg_sch_inf.h"
+#include "rg.h"
+
+/* header/extern include files (.x) */
+#include "gen.x"           /* general layer typedefs */
+#include "ssi.x"           /* system services typedefs */
+#include "cm5.x"           /* common timers */
+#include "cm_hash.x"       /* common hash list */
+#include "cm_lib.x"        /* common library */
+#include "cm_llist.x"      /* common linked list */
+#include "cm_mblk.x"       /* memory management */
+#include "cm_tkns.x"       /* common tokens */
+#include "cm_lte.x"       /* common tokens */
+#include "rgu.x"           /* RGU types */
+#include "tfu.x"           /* TFU types */
+#include "lrg.x"           /* layer management typedefs for MAC */
+#include "rgr.x"           /* layer management typedefs for MAC */
+#include "crg.x"           /* layer management typedefs for MAC */
+#include "rg_sch_inf.x"    /* typedefs for Scheduler */
+#include "rg_prg.x"        /* typedefs for PRG interface */
+#include "rg.x"            /* MAC types */
+
+#ifdef LTE_L2_MEAS
+static const char* RLOG_MODULE_NAME="MAC";
+static int RLOG_FILE_ID=183;
+static int RLOG_MODULE_ID=4096;
+#endif 
+
+/* local defines */
+#ifdef LTE_L2_MEAS
+PRIVATE S16 rgL2mInsertMeasCb ARGS((
+         RgCellCb       *cell,
+         RgL2MeasCb     *measCb,
+         RgInfL2MeasReq *measInfo ));
+
+PRIVATE RgL2MeasCb * rgL2mAllocMeasCb ARGS((
+         RgCellCb       *cell,
+         RgInfL2MeasReq *measInfo,
+         RgErrInfo      *err));
+
+/* Function definitions */
+
+/** @brief This function creates the measCb
+ *
+ * @details
+ *
+ *     Function: rgL2mCreateMeasCb
+ *         Processing steps:
+ *         - Check the measType
+ *         - Create measCb for every qci
+ *
+ * @param  [in] RgCellCb       *cell
+ * @param  [in] RgInfL2MeasReq *measInfo
+ * @param  [in] U8             measType
+ * @param  [out] RgErrInfo      *err
+ * @return  S16
+ *      -# ROK 
+ *      -# RFAILED 
+ *
+ */
+#ifdef ANSI
+PUBLIC S16 rgL2mCreateMeasCb 
+(
+RgCellCb       *cell,
+RgInfL2MeasReq *measInfo, 
+U8              measType,
+RgErrInfo      *err
+)
+#else
+PUBLIC S16 rgL2mCreateMeasCb(cell, measInfo, measType, err)
+RgCellCb       *cell;
+RgInfL2MeasReq *measInfo; 
+U8              measType;
+RgErrInfo      *err;
+#endif    
+{
+  // Inst    inst = cell->macInst - RG_INST_START;
+   U32     idx;
+   RgL2MeasCb       *measCb = NULLP;
+   U8            qciVal = 0;
+
+   UNUSED(measType);
+   UNUSED(err);
+
+   TRC3(rgL2mCreateMeasCb)
+
+      if ((measCb = rgL2mAllocMeasCb(cell, measInfo, err)) == NULLP)
+      {
+         RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,"Allocation of RgL2MeasCb failed");
+         RETVALUE(RFAILED);
+      }
+   //Memcpy is already done in rgL2mAllocMeasCb
+   /*cmMemcpy((U8 *)&measCb->measReq, (CONSTANT U8 *)measInfo,\
+     sizeof(RgInfL2MeasReq));*/
+   rgL2mInsertMeasCb(cell, measCb, measInfo);
+   measCb->measReq.timePrd = measInfo->timePrd;
+
+   if(measInfo->timePrd == 0)
+   {
+      cell->sndL2Meas = FALSE;
+   }
+
+   for(idx = 0; idx < measInfo->t.prbReq.numQci; idx++)
+   {
+      if(measInfo->timePrd == 0)
+      {
+         qciVal = measInfo->t.prbReq.qci[idx];
+         cell->qciArray[qciVal].qci = qciVal;
+      }
+      cell->qciArray[measInfo->t.prbReq.qci[idx]].mask = TRUE;
+   }
+   RETVALUE(ROK);
+} /* rgL2mCreateMeasCb */
+
+
+/**
+ * @brief Layer Manager Measurement request handler. 
+ *
+ * @details
+ *
+ *     Function : rgL2mMeasReq
+ *     
+ *     This function handles  measurement request received at MAC
+ *     from the Scheduler.
+ *     -# Measurement request will be stored in the list in descending order of
+ *     there time period.
+ *     
+ *  @param[in]  Pst *pst, the post structure     
+ *  @param[in]  RgInfL2MeasReq *measInfo, the measurement request structure
+ *  @param[out] RgErrInfo   *err, error information
+ *  @return  S16
+ *      -# ROK
+ **/
+#ifdef ANSI
+PUBLIC S16 rgL2mMeasReq 
+(
+RgCellCb       *cell,
+RgInfL2MeasReq *measInfo,
+RgErrInfo      *err
+)
+#else
+PUBLIC S16 rgL2mMeasReq(cell, measInfo, err)
+RgCellCb       *cell;
+RgInfL2MeasReq *measInfo; 
+RgErrInfo      *err;
+#endif    
+{
+   S16  ret=RFAILED;
+
+   TRC3(rgL2mMeasReq)
+   /* Creaet MeasCb Insert in cell->l2mList and return*/
+   if ( (ret = rgL2mCreateMeasCb(cell, measInfo,
+               LRG_L2MEAS_AVG_PRB_PER_QCI_UL, err)) != ROK)
+   {
+      /* Clear Downlink MeasCb created Above If exists*/
+      RETVALUE(ret);
+   }
+   RETVALUE(ROK);
+} /* rgL2mMeasReq */
+/** @brief This function sends the measurement confirm
+ *  from mac to scheduler
+ *
+ * @details
+ *
+ *     Function: rgSndL2MeasCfm
+ *
+ * @param  [in] RgCellCb          *cell
+ * @param  [in] RgInfL2MeasCfm    *measCfm
+ */
+#ifdef ANSI
+PRIVATE Void rgSndL2MeasCfm
+(
+RgCellCb          *cell, 
+RgInfL2MeasCfm    *measCfm
+)
+#else
+PRIVATE Void rgSndL2MeasCfm (cell, measCfm)
+RgCellCb          *cell; 
+RgInfL2MeasCfm    *measCfm;   
+#endif
+{
+   Pst             pst;
+   Inst            macInst = cell->macInst - RG_INST_START;
+   TRC3(rgSndL2MeasCfm)
+
+      cmMemset((U8 *)&pst, 0, sizeof(Pst));
+   rgGetPstToInst(&pst,macInst, cell->schInstMap.schInst);
+   RgMacSchL2Meas(&pst, measCfm);
+
+   RETVOID;
+}/* rgSndL2MeasCfm */
+
+/** @brief This function sends the measurement stop confirm
+ *  from mac to scheduler
+ *
+ * @details
+ *
+ *     Function: rgSndL2MeasStopCfm
+ *
+ * @param  [in] RgCellCb          *cell
+ * @param  [in] RgInfL2MeasCfm    *measCfm
+ */
+#ifdef ANSI
+PRIVATE Void rgSndL2MeasStopCfm
+(
+RgCellCb          *cell,
+RgInfL2MeasCfm    *measCfm
+)
+#else
+PRIVATE Void rgSndL2MeasStopCfm (cell, measCfm)
+RgCellCb          *cell;
+RgInfL2MeasCfm    *measCfm;
+#endif
+{
+   Pst             pst;
+   Inst            macInst = cell->macInst - RG_INST_START;
+
+   TRC3(rgSndL2MeasStopCfm)
+      cmMemset((U8 *)&pst, 0, sizeof(Pst));
+   rgGetPstToInst(&pst,macInst, cell->schInstMap.schInst);
+   RgMacSchL2MeasStop(&pst, measCfm);
+
+   RETVOID;
+}/* rgSndL2MeasStopCfm */
+
+/**
+ * @brief  L2 Measurement request handler.This function shall be called by
+ *  scheduler to calculate average PRB usage Per Qci in Uplink
+ *
+ * @details
+ *
+ *     Function : RgSchMacL2MeasReq
+ *     
+ *  @param[in]  Pst *pst, the post structure     
+ *  @param[in]  RgInfL2MeasReq *measInfo, L2 Measurement req structure
+ *  @return  S16
+ *      -# ROK
+ *      -# RFAILED
+ **/
+#ifdef ANSI
+PUBLIC S16 RgSchMacL2MeasReq
+(
+Pst               *pst,          /* post structure  */
+RgInfL2MeasReq    *measInfo      /* Meas Req Info */
+)
+#else
+PUBLIC S16 RgSchMacL2MeasReq(pst, measInfo)
+Pst               *pst;          /* post structure  */
+RgInfL2MeasReq    *measInfo;      /* Meas Req Info */
+#endif    
+{
+   Inst            inst;
+   RgCellCb        *cellCb = NULLP;
+   RgErrInfo       err;
+   S16             ret = ROK;
+   RgInfL2MeasCfm   measCfm;
+
+   TRC3(RgSchMacL2MeasReq)
+
+
+   RG_IS_INST_VALID(pst->dstInst);
+   inst   = pst->dstInst - RG_INST_START;
+   cellCb = rgCb[inst].cell;
+   /* Get the  cell using cellId */
+   if ((cellCb == NULLP) ||
+       (cellCb->cellId != measInfo->cellId))
+   {
+      RLOG_ARG0(L_ERROR,DBG_CELLID,measInfo->cellId,"unable to get the cellCb");
+      RETVALUE(RFAILED);
+   }
+   /* Call L2M Function to store Meas req */
+   ret = rgL2mMeasReq(cellCb, measInfo, &err);
+   if (ret != ROK)
+   {
+      cmMemset((U8 *)&measCfm, 0, sizeof(RgInfL2MeasCfm));
+      measCfm.transId     = measInfo->transId;
+      measCfm.cellId      = measInfo->cellId;
+      measCfm.measType    = measInfo->measType;
+      measCfm.cfm.reason   = LCM_REASON_INVALID_PAR_VAL;
+      measCfm.cfm.status  = LCM_PRIM_NOK;
+      rgSndL2MeasCfm(cellCb, &measCfm);
+      RLOG_ARG2(L_ERROR,DBG_CELLID,measInfo->cellId,
+               "Meas req Failed  errType(%d) errCause(%d)",
+               err.errType, err.errCause);
+      RETVALUE(RFAILED);
+   }
+   RETVALUE(ret);
+} /* -- RgSchMacL2MeasReq-- */
+
+/**
+ * @brief  L2 Measurement request handler.This function shall be called by
+ *         sch to to stop l2 measurement in MAC,
+ *
+ * @details
+ *
+ *     Function : RgSchMacL2MeasStopReq
+ *     
+ *  @param[in]  Pst *pst, the post structure     
+ *  @param[in]  RgInfL2MeasReq *measInfo, L2 Measurement req structure
+ *  @return  S16
+ *      -# ROK
+ *      -# RFAILED
+ **/
+#ifdef ANSI
+PUBLIC S16 RgSchMacL2MeasStopReq
+(
+Pst               *pst,          /* post structure  */
+RgInfL2MeasStopReq *measInfo      /* Meas Req Info */
+)
+#else
+PUBLIC S16 RgSchMacL2MeasStopReq(pst, measInfo)
+Pst               *pst;          /* post structure  */
+RgInfL2MeasStopReq *measInfo;      /* Meas Req Info */
+#endif
+{
+   S16             ret = ROK;   
+   CmLList         *node   = NULLP;
+   RgL2MeasCb      *measCb = NULLP;
+   U8               idx;
+   U8               qciVal;
+   Inst             inst;
+   RgCellCb        *cellCb = NULLP;
+
+   RgInfL2MeasCfm  measCfm;
+
+   TRC3(RgSchMacL2MeasStopReq)
+
+
+   RG_IS_INST_VALID(pst->dstInst);
+   inst   = pst->dstInst - RG_INST_START;
+   cellCb = rgCb[inst].cell;
+      /* Get the  cell using cellId */
+   if ((cellCb == NULLP) ||
+       (cellCb->cellId != measInfo->cellId))
+   {
+      
+      RLOG_ARG0(L_ERROR,DBG_CELLID,measInfo->cellId,
+            "Unable to get the cellCb");
+      RETVALUE(RFAILED);
+   }
+   node = cellCb->l2mList.first; 
+   while(node != NULLP)
+   {
+      measCb = (RgL2MeasCb *)(node)->node;
+      node = (node)->next;
+      /*L2 Meas off for qci in cell */
+      for(idx = 0; idx < measCb->measReq.t.prbReq.numQci; idx++)
+      {
+         qciVal = measCb->measReq.t.prbReq.qci[idx];
+         cellCb->qciArray[qciVal].mask = FALSE;
+      }
+      cmLListDelFrm(&cellCb->l2mList, &measCb->measLnk);
+      rgFreeSBuf(inst,(Data**)&measCb, sizeof(RgL2MeasCb));
+   }
+   cmMemset((U8 *)&measCfm, 0, sizeof(RgInfL2MeasCfm));
+   measCfm.transId     = measInfo->transId;
+   measCfm.cellId      = measInfo->cellId;
+   measCfm.measType    = measInfo->measType;
+   measCfm.cfm.status  = LCM_PRIM_OK;
+   rgSndL2MeasStopCfm(cellCb, &measCfm);
+   RETVALUE(ret);
+} /* -- RgSchMacL2MeasStopReq-- */
+
+/**
+ * @brief  L2 Measurement request handler.This function shall be called by
+ *  scheduler for  sending L2 meas 
+ *
+ * @details
+ *
+ *     Function : RgSchMacL2MeasSendReq
+ *     
+ *  @param[in]  Pst *pst, the post structure     
+ *  @param[in]  RgInfL2MeasReq *measInfo, L2 Measurement req structure
+ *  @return  S16
+ *      -# ROK
+ *      -# RFAILED
+ **/
+#ifdef ANSI
+PUBLIC S16 RgSchMacL2MeasSendReq
+(
+Pst               *pst,          /* post structure  */
+RgInfL2MeasSndReq *measInfo      /* Meas Req Info */
+)
+#else
+PUBLIC S16 RgSchMacL2MeasSendReq(pst, measInfo)
+Pst               *pst;          /* post structure  */
+RgInfL2MeasSndReq *measInfo;      /* Meas Req Info */
+#endif
+{
+   Inst            inst;
+   RgCellCb       *cellCb = NULLP;
+   S16             ret    = ROK;
+
+   TRC3(RgSchMacL2MeasSendReq)
+
+
+   RG_IS_INST_VALID(pst->dstInst);
+   inst   = pst->dstInst - RG_INST_START;
+   cellCb = rgCb[inst].cell;
+      /* Get the  cell using cellId */
+   if ((cellCb == NULLP) ||
+       (cellCb->cellId != measInfo->cellId))
+   {
+      
+      RLOG_ARG0(L_ERROR,DBG_CELLID,measInfo->cellId,
+            "Unable to get the cellCb");
+      RETVALUE(RFAILED);
+   }
+   /*set sndL2Meas as applicatoin sent l2 meas info request*/
+   cellCb->sndL2Meas = TRUE;
+
+   RETVALUE(ret);
+}/*RgSchMacL2MeasSendReq*/ 
+
+/** @brief This function inserts the MeasCb in to data base
+ *
+ * @details
+ *
+ *     Function: rgL2mInsertMeasCb
+ *
+ * @param  [in] RgCellCb       *cell
+ * @param  [in] RgL2MeasCb     *measCb
+ * @param  [in] RgInfMeasReq   *measInfo
+ * @return  S16
+ *      -# ROK 
+ *      -# RFAILED 
+ */
+#ifdef ANSI
+PRIVATE S16 rgL2mInsertMeasCb
+(
+RgCellCb       *cell,
+RgL2MeasCb     *measCb,
+RgInfL2MeasReq *measInfo
+)
+#else
+PRIVATE S16 rgL2mInsertMeasCb(cell, measCb, measInfo)
+RgCellCb       *cell;
+RgL2MeasCb     *measCb;
+RgInfL2MeasReq *measInfo;
+#endif
+{
+   CmLList   *lnk, *node;
+   RgL2MeasCb  *oldMeasCb;
+   U16         diffTime;
+
+   TRC3(rgL2mInsertMeasCb)
+
+      /* 
+       * 1. Check if l2mList has any entries.
+       * 2. If yes 
+       *       1. Take the first entrie's time period and find the diff with
+       *       cell->crntTime.
+       *       2. If the diff is > measInfo->timePeriod then insert before this
+       *       entry.
+       *       3. Else take the next entry in list
+       *       4. If reached without adding to list . Append at the end of list.
+       * 3. If no entries in l2mList add at the first.
+       */
+      lnk = cell->l2mList.first;
+
+   node = &measCb->measLnk;
+   node->node = (PTR)measCb;
+   while(lnk != NULLP )
+   {
+      oldMeasCb = (RgL2MeasCb *)lnk->node;
+      diffTime = (oldMeasCb->measReq.timePrd - 
+            (RG_CALC_SF_DIFF(cell->crntTime, oldMeasCb->startTime)));
+      if (diffTime > measInfo->timePrd)
+      {
+         cell->l2mList.crnt = lnk;
+         cmLListInsCrnt(&(cell->l2mList), node);
+         RETVALUE(ROK);
+      }
+      else
+      {
+         lnk = lnk->next;
+      }
+   }  /* End of While */
+
+   cmLListAdd2Tail(&(cell->l2mList), node);
+   RETVALUE(ROK);
+} /* rgL2mInsertMeasCb */
+
+/** @brief This function allocates memory from the heap
+ *
+ * @details
+ *
+ *     Function: rgL2mAllocMeasCb
+ *
+ * @param  [in] RgCellCb       *cell
+ * @param  [in] RgInfL2MeasReq *measInfo
+ * @param  [out] RgErrInfo      *err
+ * @return  RgSchL2MeasCb *
+ */
+#ifdef ANSI
+PRIVATE RgL2MeasCb * rgL2mAllocMeasCb
+(
+RgCellCb       *cell,
+RgInfL2MeasReq *measInfo,
+RgErrInfo      *err
+)
+#else
+PRIVATE RgL2MeasCb * rgL2mAllocMeasCb(cell, measInfo, err)
+RgCellCb       *cell;
+RgInfL2MeasReq *measInfo;
+RgErrInfo      *err;
+#endif
+{
+   RgL2MeasCb       *measCb = NULLP;
+   Inst             inst = cell->macInst - RG_INST_START;
+
+   TRC3(rgL2mAllocMeasCb)
+
+      if((rgAllocSBuf(inst,(Data **)&(measCb),
+                  sizeof(RgL2MeasCb))) == RFAILED)
+      {
+         RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,
+                   "Allocation of RgL2MeasCb failed");
+         err->errType  = RGERR_L2M_MEASREQ;
+         err->errCause = RGERR_RAM_MEM_EXHAUST;
+         RETVALUE(NULLP);
+      }
+   cmMemcpy((U8 *)&measCb->measReq, (U8 *)measInfo, sizeof(RgInfL2MeasReq));
+   RGCPYTIMEINFO(cell->crntTime, measCb->startTime);
+
+   RETVALUE(measCb);
+} /* rgL2mAllocMeasCb */
+
+
+/**
+ * @brief This function calculates the measurement for measType 
+ * LRG_L2MEAS_AVG_PRB_PER_QCI_UL and send the end result to the 
+ * MAC Scheduler.
+ *
+ * @details
+ *
+ *  Function : rgL2Meas
+ *     
+ *  @param[in] RgCellCb  *cell
+ *  @return  S16
+ *      -# ROK
+ *      -# RFAILED
+ **/
+#ifdef ANSI
+PUBLIC S16 rgL2Meas
+(
+RgCellCb  *cell
+)
+#else
+PUBLIC S16 rgL2Meas(cell)
+RgCellCb  *cell;
+#endif
+{
+   CmLList         *node   = NULLP;
+   RgL2MeasCb      *measCb = NULLP;
+   RgInfL2MeasCfm  measCfm;
+   U8              idx = 0;
+   U8              qciVal = 0;
+   U32             measPrd; /*LTE_L2_MEAS_PHASE2*/
+   CmLteTimingInfo  crntTime;
+   Inst           inst = cell->macInst - RG_INST_START;
+   
+   TRC3(rgL2Meas)
+
+   node = cell->l2mList.first;
+
+   while(node != NULLP)
+   {
+      measCb = (RgL2MeasCb *)node->node;
+      node = node->next;
+      crntTime = cell->crntTime;
+
+      if(cell->crntTime.sfn == 0 && (cell->crntTime.subframe % RG_NUM_SUB_FRAMES) == 0)
+      {
+         measCb->sfnCycle++;
+      }
+
+      measPrd = RG_CALC_SFN_SF_DIFF(cell->crntTime, 
+                        measCb->sfnCycle, measCb->startTime);
+      
+      /*LTE_L2_MEAS_PHASE2*/
+      if (cell->sndL2Meas || measPrd == measCb->measReq.timePrd)
+      {
+         cmMemset((U8 *)&measCfm, 0, sizeof(RgInfL2MeasCfm));
+         for(idx = 0; idx < measCb->measReq.t.prbReq.numQci; idx++)
+         {
+            qciVal = measCb->measReq.t.prbReq.qci[idx];
+            measCfm.u.prbCfm.prbUsage[idx].qciValue = qciVal;
+
+            measCfm.transId  = measCb->measReq.transId;
+            measCfm.measType = measCb->measReq.measType;
+            measCfm.cellId    = measCb->measReq.cellId;
+
+            measCfm.u.prbCfm.prbUsage[idx].prbUsage = 
+               cell->qciArray[qciVal].prbCount;
+
+            cell->qciArray[qciVal].prbCount = 0;
+            measCfm.u.prbCfm.numQci++;
+            if(measCb->measReq.timePrd > 0)
+            {
+               cell->qciArray[qciVal].mask = FALSE;
+            }
+         }
+         rgSndL2MeasCfm(cell, &measCfm);
+
+         if(measCb->measReq.timePrd > 0) 
+         {
+            cmLListDelFrm(&cell->l2mList, &measCb->measLnk);
+            rgFreeSBuf(inst,(Data**)&measCb, sizeof(RgL2MeasCb));
+         }
+         else /*if meas period is 0 then do not delette meascb , just reset l2 cntrs value to 0*/
+         { 
+            measCb->startTime = crntTime;
+            measCb->measReq.timePrd = 0;
+            cell->sndL2Meas = FALSE;
+         }
+         continue;
+      } 
+   }
+   RETVALUE(ROK);
+} /* rgL2MEas */
+
+#endif /* LTE_L2_MEAS */
+/**********************************************************************
+ 
+         End of file
+**********************************************************************/
diff --git a/src/5gnrmac/rg_lim.c b/src/5gnrmac/rg_lim.c
new file mode 100755
index 000000000..2d3188109
--- /dev/null
+++ b/src/5gnrmac/rg_lim.c
@@ -0,0 +1,694 @@
+/*******************************************************************************
+################################################################################
+#   Copyright (c) [2017-2019] [Radisys]                                        #
+#                                                                              #
+#   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.                                             #
+################################################################################
+*******************************************************************************/
+
+/************************************************************************
+ 
+     Name:     LTE-MAC layer
+  
+     Type:     C source file
+  
+     Desc:     C source code for Entry point fucntions
+  
+     File:     rg_lim.c 
+  
+**********************************************************************/
+
+/** @file rg_lim.c.
+@brief It has APIs exposed by Lower Interface Modulue of MAC. It acts as an 
+Interface handler for lower interface APIs.
+*/
+static const char* RLOG_MODULE_NAME="MAC";
+static int RLOG_FILE_ID=182;
+static int RLOG_MODULE_ID=4096;
+/* header include files -- defines (.h) */
+#include "envopt.h"        /* environment options */
+#include "envdep.h"        /* environment dependent */
+#include "envind.h"        /* environment independent */
+#include "gen.h"           /* general layer */
+#include "ssi.h"           /* system services */
+#include "cm5.h"           /* common timers defines */
+#include "cm_hash.h"       /* common hash list defines */
+#include "cm_llist.h"      /* common linked list defines */
+#include "cm_mblk.h"       /* memory management */
+#include "cm_tkns.h"       /* common tokens */
+#include "cm_lte.h"       /* common tokens */
+#include "rgu.h"           /* RGU defines */
+#include "tfu.h"           /* RGU defines */
+#include "lrg.h"           /* layer management defines for LTE-MAC */
+#include "crg.h"           /* layer management defines for LTE-MAC */
+#include "rg_sch_inf.h"           /* layer management defines for LTE-MAC */
+#include "rg_env.h"        /* customisable defines and macros for MAC */
+#include "rg.h"            /* defines and macros for MAC */
+
+
+/* header/extern include files (.x) */
+#include "gen.x"           /* general layer typedefs */
+#include "ssi.x"           /* system services typedefs */
+#include "cm5.x"           /* common timers */
+#include "cm_hash.x"       /* common hash list */
+#include "cm_lib.x"        /* common library */
+#include "cm_llist.x"      /* common linked list */
+#include "cm_mblk.x"       /* memory management */
+#include "cm_tkns.x"       /* common tokens */
+#include "cm_lte.x"       /* common tokens */
+#include "rgu.x"           /* RGU types */
+#include "tfu.x"           /* RGU types */
+#include "lrg.x"           /* layer management typedefs for MAC */
+#include "crg.x"           /* layer management typedefs for MAC */
+#include "rg_sch_inf.x"    /* SCH interface typedefs */
+#include "rg_prg.x"    /* PRG interface typedefs */
+#include "rg.x"            /* typedefs for MAC */
+
+/* local defines */
+
+/* local typedefs */
+ 
+/* local externs */
+PRIVATE S16  rgLIMValidateSap ARGS((Inst inst,SuId suId));
+PRIVATE Void rgLIMUtlFreeDatIndEvnt ARGS((TfuDatIndInfo *datInd,
+                                          Bool error));
+#ifdef RG_UNUSED
+PRIVATE Void rgLIMUtlFreeDatReqEvnt ARGS((TfuDatReqInfo *datReq,
+                                          Bool error));
+#endif
+/* forward references */
+
+/**
+ * @brief This API is invoked to send TFU SAP bind request to PHY.
+ *
+ * @details
+ *
+ *     Function : rgLIMTfuBndReq
+ *      
+ *      This API is invoked to send TFU SAP bind request to PHY. It fills in 
+ *      the Pst structure, spId and suId values and invokes bind request
+ *      primitive at TFU.
+ *           
+ *  @param[in]  Inst        inst
+ *  @param[in]  SuId            suId 
+ *  @param[in]  SpId            spId
+ *  @return  S16
+ *      -# ROK 
+ *      -# RFAILED 
+ **/
+#ifdef ANSI
+PUBLIC S16 rgLIMTfuBndReq
+(
+Inst    inst,
+SuId    suId, 
+SpId    spId
+)
+#else
+PUBLIC S16 rgLIMTfuBndReq(inst,suId, spId)
+Inst    inst;
+SuId    suId; 
+SpId    spId;
+#endif
+{
+   S16         ret;
+   RgLowSapCb  *tfuSap;
+   Pst         pst;
+
+   TRC2(rgLIMTfuBndReq);
+
+   /* Get the lower SAP control block from the layer control block. */
+   tfuSap = &(rgCb[inst].tfuSap);
+   (Void)cmMemcpy ((U8*)&pst, (U8*)&(tfuSap->sapCfg.sapPst), sizeof(Pst));
+   if((ret = RgLiTfuBndReq (&pst, suId, spId)) != ROK)
+   {
+      RLOG0(L_ERROR,"Call to RgLiTfuBndReq() failed");
+   }
+   RETVALUE(ret);
+}  /* rgLIMTfuBndReq */
+
+
+/**
+ * @brief This API is invoked to send TFU SAP unbind request to PHY.
+ *
+ * @details
+ *
+ *     Function : rgLIMTfuBndReq
+ *      
+ *      This API is invoked to send TFU SAP unbind request to PHY. It fills in 
+ *      the Pst structure and spId value and invokes unbind request
+ *      primitive at TFU.
+ *           
+ *  @param[in]  Inst        inst
+ *  @param[in]  SpId            spId
+ *  @param[in]  Reason          reason 
+ *  @return  S16
+ *      -# ROK 
+ *      -# RFAILED 
+ **/
+#ifdef ANSI
+PUBLIC S16 rgLIMTfuUbndReq
+(
+Inst    inst,
+SpId    spId, 
+Reason  reason
+)
+#else
+PUBLIC S16 rgLIMTfuUbndReq(inst,spId, reason)
+Inst    inst;
+SpId    spId; 
+Reason  reason;
+#endif
+{
+   S16         ret;
+   RgLowSapCb  *tfuSap;
+   Pst         pst;
+
+   TRC2(rgLIMTfuUbndReq);
+
+   /* Get the lower SAP control block from the layer control block. */
+   tfuSap = &(rgCb[inst].tfuSap);
+   cmMemcpy ((U8*)&pst, (U8*)&(tfuSap->sapCfg.sapPst), sizeof(Pst));
+   if((ret = RgLiTfuUbndReq (&pst, tfuSap->sapCfg.spId, reason)) != ROK)
+   {
+      RLOG0(L_ERROR,"Call to RgLiTfuUbndReq() failed");
+   }
+   RETVALUE(ret);
+
+}  /* rgLIMTfuUbndReq */
+
+
+/**
+ * @brief Bind confirm API for TFU SAP 
+ *
+ * @details
+ *
+ *     Function : RgLiTfuBndCfm
+ *      
+ *      This API is invoked by PHY to confirm TFU SAP bind. 
+ *     
+ *           
+ *  @param[in]  Pst   *pst 
+ *  @param[in]  SuId  suId 
+ *  @param[in]  U8    status
+ *  @return  S16
+ *      -# ROK 
+ *      -# RFAILED 
+ **/
+#ifdef ANSI
+PUBLIC S16 RgLiTfuBndCfm 
+(
+Pst     *pst,
+SuId    suId, 
+U8      status
+)
+#else
+PUBLIC S16 RgLiTfuBndCfm(pst, suId, status)
+Pst     *pst; 
+SuId    suId; 
+U8      status;
+#endif
+{
+   Inst inst;
+   S16 ret;
+   RgLowSapCb  *tfuSap;
+
+   TRC3(RgLiTfuBndCfm);
+
+
+   RG_IS_INST_VALID(pst->dstInst);
+   inst = pst->dstInst - RG_INST_START;
+   /* Lets validate suId first */
+   /* CA_Change */
+   tfuSap = &(rgCb[inst].tfuSap);
+
+   if (suId != tfuSap->sapCfg.suId)
+   {
+      RLOG2(L_ERROR,"Incorrect SuId. Configured (%d) Recieved (%d)",
+            tfuSap->sapCfg.suId, suId);
+      RETVALUE(RFAILED);
+   }
+   ret = rgLMMBndCfm (pst, suId, status);
+   RETVALUE(ret);
+}  /* RgLiTfuBndCfm */
+
+ /** @brief This function Validates the SAP information received along with the
+  * primitive from the lower layer. 
+  * Function:
+  *   Validates SAP information.
+ *  @param[in]  Inst        inst
+  * @param  suId The SAP Id
+  * @return 
+  *   -# ROK
+  *   -# RFAILED
+  */
+#ifdef ANSI
+PRIVATE S16 rgLIMValidateSap
+(
+ Inst    inst,
+ SuId    suId
+)
+#else
+PRIVATE S16 rgLIMValidateSap(inst,suId)
+ Inst    inst;
+ SuId    suId;
+#endif
+{
+   RgLowSapCb  *tfuSap;
+
+   TRC2(rgLIMValidateSap)
+
+   tfuSap = &(rgCb[inst].tfuSap);
+
+   /* First lets check the suId */
+   if( suId != tfuSap->sapCfg.suId)
+   {
+      RLOG2(L_ERROR,"Incorrect SuId. Configured (%d) Recieved (%d)",
+            tfuSap->sapCfg.suId, suId);
+      RETVALUE(RFAILED);
+   }
+   if (tfuSap->sapSta.sapState != LRG_BND)
+   {
+      RLOG1(L_ERROR,"Lower SAP not enabled SuId (%d)",
+            tfuSap->sapCfg.suId);
+      RETVALUE(RFAILED);
+   }
+   RETVALUE(ROK);
+} /* end of rgLIMValidateSap */
+
+/** @brief This function frees up the TfuDatIndInfo structure
+ *
+ * @details
+ *
+ *     Function: rgLIMUtlFreeDatIndEvnt 
+ *       - Function frees up the TfuDatIndInfo structure, in case of error it shall
+ *       free up the buffer's present in the datIndLst.
+ *
+ *         Processing steps:
+ * @param  [in] TfuDatIndInfo *datInd
+ * @param  [in] Bool          *error
+ * @return 
+ */
+#ifdef ANSI
+PRIVATE Void rgLIMUtlFreeDatIndEvnt 
+(
+ TfuDatIndInfo *datInd,
+ Bool          error
+ )
+#else
+PRIVATE Void rgLIMUtlFreeDatIndEvnt(datInd, error)
+ TfuDatIndInfo *datInd;
+ Bool          error;
+#endif
+{
+
+   TfuDatInfo     *datInfo;
+   CmLList        *node;
+
+   TRC2(rgLIMUtlFreeDatIndEvnt);
+   /* Steps of freeing up the TfuDatInd.
+    * 1. loop through the datIndLst and free up all the buffers.
+    * 2. free up the whole event
+    */
+   if ((error == TRUE) && (datInd->datIndLst.count > 0))
+   {
+      node =  datInd->datIndLst.first;
+      while (node)
+      {
+         datInfo = (TfuDatInfo*)node->node;
+         RG_FREE_MSG(datInfo->mBuf);
+         node = node->next;
+      }
+   }
+   RG_FREE_MEM(datInd);
+   RETVOID;
+} /* end of rgLIMUtlFreeDatIndEvnt*/
+
+/**
+ * @brief Downlink data indication from PHY.
+ *
+ * @details
+ *
+ *     Function : RgLiTfuDatInd
+ *      
+ *      This API is invoked by PHY to send data indication to MAC on 
+ *      recieving data from UEs.
+ *           
+ *  @param[in]  Pst              *pst
+ *  @param[in]  SuId             suId 
+ *  @param[in]  TfuDatIndInfo    *datInd
+ *  @return  S16
+ *      -# ROK 
+ *      -# RFAILED 
+ **/
+#ifdef ANSI
+PUBLIC S16 RgLiTfuDatInd
+(
+Pst                *pst, 
+SuId               suId, 
+TfuDatIndInfo    *datInd
+)
+#else
+PUBLIC S16 RgLiTfuDatInd(pst, suId, datInd)
+Pst                *pst; 
+SuId               suId; 
+TfuDatIndInfo    *datInd;
+#endif
+{
+   Inst             inst;
+   S16              ret;
+   VOLATILE U32     startTime=0;
+
+   TRC3(RgLiTfuDatInd);
+
+  // printf("5GTF:: DatindRcvd\n");
+
+   RG_IS_INST_VALID(pst->dstInst);
+   inst = pst->dstInst - RG_INST_START;
+   /*starting Task*/
+   SStartTask(&startTime, PID_MAC_TFU_DATIND);
+
+#ifndef NO_ERRCLS 
+   if ((ret = rgLIMValidateSap (inst,suId)) != ROK)
+   {
+      RLOG_ARG0(L_ERROR,DBG_CELLID,datInd->cellId,"SAP Validation failed");
+      rgLIMUtlFreeDatIndEvnt(datInd, TRUE);
+      RETVALUE(ret);
+   }
+#endif
+   /* Now call the TOM (Tfu ownership module) primitive to process further */
+   rgCb[inst].tfuSap.sapSts.numPduRcvd += 
+                    datInd->datIndLst.count;
+   ret = rgTOMDatInd(inst,datInd);
+   /* Fix: sriky memory corruption precautions */
+   /* Free up the memory for the request structure */
+   if (ret == ROK)
+   {
+      rgLIMUtlFreeDatIndEvnt(datInd, FALSE);
+   }
+   else
+   {
+      rgLIMUtlFreeDatIndEvnt(datInd, TRUE);
+   }
+
+   /*stoping Task*/
+   SStopTask(startTime, PID_MAC_TFU_DATIND);
+
+   RETVALUE(ret);
+}  /* RgLiTfuDatInd*/
+
+#ifdef RG_UNUSED
+/** @brief This function frees up the TfuDatReqInfo structure.
+ *
+ * @details
+ *
+ *     Function: rgLIMUtlFreeDatReqEvnt
+ *       - Function frees up the TfuDatReqInfo structure, in case of error it shall
+ *       free up the buffer's present in the PDUs list.
+ *
+ *         Processing steps:
+ * @param  [in] TfuDatReqInfo *datReq
+ * @param  [in] Bool          *error
+ * @return 
+ */
+#ifdef ANSI
+PRIVATE Void rgLIMUtlFreeDatReqEvnt
+(
+ TfuDatReqInfo *datReq,
+ Bool          error
+ )
+#else
+PRIVATE Void rgLIMUtlFreeDatReqEvnt(datReq, error)
+ TfuDatReqInfo *datReq;
+ Bool          error;
+#endif
+{
+
+   TfuDatReqPduInfo *datInfo;
+   CmLList          *node;
+   U8               i;
+
+   TRC2(rgLIMUtlFreeDatReqEvnt);
+   /* Steps of freeing up the TfuDatReq.
+    * 1. Free the bch buffer.
+    * 2. loop through the pdus list and free up all the buffers.
+    * 3. free up the whole event
+    */
+   if (error)
+   {
+      if (datReq->bchDat.pres == PRSNT_NODEF)
+      {
+         RG_FREE_MSG(datReq->bchDat.val);
+      }
+      if (datReq->pdus.count > 0)
+      {
+         node =  datReq->pdus.first;
+         while (node)
+         {
+            datInfo = (TfuDatReqPduInfo*)node->node;
+            for (i=0; inmbOfTBs; i++)
+            {
+               if (datInfo->mBuf[i] != NULLP)
+               {
+                  RG_FREE_MSG(datInfo->mBuf[i]);
+               }
+            }
+            node = node->next;
+         }
+      }
+   }
+   RG_FREE_MEM(datReq);
+   RETVOID;
+} /* end of rgLIMUtlFreeDatReqEvnt*/
+#endif
+/**
+ * @brief This API is invoked to send Data to PHY.
+ *
+ * @details
+ *
+ *     Function : rgLIMTfuDatReq
+ *      
+ *      This API is invoked to send Data to PHY. It 
+ *      fills in the Pst structure, spId value and invokes Data
+ *      request primitive at TFU.
+ *           
+ *  @param[in]  Inst        inst
+ *  @param[in]  TfuDatReqInfo *datReq
+ *  @return  S16
+ *      -# ROK 
+ *      -# RFAILED 
+ **/
+#ifdef ANSI
+PUBLIC S16 rgLIMTfuDatReq 
+(
+Inst          inst,
+TfuDatReqInfo *datReq
+)
+#else
+PUBLIC S16 rgLIMTfuDatReq(inst,datReq)
+Inst          inst;
+TfuDatReqInfo *datReq;
+#endif
+{
+   S16         ret;
+   RgLowSapCb  *tfuSap;
+
+   TRC2(rgLIMTfuDatReq)
+
+   /* Get the lower SAP control block from the layer control block. */
+   tfuSap = &(rgCb[inst].tfuSap);
+
+#ifndef NO_ERRCLS
+   if (tfuSap->sapSta.sapState != LRG_BND)
+   {
+      RLOG_ARG1(L_ERROR,DBG_CELLID,datReq->cellId,"Lower SAP not bound (%d)",
+            tfuSap->sapSta.sapState);
+#ifdef RG_UNUSED
+      /* This case will never be hit if sap is not bound then we dont get TTI */
+      rgLIMUtlFreeDatReqEvnt(datReq, TRUE);
+#endif
+      RETVALUE(RFAILED);
+   }
+#endif
+
+   tfuSap->sapSts.numPduTxmit += datReq->pdus.count; 
+
+   /* Using existing pst - for optimization */
+   if((ret = RgLiTfuDatReq (&tfuSap->sapCfg.sapPst, tfuSap->sapCfg.spId, 
+                            datReq)) != ROK)
+   {
+      RLOG_ARG0(L_ERROR,DBG_CELLID,datReq->cellId,"Call to RgLiTfuDatReq() failed");
+   }
+   RETVALUE(ret);
+}  /* rgLIMTfuDatReq*/
+
+#ifdef L2_OPTMZ
+/**
+ * @brief This API is invoked to send Data to PHY.
+ *
+ * @details
+ *
+ *     Function : rgLIMTfuDelDatReq
+ *      
+ *      This API is invoked to send Data to PHY. It 
+ *      fills in the Pst structure, spId value and invokes Data
+ *      request primitive at TFU.
+ *           
+ *  @param[in]  Inst        inst
+ *  @param[in]  TfuDelDatReqInfo *datReq
+ *  @return  S16
+ *      -# ROK 
+ *      -# RFAILED 
+ **/
+#ifdef ANSI
+PUBLIC S16 rgLIMTfuDelDatReq 
+(
+Inst          inst,
+TfuDelDatReqInfo *delDatReq
+)
+#else
+PUBLIC S16 rgLIMTfuDatReq(inst,delDatReq)
+Inst          inst;
+TfuDelDatReqInfo *delDatReq;
+#endif
+{
+   S16         ret;
+   RgLowSapCb  *tfuSap;
+
+   TRC2(rgLIMTfuDelDatReq)
+
+   /* Get the lower SAP control block from the layer control block. */
+   tfuSap = &(rgCb[inst].tfuSap);
+
+#ifndef NO_ERRCLS
+   if (tfuSap->sapSta.sapState != LRG_BND)
+   {
+      RLOG_ARG1(L_ERROR,DBG_CELLID,delDatReq->cellId,"Lower SAP not bound (%d)",
+            tfuSap->sapSta.sapState);
+      RETVALUE(RFAILED);
+   }
+#endif
+
+   if((ret = RgLiTfuDelDatReq (&tfuSap->sapCfg.sapPst, tfuSap->sapCfg.spId, 
+                            delDatReq)) != ROK)
+   {
+      RLOG_ARG0(L_ERROR,DBG_CELLID,delDatReq->cellId,"Call to RgLiTfuDelDatReq() failed");
+   }
+   RETVALUE(ret);
+}  /* rgLIMTfuDatReq*/
+#endif /*L2_OPTMZ */
+
+/**
+ * @brief Transmission time interval indication from PHY.
+ *
+ * @details
+ *
+ *     Function : RgLiTfuTtiInd 
+ *      
+ *      This API is invoked by PHY to indicate TTI indication to MAC for a cell.
+ *           
+ *  @param[in]  Pst            *pst
+ *  @param[in]  SuId           suId 
+ *  @param[in]  TfuTtiIndInfo  *ttiInd
+ *  @return  S16
+ *      -# ROK 
+ *      -# RFAILED 
+ **/
+#ifdef ANSI
+PUBLIC S16 RgLiTfuTtiInd 
+(
+Pst                 *pst, 
+SuId                suId, 
+TfuTtiIndInfo       *ttiInd
+)
+#else
+PUBLIC S16 RgLiTfuTtiInd(pst, suId, ttiInd)
+Pst                 *pst; 
+SuId                suId; 
+TfuTtiIndInfo       *ttiInd;
+#endif
+{
+   S16              ret;
+   VOLATILE U32     startTime=0;
+   Inst             inst;
+
+   TRC3(RgLiTfuTtiInd);
+
+   RG_IS_INST_VALID(pst->dstInst);
+   inst = pst->dstInst - RG_INST_START;
+   /*starting Task*/
+   SStartTask(&startTime, PID_MAC_TTI_IND);
+
+#ifdef NO_ERRCLS
+   if ((ret = rgLIMValidateSap (pst->dstInst - RG_INST_START,suId)) != ROK)
+   {
+      RLOG_ARG0(L_ERROR,DBG_CELLID,ttiInd->cells[0].cellId,"SAP Validation failed");
+      RETVALUE(ret);
+   }
+#endif
+
+   /* Now call the TOM (Tfu ownership module) primitive to process further */
+   ret = rgTOMTtiInd(inst,ttiInd);
+
+
+   /*stoping Task*/
+   SStopTask(startTime, PID_MAC_TTI_IND);
+
+   RETVALUE(ret);
+}  /* RgLiTfuTtiInd */
+
+#if defined(TENB_T2K3K_SPECIFIC_CHANGES) && defined(LTE_TDD)
+ /**
+ * @brief Transmission of non-rt indication from CL.
+ *
+ * @details
+ *
+ *     Function : RgLiTfuNonRtInd 
+ *      
+ *      This API is invoked by CL to indicate non-rt processing indication to MAC for a cell.
+ *           
+ *  @param[in]  Pst            *pst
+ *  @param[in]  SuId           suId 
+ *  @return  S16
+ *      -# ROK 
+ *      -# RFAILED 
+ **/
+#ifdef ANSI
+PUBLIC S16 RgLiTfuNonRtInd
+(
+Pst                 *pst,
+SuId                suId
+)
+#else
+PUBLIC S16 RgLiTfuNonRtInd(pst, suId)
+Pst                 *pst;
+SuId                suId;
+#endif
+{
+   TRC3(RgLiTfuNonRtInd);
+
+#ifdef NO_ERRCLS
+   if (rgLIMValidateSap (pst->dstInst - RG_INST_START, suId) != ROK)
+   {
+      RGDBGERRNEW(pst->dstInst - RG_INST_START, (rgPBuf(pst->dstInst - RG_INST_START),"RgLiTfuNonRtInd() SAP Validation failed.\n"));
+      RETVALUE(RFAILED);
+   }
+#endif
+   rgDHMFreeTbBufs(pst->dstInst - RG_INST_START);
+   RETVALUE(ROK);
+}  /* RgLiTfuNonRtInd */
+
+#endif
+/**********************************************************************
+ 
+         End of file
+**********************************************************************/
diff --git a/src/5gnrmac/rg_lmm.c b/src/5gnrmac/rg_lmm.c
new file mode 100755
index 000000000..e3dd82ed0
--- /dev/null
+++ b/src/5gnrmac/rg_lmm.c
@@ -0,0 +1,1926 @@
+/*******************************************************************************
+################################################################################
+#   Copyright (c) [2017-2019] [Radisys]                                        #
+#                                                                              #
+#   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.                                             #
+################################################################################
+*******************************************************************************/
+
+/************************************************************************
+ 
+     Name:     LTE-MAC layer
+  
+     Type:     C source file
+  
+     Desc:     C source code for Layer Manager Interface Module 
+  
+     File:     rg_lmm.c 
+  
+**********************************************************************/
+
+/** @file rg_lmm.c
+@brief This file contains the Layer Management interface module implementation.
+       The functions for the configuration, control, status and statistics 
+       request primitives are defined here.
+*/
+static const char* RLOG_MODULE_NAME="MAC";
+static int RLOG_FILE_ID=220;
+static int RLOG_MODULE_ID=4096;
+
+/* header include files (.h) */
+#include "envopt.h"        /* environment options */
+#include "envdep.h"        /* environment dependent */
+#include "envind.h"        /* environment independent */
+#include "gen.h"           /* general */
+#include "ssi.h"           /* system services */
+#include "cm_tkns.h"       /* Common Token Defines */
+#include "cm_llist.h"      /* Common Link List Defines */
+#include "cm_hash.h"       /* Common Hash List Defines */
+#include "cm_mblk.h"       /* common memory link list library */
+#include "cm_lte.h"        /* Common LTE Defines */
+#include "rg_env.h"        /* MAC Environment Defines */
+#include "crg.h"           /* CRG Interface defines */
+#include "rgu.h"           /* RGU Interface defines */
+#include "tfu.h"           /* RGU Interface defines */
+#include "rg_sch_inf.h"           /* RGR Interface defines */
+#include "lrg.h"           /* LRG Interface defines */
+#include "rg.h"            /* MAC defines */
+#include "rg_err.h"        /* MAC error defines */
+
+/* header/extern include files (.x) */
+#include "gen.x"           /* general */
+#include "ssi.x"           /* system services */
+#include "cm5.x"           /* system services */
+#include "cm_tkns.x"       /* Common Token Definitions */
+#include "cm_llist.x"      /* Common Link List Definitions */
+#include "cm_lib.x"        /* Common Library Definitions */
+#include "cm_hash.x"       /* Common Hash List Definitions */
+#include "cm_mblk.x"       /* common memory link list library */
+#include "cm_lte.x"        /* Common LTE Defines */
+#include "crg.x"           /* CRG Interface includes */
+#include "rgu.x"           /* RGU Interface includes */
+#include "tfu.x"           /* RGU Interface includes */
+#include "rg_sch_inf.x"    /* SCH Interface includes */
+#include "rg_prg.x"    /* PRG Interface includes */
+#include "lrg.x"           /* LRG Interface includes */
+#include "rg.x"            /* MAC includes */
+#ifdef SS_DIAG
+#include "ss_diag.h"        /* Common log file */
+#endif
+#include "ss_rbuf.h"
+#include "ss_rbuf.x"
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+EXTERN Void rgGetSId ARGS((SystemId *s));
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+/* forward references */
+PRIVATE U16 rgLMMGenCfg ARGS((
+   Inst           inst,
+   RgCfg          *cfg           
+));
+
+PRIVATE U16 rgLMMSapCfg ARGS((
+   Inst           inst,
+   RgCfg          *cfg,
+   Elmnt          sapType
+));
+
+PRIVATE Void rgLMMShutdown ARGS((
+   Inst           inst
+));
+
+PRIVATE Void rgLMMFillCfmPst ARGS((
+   Pst           *reqPst,
+   Pst           *cfmPst,
+   RgMngmt       *cfm
+));
+
+PRIVATE Void rgLMMGenCntrl ARGS((
+RgMngmt       *cntrl,
+RgMngmt       *cfm,
+Pst           *cfmPst
+));
+
+PRIVATE Void rgLMMSapCntrl ARGS((
+RgMngmt       *cntrl,
+RgMngmt       *cfm,
+Pst           *cfmPst
+));
+
+
+/**
+ * @brief Task Initiation callback function. 
+ *
+ * @details
+ *
+ *     Function : rgActvInit
+ *     
+ *     This function is supplied as one of parameters during MAC's 
+ *     task registration. SSI will invoke this function once, after
+ *     it creates and attaches this TAPA Task to a system task.
+ *     
+ *  @param[in]  Ent entity, the entity ID of this task.     
+ *  @param[in]  Inst inst, the instance ID of this task.
+ *  @param[in]  Region region, the region ID registered for memory 
+ *              usage of this task.
+ *  @param[in]  Reason reason.
+ *  @return  S16
+ *      -# ROK
+ **/
+#ifdef ANSI
+PUBLIC S16 rgActvInit
+(
+Ent entity,            /* entity */
+Inst inst,             /* instance */
+Region region,         /* region */
+Reason reason          /* reason */
+)
+#else
+PUBLIC S16 rgActvInit(entity, inst, region, reason)
+Ent entity;            /* entity */
+Inst inst;             /* instance */
+Region region;         /* region */
+Reason reason;         /* reason */
+#endif
+{
+   Inst macInst ;
+   TRC2(rgActvInit);
+
+   RG_IS_INST_VALID(inst);
+
+   macInst = inst - RG_INST_START;
+   /* Initialize the MAC TskInit structure to zero */
+   cmMemset ((U8 *)&rgCb[macInst], 0, sizeof(RgCb));
+
+   /* Initialize the MAC TskInit with received values */
+   rgCb[macInst].rgInit.ent = entity;
+   rgCb[macInst].rgInit.inst = inst;
+   rgCb[macInst].rgInit.region = region;
+   rgCb[macInst].rgInit.pool = 0;
+   rgCb[macInst].rgInit.reason = reason;
+   rgCb[macInst].rgInit.cfgDone = FALSE;
+   rgCb[macInst].rgInit.acnt = FALSE;
+   rgCb[macInst].rgInit.usta = FALSE;
+   rgCb[macInst].rgInit.trc = FALSE;
+   rgCb[macInst].trcLen = 0; 
+#ifdef DEBUGP
+#ifdef RG_DEBUG
+   /* disabling debugs by default */
+    rgCb[macInst].rgInit.dbgMask = 0xffffffff; 
+#endif
+#endif /* DEBUGP */
+#ifdef SS_DIAG
+   rgCb[macInst].rgInit.logMask = 0x0;
+#endif
+   rgCb[macInst].rgInit.procId = SFndProcId();
+   rgCb[macInst].tfuSap.numBndRetries = 0;
+
+   /* Initialize Sap state */
+   rgCb[macInst].tfuSap.sapSta.sapState = LRG_NOT_CFG;
+   rgCb[macInst].crgSap.sapSta.sapState = LRG_NOT_CFG;
+   rgCb[macInst].rguSap = NULLP;
+   rgCb[macInst].crgSap.sapSta.sapState = LRG_NOT_CFG;
+
+   rgCb[macInst].inactiveCell = NULLP;
+   rgCb[macInst].cell         = NULLP;
+#ifdef SS_RBUF
+   SAttachSRngBuf(SS_RNG_BUF_ULMAC_TO_ULRLC, SS_RBUF_ENT_ULMAC,SS_RNG_TX);
+   SAttachSRngBuf(SS_RNG_BUF_ULMAC_TO_ULRLC, SS_RBUF_ENT_ULRLC,SS_RNG_RX);
+#endif
+   RETVALUE(ROK);
+
+} /* rgActvInit */
+
+/**
+ * @brief Layer Manager Configuration request handler. 
+ *
+ * @details
+ *
+ *     Function : RgMiLrgCfgReq
+ *     
+ *     This function handles the configuration
+ *     request received from the Layer Manager.
+ *     -# Based on the cfg->hdr.elmId.elmnt value it invokes one of the
+ *        functions rgHdlGenCfg() or rgHdlSapCfg().
+ *     -# Invokes RgMiLrgCfgCfm() to send back the confirmation to the LM.
+ *     
+ *  @param[in]  Pst *pst, the post structure     
+ *  @param[in]  RgMngmt *cfg, the configuration parameter's structure
+ *  @return  S16
+ *      -# ROK
+ **/
+#ifdef ANSI
+PUBLIC S16 RgMiLrgCfgReq
+(
+Pst      *pst,    /* post structure  */
+RgMngmt  *cfg     /* config structure  */
+)
+#else
+PUBLIC S16 RgMiLrgCfgReq(pst, cfg)
+Pst      *pst;    /* post structure  */
+RgMngmt  *cfg;    /* config structure  */
+#endif    
+{
+   U16       ret = LCM_PRIM_OK;
+   U16       reason = LCM_REASON_NOT_APPL;
+   RgMngmt   cfm;
+   Pst       cfmPst;
+   Inst      inst;
+
+   TRC2(RgMiLrgCfgReq)
+   
+
+   RG_DIAG_LVL0(inst,0x0a0b0001, RG_DIAG_NA, SS_DIAG_INV_ARG,
+              "Received CfgReq for MAC layer, Entity = %d, Instance = %d\n",
+              pst->srcEnt, pst->srcInst,0,0);
+
+   RG_IS_INST_VALID(pst->dstInst);
+   inst = pst->dstInst - RG_INST_START;
+
+   /* Fill the post structure for sending the confirmation */
+   rgLMMFillCfmPst(pst, &cfmPst, cfg);
+
+   cmMemset((U8 *)&cfm, 0, sizeof(RgMngmt));
+
+#ifdef LMINT3
+   cfm.hdr.transId = cfg->hdr.transId;
+#endif
+
+
+   cfm.hdr.elmId.elmnt = cfg->hdr.elmId.elmnt;
+   switch(cfg->hdr.elmId.elmnt)
+   {
+      case STGEN:
+         reason = rgLMMGenCfg(inst,&cfg->t.cfg); 
+         break;
+      case STRGUSAP:
+      case STCRGSAP:
+      case STTFUSAP:
+         reason = rgLMMSapCfg(inst,&cfg->t.cfg, cfg->hdr.elmId.elmnt);
+         break;
+      default:
+         ret = LCM_PRIM_NOK;
+         reason = LCM_REASON_INVALID_ELMNT;
+         RLOG1(L_ERROR, "Invalid Elmnt=%d",
+                  cfg->hdr.elmId.elmnt);
+         break;
+   }
+
+   if (reason != LCM_REASON_NOT_APPL)
+   {
+      ret = LCM_PRIM_NOK;
+   }
+
+   cfm.cfm.status = ret;
+   cfm.cfm.reason = reason;
+
+   RgMiLrgCfgCfm(&cfmPst, &cfm);
+   
+   RETVALUE(ROK);
+}/*-- RgMiLrgCfgReq --*/
+
+
+/**
+ * @brief Layer Manager Statistics request handler. 
+ *
+ * @details
+ *
+ *     Function : RgMiLrgStsReq
+ *     
+ *     This function handles the statistics
+ *     request received from the Layer Manager.
+ *      -# Based on sts->hdr.elmId.elmnt, it retrieves either general or SAP
+ *      statistics from the rgCb global control block.
+ *      -# If action=ARST, it will reset the statistics parameters in rgCb to 0.
+ *      -# Invokes the RgMiLrgStsCfm to send back the confirmation to LM.
+ *     
+ *  @param[in]  Pst *pst, the post structure     
+ *  @param[in]  RgMngmt *sts, the statistics parameter's structure
+ *  @return  S16
+ *      -# ROK
+ **/
+#ifdef ANSI
+PUBLIC S16 RgMiLrgStsReq
+(
+Pst      *pst,    /* post structure  */
+RgMngmt  *sts     /* statistics structure  */
+)
+#else
+PUBLIC S16 RgMiLrgStsReq(pst, sts)
+Pst      *pst;    /* post structure  */
+RgMngmt  *sts;    /* statistics structure  */
+#endif    
+{
+   Pst       cfmPst;
+   RgMngmt   cfm;
+   Inst      inst;
+
+   TRC2(RgMiLrgStsReq)
+   
+
+   RG_IS_INST_VALID(pst->dstInst);
+   inst = pst->dstInst - RG_INST_START;
+   /* Fill the post structure for sending the confirmation */
+   rgLMMFillCfmPst(pst, &cfmPst, sts);
+
+   cmMemset((U8 *)&cfm, 0, sizeof(RgMngmt));
+
+#ifdef LMINT3
+   cfm.hdr.transId = sts->hdr.transId;
+#endif
+   SGetDateTime(&cfm.t.sts.dt);
+   cfm.cfm.status = LCM_PRIM_OK;
+   cfm.cfm.reason = LCM_REASON_NOT_APPL;
+   cfm.hdr.elmId.elmnt = sts->hdr.elmId.elmnt;
+   cfm.t.sts.action = sts->t.sts.action;
+
+   /* Check if General Config Done */
+   if(rgCb[inst].rgInit.cfgDone != TRUE) 
+   {
+      cfm.cfm.status = LCM_PRIM_NOK;
+      cfm.cfm.reason = LCM_REASON_GENCFG_NOT_DONE;
+      RgMiLrgStsCfm(&cfmPst,&cfm);
+      RLOG0(L_ERROR, "Gen Cfg not done");
+      RETVALUE(ROK);
+   }
+
+   switch(sts->hdr.elmId.elmnt)
+   {
+      case STGEN:
+         {
+            cmMemcpy((U8 *)&(cfm.t.sts.s.genSts), (U8 *)&rgCb[inst].genSts,
+                  sizeof(RgGenSts));
+            /* check if action is read and reset */
+            if(sts->t.sts.action == ARST)
+            {
+               rgCb[inst].genSts.numHarqFail = 0;
+            }
+            /* L2 statistics */
+#ifdef MAC_SCH_STATS
+            {
+               RgGenSts *genSts = &(cfm.t.sts.s.genSts);
+               U8       cqi = 0;
+               for(cqi=0; cqi <= 14; cqi++)
+               {
+                  /* Filling DL ACK/NACK stats */
+                  genSts->nackAckStats.dlCqiStat[cqi].mcs = \
+                     hqFailStats.dlCqiStat[cqi].mcs;
+                  genSts->nackAckStats.dlCqiStat[cqi].numOfNacks = \
+                     hqFailStats.dlCqiStat[cqi].numOfNacks;
+                  genSts->nackAckStats.dlCqiStat[cqi].numOfAcks = 
+                     hqFailStats.dlCqiStat[cqi].numOfAcks;
+
+                  /* Filling UL ACK/NACK stats */
+                  genSts->nackAckStats.ulCqiStat[cqi].mcs = \
+                     hqFailStats.ulCqiStat[cqi].mcs;
+                  genSts->nackAckStats.ulCqiStat[cqi].numOfNacks = \
+                     hqFailStats.ulCqiStat[cqi].numOfNacks;
+                  genSts->nackAckStats.ulCqiStat[cqi].numOfAcks = \
+                     hqFailStats.ulCqiStat[cqi].numOfAcks;
+
+                  /* Filling DL HQ Retx stats */
+                  genSts->hqRetxStats.dlCqiStat[cqi].mcs = \
+                     hqRetxStats.dlCqiStat[cqi].mcs;
+                  genSts->hqRetxStats.dlCqiStat[cqi].numOfHQ_1 = \
+                     hqRetxStats.dlCqiStat[cqi].numOfHQ_1;
+                  genSts->hqRetxStats.dlCqiStat[cqi].numOfHQ_2 = \
+                     hqRetxStats.dlCqiStat[cqi].numOfHQ_2;
+                  genSts->hqRetxStats.dlCqiStat[cqi].numOfHQ_3 = \
+                     hqRetxStats.dlCqiStat[cqi].numOfHQ_3;
+                  genSts->hqRetxStats.dlCqiStat[cqi].numOfHQ_4 = \
+                     hqRetxStats.dlCqiStat[cqi].numOfHQ_4;
+                  genSts->hqRetxStats.dlCqiStat[cqi].totalTx = \
+                     hqRetxStats.dlCqiStat[cqi].totalTx;
+
+                  /* Filling UL HQ Retx stats */
+                  genSts->hqRetxStats.ulCqiStat[cqi].mcs = \
+                     hqRetxStats.ulCqiStat[cqi].mcs;
+                  genSts->hqRetxStats.ulCqiStat[cqi].numOfHQ_1 = \
+                     hqRetxStats.ulCqiStat[cqi].numOfHQ_1;
+                  genSts->hqRetxStats.ulCqiStat[cqi].numOfHQ_2 = \
+                     hqRetxStats.ulCqiStat[cqi].numOfHQ_2;
+                  genSts->hqRetxStats.ulCqiStat[cqi].numOfHQ_3 = \
+                     hqRetxStats.ulCqiStat[cqi].numOfHQ_3;
+                  genSts->hqRetxStats.ulCqiStat[cqi].numOfHQ_4 = \
+                     hqRetxStats.ulCqiStat[cqi].numOfHQ_4;
+                  genSts->hqRetxStats.ulCqiStat[cqi].totalTx = \
+                     hqRetxStats.ulCqiStat[cqi].totalTx;
+               }
+               /* Reset statistics */
+               if(sts->t.sts.action == ZEROSTS)
+               {
+                  cmMemset((U8 *)&hqRetxStats, 0, \
+                        sizeof(RgSchHqRetxStats));
+                  cmMemset((U8 *)&hqFailStats, 0, \
+                        sizeof(RgSchNackAckStats));
+               }
+            }
+#endif /* MAC_SCH_STATS*/
+         }
+         break;
+      case STRGUSAP:
+         cmMemcpy((U8 *)&(cfm.t.sts.s.rguSts), (U8 *)&rgCb[inst].rguSap[sts->t.sts.sapInst].sapSts,
+                  sizeof(RgSapSts));
+
+         /* check if action is read and reset */
+         if(sts->t.sts.action == ARST)
+            cmMemset((U8 *)&rgCb[inst].rguSap[sts->t.sts.sapInst].sapSts, 0, sizeof(RgSapSts));
+
+         break;
+      case STCRGSAP:
+         cmMemcpy((U8 *)&(cfm.t.sts.s.crgSts), (U8 *)&rgCb[inst].crgSap.sapSts,
+                  sizeof(RgSapSts));
+
+         /* check if action is read and reset */
+         if(sts->t.sts.action == ARST)
+            cmMemset((U8 *)&rgCb[inst].crgSap.sapSts, 0, sizeof(RgSapSts));
+
+         break;
+      case STTFUSAP:
+         cmMemcpy((U8 *)&(cfm.t.sts.s.tfuSts), (U8 *)&rgCb[inst].tfuSap.sapSts,
+                  sizeof(RgSapSts));
+
+         /* check if action is read and reset */
+         if(sts->t.sts.action == ARST)
+            cmMemset((U8 *)&rgCb[inst].tfuSap.sapSts, 0, sizeof(RgSapSts));
+
+         break;
+      default:
+         cfm.cfm.status = LCM_PRIM_NOK;
+         cfm.cfm.reason = LCM_REASON_INVALID_ELMNT;
+         RLOG1(L_ERROR, "Invalid Elmnt = %d",sts->hdr.elmId.elmnt);
+         break;     
+   }
+   RgMiLrgStsCfm(&cfmPst,&cfm);
+   RETVALUE(ROK);
+}/*-- RgMiLrgStsReq --*/
+
+
+/**
+ * @brief Layer Manager Status request handler. 
+ *
+ * @details
+ *
+ *     Function : RgMiLrgStaReq
+ *     
+ *     This function handles the solicited status
+ *     request received from the Layer Manager.
+ *      -# Based on sta->hdr.elmId.elmnt, it retrieves the status of a
+ *      particular SAP from the rgCb global control block.
+ *      -# Invokes the RgMiLrgStaCfm to send back the confirmation to LM.
+ *     
+ *  @param[in]  Pst *pst, the post structure     
+ *  @param[in]  RgMngmt *sta, the status parameter's structure
+ *  @return  S16
+ *      -# ROK
+ **/
+#ifdef ANSI
+PUBLIC S16 RgMiLrgStaReq
+(
+Pst      *pst,    /* post structure  */
+RgMngmt  *sta     /* status structure  */
+)
+#else
+PUBLIC S16 RgMiLrgStaReq(pst, sta)
+Pst      *pst;    /* post structure  */
+RgMngmt  *sta;    /* status structure  */
+#endif    
+{
+   Pst       cfmPst;
+   RgMngmt   cfm;
+   Inst      inst ;
+
+   TRC2(RgMiLrgStaReq)
+   
+
+   RG_IS_INST_VALID(pst->dstInst);
+   inst = pst->dstInst - RG_INST_START;
+
+
+   /* Fill the post structure for sending the confirmation */
+   rgLMMFillCfmPst(pst, &cfmPst, sta);
+
+   if (sta->t.ssta.s.sysId.ptNmb != NULLP)
+   {
+      SPutSBuf(pst->region, pst->pool, (Data *)sta->t.ssta.s.sysId.ptNmb, LRG_MAX_PT_NUM_SIZE);
+   }
+   
+   cmMemset((U8 *)&cfm, 0, sizeof(RgMngmt));
+   cfm.hdr.elmId.elmnt = sta->hdr.elmId.elmnt;
+
+#ifdef LMINT3
+   cfm.hdr.transId = sta->hdr.transId;
+#endif
+   /* Check if General Config Done */
+   if(rgCb[inst].rgInit.cfgDone != TRUE) 
+   {
+      SGetDateTime(&cfm.t.ssta.dt);
+      if (SGetSBuf(cfmPst.region, cfmPst.pool, 
+          (Data **)&(cfm.t.ssta.s.sysId.ptNmb), LRG_MAX_PT_NUM_SIZE)
+         != ROK)
+      {
+         RLOG0(L_ERROR, "Memory Unavailable for Confirmation");
+         RETVALUE(ROK);
+      } 
+      cmMemset((U8 *)(cfm.t.ssta.s.sysId.ptNmb), 0, LRG_MAX_PT_NUM_SIZE);
+      rgGetSId(&cfm.t.ssta.s.sysId);
+      cfm.cfm.status = LCM_PRIM_NOK;
+      cfm.cfm.reason = LCM_REASON_GENCFG_NOT_DONE;
+      cfm.hdr.elmId.elmnt = sta->hdr.elmId.elmnt;
+      RgMiLrgStaCfm(&cfmPst, &cfm);
+      RLOG0(L_ERROR, "Gen Cfg not done");
+      RETVALUE(ROK);
+   }
+
+   switch(sta->hdr.elmId.elmnt)
+   {
+      case STGEN:
+         SGetDateTime(&cfm.t.ssta.dt);
+         if (SGetSBuf(cfmPst.region, cfmPst.pool, 
+             (Data **)&(cfm.t.ssta.s.sysId.ptNmb), LRG_MAX_PT_NUM_SIZE)
+            != ROK)
+         {
+            RLOG0(L_ERROR, "Memory Unavailable for Confirmation");
+            RETVALUE(ROK);
+         } 
+         cmMemset((U8 *)(cfm.t.ssta.s.sysId.ptNmb), 0, LRG_MAX_PT_NUM_SIZE);
+         rgGetSId(&cfm.t.ssta.s.sysId);
+         cfm.cfm.status = LCM_PRIM_OK;
+         cfm.cfm.reason = LCM_REASON_NOT_APPL;
+         RgMiLrgStaCfm(&cfmPst, &cfm);
+         break;
+      case STRGUSAP:
+         cfm.cfm.status = LCM_PRIM_OK;
+         cfm.cfm.reason = LCM_REASON_NOT_APPL;
+         SGetDateTime(&cfm.t.ssta.dt);
+         cmMemcpy((U8 *)&(cfm.t.ssta.s.rguSapSta), 
+				(U8 *)&rgCb[inst].rguSap[sta->t.ssta.sapInst].sapSta,
+            sizeof(RgSapSta));
+         RgMiLrgStaCfm(&cfmPst, &cfm);
+         break;
+      case STCRGSAP:
+         cfm.cfm.status = LCM_PRIM_OK;
+         cfm.cfm.reason = LCM_REASON_NOT_APPL;
+         SGetDateTime(&cfm.t.ssta.dt);
+         cmMemcpy((U8 *)&(cfm.t.ssta.s.crgSapSta), (U8 *)&rgCb[inst].crgSap.sapSta,
+         sizeof(RgSapSta));
+         RgMiLrgStaCfm(&cfmPst, &cfm);
+         break;
+      case STTFUSAP:
+         cfm.cfm.status = LCM_PRIM_OK;
+         cfm.cfm.reason = LCM_REASON_NOT_APPL;
+         SGetDateTime(&cfm.t.ssta.dt);
+         cmMemcpy((U8 *)&(cfm.t.ssta.s.tfuSapSta), (U8 *)&rgCb[inst].tfuSap.sapSta,
+         sizeof(RgSapSta));
+         RgMiLrgStaCfm(&cfmPst, &cfm);
+         break;
+      default:
+         cfm.cfm.status = LCM_PRIM_NOK;
+         cfm.cfm.reason = LCM_REASON_INVALID_ELMNT;
+         RgMiLrgStaCfm(&cfmPst, &cfm);
+         RLOG1(L_ERROR, "Invalid elmnt=%d",sta->hdr.elmId.elmnt);
+         break;     
+   }
+   RETVALUE(ROK);
+}/*-- RgMiLrgStaReq --*/
+
+
+/**
+ * @brief Layer Manager Control request handler. 
+ *
+ * @details
+ *
+ *     Function : RgMiLrgCntrlReq
+ *     
+ *     This function handles the control
+ *     request received from the Layer Manager.
+ *      -# Based on cntrl->hdr.elmId.elmnt, cntrl->t.cntrl.action
+ *      and cntrl->t.cntrl.subAction, it performs the appropriate control action
+ *      of SAP (enable/disable), Debug (enable/disable), Trace (enable/disable)
+ *      and layer shutdown.
+ *      -# Invokes the RgMiLrgCntrlCfm to send back the confirmation to LM.
+ *     
+ *  @param[in]  Pst *pst, the post structure     
+ *  @param[in]  RgMngmt *cntrl, the control parameter's structure
+ *  @return  S16
+ *      -# ROK
+ **/
+#ifdef ANSI
+PUBLIC S16 RgMiLrgCntrlReq
+(
+Pst      *pst,    /* post structure  */
+RgMngmt  *cntrl   /* control structure  */
+)
+#else
+PUBLIC S16 RgMiLrgCntrlReq(pst, cntrl)
+Pst      *pst;    /* post structure  */
+RgMngmt  *cntrl;  /* control structure  */
+#endif    
+{
+   S16       ret = ROK;            /* return value */
+   Pst       cfmPst;
+   RgMngmt   cfm;
+   Inst      inst;
+   
+   TRC2(RgMiLrgCntrlReq)
+   
+   /* Fill the post structure for sending the confirmation */
+
+   RG_IS_INST_VALID(pst->dstInst);
+   inst = pst->dstInst - RG_INST_START;
+
+   rgLMMFillCfmPst(pst, &cfmPst, cntrl);
+
+   cmMemset((U8 *)&cfm, 0, sizeof(RgMngmt));
+#ifdef LMINT3
+   cfm.hdr.transId = cntrl->hdr.transId;
+#endif
+   cfm.hdr.elmId.elmnt = cntrl->hdr.elmId.elmnt;
+   cfm.t.cntrl.action = cntrl->t.cntrl.action;
+   cfm.t.cntrl.subAction = cntrl->t.cntrl.subAction;
+
+   /* Check if General Config Done*/
+   if(rgCb[inst].rgInit.cfgDone != TRUE)
+   {
+      cfm.cfm.status = LCM_PRIM_NOK;
+      cfm.cfm.reason = LCM_REASON_GENCFG_NOT_DONE;
+      cfm.hdr.elmId.elmnt = cntrl->hdr.elmId.elmnt;
+      RgMiLrgCntrlCfm(&cfmPst, &cfm);
+      RLOG0(L_ERROR, "Gen Cfg not done");
+      RETVALUE(ROK);
+   }
+ 
+   /* General Config done, process the Control request */   
+   switch(cntrl->hdr.elmId.elmnt)
+   {
+      case STGEN:
+         rgLMMGenCntrl(cntrl, &cfm, &cfmPst);
+         break;
+      case STTFUSAP:
+      case STRGUSAP:
+      case STCRGSAP:
+         rgLMMSapCntrl(cntrl, &cfm, &cfmPst);
+         break;
+      default:
+         cfm.cfm.status = LCM_PRIM_NOK;
+         cfm.cfm.reason = LCM_REASON_INVALID_PAR_VAL;
+         RgMiLrgCntrlCfm(&cfmPst, &cfm);
+         RLOG1(L_ERROR, "invalid elmnt=%d",cntrl->hdr.elmId.elmnt);
+         break;
+   }
+   RETVALUE(ret);
+}/*-- RgMiLrgCntrlReq --*/
+
+
+/**
+ * @brief SAP Configuration Handler. 
+ *
+ * @details
+ *
+ *     Function : rgLMMSapCfg
+ *     
+ *     This function in called by RgMiLrgCfgReq(). It handles the
+ *     interface SAP configuration of the LTE MAC layer. It 
+ *     initializes the sapState to LRG_UNBND. Returns
+ *     reason for success/failure of this function.
+ *     
+ *  @param[in]  Inst        inst
+ *  @param[in]  RgCfg *cfg, the Configuaration information 
+ *  @return  U16
+ *      -# LCM_REASON_GENCFG_NOT_DONE
+ *      -# LCM_REASON_INVALID_SAP
+ *      -# LCM_REASON_NOT_APPL
+ **/
+#ifdef ANSI
+PRIVATE U16 rgLMMSapCfg
+(
+Inst  inst,
+RgCfg *cfg,            /* Configuaration information */
+Elmnt sapType             /* Sap Type */
+)
+#else
+PRIVATE U16 rgLMMSapCfg(inst,cfg,sapType)
+Inst  inst;
+RgCfg *cfg;            /* Configuaration information */
+Elmnt sapType;            /* Sap Type */
+#endif
+{
+   U16               ret = LCM_REASON_NOT_APPL;
+   RgLowSapCfgInfo   *lowSapCfg = NULLP;
+   RgUpSapCfgInfo    *upSapCfg = NULLP;
+   RgUpSapCb          *upSapCb  = NULLP;
+
+   TRC2(rgLMMSapCfg)
+
+   /* Check if Gen Config has been done */
+   if(rgCb[inst].rgInit.cfgDone != TRUE)
+      RETVALUE(LCM_REASON_GENCFG_NOT_DONE);
+
+   switch(sapType)
+   {   
+      case STRGUSAP:
+         if ((cfg->s.rguSap.spId > LRG_MAX_RGU_SAPS) &&
+             (cfg->s.rguSap.selector != RGU_SEL_TC) &&
+             (cfg->s.rguSap.selector != RGU_SEL_LC))
+         {
+            ret = LCM_REASON_INVALID_PAR_VAL;
+            RLOG0(L_ERROR, "unsupported Selector value for RGU");
+            break;
+         }
+         upSapCb = &(rgCb[inst].rguSap[cfg->s.rguSap.spId]);
+         if(upSapCb->sapSta.sapState == LRG_NOT_CFG)
+         { 
+            upSapCb->sapSta.sapState = LRG_UNBND;
+         }
+         upSapCfg = &(upSapCb->sapCfg);
+         upSapCfg->sapPst.dstEnt = cfg->s.rguSap.ent;
+         upSapCfg->sapPst.dstInst = cfg->s.rguSap.inst;
+         upSapCfg->sapPst.dstProcId = cfg->s.rguSap.procId;
+         upSapCfg->sapPst.srcEnt = rgCb[inst].rgInit.ent;
+         upSapCfg->sapPst.srcInst = rgCb[inst].rgInit.inst;
+         upSapCfg->sapPst.srcProcId = rgCb[inst].rgInit.procId;
+         upSapCfg->sapPst.region = cfg->s.rguSap.mem.region;
+         upSapCfg->sapPst.pool = cfg->s.rguSap.mem.pool;
+         upSapCfg->sapPst.selector = cfg->s.rguSap.selector;
+         upSapCfg->sapPst.route = cfg->s.rguSap.route;
+         upSapCfg->sapPst.intfVer = 0; 
+         upSapCfg->sapPst.prior = cfg->s.rguSap.prior;
+         upSapCfg->suId = cfg->s.rguSap.suId;
+         upSapCfg->spId = cfg->s.rguSap.spId;
+         /*T2K uses 2 saps, T3K uses 1 sap. change the rgRguDlSap to 1 only if
+          * there is cfg request with sap is 1*/
+         break;
+      case STCRGSAP:
+         if ((cfg->s.crgSap.selector != CRG_SEL_TC) &&
+             (cfg->s.crgSap.selector != CRG_SEL_LC))
+         {
+            ret = LCM_REASON_INVALID_PAR_VAL;
+            RLOG0(L_ERROR, "unsupported Selector value for CRG");
+            break;
+         }
+         if(rgCb[inst].crgSap.sapSta.sapState == LRG_NOT_CFG)
+         { 
+            rgCb[inst].crgSap.sapSta.sapState = LRG_UNBND;
+         }
+         upSapCfg = &rgCb[inst].crgSap.sapCfg;
+
+         upSapCfg->sapPst.dstEnt = cfg->s.crgSap.ent;
+         upSapCfg->sapPst.dstInst = cfg->s.crgSap.inst;
+         upSapCfg->sapPst.dstProcId = cfg->s.crgSap.procId;
+         upSapCfg->sapPst.srcEnt = rgCb[inst].rgInit.ent;
+         upSapCfg->sapPst.srcInst = rgCb[inst].rgInit.inst;
+         upSapCfg->sapPst.srcProcId = rgCb[inst].rgInit.procId;
+         upSapCfg->sapPst.region = cfg->s.crgSap.mem.region;
+         upSapCfg->sapPst.pool = cfg->s.crgSap.mem.pool;
+         upSapCfg->sapPst.selector = cfg->s.crgSap.selector;
+         upSapCfg->sapPst.route = cfg->s.crgSap.route;
+         upSapCfg->sapPst.intfVer = 0; 
+         upSapCfg->sapPst.prior = cfg->s.crgSap.prior;
+         upSapCfg->suId = cfg->s.crgSap.suId;
+         upSapCfg->spId = cfg->s.crgSap.spId;
+         break;
+      case STTFUSAP:
+#ifndef CL_MAC_LWLC 
+         if ((cfg->s.tfuSap.selector != TFU_SEL_TC) &&
+             (cfg->s.tfuSap.selector != TFU_SEL_LC))
+         {
+            ret = LCM_REASON_INVALID_PAR_VAL;
+            RLOG0(L_ERROR, "unsupported Selector value for TFU");
+            break;
+         }
+#endif
+         if (rgCb[inst].tfuSap.sapSta.sapState == LRG_NOT_CFG) 
+         { 
+            rgCb[inst].tfuSap.sapSta.sapState = LRG_UNBND;
+         }
+         lowSapCfg = &rgCb[inst].tfuSap.sapCfg;
+
+         lowSapCfg->sapPst.dstEnt = cfg->s.tfuSap.ent;
+         lowSapCfg->sapPst.dstInst = cfg->s.tfuSap.inst;
+         lowSapCfg->sapPst.dstProcId = rgCb[inst].rgInit.procId;
+         lowSapCfg->sapPst.srcEnt = rgCb[inst].rgInit.ent;
+         lowSapCfg->sapPst.srcInst = rgCb[inst].rgInit.inst;
+         lowSapCfg->sapPst.srcProcId = rgCb[inst].rgInit.procId;
+         lowSapCfg->sapPst.region = cfg->s.tfuSap.mem.region;
+         lowSapCfg->sapPst.pool = cfg->s.tfuSap.mem.pool;
+         lowSapCfg->sapPst.selector = cfg->s.tfuSap.selector;
+         lowSapCfg->sapPst.route = cfg->s.tfuSap.route;
+         lowSapCfg->sapPst.intfVer = 0; 
+         lowSapCfg->sapPst.prior = cfg->s.tfuSap.prior;
+         lowSapCfg->suId = cfg->s.tfuSap.suId;
+         lowSapCfg->spId = cfg->s.tfuSap.spId;
+         cmMemcpy((U8 *)&lowSapCfg->bndTmr, (U8 *)&cfg->s.tfuSap.bndTmr,
+                   sizeof(TmrCfg));
+         break;
+      default:
+         /* would never reach here */
+         break;
+   }
+   RETVALUE(ret);
+}
+
+
+/**
+ * @brief General Configuration Handler. 
+ *
+ * @details
+ *
+ *     Function : rgLMMGenCfg
+ *     
+ *     This function in called by RgMiLrgCfgReq(). It handles the
+ *     general configuration of the LTE MAC layer. It initializes 
+ *     the hash lists of RgCb. Returns
+ *     reason for success/failure of this function.
+ *     
+ *  @param[in]  Inst        inst
+ *  @param[in]  RgCfg *cfg, the Configuaration information 
+ *  @return  U16
+ *      -# LCM_REASON_NOT_APPL 
+ *      -# LCM_REASON_INVALID_MSGTYPE
+ *      -# LCM_REASON_MEM_NOAVAIL
+ **/
+#ifdef ANSI
+PRIVATE U16 rgLMMGenCfg
+(
+Inst inst,
+RgCfg *cfg            /* Configuaration information */
+)
+#else
+PRIVATE U16 rgLMMGenCfg(inst,cfg)
+Inst inst;
+RgCfg *cfg;            /* Configuaration information */
+#endif
+{
+   U16    ret = LCM_REASON_NOT_APPL;
+
+   TRC2(rgLMMGenCfg)
+
+   /* Check if General Configuration is done already */
+   if (rgCb[inst].rgInit.cfgDone == TRUE)
+   {
+      RETVALUE(LCM_REASON_INVALID_MSGTYPE);
+   }
+   if ((cfg->s.genCfg.lmPst.selector != LRG_SEL_TC) &&
+       (cfg->s.genCfg.lmPst.selector != LRG_SEL_LC))
+   {
+      RLOG0(L_ERROR, "unsupported Selector value for RGU");
+      RETVALUE(LCM_REASON_INVALID_PAR_VAL);
+   }
+   /* Update the Pst structure for LM interface */
+   cmMemcpy((U8 *)&rgCb[inst].rgInit.lmPst, (U8 *)&cfg->s.genCfg.lmPst,
+             sizeof(Pst));
+
+   rgCb[inst].rgInit.lmPst.srcProcId = rgCb[inst].rgInit.procId;
+   rgCb[inst].rgInit.lmPst.srcEnt = rgCb[inst].rgInit.ent;
+   rgCb[inst].rgInit.lmPst.srcInst = rgCb[inst].rgInit.inst;
+   rgCb[inst].rgInit.lmPst.event = EVTNONE;
+
+   rgCb[inst].rgInit.region = cfg->s.genCfg.mem.region;
+   rgCb[inst].rgInit.pool = cfg->s.genCfg.mem.pool;
+   rgCb[inst].genCfg.tmrRes = cfg->s.genCfg.tmrRes;
+   /* Initialize SAP States */
+   rgCb[inst].crgSap.sapSta.sapState = LRG_NOT_CFG;
+
+   if(cfg->s.genCfg.numRguSaps == 0)
+   {
+      RGDBGERRNEW(inst,(rgPBuf(inst), "\nrgGenCfg(): Invalid numRguSap.\n"));
+      RETVALUE(RFAILED);
+   }
+
+   /* allocate RGR saps */
+   if (SGetSBuf(rgCb[inst].rgInit.region,
+                rgCb[inst].rgInit.pool,
+                (Data **)&rgCb[inst].rguSap,
+                (sizeof(RgUpSapCb) * cfg->s.genCfg.numRguSaps)) != ROK)
+   {
+      RGDBGERRNEW(inst,(rgPBuf(inst), "\nrgGenCfg(): Failed to allocate mem for RGU SAP's.\n"));
+      RETVALUE(RFAILED);
+   }
+   rgCb[inst].numRguSaps = cfg->s.genCfg.numRguSaps;
+
+   for (int idx = 0; idx < rgCb[inst].numRguSaps; idx++)
+   {
+      rgCb[inst].rguSap[idx].sapSta.sapState = LRG_NOT_CFG;
+      cmMemset((U8 *)&rgCb[inst].rguSap[idx], 0, sizeof(RgUpSapCb));
+   }
+   rgCb[inst].tfuSap.sapSta.sapState = LRG_NOT_CFG;
+   /* Initialize the timer blocks */
+   cmInitTimers(rgCb[inst].tmrBlk, RG_MAX_TIMER);
+   /* Initialzie the timer queue */   
+   cmMemset((U8 *)&rgCb[inst].tmrTq, 0, sizeof(CmTqType)*RG_TQ_SIZE);
+   /* Initialize the timer control point */
+   cmMemset((U8 *)&rgCb[inst].tmrTqCp, 0, sizeof(CmTqCp));
+   rgCb[inst].tmrTqCp.tmrLen = RG_TQ_SIZE;
+   /* Timer Registration request to SSI */
+   if (SRegTmrMt(rgCb[inst].rgInit.ent, rgCb[inst].rgInit.inst,
+            (S16)rgCb[inst].genCfg.tmrRes, rgActvTmr) != ROK)
+   {
+      
+      RLOG0(L_ERROR, "Failed to register timer");
+
+      SPutSBuf(rgCb[inst].rgInit.region,
+                rgCb[inst].rgInit.pool,
+                (Data *)rgCb[inst].rguSap,
+                (sizeof(RgUpSapCb) * cfg->s.genCfg.numRguSaps));
+
+      RETVALUE(LCM_REASON_MEM_NOAVAIL);
+   }
+   /* Set Config done in TskInit */
+   rgCb[inst].rgInit.cfgDone = TRUE;
+
+   RETVALUE(ret);
+}
+
+
+/***********************************************************
+ *
+ *     Func : rgLMMShutdown
+ *        
+ *
+ *     Desc : Handles the MAC layer shutdown request. Calls 
+ *     rgCFGFreeCellCb(RgCellCb*) to handle each cellCb deallocation.
+ *            
+ *
+ *     Ret  : Void
+ *
+ *     Notes: 
+ *
+ *     File : rg_lmm.c 
+ *
+ **********************************************************/
+#ifdef ANSI
+PRIVATE Void rgLMMShutdown
+(
+Inst inst
+)
+#else
+PRIVATE Void rgLMMShutdown(inst)
+Inst inst;
+#endif
+{
+   RgCellCb   *cell = rgCb[inst].cell;
+   U8 idx;
+
+   TRC2(rgLMMShutdown)
+
+   /* Unbind the TFU Sap */
+   if(rgCb[inst].tfuSap.sapSta.sapState == LRG_WAIT_BNDCFM)
+   {
+      rgLIMTfuUbndReq(inst,rgCb[inst].tfuSap.sapCfg.spId, LRG_UNBND);
+      if (rgCb[inst].tfuSap.sapCfg.bndTmr.enb == TRUE)
+      {
+         rgLMMStopTmr(inst,RG_BNDREQ_TMR, (PTR)&rgCb[inst].tfuSap); 
+      }
+      rgCb[inst].tfuSap.sapSta.sapState = LRG_UNBND;
+   }
+   if(rgCb[inst].tfuSap.sapSta.sapState == LRG_BND)
+   {
+      rgLIMTfuUbndReq(inst,rgCb[inst].tfuSap.sapCfg.spId, LRG_UNBND);
+      rgCb[inst].tfuSap.sapSta.sapState = LRG_UNBND;
+   }
+
+
+   if(cell != NULLP)
+   {
+      for(idx=0;idx < RG_NUM_SUB_FRAMES; idx++)
+      {
+         rgTOMRlsSf(inst,&cell->subFrms[idx]);
+      }
+
+      rgCFGFreeCellCb(cell);
+   }
+
+   /* Deleting the RGU SAPs */
+   SPutSBuf(rgCb[inst].rgInit.region,
+                rgCb[inst].rgInit.pool,
+                (Data *)rgCb[inst].rguSap,
+                (sizeof(RgUpSapCb) * rgCb[inst].numRguSaps));
+   rgCb[inst].rguSap = NULLP;
+
+   rgCb[inst].inactiveCell = NULLP;
+   rgCb[inst].cell         = NULLP;
+
+   /* De-register the Timer Service */
+   (Void) SDeregTmrMt(rgCb[inst].rgInit.ent, rgCb[inst].rgInit.inst,
+                     (S16)rgCb[inst].genCfg.tmrRes, rgActvTmr); 
+
+   /* call back the task initialization function to intialize
+    * the global RgCb Struct */
+   rgActvInit(rgCb[inst].rgInit.ent, rgCb[inst].rgInit.inst, rgCb[inst].rgInit.region, 
+              rgCb[inst].rgInit.reason);
+
+   RETVOID;
+}
+
+
+/***********************************************************
+ *
+ *     Func : rgLMMGenCntrl 
+ *        
+ *
+ *     Desc : Processes the LM control request for STGEN elmnt.
+ *            
+ *
+ *     Ret  : Void
+ *
+ *     Notes: 
+ *
+ *     File : rg_lmm.c 
+ *
+ **********************************************************/
+#ifdef ANSI
+PRIVATE Void rgLMMGenCntrl 
+(
+RgMngmt       *cntrl,
+RgMngmt       *cfm,
+Pst           *cfmPst
+)
+#else
+PRIVATE Void rgLMMGenCntrl(cntrl, cfm, cfmPst)
+RgMngmt       *cntrl;
+RgMngmt       *cfm;
+Pst           *cfmPst;
+#endif
+{
+   Inst      inst = (cfmPst->srcInst - RG_INST_START);
+   TRC2(rgLMMGenCntrl)
+
+   cfm->cfm.status = LCM_PRIM_OK;
+   cfm->cfm.reason = LCM_REASON_NOT_APPL;
+   
+
+   switch(cntrl->t.cntrl.action)
+   {
+      case AENA:
+         /* Action is Enable */
+         switch(cntrl->t.cntrl.subAction)
+         {
+            case SATRC:
+            /* Enable Traces */
+               rgCb[inst].rgInit.trc = TRUE;
+               rgCb[inst].trcLen = cntrl->t.cntrl.s.trcLen;
+               /*Store the response and TransId for sending the Traces */
+               cmMemcpy((U8 *)&rgCb[inst].genCfg.trcResp.response, 
+               (U8 *)&cntrl->hdr.response, sizeof(Resp));
+               rgCb[inst].genCfg.trcResp.transId = cntrl->hdr.transId;
+               
+               break;
+            case SAUSTA:   
+            /* Enable Unsolicited Status (alarms) */
+               rgCb[inst].rgInit.usta = TRUE;
+               /*Store the response and TransId for sending the Alarms */
+               cmMemcpy((U8 *)&rgCb[inst].genCfg.ustaResp.response, 
+               (U8 *)&cntrl->hdr.response, sizeof(Resp));
+               rgCb[inst].genCfg.ustaResp.transId = cntrl->hdr.transId;
+               break;
+            case SADBG:
+            /* Enable Debug Printing */
+#ifdef DEBUGP
+               rgCb[inst].rgInit.dbgMask |= cntrl->t.cntrl.s.rgDbgCntrl.dbgMask;
+#endif
+               break;
+#ifdef SS_DIAG
+            case SALOG:
+               rgCb[inst].rgInit.logMask = cntrl->t.cntrl.s.logMask;
+               break;
+#endif
+
+            default:
+               cfm->cfm.status = LCM_PRIM_NOK;
+               cfm->cfm.reason = LCM_REASON_INVALID_PAR_VAL;
+               RLOG1(L_ERROR, "invalid subaction=%d",cntrl->t.cntrl.subAction);
+               break;
+         }
+         break;
+      case ADISIMM:
+         /* Action is Diable immidiately */
+         switch(cntrl->t.cntrl.subAction)
+         {
+            case SATRC:
+            /* Disable Traces */
+               rgCb[inst].rgInit.trc = FALSE;
+               break;
+            case SAUSTA:
+            /* Disable Unsolicited Status (alarms) */
+               rgCb[inst].rgInit.usta = FALSE;
+               break;
+            case SADBG:
+            /* Disable Debug Printing */
+#ifdef DEBUGP
+               rgCb[inst].rgInit.dbgMask &=~cntrl->t.cntrl.s.rgDbgCntrl.dbgMask;
+#endif
+               break;
+#ifdef SS_DIAG
+            case SALOG:
+               rgCb[inst].rgInit.logMask = cntrl->t.cntrl.s.logMask;
+                break;
+#endif
+
+            default:
+               cfm->cfm.status = LCM_PRIM_NOK;
+               cfm->cfm.reason = LCM_REASON_INVALID_PAR_VAL;
+               RLOG1(L_ERROR, "invalid subaction=%d",cntrl->t.cntrl.subAction);
+               break;
+         }
+         break;
+      case ASHUTDOWN:
+         /* Free all the memory dynamically allocated by MAC */
+         rgLMMShutdown(inst);
+         break;
+      default:
+         cfm->cfm.status = LCM_PRIM_NOK;
+         cfm->cfm.reason = LCM_REASON_INVALID_PAR_VAL;
+         RLOG1(L_ERROR, "invalid action=%d",cntrl->t.cntrl.action);
+         break;
+   }
+   RgMiLrgCntrlCfm(cfmPst, cfm);
+   RETVOID;
+}
+
+
+/***********************************************************
+ *
+ *     Func : rgLMMSapCntrl 
+ *        
+ *
+ *     Desc : Processes the LM control request for STxxxSAP elmnt.
+ *            
+ *
+ *     Ret  : Void
+ *
+ *     Notes: 
+ *
+ *     File : rg_lmm.c 
+ *
+ **********************************************************/
+#ifdef ANSI
+PRIVATE Void rgLMMSapCntrl 
+(
+RgMngmt       *cntrl,
+RgMngmt       *cfm,
+Pst           *cfmPst
+)
+#else
+PRIVATE Void rgLMMSapCntrl(cntrl, cfm, cfmPst)
+RgMngmt       *cntrl;
+RgMngmt       *cfm;
+Pst           *cfmPst;
+#endif
+{
+   Inst      inst = cfmPst->srcInst - RG_INST_START;
+   TRC2(rgLMMSapCntrl)
+
+   /* Only TFU Sap can be controlled by LM */
+   switch(cntrl->hdr.elmId.elmnt)
+   {
+      case STTFUSAP:
+         switch(cntrl->t.cntrl.action)
+         {
+            case ABND:
+            /* Bind Enable Request */
+               if ((rgCb[inst].tfuSap.sapSta.sapState == LRG_NOT_CFG) ||
+                   (rgCb[inst].tfuSap.sapSta.sapState == LRG_BND))
+               {
+                  cfm->cfm.status = LCM_PRIM_NOK;
+                  cfm->cfm.reason = LCM_REASON_INVALID_SAP;
+               }
+               else
+               {
+                  if (rgCb[inst].tfuSap.sapCfg.bndTmr.enb == TRUE)
+                  {
+                     rgLMMStartTmr(inst,RG_BNDREQ_TMR, rgCb[inst].tfuSap.sapCfg.bndTmr.val, 
+                     (PTR)&rgCb[inst].tfuSap);
+                  }
+                  /* Change SAP state */
+                  rgCb[inst].tfuSap.sapSta.sapState = LRG_WAIT_BNDCFM;
+                  rgCb[inst].tfuSap.numBndRetries++;
+                  /* Store the response and TransId for sending 
+                   * the Control confirm */
+                  cmMemcpy((U8 *)&rgCb[inst].genCfg.bndCfmResp.response,
+                           (U8 *)&cntrl->hdr.response, sizeof(Resp));
+                  rgCb[inst].genCfg.bndCfmResp.transId = cntrl->hdr.transId;
+
+                  /* Sending Status Indication to Layer Manager */
+                  cfm->cfm.status = LCM_PRIM_OK_NDONE;
+                  cfm->cfm.reason = LCM_REASON_NOT_APPL;
+                  RgMiLrgCntrlCfm(cfmPst, cfm);
+
+                  rgLIMTfuBndReq(inst,rgCb[inst].tfuSap.sapCfg.suId,
+                                      rgCb[inst].tfuSap.sapCfg.spId);
+                  RETVOID;
+               }
+               break;
+            case AUBND:
+            /* Unbind request */
+
+               /* Check if the SAP is configured */
+               if( (rgCb[inst].tfuSap.sapSta.sapState == LRG_NOT_CFG) ||
+                     (rgCb[inst].tfuSap.sapSta.sapState == LRG_UNBND))
+               {
+                  cfm->cfm.status = LCM_PRIM_NOK;
+                  cfm->cfm.reason = LCM_REASON_INVALID_MSGTYPE;
+               }
+               else
+               {
+                  rgLIMTfuUbndReq(inst,rgCb[inst].tfuSap.sapCfg.spId, TFU_UBNDREQ_MNGMT);
+                  if (rgCb[inst].tfuSap.sapCfg.bndTmr.enb == TRUE)
+                  {
+                     rgLMMStopTmr(inst,RG_BNDREQ_TMR, (PTR)&rgCb[inst].tfuSap);
+                  }
+                  /* Change SAP state */
+                  rgCb[inst].tfuSap.sapSta.sapState = LRG_UNBND;
+                  cfm->cfm.status = LCM_PRIM_OK;
+                  cfm->cfm.reason = LCM_REASON_NOT_APPL;
+               }
+               break;
+            case ADEL:
+               /* Delete SAP, does initialization of SAP */
+               if ((rgCb[inst].tfuSap.sapSta.sapState == LRG_WAIT_BNDCFM) ||
+                   (rgCb[inst].tfuSap.sapSta.sapState == LRG_BND))
+               {
+                  rgLIMTfuUbndReq(inst,rgCb[inst].tfuSap.sapCfg.spId, TFU_UBNDREQ_MNGMT);
+                  if (rgCb[inst].tfuSap.sapCfg.bndTmr.enb == TRUE)
+                  {
+                     rgLMMStopTmr(inst,RG_BNDREQ_TMR, (PTR)&rgCb[inst].tfuSap);
+                  }
+               }
+               cmMemset((U8 *)&rgCb[inst].tfuSap, 0, sizeof(RgLowSapCb));
+               rgCb[inst].tfuSap.sapSta.sapState = LRG_NOT_CFG;
+               cfm->cfm.status = LCM_PRIM_OK;
+               cfm->cfm.reason = LCM_REASON_NOT_APPL;
+               break;
+            default:
+               cfm->cfm.status = LCM_PRIM_NOK;
+               cfm->cfm.reason = LCM_REASON_INVALID_PAR_VAL;
+               RGDBGERRNEW(inst,(rgPBuf(inst), "\nrgLMMSapCntrl(): invalid action=%d",
+               cntrl->t.cntrl.action));
+               break;
+         }
+         break;
+      case STRGUSAP:
+         switch(cntrl->t.cntrl.action)
+         {
+            case ADEL:
+               cmMemset((U8 *)&rgCb[inst].rguSap[cntrl->t.cntrl.instId], 0, sizeof(RgUpSapCb));
+               rgCb[inst].rguSap[cntrl->t.cntrl.instId].sapSta.sapState = LRG_NOT_CFG;
+               cfm->cfm.status = LCM_PRIM_OK;
+               cfm->cfm.reason = LCM_REASON_NOT_APPL;
+               break;
+            default:
+               cfm->cfm.status = LCM_PRIM_NOK;
+               cfm->cfm.reason = LCM_REASON_INVALID_PAR_VAL;
+               RGDBGERRNEW(inst,(rgPBuf(inst), "\nrgLMMSapCntrl(): invalid action=%d",
+               cntrl->t.cntrl.action));
+               break;
+         }
+         break;
+      case STCRGSAP:
+         switch(cntrl->t.cntrl.action)
+         {
+            case ADEL:
+               cmMemset((U8 *)&rgCb[inst].crgSap, 0, sizeof(RgUpSapCb));
+               rgCb[inst].crgSap.sapSta.sapState = LRG_NOT_CFG;
+               cfm->cfm.status = LCM_PRIM_OK;
+               cfm->cfm.reason = LCM_REASON_NOT_APPL;
+               break;
+            default:
+               cfm->cfm.status = LCM_PRIM_NOK;
+               cfm->cfm.reason = LCM_REASON_INVALID_PAR_VAL;
+               RLOG1(L_ERROR, "invalid action=%d",cntrl->t.cntrl.action);
+               
+               break;
+         }
+         break;
+      default:
+         /* Would never here. */
+         RETVOID;
+   }
+   RgMiLrgCntrlCfm(cfmPst, cfm);
+   RETVOID;
+}
+
+
+/***********************************************************
+ *
+ *     Func : rgLMMFillCfmPst 
+ *        
+ *
+ *     Desc : Fills the Confirmation Post Structure cfmPst using the reqPst 
+ *            and the cfm->hdr.response.
+ *            
+ *
+ *     Ret  : Void
+ *
+ *     Notes: 
+ *
+ *     File : rg_lmm.c 
+ *
+ **********************************************************/
+#ifdef ANSI
+PRIVATE Void rgLMMFillCfmPst
+(
+Pst           *reqPst,
+Pst           *cfmPst,
+RgMngmt       *cfm
+)
+#else
+PRIVATE Void rgLMMFillCfmPst(reqPst, cfmPst, cfm)
+Pst           *reqPst;
+Pst           *cfmPst;
+RgMngmt       *cfm;
+#endif
+{
+   Inst inst;
+   TRC2(rgLMMFillCfmPst)
+   inst = (reqPst->dstInst - RG_INST_START);
+
+   cfmPst->srcEnt    = rgCb[inst].rgInit.ent;
+   cfmPst->srcInst   = rgCb[inst].rgInit.inst;
+   cfmPst->srcProcId = rgCb[inst].rgInit.procId;
+   cfmPst->dstEnt    = reqPst->srcEnt;
+   cfmPst->dstInst   = reqPst->srcInst;
+   cfmPst->dstProcId = reqPst->srcProcId;
+
+   cfmPst->selector  = cfm->hdr.response.selector;
+   cfmPst->prior     = cfm->hdr.response.prior;
+   cfmPst->route     = cfm->hdr.response.route;
+   cfmPst->region    = cfm->hdr.response.mem.region;
+   cfmPst->pool      = cfm->hdr.response.mem.pool;
+
+   RETVOID;
+}
+
+
+/**
+ * @brief Timer start handler. 
+ *
+ * @details
+ *
+ *     Function : rgLMMStartTmr
+ *     
+ *     This function based on the input parameters starts the timer for 
+ *     "tmrVal" duration. As of now MAC uses the timer functionality for 
+ *     BndReq only. Hence there is no conditional code based on "tmrEvnt".
+ *     
+ *  @param[in]  Inst        inst
+ *  @param[in]  S16   tmrEvnt, the Timer Event    
+ *  @param[in]  U32   tmrVal,  the Wait Time
+ *  @param[in]  PTR   cb,  Entry for which Timer expired
+ *  @return  S16
+ *      -# ROK
+ **/
+#ifdef ANSI
+PUBLIC S16 rgLMMStartTmr
+(
+Inst               inst,
+S16                tmrEvnt,            /* Timer Event */
+U32                tmrVal,             /* Wait Time */
+PTR                cb                  /* Entry for which Timer Expired */
+)
+#else
+PUBLIC S16 rgLMMStartTmr(tmrEvnt, tmrVal, cb)
+Inst               inst;
+S16                tmrEvnt;            /* Timer Event */
+U32                tmrVal;             /* Wait Time */
+PTR                cb;                 /* Entry for which Timer Expired */
+#endif
+{
+   CmTmrArg    arg;
+
+   TRC2(rgLMMStartTmr)
+
+   UNUSED(tmrEvnt);
+
+   /* Initialize the arg structure */
+   cmMemset((U8 *)&arg, 0, sizeof(CmTmrArg));
+
+   arg.tqCp = &rgCb[inst].tmrTqCp;
+   arg.tq = rgCb[inst].tmrTq;
+   arg.timers = rgCb[inst].tmrBlk;
+   arg.cb = cb;
+   arg.tNum = 0;
+   arg.max = RG_MAX_TIMER;
+   arg.evnt = RG_BNDREQ_TMR;
+   arg.wait = tmrVal;      
+   cmPlcCbTq(&arg);
+
+   RETVALUE(ROK);
+}
+
+
+/**
+ * @brief Timer stop handler. 
+ *
+ * @details
+ *
+ *     Function : rgLMMStopTmr
+ *     
+ *     This function based on the input parameters stops the timer for 
+ *     "tmrEvnt". As of now MAC uses the timer functionality for 
+ *     BndReq only. Hence there is no conditional code based on "tmrEvnt".
+ *     Once the bind happens and this timer is stopped, the timer functionality
+ *     is deregistered with SSI. As there is no further use of timer processing.
+ *     
+ *  @param[in]  Inst        inst
+ *  @param[in]  S16   tmrEvnt, the Timer Event    
+ *  @param[in]  PTR   cb,  Entry for which Timer expired
+ *  @return  S16
+ *      -# ROK
+ *      -# RFAILED
+ **/
+#ifdef ANSI
+PUBLIC S16 rgLMMStopTmr
+(
+Inst               inst,             /* Scheduler instance */
+S16                tmrEvnt,            /* Timer Event */
+PTR                cb                  /* Entry for which Timer Expired */
+)
+#else
+PUBLIC S16 rgLMMStopTmr(inst,tmrEvnt, cb)
+Inst               inst;             /* Scheduler instance */
+S16                tmrEvnt;            /* Timer Event */
+PTR                cb;                 /* Entry for which Timer Expired */
+#endif
+{
+   CmTmrArg   arg;
+   U8         i;
+   S16        ret; 
+
+   TRC2(rgLMMStopTmr)
+
+   ret = RFAILED;
+
+   for(i=0;isapCfg.sapPst.srcInst - RG_INST_START;
+
+   TRC2(rgLMMTmrExpiry)
+
+   
+   switch(tmrEvnt)
+   {
+      case RG_BNDREQ_TMR:
+         tfuSap->numBndRetries++;
+         if(tfuSap->numBndRetries > RG_MAX_BNDRETRY)
+         {
+            rgLMMStaInd(inst,LCM_CATEGORY_INTERFACE, LCM_EVENT_BND_FAIL,
+                        LCM_CAUSE_TMR_EXPIRED, NULLP);
+         }
+         else
+         {
+            /* Restart the bind timer */
+            if (tfuSap->sapCfg.bndTmr.enb == TRUE)
+            {
+               ret = rgLMMStartTmr(inst,RG_BNDREQ_TMR, tfuSap->sapCfg.bndTmr.val,
+               cb);
+            }
+
+            /* Send bind request */
+            rgLIMTfuBndReq(inst,rgCb[inst].tfuSap.sapCfg.suId,
+                                rgCb[inst].tfuSap.sapCfg.spId);
+         }
+         break;
+      default:
+         RLOG1(L_ERROR, "Invalid tmrEvnt=%d",tmrEvnt);
+         ret = RFAILED;
+         break;
+   }
+   RETVALUE(ret);
+}
+
+
+
+/**
+ * @brief Layer Manager Unsolicited Status Indication generation. 
+ *
+ * @details
+ *
+ *     Function : rgLMMStaInd 
+ *     
+ *     This API is used by the other modules of MAC to send a unsolicited
+ *     status indication to the Layer Manager.
+ *     
+ *  @param[in]  Inst        inst
+ *  @param[in]  U16 category, the Alarm category
+ *  @param[in]  U16 event, the Alarm event
+ *  @param[in]  U16 cause, the cause of the Alarm
+ *  @param[in]  RgUstaDgn *dgn, Alarm Diagonostics
+ *  @return  S16
+ *      -# ROK
+ **/
+#ifdef ANSI
+PUBLIC S16 rgLMMStaInd
+(
+Inst inst,
+U16 category,
+U16 event,
+U16 cause,
+RgUstaDgn *dgn
+)
+#else
+PUBLIC S16 rgLMMStaInd(inst,category, event, cause, dgn) 
+Inst inst;
+U16 category;
+U16 event;
+U16 cause;
+RgUstaDgn *dgn;
+#endif
+{
+   RgMngmt    usta;
+
+   TRC2(rgLMMStaInd)
+
+   if(rgCb[inst].rgInit.usta == FALSE)
+   {
+      RETVALUE(ROK);
+   }
+
+   cmMemset((U8 *)&usta, 0, sizeof(RgMngmt));
+
+   SGetDateTime(&usta.t.usta.cmAlarm.dt);
+   usta.t.usta.cmAlarm.category = category;
+   usta.t.usta.cmAlarm.event = event;
+   usta.t.usta.cmAlarm.cause = cause;
+   if (dgn != NULLP)
+   {
+      cmMemcpy((U8 *)&usta.t.usta.dgn, (U8 *)dgn, sizeof(RgUstaDgn));
+   }
+
+   rgCb[inst].rgInit.lmPst.selector = rgCb[inst].genCfg.ustaResp.response.selector;
+   rgCb[inst].rgInit.lmPst.prior = rgCb[inst].genCfg.ustaResp.response.prior;
+   rgCb[inst].rgInit.lmPst.route = rgCb[inst].genCfg.ustaResp.response.route;
+   rgCb[inst].rgInit.lmPst.region = rgCb[inst].genCfg.ustaResp.response.mem.region;
+   rgCb[inst].rgInit.lmPst.pool = rgCb[inst].genCfg.ustaResp.response.mem.pool;
+   usta.hdr.transId = rgCb[inst].genCfg.ustaResp.transId;
+
+   RETVALUE(RgMiLrgStaInd(&rgCb[inst].rgInit.lmPst, &usta));
+}
+
+
+/**
+ * @brief Layer Manager Trace Indication generation. 
+ *
+ * @details
+ *
+ *     Function : rgLMMTrcInd 
+ *     
+ *     This API is used by the other modules of MAC to send a 
+ *     Trace indication to the Layer Manager.
+ *     
+ *  @param[in]  Inst        inst
+ *  @param[in]   Buffer *srcMbuf, the Message Buffer .
+ *  @param[in]   U8 event, the trace event.
+ *  @return Void 
+ **/
+#ifdef ANSI
+PUBLIC Void rgLMMTrcInd
+(
+Inst   inst,
+Buffer *srcMbuf,    /* Message Buffer */
+U8 event            /* event */
+)
+#else
+PUBLIC Void rgLMMTrcInd(inst,srcMbuf,event)
+Inst   inst;
+Buffer *srcMbuf;    /* Message Buffer */
+U8 event;           /* event */
+#endif
+{
+   Buffer   *dstMbuf = NULLP;   
+   MsgLen   bufLen  = 0;
+   Data     *tempBuf;
+   MsgLen   tempCnt;
+   RgMngmt  trc;
+   Pst      pst;
+
+   TRC2(rgLMMTrcInd)
+
+
+   if ((rgCb[inst].trcLen == LRG_NO_TRACE) || (srcMbuf == NULLP))
+   {
+      RLOG0(L_ERROR, "Trace Disabled.");
+      RETVOID;
+   }
+   
+   cmMemset((U8 *)&trc, 0, sizeof(RgMngmt));
+
+   pst = rgCb[inst].rgInit.lmPst;
+   pst.selector = rgCb[inst].genCfg.trcResp.response.selector;
+   pst.prior = rgCb[inst].genCfg.trcResp.response.prior;
+   pst.route = rgCb[inst].genCfg.trcResp.response.route;
+   pst.region = rgCb[inst].genCfg.trcResp.response.mem.region;
+   pst.pool = rgCb[inst].genCfg.trcResp.response.mem.pool;
+
+   trc.hdr.transId = rgCb[inst].genCfg.trcResp.transId;
+
+   SGetDateTime(&trc.t.trc.dt);
+      
+   /* Check if the whole buffer is to be sent in Trace indication */
+   if(rgCb[inst].trcLen == LRG_FULL_TRACE)
+   {
+      if (SCpyMsgMsg(srcMbuf, pst.region, pst.pool, &dstMbuf)
+         != ROK)
+      {
+         RLOG0(L_ERROR, "SCpyMsgMsg Failed.");
+         RETVOID;
+      }
+      trc.cfm.status = LCM_PRIM_OK;
+      trc.cfm.reason = LCM_REASON_NOT_APPL;
+      trc.t.trc.evnt = event;
+         
+      /* Send Trace Indication to Layer manager */
+      RgMiLrgTrcInd(&pst, &trc, dstMbuf);
+   }
+   /* check if only a specified number of bytes are to be sent */
+   else if(rgCb[inst].trcLen > 0)
+   {
+      /* Get the length of the recvd message buffer */
+      if (SFndLenMsg(srcMbuf, &bufLen) != ROK)
+      {
+         RLOG0(L_ERROR, "SFndLenMsg Failed.");
+         RETVOID;
+      }
+      /* Check if the recvd buffer size is less than request trace len */
+      if(bufLen < rgCb[inst].trcLen)
+      {
+         /* Copy the whole of the recvd buffer in trace indication */
+      
+         if (SCpyMsgMsg(srcMbuf, pst.region, pst.pool, &dstMbuf)
+            != ROK)
+         {
+            RLOG0(L_ERROR, "SCpyMsgMsg Failed.");
+            RETVOID;
+         }
+         
+         trc.cfm.status = LCM_PRIM_OK;
+         trc.cfm.reason = LCM_REASON_NOT_APPL;
+         trc.t.trc.evnt = event;
+
+         /* Send Trace Indication to Layer manager */
+         RgMiLrgTrcInd(&pst, &trc, dstMbuf);
+      }
+      /* if the recvd buffer size is greater than request trace len */
+      if(bufLen >= rgCb[inst].trcLen)
+      {
+         /* Get a temporary buffer to store the msg */
+         if (rgAllocSBuf(inst,&tempBuf, rgCb[inst].trcLen) != ROK)
+         {
+            RLOG0(L_ERROR, "rgAllocSBuf Failed.");
+            RETVOID;
+         }
+         
+         /* Copy trcLen nos of bytes from the recvd message */
+         if (SCpyMsgFix(srcMbuf,0,rgCb[inst].trcLen,tempBuf,&tempCnt) != ROK)   
+         {
+            RLOG0(L_ERROR, "SCpyMsgFix Failed.");
+            RETVOID;
+         }
+
+         if (SGetMsg(pst.region, pst.pool, &dstMbuf) != ROK)
+         {
+            RLOG0(L_ERROR, "dstMbuf Allocation Failed");
+            RETVOID;
+         }
+         /* Copy the tempBuf data to dst mBuf */
+         if (SCpyFixMsg(tempBuf,dstMbuf,0,rgCb[inst].trcLen,&tempCnt) != ROK)
+         {
+            RLOG0(L_ERROR, "SCpyFixMsg Failed.");
+            RETVOID;
+         }
+
+         /*ccpu00117052 - MOD - Passing double pointer for proper NULLP 
+                               assignment */
+         /* Free the memory allocated for tempBuf */
+         rgFreeSBuf(inst,&tempBuf, rgCb[inst].trcLen);
+               
+         trc.cfm.status = LCM_PRIM_OK;
+         trc.cfm.reason = LCM_REASON_NOT_APPL;
+         trc.t.trc.evnt = event;
+      
+         /* Send Trace Indication to Layer manager */
+         RgMiLrgTrcInd(&pst, &trc, dstMbuf);
+      }
+   }
+   RETVOID;
+}
+
+
+/**
+ * @brief Layer Manager Control Confirm generation handler
+ *        for Bind Confirm reception at TFU interface.
+ *        RgLiTfuBndCfm() forwards the confirmation to this 
+ *        function. All SAP state related handling is restricted
+ *        to LMM modules, hence the cfm forwarding.
+ *
+ * @details
+ *
+ *     Function : rgLMMBndCfm 
+ *     
+ *     This API is used by the LIM module of MAC to forward
+ *     the Bind Confirm it receives over the TFU interface.
+ *     
+ *  @param[in]   Pst *pst, Post Structure
+ *  @param[in]   SuId suId, Service user ID
+ *  @param[in]   U8 status, Status
+ *  @return  S16
+ *      -# ROK
+ **/
+#ifdef ANSI
+PUBLIC S16 rgLMMBndCfm
+(
+Pst *pst,               /* Post Structure */
+SuId suId,              /* Service user ID */
+U8 status               /* Status */
+)
+#else
+PUBLIC S16 rgLMMBndCfm(pst,suId,status)
+Pst *pst;               /* Post Structure */
+SuId suId;              /* Service user ID */
+U8 status;              /* Status */
+#endif
+{
+   Inst      inst = pst->dstInst - RG_INST_START;
+   S16       ret = ROK;
+   RgMngmt   cntrlCfm;
+   Pst       cfmPst;
+
+   TRC3(rgLMMBndCfm)
+
+   UNUSED(pst);
+
+   /* Check if the suId is valid */
+   if(rgCb[inst].tfuSap.sapCfg.suId != suId)
+   {
+      RLOG0(L_ERROR, "Invalid SuId");
+      RETVALUE(RFAILED);
+   }
+
+   /* check the Sap State */
+   switch(rgCb[inst].tfuSap.sapSta.sapState)
+   {
+      case LRG_WAIT_BNDCFM:
+         break;
+      case LRG_BND:
+         /* SAP is already bound */
+         RETVALUE(ROK);
+      default:
+         RETVALUE(RFAILED);
+   }
+
+   cfmPst = rgCb[inst].rgInit.lmPst;
+   cfmPst.selector = rgCb[inst].genCfg.bndCfmResp.response.selector;
+   cfmPst.prior = rgCb[inst].genCfg.bndCfmResp.response.prior;
+   cfmPst.route = rgCb[inst].genCfg.bndCfmResp.response.route;
+   cfmPst.region = rgCb[inst].genCfg.bndCfmResp.response.mem.region;
+   cfmPst.pool = rgCb[inst].genCfg.bndCfmResp.response.mem.pool;
+   
+   cmMemset((U8 *)&cntrlCfm, 0, sizeof(RgMngmt));
+
+   switch(status)
+   {
+      case CM_BND_OK: /* status is OK */
+         /* Change SAP state to Bound */
+         rgCb[inst].tfuSap.sapSta.sapState = LRG_BND;
+         if (rgCb[inst].tfuSap.sapCfg.bndTmr.enb == TRUE)
+         {
+            ret = rgLMMStopTmr(inst,RG_BNDREQ_TMR, (PTR)&rgCb[inst].tfuSap);
+         }
+         /* Send Control Confirm with status as OK to Layer Manager */
+         cntrlCfm.cfm.status = LCM_PRIM_OK;
+         cntrlCfm.cfm.reason = LCM_REASON_NOT_APPL;
+         break;
+
+      default:
+         /* Change SAP state to UnBound */
+         rgCb[inst].tfuSap.sapSta.sapState = LRG_UNBND;
+         if (rgCb[inst].tfuSap.sapCfg.bndTmr.enb == TRUE)
+         {
+            ret = rgLMMStopTmr(inst,RG_BNDREQ_TMR, (PTR)&rgCb[inst].tfuSap);
+         }
+         /* Send Control Confirm with status as NOK to Layer Manager */
+         cntrlCfm.cfm.status = LCM_PRIM_NOK;
+         cntrlCfm.cfm.reason = LCM_REASON_NEG_CFM;
+         break;
+   }
+   rgCb[inst].tfuSap.numBndRetries = 0;
+   cntrlCfm.hdr.elmId.elmnt = STTFUSAP;
+   cntrlCfm.hdr.transId = rgCb[inst].genCfg.bndCfmResp.transId;
+
+   ret = RgMiLrgCntrlCfm(&cfmPst, &cntrlCfm);
+
+   RETVALUE(ret);
+}
+
+
+/**
+ * @brief LTE MAC timer call back function registered with SSI. 
+ *
+ * @details
+ *
+ *     Function :  rgActvTmr
+ *     
+ *     This function is invoked by SSI for every timer activation
+ *     period expiry.
+ *     
+ *  @return  S16
+ *      -# ROK
+ **/
+#ifdef ANSI
+PUBLIC S16 rgActvTmr
+(
+ Ent     ent,
+ Inst    inst
+)
+#else
+PUBLIC S16 rgActvTmr(ent, inst)
+Ent     ent;
+Inst    inst;
+#endif
+{
+   Inst macInst = (inst  - RG_INST_START);
+   TRC3(rgActvTmr)
+
+   /* Check if any MAC timer has expired */ 
+   cmPrcTmr(&rgCb[macInst].tmrTqCp, rgCb[macInst].tmrTq, (PFV) rgLMMTmrExpiry);
+ 
+   RETVALUE(ROK);
+ 
+} /* end of rgActvTmr */
+
+
+/**********************************************************************
+ 
+         End of file
+**********************************************************************/
diff --git a/src/5gnrmac/rg_mux.c b/src/5gnrmac/rg_mux.c
new file mode 100755
index 000000000..6849151d5
--- /dev/null
+++ b/src/5gnrmac/rg_mux.c
@@ -0,0 +1,1285 @@
+/*******************************************************************************
+################################################################################
+#   Copyright (c) [2017-2019] [Radisys]                                        #
+#                                                                              #
+#   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.                                             #
+################################################################################
+*******************************************************************************/
+
+/************************************************************************
+ 
+     Name:     LTE-MAC layer
+  
+     Type:     C source file
+  
+     Desc:     C source code for Entry point fucntions
+  
+     File:     rg_mux.c 
+  
+**********************************************************************/
+
+/** @file rg_mux.c
+@brief MAC Multiplexing API.
+*/
+
+static const char* RLOG_MODULE_NAME="MAC";
+static int RLOG_FILE_ID=229;
+static int RLOG_MODULE_ID=4096;
+
+/* header include files -- defines (.h) */
+#include "envopt.h"        /* environment options */
+#include "envdep.h"        /* environment dependent */
+#include "envind.h"        /* environment independent */
+  
+#include "gen.h"           /* general */
+#include "ssi.h"           /* system services */
+
+#include "cm_tkns.h"       /* Common Token Defines */
+#include "cm_llist.h"      /* Common Link List Defines */
+#include "cm_hash.h"       /* Common Hash List Defines */
+#include "cm_mblk.h"       /* memory management */
+#include "cm_lte.h"        /* Common LTE Defines */
+
+#include "rg_env.h"        /* MAC Environment Defines */
+#include "tfu.h"           /* TFU Interface defines */
+#include "crg.h"           /* CRG Interface defines */
+#include "rg_sch_inf.h"           /* RGR Interface defines */
+#include "rgu.h"           /* RGU Interface defines */
+#include "lrg.h"           /* LRG Interface defines */
+
+#include "rg_err.h"        /* MAC error defines */
+#include "rg.h"            /* MAC defines */
+
+/* header/extern include files (.x) */
+#include "gen.x"           /* general */
+#include "ssi.x"           /* system services */
+#include "cm5.x"           /* system services */
+#include "cm_tkns.x"       /* Common Token Definitions */
+#include "cm_llist.x"      /* Common Link List Definitions */
+#include "cm_lib.x"        /* Common Library Definitions */
+#include "cm_hash.x"       /* Common Hash List Definitions */
+#include "cm_mblk.x"       /* memory management */
+#include "cm_lte.x"        /* Common LTE Definitions */
+
+#include "rgu.x"           /* RGU Interface includes */
+#include "tfu.x"           /* CRG Interface includes */
+#include "crg.x"           /* CRG Interface includes */
+#include "rg_sch_inf.x"    /* SCH Interface includes */
+#include "rg_prg.x"        /* PRG Interface includes */
+#include "rgu.x"           /* RGU Interface includes */
+#include "lrg.x"           /* LRG Interface includes */
+
+#include "rg.x"            /* MAC includes */
+#include "ss_queue.h"
+#include "ss_queue.x"
+#include "ss_task.x"
+#include "ss_msg.x"            /* MAC includes */
+/* local defines */
+#ifndef T2K_MEM_LEAK_DBG
+EXTERN  S16 ssGetDBufOfSize(Region region,Size size,Buffer **dBuf);
+#else
+char* file = __FILE__;
+U32 line = __LINE__;
+#endif
+
+/* local typedefs */
+
+/* global variables */
+U32 rgDlrate_rgu;
+
+/* local externs */
+
+PRIVATE Void rgMUXGet20bitRarGrnt ARGS((U8 ulBw,
+                                        RgInfRarUlGrnt *msg3Grnt,
+                                        U8 *grnt));
+EXTERN U16 rgMUXCalcRiv ARGS((U8 bw,
+                                U8 rbStart,
+                                U8 numRb));
+ 
+#ifndef MS_MBUF_CORRUPTION
+#define MS_BUF_ADD_ALLOC_CALLER()
+#endif
+/* forward references */
+
+#define RG_PACK_SHDR_FIXD_SZ(_subHdr, _lcId, _mBuf, _ret) {\
+   _subHdr.shLen = RG_FIXDSZ_CE_SHDR_LEN;\
+   _subHdr.shData[0] = (0x3F & _lcId);\
+   MS_BUF_ADD_ALLOC_CALLER(); \
+   _ret = SAddPstMsgMult(&_subHdr.shData[0], _subHdr.shLen, _mBuf);\
+}
+
+#define RG_PACK_CE(_ce, _len, _ceBuf, _ret) {\
+   MS_BUF_ADD_ALLOC_CALLER(); \
+   _ret = SAddPstMsgMult((U8 *)(&(_ce)), _len, _ceBuf);\
+}
+
+#define RG_MUX_CALC_LEN(_len,_lenBytes,_elmTotLen) {\
+   U8 _hdrLen;\
+   _lenBytes    = (_len <= 255) ? 1 : 2;\
+   _hdrLen      = _lenBytes + RG_SDU_SHDR_LEN;\
+   _elmTotLen   = _hdrLen + _len;\
+}
+
+#define RG_PACK_VAR_SZ_CE_SDU_SHDR(_subHdr, _lcId, _len,_mBuf, _ret) {\
+   _ret = ROK;\
+   if(_len <= 255)\
+   {\
+      _subHdr.shData[0] = (0x3F & _lcId);\
+      _subHdr.shLen = 2;\
+      _subHdr.shData[1] = (0xFF & _len);\
+      _subHdr.shData[2] = 0;\
+   }\
+   else\
+   {\
+   _subHdr.shData[0] = (0x7F & ((0x40) | _lcId));\
+      _subHdr.shLen = 3;\
+      _subHdr.shData[1] = (0xFF & (_len >> 8));\
+      _subHdr.shData[2] = (0xFF & _len);\
+   }\
+   MS_BUF_ADD_ALLOC_CALLER(); \
+   _ret = SAddPstMsgMult(&_subHdr.shData[0], _subHdr.shLen, _mBuf);\
+}
+
+#define RG_PACK_PAD_SHDR(_mBuf, _ret) {\
+      _ret = SAddPreMsg(0x3F, _mBuf);\
+}
+
+#define RG_PACK_RAR_SHDR(_byte, _mBuf, _ret) {\
+   _ret = SAddPstMsg(_byte, _mBuf);\
+}
+
+
+/**
+ * @brief Function to add ces along with subhdrs.
+ * This function packs first CE sub-hdr and then CE in ceBuf pointer 
+ *
+ * @details
+ *
+ *     Function : rgMUXAddCes
+ *     
+ *  @param[in]  Inst        inst
+ *  @param[in] RgBldPduInfo   *pdu
+ *  @param[in] Buffer        *ceBuf 
+ *  @param[in] RgErrInfo     *err 
+ *  @return    S16
+ *      -# ROK 
+ *      -# RFAILED 
+ **/
+#ifdef ANSI
+PRIVATE S16 rgMUXAddCes
+(
+Inst           inst,
+RgBldPduInfo   *pdu,
+Buffer         *ceBuf,
+RgErrInfo      *err
+)
+#else
+PRIVATE S16 rgMUXAddCes(inst,pdu, ceShdrBuf, ceBuf, err)
+Inst           inst;
+RgBldPduInfo   *pdu;
+Buffer         *ceBuf;
+RgErrInfo      *err;
+#endif
+{
+   S16            ret;
+   RgMUXSubHdr    subHdr;
+
+   TRC2(rgMUXAddCes)
+
+   if (NULLP != pdu->contResId)
+   {
+      if(pdu->schdTbSz >= RG_CRES_ELM_LEN)
+      {
+         RG_PACK_SHDR_FIXD_SZ(subHdr, RG_CRES_LCID_IDX, ceBuf, ret);
+
+         if(ret != ROK)
+         {
+            err->errCause = RGERR_MUX_BLD_CEHDR_FAIL;
+            RLOG0(L_ERROR, "Muxing of Contention Resolution CE sub-header is failed");
+            RETVALUE(RFAILED);
+         }
+
+         RG_PACK_CE(pdu->contResId->resId[0], RG_CRES_LEN, ceBuf, ret);
+
+         if(ret != ROK)
+         {
+            err->errCause = RGERR_MUX_BLD_CE_FAIL;
+            RLOG0(L_ERROR, "Muxing of Contention Resolution CE is failed")
+            RETVALUE(RFAILED);
+         }
+         pdu->schdTbSz -= RG_CRES_ELM_LEN;
+      }
+   }
+   if (TRUE == pdu->ta.pres)
+   {
+      if(pdu->schdTbSz >= RG_TA_ELM_LEN)
+      {
+         U8 taVal; /* Moving from outer scope to available scope */
+         RG_PACK_SHDR_FIXD_SZ(subHdr, RG_TA_LCID_IDX, ceBuf, ret);
+
+         if(ret != ROK)
+         {
+            err->errCause = RGERR_MUX_BLD_CEHDR_FAIL;
+            RLOG0(L_ERROR, "Muxing of TA CE sub-hdr is failed")
+            RETVALUE(RFAILED);
+         }
+
+         taVal = pdu->ta.val;
+         RG_PACK_CE(taVal, RG_TA_LEN, ceBuf, ret);
+
+         if(ret != ROK)
+         {
+            err->errCause = RGERR_MUX_BLD_CE_FAIL;
+            RLOG0(L_ERROR, "Muxing of TA CE is failed")
+            RETVALUE(RFAILED);
+         }
+         pdu->schdTbSz -= RG_TA_ELM_LEN;
+         RLOG1(L_DEBUG,"TA muxed by MAC: %u", pdu->ta.val);
+      }
+   }
+#ifdef LTE_ADV
+   if(TRUE == pdu->sCellActCe.pres)
+   {
+      if(pdu->schdTbSz >= RG_SCELL_CE_ELM_LEN)
+      {
+         /* Adding the subheader for ACT CE */
+         RG_PACK_SHDR_FIXD_SZ(subHdr, RG_SCELL_LCID_IDX, ceBuf, ret);
+
+         if(ret != ROK)
+         {
+            err->errCause = RGERR_MUX_BLD_CEHDR_FAIL;
+            RLOG0(L_ERROR, "Muxing of SCELL Activation CE sub-hdr is failed")
+            RETVALUE(RFAILED);
+         }
+
+         /* Adding the ACT CE */
+         RG_PACK_CE(pdu->sCellActCe.val, RG_SCELL_ACT_CE_LEN, ceBuf, ret);
+
+         if(ret != ROK)
+         {
+            err->errCause = RGERR_MUX_BLD_CE_FAIL;
+            RLOG0(L_ERROR, "Muxing of SCELL Activation CE is failed")
+            RETVALUE(RFAILED);
+         }
+         pdu->schdTbSz -= RG_SCELL_CE_ELM_LEN;
+
+      }
+   }
+#endif
+  
+  /*LcId is not yet decided in 5G-NR spec for MAC CEs Hence, not writing code
+   * new MAC CEs. */
+
+   RETVALUE(ROK);
+} /* rgMUXAddCes */
+
+/**
+ * @brief Function to insert SDU along with sub headers.
+ *
+ * @details
+ *
+ *     Function : rgMUXInsSdu
+ *     
+ *  @param[in]       Inst        inst
+ *  @param[in]       MsgLen      *schdTbSz
+ *  @param[in]       U8          lcId
+ *  @param[in]       Buffer      *sdu
+ *  @param[out]      Buffer      *sduBuf 
+ *  @param[out]      RgErrInfo   *err 
+ *  @return    S16
+ *      -# ROK 
+ *      -# RFAILED
+ **/
+#ifdef ANSI
+PRIVATE S16 rgMUXInsSdu
+(
+Inst           inst,
+MsgLen         *schdTbSz,
+U8             lcId,
+Buffer         *sdu,
+Buffer         *sduBuf,
+RgErrInfo      *err
+)
+#else
+PRIVATE S16 rgMUXInsSdu(inst,schdTbSz, lcId, sdu, sduBuf, err)
+Inst           inst;
+MsgLen         *schdTbSz;
+U8             lcId;
+Buffer         *sdu;
+Buffer         *sduBuf;
+RgErrInfo      *err;
+#endif
+{
+   S16            ret;
+   MsgLen         msgLen = 0;
+   U8             lenBytes;
+   MsgLen         elmTotLen;
+
+   TRC2(rgMUXInsSdu)
+   SFndLenMsg(sdu, &msgLen);
+
+   RG_MUX_CALC_LEN(msgLen,lenBytes,elmTotLen);
+   
+   if (lcId == 3)
+   {
+     rgDlrate_rgu += msgLen; 
+   }
+   if (*schdTbSz >= elmTotLen)
+   {
+      RgMUXSubHdr    subHdr;
+      RG_PACK_VAR_SZ_CE_SDU_SHDR(subHdr, lcId, msgLen,sduBuf, ret);
+      if(ret != ROK)
+      {
+         err->errCause = RGERR_MUX_BLD_SDUHDR_FAIL;
+         RLOG1(L_ERROR, "RGERR_MUX_BLD_SDUHDR_FAIL for LCID:%d",lcId);
+         RETVALUE(RFAILED);
+      }
+
+#ifndef L2_OPTMZ /* no need to pack as passing not muxing all LCs PDUs to 1*/
+      RG_PACK_SDU(sduBuf, sdu, ret);
+#else
+  //UDAY
+      ret = ROK;
+      UNUSED(sduBuf);
+#endif
+
+      if(ret != ROK)
+      {
+         err->errCause = RGERR_MUX_BLD_SDU_FAIL;
+         RLOG1(L_ERROR, "RGERR_MUX_BLD_SDU_FAIL for LCID:%d",lcId);
+         RETVALUE(RFAILED);
+      }
+
+      *schdTbSz -= elmTotLen;
+   }
+   else
+   {
+      /* This Sub-PDU can not be accodmodated at all */
+      RLOG4(L_ERROR, "Failed lcId %u, elmTotLen %d lenBytes %d LCID:%d",
+               lcId, ((S16)elmTotLen), lenBytes,lcId);
+      RLOG3(L_ERROR, "msglen %d schdTbSz %d LCID:%d",
+               ((S16)msgLen), ((S16)*schdTbSz),lcId);
+      RETVALUE(RFAILED);
+   }
+   RETVALUE(ROK);
+}
+
+/**
+ * @brief Function to insert SDU along with sub headers.
+ *
+ * @details
+ *
+ *     Function : rgMUXAddPadd
+ *     
+ *  @param[in]  Inst        inst
+ *  @param[in]       RgBldPduInfo   *pdu
+ *  @param[out]      Buffer        *mBuf 
+ *  @param[out]      Buffer        *sduBuf 
+ *  @return    S16
+ *      -# ROK 
+ *      -# RFAILED
+ **/
+#ifdef L2_OPTMZ
+U32 padSize = 0;
+#endif
+#ifdef ANSI
+PUBLIC S16 rgMUXAddPadd
+(
+Inst           inst,
+MsgLen         *schdTbSz,
+Buffer         *sduBuf,
+Bool           isRar,
+RgErrInfo      *err
+)
+#else
+PUBLIC S16 rgMUXAddPadd(inst,schdTbSz, sduBuf, isRar, err)
+Inst           inst;
+MsgLen         *schdTbSz;
+Buffer         *sduBuf;
+Bool           isRar;
+RgErrInfo      *err;
+#endif
+{
+   S16     ret = ROK;
+   Buffer         *padBuf = NULLP;
+   RgMUXSubHdr    subHdr;
+   TRC2(rgMUXAddPadd)
+
+#ifdef L2_OPTMZ
+   padSize = 0;
+#endif
+   if(*schdTbSz)
+   {
+#ifndef L2_OPTMZ
+      if(FALSE == isRar)
+#else
+      if((FALSE == isRar) && (NULL != sHdrBuf))
+#endif
+
+      {
+         RG_PACK_SHDR_FIXD_SZ(subHdr, RG_PAD_LCID_IDX, sduBuf, ret);  
+
+         if(ret != ROK)
+         {
+            err->errCause = RGERR_MUX_BLD_PADHDR_FAIL;
+            RLOG0(L_ERROR, "RGERR_MUX_BLD_PADHDR_FAIL");
+            RETVALUE(RFAILED);
+         }
+
+         *schdTbSz -= 1;
+      }
+
+      if (*schdTbSz)
+      {
+         if (*schdTbSz <= RG_MAX_PAD_ARR_SZ)
+         {
+#ifndef L2_OPTMZ
+            RG_PACK_PAD(padBuf,*schdTbSz,sduBuf);
+#else
+            if(sduBuf)
+            {
+               RG_PACK_PAD(padBuf,*schdTbSz,sduBuf);
+            }
+            else
+               padSize += *schdTbSz;
+#endif
+            if(ret != ROK)
+            {
+               err->errCause = RGERR_MUX_BLD_PAD_FAIL;
+               RLOG0(L_ERROR, "RGERR_MUX_BLD_PAD_FAIL");
+               RETVALUE(RFAILED);
+            }
+            *schdTbSz = 0;
+         }
+         else
+         {
+            while (*schdTbSz)
+            {
+               if (*schdTbSz > RG_MAX_PAD_ARR_SZ)
+               {
+#ifndef L2_OPTMZ
+                  RG_PACK_PAD(padBuf,RG_MAX_PAD_ARR_SZ,sduBuf);
+#else
+                  if(sduBuf)
+                  {
+                     RG_PACK_PAD(padBuf,RG_MAX_PAD_ARR_SZ,sduBuf);
+                  }
+                  else
+                     padSize += RG_MAX_PAD_ARR_SZ;
+#endif
+
+                  if(ret != ROK)
+                  {
+                     err->errCause = RGERR_MUX_BLD_PAD_FAIL;
+                     RLOG0(L_ERROR, "RGERR_MUX_BLD_PAD_FAIL");
+                     RETVALUE(RFAILED);
+                  }
+
+                  *schdTbSz -= RG_MAX_PAD_ARR_SZ;
+               }
+               else
+               {
+#ifndef L2_OPTMZ
+                  RG_PACK_PAD(padBuf,*schdTbSz,sduBuf);
+#else
+                  if(sduBuf)
+                  {
+                     RG_PACK_PAD(padBuf,*schdTbSz,sduBuf);
+                  }
+                  else
+                     padSize += *schdTbSz;
+#endif
+
+                  if(ret != ROK)
+                  {
+                     err->errCause = RGERR_MUX_BLD_PAD_FAIL;
+                     RLOG0(L_ERROR, "RGERR_MUX_BLD_PAD_FAIL");
+                     RETVALUE(RFAILED);
+
+                  }
+                  *schdTbSz = 0;
+               }
+            }
+         }
+      }
+   }
+
+   RETVALUE(ROK);
+} /* rgMUXAddPadd */
+
+#ifndef L2_OPTMZ
+/**
+ * @brief Function to add SDU along with sub headers.
+ *
+ * @details
+ *
+ *     Function : rgMUXAddSdus
+ *     
+ *  @param[in]  Inst        inst
+ *  @param[in]       RgBldPduInfo   *pdu
+ *  @param[out]      Buffer        *mBuf 
+ *  @param[out]      Buffer        *sduBuf 
+ *  @return    S16
+ *      -# ROK 
+ *      -# RFAILED
+ **/
+#ifdef ANSI
+PRIVATE S16 rgMUXAddSdus
+(
+Inst           inst,
+RgBldPduInfo   *pdu,
+Buffer         *sduBuf,
+RgErrInfo      *err
+)
+#else
+PRIVATE S16 rgMUXAddSdus(inst,pdu, sduBuf, err)
+Inst           inst;
+RgBldPduInfo   *pdu;
+Buffer         *sduBuf;
+RgErrInfo      *err;
+#endif
+{
+   RgRguDDatReqPerUe *dDatReq;
+   RgRguCmnDatReq    *cDatReq;
+
+   TRC2(rgMUXAddSdus)
+
+   switch(pdu->reqType)
+   {
+      case EVTRGUCDATREQ:
+         cDatReq = (RgRguCmnDatReq *)(pdu->datReq);
+         /* Add sdu(s) to the Message Buffer */
+         if (NULLP != cDatReq)
+         {
+            if(rgMUXInsSdu(inst,&pdu->schdTbSz, 
+                     RG_CCCH_LCID, cDatReq->pdu, sduBuf, err) != ROK)
+            {
+               RETVALUE(RFAILED);
+            }
+            RG_FREE_MSG(cDatReq->pdu);
+         }
+         break;
+
+      case EVTRGUDDATREQ:
+         dDatReq = (RgRguDDatReqPerUe *)(pdu->datReq);
+         /* Add sdu(s) to the Message Buffer */
+         if (NULLP != dDatReq)
+         {
+            if(pdu->tbIndex == 1)
+            {
+               U16 idx1, idx2;
+               /* Adding this temporary variable for optimization */
+               RguDatReqTb *datReqTb = &dDatReq->datReqTb[0];
+
+               for (idx1=0; (idx1 < datReqTb->nmbLch); idx1++)
+               {
+                  for(idx2=0;
+                     (idx2 < datReqTb->lchData[idx1].pdu.numPdu);
+                     idx2++)
+                  {
+                     if(pdu->schdTbSz)
+                     {
+                        if(rgMUXInsSdu(inst,&pdu->schdTbSz,
+                           datReqTb->lchData[idx1].lcId, 
+                           datReqTb->lchData[idx1].pdu.mBuf[idx2],
+                           sduBuf, err) != ROK)
+                        {
+                           RLOG1(L_ERROR, "FAILED for LCID:%d",datReqTb->lchData[idx1].lcId);
+                           RETVALUE(RFAILED);
+                        }
+                     }
+                     RG_FREE_MSG(datReqTb->lchData[idx1].pdu.mBuf[idx2]);
+                  }
+               }
+            }
+            else if(pdu->tbIndex == 2)
+            {
+               U16 idx1, idx2;
+               RguDatReqTb *datReqTb = &dDatReq->datReqTb[1];
+               for (idx1=0; (idx1 < datReqTb->nmbLch); idx1++)
+               {
+                  for(idx2=0;
+                     (idx2 < datReqTb->lchData[idx1].pdu.numPdu);
+                     idx2++)
+                  {
+                     if(pdu->schdTbSz)
+                     {
+                        if(rgMUXInsSdu(inst,&pdu->schdTbSz,
+                           datReqTb->lchData[idx1].lcId, 
+                           datReqTb->lchData[idx1].pdu.mBuf[idx2],
+                           sduBuf, err) != ROK)
+                        {
+                           RLOG2(L_ERROR, "FAILED TB Size %d LCID:%d",
+                                    ((S16)pdu->schdTbSz),datReqTb->lchData[idx1].lcId);
+                           RETVALUE(RFAILED);
+                        }
+                     }
+                     RG_FREE_MSG(datReqTb->lchData[idx1].pdu.mBuf[idx2]);
+                  }
+               }
+            }
+         }
+         break;
+
+      case EVTTFUTTIIND:
+         break;
+      default:
+         break;
+   } /* End of switch(reqType) */
+   if(rgMUXAddPadd(inst,&pdu->schdTbSz, sduBuf, FALSE, err) != ROK)
+   {
+      RLOG1(L_ERROR, "FAILED for TB Size:%d",(S16)pdu->schdTbSz);
+      RETVALUE(RFAILED);
+   }
+   RETVALUE(ROK);
+}
+
+/**
+ * @brief Function to create MAC PDU from RLC SDUs and control elements, if any. 
+ *
+ * @details
+ *
+ *     Function : rgMUXBldPdu
+ *     
+ *     -# This function shall be invoked by Downlink Harq Module as soon as a
+ *        Data request is received from RLC for a UE along with its stored 
+ *        control elements to create a MAC PDU.
+ *     -# It shall create subheaders for the control elements (timing advance
+ *        and contention resolution ID) and pack sub-header before each CE,
+ *        if given, and then shall run through all the logical channels and
+ *        create subheader for each of the SDUs given on that logical channel
+ *        and pack corresponding sub-header before the each SDU 
+ *     -# It shall invoke rgMUXPadPdu if the total length of the created 
+ *        buffer is less than the scheduled TB size. 
+ *     
+ *           
+ *  @param[in]  Inst           *inst
+ *  @param[in]  RgBldPduInfo   *bldPdu
+ *  @param[in]  Buffer         **txPdu
+ *  @param[out] RgErrInfo      *err
+ *  @return  S16
+ *      -# ROK 
+ *      -# RFAILED 
+ **/
+#ifdef ANSI
+PUBLIC S16 rgMUXBldPdu
+(
+Inst           inst,
+RgBldPduInfo   *pdu,
+Buffer         **txPdu,
+RgErrInfo      *err
+)
+#else
+PUBLIC S16 rgMUXBldPdu(inst, pdu, txPdu, err)
+Inst           inst;
+RgBldPduInfo   *pdu;
+Buffer         **txPdu;
+RgErrInfo      *err;
+#endif
+{
+   Buffer         *mBuf = NULLP;
+
+   TRC2(rgMUXBldPdu)
+
+ 
+   if (rgGetMsg(inst, &mBuf) != ROK)
+   {
+      /* Buffer couldnt get allocated. Return a failure */
+      err->errCause = RGERR_MUX_MEM_ALLOC_FAIL;
+      err->errType = RGERR_MUX_BLD_PDU;
+      RLOG1(L_FATAL, "Memory allocation failed during MUXing of MAC TB: MacInst %d", inst);
+      RETVALUE(RFAILED);
+   }
+
+   if(rgMUXAddCes(inst, pdu, mBuf, err) != ROK)
+   {
+      RG_FREE_MSG(mBuf);
+      err->errType = RGERR_MUX_BLD_PDU;
+      RLOG1(L_ERROR, "Failed to Multiplex MAC CEs: MacInst %d", inst);
+      RETVALUE(RFAILED);
+   }
+
+   if(rgMUXAddSdus(inst, pdu, mBuf, err) != ROK)
+   {
+      RG_FREE_MSG(mBuf);
+      err->errType = RGERR_MUX_BLD_PDU;
+      RLOG1(L_ERROR, "FAILED to Multiplex MAC SDU: MacInst %d", inst);
+      RETVALUE(RFAILED);
+   }
+
+   *txPdu = mBuf;
+
+   RETVALUE(ROK);
+
+}  /* rgMUXBldPdu */
+
+#else /* else of ifndef L2_OPTMZ */
+
+/**
+ * @brief Function to add SDU along with sub headers.
+ *
+ * @details
+ *
+ *     Function : rgMUXAddSdus
+ *     
+ *  @param[in]       RgBldPduInfo   *pdu
+ *  @param[out]      Buffer        *mBuf 
+ *  @param[out]      Buffer        *sduBuf 
+ *  @return    S16
+ *      -# ROK 
+ *      -# RFAILED
+ **/
+#ifdef ANSI
+PRIVATE S16 rgMUXAddSdus
+(
+Inst                inst,
+RgBldPduInfo        *pdu,
+Buffer              *sHdrBuf,
+RgTfuDatReqTbInfo   *tb,
+RgErrInfo           *err
+)
+#else
+PRIVATE S16 rgMUXAddSdus(pdu, sHdrBuf, tb, err)
+Inst                inst;
+RgBldPduInfo        *pdu;
+Buffer              *sHdrBuf;
+RgTfuDatReqTbInfo   *tb;
+RgErrInfo           *err;
+#endif
+{
+   RgRguDDatReqPerUe  *dDatReq;
+   RgRguCmnDatReq     *cDatReq;
+   U32 lchIdx, pduIdx;
+
+   TRC2(rgMUXAddSdus)
+
+   switch(pdu->reqType)
+   {
+      case EVTRGUCDATREQ:
+         cDatReq = (RgRguCmnDatReq *)(pdu->datReq);
+         /* Add sdu(s) to the Message Buffer */
+         if (NULLP != cDatReq)
+         {
+            if(rgMUXInsSdu(inst, &pdu->schdTbSz, 
+                     RG_CCCH_LCID, cDatReq->pdu, 
+                     sHdrBuf, NULLP, err) != ROK)
+            {
+               RETVALUE(RFAILED);
+            }
+            /* L2 Optimization for mUe/Tti: RLC pdu mbuf pointer will be passed
+             * to CL it is stored in DlHqProc->TbInfo and it will be used in
+             * case of harq retransmission. Store CCCH data at 0th index of
+             * lch array*/
+            tb->lchInfo[tb->numLch].mBuf[(tb->lchInfo[tb->numLch].numPdu)]\
+               = cDatReq->pdu;
+            tb->lchInfo[tb->numLch].numPdu++;
+            tb->numLch++;
+           RLOG3(L_INFO,"MSG4 is muxed  numLch=%ld numPdu=%ld tbaddr =%p", tb->numLch,tb->lchInfo[tb->numLch-1].numPdu, (U32)tb);
+         }
+         break;
+
+      case EVTRGUDDATREQ:
+         dDatReq = (RgRguDDatReqPerUe *)(pdu->datReq);
+         /* Add sdu(s) to the Message Buffer */
+         if (NULLP != dDatReq)
+         {
+            if(pdu->tbIndex == 1)
+            {
+               U16 idx1, idx2;
+               /* Adding this temporary variable for optimization */
+               RguDatReqTb *datReqTb = &dDatReq->datReqTb[0];
+             
+               tb->numLch = lchIdx = 0;
+
+               for (idx1=0; (idx1 < datReqTb->nmbLch); idx1++)
+               {
+                  tb->lchInfo[lchIdx].numPdu = pduIdx = 0;
+
+                  for(idx2=0;
+                     (idx2 < datReqTb->lchData[idx1].pdu.numPdu);
+                     idx2++)
+                  {
+                     if(pdu->schdTbSz)
+                     {
+                        if(rgMUXInsSdu(inst, &pdu->schdTbSz,
+                           datReqTb->lchData[idx1].lcId, 
+                           datReqTb->lchData[idx1].pdu.mBuf[idx2],
+                           sHdrBuf, NULLP, err) != ROK)
+                        {
+                           RGDBGERRNEW(inst,(rgPBuf(inst), "FAILED\n"));
+                           RETVALUE(RFAILED);
+                        }
+
+                        /* L2 Optimization for mUe/Tti:Increment numPdu by 1
+                         * Store pdu buffer in tb to send it to CL/PHY. Increment
+                         * numPdu by 1*/
+                        tb->lchInfo[lchIdx].mBuf[pduIdx] = datReqTb->lchData[idx1].pdu.mBuf[idx2];
+
+#ifdef L2_OPTMZ
+                        if(datReqTb->lchData[idx1].freeBuff == FALSE)
+                        {/* Not incrementing refCnt for UM Mode. */
+                           tb->lchInfo[lchIdx].mBuf[pduIdx]->refCnt++;
+                        }
+#endif
+//UDAY 
+                        if(NULL != datReqTb->lchData[idx1].pdu.mBuf[idx2]->b_cont)
+                        {
+                             Buffer *tmp;
+                             tmp = datReqTb->lchData[idx1].pdu.mBuf[idx2]->b_cont;
+                             if(NULL == tmp->b_rptr)
+                             {
+                                RLOG0(L_INFO,"11111Its Null here only ");
+                             }
+                        }
+                        else
+                        {
+                            RLOG0(L_INFO,"222222Its Null here only \n");
+                        }
+                        pduIdx++;
+                        //tb->lchInfo[tb->numLch].numPdu++;
+                        //tb->numLch++;
+
+                    }
+                  }
+                  
+                  if(pduIdx)
+                  {
+                    tb->lchInfo[lchIdx].numPdu = pduIdx;
+                    /* If Bearer is UM then MBUF to be free by MAC layer */
+                    tb->lchInfo[lchIdx].freeBuff = datReqTb->lchData[idx1].freeBuff;
+                    lchIdx++;
+                  }
+               }
+               tb->numLch = lchIdx;
+            }
+            else if(pdu->tbIndex == 2)
+            {
+               U16 idx1, idx2;
+               RguDatReqTb *datReqTb = &dDatReq->datReqTb[1];
+               tb->numLch = lchIdx = 0;
+         //      prc_trace_format_string(0x40,3,": AddSdus: numOfLch=%d numOfPdu=%d, schdSz=%d", datReqTb->nmbLch, datReqTb->lchData[0].pdu.numPdu, pdu->schdTbSz);
+              for (idx1=0; (idx1 < datReqTb->nmbLch); idx1++)
+               {
+                 tb->lchInfo[lchIdx].numPdu = pduIdx = 0;
+                 for(idx2=0;
+                     (idx2 < datReqTb->lchData[idx1].pdu.numPdu);
+                     idx2++)
+                  {
+                     if(pdu->schdTbSz)
+                     {
+                        if(rgMUXInsSdu(inst, &pdu->schdTbSz,
+                           datReqTb->lchData[idx1].lcId, 
+                           datReqTb->lchData[idx1].pdu.mBuf[idx2],
+                           sHdrBuf, NULLP, err) != ROK)
+                        {
+                           RGDBGERRNEW(inst,(rgPBuf(inst), "FAILED TB Size %d\n",
+                                    ((S16)pdu->schdTbSz)));
+                           RETVALUE(RFAILED);
+                        }
+                         /* L2 Optimization for mUe/Tti:Increment numPdu by 1
+                         * Store pdu buffer in tb to send it to CL/PHY. Increment
+                         * numPdu by 1*/
+                        tb->lchInfo[lchIdx].mBuf[pduIdx] = datReqTb->lchData[idx1].pdu.mBuf[idx2];
+#ifdef L2_OPTMZ
+                        if(datReqTb->lchData[idx1].freeBuff == FALSE)
+                        {/* Not incrementing refCnt for UM Mode. */
+                           tb->lchInfo[lchIdx].mBuf[pduIdx]->refCnt++;
+                        }
+#endif
+                        if(NULL != datReqTb->lchData[idx1].pdu.mBuf[idx2]->b_cont)
+                        {
+                             Buffer *tmp;
+                             tmp = datReqTb->lchData[idx1].pdu.mBuf[idx2]->b_cont;
+                             if(NULL == tmp->b_rptr)
+                             {
+                                RLOG0(L_INFO,"2212121Its Null here only \n");
+                             }
+                        }
+                        else
+                        {
+                            RLOG0(L_INFO,"343343433ts Null here only \n");
+                        }
+                        pduIdx++;
+                       // tb->lchInfo[tb->numLch].numPdu++;
+                       // tb->numLch++;
+
+                     }
+                  }
+
+                  if(pduIdx)
+                  {
+                    tb->lchInfo[lchIdx].numPdu = pduIdx;
+                    /* If Bearer is UM then MBUF to be free by MAC layer */
+                    tb->lchInfo[lchIdx].freeBuff = datReqTb->lchData[idx1].freeBuff;
+                    lchIdx++;
+                  }
+               }
+
+               tb->numLch = lchIdx;
+           }
+         }
+         break;
+
+      case EVTTFUTTIIND:
+         break;
+      default:
+         break;
+   } /* End of switch(reqType) */
+
+   
+   if(rgMUXAddPadd(inst, &pdu->schdTbSz, sduBuf, NULLP, FALSE, err) != ROK)
+   {
+      //RGDBGERRNEW((rgPBuf, "FAILED"));
+      RETVALUE(RFAILED);
+   }
+   tb->padSize = padSize;
+
+   RETVALUE(ROK);
+}
+
+/**
+ * @brief Function to create MAC PDU from RLC SDUs and control elements, if any. 
+ *
+ * @details
+ *
+ *     Function : rgMUXBldPdu
+ *     -# This function shall be invoked by Downlink Harq Module as soon as a
+ *        Data request is received from RLC for a UE along with its stored 
+ *        control elements to create a MAC PDU.
+ *     -# It shall create subheaders for the control elements (timing advance
+ *        and contention resolution ID), if given, and then shall run through
+ *        all the logical channels and create subheader for each of the SDUs
+ *        given on that logical channel.
+ *     -# L2 Optimization for mUe/Tti: Avoiding muxing to reduce overhead of 
+ *           additional Mbuf allocation memory related operation.
+       -# MAC header, MAC CEs, MAC PDUs and MAC padding are stored in pre-
+            allocated mBufs. These pointers will not be freed by CL    
+ *     -# It shall invoke rgMUXPadPdu if the total length of the created 
+ *        buffer is less than the scheduled TB size.
+ *     -# At successfull operation of this function tb->macHdr, will have
+ *        complete MAC Header. tb->macCes will have MAC CEs if any. tb->
+ *        lchInfo[idx].mBuf[idx] will have MAC SDU per LCH per TB per UE 
+ *     
+ *           
+ *  @param[in]  RgBldPduInfo   *bldPdu
+ *  @param[out] RgTbInfo       *tb
+ *  @param[out] RgErrInfo      *err
+ *  @return  S16
+ *      -# ROK 
+ *      -# RFAILED 
+ **/
+#ifdef ANSI
+PUBLIC S16 rgMUXBldPdu
+(
+Inst               inst,
+RgBldPduInfo       *pdu,
+RgTfuDatReqTbInfo  *tb,
+RgErrInfo          *err
+)
+#else
+PUBLIC S16 rgMUXBldPdu(inst, pdu, tb, err)
+Inst               inst;
+RgBldPduInfo       *pdu;
+RgTfuDatReqTbInfo  *tb;
+RgErrInfo          *err;
+#endif
+{
+   Buffer         *mBuf1; /* MAC hearder */
+   Buffer         *mBuf2; /* MAC CEs */
+   //U32            lchIdx, pduIdx;
+
+   TRC2(rgMUXBldPdu)
+   
+  /* Reseting macHdr and macCes pointers */
+  if(tb->macHdr)
+   SResetMBuf(tb->macHdr);
+   if(tb->macCes)
+   SResetMBuf(tb->macCes);
+   
+   mBuf1 = tb->macHdr; /* MAC hearder */
+   mBuf2 = tb->macCes; /* MAC CEs */
+   tb->tbSize  = pdu->schdTbSz;
+
+   if(rgMUXAddCes(inst, pdu, mBuf1, mBuf2, err) != ROK)
+   {
+      /* Reset rPtr and wPtr to the base of data buffer(db_base)*/
+      RLOG0(L_INFO,"rgMUXBldPdu: rgMUXAddCes is Failed \n");
+      RG_FREE_TB(tb);
+      err->errType = RGERR_MUX_BLD_PDU;
+      //RGDBGERRNEW((rgPBuf, "FAILED"));
+      RETVALUE(RFAILED);
+   }
+   if(rgMUXAddSdus(inst, pdu, mBuf1, tb, err) != ROK)
+   {
+      /*TODO:MP Reset rPtr and wPtr to the base of data buffer(db_base)
+       * Reset numLch and numPdu to zero and set MAC SDU buf to NULLP */
+      RLOG0(L_INFO, "rgMUXBldPdu: rgMUXAddSdus is Failed \n");
+      RG_FREE_TB(tb);
+
+      err->errType = RGERR_MUX_BLD_PDU;
+      //RGDBGERRNEW((rgPBuf, "FAILED"));
+      RETVALUE(RFAILED);
+   }
+// UDAY 
+//      SPrntMsg(tb->macHdr, 0, 0);
+//   prc_trace_format_string(0x40,3,": padSize=%ld", tb->padSize);
+
+   tb->tbPres = TRUE;
+   RETVALUE(ROK);
+
+}  /* rgMUXBldPdu */
+
+#endif /* end of L2_OPTMZ */
+
+/**
+ * @brief Function to create RAR PDU. 
+ *
+ * @details
+ *
+ *     Function : rgMUXBldRarPdu
+ *                This function is used to build RAR PDUs and is being 
+ *                invoked by the scheduler.
+ *     
+ *  @param[out]RgCellCb       *cellCb
+ *  @param[in] RgRaRspAlloc   *bldPdu
+ *  @param[in] Buffer         **txPdu 
+ *  @param[out] RgErrInfo     *err
+ *  @return    S16
+ *      -# ROK 
+ *      -# RFAILED 
+ **/
+#ifdef ANSI
+PUBLIC S16 rgMUXBldRarPdu
+(
+RgCellCb        *cell,
+RgInfRaRntiInfo *alloc,
+Buffer          **txPdu,
+RgErrInfo       *err
+)
+#else
+PUBLIC S16 rgMUXBldRarPdu(cell, alloc, txPdu, err)
+RgCellCb        *cell;
+RgInfRaRntiInfo *alloc;
+Buffer          **txPdu;
+RgErrInfo       *err;
+#endif
+{
+   Buffer      *datBuf = NULLP;
+   S16         ret; 
+   U8          data[RG_RAR_ELEM_LEN];
+   U8          hdrByte;
+   MsgLen      schdTbSz;
+   U8          idx;
+   Inst        inst = cell->macInst - RG_INST_START;
+
+   TRC2(rgMUXBldRarPdu)
+
+   schdTbSz = alloc->schdTbSz;
+   /* RAR PDU Requirements */
+   /*
+   1. SubHeader - R/T/RAPID. //5GNR, changed E to R
+   2. TA ( if applicable)
+   3. Ul Grant:
+         a. Hopping Flag - 1 Bit.
+         b. Fixed Size RB Assignment. - 10 Bits.
+         c. Truncated Modulation and coding scheme - 4 Bits.
+         d. TPC command for scheduled PUSCH. - 3 Bits.
+         e. UL Delay - 1 Bit.
+         f. CQI Request - 1 Bit.
+   4. Temporary Crnti.
+   */
+
+   /* Initialize the error type */
+   err->errType = RGERR_MUX_BLD_RAR_PDU;
+  
+   if ((ret = rgGetMsg(inst,&datBuf)) != ROK)
+   {
+      /* Buffer couldnt get allocated. Return a failure */
+      err->errCause = RGERR_MUX_MEM_ALLOC_FAIL;
+      RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId, "FAILED to getMsg");
+      RETVALUE(RFAILED);
+   }
+
+   if (TRUE == alloc->backOffInd.pres)
+   {
+      /*Set T Bit , NO E bit Required */
+      hdrByte = 0x00;
+      /* Add the bi */
+      hdrByte |= (0x0F & (alloc->backOffInd.val));
+
+      /* Add the header */
+      RG_PACK_RAR_SHDR(hdrByte, datBuf, ret);
+      if(ret != ROK)
+      {
+         err->errCause = RGERR_MUX_BLD_BI_FAIL;
+         RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,"RGERR_MUX_BLD_BI_FAIL");
+         RG_FREE_MSG(datBuf);
+         RETVALUE(RFAILED);
+      }
+      schdTbSz--;
+   }
+
+   for (idx=0; idx < (alloc->numCrnti) && 
+         (schdTbSz >= RG_RAR_ELEM_LEN+RG_RAR_SHDR_LEN); idx++)
+   {
+      /* Add the tBit */
+      hdrByte = 0x40; 
+      /* Add the rapId */
+      hdrByte |= (0x3F & (alloc->crntiInfo[idx].rapId));
+
+         /* Add the header */
+         RG_PACK_RAR_SHDR(hdrByte, datBuf, ret);
+         if(ret != ROK)
+         {
+            err->errCause = RGERR_MUX_BLD_RAPIDHDR_FAIL;
+            RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,"RGERR_MUX_BLD_RAPIDHDR_FAIL");
+            RG_FREE_MSG(datBuf);
+            RETVALUE(RFAILED);
+         }
+
+      /* Prepare the data */
+      data[0]  =  0x7F & ((alloc->crntiInfo[idx].ta.val) >> 4);
+      data[1] = 0;
+      data[2] = 0;
+      data[3] = 0;
+      {    
+         rgMUXGet20bitRarGrnt(cell->bwCfg.ulTotalBw, &(alloc->crntiInfo[idx].grnt), &data[1]);
+      }
+      data[1] |=  ((U8)((alloc->crntiInfo[idx].ta.val) << 4));
+      data[4]  =  (alloc->crntiInfo[idx].tmpCrnti) >> 8;
+      data[5]  =  (U8) (alloc->crntiInfo[idx].tmpCrnti);
+
+      RLOG_ARG2(L_DEBUG,DBG_CELLID,cell->cellId,
+         		"Rar,Rapid=%d, Temp CRNTI:%d", 
+                alloc->crntiInfo[idx].rapId,
+                alloc->crntiInfo[idx].tmpCrnti);
+     MS_BUF_ADD_ALLOC_CALLER();
+      if(SAddPstMsgMult(&data[0], RG_RAR_ELEM_LEN, datBuf) != ROK)
+      {
+         err->errCause = RGERR_MUX_BLD_RAPID_FAIL;
+         RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,"RGERR_MUX_BLD_RAPID_FAIL");
+         RG_FREE_MSG(datBuf);
+         RETVALUE(RFAILED);
+      }
+      schdTbSz -= RG_RAR_ELEM_LEN+RG_RAR_SHDR_LEN;
+   }
+
+   if(rgMUXAddPadd(inst,&schdTbSz, datBuf, TRUE, err) != ROK)
+   {
+      RG_FREE_MSG(datBuf);
+      RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,"FAILED to mux add padding");
+      RETVALUE(RFAILED);
+   }
+
+   *txPdu = datBuf;
+
+   RETVALUE(ROK);
+} /* rgMUXBldRarPdu */
+
+/***********************************************************
+ *
+ *     Func : rgMUXGet20bitRarGrnt
+ *
+ *     Desc : This function fills up the 20-bit grant
+ *            for RA response.
+ *
+ *     Ret  : None.
+ *
+ *     Notes: None.
+ *
+ *     File : rg_mux.c
+ *
+ **********************************************************/
+#ifdef ANSI
+PRIVATE Void rgMUXGet20bitRarGrnt
+(
+U8             ulBw,
+RgInfRarUlGrnt *msg3Grnt,
+U8             *grnt
+)
+#else
+PRIVATE Void rgMUXGet20bitRarGrnt(ulBw, msg3Grnt, grnt)
+U8             ulBw;
+RgInfRarUlGrnt *msg3Grnt;
+U8             *grnt;
+#endif
+{
+   U16       riv = rgMUXCalcRiv(ulBw, msg3Grnt->rbStart, msg3Grnt->numRb);
+
+   TRC2(rgMUXGet20bitRarGrnt);
+
+   grnt[2]  = msg3Grnt->cqiBit;   /* cqi bit is 0, output from sched */
+   grnt[2] |= (msg3Grnt->delayBit << 1);
+   grnt[2] |= (msg3Grnt->tpc << 2);
+   grnt[2] |= (msg3Grnt->iMcsCrnt << 5);
+
+   grnt[1]  = (msg3Grnt->iMcsCrnt >> 3);
+   /* Forcing right shift to insert 0 as the LSB: 
+    * since this is assumed in the computation */
+   grnt[1] |= (U8)((riv << 1) & 0xFE);
+
+   grnt[0]  = (U8)((riv >> 7) & 0x07);
+   grnt[0] |= ((msg3Grnt->hop & 0x01) << 3);
+
+   RETVOID;
+} /* rgMUXGet20bitRarGrnt */
+
+/***********************************************************
+ *
+ *     Func : rgMUXCalcRiv
+ *
+ *     Desc : This function calculates RIV.
+ *
+ *     Ret  : None.
+ *
+ *     Notes: None.
+ *
+ *     File : rg_mux.c
+ *
+ **********************************************************/
+#ifdef ANSI
+PUBLIC U16 rgMUXCalcRiv
+(
+U8           bw,
+U8           rbStart,
+U8           numRb
+)
+#else
+PUBLIC U16 rgMUXCalcRiv(bw, rbStart, numRb)
+U8           bw;
+U8           rbStart;
+U8           numRb;
+#endif
+{
+   U8           numRbMinus1 = numRb - 1;
+   U16          riv;
+
+   TRC2(rgMUXCalcRiv);
+
+   if (numRbMinus1 <= bw/2)
+   {
+      riv = bw * numRbMinus1 + rbStart;
+   }
+   else
+   {
+      riv = bw * (bw - numRbMinus1) + (bw - rbStart - 1);
+   }
+   RETVALUE(riv);
+} /* rgMUXCalcRiv */
+
+
+
+/**********************************************************************
+ 
+         End of file
+**********************************************************************/
diff --git a/src/5gnrmac/rg_pom_scell.c b/src/5gnrmac/rg_pom_scell.c
new file mode 100755
index 000000000..dda848f51
--- /dev/null
+++ b/src/5gnrmac/rg_pom_scell.c
@@ -0,0 +1,1127 @@
+/*******************************************************************************
+################################################################################
+#   Copyright (c) [2017-2019] [Radisys]                                        #
+#                                                                              #
+#   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.                                             #
+################################################################################
+*******************************************************************************/
+
+/************************************************************************
+ 
+     Name:     LTE-MAC layer
+  
+     Type:     C source file
+  
+     Desc:     C source code for Entry point functions
+  
+     File:     rg_pom_scell.c 
+  
+**********************************************************************/
+
+/** @file rg_pom_scell.c
+@brief This module does processing related to handling of SCell related function.
+*/
+
+/* header include files -- defines (.h) */
+#include "envopt.h"        /* environment options */
+#include "envdep.h"        /* environment dependent */
+#include "envind.h"        /* environment independent */
+#include "gen.h"           /* general layer */
+#include "ssi.h"           /* system service interface */
+#include "cm_hash.h"       /* common hash list */
+#include "cm_mblk.h"       /* common memory link list library */
+#include "cm_llist.h"      /* common linked list library */
+#include "cm_err.h"        /* common error */
+#include "cm_lte.h"        /* common LTE */
+#include "lrg.h"
+#include "crg.h"
+#include "rgu.h"
+#include "tfu.h"
+#include "rg_sch_inf.h"
+#include "rg_prg.h"       /* PRG interface includes*/
+#include "rg_env.h"
+#include "rg.h"
+#include "rg_err.h"
+
+/* header/extern include files (.x) */
+#include "gen.x"           /* general layer */
+#include "ssi.x"           /* system service interface */
+#include "cm5.x"           /* common timers */
+#include "cm_lib.x"        /* common library */
+#include "cm_hash.x"       /* common hash list */
+#include "cm_mblk.x"       /* common memory link list library */
+#include "cm_llist.x"      /* common linked list library */
+#include "cm_tkns.x"       /* common tokens */
+#include "cm_lte.x"        /* common LTE */
+#include "lrg.x"
+#include "crg.x"
+#include "rgu.x"
+#include "tfu.x"
+#include "rg_sch_inf.x"
+#include "rg_prg.x"       /* PRG interface typedefs*/
+#include "rg.x"
+#ifdef LTE_ADV
+#include "rg_pom_scell.x"
+PRIVATE S16 rgPomVldtSCellDedLchCfg ARGS((
+            Inst                       inst,
+            RgPrgUeSCellLchAddInfo     *lcCfg,
+            RgCellCb                   **cell,
+            RgUeCb                     **ue
+          ));
+PRIVATE S16 rgPomUeSCellDedLcCfg ARGS((RgCellCb                   *cell,
+                                       RgUeCb                     *ue,
+                                       RgPrgUeSCellLchAddInfo     *lcCfg
+                                     ));
+/**
+ * @brief Handler for the Lch reconfiguration request from PMAC to SMAC.
+ *
+ * @details
+ *
+ *     Function : RgPrgPMacSMacUeSCellLchModReq
+ *
+ *     Processing Steps:
+ *      - calls the function for validating cell, uecb and lch sent by PMAC
+ *      - Updates the lch recfg into ueCb.
+ *      - If successful, add the control block to hash list of UEs for the cell
+ *        else Rollback and FAIL.
+ *
+ *  @param[in]  Pst                    *pst
+ *  @param[in]  RgPrgUeSCellLchModInfo *lchCfgCb
+ *  @return  S16
+ *      -# ROK
+ *      -# RFAILED
+ **/
+#ifdef ANSI
+PUBLIC S16 RgPrgPMacSMacUeSCellLchModReq
+(
+Pst                      *pst,    
+RgPrgUeSCellLchModInfo   *lchCfgCb
+)
+#else
+PUBLIC S16 RgPrgPMacSMacUeSCellLchModReq(pst, lchCfgCb)
+Pst                      *pst;    
+RgPrgUeSCellLchModInfo   *lchCfgCb;
+#endif
+{
+   RgPrgCfgCfmInfo  cfgCfm;
+   Inst             inst = pst->dstInst;
+   RgCellCb         *cell;
+   S16              ret;
+   Pst              cfmPst;    
+   RgUeCb           *ue;
+   RgUlLcCb         *ulLc;
+
+   TRC2(RgPrgPMacSMacUeSCellLchModReq);
+   
+   RGDBGPRM(inst,(rgPBuf(inst),
+            "APPLYING CRG UE SCELL CONFIG: cellId %d ueId %d lcId %d lcgId %d\n",
+         lchCfgCb->cellId, lchCfgCb->crnti,lchCfgCb->lcId,lchCfgCb->ulLchRecfg.lcgId));
+
+   cfgCfm.ueId = lchCfgCb->crnti;
+   cfgCfm.sCellId = lchCfgCb->cellId;
+   cfgCfm.status = PRG_CFG_CFM_OK;
+   cfgCfm.event = EVTPRGUESCELLLCHMODCFM; 
+   rgGetPstToInst(&cfmPst, inst, pst->srcInst);
+
+   ret = rgPomVltdModLch(inst,lchCfgCb, &cell, &ue,&ulLc);
+  if(ret != ROK)
+  {
+     RGDBGERRNEW(inst,(rgPBuf(inst), "[%d] SMAC SCell Lc Cfg failed:\
+              cellId %d\n", lchCfgCb->crnti, lchCfgCb->cellId));
+     /* Set status as Not OK*/
+     cfgCfm.status = PRG_CFG_CFM_NOK;
+  }
+  else
+  {
+     ret = rgPomUeSCellLcMod(inst, ue, ulLc, lchCfgCb);
+     if(ret != ROK)
+     {
+        RGDBGERRNEW(inst,(rgPBuf(inst), "[%d] SMac SCell lc cfg failed:\
+                 cellId %d\n", lchCfgCb->crnti, lchCfgCb->cellId));
+        /* Set status as Not OK*/
+        cfgCfm.status = PRG_CFG_CFM_NOK;
+     }
+  }
+  
+  RGDBGINFONEW(inst,(rgPBuf(inst), "[%d] Scell Lch Config done:\
+           cellId %d\n", lchCfgCb->crnti, lchCfgCb->cellId));
+
+  /* Send positive confirmation to primary cell*/
+  RgPrgSMacPMacCfg(&cfmPst, &cfgCfm);
+  RETVALUE(ROK);
+}  /* RgPrgPMacSMacUeSCellLchModReq */
+
+
+/**
+ * @brief A wrapper class to send the LCH Del req from PMAC to SMAC
+ *
+ * @details
+ *
+ *     Function : rgPomSndUeSCellLchDelToSmac 
+ *
+ *     Processing Steps:
+ *      - Retrieve the cell control block.
+ *      - If successful,
+ *        - Validate the range of values received in
+ *          delete request.
+ *        - Checks if the Ue has any scell added.
+ *        - If validated successfully,
+ *          - if SCells have been added ,then 
+ *            send the lchDel structure to update the same values to SMAC.
+ *        - Return ROK.
+ *      - Else return RFAILED.
+ *
+ *  @param[in]  Inst          inst
+ *  @param[in]  CrgDel        *lcDel
+ *  @param[in]  Bool          *isCfmRqrd
+ *  @return  S16
+ *      -# ROK
+ *      -# RFAILED
+ **/
+#ifdef ANSI
+PUBLIC S16 rgPomSndUeSCellLchDelToSmac
+(
+Inst            inst,
+CrgDel          *lcDel,
+Bool            *isCfmRqrd
+)
+#else
+PUBLIC S16 rgPomSndUeSCellLchDelToSmac(inst,lcDel,isCfmRqrd)
+Inst            inst;
+CrgDel          *lcDel;
+Bool            *isCfmRqrd;
+#endif
+{
+   U8                         idx = 0;
+   Inst                       dstMacInst;
+   Pst                        dstInstPst;
+   RgPrgUeSCellLchDelInfo     delLcCb;
+   RgCellCb                   *cell;
+   RgUeCb                     *ue;
+
+   TRC2(rgPomSndUeSCellLchDelToSmac);
+  
+  /* Fetch the Active cell */
+   if(((cell = rgCb[inst].cell) == NULLP) ||
+       (cell->cellId != lcDel->u.lchDel.cellId))
+   {
+      RGDBGERRNEW(inst,(rgPBuf(inst), 
+                       "[%d]Active Cell does not exist %d\n",
+                                  lcDel->u.lchDel.crnti, lcDel->u.lchDel.cellId));
+      RETVALUE(RFAILED);
+   }
+
+   RGDBGPRM(inst,(rgPBuf(inst), 
+            "Filling SCell LCh Config : cellId %d ueId %d\n",
+            cell->cellId, cell->ueId));
+
+   if ((ue = rgDBMGetUeCb(cell, lcDel->u.lchDel.crnti)) == NULLP)
+   {
+      RGDBGERRNEW(inst,(rgPBuf(inst), 
+               "[%d]Ue does not exist\n", lcDel->u.lchDel.crnti));
+      RETVALUE(RFAILED);
+   }
+   for(idx = 0; idx < RG_MAX_SCELL_PER_UE ; idx++)
+   {
+      if(TRUE == ue->sCelInfo[idx].isSCellAdded)
+      {
+         dstMacInst = ue->sCelInfo[idx].macInst - RG_INST_START;
+         delLcCb.cellId = ue->sCelInfo[idx].sCellId;
+         delLcCb.crnti = lcDel->u.lchDel.crnti;
+         delLcCb.lcId = lcDel->u.lchDel.lcId;
+         delLcCb.dir = lcDel->u.lchDel.dir;
+
+      /* Get post structure of the cell to whom delLcCb needs to be sent
+       * And then send the lch recfg based on Mac instances */
+         rgGetPstToInst(&dstInstPst, inst, dstMacInst);
+         RgPrgPMacSMacUeScellLchDel(&dstInstPst, &delLcCb);
+         *isCfmRqrd = FALSE;
+      }
+   }
+   RETVALUE(ROK);
+}
+
+
+/**
+ * @brief A wrapper class to send the LCH reconfig req from PMAC to SMAC
+ *
+ * @details
+ *
+ *     Function : rgPomSndUeSCellLchModToSmac 
+ *
+ *     Processing Steps:
+ *      - Retrieve the cell control block.
+ *      - If successful,
+ *        - Validate the range of re-configured values recieved in
+ *          re-configuration request.
+ *        - Checks if the Ue has any scell added.
+ *        - If validated successfully,
+ *          - if SCells have been added ,then 
+ *            send the lchRecfg structure to update the same values to SMAC.
+ *        - Return ROK.
+ *      - Else return RFAILED.
+ *
+ *  @param[in]  Inst          inst
+ *  @param[in]  RgCellCb      *cell
+    @param[in]  RgUeCb        *ue,
+    @param[in]  CrgLchRecfg   *lchRecfg,
+    @param[in]  Bool          *isCfmRqrd
+ *  @return  S16
+ *      -# ROK
+ *      -# RFAILED
+ **/
+#ifdef ANSI
+PUBLIC S16 rgPomSndUeSCellLchModToSmac
+(
+Inst           inst,
+RgCellCb       *cell,
+RgUeCb         *ue,
+CrgLchRecfg    *lchRecfg,
+Bool           *isCfmRqrd
+)
+#else
+PUBLIC S16 rgPomSndUeSCellLchModToSmac(inst, cell, ue, lchRecfg, isCfmRqrd)
+Inst           inst;
+RgCellCb       *cell;
+RgUeCb         *ue;
+CrgLchRecfg    *lchRecfg;
+Bool           *isCfmRqrd;
+#endif
+{
+   U8                        idx = 0;
+   Inst                      dstMacInst;
+   RgPrgUeSCellLchModInfo    lchCfgCb; 
+   Pst                       dstInstPst;
+
+   TRC2(rgPomSndUeSCellLchModToSmac);
+  
+   for(idx = 0; idx < RG_MAX_SCELL_PER_UE ; idx++)
+   {
+      if(TRUE == ue->sCelInfo[idx].isSCellAdded)
+      {
+         dstMacInst = ue->sCelInfo[idx].macInst - RG_INST_START;
+         lchCfgCb.cellId = ue->sCelInfo[idx].sCellId;
+         lchCfgCb.crnti = lchRecfg->crnti;
+         lchCfgCb.lcId = lchRecfg->lcId;
+         lchCfgCb.ulLchRecfg.lcgId = lchRecfg->ulRecfg.lcgId;
+
+      /* Get post structure of the cell to whom lchCfgCb needs to be sent
+       * And then send the lch recfg based on Mac instances */
+         rgGetPstToInst(&dstInstPst, inst, dstMacInst);
+         RgPrgPMacSMacUeScellLchMod(&dstInstPst, &lchCfgCb);
+         *isCfmRqrd = FALSE;
+      }
+   }
+   RETVALUE(ROK);
+}
+
+/**
+ * @brief A wrapper class to send the LCH config req from PMAC to SMAC
+ *
+ * @details
+ *
+ *     Function : rgPomSndUeSCellLchAddToSmac
+ *
+ *     Processing Steps:
+ *        - Checks if the Ue has any scell added.
+ *          - if SCells have been added ,then 
+ *            send the lchCfgCb structure to update the same values to SMAC.
+ *        - Return ROK.
+ *      - Else return RFAILED.
+ *
+ *  @param[in]  Inst          insg
+ *
+ *  @param[in]  RgCellCb      *cell
+ *  @paran[in]  RgUeCb        *ue
+ *  @paran[in]  CrgLchCfg     *lchCfg
+ *  @paran[in]   Bool         *isCfmRqrd
+ *  @return  S16
+ *      -# ROK
+ *      -# RFAILED
+ **/
+#ifdef ANSI
+PUBLIC S16 rgPomSndUeSCellLchAddToSmac
+(
+Inst           inst,
+RgCellCb       *cell,
+RgUeCb         *ue,
+CrgLchCfg      *lchCfg,
+Bool           *isCfmRqrd
+)
+#else
+PUBLIC S16 rgPomSndUeSCellLchAddToSmac(inst, cell, ue, lchCfg, isCfmRqrd)
+Inst           inst;
+RgCellCb       *cell;
+RgUeCb         *ue;
+CrgLchCfg      *lchCfg;
+Bool           *isCfmRqrd;
+#endif
+{
+   U8                        idx = 0;
+   Inst                      dstMacInst;
+   RgPrgUeSCellLchAddInfo    lchCfgCb; 
+   Pst                       dstInstPst;
+
+   TRC2(rgPomSndUeSCellLchAddToSmac);
+  
+   for(idx = 0; idx < RG_MAX_SCELL_PER_UE ; idx++)
+   {
+      if(TRUE == ue->sCelInfo[idx].isSCellAdded)
+      {
+         dstMacInst = ue->sCelInfo[idx].macInst - RG_INST_START;
+         lchCfgCb.cellId = ue->sCelInfo[idx].sCellId;
+         lchCfgCb.crnti =  lchCfg->crnti;
+         lchCfgCb.lcId = lchCfg->lcId;
+         lchCfgCb.lcType = lchCfg->lcType;
+         lchCfgCb.dir = lchCfg->dir;
+         lchCfgCb.dlInfo.dlTrchType = lchCfg->dlInfo.dlTrchType;
+         lchCfgCb.ulInfo.ulTrchType = lchCfg->ulInfo.ulTrchType;
+         lchCfgCb.ulInfo.lcgId = lchCfg->ulInfo.lcgId;
+#ifdef LTE_L2_MEAS
+         lchCfgCb.qci = lchCfg->qci;
+#endif /* LTE_L2_MEAS */
+
+      /* Get post structure of the cell to whom lchCfgCb needs to be sent
+       * And then send the lch recfg based on Mac instances */
+         rgGetPstToInst(&dstInstPst, inst, dstMacInst);
+         RgPrgPMacSMacUeScellLchAdd(&dstInstPst, &lchCfgCb);
+         *isCfmRqrd = FALSE;
+      }
+   }
+   RETVALUE(ROK);
+} /* rgPomSndUeSCellLchAddToSmac */
+
+/**
+ * @brief Handler for the Lch delete request from PMAC to SMAC.
+ *
+ * @details
+ *
+ *     Function : RgPrgPMacSMacUeSCellLchDelReq
+ *
+ *     Processing Steps:
+ *      - calls the function for validating cell, uecb and Lch sent by PMAC
+ *      - If successful, delete the logical channel 
+ *        else Rollback and FAIL.
+ *
+ *  @param[in]  Pst                    *pst
+ *  @param[in]  RgPrgUeSCellLchDelInfo *lchCfgCb
+ *  @return  S16
+ *      -# ROK
+ *      -# RFAILED
+ **/
+#ifdef ANSI
+PUBLIC S16 RgPrgPMacSMacUeSCellLchDelReq
+(
+Pst                       *pst,    
+RgPrgUeSCellLchDelInfo    *delLcCb
+)
+#else
+PUBLIC S16 RgPrgPMacSMacUeSCellLchDelReq(pst, delLcCb)
+Pst                       *pst;    
+RgPrgUeSCellLchDelInfo    *delLcCb;
+#endif
+{
+   RgPrgCfgCfmInfo  cfgCfm;
+   Inst             inst = pst->dstInst;
+   RgCellCb         *cell;
+   S16              ret;
+   Pst              cfmPst;    
+   RgUeCb           *ue;
+   RgUlLcCb         *ulLc;
+   RgDlLcCb         *dlLc;
+
+   TRC2(RgPrgPMacSMacUeSCellLchDelReq);
+   
+   RGDBGPRM(inst,(rgPBuf(inst),
+            "APPLYING CRG UE SCELL CONFIG: cellId %d ueId %d\n",
+         lchCfgCb->cellId, lchCfgCb->crnti));
+
+   cfgCfm.ueId = delLcCb->crnti;
+   cfgCfm.sCellId = delLcCb->cellId;
+   cfgCfm.status = PRG_CFG_CFM_OK;
+   cfgCfm.event = EVTPRGUESCELLLCHDELCFM; 
+   rgGetPstToInst(&cfmPst, inst, pst->srcInst);
+
+   ret = rgPomVltdDelLch(inst,delLcCb, &cell, &ue,&ulLc,&dlLc);
+  if(ret != ROK)
+  {
+     RGDBGERRNEW(inst,(rgPBuf(inst), "[%d] SMAC SCell Lc Cfg failed:\
+              cellId %d\n", delLcCb->crnti, delLcCb->cellId));
+     /* Set status as Not OK*/
+     cfgCfm.status = PRG_CFG_CFM_NOK;
+  }
+  else
+  {
+     ret = rgPomUeSCellLcDel(inst, delLcCb, ue, ulLc,dlLc);
+     if(ret != ROK)
+     {
+        RGDBGERRNEW(inst,(rgPBuf(inst), "[%d] SMac SCell lc cfg failed:\
+                 cellId %d\n", delLcCb->crnti, delLcCb->cellId));
+        /* Set status as Not OK*/
+        cfgCfm.status = PRG_CFG_CFM_NOK;
+     }
+  }
+  
+  RGDBGINFONEW(inst,(rgPBuf(inst), "[%d] Scell Lch Config done:\
+           cellId %d\n", delLcCb->crnti, delLcCb->cellId));
+
+  /* Send positive confirmation to primary cell*/
+  RgPrgSMacPMacCfg(&cfmPst, &cfgCfm);
+  RETVALUE(ROK);
+}  /* RgPrgPMacSMacUeSCellLchDelReq */
+
+
+/**
+ * @brief Handler for the Lch configuration request from PMAC to SMAC.
+ *
+ * @details
+ *
+ *     Function : RgPrgPMacSMacUeSCellLchAddReq
+ *
+ *     Processing Steps:
+ *      - calls the function for validating cell, uecb and Lch sent by PMAC
+ *      - Updates the lch recfg into ueCb.
+ *      - If successful, add the control block to hash list of UEs for the cell
+ *        else Rollback and FAIL.
+ *
+ *  @param[in]  Pst                 *pst
+ *  @param[in]  RgPrgLchRecfgInfo   *lchCfgCb
+ *  @return  S16
+ *      -# ROK
+ *      -# RFAILED
+ **/
+#ifdef ANSI
+PUBLIC S16 RgPrgPMacSMacUeSCellLchAddReq
+(
+Pst                      *pst,    
+RgPrgUeSCellLchAddInfo   *lchCfgCb
+)
+#else
+PUBLIC S16 RgPrgPMacSMacUeSCellLchAddReq(pst, lchCfgCb)
+Pst                      *pst;    
+RgPrgUeSCellLchAddInfo   *lchCfgCb;
+#endif
+{
+   RgPrgCfgCfmInfo   cfgCfm;
+   Inst              inst = pst->dstInst;
+   RgCellCb          *cell;
+   S16               ret;
+   Pst               cfmPst;    
+   RgUeCb            *ue;
+
+   TRC2(RgPrgPMacSMacUeSCellLchAddReq);
+   
+   RGDBGPRM(inst,(rgPBuf(inst),
+            "APPLYING UE SCELL CONFIG AT SMAC : cellId %d ueId %d\n",
+         lchCfgCb->cellId, lchCfgCb->crnti));
+
+   cfgCfm.ueId = lchCfgCb->crnti;
+   cfgCfm.sCellId = lchCfgCb->cellId;
+   cfgCfm.status = PRG_CFG_CFM_OK;
+   cfgCfm.event = EVTPRGUESCELLLCHADDCFM; 
+   rgGetPstToInst(&cfmPst, inst, pst->srcInst);
+
+   ret = rgPomVldtAddLch(inst,lchCfgCb, &cell, &ue);
+  if(ret != ROK)
+  {
+     RGDBGERRNEW(inst,(rgPBuf(inst), "[%d] SMAC SCell Lc Cfg failed:\
+              cellId %d\n", lchCfgCb->crnti, lchCfgCb->cellId));
+     /* Set status as Not OK*/
+     cfgCfm.status = PRG_CFG_CFM_NOK;
+  }
+  else
+  {
+     ret = rgPomUeSCellLcAdd(inst, cell, ue, lchCfgCb);
+     if(ret != ROK)
+     {
+        RGDBGERRNEW(inst,(rgPBuf(inst), "[%d] SMac SCell lc cfg failed:\
+                 cellId %d\n", lchCfgCb->crnti, lchCfgCb->cellId));
+        /* Set status as Not OK*/
+        cfgCfm.status = PRG_CFG_CFM_NOK;
+     }
+  }
+  
+  RGDBGINFONEW(inst,(rgPBuf(inst), "[%d] Scell Lch Config done:\
+           cellId %d\n", lchCfgCb->crnti, lchCfgCb->cellId));
+
+  /* Send positive confirmation to primary cell*/
+  RgPrgSMacPMacCfg(&cfmPst, &cfgCfm);
+  RETVALUE(ROK);
+}  /* RgPrgPMacSMacUeSCellLchAddReq */
+/**
+ * @brief Validates the logical channel configuration request from PMAC to SMAC.
+ *
+ * @details
+ *
+ *     Function : rPommVldtAddLch
+ *
+ *     Processing Steps:
+ *      - Validate the logical channel configuration request from PMAC to
+ *        SMAC : validate if configured values are within the range.
+ *      - If validated successfully,
+ *        - Return ROK and pointer to cell and UE for dedicated logical channels.
+ *      - Else 
+ *        - Return RFAILED.
+ *
+ *  @param[in]  Inst                     inst
+ *  @param[in]  RgPrgUeSCellLchAddInfo   *lcCfg
+ *  @param[out] RgCellCb                 **cell
+ *  @param[out] RgUeCb                   **ue
+ *  @return  S16
+ *      -# ROK
+ *      -# RFAILED
+ **/
+#ifdef ANSI
+PUBLIC S16 rgPomVldtAddLch
+(
+Inst                    inst, 
+RgPrgUeSCellLchAddInfo  *lcCfg,
+RgCellCb                **cell,
+RgUeCb                  **ue
+)
+#else
+PUBLIC S16 rgPomVldtAddLch(inst,lcCfg, cell, ue)
+Inst                    inst;
+RgPrgUeSCellLchAddInfo  *lcCfg;
+RgCellCb                **cell;
+RgUeCb                  **ue;
+#endif
+{
+
+   TRC2(rgPomVldtAddLch);
+   RGDBGPRM(inst,(rgPBuf(inst), "VALIDATE SMAC LC CONFIG: cellId %d ueId %d lcId %d\
+            cell %p ue %p\n", lcCfg->cellId, lcCfg->crnti, lcCfg->lcId,
+            (void*)*cell, (void*)*ue));
+
+   if (lcCfg->lcType == CM_LTE_LCH_DTCH || lcCfg->lcType == CM_LTE_LCH_DCCH)
+   {
+      /* Dedicated logical channels */
+      if ((rgPomVldtSCellDedLchCfg(inst,lcCfg, cell, ue)) != ROK)
+      {
+         RGDBGERRNEW(inst,(rgPBuf(inst), "[%d]UEID Validation for dedicated LC failed\n",
+                  lcCfg->crnti));
+         RETVALUE(RFAILED);
+      }
+   }
+   else
+   {
+      RGDBGERRNEW(inst,(rgPBuf(inst), "[%d]UEID Invalid logical channel type %d\n",\
+               lcCfg->crnti, lcCfg->lcType));
+      RETVALUE(RFAILED);
+   }
+#ifdef LTE_L2_MEAS
+   if ( lcCfg->qci <  RG_QCI_MIN ||
+        lcCfg->qci >  RG_QCI_MAX
+      )
+   {
+      RGDBGERRNEW(inst,(rgPBuf(inst), "[%d]UEID Invalid qci %x\n",
+               lcCfg->crnti, lcCfg->qci));
+      RETVALUE(RFAILED);
+   }
+   /*validate qci */
+#endif /*LTE_L2_MEAS */
+
+   RGDBGINFONEW(inst,(rgPBuf(inst),"[%d]UEID CRG LCconfig validation done:cellId:%d lcId:%d\n",
+            lcCfg->crnti, lcCfg->cellId, lcCfg->lcId));
+   RETVALUE(ROK);
+}
+/**
+ * @brief Handler for the logical channel configuration request from
+ * PMAC to SMAC.
+ *
+ * @details
+ *
+ *     Function : rgPomUeSCellLcAdd
+ *
+ *     Processing Steps:
+ *      - Update the dedicated logical channel Cb with the configured values.
+ *      - If successful, return ROK else RFAILED.
+ *
+ *  @param[in]  Inst        inst
+ *  @param[in]  RgCellCb    *cell
+ *  @param[in]  RgUeCb      *ue
+ *  @param[in]  CrgLchCfg   *lcCfg
+ *  @param[out] RgErrInfo   *errInfo
+ *  @return  S16
+ *      -# ROK
+ *      -# RFAILED
+ **/
+#ifdef ANSI
+PUBLIC S16 rgPomUeSCellLcAdd
+(
+Inst                     inst,
+RgCellCb                 *cell,
+RgUeCb                   *ue,
+RgPrgUeSCellLchAddInfo   *lcCfg
+)
+#else
+PUBLIC S16 rgPomUeSCellLcAdd(inst,cell, ue, lcCfg)
+Inst                     inst;
+RgCellCb                 *cell;
+RgUeCb                   *ue;
+RgPrgUeSCellLchAddInfo   *lcCfg;
+#endif
+{
+
+   TRC2(rgPomUeSCellLcAdd);
+   RGDBGPRM(inst,(rgPBuf(inst), "APPLYING CRG LC CONFIG: cellId %d ueId %d\
+            lcId %d dir %d cell %p ue %p\n", lcCfg->cellId, lcCfg->crnti,
+            lcCfg->lcId, lcCfg->dir, (void*)cell, (void*)ue));
+   
+      if ((rgPomUeSCellDedLcCfg(cell, ue, lcCfg)) != ROK)
+      {
+         RGDBGERRNEW(inst,(rgPBuf(inst), "[%d]Dedicated logical channel configuration"
+                  "failed in SCell%d\n", lcCfg->crnti, lcCfg->lcId));
+         RETVALUE(RFAILED);
+      }
+
+   RGDBGINFONEW(inst,(rgPBuf(inst), "[%d]SCell LC config done: cellId %d lcId %d\n",
+          lcCfg->crnti, lcCfg->cellId, lcCfg->lcId));
+   RETVALUE(ROK);
+}  /* rgPomUeSCellLcAdd */
+
+/***********************************************************
+ *
+ *     Func : rgPomVldtSCellDedLchCfg
+ *
+ *
+ *     Desc : Validates dedicated logical channel configuration received from PMAC.
+ *
+ *     @param[in] Inst                     inst
+ *     @param[in] RgPrgUeScellLchAddInfo   *lcCfg 
+ *     @param[in] RgCellCb                 **cell
+ *     @param[in] RgUeCb                   **ue
+ *
+ *     Ret  : S16
+ *            ROK - Success
+ *            RFAILED - Failed
+ *
+ *     Notes:
+ *
+ *     File :
+ *
+ **********************************************************/
+#ifdef ANSI
+PRIVATE S16 rgPomVldtSCellDedLchCfg
+(
+Inst                       inst, 
+RgPrgUeSCellLchAddInfo     *lcCfg,
+RgCellCb                   **cell,
+RgUeCb                     **ue
+)
+#else
+PRIVATE S16 rgPomVldtSCellDedLchCfg(inst,lcCfg, cell, ue)
+Inst                       inst;
+RgPrgUeSCellLchAddInfo     *lcCfg;
+RgCellCb                   **cell;
+RgUeCb                     **ue;
+#endif
+{
+   TRC2(rgPomVldtSCellDedLchCfg);
+   RGDBGPRM(inst,(rgPBuf(inst), "VALIDATING CRG DEDICATED LC CONFIG \n"));
+
+
+   /* Fetch the Active cell */
+   if (((*cell = rgCb[inst].cell) == NULLP)
+      || ((*cell)->cellId != lcCfg->cellId))
+   {
+      RGDBGERRNEW(inst,(rgPBuf(inst), "[%d]Active Cell does not exist: Cell %d\n",
+               lcCfg->crnti, lcCfg->cellId));
+      RETVALUE(RFAILED);
+   }
+
+   /* Fetch the Ue */
+   if ((*ue = rgDBMGetUeCb(*cell, lcCfg->crnti)) == NULLP)
+   {
+      RGDBGERRNEW(inst,(rgPBuf(inst), "[%d]UE  does not exist for dedicated logical"
+               "channel %d\n", lcCfg->crnti, lcCfg->lcId));
+      RETVALUE(RFAILED);
+   }
+
+   /* Validate logical channel Id */
+   /*if ((lcCfg->lcId < RG_DEDLC_MIN_LCID)
+            ||(lcCfg->lcId > RG_DEDLC_MAX_LCID))
+   {
+      RGDBGERRNEW(inst,(rgPBuf(inst), "[%d]Invalid logical channel Id %d\n",
+                lcCfg->crnti, lcCfg->lcId));
+      RETVALUE(RFAILED);
+   }*/
+   /* Validate downlink info */
+   if (lcCfg->dir & PRG_DIR_TX)
+   {
+      if (rgDBMGetDlDedLcCb((*ue), lcCfg->lcId) != NULLP)
+      {
+         RGDBGERRNEW(inst,(rgPBuf(inst), "[%d]UE: Dedicated DL LC %d already configured\n",
+                   lcCfg->crnti, lcCfg->lcId));
+         RETVALUE(RFAILED);
+      }
+/*      dirVld = TRUE;*/
+   }
+
+   /* Validate uplink info */
+   if (lcCfg->dir & PRG_DIR_RX)
+   {
+      if (lcCfg->ulInfo.lcgId > (RG_MAX_LCG_PER_UE - 1))
+      {
+         RGDBGERRNEW(inst,(rgPBuf(inst), "[%d]UE: Invalid lcgId for uplink logical"
+                  "channel %d\n", lcCfg->crnti, lcCfg->ulInfo.lcgId));
+         RETVALUE(RFAILED);
+      }
+      if (rgDBMGetUlDedLcCb((*ue), lcCfg->lcId) != NULLP)
+      {
+         RGDBGERRNEW(inst,(rgPBuf(inst), "[%d]UE: Dedicated UL LC %d already configured\n",
+                   lcCfg->crnti, lcCfg->lcId));
+         RETVALUE(RFAILED);
+      }
+/*      dirVld = TRUE;*/
+   }
+/*
+   if (!dirVld)
+   {
+      RGDBGERRNEW(inst,(rgPBuf(inst), "[%d]Invalid Direction %d \n",
+               lcCfg->crnti, lcCfg->dir));
+      RETVALUE(RFAILED);
+   }
+*/
+   RGDBGINFONEW(inst,(rgPBuf(inst), "[%d]Dedicated logical channel %d validated"
+            "for cell %d\n", lcCfg->crnti, lcCfg->lcId, lcCfg->cellId));
+   RETVALUE(ROK);
+}  /* rgPomVldtSCellDedLchCfg */
+/***********************************************************
+ *
+ *     Func : rgPomUeSCellDedLcCfg
+ *
+ *
+ *     Desc : Validates dedicated logical channel configuration received from PMAC.
+ *
+ *     @param[in] RgCellCb                 *cell
+ *     @param[in] RgUeCb                   *ue 
+ *     @param[in] RgPrgUeSCellLchAddInfo   *lcCfg
+ *
+ *     Ret  : S16
+ *            ROK - Success
+ *            RFAILED - Failed
+ *
+ *     Notes:
+ *
+ *     File :
+ *
+ **********************************************************/
+#ifdef ANSI
+PRIVATE S16 rgPomUeSCellDedLcCfg
+(
+RgCellCb                   *cell,
+RgUeCb                     *ue,
+RgPrgUeSCellLchAddInfo     *lcCfg
+)
+#else
+PRIVATE S16 rgPomUeSCellDedLcCfg(cell, ue, lcCfg)
+RgCellCb                   *cell;
+RgUeCb                     *ue;
+RgPrgUeSCellLchAddInfo     *lcCfg;
+#endif
+{
+   //Inst     inst = cell->macInst - RG_INST_START;
+   TRC2(rgPomUeSCellDedLcCfg);
+   //RGDBGPRM(inst,(rgPBuf(inst), "APPLYING DEDICATED LC CONFIG\n"));
+
+   /* Uplink/Bi-directional logical channel */
+   if (lcCfg->dir & PRG_DIR_RX)
+   {
+#ifdef LTE_L2_MEAS
+      rgDBMInsUlDedLcCb(ue, lcCfg->lcId, lcCfg->ulInfo.lcgId, lcCfg->qci);
+      cell->qciArray[lcCfg->qci].qci = lcCfg->qci;
+      if(lcCfg->lcType == CM_LTE_LCH_DTCH)
+      {
+        rgAddToL2MeasPerQci(cell,lcCfg->qci);/*LTE_L2_MEAS_PHASE2*/ 
+      }
+#else
+      rgDBMInsUlDedLcCb(ue, lcCfg->lcId, lcCfg->ulInfo.lcgId);
+#endif
+   }
+
+   /* Downlink/Bi-directional logical channel */
+   if (lcCfg->dir & PRG_DIR_TX)
+   {
+      rgDBMInsDlDedLcCb(ue, lcCfg->lcId);
+   }
+   RGDBGINFO(inst,(rgPBuf(inst), "Dedicated LC config done\n"));
+   RETVALUE(ROK);
+
+  }  /* rgPomUeSCellDedLcCfg */
+/**
+ * @brief Function to validate SCellLchReCfg.
+ *
+ * @details
+ *
+ *     Function : rgPomVltdModLch
+ *     
+ *           
+ *  @param[in] inst        instance number to fetch rgCb instance
+ *  @param[in] lchCfg Cb   lchCfg CB for validation
+ *  @param[out] cell        cell control block
+ *  @param[out] RgCellCb     **cell
+ *  @param[out] RgUeCb       **ue
+ *  @param[out] RgUlLcCb     **ulLc
+ *  @return  S16
+ *      -# ROK 
+ **/
+#ifdef ANSI
+PUBLIC S16 rgPomVltdModLch
+(
+ Inst                     inst,
+ RgPrgUeSCellLchModInfo   *lchCfgCb,
+ RgCellCb                 **cell,
+ RgUeCb                   **ue,
+ RgUlLcCb                 **ulLc
+)
+#else
+PUBLIC S16 rgPomVltdModLch(inst, lchCfgCb, cell, ue, ulLc)
+ Inst                     inst;
+ RgPrgUeSCellLchModInfo   *lchCfgCb;
+ RgCellCb                 **cell;
+ RgUeCb                   **ue;
+ RgUlLcCb                 **ulLc;
+#endif
+{
+   TRC2(rgPomVltdModLch);
+   RGDBGPRM(inst,(rgPBuf(inst), "VALIDATE SMAC LC RECONFIG: cellId %d ueId %d \
+            lcId %d cell %p ue %p ulLc %p\n",lchCfgCb->cellId,
+            lchCfgCb->crnti,lchCfgCb->lcId, (void*)*cell, (void*)*ue,
+            (void*)*ulLc));
+   /* Fetch the cell */
+   if ((((*cell = rgCb[inst].cell)) == NULLP)
+         || ((*cell)->cellId != lchCfgCb->cellId))
+   {
+      RGDBGERRNEW(inst,(rgPBuf(inst), "[%d]Active Cell does not exist %d\n",lchCfgCb->crnti, lchCfgCb->cellId));
+      RETVALUE(RFAILED);
+   }
+   /* Fetch the Ue for dedicated channels */
+   if ((*ue = rgDBMGetUeCb(*cell, lchCfgCb->crnti)) == NULLP)
+   {
+      RGDBGERRNEW(inst,(rgPBuf(inst), "[%d]Ue does not exist for dedicated logical channel\n",
+               lchCfgCb->crnti));
+      RETVALUE(RFAILED);
+   }
+   if ((*ulLc = rgDBMGetUlDedLcCb((*ue), lchCfgCb->lcId)) == NULLP)
+   {
+      RGDBGERRNEW(inst,(rgPBuf(inst), "[%d]Dedicated UL LC does not exist %d\n",
+               lchCfgCb->crnti, lchCfgCb->lcId));
+      RETVALUE(RFAILED);
+   }
+  /* if (lchCfgCb->ulLchRecfg.lcgId > (RG_MAX_LCG_PER_UE - 1))
+   {
+      RGDBGERRNEW(inst,(rgPBuf(inst), "[%d]Invalid lcgId for uplink logical channel: lcg %d"
+               "lc %d\n",lchCfgCb->crnti, lchCfgCb->ulLchRecfg.lcgId, lchCfgCb->lcId));
+      RETVALUE(RFAILED);
+   }*/
+   RETVALUE(ROK);
+} /*rgPomVltdModLch*/
+/**
+ * @brief Handler for the logical channel re-configuration request from
+ * PMAC to SMAC.
+ *
+ * @details
+ *
+ *     Function : rgPomUeSCellLcMod
+ *
+ *     Processing Steps:
+ *      - Update the dedicated logical channel Cb with the re-configured
+ *        values.
+ *      - If successful, return ROK else RFAILED.
+ *
+ *  @param[in]  Inst              inst
+ *  @param[in]  RgUlUeCb          *ue
+ *  @param[in]  RgUlLcCb          *ulLc
+ *  @param[in]  RgPrgLchRecfgInfo *lchCfgCb
+ *  @return  S16
+ *      -# ROK
+ *      -# RFAILED
+ **/
+#ifdef ANSI
+PUBLIC S16 rgPomUeSCellLcMod
+(
+Inst                    inst,
+RgUeCb                  *ue,
+RgUlLcCb                *ulLc,
+RgPrgUeSCellLchModInfo  *lchCfgCb
+)
+#else
+PUBLIC S16 rgPomUeSCellLcMod(inst,cell, ue, ulLc, lchCfgCb)
+Inst                    inst;
+RgUeCb                  *ue;
+RgUlLcCb                *ulLc;
+RgPrgUeSCellLchModInfo  *lchCfgCb;
+#endif
+{
+   TRC2(rgPomUeSCellLcMod);
+   RGDBGPRM(inst,(rgPBuf(inst), "APPLYING SMAC LC RECONFIG: cellId %d ueId %d\
+            lcId %d  \n",
+            lchCfgCb->cellId, lchCfgCb->crnti, lchCfgCb->lcId));
+
+   if (ulLc->lcgId != lchCfgCb->ulLchRecfg.lcgId)
+   {
+      rgDBMUpdUlDedLcCb(ue, ulLc, lchCfgCb->ulLchRecfg.lcgId);
+   }
+
+   RGDBGINFO(inst,(rgPBuf(inst), "LC %d of Ue %d of cell %d Reconfigured\n", 
+            lchCfgCb->lcId, ue->ueId, cell->cellId));
+   RETVALUE(ROK);
+}  /* rgPomUeSCellLcMod */
+/**
+ * @brief Function to validate SCellLchDel.
+ *
+ * @details
+ *
+ *     Function : rgPomVltdDelLch
+ *     
+ *           
+ *  @param[in] inst        instance number to fetch rgCb instance
+ *  @param[in] lchCfg Cb   lchCfg CB for validation
+ *  @param[out] cell        cell control block
+ *  @param[out] RgCellCb     **cell
+ *  @param[out] RgUeCb       **ue
+ *  @param[out] RgUlLcCb     **ulLc
+ *  @return  S16
+ *      -# ROK 
+ **/
+#ifdef ANSI
+PUBLIC S16 rgPomVltdDelLch
+(
+ Inst                      inst,
+ RgPrgUeSCellLchDelInfo    *delLcCb,
+ RgCellCb                  **cell,
+ RgUeCb                    **ue,
+ RgUlLcCb                  **ulLc,
+ RgDlLcCb                  **dlLc
+)
+#else
+PUBLIC S16 rgPomVltdDelLch(inst, delLcCb, cell, ue, ulLc, dlLc)
+ Inst                      inst;
+ RgPrgUeSCellLchDelInfo    *delLcCb;
+ RgCellCb                  **cell;
+ RgUeCb                    **ue;
+ RgUlLcCb                  **ulLc;
+ RgDlLcCb                  **dlLc;
+#endif
+{
+   TRC2(rgPomVltdDelLch);
+   RGDBGPRM(inst,(rgPBuf(inst), "VALIDATE SMAC LC RECONFIG: cellId %d ueId %d \
+            lcId %d cell %p ue %p ulLc %p\n",delLcCb->cellId,
+            delLcCb->crnti,delLcCb->lcId, (void*)*cell, (void*)*ue,
+            (void*)*ulLc));
+   /* Fetch the cell */
+   if ((((*cell = rgCb[inst].cell)) == NULLP)
+         || ((*cell)->cellId != delLcCb->cellId))
+   {
+      RGDBGERRNEW(inst,(rgPBuf(inst), "[%d]Active Cell does not exist %d\n",delLcCb->crnti, delLcCb->cellId));
+      RETVALUE(RFAILED);
+   }
+   /* Fetch the Ue for dedicated channels */
+   if ((*ue = rgDBMGetUeCb(*cell, delLcCb->crnti)) == NULLP)
+   {
+      RGDBGERRNEW(inst,(rgPBuf(inst), "[%d]Ue does not exist for dedicated logical channel\n",
+               delLcCb->crnti));
+      RETVALUE(RFAILED);
+   }
+   if ((*ulLc = rgDBMGetUlDedLcCb((*ue), delLcCb->lcId)) == NULLP)
+   {
+      RGDBGERRNEW(inst,(rgPBuf(inst), "[%d]Dedicated UL LC does not exist %d\n",
+               delLcCb->crnti, delLcCb->lcId));
+      RETVALUE(RFAILED);
+   }
+   if ((*dlLc = rgDBMGetDlDedLcCb((*ue), delLcCb->lcId)) == NULLP)
+   {
+         RGDBGERRNEW(inst,(rgPBuf(inst), "[%d]DL LC %d does not exist\n",
+               delLcCb->crnti, delLcCb->lcId));
+         RETVALUE(RFAILED);
+   }
+   RETVALUE(ROK);
+} /*rgPomVltdDelLch*/
+/**
+ * @brief Handler for the logical channel delete request from
+ * PMAC to SMAC.
+ *
+ * @details
+ *
+ *     Function : rgPomUeSCellLcDel
+ *
+ *     Processing Steps:
+ *      - Fetch the logical channel control block.
+ *      - Free the logical channel control block.
+ *      - If successful, return ROK else return RFAILED.
+ *
+ *  @param[in]  Inst                      inst
+ *  @param[in]  RgPrgUeSCellLchDelInfo    *delLcCb
+ *  @param[in]  RgUeCb                    *ue
+ *  @param[in]  RgUlLcCb                  *ulLc
+ *  @return  S16
+ *      -# ROK
+ *      -# RFAILED
+ **/
+#ifdef ANSI
+PUBLIC S16 rgPomUeSCellLcDel
+(
+Inst                      inst,
+RgPrgUeSCellLchDelInfo    *delLcCb,
+RgUeCb                    *ue,
+RgUlLcCb                  *ulLc,
+RgDlLcCb                  *dlLc
+)
+#else
+PUBLIC S16 rgPomUeSCellLcDel(inst,delLcCb,ue,ulLc,dlLc)
+Inst                      inst;
+RgPrgUeSCellLchDelInfo    *delLcCb;
+RgUeCb                    *ue;
+RgUlLcCb                  *ulLc;
+RgDlLcCb                  *dlLc;
+#endif
+{
+
+   TRC2(rgPomUeSCellLcDel);
+   RGDBGPRM(inst,(rgPBuf(inst), "APPLYING CRG LC DELETE: cellId %d ueId %d\
+            lcId %d dir %d\n", delLcCb->cellId,
+            delLcCb->crnti, delLcCb->lcId,
+            delLcCb->dir));
+
+
+   /* Validate downlink info */
+   if (delLcCb->dir & PRG_DIR_TX)
+   {
+      rgDBMDelDlDedLcCb(ue, dlLc);
+/*      dirVld = TRUE;*/
+   }
+
+   /* Validate uplink info */
+   if (delLcCb->dir & PRG_DIR_RX)
+   {
+      rgDBMDelUlDedLcCb(ue, ulLc);
+/*      dirVld = TRUE;*/
+   }
+
+   /*if (!dirVld)
+   {
+      RGDBGERRNEW(inst,(rgPBuf(inst), "[%d]Invalid direction %d for LC Delete\n",
+            delLcCb->crnti, delLcCb->dir));
+      RETVALUE(RFAILED);
+   }*/
+   RGDBGINFONEW(inst,(rgPBuf(inst), "[%d]UE's Logical channel %d deleted from cell %d\n",
+         delLcCb->crnti, delLcCb->lcId,
+         delLcCb->cellId));
+   RETVALUE(ROK);
+}  /* rgPomUeSCellLcDel */
+#endif /*LTE_ADV */
+/**********************************************************************
+ 
+         End of file
+**********************************************************************/
diff --git a/src/5gnrmac/rg_pom_scell.x b/src/5gnrmac/rg_pom_scell.x
new file mode 100755
index 000000000..afa37632e
--- /dev/null
+++ b/src/5gnrmac/rg_pom_scell.x
@@ -0,0 +1,109 @@
+/*******************************************************************************
+################################################################################
+#   Copyright (c) [2017-2019] [Radisys]                                        #
+#                                                                              #
+#   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.                                             #
+################################################################################
+*******************************************************************************/
+
+/* *****************************************************************************
+  Name:     LTE-MAC layer 
+  
+  Type:     C Include File 
+  
+  Desc:     Structures, variables, and typedefs required by Secondary cell
+            received through PRG interface.
+
+  File:     rg_pom_scell.x 
+
+**********************************************************************/
+/** 
+  @file rg_pom_scell.x 
+  @brief Structure declarations and definitions for Secondary cell received from  (PRG) interface.
+  */
+
+#ifndef __RGPOMSCELL_X__ 
+#define __RGPOMSCELL_X__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+#ifdef LTE_ADV
+EXTERN S16 RgPrgPMacSMacUeSCellLchModReq ARGS
+((
+ Pst                      *pst,
+ RgPrgUeSCellLchModInfo   *lchCfgCb
+));
+EXTERN S16 RgPrgPMacSMacUeSCellLchAddReq ARGS
+((
+ Pst                      *pst,
+ RgPrgUeSCellLchAddInfo   *lchCfgCb
+));
+EXTERN S16 RgPrgPMacSMacUeSCellLchDelReq ARGS
+((
+ Pst                       *pst,
+ RgPrgUeSCellLchDelInfo    *delLcCb
+));
+EXTERN S16 rgPomSndUeSCellLchDelToSmac ARGS((Inst inst,CrgDel *lcDel,
+                                              Bool *isCfmRqrd));
+EXTERN S16 rgPomSndUeSCellLchAddToSmac ARGS((Inst inst,RgCellCb *cell,
+                                              RgUeCb *ue,CrgLchCfg *lchCfg,
+                                              Bool *isCfmRqrd));
+EXTERN S16 rgPomSndUeSCellLchModToSmac ARGS((Inst inst,RgCellCb *cell,
+                                              RgUeCb *ue,CrgLchRecfg *lchRecfg,
+                                              Bool *isCfmRqrd));
+EXTERN S16 rgPomVldtAddLch ARGS((Inst                    inst,
+                                 RgPrgUeSCellLchAddInfo  *lcCfg,
+                                 RgCellCb                **cell,
+                                 RgUeCb                  **ue
+                               ));
+EXTERN S16 rgPomUeSCellLcAdd ARGS((Inst                     inst,
+                                   RgCellCb                 *cell,
+                                   RgUeCb                   *ue,
+                                   RgPrgUeSCellLchAddInfo   *lcCfg
+                                 ));
+EXTERN S16 rgPomVltdModLch ARGS ((Inst                     inst,
+                                  RgPrgUeSCellLchModInfo   *lchCfgCb,
+                                  RgCellCb                 **cell,
+                                  RgUeCb                   **ue,
+                                  RgUlLcCb                 **ulLc
+                                 ));
+EXTERN S16 rgPomUeSCellLcMod ARGS((Inst                     inst,
+                                    RgUeCb                  *ue,
+                                    RgUlLcCb                *ulLc,
+                                    RgPrgUeSCellLchModInfo  *lchCfgCb
+                                  ));
+EXTERN S16 rgPomUeSCellLcDel ARGS((Inst                   inst,
+                                 RgPrgUeSCellLchDelInfo   *delLcCb,
+                                 RgUeCb                   *ue,
+                                 RgUlLcCb                 *ulLc,
+                                 RgDlLcCb                 *dlLc
+                               ));
+EXTERN S16 rgPomVltdDelLch ARGS ((Inst                      inst,
+                                  RgPrgUeSCellLchDelInfo    *delLcCb,                              
+                                  RgCellCb                  **cell,
+                                  RgUeCb                    **ue,
+                                  RgUlLcCb                  **ulLc,
+                                  RgDlLcCb                  **dlLc
+                                ));
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* __RGPRG_X__*/
+
+/**********************************************************************
+  
+         End of file:     rg_pom_scell.x
+**********************************************************************/
diff --git a/src/5gnrmac/rg_prg.c b/src/5gnrmac/rg_prg.c
new file mode 100755
index 000000000..b4d3f9cfb
--- /dev/null
+++ b/src/5gnrmac/rg_prg.c
@@ -0,0 +1,623 @@
+/*******************************************************************************
+################################################################################
+#   Copyright (c) [2017-2019] [Radisys]                                        #
+#                                                                              #
+#   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.                                             #
+################################################################################
+*******************************************************************************/
+
+/************************************************************************
+ 
+     Name:     LTE-MAC layer
+  
+     Type:     C source file
+  
+     Desc:     C source code for packing/unpacking of MAC to MAC interface
+               primitives.
+  
+     File:     rg_prg.c 
+  
+**********************************************************************/
+/* header include files -- defines (.h) */
+#include "envopt.h"        /* environment options */
+#include "envdep.h"        /* environment dependent */
+#include "envind.h"        /* environment independent */
+#include "gen.h"           /* general layer */
+#include "ssi.h"           /* system service interface */
+#include "cm_hash.h"       /* common hash list */
+#include "cm_mblk.h"       /* common memory link list library */
+#include "cm_llist.h"      /* common linked list library */
+#include "cm_err.h"        /* common error */
+#include "cm_lte.h"        /* common LTE */
+#include "lrg.h"
+#include "crg.h"
+#include "rgu.h"
+#include "tfu.h"
+#include "rg_sch_inf.h"
+#include "rg_prg.h"
+#include "rg_env.h"
+#include "rg.h"
+#include "rg_err.h"
+
+/* header/extern include files (.x) */
+#include "gen.x"           /* general layer typedefs */
+#include "ssi.x"           /* system services typedefs */
+#include "cm5.x"           /* common timers */
+#include "cm_hash.x"       /* common hash list */
+#include "cm_lib.x"        /* common library */
+#include "cm_llist.x"      /* common linked list */
+#include "cm_mblk.x"       /* memory management */
+#include "cm_tkns.x"       /* common tokens */
+#include "cm_lte.x"       /* common tokens */
+#include "rgu.x"           /* RGU types */
+#include "tfu.x"           /* RGU types */
+#include "lrg.x"           /* layer management typedefs for MAC */
+#include "crg.x"           /* layer management typedefs for MAC */
+#include "rg_sch_inf.x"           /* layer management typedefs for MAC */
+#include "rg_prg.x"           /* Prg(MAC-MAC)interface includes */
+#include "rg.x"            /* typedefs for MAC */
+
+#ifdef LTE_ADV
+#ifdef LCPRG
+/** 
+ * @brief Ue SCell Cfg Req from PMac to SMac.
+ * @details This primitive is used for light-weight loose coupling.
+ *
+ * @details
+ *
+ *     Function : cmPkPrgPMacSMacUeSCellCfgReq
+ *
+ *  @param[in]   Pst*  pst
+ *  @param[in]   RgPrgUeSCellCfgInfo   *ueSCellCfgInfo
+ *  @return   S16
+ *      -# ROK
+ **/
+#ifdef ANSI
+PUBLIC S16 cmPkPrgPMacSMacUeSCellCfgReq
+(
+Pst           *pst,
+RgPrgUeSCellCfgInfo   *ueSCellCfgInfo
+)
+#else
+PUBLIC S16 cmPkPrgPMacSMacUeSCellCfgReq(pst, ueSCellCfgInfo)
+Pst            *pst;
+RgPrgUeSCellCfgInfo    *ueSCellCfgInfo;
+#endif
+{
+   Buffer *mBuf = NULLP;
+
+   TRC2(cmPkPrgPMacSMacUeSCellCfgReq)
+
+   if (SGetMsg(pst->region, pst->pool, &mBuf) != ROK) 
+   {
+      RETVALUE(RFAILED);
+   }
+   
+   if(SAddPstMsgMult((Data *)ueSCellCfgInfo, sizeof(RgPrgUeSCellCfgInfo),\
+            mBuf) != ROK)
+   {
+      RGPRG_FREE_MSG(mBuf);
+      RETVALUE(RFAILED);
+   }
+
+   pst->event = (Event) EVTPRGUESCELLCFGREQ;
+   RETVALUE(SPstTsk(pst,mBuf));
+}
+
+/** 
+ * @brief Ue SCell Cfg Req from PMac to SMac.
+ * @details This primitive is used for light-weight loose coupling.
+ *
+ * @details
+ *
+ *     Function : cmUnpkPrgPMacSMacUeSCellCfgReq
+ *
+ *  @param[in]   Pst*  pst
+ *  @param[in]   RgPrgUeSCellCfgInfo   *ueSCellCfgInfo
+ *  @return   S16
+ *      -# ROK
+ **/
+#ifdef ANSI
+PUBLIC S16 cmUnpkPrgPMacSMacUeSCellCfgReq
+(
+RgPrgUeSCellCfgReq   func,
+Pst                  *pst,
+Buffer               *mBuf
+)
+#else
+PUBLIC S16 cmUnpkPrgPMacSMacUeSCellCfgReq(func, pst, mBuf)
+RgPrgUeSCellCfgReq   func;
+Pst                  *pst;
+Buffer               *mBuf;
+#endif
+{
+   RgPrgUeSCellCfgInfo    ueSCellCfgInfo;
+   
+   TRC2(cmUnpkPrgPMacSMacUeSCellCfgReq)
+
+   if(SRemPreMsgMult((Data *)&ueSCellCfgInfo, sizeof(RgPrgUeSCellCfgInfo), mBuf) != ROK)
+   {
+      RGPRG_FREE_MSG(mBuf);
+      RETVALUE(RFAILED);
+   }
+
+   RGPRG_FREE_MSG(mBuf);
+   RETVALUE((*func)(pst, &ueSCellCfgInfo));
+}
+
+/** 
+ * @brief Config confirm for Ue SCell config Req.
+ * @details This primitive is used for light-weight loose coupling.
+ *
+ * @details
+ *
+ *     Function : cmPkPrgSMacPMacCfgCfm
+ *
+ *  @param[in]   Pst              *pst
+ *  @param[in]   RgPrgCfgCfmInfo  *cfgCfm
+ *  @return   S16
+ *      -# ROK
+ **/
+#ifdef ANSI
+PUBLIC S16 cmPkPrgSMacPMacCfgCfm
+(
+Pst               *pst,
+RgPrgCfgCfmInfo   *cfgCfm
+)
+#else
+PUBLIC S16 cmPkPrgSMacPMacCfgCfm(pst, cfgCfm)
+Pst                *pst;
+RgPrgCfgCfmInfo    *cfgCfm;
+#endif
+{
+   Buffer *mBuf = NULLP;
+
+   TRC2(cmPkPrgSMacPMacCfgCfm)
+
+   if (SGetMsg(pst->region, pst->pool, &mBuf) != ROK) 
+   {
+      RETVALUE(RFAILED);
+   }
+   
+   if(SAddPstMsgMult((Data *)cfgCfm, sizeof(RgPrgCfgCfmInfo), mBuf) != ROK)
+   {
+      RGPRG_FREE_MSG(mBuf);
+      RETVALUE(RFAILED);
+   }
+   switch(cfgCfm->event)
+   {
+      case EVTPRGUESCELLLCHMODCFM : /*cfm for Lch recfg */ 
+      {
+         pst->event = (Event) EVTPRGUESCELLLCHMODCFM;
+      }
+      break;
+      case EVTPRGUESCELLCFGCFM : /*cfm for Adding Scell */ 
+      {
+         pst->event = (Event) EVTPRGUESCELLCFGCFM;
+      }
+      break;
+      case EVTPRGUESCELLLCHDELCFM : /* cfm for deleting Lch */
+      {
+         pst->event = (Event) EVTPRGUESCELLLCHDELCFM;
+      }
+      break;
+      case EVTPRGUESCELLLCHADDCFM: /* cfm for adding of LCh */
+      {
+         pst->event = (Event) EVTPRGUESCELLLCHADDCFM;
+      }
+      break;
+   }
+   RETVALUE(SPstTsk(pst,mBuf));
+}
+
+/** 
+ * @brief Config confirm for SCell addd Req.
+ * @details This primitive is used for light-weight loose coupling.
+ *
+ * @details
+ *
+ *     Function : cmUnpkPrgSMacPMacCfgCfm
+ *
+ *  @param[in]   CfgCfm          fun
+ *  @param[in]   Pst*            pst
+ *  @param[in]   RgPrgCfgCfmInfo *cfgCfm
+ *  @return   S16
+ *      -# ROK
+ **/
+#ifdef ANSI
+PUBLIC S16 cmUnpkPrgSMacPMacCfgCfm
+(
+RgSMacPMacCfgCfm    func,
+Pst                 *pst,
+Buffer              *mBuf
+)
+#else
+PUBLIC S16 cmUnpkPrgSMacPMacCfgCfm(func, pst, mBuf)
+RgSMacPMacCfgCfm    func;
+Pst                 *pst;
+Buffer              *mBuf;
+#endif
+{
+   RgPrgCfgCfmInfo   cfgCfm;
+   
+   TRC2(cmUnpkPrgSMacPMacCfgCfm)
+
+   if(SRemPreMsgMult((Data *)&cfgCfm, sizeof(RgPrgCfgCfmInfo), mBuf) != ROK)
+   {
+      RGPRG_FREE_MSG(mBuf);
+      RETVALUE(RFAILED);
+   }
+
+   RGPRG_FREE_MSG(mBuf);
+   RETVALUE((*func)(pst, &cfgCfm));
+}
+
+/** 
+ * @brief SCell Ue Delete Req/UeId change req from PMac to SMac.
+ * @details This primitive is used for light-weight loose coupling.
+ *
+ * @details
+ *
+ *     Function : cmPkPrgPMacSMacUeSCellDelReq
+ *
+ *  @param[in]   Pst                  *pst
+ *  @param[in]   RgPrgUeSCellDelInfo  *ueSCellDelInfo
+ *  @return   S16
+ *      -# ROK
+ **/
+#ifdef ANSI
+PUBLIC S16 cmPkPrgPMacSMacUeSCellDelReq
+(
+Pst                   *pst,
+RgPrgUeSCellDelInfo   *ueSCellDelInfo
+)
+#else
+PUBLIC S16 cmPkPrgPMacSMacUeSCellDelReq(pst, ueSCellDelInfo)
+Pst                    *pst;
+RgPrgUeSCellDelInfo    *ueSCellDelInfo;
+#endif
+{
+   Buffer *mBuf = NULLP;
+
+   TRC2(cmPkPrgPMacSMacUeSCellDelReq)
+
+   if (SGetMsg(pst->region, pst->pool, &mBuf) != ROK) 
+   {
+      RETVALUE(RFAILED);
+   }
+   
+   if(SAddPstMsgMult((Data *)ueSCellDelInfo, sizeof(RgPrgUeSCellDelInfo), mBuf)\
+         != ROK)
+   {
+      RGPRG_FREE_MSG(mBuf);
+      RETVALUE(RFAILED);
+   }
+
+   pst->event = (Event) EVTPRGUESCELLDELREQ;
+   RETVALUE(SPstTsk(pst,mBuf));
+}
+
+/** 
+ * @brief Unpacking for SCell UE delete/Ue Id Change Req to SMAC.
+ * @details This primitive is used for light-weight loose coupling.
+ *
+ * @details
+ *
+ *     Function : cmUnpkPrgPMacSMacUeSCellDelReq
+ *
+ *  @param[in]   CfgCfm        fun
+ *  @param[in]   Pst*          pst
+ *  @param[in]   Buffer        *mBuf
+ *  @return   S16
+ *      -# ROK
+ **/
+#ifdef ANSI
+PUBLIC S16 cmUnpkPrgPMacSMacUeSCellDelReq
+(
+RgUeSCellDelReq    func,
+Pst                *pst,
+Buffer             *mBuf
+)
+#else
+PUBLIC S16 cmUnpkPrgPMacSMacUeSCellDelReq(func, pst, mBuf)
+RgUeSCellDelReq  func;
+Pst              *pst;
+Buffer           *mBuf;
+#endif
+{
+  RgPrgUeSCellDelInfo ueSCellDelInfo;
+   
+   TRC2(cmUnpkPrgPMacSMacUeSCellDelReq)
+
+   if(SRemPreMsgMult((Data *)&ueSCellDelInfo, sizeof(RgPrgUeSCellDelInfo),\
+            mBuf) != ROK)
+   {
+      RGPRG_FREE_MSG(mBuf);
+      RETVALUE(RFAILED);
+   }
+
+   RGPRG_FREE_MSG(mBuf);
+   RETVALUE((*func)(pst, &ueSCellDelInfo));
+}
+
+/** 
+ * @brief Ue Lch Addition  Req from PMac to SMac.
+ * @details This primitive is used for light-weight loose coupling.
+ *
+ * @details
+ *
+ *     Function : cmPkPrgPMacSMacUeSCellLchAddReq
+ *
+ *  @param[in]   Pst*                      pst
+ *  @param[in]   RgPrgUeSCellLchAddInfo   *lchCfgInfo
+ *  @return   S16
+ *      -# ROK
+ **/
+#ifdef ANSI
+PUBLIC S16 cmPkPrgPMacSMacUeSCellLchAddReq
+(
+Pst                      *pst,
+RgPrgUeSCellLchAddInfo   *lchCfgInfo,
+)
+#else
+PUBLIC S16 cmPkPrgPMacSMacUeSCellLchAddReq(pst, lchCfgInfo)
+Pst                       *pst;
+RgPrgUeSCellLchAddInfo    *lchCfgInfo;
+#endif
+{
+   Buffer *mBuf = NULLP;
+
+   TRC2(cmPkPrgPMacSMacUeSCellLchAddReq)
+
+   if (SGetMsg(pst->region, pst->pool, &mBuf) != ROK) 
+   {
+      RETVALUE(RFAILED);
+   }
+   
+   if(SAddPstMsgMult((Data *)lchCfgInfo, sizeof(RgPrgUeSCellLchAddInfo),\
+            mBuf) != ROK)
+   {
+      RGPRG_FREE_MSG(mBuf);
+      RETVALUE(RFAILED);
+   }
+
+   pst->event = (Event) EVTPRGUESCELLLCHADDREQ;
+   RETVALUE(SPstTsk(pst,mBuf));
+}
+
+/** 
+ * @brief LCH Addition Req from PMac to SMac.
+ * @details This primitive is used for light-weight loose coupling.
+ *
+ * @details
+ *
+ *     Function : cmUnpkPrgPMacSMacUeSCellLchAddReq
+ *
+ *  @param[in]   Pst*                     pst
+ *  @param[in]   RgPrgUeSCellLchAddInfo   *lchCfgInfo
+ *  @param[in]Buffer                      *mBuf
+ *  @return   S16
+ *      -# ROK
+ **/
+#ifdef ANSI
+PUBLIC S16 cmUnpkPrgPMacSMacUeSCellLchAddReq
+(
+RgPrgUeSCellLchAddInfo       func,
+Pst                          *pst,
+Buffer                       *mBuf
+)
+#else
+PUBLIC S16 cmUnpkPrgPMacSMacUeSCellLchAddReq(func, pst, mBuf)
+RgPrgUeSCellLchAddInfo       func;
+Pst                          *pst;
+Buffer                       *mBuf;
+#endif
+{
+   RgPrgLchRecfgInfo    lchCfgInfo;
+   
+   TRC2(cmUnpkPrgPMacSMacUeSCellLchAddReq)
+
+   if(SRemPreMsgMult((Data *)&lchCfgInfo, sizeof(RgPrgUeSCellLchAddInfo), mBuf) != ROK)
+   {
+      RGPRG_FREE_MSG(mBuf);
+      RETVALUE(RFAILED);
+   }
+
+   RGPRG_FREE_MSG(mBuf);
+   RETVALUE((*func)(pst, &lchCfgInfo));
+}
+
+/** 
+ * @brief Ue SCell Delete Req from PMac to SMac.
+ * @details This primitive is used for light-weight loose coupling.
+ *
+ * @details
+ *
+ *     Function : cmPkPrgPMacSMacUeSCellLchDelReq
+ *
+ *  @param[in]   Pst                       *pst
+ *  @param[in]   RgPrgUeSCellLchDelInfo    *delLcCb
+ *  @return   S16
+ *      -# ROK
+ **/
+#ifdef ANSI
+PUBLIC S16 cmPkPrgPMacSMacUeSCellLchDelReq
+(
+Pst                       *pst,
+RgPrgUeSCellLchDelInfo    *delLcCb
+)
+#else
+PUBLIC S16 cmPkPrgPMacSMacUeSCellLchDelReq(pst, delLcCb)
+Pst                       *pst;
+RgPrgUeSCellLchDelInfo    *delLcCb;
+#endif
+{
+   Buffer *mBuf = NULLP;
+
+   TRC2(cmPkPrgPMacSMacUeSCellLchDelReq)
+
+   if (SGetMsg(pst->region, pst->pool, &mBuf) != ROK) 
+   {
+      RETVALUE(RFAILED);
+   }
+   
+   if(SAddPstMsgMult((Data *)delLcCb, sizeof(RgPrgUeSCellLchDelInfo),\
+            mBuf) != ROK)
+   {
+      RGPRG_FREE_MSG(mBuf);
+      RETVALUE(RFAILED);
+   }
+
+   pst->event = (Event) EVTPRGUESCELLLCHDELREQ;
+   RETVALUE(SPstTsk(pst,mBuf));
+}
+
+
+/** 
+ * @brief Ue Lch reCfg Req from PMac to SMac.
+ * @details This primitive is used for light-weight loose coupling.
+ *
+ * @details
+ *
+ *     Function : cmPkPrgPMacSMacUeSCellLchModReq
+ *
+ *  @param[in]   Pst                      *pst
+ *  @param[in]   RgPrgUeSCellLchModInfo   *lchCfgInfo
+ *  @return   S16
+ *      -# ROK
+ **/
+#ifdef ANSI
+PUBLIC S16 cmPkPrgPMacSMacUeSCellLchModReq
+(
+Pst                      *pst,
+RgPrgUeSCellLchModInfo   *lchCfgInfo
+)
+#else
+PUBLIC S16 cmPkPrgPMacSMacUeSCellLchModReq(pst, lchCfgInfo)
+Pst                       *pst;
+RgPrgUeSCellLchModInfo    *lchCfgInfo;
+#endif
+{
+   Buffer *mBuf = NULLP;
+
+   TRC2(cmPkPrgPMacSMacUeSCellLchModReq)
+
+   if (SGetMsg(pst->region, pst->pool, &mBuf) != ROK) 
+   {
+      RETVALUE(RFAILED);
+   }
+   
+   if(SAddPstMsgMult((Data *)lchCfgInfo, sizeof(RgPrgUeSCellLchModInfo),\
+            mBuf) != ROK)
+   {
+      RGPRG_FREE_MSG(mBuf);
+      RETVALUE(RFAILED);
+   }
+
+   pst->event = (Event) EVTPRGUESCELLLCHMODREQ;
+   RETVALUE(SPstTsk(pst,mBuf));
+}
+
+
+/** 
+ * @brief LCH Cfg Req from PMac to SMac.
+ * @details This primitive is used for light-weight loose coupling.
+ *
+ * @details
+ *
+ *     Function : cmUnpkPrgPMacSMacUeSCellLchModReq
+ *
+ *  @param[in]   Pst*                pst
+ *  @param[in]   RgPrgLchRecfgInfo   *lchCfgInfo
+ *  @param[in]   Buffer              *mBuf
+ *  @return   S16
+ *      -# ROK
+ **/
+#ifdef ANSI
+PUBLIC S16 cmUnpkPrgPMacSMacUeSCellLchModReq
+(
+RgPrgUeScellModLchReq   func,
+Pst                     *pst,
+Buffer                  *mBuf
+)
+#else
+PUBLIC S16 cmUnpkPrgPMacSMacAddLchCfgReq(func, pst, mBuf)
+RgPrgUeScellModLchReq   func;
+Pst                     *pst;
+Buffer                  *mBuf;
+#endif
+{
+   RgPrgUeSCellLchModInfo   lchCfgInfo;
+   
+   TRC2(cmUnpkPrgPMacSMacAddLchCfgReq)
+
+   if(SRemPreMsgMult((Data *)&lchCfgInfo, sizeof(RgPrgUeSCellLchModInfo), mBuf) != ROK)
+   {
+      RGPRG_FREE_MSG(mBuf);
+      RETVALUE(RFAILED);
+   }
+
+   RGPRG_FREE_MSG(mBuf);
+   RETVALUE((*func)(pst, &lchCfgInfo));
+}
+
+
+/** 
+ * @brief LCH Del Req from PMac to SMac.
+ * @details This primitive is used for light-weight loose coupling.
+ *
+ * @details
+ *
+ *     Function : cmUnpkPrgPMacSMacUeSCellLchDelReq
+ *
+ *  @param[in]   Pst*                    pst
+ *  @param[in]   RgPrgUeScellDelLchReq   func;
+ *  @param[in]   Buffer                  *mBuf;
+ *  @return      S16
+ *      -# ROK
+ **/
+#ifdef ANSI
+PUBLIC S16 cmUnpkPrgPMacSMacUeSCellLchDelReq
+(
+RgPrgUeScellDelLchReq   func,
+Pst                     *pst,
+Buffer                  *mBuf
+)
+#else
+PUBLIC S16 cmUnpkPrgPMacSMacUeSCellLchDelReq(func, pst, mBuf)
+RgPrgUeScellDelLchReq   func;
+Pst                     *pst;
+Buffer                  *mBuf;
+#endif
+{
+   RgPrgUeSCellLchDelInfo   lchCfgInfo;
+   
+   TRC2(cmUnpkPrgPMacSMacUeSCellLchDelReq)
+
+   if(SRemPreMsgMult((Data *)&lchCfgInfo, sizeof(RgPrgUeSCellLchDelInfo), mBuf) != ROK)
+   {
+      RGPRG_FREE_MSG(mBuf);
+      RETVALUE(RFAILED);
+   }
+
+   RGPRG_FREE_MSG(mBuf);
+   RETVALUE((*func)(pst, &lchCfgInfo));
+}
+
+#endif /*LCPRG*/ 
+#endif /*LTE_ADV*/
+
+/**********************************************************************
+ 
+         End of file
+**********************************************************************/
diff --git a/src/5gnrmac/rg_prg.h b/src/5gnrmac/rg_prg.h
new file mode 100755
index 000000000..067f8b2ed
--- /dev/null
+++ b/src/5gnrmac/rg_prg.h
@@ -0,0 +1,85 @@
+/*******************************************************************************
+################################################################################
+#   Copyright (c) [2017-2019] [Radisys]                                        #
+#                                                                              #
+#   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.                                             #
+################################################################################
+*******************************************************************************/
+
+/**********************************************************************
+     Name:    MAC to MAC interface (PRG)
+
+     Type:    C header file
+
+     Desc:    Constants needed for PRG(MAC to MAC) interface
+
+     File:    rg_prg.h
+
+*********************************************************************21*/
+
+#ifndef __RGPRG_H__ 
+#define __RGPRG_H__
+
+#ifdef LTE_ADV
+
+#define RG_PRG_MAX                     1             /* MAC interface support only LC and TC*/
+#define PRG_DIR_TX                     CRG_DIR_TX    /*!< Macreo for Transmit 
+                                                      *   direction Mask */
+#define PRG_DIR_RX                     CRG_DIR_RX    /*!< Macro For Receive
+                                                      *   direction Mask */
+#define PRG_DIR_TX_RX                  CRG_DIR_TX_RX /*!< Macro for Transmitt and Receive
+                                                      *   direction Mask */
+/* Event corresponding to each primitive at this interface. PRG interface
+ *events values starts from 50 onwards and 1 to 49 reserved for SCH interface*/
+#define EVTPRGUESCELLCFGREQ           50  /* Add Ue SCell Config Req from PMAC
+                                            to SMAC*/
+#define EVTPRGUESCELLCFGCFM           51  /* Config confirm for Add Ue Scell on PRG
+                                            interface from SMAC to PMAC*/
+#define EVTPRGUESCELLDELREQ           52  /* Ue SCell delete Req from PMAC to
+                                            SMAC*/
+#define EVTPRGUESCELLLCHMODREQ        53    /*  SCell Lch recfg Req from PMAC to
+                                            SMAC*/
+
+#define EVTPRGUESCELLLCHMODCFM        54    /* Lch ReConfig confirm for Scell on PRG
+                                            interface from SMAC to PMAC*/
+
+#define EVTPRGUESCELLLCHDELCFM        55    /* Delete Lch  confirm for Scell on PRG
+                                            interface from SMAC to PMAC*/
+
+#define EVTPRGUESCELLLCHDELREQ        56    /* Delete Lch request for Scell on PRG
+                                            interface from SMAC to PMAC*/
+
+#define EVTPRGUESCELLLCHADDREQ        57    /* Lch config req for Scell on PRG 
+                                                  interface from SMAC to PMAC */
+
+#define EVTPRGUESCELLLCHADDCFM        58    /* Lch Config confirm for Scell on PRG
+                                            interface from SMAC to PMAC*/
+#define PRG_CFG_CFM_OK    CRG_CFG_CFM_OK  /* mapping to CRG NOK macro*/
+#define PRG_CFG_CFM_NOK   CRG_CFG_CFM_NOK /* mapping to CRG NOK macro*/
+
+#define RGPRG_FREE_MSG(_buf)\
+{\
+   if (NULLP != (_buf)) \
+   { \
+      SPutMsg((_buf)); \
+      _buf = NULLP; \
+   } \
+}
+
+#endif /* LTE_ADV*/
+#endif /* __RGPRG_H__ */
+
+/********************************************************************30**
+
+         End of file:     rg_prg.h
+**********************************************************************/
diff --git a/src/5gnrmac/rg_prg.x b/src/5gnrmac/rg_prg.x
new file mode 100755
index 000000000..d45c35c0c
--- /dev/null
+++ b/src/5gnrmac/rg_prg.x
@@ -0,0 +1,523 @@
+/*******************************************************************************
+################################################################################
+#   Copyright (c) [2017-2019] [Radisys]                                        #
+#                                                                              #
+#   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.                                             #
+################################################################################
+*******************************************************************************/
+
+/**********************************************************************
+
+  Name:     LTE-MAC layer 
+  
+  Type:     C Include File 
+  
+  Desc:     Structures, variables, and typedefs required by the interface between
+            Two MAC instances(PRG = MAC to MAC).
+
+  File:     rg_prg.x 
+
+**********************************************************************/
+/** 
+  @file rg_Prg.x 
+  @brief Structure declarations and definitions for MAC-MAC (PRG) interface.
+  */
+
+#ifndef __RGPRG_X__ 
+#define __RGPRG_X__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef L2_OPTMZ
+typedef TfuDatReqTbInfo    RgPrgDatReqTbInfo;
+#endif
+
+/** 
+  * @brief Typedef for uplink Dedicated Logical channel group Id.
+  */
+typedef U8                 RgPrgLteLcgId;
+
+/** 
+  * @brief Structure to hold uplink Dedicated Logical channel info.
+  *
+  * @details
+  *    - lcId      : Logical channel ID at MAC
+  *    - lcgId     : Logical channel group ID at MAC
+  *    - qci       : QCI for this logical channel control block
+  *    - measOn    : TRUE if Timing Info needs to be fetched for scheduled UL
+  *                  IP throughput else FALSE
+  */
+typedef struct rgPrgUlLcInfo
+{
+   CmLteLcId     lcId;    /*!< Logical channel ID */
+   RgPrgLteLcgId      lcgId;    /*!< Logical channel group */
+#ifdef LTE_L2_MEAS
+   U8              qci;     /*!< QCI for this logical channel control block */
+
+   Bool          measOn;   /*!< TRUE if Timing Info needs to be fetched for
+                             Scheduled UL IP throughput else FALSE */
+
+#endif
+}RgPrgUlLcInfo;
+
+/** 
+  * @brief Structure to hold logical channel group information
+  *
+  * @Details
+  *    - lcgId   : Logical channel group ID at MAC
+  *    - lcCount : Logical channel count
+  *    - isGbr   : Indicate if LCG is GBR LCG
+  */
+typedef struct rgPrgLcgInfo
+{
+   /* Right now not keeping associated logical channels, searching for
+    * associated channels needed only during config */
+   RgPrgLteLcgId    lcgId;   /*!< Group ID */
+   U8               lcCount; /*!< Lc count */
+   Bool             isGbr;   /*!< Indicate if LCG is GBR LCG */
+}RgPrgLcgInfo;
+
+/** 
+  * @brief Structure to hold downlink Dedicated Logical channel info.
+  * 
+  * @Details
+  *   - lcId   : Logical channel ID at MAC
+  */
+typedef struct rgPrgDlLcInfo
+{
+   CmLteLcId            lcId;    /*!< Logical channel ID */
+}RgPrgDlLcInfo;
+
+#ifdef LTE_ADV
+/** 
+  * @brief Structure to hold Config req from PMAC to SMAC.
+  * 
+  * @details
+  *   - ueId        : UE identifier
+  *   - cellId      : Cell ID
+  *   - maxUlHqRetx : Maximum number of harq retx
+  *   - ulLcInfo    : Dedicated Uplink logical channel info
+  *   - lcgInfo     :  Logical channel groups
+  *   - dlLcInfo    : Dedicated Downlink logical channels in UE
+  *   - txMode      : UE Transmission mode Cfg
+  *   - rguDlSapId  : Sap id for associated with RLC DL
+  *   - rguUlSapId  : Sap id for associated with RLC UL
+  */
+typedef struct rgPrgUeSCellCfgInfo
+{
+   CmLteRnti            ueId;            /*!< UE identifier */
+   CmLteCellId          cellId;          /*!< Cell ID */
+
+   U8                   maxUlHqRetx;     /*!< Maximum number of harq
+                                          * re-transmissions */ 
+   RgPrgUlLcInfo        ulLcInfo[RG_MAX_LC_PER_UE];  /*!< Dedicated Uplink 
+                                                logical channel information */
+   RgPrgLcgInfo         lcgInfo[RG_MAX_LCG_PER_UE]; /*!< Logical channel 
+                                                 groups */
+   RgPrgDlLcInfo        dlLcInfo[RG_MAX_LC_PER_UE];  /*!< Dedicated Downlink 
+                                                 logical channels in UE */
+
+   CrgTxMode            txMode;          /*!< UE Transmission mode Cfg */
+
+   SuId                 rguDlSapId;      /* !< Sap id for associated 
+                                     with RLC DL */
+   SuId                 rguUlSapId;      /* !< Sap id for associated 
+                                      with RLC UL */
+}RgPrgUeSCellCfgInfo;
+
+/** 
+  * @brief Structure to hold config confirm info from PMAC to SMAC.
+  * 
+  * @details
+  *   - ueId    : UE identifier
+  *   - sCellId : SCell ID
+  *   - status  : status (OK/NOK)
+  */
+typedef struct rgPrgCfgCfmInfo
+{
+   CmLteRnti       ueId;    /*!< UE identifier */
+   CmLteCellId     sCellId;  /*!< SCell ID */
+   U8              status;  /*!< Status: OK/NOK */
+   U8              event;   /*!< type of event */ 
+}RgPrgCfgCfmInfo;
+
+/** 
+  * @brief  Structure to hold Ue delete Req/Ue Id change Info from PMAC to SMAC.
+  *
+  * @details
+  *    - ueId     : UE identifier
+  *    - sCellId  : sCell ID
+  *    - newRnti  : new RNTI changed as part of reestablishment
+  **/
+typedef struct rgPrgUeSCellDelInfo
+{
+   CmLteRnti       ueId;     /*!< UE identifier */
+   CmLteCellId     sCellId;  /*!< sCell ID */
+   CmLteRnti       newRnti;  /*!< new RNTI changed as part of reestablishment */
+}RgPrgUeSCellDelInfo;
+
+/** 
+  * @brief Structure to hold LC Config req from PMAC to SMAC.
+  * 
+  * @details
+  *   - cellId      : Cell ID
+  *   - crnti       : CRNTI for DTCH and DCCH
+  *   - lcId        : Logical Channel Id
+  *   - lcgId       : Logical channel group Id
+  */
+typedef struct rgPrgUeSCellLchModInfo
+{
+   CmLteCellId cellId;       /*!< Cell ID */
+   CmLteRnti   crnti;        /*!< CRNTI for DTCH and DCCH */
+   CmLteLcId   lcId;         /*!< Logical channel ID */
+
+   struct ulLchRecfgS
+   {
+      U8             lcgId;  /*!< Logical channel group ID */
+   } ulLchRecfg;                /*!< Uplink logical channel reconfiguration
+                               information */
+}RgPrgUeSCellLchModInfo;
+
+/** 
+  * @brief Structure to hold LC Config req for deletion from PMAC to SMAC.
+  * 
+  * @details
+  *   - cellId      : Cell ID
+  *   - crnti       : CRNTI for DTCH and DCCH
+  *   - lcId        : Logical Channel Id
+  *   - dir         : Indicates Direction
+  */
+typedef struct rgPrgUeSCellLchDelInfo
+{
+   CmLteCellId cellId;       /*!< Cell ID */
+   CmLteRnti   crnti;        /*!< CRNTI for DTCH and DCCH */
+   CmLteLcId   lcId;         /*!< Logical channel ID */
+   U8          dir;          /*!< Indicates Direction. Direction can take following
+                            values:
+ PRG_DIR_TX
+ PRG_DIR_RX
+ PRG_DIR_TX_RX + */ +}RgPrgUeSCellLchDelInfo; + +/** + * @brief Logical channel configuration information for uplink logical channels. + * + * @details + * -ulTrchType : Indicates type of UL transport channel: + Validated only for BCCH at MAC. + UL Transport channel type can take following values:
+ CM_LTE_TRCH_RACH
+ CM_LTE_TRCH_UL_SCH + * -lcgId; : Logical channel group ID + */ +typedef struct rgPrgUlLchCfg +{ + U8 ulTrchType; /*!< Indicates type of UL transport channel: + Validated only for BCCH at MAC. + UL Transport channel type can take following values:
+ CM_LTE_TRCH_RACH
+ CM_LTE_TRCH_UL_SCH */ + U8 lcgId; /*!< Logical channel group ID */ +} RgPrgUlLchCfg; + + +/** + * @brief Logical channel configuration information for downlink logical channels. + * + * @details + * -dlTrchType : Indicates type of DL transport channel: + Validated only for BCCH at MAC. DL Transport + channel type can take following values:
+ CM_LTE_TRCH_BCH
+ CM_LTE_TRCH_PCH
+ CM_LTE_TRCH_DL_SCH +*/ +typedef struct rgPrgDlLchCfg +{ + U8 dlTrchType; /*!< Indicates type of DL transport channel: + Validated only for BCCH at MAC. DL Transport + channel type can take following values:
+ CM_LTE_TRCH_BCH
+ CM_LTE_TRCH_PCH
+ CM_LTE_TRCH_DL_SCH */ +} RgPrgDlLchCfg; + /** @brief Logical channel configuration information for common and dedicated channels. + * + * @details + * cellId : Cell ID + * crnti : CRNTI for DTCH and DCCH + * lcId : Logical channel ID + * lcType : Identifies the Logical channel type. lcType can take the following values:
+ CM_LTE_LCH_BCCH
+ CM_LTE_LCH_PCCH
+ CM_LTE_LCH_CCCH
+ CM_LTE_LCH_DCCH
+ CM_LTE_LCH_DTCH + + * dir : Indicates Direction. Direction can take following + values:
+ PRG_DIR_TX
+ PRG_DIR_RX
+ PRG_DIR_TX_RX + + * dlInfo : Downlink logical channel configuration info + * ulInfo : Uplink logical channel configuration info + + * qci; : QCI for the logical channel. + Valid Range:[0-255] (Actual QCI - 1). +*/ +typedef struct rgPrgUeSCellLchAddInfo +{ + CmLteCellId cellId; /*!< Cell ID */ + CmLteRnti crnti; /*!< CRNTI for DTCH and DCCH */ + CmLteLcId lcId; /*!< Logical channel ID */ + CmLteLcType lcType; /*!< Identifies the Logical channel type. lcType can take the following values:
+ CM_LTE_LCH_BCCH
+ CM_LTE_LCH_PCCH
+ CM_LTE_LCH_CCCH
+ CM_LTE_LCH_DCCH
+ CM_LTE_LCH_DTCH */ + + U8 dir; /*!< Indicates Direction. Direction can take following + values:
+ PRG_DIR_TX
+ PRG_DIR_RX
+ PRG_DIR_TX_RX */ + + RgPrgDlLchCfg dlInfo; /*!< Downlink logical channel configuration info */ + RgPrgUlLchCfg ulInfo; /*!< Uplink logical channel configuration info */ +#ifdef LTE_L2_MEAS + U8 qci; /*!< QCI for the logical channel. + Valid Range:[0-255] (Actual QCI - 1). */ + +#endif /* LTE_L2_MEAS */ +} RgPrgUeSCellLchAddInfo; + + +/* + Function Prototypes + */ +/** @brief Request from PMAC to SMAC to add Ue Scell config. */ +EXTERN S16 RgPrgPMacSMacUeSCellCfg ARGS + (( + Pst *pst, + RgPrgUeSCellCfgInfo *ueSCellCb + )); + +/** @brief Request from PMAC to SMAC to add Ue Scell config. */ +EXTERN S16 RgPrgPMacSMacUeSCellCfgReq ARGS +(( + Pst *pst, + RgPrgUeSCellCfgInfo *ueSCellCb +)); + +/** @brief Function ptr for Request from PMAC to SMAC to add Ue Scell config.*/ +typedef S16 (*RgPrgUeSCellCfgReq) ARGS (( + Pst* pst, + RgPrgUeSCellCfgInfo *ueSCellCb + )); + +/** @brief Config confirm of Ue SCell config Req from SMAC to PMAC */ +EXTERN S16 RgPrgSMacPMacCfg ARGS (( + Pst *pst, + RgPrgCfgCfmInfo *cfgCfm + )); + +/** @brief Config confirm from SMAC to PMAC */ +EXTERN S16 RgPrgSMacPMacCfgCfm ARGS (( + Pst *pst, + RgPrgCfgCfmInfo *cfgCfm + )); + +/** @brief Function ptr for Config confirm from SMAC to PMAC */ +typedef S16 (*RgSMacPMacCfgCfm) ARGS(( + Pst* pst, + RgPrgCfgCfmInfo *cfgCfm + )); + +/** + * @brief Ue SCell cfg delete Req from PMac to SMac*/ +EXTERN S16 RgPrgPMacSMacUeSCellDel ARGS (( + Pst *pst, + RgPrgUeSCellDelInfo *sCellUedelReq + )); + +/** + * @brief Ue SCell cfg delete Req from PMac to SMac*/ +EXTERN S16 RgPrgPMacSMacUeSCellDelReq ARGS (( + Pst *pst, + RgPrgUeSCellDelInfo *sCellUedelReq + )); + +/** + * @brief Function ptr to Ue SCell cfg delete Req from PMac to SMac*/ +typedef S16 (*RgUeSCellDelReq) ARGS(( + Pst *pst, + RgPrgUeSCellDelInfo *sCellUedelReq + )); + +#ifdef LCPRG +/** + * @brief Ue SCell Cfg Req from PMac to SMac. + * @details This primitive is used for light-weight loose coupling. + */ +EXTERN S16 cmPkPrgPMacSMacUeSCellCfgReq ARGS (( + Pst *pst, + RgPrgUeSCellCfgInfo *ueSCellCb + )); + +EXTERN S16 cmUnpkPrgPMacSMacUeSCellCfgReq ARGS (( + RgPrgUeSCellCfgReq func, + Pst *pst, + Buffer *mBuf + )); + +/** + * @brief Ue SCell Add Cfg cfm from SMac to PMac. + * @details This primitive is used for light-weight loose coupling. + */ +EXTERN S16 cmPkPrgSMacPMacCfgCfm ARGS(( + Pst *pst, + RgPrgCfgCfmInfo *cfgCfm + )); + + +EXTERN S16 cmUnpkPrgSMacPMacCfgCfm ARGS(( + RgSMacPMacCfgCfm func, + Pst *pst, + Buffer *mBuf + )); +/** + * @brief SCell Ue Delete Req from PMac to SMac. + * @details This primitive is used for light-weight loose coupling. + */ +EXTERN S16 cmPkPrgPMacSMacUeSCellDelReq ARGS(( + Pst *pst, + RgPrgUeSCellDelInfo *sCellUeDelInfo + )); + + +EXTERN S16 cmUnpkPrgPMacSMacUeSCellDelReq ARGS(( + RgUeSCellDelReq func, + Pst *pst, + Buffer *mBuf + )); + + +/** + * @brief Ue Lch recfg Req from PMac to SMac. + * @details This primitive is used for light-weight loose coupling. + */ +EXTERN S16 cmPkPrgPMacSMacUeSCellLchModReq ARGS(( + Pst *pst, + RgPrgUeSCellLchModInfo *lchCfgCb + )); + +EXTERN S16 cmUnpkPrgPMacSMacUeSCellLchModReq ARGS(( + RgPrgUeScellModLchReq func, + Pst *pst, + Buffer *mBuf + )); + +/** + * @brief SCell Ue Delete Req from PMac to SMac. + * @details This primitive is used for light-weight loose coupling. + */ +EXTERN S16 cmPkPrgPMacSMacUeSCellLchDelReq ARGS(( + Pst *pst, + RgPrgUeSCellLchDelInfo *delLcCb + )); + + +EXTERN S16 cmUnpkPrgPMacSMacUeSCellLchDelReq ARGS(( + RgPrgUeScellDelLchReq func, + Pst *pst, + Buffer *mBuf + )); + +/** + * @brief Ue Lch cfg Req from PMac to SMac. + * @details This primitive is used for light-weight loose coupling. + */ +EXTERN S16 cmPkPrgPMacSMacUeSCellLchAddReq ARGS (( + Pst *pst, + RgPrgUeSCellLchAddInfo *lchCfgCb + )); + +EXTERN S16 cmUnpkPrgPMacSMacUeSCellLchAddReq ARGS (( + RgPrgUeScellAddLchReq func, + Pst *pst, + Buffer *mBuf + )); + + +#endif /* LCPRG */ + +/** @brief Request from PMAC to SMAC to add Lch Reconfig. */ +EXTERN S16 RgPrgPMacSMacUeScellLchMod ARGS + (( + Pst *pst, + RgPrgUeSCellLchModInfo *lchCfgCb + )); + +/** @brief Request from PMAC to SMAC to add Lch Reconfig. */ + +/** @brief Function ptr for Request from PMAC to SMAC to add Lch Reconfig.*/ +typedef S16 (*RgPrgUeScellModLchReq) ARGS(( + Pst* pst, + RgPrgUeSCellLchModInfo *lchCfgCb + )); + +/** @brief Request from PMAC to SMAC to delete Lch . */ +EXTERN S16 RgPrgPMacSMacUeScellLchDel ARGS + (( + Pst *pst, + RgPrgUeSCellLchDelInfo *delLcCb + )); + +/** @brief Request from PMAC to SMAC to delete Lch. */ + +/** @brief Function ptr for Request from PMAC to SMAC to delete Lch.*/ +typedef S16 (*RgPrgUeScellDelLchReq) ARGS(( + Pst* pst, + RgPrgUeSCellLchDelInfo *delLcCb + )); + + +/** @brief Request from PMAC to SMAC to add Lch config. */ +EXTERN S16 RgPrgPMacSMacUeScellLchAdd ARGS + (( + Pst *pst, + RgPrgUeSCellLchAddInfo *lchCfgCb + )); + +/** @brief Request from PMAC to SMAC to add Lch config. */ + +/** @brief Function ptr for Request from PMAC to SMAC to add Lch config.*/ +typedef S16 (*RgPrgUeScellAddLchReq) ARGS + ((Pst *pst, + RgPrgUeSCellLchAddInfo *lchCfgCb + )); +#endif /* LTE_ADV */ +#ifdef __cplusplus +} +#endif +#endif /* __RGPRG_X__*/ + +/********************************************************************** + + End of file: rg_prg.x +**********************************************************************/ diff --git a/src/5gnrmac/rg_prg_pt.c b/src/5gnrmac/rg_prg_pt.c new file mode 100755 index 000000000..f8060546f --- /dev/null +++ b/src/5gnrmac/rg_prg_pt.c @@ -0,0 +1,325 @@ +/******************************************************************************* +################################################################################ +# Copyright (c) [2017-2019] [Radisys] # +# # +# 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. # +################################################################################ +*******************************************************************************/ + +/************************************************************************ + + Name: LTE-MAC layer + + Type: C source file + + Desc: C source code for MAC to MAC (PRG) interface + + File: rg_prg_pt.c + +**********************************************************************/ + +/* header include files -- defines (.h) */ +#include "envopt.h" /* environment options */ +#include "envdep.h" /* environment dependent */ +#include "envind.h" /* environment independent */ +#include "gen.h" /* general layer */ +#include "ssi.h" /* system service interface */ +#include "cm_hash.h" /* common hash list */ +#include "cm_mblk.h" /* common memory link list library */ +#include "cm_llist.h" /* common linked list library */ +#include "cm_err.h" /* common error */ +#include "cm_lte.h" /* common LTE */ +#include "lrg.h" /* layer manager for MAC */ +#include "crg.h" /* CRG interface includes*/ +#include "rgu.h" /* RGU interface includes*/ +#include "tfu.h" /* TFU interface includes*/ +#include "rg_sch_inf.h" /* SCH interface includes*/ +#include "rg_prg.h" /* PRG interface includes*/ +#include "rg_env.h" /* MAC Enviroments includes */ +#include "rg.h" /* MAC includes*/ +#include "rg_err.h" /* MAC error includes*/ + +/* header/extern include files (.x) */ +#include "gen.x" /* general layer typedefs */ +#include "ssi.x" /* system services typedefs */ +#include "cm5.x" /* common timers */ +#include "cm_hash.x" /* common hash list */ +#include "cm_lib.x" /* common library */ +#include "cm_llist.x" /* common linked list */ +#include "cm_mblk.x" /* memory management */ +#include "cm_tkns.x" /* common tokens */ +#include "cm_lte.x" /* common tokens */ +#include "rgu.x" /* RGU types */ +#include "tfu.x" /* RGU types */ +#include "lrg.x" /* layer management typedefs for MAC */ +#include "crg.x" /* layer management typedefs for MAC */ +#include "rg_sch_inf.x" /* layer management typedefs for MAC */ +#include "rg_prg.x" /* PRG interface typedefs*/ +#include "rg.x" /* typedefs for MAC */ + +#ifdef LTE_ADV +#include "rg_pom_scell.x" + +/* Matrix for Ue SCell Config Req*/ +PRIVATE CONSTANT RgPrgUeSCellCfgReq RgPrgPMacSMacUeSCellCfgReqMt[RG_PRG_MAX] = +{ +#ifdef LCPRG + cmPkPrgPMacSMacUeSCellCfgReq, +#else + RgPrgPMacSMacUeSCellCfgReq +#endif +}; + +/** +* @brief Ue SCell config Req from PMac to SMac +* +* @details +* +* Function : RgPrgPMacSMacUeSCellCfg +* +* @param[in] Pst *pst +* @param[in] RgPrgUeSCellCfgInfo *ueSCellCfgInfo; +* @return S16 +* -# ROK +**/ +#ifdef ANSI +PUBLIC S16 RgPrgPMacSMacUeSCellCfg +( + Pst *pst, + RgPrgUeSCellCfgInfo *ueSCellCfgInfo +) +#else +PUBLIC S16 RgPrgPMacSMacUeSCellCfg(pst, ueSCellCfgInfo) + Pst *pst; + RgPrgUeSCellCfgInfo *ueSCellCfgInfo; +#endif +{ + + TRC3(RgPrgPMacSMacUeSCellCfg); + + RETVALUE((*RgPrgPMacSMacUeSCellCfgReqMt[0])(pst, ueSCellCfgInfo)); +} + +/* Matrix for config confirm from SMac to Pmac*/ +PRIVATE CONSTANT RgSMacPMacCfgCfm RgPrgSMacPMacCfgCfmMt[RG_PRG_MAX] = +{ +#ifdef LCPRG + cmPkPrgSMacPMacCfgCfm, +#else + RgPrgSMacPMacCfgCfm +#endif +}; + +/** +* @brief Config confirm from SMac to PMac for Ue Cell Config Req +* +* @details +* +* Function :RgPrgSMacPMacCfg +* +* @param[in] Pst *pst +* @param[in] RgPrgCfgCfmInfo *cfmCfm +* @return S16 +* -# ROK +**/ +#ifdef ANSI +PUBLIC S16 RgPrgSMacPMacCfg +( + Pst *pst, + RgPrgCfgCfmInfo *cfgCfm +) +#else +PUBLIC S16 RgPrgSMacPMacCfg(pst, cfgCfm) + Pst *pst; + RgPrgCfgCfmInfo *cfgCfm; +#endif +{ + + TRC3(RgPrgSMacPMacCfg); + + RETVALUE((*RgPrgSMacPMacCfgCfmMt[0])(pst, cfgCfm)); +} + +/* Matrix for Ue SCell delete req/Ue Id change req from PMac to SMac */ +PRIVATE CONSTANT RgUeSCellDelReq RgPrgPMacSMacUeSCellDelReqMt[RG_PRG_MAX] = +{ +#ifdef LCPRG + cmPkPrgPMacSMacUeSCellDelReq, +#else + RgPrgPMacSMacUeSCellDelReq +#endif +}; + +/** +* @brief Ue SCell delete Req/Ue Id change Req from PMac to SMac +* +* @details +* +* Function : RgPrgPMacSMacUeSCellDel +* +* @param[in] Pst *pst +* @param[in] RgPrgUeSCellDelInfo *ueSCellDelInfo; +* @return S16 +* -# ROK +**/ +#ifdef ANSI +PUBLIC S16 RgPrgPMacSMacUeSCellDel +( + Pst *pst, + RgPrgUeSCellDelInfo *ueSCellDelInfo +) +#else +PUBLIC S16 RgPrgPMacSMacUeSCellDel(pst, ueSCellDelInfo) + Pst *pst; + RgPrgUeSCellDelInfo *ueSCellDelInfo; +#endif +{ + + TRC3(RgPrgPMacSMacUeSCellDel); + + RETVALUE((*RgPrgPMacSMacUeSCellDelReqMt[0])(pst, ueSCellDelInfo)); +} + + + +/* Matrix for Lch ReConfig Req*/ +PRIVATE CONSTANT RgPrgUeScellModLchReq RgPrgPMacSMacUeScellModLchReqMt[RG_PRG_MAX] = +{ +#ifdef LCPRG + cmPkPrgPMacSMacUeSCellLchModReq, +#else + RgPrgPMacSMacUeSCellLchModReq +#endif +}; + + +/** +* @brief Ue Lch Reconfig Req from PMac to SMac +* +* @details +* +* Function : RgPrgPMacSMacUeScellLchMod +* +* @param[in] Pst *pst +* @param[in] RgPrgUeSCellLchModInfo *lchCfgInfo +* @return S16 +* -# ROK +**/ +#ifdef ANSI +PUBLIC S16 RgPrgPMacSMacUeScellLchMod +( + Pst *pst, + RgPrgUeSCellLchModInfo *lchCfgInfo +) +#else +PUBLIC S16 RgPrgPMacSMacUeScellLchMod(pst, lchCfgInfo) + Pst *pst; + RgPrgUeSCellLchModInfo *lchCfgInfo; +#endif +{ + + TRC3(RgPrgPMacSMacUeScellLchMod); + + RETVALUE((*RgPrgPMacSMacUeScellModLchReqMt[0])(pst, lchCfgInfo)); +} + + +/* Matrix for delete Lch Req*/ +PRIVATE CONSTANT RgPrgUeScellDelLchReq RgPrgPMacSMacUeScellDelLchReqMt[RG_PRG_MAX] = +{ +#ifdef LCPRG + cmPkPrgPMacSMacUeSCellLchDelReq, +#else + RgPrgPMacSMacUeSCellLchDelReq +#endif +}; + + +/** +* @brief Delete Lch Req from PMac to SMac +* +* @details +* +* Function : RgPrgPMacSMacUeScellLchDel +* +* @param[in] Pst *pst +* @param[in] RgPrgUeSCellLchDelInfo *delLcCb +* @return S16 +* -# ROK +**/ +#ifdef ANSI +PUBLIC S16 RgPrgPMacSMacUeScellLchDel +( + Pst *pst, + RgPrgUeSCellLchDelInfo *delLcCb +) +#else +PUBLIC S16 RgPrgPMacSMacUeScellLchDel(pst, delLcCb) + Pst *pst; + RgPrgUeSCellLchDelInfo *delLcCb; +#endif +{ + + TRC3(RgPrgPMacSMacUeScellLchDel); + + RETVALUE((*RgPrgPMacSMacUeScellDelLchReqMt[0])(pst, delLcCb)); +} + + +/* Matrix for Lch Config Req*/ +PRIVATE CONSTANT RgPrgUeScellAddLchReq RgPrgPMacSMacUeScellAddLchReqMt[RG_PRG_MAX] = +{ +#ifdef LCPRG + cmPkPrgPMacSMacUeSCellLchAddReq, +#else + RgPrgPMacSMacUeSCellLchAddReq +#endif +}; + + +/** +* @brief Ue Lch config Req from PMac to SMac +* +* @details +* +* Function : RgPrgPMacSMacUeScellLchAdd +* +* @param[in] Pst *pst +* @param[in] RgPrgUeSCellLchAddInfo *lchCfgInfo +* @return S16 +* -# ROK +**/ +#ifdef ANSI +PUBLIC S16 RgPrgPMacSMacUeScellLchAdd +( + Pst *pst, + RgPrgUeSCellLchAddInfo *lchCfgInfo +) +#else +PUBLIC S16 RgPrgPMacSMacUeScellLchAdd(pst, lchCfgInfo) + Pst *pst; + RgPrgUeSCellLchAddInfo *lchCfgInfo; +#endif +{ + + TRC3(RgPrgPMacSMacUeScellLchAdd); + + RETVALUE((*RgPrgPMacSMacUeScellAddLchReqMt[0])(pst, lchCfgInfo)); +} + +#endif /* LTE_ADV */ + +/********************************************************************** + + End of file +**********************************************************************/ diff --git a/src/5gnrmac/rg_ptli.c b/src/5gnrmac/rg_ptli.c new file mode 100755 index 000000000..13e63041d --- /dev/null +++ b/src/5gnrmac/rg_ptli.c @@ -0,0 +1,1182 @@ +/******************************************************************************* +################################################################################ +# Copyright (c) [2017-2019] [Radisys] # +# # +# 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. # +################################################################################ +*******************************************************************************/ + +/************************************************************************ + + Name: LTE-MAC layer + + Type: C source file + + Desc: C source code for Entry point fucntions + + File: rg_ptli.c + +**********************************************************************/ + +/** @file rg_dhm.c +@brief APIs related to Downlink HARQ. +*/ + +/* header include files (.h) */ +#include "envopt.h" /* environment options */ +#include "envdep.h" /* environment dependent */ +#include "envind.h" /* environment independent */ +#include "gen.h" /* general */ +#include "ssi.h" /* system services */ +#include "cm_tkns.h" /* Common Token Defines */ +#include "cm_llist.h" /* Common Link List Defines */ +#include "cm_hash.h" /* Common Hash List Defines */ +#include "cm_mblk.h" +#include "cm_lte.h" /* Common LTE Defines */ +#include "tfu.h" /* RGU Interface defines */ + +/* header/extern include files (.x) */ +#include "gen.x" /* general */ +#include "ssi.x" /* system services */ +#include "cm_tkns.x" /* Common Token Definitions */ +#include "cm_llist.x" /* Common Link List Definitions */ +#include "cm_lib.x" /* Common Library Definitions */ +#include "cm_hash.x" /* Common Hash List Definitions */ +#include "cm_mblk.x" +#include "cm_lte.x" /* Common LTE Defines */ +#include "tfu.x" /* RGU Interface includes */ + + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#if !(defined(LCRGLITFU) && defined(TF) && defined(LWLCRGLITFU)) +#define PTRGLITFU +#endif + + +/* MAX Number of Service Providers of RG */ +#define RG_MAX_TFU_PROV 3 + +#ifdef PTRGLITFU +/** @brief This API is used to send a Bind Request from MAC to PHY. + * @param pst Pointer to the post structure. + * @param suId SAP ID of the service user. + * @param spId SAP ID of the service provider. + * @return ROK/RFAILED + */ +EXTERN S16 PtLiTfuBndReq ARGS((Pst * pst, SuId suId, SpId spId)); +/** @brief This API is used to send a Bind Request from Scheduler to PHY. + * @param pst Pointer to the post structure. + * @param suId SAP ID of the service user. + * @param spId SAP ID of the service provider. + * @return ROK/RFAILED + */ +EXTERN S16 PtLiTfuSchBndReq ARGS((Pst * pst, SuId suId, SpId spId)); +/** @brief This API is used to send an Unbind Request from MAC to PHY. + * @param pst Pointer to the post structure. + * @param suId SAP ID of the service provider. + * @param reason Reason for Unbind request. + * @return ROK/RFAILED + */ +EXTERN S16 PtLiTfuUbndReq ARGS((Pst * pst, SpId spId, Reason reason)); +/** @brief This API is used to send an Unbind Request from Scheduler to PHY. + * @param pst Pointer to the post structure. + * @param suId SAP ID of the service provider. + * @param reason Reason for Unbind request. + * @return ROK/RFAILED + */ +EXTERN S16 PtLiTfuSchUbndReq ARGS((Pst * pst, SpId spId, Reason reason)); +/** @brief This primitive is sent from Scheduler to PHY. + * @details This primitive provides PHY with all the information required by + * PHY to decode transmissions from the UE on either PUCCH or PUSCH. + * -# On PUCCH UE can transmit the following + * -# SR + * -# HARQ feedback + * -# CQI report + * -# HARQ + CQI + * -# HARQ + SR + * -# On PUSCH UE can transmit the following + * -# Data + * -# Data + CQI + * -# Data + HARQ Feedback + * This primitive carries all the information for the expected subframe for all + * the UEs that have been scheduled to transmit. + * @param pst Pointer to the post structure. + * @param spId SAP ID of the service provider. + * @param recpReq Pointer to the TfuRecpReqInfo structure. + * @return ROK/RFAILED + */ +EXTERN S16 PtLiTfuRecpReq ARGS((Pst * pst, SpId spId, TfuRecpReqInfo * recpReq)); +/** @brief This Primitive is sent from Scheduler to PHY. It provides PHY with + * all the control information + * @details This primitive carries the information sent on the following + * channels - + * -# PDCCH + * -# PHICH + * -# PCFICH + * + * @param pst + * @param spId + * @param cntrlReq pointer to TfuCntrlReqInfo + * @return ROK/RFAILED + */ +EXTERN S16 PtLiTfuCntrlReq ARGS((Pst * pst, SpId spId, TfuCntrlReqInfo * cntrlReq)); +/** @brief This Primitive carries the Data PDUs from MAC to PHY for + * transmission. + * @details The data being sent in this primitive is meant to be transmitted on + * the downlink channel PDSCH and PBCH (if present). To facilitate physical + * layer processing, requisite control information is also sent along with the + * data. + * @sa TfUiTfuCntrlReq + * @param pst + * @param spId + * @param tfuDatReq pointer to TfuDatReqInfo + * @return + */ +EXTERN S16 PtLiTfuDatReq ARGS((Pst * pst, SpId spId, TfuDatReqInfo * datReq)); +#ifdef L2_OPTMZ +/** @brief This Primitive carries cellId and UeId for which datReq need to be deleted. + * @details This primitive is used to send delDatReq to CL to delete the PDUs of + * UE which has been deleted in MAC due to ueId change or anyother scenario + * @details The data being sent in this primitive is meant to be transmitted on + * @sa TfUiTfuDelDatReq + * @param pst + * @param spId + * @param tfuDelDatReq pointer to TfuDelDatReqInfo + * @return + */ +EXTERN S16 PtLiTfuDelDatReq ARGS((Pst * pst, SpId spId, TfuDelDatReqInfo * datReq)); +#endif /*L2_OPTMZ*/ +#endif /*--#ifdef PTRGLITFU--*/ + +/** @brief This API is used to send a Bind Request from MAC to PHY. + * @param pst Pointer to the post structure. + * @param suId SAP ID of the service user. + * @param spId SAP ID of the service provider. + * @return ROK/RFAILED + */ +PRIVATE CONSTANT TfuBndReq RgLiTfuBndReqMt[RG_MAX_TFU_PROV] = +{ +#ifdef LCRGLITFU + cmPkTfuBndReq, +#else + PtLiTfuBndReq, +#endif +#ifdef TF + TfUiTfuBndReq, +#else + PtLiTfuBndReq, +#endif +#ifdef LWLCRGLITFU + cmPkTfuBndReq +#else + PtLiTfuBndReq +#endif +}; + +/** @brief This API is used to send a Bind Request from Scheduler to PHY. + * @param pst Pointer to the post structure. + * @param suId SAP ID of the service user. + * @param spId SAP ID of the service provider. + * @return ROK/RFAILED + */ +PRIVATE CONSTANT TfuSchBndReq RgLiTfuSchBndReqMt[RG_MAX_TFU_PROV] = +{ +#ifdef LCRGLITFU + cmPkTfuSchBndReq, +#else + PtLiTfuSchBndReq, +#endif +#ifdef TF + TfUiTfuSchBndReq, +#else + PtLiTfuSchBndReq, +#endif +#ifdef LWLCRGLITFU + cmPkTfuSchBndReq +#else + PtLiTfuSchBndReq +#endif +}; + +/** @brief This API is used to send an Unbind Request from MAC to PHY. + * @param pst Pointer to the post structure. + * @param suId SAP ID of the service provider. + * @param reason Reason for Unbind request. + * @return ROK/RFAILED + */ +PRIVATE CONSTANT TfuUbndReq RgLiTfuUbndReqMt[RG_MAX_TFU_PROV] = +{ +#ifdef LCRGLITFU + cmPkTfuUbndReq, +#else + PtLiTfuUbndReq, +#endif +#ifdef TF + TfUiTfuUbndReq, +#else + PtLiTfuUbndReq, +#endif +#ifdef LWLCRGLITFU + cmPkTfuUbndReq +#else + PtLiTfuUbndReq +#endif +}; + +/** @brief This API is used to send an Unbind Request from Scheduler to PHY. + * @param pst Pointer to the post structure. + * @param suId SAP ID of the service provider. + * @param reason Reason for Unbind request. + * @return ROK/RFAILED + */ +PRIVATE CONSTANT TfuSchUbndReq RgLiTfuSchUbndReqMt[RG_MAX_TFU_PROV] = +{ +#ifdef LCRGLITFU + cmPkTfuSchUbndReq, +#else + PtLiTfuSchUbndReq, +#endif +#ifdef TF + TfUiTfuSchUbndReq, +#else + PtLiTfuSchUbndReq, +#endif +#ifdef LWLCRGLITFU + cmPkTfuSchUbndReq +#else + PtLiTfuSchUbndReq +#endif +}; + +/** @brief This primitive is sent from Scheduler to PHY. + * @details This primitive provides PHY with all the information required by + * PHY to decode transmissions from the UE on either PUCCH or PUSCH. + * -# On PUCCH UE can transmit the following + * -# SR + * -# HARQ feedback + * -# CQI report + * -# HARQ + CQI + * -# HARQ + SR + * -# On PUSCH UE can transmit the following + * -# Data + * -# Data + CQI + * -# Data + HARQ Feedback + * This primitive carries all the information for the expected subframe for all + * the UEs that have been scheduled to transmit. + * @param pst Pointer to the post structure. + * @param spId SAP ID of the service provider. + * @param recpReq Pointer to the TfuRecpReqInfo structure. + * @return ROK/RFAILED + */ +PRIVATE CONSTANT TfuRecpReq RgLiTfuRecpReqMt[RG_MAX_TFU_PROV] = +{ +#ifdef LCRGLITFU + cmPkTfuRecpReq, +#else + PtLiTfuRecpReq, +#endif +#ifdef TF + TfUiTfuRecpReq, +#else + PtLiTfuRecpReq, +#endif +#ifdef LWLCRGLITFU + cmPkTfuRecpReq +#else + PtLiTfuRecpReq +#endif +}; + +/** @brief This Primitive is sent from Scheduler to PHY. It provides PHY with + * all the control information + * @details This primitive carries the information sent on the following + * channels - + * -# PDCCH + * -# PHICH + * -# PCFICH + * + * @param pst + * @param spId + * @param cntrlReq pointer to TfuCntrlReqInfo + * @return ROK/RFAILED + */ +PRIVATE CONSTANT TfuCntrlReq RgLiTfuCntrlReqMt[RG_MAX_TFU_PROV] = +{ +#ifdef LCRGLITFU + cmPkTfuCntrlReq, +#else + PtLiTfuCntrlReq, +#endif +#ifdef TF + TfUiTfuCntrlReq, +#else + PtLiTfuCntrlReq, +#endif +#ifdef LWLCRGLITFU + cmPkTfuCntrlReq +#else + PtLiTfuCntrlReq +#endif +}; + +/** @brief This Primitive carries the Data PDUs from MAC to PHY for + * transmission. + * @details The data being sent in this primitive is meant to be transmitted on + * the downlink channel PDSCH and PBCH (if present). To facilitate physical + * layer processing, requisite control information is also sent along with the + * data. + * @sa TfUiTfuCntrlReq + * @param pst + * @param spId + * @param tfuDatReq pointer to TfuDatReqInfo + * @return + */ +PRIVATE CONSTANT TfuDatReq RgLiTfuDatReqMt[RG_MAX_TFU_PROV] = +{ +#ifdef LCRGLITFU + cmPkTfuDatReq, +#else + PtLiTfuDatReq, +#endif +#ifdef TF + TfUiTfuDatReq, +#else + PtLiTfuDatReq, +#endif +#ifdef LWLCRGLITFU + cmPkTfuDatReq +#else + PtLiTfuDatReq +#endif +}; + +#ifdef L2_OPTMZ +/** @brief This Primitive carries cellId and UeId for which datReq need to be deleted. + * @details This primitive is used to send delDatReq to CL to delete the PDUs of + * UE which has been deleted in MAC due to ueId change or anyother scenario + * NOTE:: This API is only supported for TC because race condition issue + * happens only in case of TC + * @sa TfUiTfuDelDatReq + * @param pst + * @param spId + * @param tfuDelDatReq pointer to TfuDelDatReqInfo + * @return + */ +PRIVATE CONSTANT TfuDelDatReq RgLiTfuDelDatReqMt[RG_MAX_TFU_PROV] = +{ +#ifdef LCRGLITFU + PtLiTfuDelDatReq, /*calling dummy api as LC not required for this privitive*/ +#else + PtLiTfuDelDatReq, +#endif +#ifdef TF + TfUiTfuDelDatReq, +#else + PtLiTfuDelDatReq, +#endif +#ifdef LWLCRGLITFU + PtLiTfuDelDatReq, /*calling dummy api as LWLC not required for this privitive*/ +#else + PtLiTfuDelDatReq +#endif +}; +#endif /* L2_OPTMZ*/ + +#ifdef RG + + + +/*********************************************************** +* +* Func : RgLiTfuBndReq +* +* +* Desc : This API is used to send a Bind Request from MAC to PHY. + * @param pst Pointer to the post structure. + * @param suId SAP ID of the service user. + * @param spId SAP ID of the service provider. + * @return ROK/RFAILED +* +* +* Ret : S16 +* +* Notes: +* +* File : +* +**********************************************************/ +#ifdef ANSI +PUBLIC S16 RgLiTfuBndReq +( +Pst * pst, +SuId suId, +SpId spId +) +#else +PUBLIC S16 RgLiTfuBndReq(pst, suId, spId) +Pst * pst; +SuId suId; +SpId spId; +#endif +{ + + TRC3(RgLiTfuBndReq) + + RETVALUE((*RgLiTfuBndReqMt[pst->selector])(pst, suId, spId)); + +} + + + +/*********************************************************** +* +* Func : RgLiTfuSchBndReq +* +* +* Desc : This API is used to send a Bind Request from Scheduler to PHY. + * @param pst Pointer to the post structure. + * @param suId SAP ID of the service user. + * @param spId SAP ID of the service provider. + * @return ROK/RFAILED +* +* +* Ret : S16 +* +* Notes: +* +* File : +* +**********************************************************/ +#ifdef ANSI +PUBLIC S16 RgLiTfuSchBndReq +( +Pst * pst, +SuId suId, +SpId spId +) +#else +PUBLIC S16 RgLiTfuSchBndReq(pst, suId, spId) +Pst * pst; +SuId suId; +SpId spId; +#endif +{ + + TRC3(RgLiTfuSchBndReq) + + RETVALUE((*RgLiTfuSchBndReqMt[pst->selector])(pst, suId, spId)); + +} + + + +/*********************************************************** +* +* Func : RgLiTfuUbndReq +* +* +* Desc : This API is used to send an Unbind Request from MAC to PHY. + * @param pst Pointer to the post structure. + * @param suId SAP ID of the service provider. + * @param reason Reason for Unbind request. + * @return ROK/RFAILED +* +* +* Ret : S16 +* +* Notes: +* +* File : +* +**********************************************************/ +#ifdef ANSI +PUBLIC S16 RgLiTfuUbndReq +( +Pst * pst, +SpId spId, +Reason reason +) +#else +PUBLIC S16 RgLiTfuUbndReq(pst, spId, reason) +Pst * pst; +SpId spId; +Reason reason; +#endif +{ + + TRC3(RgLiTfuUbndReq) + + RETVALUE((*RgLiTfuUbndReqMt[pst->selector])(pst, spId, reason)); + +} + + + +/*********************************************************** +* +* Func : RgLiTfuSchUbndReq +* +* +* Desc : This API is used to send an Unbind Request from Scheduler to PHY. + * @param pst Pointer to the post structure. + * @param suId SAP ID of the service provider. + * @param reason Reason for Unbind request. + * @return ROK/RFAILED +* +* +* Ret : S16 +* +* Notes: +* +* File : +* +**********************************************************/ +#ifdef ANSI +PUBLIC S16 RgLiTfuSchUbndReq +( +Pst * pst, +SpId spId, +Reason reason +) +#else +PUBLIC S16 RgLiTfuSchUbndReq(pst, spId, reason) +Pst * pst; +SpId spId; +Reason reason; +#endif +{ + + TRC3(RgLiTfuSchUbndReq) + + RETVALUE((*RgLiTfuSchUbndReqMt[pst->selector])(pst, spId, reason)); + +} + + + +/*********************************************************** +* +* Func : RgLiTfuRecpReq +* +* +* Desc : This primitive is sent from Scheduler to PHY. + * @details This primitive provides PHY with all the information required by + * PHY to decode transmissions from the UE on either PUCCH or PUSCH. + * -# On PUCCH UE can transmit the following + * -# SR + * -# HARQ feedback + * -# CQI report + * -# HARQ + CQI + * -# HARQ + SR + * -# On PUSCH UE can transmit the following + * -# Data + * -# Data + CQI + * -# Data + HARQ Feedback + * This primitive carries all the information for the expected subframe for all + * the UEs that have been scheduled to transmit. + * @param pst Pointer to the post structure. + * @param spId SAP ID of the service provider. + * @param recpReq Pointer to the TfuRecpReqInfo structure. + * @return ROK/RFAILED +* +* +* Ret : S16 +* +* Notes: +* +* File : +* +**********************************************************/ +#ifdef ANSI +PUBLIC S16 RgLiTfuRecpReq +( +Pst * pst, +SpId spId, +TfuRecpReqInfo * recpReq +) +#else +PUBLIC S16 RgLiTfuRecpReq(pst, spId, recpReq) +Pst * pst; +SpId spId; +TfuRecpReqInfo * recpReq; +#endif +{ + + TRC3(RgLiTfuRecpReq) + + RETVALUE((*RgLiTfuRecpReqMt[pst->selector])(pst, spId, recpReq)); + +} + + + +/*********************************************************** +* +* Func : RgLiTfuCntrlReq +* +* +* Desc : This Primitive is sent from Scheduler to PHY. It provides PHY with + * all the control information + * @details This primitive carries the information sent on the following + * channels - + * -# PDCCH + * -# PHICH + * -# PCFICH + * + * @param pst + * @param spId + * @param cntrlReq pointer to TfuCntrlReqInfo + * @return ROK/RFAILED +* +* +* Ret : S16 +* +* Notes: +* +* File : +* +**********************************************************/ +#ifdef ANSI +PUBLIC S16 RgLiTfuCntrlReq +( +Pst * pst, +SpId spId, +TfuCntrlReqInfo * cntrlReq +) +#else +PUBLIC S16 RgLiTfuCntrlReq(pst, spId, cntrlReq) +Pst * pst; +SpId spId; +TfuCntrlReqInfo * cntrlReq; +#endif +{ + + TRC3(RgLiTfuCntrlReq) + + RETVALUE((*RgLiTfuCntrlReqMt[pst->selector])(pst, spId, cntrlReq)); + +} + + + +/*********************************************************** +* +* Func : RgLiTfuDatReq +* +* +* Desc : This Primitive carries the Data PDUs from MAC to PHY for + * transmission. + * @details The data being sent in this primitive is meant to be transmitted on + * the downlink channel PDSCH and PBCH (if present). To facilitate physical + * layer processing, requisite control information is also sent along with the + * data. + * @sa TfUiTfuCntrlReq + * @param pst + * @param spId + * @param tfuDatReq pointer to TfuDatReqInfo + * @return +* +* +* Ret : S16 +* +* Notes: +* +* File : +* +**********************************************************/ +#ifdef ANSI +PUBLIC S16 RgLiTfuDatReq +( +Pst * pst, +SpId spId, +TfuDatReqInfo * datReq +) +#else +PUBLIC S16 RgLiTfuDatReq(pst, spId, datReq) +Pst * pst; +SpId spId; +TfuDatReqInfo * datReq; +#endif +{ + + TRC3(RgLiTfuDatReq) + + RETVALUE((*RgLiTfuDatReqMt[pst->selector])(pst, spId, datReq)); + +} + +#ifdef L2_OPTMZ + +/*********************************************************** +* +* Func : RgLiTfuDelDatReq +* +* +* Desc : This Primitive is used to delete datReq in CL when there is ueId change. + * @details: This primitive is required when L2_OPMZ flag is elabed. this is required + * To delete datRq PDUs from CL for the Ue for which Ue Id got changed or + * anyother similar scenario + * @sa TfUiTfuDelDatReq + * @param pst + * @param spId + * @param tfuDelDatReq pointer to TfuDelDatReqInfo + * @return +* +* +* Ret : S16 +* +* Notes: +* +* File : +* +**********************************************************/ +#ifdef ANSI +PUBLIC S16 RgLiTfuDelDatReq +( +Pst * pst, +SpId spId, +TfuDelDatReqInfo * delDatReq +) +#else +PUBLIC S16 RgLiTfuDelDatReq(pst, spId, delDatReq) +Pst * pst; +SpId spId; +TfuDelDatReqInfo * delDatReq; +#endif +{ + + TRC3(RgLiTfuDelDatReq) + + RETVALUE((*RgLiTfuDelDatReqMt[pst->selector])(pst, spId, delDatReq)); + +} +#endif /* L2_OPTMZ*/ + +#endif /*--ifdef RG--*/ + +#ifdef PTRGLITFU + + + +/*********************************************************** +* +* Func : PtLiTfuBndReq +* +* +* Desc : This API is used to send a Bind Request from MAC to PHY. + * @param pst Pointer to the post structure. + * @param suId SAP ID of the service user. + * @param spId SAP ID of the service provider. + * @return ROK/RFAILED +* +* +* Ret : S16 +* +* Notes: +* +* File : +* +**********************************************************/ +#ifdef ANSI +PUBLIC S16 PtLiTfuBndReq +( +Pst * pst, +SuId suId, +SpId spId +) +#else +PUBLIC S16 PtLiTfuBndReq(pst, suId, spId) +Pst * pst; +SuId suId; +SpId spId; +#endif +{ + + TRC3(PtLiTfuBndReq) + + UNUSED(pst); + UNUSED(suId); + UNUSED(spId); + + RETVALUE(ROK); + +} + + + +/*********************************************************** +* +* Func : PtLiTfuSchBndReq +* +* +* Desc : This API is used to send a Bind Request from Scheduler to PHY. + * @param pst Pointer to the post structure. + * @param suId SAP ID of the service user. + * @param spId SAP ID of the service provider. + * @return ROK/RFAILED +* +* +* Ret : S16 +* +* Notes: +* +* File : +* +**********************************************************/ +#ifdef ANSI +PUBLIC S16 PtLiTfuSchBndReq +( +Pst * pst, +SuId suId, +SpId spId +) +#else +PUBLIC S16 PtLiTfuSchBndReq(pst, suId, spId) +Pst * pst; +SuId suId; +SpId spId; +#endif +{ + + TRC3(PtLiTfuSchBndReq) + + UNUSED(pst); + UNUSED(suId); + UNUSED(spId); + + RETVALUE(ROK); + +} + + + +/*********************************************************** +* +* Func : PtLiTfuUbndReq +* +* +* Desc : This API is used to send an Unbind Request from MAC to PHY. + * @param pst Pointer to the post structure. + * @param suId SAP ID of the service provider. + * @param reason Reason for Unbind request. + * @return ROK/RFAILED +* +* +* Ret : S16 +* +* Notes: +* +* File : +* +**********************************************************/ +#ifdef ANSI +PUBLIC S16 PtLiTfuUbndReq +( +Pst * pst, +SpId spId, +Reason reason +) +#else +PUBLIC S16 PtLiTfuUbndReq(pst, spId, reason) +Pst * pst; +SpId spId; +Reason reason; +#endif +{ + + TRC3(PtLiTfuUbndReq) + + UNUSED(pst); + UNUSED(spId); + UNUSED(reason); + + RETVALUE(ROK); + +} + + + +/*********************************************************** +* +* Func : PtLiTfuSchUbndReq +* +* +* Desc : This API is used to send an Unbind Request from Scheduler to PHY. + * @param pst Pointer to the post structure. + * @param suId SAP ID of the service provider. + * @param reason Reason for Unbind request. + * @return ROK/RFAILED +* +* +* Ret : S16 +* +* Notes: +* +* File : +* +**********************************************************/ +#ifdef ANSI +PUBLIC S16 PtLiTfuSchUbndReq +( +Pst * pst, +SpId spId, +Reason reason +) +#else +PUBLIC S16 PtLiTfuSchUbndReq(pst, spId, reason) +Pst * pst; +SpId spId; +Reason reason; +#endif +{ + + TRC3(PtLiTfuSchUbndReq) + + UNUSED(pst); + UNUSED(spId); + UNUSED(reason); + + RETVALUE(ROK); + +} + + + +/*********************************************************** +* +* Func : PtLiTfuRecpReq +* +* +* Desc : This primitive is sent from Scheduler to PHY. + * @details This primitive provides PHY with all the information required by + * PHY to decode transmissions from the UE on either PUCCH or PUSCH. + * -# On PUCCH UE can transmit the following + * -# SR + * -# HARQ feedback + * -# CQI report + * -# HARQ + CQI + * -# HARQ + SR + * -# On PUSCH UE can transmit the following + * -# Data + * -# Data + CQI + * -# Data + HARQ Feedback + * This primitive carries all the information for the expected subframe for all + * the UEs that have been scheduled to transmit. + * @param pst Pointer to the post structure. + * @param spId SAP ID of the service provider. + * @param recpReq Pointer to the TfuRecpReqInfo structure. + * @return ROK/RFAILED +* +* +* Ret : S16 +* +* Notes: +* +* File : +* +**********************************************************/ +#ifdef ANSI +PUBLIC S16 PtLiTfuRecpReq +( +Pst * pst, +SpId spId, +TfuRecpReqInfo * recpReq +) +#else +PUBLIC S16 PtLiTfuRecpReq(pst, spId, recpReq) +Pst * pst; +SpId spId; +TfuRecpReqInfo * recpReq; +#endif +{ + + TRC3(PtLiTfuRecpReq) + + UNUSED(pst); + UNUSED(spId); + UNUSED(recpReq); + + RETVALUE(ROK); + +} + + + +/*********************************************************** +* +* Func : PtLiTfuCntrlReq +* +* +* Desc : This Primitive is sent from Scheduler to PHY. It provides PHY with + * all the control information + * @details This primitive carries the information sent on the following + * channels - + * -# PDCCH + * -# PHICH + * -# PCFICH + * + * @param pst + * @param spId + * @param cntrlReq pointer to TfuCntrlReqInfo + * @return ROK/RFAILED +* +* +* Ret : S16 +* +* Notes: +* +* File : +* +**********************************************************/ +#ifdef ANSI +PUBLIC S16 PtLiTfuCntrlReq +( +Pst * pst, +SpId spId, +TfuCntrlReqInfo * cntrlReq +) +#else +PUBLIC S16 PtLiTfuCntrlReq(pst, spId, cntrlReq) +Pst * pst; +SpId spId; +TfuCntrlReqInfo * cntrlReq; +#endif +{ + + TRC3(PtLiTfuCntrlReq) + + UNUSED(pst); + UNUSED(spId); + UNUSED(cntrlReq); + + RETVALUE(ROK); + +} + + + +/*********************************************************** +* +* Func : PtLiTfuDatReq +* +* +* Desc : This Primitive carries the Data PDUs from MAC to PHY for + * transmission. + * @details The data being sent in this primitive is meant to be transmitted on + * the downlink channel PDSCH and PBCH (if present). To facilitate physical + * layer processing, requisite control information is also sent along with the + * data. + * @sa TfUiTfuCntrlReq + * @param pst + * @param spId + * @param tfuDatReq pointer to TfuDatReqInfo + * @return +* +* +* Ret : S16 +* +* Notes: +* +* File : +* +**********************************************************/ +#ifdef ANSI +PUBLIC S16 PtLiTfuDatReq +( +Pst * pst, +SpId spId, +TfuDatReqInfo * datReq +) +#else +PUBLIC S16 PtLiTfuDatReq(pst, spId, datReq) +Pst * pst; +SpId spId; +TfuDatReqInfo * datReq; +#endif +{ + + TRC3(PtLiTfuDatReq) + + UNUSED(pst); + UNUSED(spId); + UNUSED(datReq); + + RETVALUE(ROK); + +} + + +#ifdef L2_OPTMZ +/*********************************************************** +* +* Func : PtLiTfuDelDatReq +* +* +* @brief This Primitive carries cellId and UeId for which datReq need to be deleted. + * @details This primitive is used to send delDatReq to CL to delete the PDUs of + * UE which has been deleted in MAC due to ueId change or anyother scenario + + * @details The data being sent in this primitive is meant to be transmitted on + * @sa TfUiTfuDelDatReq + * @param pst + * @param spId + * @param tfuDelDatReq pointer to TfuDelDatReqInfo + * @return +* +* +* Ret : S16 +* +* Notes: +* +* File : +* +**********************************************************/ +#ifdef ANSI +PUBLIC S16 PtLiTfuDelDatReq +( +Pst * pst, +SpId spId, +TfuDelDatReqInfo * delDatReq +) +#else +PUBLIC S16 PtLiTfuDelDatReq(pst, spId, delDatReq) +Pst * pst; +SpId spId; +TfuDelDatReqInfo * DelDatReq; +#endif +{ + + TRC3(PtLiTfuDelDatReq) + + UNUSED(pst); + UNUSED(spId); + UNUSED(delDatReq); + + RETVALUE(ROK); + +} +#endif /*L2_OPTMZ*/ + +#endif /*--ifdef PTRGLITFU--*/ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +/********************************************************************** + + End of file +**********************************************************************/ diff --git a/src/5gnrmac/rg_ptmi.c b/src/5gnrmac/rg_ptmi.c new file mode 100755 index 000000000..ca75c16ec --- /dev/null +++ b/src/5gnrmac/rg_ptmi.c @@ -0,0 +1,1094 @@ +/******************************************************************************* +################################################################################ +# Copyright (c) [2017-2019] [Radisys] # +# # +# 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. # +################################################################################ +*******************************************************************************/ + +/************************************************************************ + + Name: LTE-MAC layer + + Type: C source file + + Desc: C source code for portable definitions for Layer Manager + Interface primitives. + + File: rg_ptmi.c + +**********************************************************************/ + +/** @file rg_ptmi.c +@brief This file contains the definitions for Layer Manager + Interface primitives that are invoked from MAC to Layer Manager + (Confirmations and Indications) Portable functions corresponding + to these primitives are also defined. +*/ + +/* header include files (.h) */ +#include "envopt.h" /* environment options */ +#include "envdep.h" /* environment dependent */ +#include "envind.h" /* environment independent */ +#include "gen.h" /* general */ +#include "ssi.h" /* system services */ +#include "cm_tkns.h" /* Common Token Defines */ +#include "cm_llist.h" /* Common Link List Defines */ +#include "cm_hash.h" /* Common Hash List Defines */ +#include "cm_lte.h" /* Common LTE Defines */ +#include "lrg.h" /* LRG Interface defines */ + +/* header/extern include files (.x) */ +#include "gen.x" /* general */ +#include "ssi.x" /* system services */ +#include "cm_tkns.x" /* Common Token Definitions */ +#include "cm_llist.x" /* Common Link List Definitions */ +#include "cm_lib.x" /* Common Library Definitions */ +#include "cm_hash.x" /* Common Hash List Definitions */ +#include "cm_lte.x" /* Common LTE Defines */ +#include "lrg.x" /* LRG Interface includes */ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#if !(defined(LCRGMILRG) && defined(SM)) +#define PTRGMILRG +#endif + +#define RG_MAX_LRG_USR 2 + +/* portable functions at LRG interface */ +#ifdef PTRGMILRG +EXTERN S16 PtMiLrgCfgCfm ARGS((Pst *pst, RgMngmt *cfm)); +EXTERN S16 PtMiLrgSchCfgCfm ARGS((Pst *pst, RgMngmt *cfm)); +EXTERN S16 PtMiLrgStsCfm ARGS((Pst *pst, RgMngmt *cfm)); +EXTERN S16 PtMiLrgStaCfm ARGS((Pst *pst, RgMngmt *cfm)); +EXTERN S16 PtMiLrgStaInd ARGS((Pst *pst, RgMngmt *usta)); +EXTERN S16 PtMiLrgSchStaInd ARGS((Pst *pst, RgMngmt *usta)); +EXTERN S16 PtMiLrgCntrlCfm ARGS((Pst *pst, RgMngmt *cfm)); +EXTERN S16 PtMiLrgSchCntrlCfm ARGS((Pst *pst, RgMngmt *cfm)); +EXTERN S16 PtMiLrgTrcInd ARGS((Pst *pst, RgMngmt *trc,Buffer *mBuf)); +#ifdef LTE_L2_MEAS +EXTERN S16 PtMiLrgSchL2MeasCfm ARGS((Pst *pst, LrgSchMeasCfmInfo *cfm)); +EXTERN S16 PtMiLrgSchL2MeasStopCfm ARGS((Pst *pst,LrgSchMeasCfmInfo *cfm )); +#endif +#endif + +/* ***********LRG interface Mapping matrices ********************/ + +/** @brief Configuration Confirm primitive Matrix + * This matrix defines the mapping between the configuration confirm + * primitive called by the upper interface of MAC layer and the + * corresponding primitives of the MAC layer service user(s). + * + * The parameter RG_MAX_LRG_USR defines the maximum number of Layer + * managers of MAC at the LRG interface. This is an array of functions + * per primitive invoked by MAC whose size is RG_MAX_LRG_USR. + * + * The dispatching is performed by the configurable variable: selector. + * The selector is configured on a per SAP basis. The selectors are: + * + * LCRGMILRG - loosely coupled LMK interface + * TCRGMILRG - Tightly coupled LMK interface + * + * In a similar fashion, the matrices for Status, Statistics and + * Control confirms and, Status and trace indications are defined. + **/ +PRIVATE CONSTANT LrgCfgCfm RgMiLrgCfgCfmMt[RG_MAX_LRG_USR] = +{ +#ifdef LCRGMILRG + cmPkLrgCfgCfm, /* 0 - loosely coupled */ +#else + PtMiLrgCfgCfm, /* 0 - loosely coupled */ +#endif +#ifdef SM + SmMiLrgCfgCfm, /* 1 - Tightly coupled SM */ +#else + PtMiLrgCfgCfm, /* 1 - Tightly coupled SM */ +#endif +}; + +/** @brief Scheduler Config Confirm primitive Matrix */ +PRIVATE CONSTANT LrgSchCfgCfm RgMiLrgSchCfgCfmMt[RG_MAX_LRG_USR] = +{ +#ifdef LCRGMILRG + cmPkLrgSchCfgCfm, /* 0 - loosely coupled */ +#else + PtMiLrgSchCfgCfm, /* 0 - loosely coupled */ +#endif +#ifdef SM + SmMiLrgSchCfgCfm, /* 1 - Tightly coupled SM */ +#else + PtMiLrgSchCfgCfm, /* 1 - Tightly coupled SM */ +#endif +}; + +/** @brief Statistics Confirm primitive Matrix */ +PRIVATE CONSTANT LrgStsCfm RgMiLrgStsCfmMt[RG_MAX_LRG_USR] = +{ +#ifdef LCRGMILRG + cmPkLrgStsCfm, /* 0 - loosely coupled */ +#else + PtMiLrgStsCfm, /* 0 - loosely coupled */ +#endif +#ifdef SM + SmMiLrgStsCfm, /* 1 - Tightly coupled SM */ +#else + PtMiLrgStsCfm, /* 1 - Tightly coupled SM */ +#endif +}; + +/** @brief Status Confirm primitive Matrix */ +PRIVATE CONSTANT LrgStaCfm RgMiLrgStaCfmMt[RG_MAX_LRG_USR] = +{ +#ifdef LCRGMILRG + cmPkLrgStaCfm, /* 0 - loosely coupled */ +#else + PtMiLrgStaCfm, /* 0 - loosely coupled */ +#endif +#ifdef SM + SmMiLrgStaCfm, /* 1 - Tightly coupled SM */ +#else + PtMiLrgStaCfm, /* 1 - Tightly coupled SM */ +#endif +}; + + +/** @brief Status Indication primitive Matrix */ +PRIVATE CONSTANT LrgStaInd RgMiLrgStaIndMt[RG_MAX_LRG_USR] = +{ +#ifdef LCRGMILRG + cmPkLrgStaInd, /* 0 - loosely coupled */ +#else + PtMiLrgStaInd, /* 0 - loosely coupled */ +#endif +#ifdef SM + SmMiLrgStaInd, /* 1 - Tightly coupled SM */ +#else + PtMiLrgStaInd, /* 1 - Tightly coupled SM */ +#endif +}; + +/** @brief Scheduler Status Indication primitive Matrix */ +PRIVATE CONSTANT LrgSchStaInd RgMiLrgSchStaIndMt[RG_MAX_LRG_USR] = +{ +#ifdef LCRGMILRG + cmPkLrgSchStaInd, /* 0 - loosely coupled */ +#else + PtMiLrgSchStaInd, /* 0 - loosely coupled */ +#endif +#ifdef SM + SmMiLrgSchStaInd, /* 1 - Tightly coupled SM */ +#else + PtMiLrgSchStaInd, /* 1 - Tightly coupled SM */ +#endif +}; + + +/** @brief Control Confirm primitive Matrix */ +PRIVATE CONSTANT LrgCntrlCfm RgMiLrgCntrlCfmMt[RG_MAX_LRG_USR] = +{ +#ifdef LCRGMILRG + cmPkLrgCntrlCfm, /* 0 - loosely coupled */ +#else + PtMiLrgCntrlCfm, /* 0 - loosely coupled */ +#endif +#ifdef SM + SmMiLrgCntrlCfm, /* 1 - Tightly coupled SM */ +#else + PtMiLrgCntrlCfm, /* 1 - Tightly coupled SM */ +#endif +}; + +/** @brief Scheduler Control Confirm primitive Matrix */ +PRIVATE CONSTANT LrgSchCntrlCfm RgMiLrgSchCntrlCfmMt[RG_MAX_LRG_USR] = +{ +#ifdef LCRGMILRG + cmPkLrgSchCntrlCfm, /* 0 - loosely coupled */ +#else + PtMiLrgSchCntrlCfm, /* 0 - loosely coupled */ +#endif +#ifdef SM + SmMiLrgSchCntrlCfm, /* 1 - Tightly coupled SM */ +#else + PtMiLrgSchCntrlCfm, /* 1 - Tightly coupled SM */ +#endif +}; + +/** @brief Trace Indication primitive Matrix */ +PRIVATE CONSTANT LrgTrcInd RgMiLrgTrcIndMt[RG_MAX_LRG_USR] = +{ +#ifdef LCRGMILRG + cmPkLrgTrcInd, /* 0 - loosely coupled */ +#else + PtMiLrgTrcInd, /* 0 - loosely coupled */ +#endif +#ifdef SM + SmMiLrgTrcInd, /* 1 - Tightly coupled SM */ +#else + PtMiLrgTrcInd, /* 1 - Tightly coupled SM */ +#endif +}; +#ifdef LTE_L2_MEAS +/** @brief L2 Meas Cfm primitive Matrix */ +PRIVATE CONSTANT LrgSchL2MeasCfm RgMiLrgSchL2mMeasCfmMt[RG_MAX_LRG_USR] = +{ +#ifdef LCRGMILRG + cmPkLrgSchL2MeasCfm, /* 0 - loosely coupled */ +#else + PtMiLrgSchL2MeasCfm, /* 0 - loosely coupled */ +#endif +#ifdef SM + SmMiLrgSchL2MeasCfm, /* 1 - Tightly coupled SM */ +#else + PtMiLrgSchL2MeasCfm, /* 1 - loosely coupled */ +#endif +}; +/** @brief L2 Meas Stop Cfm primitive Matrix */ +PRIVATE CONSTANT LrgSchL2MeasStopCfm RgMiLrgSchL2mMeasStopCfmMt[RG_MAX_LRG_USR] = +{ +#ifdef LCRGMILRG + cmPkLrgSchL2MeasStopCfm, /* 0 - loosely coupled */ +#else + PtMiLrgSchL2MeasStopCfm, /* 0 - loosely coupled */ +#endif +#ifdef SM + SmMiLrgSchL2MeasStopCfm, /* 1 - Tightly coupled SM */ +#else + PtMiLrgSchL2MeasStopCfm, /* 1 - loosely coupled */ +#endif +}; +#endif /* LTE_L2_MEAS */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#ifdef RG + + +/** + * @brief Layer Manager Configuration confirm handler. + * + * @details + * + * Function : RgMiLrgCfgCfm + * + * This function handles the configuration + * confirm invoked by MAC to Layer Manager. + * -# Based on the pst->selector value it invokes one of the + * functions cmPkLrgCfgCfm() or SmMiLrgCfgCfm(). + * + * @param[in] Pst *pst, the post structure + * @param[in] RgMngmt *cfm, the configuration confirm structure + * @return S16 + * -# ROK + **/ +#ifdef ANSI +PUBLIC S16 RgMiLrgCfgCfm +( +Pst *pst, /* post structure */ +RgMngmt *cfm /* config confirm structure */ +) +#else +PUBLIC S16 RgMiLrgCfgCfm(pst, cfm) +Pst *pst; /* post structure */ +RgMngmt *cfm; /* config confirm structure */ +#endif +{ + + TRC3(RgMiLrgCfgCfm); + + (*RgMiLrgCfgCfmMt[pst->selector])(pst, cfm); + + RETVALUE(ROK); + +}/*-- RgMiLrgCfgCfm --*/ + +/** + * @brief Layer Manager scheduler Configuration confirm handler. + * + * @details + * + * Function : RgMiLrgSchCfgCfm + * + * This function handles the configuration + * confirm invoked by Scheduler to Layer Manager. + * -# Based on the pst->selector value it invokes one of the + * functions cmPkLrgSchCfgCfm() or SmMiLrgSchCfgCfm(). + * + * @param[in] Pst *pst, the post structure + * @param[in] RgMngmt *cfm, the configuration confirm structure + * @return S16 + * -# ROK + **/ +#ifdef ANSI +PUBLIC S16 RgMiLrgSchCfgCfm +( +Pst *pst, /* post structure */ +RgMngmt *cfm /* config confirm structure */ +) +#else +PUBLIC S16 RgMiLrgSchCfgCfm(pst, cfm) +Pst *pst; /* post structure */ +RgMngmt *cfm; /* config confirm structure */ +#endif +{ + + TRC3(RgMiLrgSchCfgCfm); + + (*RgMiLrgSchCfgCfmMt[pst->selector])(pst, cfm); + + RETVALUE(ROK); + +}/*-- RgMiLrgSchCfgCfm --*/ + + + +/** + * @brief Layer Manager Statistics confirm handler. + * + * @details + * + * Function : RgMiLrgStsCfm + * + * This function handles the statistics + * confirm invoked by MAC to Layer Manager. + * -# Based on the pst->selector value it invokes one of the + * functions cmPkLrgStsCfm() or SmMiLrgStsCfm(). + * + * @param[in] Pst *pst, the post structure + * @param[in] RgMngmt *cfm, the statistics confirm structure + * @return S16 + * -# ROK + **/ +#ifdef ANSI +PUBLIC S16 RgMiLrgStsCfm +( +Pst *pst, /* post structure */ +RgMngmt *cfm /* statistics confirm structure */ +) +#else +PUBLIC S16 RgMiLrgStsCfm(pst, cfm) +Pst *pst; /* post structure */ +RgMngmt *cfm; /* statistics confirm structure */ +#endif +{ + + TRC3(RgMiLrgStsCfm); + + (*RgMiLrgStsCfmMt[pst->selector])(pst, cfm); + + RETVALUE(ROK); + +}/*-- RgMiLrgStsCfm --*/ + + +/** + * @brief Layer Manager Status confirm handler. + * + * @details + * + * Function : RgMiLrgStaCfm + * + * This function handles the status + * confirm invoked by MAC to Layer Manager. + * -# Based on the pst->selector value it invokes one of the + * functions cmPkLrgStaCfm() or SmMiLrgStaCfm(). + * + * @param[in] Pst *pst, the post structure + * @param[in] RgMngmt *cfm, the status confirm structure + * @return S16 + * -# ROK + **/ +#ifdef ANSI +PUBLIC S16 RgMiLrgStaCfm +( +Pst *pst, /* post structure */ +RgMngmt *cfm /* status confirm structure */ +) +#else +PUBLIC S16 RgMiLrgStaCfm(pst, cfm) +Pst *pst; /* post structure */ +RgMngmt *cfm; /* status confirm structure */ +#endif +{ + + TRC3(RgMiLrgStaCfm); + + (*RgMiLrgStaCfmMt[pst->selector])(pst,cfm); + + RETVALUE(ROK); + +}/*-- RgMiLrgStaCfm --*/ + + +/** + * @brief Layer Manager Control confirm handler. + * + * @details + * + * Function : RgMiLrgCntrlCfm + * + * This function handles the control + * confirm invoked by MAC to Layer Manager. + * -# Based on the pst->selector value it invokes one of the + * functions cmPkLrgCntrlCfm() or SmMiLrgCntrlCfm(). + * + * @param[in] Pst *pst, the post structure + * @param[in] RgMngmt *cfm, the control confirm structure + * @return S16 + * -# ROK + **/ +#ifdef ANSI +PUBLIC S16 RgMiLrgCntrlCfm +( +Pst *pst, /* post structure */ +RgMngmt *cfm /* control confirm structure */ +) +#else +PUBLIC S16 RgMiLrgCntrlCfm(pst, cfm) +Pst *pst; /* post structure */ +RgMngmt *cfm; /* control confirm structure */ +#endif +{ + + TRC3(RgMiLrgCntrlCfm); + + (*RgMiLrgCntrlCfmMt[pst->selector])(pst,cfm); + + RETVALUE(ROK); + +}/*-- RgMiLrgCntrlCfm --*/ + +/** + * @brief Layer Manager scheduler Control confirm handler. + * + * @details + * + * Function : RgMiLrgSchCntrlCfm + * + * This function handles the control + * confirm invoked by scheduler to Layer Manager. + * -# Based on the pst->selector value it invokes one of the + * functions cmPkLrgSchCntrlCfm() or SmMiLrgSchCntrlCfm(). + * + * @param[in] Pst *pst, the post structure + * @param[in] RgMngmt *cfm, the control confirm structure + * @return S16 + * -# ROK + **/ +#ifdef ANSI +PUBLIC S16 RgMiLrgSchCntrlCfm +( +Pst *pst, /* post structure */ +RgMngmt *cfm /* control confirm structure */ +) +#else +PUBLIC S16 RgMiLrgSchCntrlCfm(pst, cfm) +Pst *pst; /* post structure */ +RgMngmt *cfm; /* control confirm structure */ +#endif +{ + + TRC3(RgMiLrgSchCntrlCfm); + + (*RgMiLrgSchCntrlCfmMt[pst->selector])(pst,cfm); + + RETVALUE(ROK); + +}/*-- RgMiLrgSchCntrlCfm --*/ + + +/** + * @brief Layer Manager Unsolicited Status Indication handler. + * + * @details + * + * Function : RgMiLrgStaInd + * + * This function handles the unsolicited status + * Indication invoked by MAC to Layer Manager. + * -# Based on the pst->selector value it invokes one of the + * functions cmPkLrgStaInd() or SmMiLrgStaInd(). + * + * @param[in] Pst *pst, the post structure + * @param[in] RgMngmt *usta, the status indication structure + * @return S16 + * -# ROK + **/ +#ifdef ANSI +PUBLIC S16 RgMiLrgStaInd +( +Pst *pst, /* post structure */ +RgMngmt *usta /* status indication structure */ +) +#else +PUBLIC S16 RgMiLrgStaInd(pst, usta) +Pst *pst; /* post structure */ +RgMngmt *usta; /* status indication structure */ +#endif +{ + + TRC3(RgMiLrgStaInd); + + (*RgMiLrgStaIndMt[pst->selector])(pst,usta); + + RETVALUE(ROK); + +}/*-- RgMiLrgStaInd --*/ + +/** + * @brief Layer Manager Unsolicited Status Indication handler from scheduler + * + * @details + * + * Function : RgMiLrgSchStaInd + * + * This function handles the unsolicited status + * Indication invoked by Scheduler to Layer Manager. + * -# Based on the pst->selector value it invokes one of the + * functions cmPkLrgSchStaInd() or SmMiLrgSchStaInd(). + * + * @param[in] Pst *pst, the post structure + * @param[in] RgMngmt *usta, the status indication structure + * @return S16 + * -# ROK + **/ +#ifdef ANSI +PUBLIC S16 RgMiLrgSchStaInd +( +Pst *pst, /* post structure */ +RgMngmt *usta /* status indication structure */ +) +#else +PUBLIC S16 RgMiLrgSchStaInd(pst, usta) +Pst *pst; /* post structure */ +RgMngmt *usta; /* status indication structure */ +#endif +{ + + TRC3(RgMiLrgSchStaInd); + + (*RgMiLrgSchStaIndMt[pst->selector])(pst,usta); + + RETVALUE(ROK); + +}/*-- RgMiLrgSchStaInd --*/ + + +/** + * @brief Layer Manager Trace Indication handler. + * + * @details + * + * Function : RgMiLrgTrcInd + * + * This function handles the trace + * Indication invoked by MAC to Layer Manager. + * -# Based on the pst->selector value it invokes one of the + * functions cmPkLrgTrcInd() or SmMiLrgTrcInd(). + * + * @param[in] Pst *pst, the post structure + * @param[in] RgMngmt *trc, the trace event + * @param[in] Buffer *mBuf, the trace message + * @return S16 + * -# ROK + **/ +#ifdef ANSI +PUBLIC S16 RgMiLrgTrcInd +( +Pst *pst, /* post structure */ +RgMngmt *trc, /* Trace event */ +Buffer *mBuf /* Trace message */ +) +#else +PUBLIC S16 RgMiLrgTrcInd(pst, trc, mBuf) +Pst *pst; /* post structure */ +RgMngmt *trc; /* Trace event */ +Buffer *mBuf; /* Trace message */ +#endif +{ + + TRC3(RgMiLrgTrcInd); + + (*RgMiLrgTrcIndMt[pst->selector])(pst,trc,mBuf); + + RETVALUE(ROK); + +}/*-- RgMiLrgTrcInd --*/ + +#ifdef LTE_L2_MEAS + +/* TODO: Function header */ +#ifdef ANSI +PUBLIC S16 RgMiLrgSchL2MeasCfm +( +Pst *pst, /* post structure */ +LrgSchMeasCfmInfo *cfm /* Meas Cfm Info */ +) +#else +PUBLIC S16 RgMiLrgSchL2MeasCfm(pst, cfm) +Pst *pst; /* post structure */ +LrgSchMeasCfmInfo *cfm; /* Meas Cfm Info */ +#endif +{ + TRC3(RgMiLrgSchL2MeasCfm) + + (*RgMiLrgSchL2mMeasCfmMt[pst->selector])(pst,cfm); + + RETVALUE(ROK); + +} /* RgMiLrgSchL2MeasCfm */ + +/** + * @brief This function used to send L2 measurement stop confirmation + * to Layer manager. + * + * + * @details + * + * Function : RgMiLrgSchL2MeasStopCfm + * This function sends reposnes to L2 Measurement stop request + * + * + * @param[in] Pst *pst, the post structure + * @param[in] LrgSchMeasCfmInfo *cfm, theconfirm structure + * @return S16 + * -# ROK + **/ + +#ifdef ANSI +PUBLIC S16 RgMiLrgSchL2MeasStopCfm +( +Pst *pst, /* post structure */ +LrgSchMeasCfmInfo *cfm /* Meas Cfm Info */ +) +#else +PUBLIC S16 RgMiLrgSchL2MeasStopCfm(pst, cfm) +Pst *pst; /* post structure */ +LrgSchMeasCfmInfo *cfm; /* Meas Cfm Info */ +#endif +{ + TRC3(RgMiLrgSchL2MeasStopCfm) + + (*RgMiLrgSchL2mMeasStopCfmMt[pst->selector])(pst,cfm); + + RETVALUE(ROK); + +} /* RgMiLrgSchL2MeasStopCfm */ + +#endif /* LTE_L2_MEAS */ + +#endif /*-- MK --*/ + +#ifdef PTRGMILRG + +/** + * @brief Portable Function definition for Layer Manager Configuration + * confirm handler. + * + * @details + * + * Function : PtMiLrgCfgCfm + * + * This function handles the configuration + * confirm invoked by MAC to Layer Manager. + * Users of MAC who intend to provide a glue logic + * for portability of Configuration Confirm are expected + * to fill in the code in this function definition. + * + * @param[in] Pst *pst, the post structure + * @param[in] RgMngmt *cfm, the configuration confirm structure + * @return S16 + * -# ROK + **/ +#ifdef ANSI +PUBLIC S16 PtMiLrgCfgCfm +( +Pst *pst, /* post structure */ +RgMngmt *cfm /* Config Confirm */ +) +#else +PUBLIC S16 PtMiLrgCfgCfm (pst, cfm) +Pst *pst; /* post structure */ +RgMngmt *cfm; /* Config Confirm */ +#endif +{ + TRC3(PtMiLrgCfgCfm) + + RETVALUE(ROK); +}/* end of PtMiLrgCfgCfm */ + +/** + * @brief Portable Function definition for Layer Manager Configuration + * confirm handler. + * + * @details + * + * Function : PtMiLrgSchCfgCfm + * + * This function handles the configuration + * confirm invoked by scheduler to Layer Manager. + * Users of MAC who intend to provide a glue logic + * for portability of Configuration Confirm are expected + * to fill in the code in this function definition. + * + * @param[in] Pst *pst, the post structure + * @param[in] RgMngmt *cfm, the configuration confirm structure + * @return S16 + * -# ROK + **/ +#ifdef ANSI +PUBLIC S16 PtMiLrgSchCfgCfm +( +Pst *pst, /* post structure */ +RgMngmt *cfm /* Config Confirm */ +) +#else +PUBLIC S16 PtMiLrgSchCfgCfm (pst, cfm) +Pst *pst; /* post structure */ +RgMngmt *cfm; /* Config Confirm */ +#endif +{ + TRC3(PtMiLrgSchCfgCfm) + + RETVALUE(ROK); +}/* end of PtMiLrgSchCfgCfm */ + + + +/** + * @brief Portable Function definition for Layer Manager Statistics + * confirm handler. + * + * @details + * + * Function : PtMiLrgStsCfm + * + * This function handles the statistics + * confirm invoked by MAC to Layer Manager. + * Users of MAC who intend to provide a glue logic + * for portability of statistics Confirm are expected + * to fill in the code in this function definition. + * + * @param[in] Pst *pst, the post structure + * @param[in] RgMngmt *cfm, the statistics confirm structure + * @return S16 + * -# ROK + **/ +#ifdef ANSI +PUBLIC S16 PtMiLrgStsCfm +( +Pst *pst, /* post structure */ +RgMngmt *cfm /* Statistics Confirm */ +) +#else +PUBLIC S16 PtMiLrgStsCfm (pst, cfm) +Pst *pst; /* post structure */ +RgMngmt *cfm; /* Statistics Confirm */ +#endif +{ + TRC3(PtMiLrgStsCfm) + + RETVALUE(ROK); +}/* end of PtMiLrgStsCfm */ + + + +/** + * @brief Portable Function definition for Layer Manager Status + * confirm handler. + * + * @details + * + * Function : PtMiLrgStaCfm + * + * This function handles the status + * confirm invoked by MAC to Layer Manager. + * Users of MAC who intend to provide a glue logic + * for portability of status Confirm are expected + * to fill in the code in this function definition. + * + * @param[in] Pst *pst, the post structure + * @param[in] RgMngmt *cfm, the status confirm structure + * @return S16 + * -# ROK + **/ +#ifdef ANSI +PUBLIC S16 PtMiLrgStaCfm +( +Pst *pst, /* post structure */ +RgMngmt *cfm /* Status Confirm */ +) +#else +PUBLIC S16 PtMiLrgStaCfm (pst, cfm) +Pst *pst; /* post structure */ +RgMngmt *cfm; /* Status Confirm */ +#endif +{ + TRC3(PtMiLrgStaCfm) + RETVALUE(ROK); +}/* end of PtMiLrgStaCfm */ + + + +/** + * @brief Portable Function definition for Layer Manager Status + * Indication handler. + * + * @details + * + * Function : PtMiLrgStaInd + * + * This function handles the status + * indication invoked by MAC to Layer Manager. + * Users of MAC who intend to provide a glue logic + * for portability of status indication are expected + * to fill in the code in this function definition. + * + * @param[in] Pst *pst, the post structure + * @param[in] RgMngmt *cfm, the status indication structure + * @return S16 + * -# ROK + **/ +#ifdef ANSI +PUBLIC S16 PtMiLrgStaInd +( +Pst *pst, /* post structure */ +RgMngmt *usta /* Status Indication */ +) +#else +PUBLIC S16 PtMiLrgStaInd (pst, usta) +Pst *pst; /* post structure */ +RgMngmt *usta; /* Status indication */ +#endif +{ + TRC3(PtMiLrgStaInd) + RETVALUE(ROK); +}/* end of PtMiLrgStaInd */ + +/** + * @brief Portable Function definition for Layer Manager Status + * Indication handler. + * + * @details + * + * Function : PtMiLrgSchStaInd + * + * This function handles the status + * indication invoked by Scheduler to Layer Manager. + * Users of MAC who intend to provide a glue logic + * for portability of status indication are expected + * to fill in the code in this function definition. + * + * @param[in] Pst *pst, the post structure + * @param[in] RgMngmt *cfm, the status indication structure + * @return S16 + * -# ROK + **/ +#ifdef ANSI +PUBLIC S16 PtMiLrgSchStaInd +( +Pst *pst, /* post structure */ +RgMngmt *usta /* Status Indication */ +) +#else +PUBLIC S16 PtMiLrgSchStaInd (pst, usta) +Pst *pst; /* post structure */ +RgMngmt *usta; /* Status indication */ +#endif +{ + TRC3(PtMiLrgSchStaInd) + RETVALUE(ROK); +}/* end of PtMiLrgSchStaInd */ + + +/** + * @brief Portable Function definition for Layer Manager Control + * confirm handler. + * + * @details + * + * Function : PtMiLrgCntrlCfm + * + * This function handles the control + * confirm invoked by MAC to Layer Manager. + * Users of MAC who intend to provide a glue logic + * for portability of control Confirm are expected + * to fill in the code in this function definition. + * + * @param[in] Pst *pst, the post structure + * @param[in] RgMngmt *cfm, the control confirm structure + * @return S16 + * -# ROK + **/ +#ifdef ANSI +PUBLIC S16 PtMiLrgCntrlCfm +( +Pst *pst, /* post structure */ +RgMngmt *cfm /* Control Confirm */ +) +#else +PUBLIC S16 PtMiLrgCntrlCfm (pst, cfm) +Pst *pst; /* post structure */ +RgMngmt *cfm; /* Control Confirm */ +#endif +{ + TRC3(PtMiLrgCntrlCfm) + RETVALUE(ROK); +}/* end of PtMiLrgCntrlCfm */ + +/** + * @brief Portable Function definition for Layer Manager Control + * confirm handler. + * + * @details + * + * Function : PtMiLrgSchCntrlCfm + * + * This function handles the control + * confirm invoked by scheduler to Layer Manager. + * Users of MAC who intend to provide a glue logic + * for portability of control Confirm are expected + * to fill in the code in this function definition. + * + * @param[in] Pst *pst, the post structure + * @param[in] RgMngmt *cfm, the control confirm structure + * @return S16 + * -# ROK + **/ +#ifdef ANSI +PUBLIC S16 PtMiLrgSchCntrlCfm +( +Pst *pst, /* post structure */ +RgMngmt *cfm /* Control Confirm */ +) +#else +PUBLIC S16 PtMiLrgSchCntrlCfm (pst, cfm) +Pst *pst; /* post structure */ +RgMngmt *cfm; /* Control Confirm */ +#endif +{ + TRC3(PtMiLrgSchCntrlCfm) + RETVALUE(ROK); +}/* end of PtMiLrgSchCntrlCfm */ + + +/** + * @brief Portable Function definition for Layer Manager Trace + * Indication handler. + * + * @details + * + * Function : PtMiLrgTrcInd + * + * This function handles the trace + * indication invoked by MAC to Layer Manager. + * Users of MAC who intend to provide a glue logic + * for portability of trace indication are expected + * to fill in the code in this function definition. + * + * @param[in] Pst *pst, the post structure + * @param[in] RgMngmt *cfm, the trace indication structure + * @return S16 + * -# ROK + **/ +#ifdef ANSI +PUBLIC S16 PtMiLrgTrcInd +( +Pst *pst, /* post structure */ +RgMngmt *trc, /* Trace Event */ +Buffer *mBuf /* Trace message */ +) +#else +PUBLIC S16 PtMiLrgTrcInd (pst, trc,mBuf) +Pst *pst; /* post structure */ +RgMngmt *trc; /* Trace Event */ +Buffer *mBuf; /* Trace message */ +#endif +{ + TRC3(PtMiLrgTrcInd) + RETVALUE(ROK); +}/* end of PtMiLrgTrcInd */ +#ifdef LTE_L2_MEAS +/** + * @brief Portable Function definition for L2 Measurement Configuration + * confirm handler. + * + * @details + * + * Function : PtMiLrgSchL2MeasCfm + * + * + * @param[in] Pst *pst, the post structure + * @param[in] *cfm, the measurement confirm structure + * @return S16 + * -# ROK + **/ +#ifdef ANSI +PUBLIC S16 PtMiLrgSchL2MeasCfm +( +Pst *pst, /* post structure */ +LrgSchMeasCfmInfo *cfm /* Measurement Confirm */ +) +#else +PUBLIC S16 PtMiLrgSchL2MeasCfm(pst, cfm) +Pst *pst; /* post structure */ +LrgSchMeasCfmInfo *cfm; /* Measurement Confirm */ +#endif +{ + TRC3(PtMiLrgSchL2MeasCfm) + + RETVALUE(ROK); +}/* end of PtMiLrgSchL2MeasCfm */ + +/** + * @brief Portable Function definition for L2 Measurement stop + * confirm handler. + * + * @details + * + * Function : PtMiLrgSchL2MeasStopCfm + * + * + * @param[in] Pst *pst, the post structure + * @param[in] *cfm, the measurement confirm structure + * @return S16 + * -# ROK + **/ +#ifdef ANSI +PUBLIC S16 PtMiLrgSchL2MeasStopCfm +( +Pst *pst, /* post structure */ +LrgSchMeasCfmInfo *cfm /* Measurement Confirm */ +) +#else +PUBLIC S16 PtMiLrgSchL2MeasStopCfm(pst, cfm) +Pst *pst; /* post structure */ +LrgSchMeasCfmInfo *cfm; /* Measurement Confirm */ +#endif +{ + TRC3(PtMiLrgSchL2MeasStopCfm) + + RETVALUE(ROK); +}/* end of PtMiLrgSchL2MeasStopCfm */ +#endif +#endif /*--PTRGMILRG--*/ + + +/********************************************************************** + + End of file +**********************************************************************/ diff --git a/src/5gnrmac/rg_ptui.c b/src/5gnrmac/rg_ptui.c new file mode 100755 index 000000000..cfe0b7c13 --- /dev/null +++ b/src/5gnrmac/rg_ptui.c @@ -0,0 +1,2286 @@ +/******************************************************************************* +################################################################################ +# Copyright (c) [2017-2019] [Radisys] # +# # +# 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. # +################################################################################ +*******************************************************************************/ + +/************************************************************************ + + Name: LTE-MAC layer + + Type: C source file + + Desc: C source code for Upper Interface Module + + File: rg_ptui.c + +**********************************************************************/ + +/** @file rg_ptui.c +@brief This file contains the definitions for Upper Interface(RGR/CRG/RGU) + primitives that are invoked from MAC to its service users. + Portable functions corresponding to these primitives are also defined. +*/ +/* header include files (.h) */ +#include "envopt.h" /* environment options */ +#include "envdep.h" /* environment dependent */ +#include "envind.h" /* environment independent */ +#include "gen.h" /* general */ +#include "ssi.h" /* system services */ +#include "cm_tkns.h" /* Common Token Defines */ +#include "cm_llist.h" /* Common Link List Defines */ +#include "cm_hash.h" /* Common Hash List Defines */ +#include "cm_lte.h" /* Common LTE Defines */ +#include "rg_env.h" /* MAC Environment Defines */ +#include "crg.h" /* CRG Interface defines */ +#include "rgr.h" /* RGR Interface defines */ +#include "rgu.h" /* RGU Interface defines */ +#include "rgm.h" /* RGM Interface defines*/ + +/* header/extern include files (.x) */ +#include "gen.x" /* general */ +#include "ssi.x" /* system services */ +#include "cm_tkns.x" /* Common Token Definitions */ +#include "cm_llist.x" /* Common Link List Definitions */ +#include "cm_lib.x" /* Common Library Definitions */ +#include "cm_hash.x" /* Common Hash List Definitions */ +#include "cm_lte.x" /* Common LTE Defines */ +#include "crg.x" /* CRG Interface includes */ +#include "rgr.x" /* RGR Interface includes */ +#include "rgu.x" /* RGU Interface includes */ +#include "rgm.x" /* RGM Interface includes*/ +#include "ss_rbuf.h" +#include "ss_rbuf.x" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#if !(defined(LCRGUIRGU) && defined(LWLCRGUIRGU) && defined(KW)) +#define PTRGUIRGU +#endif + +#if !(defined(LCRGUICRG) && defined(NH)) +#define PTRGUICRG +#endif + +#if !(defined(LCRGUIRGR) && defined(NX)) +#define PTRGUIRGR +#endif + +#if !(defined(LCRGUIRGM) && defined(RM)) +#define PTRGUIRGM +#endif + +/* MAX Number of Service Users of RG */ +#define RG_MAX_RGU_USR 3 + +/* MAX Number of Service Users of RG */ +#define RG_MAX_CRG_USR 2 + +/* MAX Number of Service Users of RG */ +#define RG_MAX_RGR_USR 2 + +/* MAX Number of Service Users of RG */ +#define RG_MAX_RGM_USR 2 +#ifdef PTRGUIRGU +/** @brief Confirmation from MAC to RLC for the bind/Unbind + * request for the interface saps */ +EXTERN S16 PtUiRguBndCfm ARGS((Pst* pst, SuId suId, U8 status)); +/** @brief Data Indication from MAC to RLC to + * forward the data received for common channels*/ +EXTERN S16 PtUiRguCDatInd ARGS((Pst* pst, SuId suId, RguCDatIndInfo * datInd)); +/** @brief Data Indication from MAC to RLC to + * forward the data received for dedicated channels*/ +EXTERN S16 PtUiRguDDatInd ARGS((Pst* pst, SuId suId, RguDDatIndInfo * datInd)); +/** @brief Status Indication from MAC to RLC + * as a response to the staRsp primitive from RLC. + * Informs RLC of the totalBufferSize and Timing Info + * for the transmission on common channels. */ +EXTERN S16 PtUiRguCStaInd ARGS((Pst* pst, SuId suId, RguCStaIndInfo * staInd)); +/** @brief Status Indication from MAC to RLC + * as a response to the staRsp primitive from RLC. + * Informs RLC of the totalBufferSize and Timing Info + * for the transmission on dedicated channels. */ +EXTERN S16 PtUiRguDStaInd ARGS((Pst* pst, SuId suId, RguDStaIndInfo * staInd)); +#ifdef LTE_L2_MEAS +/**@brief HARQ Status Indication from MAC to RLC */ +EXTERN S16 PtUiRguHqStaInd ARGS((Pst* pst,SuId suId, + RguHarqStatusInd *harqStatusInd)); +#endif +/**@brief PDB FLow Control Indication from MAC to RLC */ +EXTERN S16 PtUiRguFlowCntrlInd ARGS((Pst* pst,SuId suId, + RguFlowCntrlInd *flowCntrlInd)); +#endif /*--#ifdef PTRGUIRGU--*/ +S16 RgUiRguFlowCntrlInd(Pst* pst, SuId suId, RguFlowCntrlInd *flowCntrlInd); +#ifdef LTE_L2_MEAS +#ifdef MAC_RLC_HARQ_STA_RBUF +PUBLIC S16 RgUiRguHqStaIndRbuf ARGS((Pst* pst,SuId suId,RguHarqStatusInd *harqStatusInd)); +#endif +#endif + +#if defined(MAC_RLC_UL_RBUF) && !defined(SS_RBUF) +PRIVATE S16 RgUiRguDDatIndRbuf ARGS((RguDDatIndInfo *datInd)); +#endif +EXTERN Void rgFreeSharableSBuf ARGS((Data **data, Size size)); + +#ifdef RGR_CQI_REPT +EXTERN S16 PtUiRgrStaInd ARGS(( Pst* pst, SuId suId, RgrStaIndInfo *staInd)); +#endif +/* LTE_ADV_FLAG_REMOVED_START */ +EXTERN S16 PtUiRgrLoadInfInd ARGS(( Pst* pst, SuId suId, RgrLoadInfIndInfo *loadInfInd)); +/* LTE_ADV_FLAG_REMOVED_END */ +EXTERN S16 PtUiRgrUeStaInd ARGS +(( +Pst* pst, +SuId suId, +RgrUeStaIndInfo *staInd +)); +#ifdef PTRGUICRG +/** @brief Confirmation from MAC to RRC for the bind/Unbind + * request for the interface saps */ +EXTERN S16 PtUiCrgBndCfm ARGS((Pst* pst, SuId suId, U8 status)); +/** @brief Configuration Confirm from MAC to RRC */ +EXTERN S16 PtUiCrgCfgCfm ARGS((Pst* pst, SuId suId, CrgCfgTransId transId, U8 status)); +#endif /*--#ifdef PTRGUICRG--*/ + +#ifdef PTRGUIRGR +/** @brief Confirmation from MAC to RRM for the bind/Unbind + * request for the interface saps */ +EXTERN S16 PtUiRgrBndCfm ARGS((Pst* pst, SuId suId, U8 status)); +/** @brief Configuration Confirm from MAC to RRM */ +EXTERN S16 PtUiRgrCfgCfm ARGS((Pst* pst, SuId suId, RgrCfgTransId transId, U8 status)); +EXTERN S16 PtUiRgrTtiInd ARGS((Pst* pst, SuId suId, RgrTtiIndInfo *ttiInd)); +/* Added for SI Enhancement*/ +#ifdef RGR_SI_SCH +EXTERN S16 PtUiRgrSiCfgCfm ARGS((Pst* pst, SuId suId, RgrCfgTransId transId, U8 status)); +EXTERN S16 PtUiRgrWarningSiCfgCfm ARGS((Pst* pst, SuId suId, + RgrCfgTransId transId, U8 siId, U8 status)); +#endif/*RGR_SI_SCH*/ +#endif /*--#ifdef PTRGUIRGR--*/ + +#ifdef PTRGUIRGM +PUBLIC S16 PtUiRgmPrbRprtInd ARGS((Pst* pst, SuId suId, RgmPrbRprtInd *prbRprtInd)); +PUBLIC S16 PtUiRgmBndCfm ARGS((Pst* pst, SuId suId, U8 status)); +PUBLIC S16 PtUiRgmTransModeInd ARGS((Pst* pst, SuId suId, RgmTransModeInd *transModeInd)); +#endif +PUBLIC S16 RgUiRgmSendPrbRprtInd ARGS((Pst* pst, SuId suId, RgmPrbRprtInd *prbRprtInd)); +PUBLIC S16 RgUiRgmChangeTransModeInd ARGS((Pst* pst, SuId suId, RgmTransModeInd *transModeInd)); + +PUBLIC S16 RgUiRguFlowCntrlInd ARGS((Pst* pst, SuId suId, RguFlowCntrlInd *flowCntrlInd)); +/* Added for sending TTI tick to RRM */ +/** @brief TTI indication from MAC to RRM */ +PRIVATE CONSTANT RgrTtiInd RgUiRgrTtiIndMt[RG_MAX_RGR_USR] = +{ +#ifdef LCRGUIRGR + cmPkRgrTtiInd, +#else + PtUiRgrTtiInd, +#endif +#ifdef NX + NxLiRgrTtiInd, +#else + PtUiRgrTtiInd, +#endif +}; + + +/** @brief Confirmation from MAC to RRM for the bind/Unbind + * request for the interface saps */ +PRIVATE CONSTANT RgrBndCfm RgUiRgrBndCfmMt[RG_MAX_RGR_USR] = +{ +#ifdef LCRGUIRGR + cmPkRgrBndCfm, +#else + PtUiRgrBndCfm, +#endif +#ifdef NX + NxLiRgrBndCfm, +#else + PtUiRgrBndCfm, +#endif +}; + +/** @brief Confirmation from MAC to RRM for the bind/Unbind + * request for the interface saps via RGM interface*/ +PRIVATE CONSTANT RgmBndCfm RgUiRgmBndCfmMt[RG_MAX_RGM_USR] = +{ +#ifdef RGM_LC + cmPkRgmBndCfm, +#else + PtUiRgmBndCfm, +#endif +#ifdef RM + RmLiRgmBndCfm, /*To be added by RRM*/ +#else + PtUiRgmBndCfm, +#endif +}; + + +/** @brief Configuration Confirm from MAC to RRM */ +PRIVATE CONSTANT RgrCfgCfm RgUiRgrCfgCfmMt[RG_MAX_RGR_USR] = +{ +#ifdef LCRGUIRGR + cmPkRgrCfgCfm, +#else + PtUiRgrCfgCfm, +#endif +#ifdef NX + NxLiRgrCfgCfm, +#else + PtUiRgrCfgCfm, +#endif +}; + +/* Added for SI Enhancement*/ +#ifdef RGR_SI_SCH +/** @brief SI Configuration Confirm from MAC to RRM */ +PRIVATE CONSTANT RgrSiCfgCfm RgUiRgrSiCfgCfmMt[RG_MAX_RGR_USR] = +{ +#ifdef LCRGUIRGR + cmPkRgrSiCfgCfm, +#else + PtUiRgrSiCfgCfm, +#endif +#ifdef NX + NxLiRgrSiCfgCfm, +#else + PtUiRgrSiCfgCfm, +#endif +}; + + +/** @brief Warning SI Configuration Confirm from MAC to RRM */ +PRIVATE CONSTANT RgrWarningSiCfgCfm RgUiRgrWarningSiCfgCfmMt[RG_MAX_RGR_USR] = +{ +#ifdef LCRGUIRGR + cmPkRgrWarningSiCfgCfm, +#else + PtUiRgrWarningSiCfgCfm, +#endif +#ifdef NX + NxLiRgrWarningSiCfgCfm, +#else + PtUiRgrWarningSiCfgCfm, +#endif +}; + +#endif/*RGR_SI_SCH */ +/** @brief Confirmation from MAC to RRC for the bind/Unbind + * request for the interface saps */ +PRIVATE CONSTANT CrgBndCfm RgUiCrgBndCfmMt[RG_MAX_CRG_USR] = +{ +#ifdef LCRGUICRG + cmPkCrgBndCfm, +#else + PtUiCrgBndCfm, +#endif +#ifdef NH + NhLiCrgBndCfm, +#else + PtUiCrgBndCfm, +#endif +}; + +/** @brief Configuration Confirm from MAC to RRC */ +PRIVATE CONSTANT CrgCfgCfm RgUiCrgCfgCfmMt[RG_MAX_CRG_USR] = +{ +#ifdef LCRGUICRG + cmPkCrgCfgCfm, +#else + PtUiCrgCfgCfm, +#endif +#ifdef NH + NhLiCrgCfgCfm, +#else + PtUiCrgCfgCfm, +#endif +}; + + +/** @brief Confirmation from MAC to RLC for the bind/Unbind + * request for the interface saps */ +PRIVATE CONSTANT RguBndCfm RgUiRguBndCfmMt[RG_MAX_RGU_USR] = +{ +#ifdef LCRGUIRGU + cmPkRguBndCfm, +#else + PtUiRguBndCfm, +#endif +#ifdef KW + KwLiRguBndCfm, +#else + PtUiRguBndCfm, +#endif +#ifdef LWLCRGUIRGU + cmPkRguBndCfm, +#else + PtUiRguBndCfm, +#endif +}; + +/** @brief Data Indication from MAC to RLC to + * forward the data received for common channels*/ +PRIVATE CONSTANT RguCDatInd RgUiRguCDatIndMt[RG_MAX_RGU_USR] = +{ +#ifdef LCRGUIRGU + cmPkRguCDatInd, +#else + PtUiRguCDatInd, +#endif +#ifdef KW + KwLiRguCDatInd, +#else + PtUiRguCDatInd, +#endif +#ifdef LWLCRGUIRGU + cmPkRguCDatInd, +#else + PtUiRguCDatInd, +#endif +}; + +/** @brief Data Indication from MAC to RLC to + * forward the data received for dedicated channels*/ +PRIVATE CONSTANT RguDDatInd RgUiRguDDatIndMt[RG_MAX_RGU_USR] = +{ +#ifdef LCRGUIRGU + cmPkRguDDatInd, +#else + PtUiRguDDatInd, +#endif +#ifdef KW + KwLiRguDDatInd, +#else + PtUiRguDDatInd, +#endif +#ifdef LWLCRGUIRGU + cmPkRguDDatInd, +#else + PtUiRguDDatInd, +#endif +}; + +/** @brief Status Indication from MAC to RLC + * as a response to the staRsp primitive from RLC. + * Informs RLC of the totalBufferSize and Timing Info + * for the transmission on common channels. */ +PRIVATE CONSTANT RguCStaInd RgUiRguCStaIndMt[RG_MAX_RGU_USR] = +{ +#ifdef LCRGUIRGU + cmPkRguCStaInd, +#else + PtUiRguCStaInd, +#endif +#ifdef KW + KwLiRguCStaInd, +#else + PtUiRguCStaInd, +#endif +#ifdef LWLCRGUIRGU + cmPkRguCStaInd, +#else + PtUiRguCStaInd, +#endif +}; + +/** @brief Status Indication from MAC to RLC + * as a response to the staRsp primitive from RLC. + * Informs RLC of the totalBufferSize and Timing Info + * for the transmission on dedicated channels. */ +PRIVATE CONSTANT RguDStaInd RgUiRguDStaIndMt[RG_MAX_RGU_USR] = +{ +#ifdef LCRGUIRGU + cmPkRguDStaInd, +#else + PtUiRguDStaInd, +#endif +#ifdef KW + KwLiRguDStaInd, +#else + PtUiRguDStaInd, +#endif +#ifdef LWLCRGUIRGU + cmPkRguDStaInd, +#else + PtUiRguDStaInd, +#endif +}; + +#ifdef LTE_L2_MEAS +/** @brief HARQ Status Indication from MAC to RLC + * as a response to the DdatReq primitive from RLC. + * Informs RLC of the successful transmission of TB's + * (ACK/NACK) along with Mapping Info. */ +PRIVATE CONSTANT RguHqStaInd RgUiRguHqStaIndMt[RG_MAX_RGU_USR] = +{ +#ifdef LCRGUIRGU + cmPkRguHqStaInd, +#else + PtUiRguHqStaInd, +#endif +#ifdef KW + KwLiRguHqStaInd, +#else + PtUiRguHqStaInd, +#endif +#ifdef LWLCRGUIRGU + cmPkRguHqStaInd, +#else + PtUiRguHqStaInd, +#endif +}; +#endif /* LTE_L2_MEAS */ + +/* ccpu00117452 - MOD - Changed macro name from + RGR_RRM_DLPWR_CNTRL to RGR_CQI_REPT */ +#ifdef RGR_CQI_REPT +/** @brief TTI indication from MAC to RRM */ +PRIVATE CONSTANT RgrStaInd RgUiRgrStaIndMt[RG_MAX_RGR_USR] = +{ +#ifdef LCRGUIRGR + cmPkRgrStaInd, +#else + PtUiRgrStaInd, +#endif +#ifdef NX + NxLiRgrStaInd, +#else + PtUiRgrStaInd, +#endif +}; +#endif /* RGR_CQI_REPT */ + +/* LTE_ADV_FLAG_REMOVED_START */ +/** @brief LOAD INF indication from MAC to RRM */ +PRIVATE CONSTANT RgrLoadInfInd RgUiRgrLoadInfIndMt[RG_MAX_RGR_USR] = +{ +#ifdef LCRGUIRGR + cmPkRgrLoadInfInd, +#else + PtUiRgrLoadInfInd, +#endif +#ifdef NX + NxLiRgrLoadInfInd, +#else + PtUiRgrLoadInfInd, +#endif +}; +/* LTE_ADV_FLAG_REMOVED_END */ + +/** @brief TTI indication from MAC to RRM */ +PRIVATE CONSTANT RgrUeStaInd RgUiRgrUeStaIndMt[RG_MAX_RGR_USR] = +{ +#ifdef LCRGUIRGR + cmPkRgrUeStaInd, +#else + PtUiRgrUeStaInd, +#endif +#ifdef NX + NxLiRgrUeStaInd, +#else + PtUiRgrUeStaInd, +#endif +}; + +/** @brief Average PRB usage indication from MAC to RRM */ +PRIVATE CONSTANT RgmPrbRprtIndFptr RgUiRgmSendPrbRprtIndMt[RG_MAX_RGM_USR] = +{ +#ifdef RGM_LC + cmPkRgmPrbRprtInd, +#else + PtUiRgmPrbRprtInd, +#endif +#ifdef RM + RmLiRgmPrbRprtInd, +#else + PtUiRgmPrbRprtInd, +#endif +}; + + +/** @brief Transmission Mode Change indication from MAC to RRM */ +PRIVATE CONSTANT RgmTransModeIndFptr RgUiRgmChangeTransModeIndMt[RG_MAX_RGM_USR] = +{ +#ifdef RGM_LC + cmPkRgmTransModeInd, +#else + PtUiRgmTransModeInd, +#endif +#ifdef RM + RmLiRgmTransModeInd, +#else + PtUiRgmTransModeInd, +#endif +}; + +PRIVATE CONSTANT RguFlowCntrlIndInfo RgUiRguFlowCntrlIndMt[RG_MAX_RGU_USR] = +{ +#ifdef LCRGUIRGU + cmPkRguFlowCntrlInd, +#else + PtUiRguFlowCntrlInd, +#endif +#ifdef KW + KwLiRguFlowCntrlInd, +#else + PtUiRguFlowCntrlInd, +#endif +#ifdef LWLCRGUIRGU + cmPkRguFlowCntrlInd, +#else + PtUiRguFlowCntrlInd, +#endif +}; +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#ifdef RG + +/** +* @brief Confirmation from MAC to RRM for the bind/Unbind + * request for the interface saps +* +* @details +* +* Function : RgUiRgrBndCfm +* +* @param[in] Pst* pst +* @param[in] SuId suId +* @param[in] U8 status +* @return S16 +* -# ROK +**/ +#ifdef ANSI +PUBLIC S16 RgUiRgrBndCfm +( +Pst* pst, +SuId suId, +U8 status +) +#else +PUBLIC S16 RgUiRgrBndCfm(pst, suId, status) +Pst* pst; +SuId suId; +U8 status; +#endif +{ + + TRC3(RgUiRgrBndCfm); + + RETVALUE((*RgUiRgrBndCfmMt[pst->selector])(pst, suId, status)); + +} +/** +* @brief Confirmation from MAC to RRM for the bind/Unbind + * request for the interface saps via RGM interface +* +* @details +* +* Function : RgUiRgmBndCfm +* +* @param[in] Pst* pst +* @param[in] SuId suId +* @param[in] U8 status +* @return S16 +* -# ROK +**/ +#ifdef ANSI +PUBLIC S16 RgUiRgmBndCfm +( +Pst* pst, +SuId suId, +U8 status +) +#else +PUBLIC S16 RgUiRgmBndCfm(pst, suId, status) +Pst* pst; +SuId suId; +U8 status; +#endif +{ + + TRC3(RgUiRgmBndCfm); + + RETVALUE((*RgUiRgmBndCfmMt[pst->selector])(pst, suId, status)); + +} + + + +/* Added for sending TTI tick to RRM */ + +/** +* @brief TTI indication from MAC to RGR user. +* +* @details +* +* Function : RgUiRgrTtiInd +* +* @param[in] Pst* pst +* @param[in] SuId suId +* @param[in] RgrTtiIndInfo ttiInd +* @return S16 +* -# ROK +**/ +#ifdef ANSI +PUBLIC S16 RgUiRgrTtiInd +( +Pst* pst, +SuId suId, +RgrTtiIndInfo *ttiInd +) +#else +PUBLIC S16 RgUiRgrTtiInd(pst, suId, ttiInd) +Pst* pst; +SuId suId; +RgrTtiIndInfo *ttiInd; +#endif +{ + + TRC3(RgUiRgrTtiInd); + + RETVALUE((*RgUiRgrTtiIndMt[pst->selector])(pst, suId, ttiInd)); + +} + + + +/** +* @brief Configuration Confirm from MAC to RRM +* +* @details +* +* Function : RgUiRgrCfgCfm +* +* @param[in] Pst* pst +* @param[in] SuId suId +* @param[in] RgrCfgTransId transId +* @param[in] U8 status +* @return S16 +* -# ROK +**/ +#ifdef ANSI +PUBLIC S16 RgUiRgrCfgCfm +( +Pst* pst, +SuId suId, +RgrCfgTransId transId, +U8 status +) +#else +PUBLIC S16 RgUiRgrCfgCfm(pst, suId, transId, status) +Pst* pst; +SuId suId; +RgrCfgTransId transId; +U8 status; +#endif +{ + + TRC3(RgUiRgrCfgCfm); + + RETVALUE((*RgUiRgrCfgCfmMt[pst->selector])(pst, suId, transId, status)); + +} + + +/** +* @brief Confirmation from MAC to RRC for the bind/Unbind + * request for the interface saps +* +* @details +* +* Function : RgUiCrgBndCfm +* +* @param[in] Pst* pst +* @param[in] SuId suId +* @param[in] U8 status +* @return S16 +* -# ROK +**/ +#ifdef ANSI +PUBLIC S16 RgUiCrgBndCfm +( +Pst* pst, +SuId suId, +U8 status +) +#else +PUBLIC S16 RgUiCrgBndCfm(pst, suId, status) +Pst* pst; +SuId suId; +U8 status; +#endif +{ + + TRC3(RgUiCrgBndCfm); + + RETVALUE((*RgUiCrgBndCfmMt[pst->selector])(pst, suId, status)); + +} + + + +/** +* @brief Configuration Confirm from MAC to RRC +* +* @details +* +* Function : RgUiCrgCfgCfm +* +* @param[in] Pst* pst +* @param[in] SuId suId +* @param[in] CrgCfgTransId transId +* @param[in] U8 status +* @return S16 +* -# ROK +**/ +#ifdef ANSI +PUBLIC S16 RgUiCrgCfgCfm +( +Pst* pst, +SuId suId, +CrgCfgTransId transId, +U8 status +) +#else +PUBLIC S16 RgUiCrgCfgCfm(pst, suId, transId, status) +Pst* pst; +SuId suId; +CrgCfgTransId transId; +U8 status; +#endif +{ + + TRC3(RgUiCrgCfgCfm); + + RETVALUE((*RgUiCrgCfgCfmMt[pst->selector])(pst, suId, transId, status)); + +} + + +/** +* @brief Confirmation from MAC to RLC for the bind/Unbind + * request for the interface saps +* +* @details +* +* Function : RgUiRguBndCfm +* +* @param[in] Pst* pst +* @param[in] SuId suId +* @param[in] U8 status +* @return S16 +* -# ROK +**/ +#ifdef ANSI +PUBLIC S16 RgUiRguBndCfm +( +Pst* pst, +SuId suId, +U8 status +) +#else +PUBLIC S16 RgUiRguBndCfm(pst, suId, status) +Pst* pst; +SuId suId; +U8 status; +#endif +{ + + TRC3(RgUiRguBndCfm); + + RETVALUE((*RgUiRguBndCfmMt[pst->selector])(pst, suId, status)); + +} + +PUBLIC int macDDatIndSnt; +PUBLIC int macCDatIndSnt; + + +/** +* @brief Data Indication from MAC to RLC to + * forward the data received for common channels +* +* @details +* +* Function : RgUiRguCDatInd +* +* @param[in] Pst* pst +* @param[in] SuId suId +* @param[in] RguCDatIndInfo * datInd +* @return S16 +* -# ROK +**/ +#ifdef ANSI +PUBLIC S16 RgUiRguCDatInd +( +Pst* pst, +SuId suId, +RguCDatIndInfo * datInd +) +#else +PUBLIC S16 RgUiRguCDatInd(pst, suId, datInd) +Pst* pst; +SuId suId; +RguCDatIndInfo * datInd; +#endif +{ + macCDatIndSnt++; + + TRC3(RgUiRguCDatInd); + + RETVALUE((*RgUiRguCDatIndMt[pst->selector])(pst, suId, datInd)); + +} + + +/** +* @brief Data Indication from MAC to RLC to + * forward the data received for dedicated channels +* +* @details +* +* Function : RgUiRguDDatInd +* +* @param[in] Pst* pst +* @param[in] SuId suId +* @param[in] RguDDatIndInfo * datInd +* @return S16 +* -# ROK +**/ +#ifdef ANSI +PUBLIC S16 RgUiRguDDatInd +( +Pst* pst, +SuId suId, +RguDDatIndInfo * datInd +) +#else +PUBLIC S16 RgUiRguDDatInd(pst, suId, datInd) +Pst* pst; +SuId suId; +RguDDatIndInfo * datInd; +#endif +{ + macDDatIndSnt++; + + TRC3(RgUiRguDDatInd); + +#if defined(MAC_RLC_UL_RBUF) && !defined(SS_RBUF) + RETVALUE(RgUiRguDDatIndRbuf(datInd)); +#else + RETVALUE((*RgUiRguDDatIndMt[pst->selector])(pst, suId, datInd)); +#endif +} + + + +/** +* @brief Status Indication from MAC to RLC + * as a response to the staRsp primitive from RLC. + * Informs RLC of the totalBufferSize and Timing Info + * for the transmission on common channels. +* +* @details +* +* Function : RgUiRguCStaInd +* +* @param[in] Pst* pst +* @param[in] SuId suId +* @param[in] RguCStaIndInfo * staInd +* @return S16 +* -# ROK +**/ +#ifdef ANSI +PUBLIC S16 RgUiRguCStaInd +( +Pst* pst, +SuId suId, +RguCStaIndInfo * staInd +) +#else +PUBLIC S16 RgUiRguCStaInd(pst, suId, staInd) +Pst* pst; +SuId suId; +RguCStaIndInfo * staInd; +#endif +{ + + TRC3(RgUiRguCStaInd); + + RETVALUE((*RgUiRguCStaIndMt[pst->selector])(pst, suId, staInd)); + +} + + + +/** +* @brief Status Indication from MAC to RLC + * as a response to the staRsp primitive from RLC. + * Informs RLC of the totalBufferSize and Timing Info + * for the transmission on dedicated channels. +* +* @details +* +* Function : RgUiRguDStaInd +* +* @param[in] Pst* pst +* @param[in] SuId suId +* @param[in] RguDStaIndInfo * staInd +* @return S16 +* -# ROK +**/ +#ifdef ANSI +PUBLIC S16 RgUiRguDStaInd +( +Pst* pst, +SuId suId, +RguDStaIndInfo * staInd +) +#else +PUBLIC S16 RgUiRguDStaInd(pst, suId, staInd) +Pst* pst; +SuId suId; +RguDStaIndInfo * staInd; +#endif +{ + + TRC3(RgUiRguDStaInd); + + RETVALUE((*RgUiRguDStaIndMt[pst->selector])(pst, suId, staInd)); + +} +#ifdef LTE_L2_MEAS +/* TODO: Function header */ +#ifdef ANSI +PUBLIC S16 RgUiRguHqStaInd +( +Pst* pst, +SuId suId, +RguHarqStatusInd *harqStatusInd +) +#else +PUBLIC S16 RgUiRguHqStaInd(pst, suId, harqStatusInd) +Pst* pst; +SuId suId; +RguHarqStatusInd *harqStatusInd; +#endif +{ + + TRC3(RgUiRguHqStaInd); +#if defined(SPLIT_RLC_DL_TASK) && defined(MAC_RLC_HARQ_STA_RBUF) + S16 ret=ROK; + ret = RgUiRguHqStaIndRbuf(pst,suId,harqStatusInd); + RETVALUE(ret); +#else + RETVALUE((*RgUiRguHqStaIndMt[pst->selector])(pst, suId, harqStatusInd)); +#endif + +} /* RgUiRguHqStaInd */ +#endif /* LTE_L2_MEAS */ + +#ifdef ANSI +PUBLIC S16 RgUiRguFlowCntrlInd +( +Pst* pst, +SuId suId, +RguFlowCntrlInd *flowCntrlInd +) +#else +PUBLIC S16 RgUiRguFlowCntrlInd(pst, suId, harqStatusInd) +Pst* pst; +SuId suId; +RguFlowCntrlInd *flowCntrlInd; +#endif +{ + RETVALUE((*RgUiRguFlowCntrlIndMt[pst->selector])(pst, suId, flowCntrlInd)); +} +/* Added for SI Enhancement*/ +#ifdef RGR_SI_SCH +/** +* @brief SI Configuration Confirm from MAC to RRM +* +* @details +* +* Function : RgUiRgrSiCfgCfm +* +* @param[in] Pst* pst +* @param[in] SuId suId +* @param[in] RgrCfgTransId transId +* @param[in] U8 status +* @return S16 +* -# ROK +**/ +#ifdef ANSI +PUBLIC S16 RgUiRgrSiCfgCfm +( +Pst* pst, +SuId suId, +RgrCfgTransId transId, +U8 status +) +#else +PUBLIC S16 RgUiRgrSiCfgCfm(pst, suId, transId, status) +Pst* pst; +SuId suId; +RgrCfgTransId transId; +U8 status; +#endif +{ + + TRC3(RgUiRgrSiCfgCfm); + + RETVALUE((*RgUiRgrSiCfgCfmMt[pst->selector])(pst, suId, transId, status)); + +} + +/** +* @brief Warning SI Configuration Confirm from MAC to RRM +* +* @details +* +* Function : RgUiRgrWarningSiCfgCfm +* +* @param[in] Pst* pst +* @param[in] SuId suId +* @param[in] RgrCfgTransId transId +* @param[in] U8 siId +* @param[in] U8 status +* @return S16 +* -# ROK +**/ +#ifdef ANSI +PUBLIC S16 RgUiRgrWarningSiCfgCfm +( +Pst* pst, +SuId suId, +RgrCfgTransId transId, +U8 siId, +U8 status +) +#else +PUBLIC S16 RgUiRgrWarningSiCfgCfm(pst, suId, transId, siId,status) +Pst* pst; +SuId suId; +RgrCfgTransId transId; +U8 siId; +U8 status; +#endif +{ + TRC3(RgUiRgrWarningSiCfgCfm); + + RETVALUE((*RgUiRgrWarningSiCfgCfmMt[pst->selector]) + (pst, suId, transId, siId, status)); +} + +#endif/*RGR_SI_SCH*/ + + +/* ccpu00117452 - MOD - Changed macro name from + RGR_RRM_DLPWR_CNTRL to RGR_CQI_REPT */ +#ifdef RGR_CQI_REPT +/** +* @brief STA indication from MAC to RGR user. +* +* @details +* +* Function : RgUiRgrStaInd +* +* @param[in] Pst* pst +* @param[in] SuId suId +* @param[in] RgrStaIndInfo *staInd +* @return S16 +* -# ROK +**/ +#ifdef ANSI +PUBLIC S16 RgUiRgrStaInd +( +Pst* pst, +SuId suId, +RgrStaIndInfo *staInd +) +#else +PUBLIC S16 RgUiRgrStaInd(pst, suId, staInd) +Pst* pst; +SuId suId; +RgrStaIndInfo *staInd; +#endif +{ + + TRC3(RgUiRgrStaInd); + + RETVALUE((*RgUiRgrStaIndMt[pst->selector])(pst, suId, staInd)); + +} +#endif /* End of RGR_CQI_REPT */ + +/* LTE_ADV_FLAG_REMOVED_START */ +/** + * @brief LOAD INF indication from MAC to RGR user. + * + * @details + * + * Function : RgUiRgrLoadInfInd + * + * @param[in] Pst* pst + * @param[in] SuId suId + * @param[in] RgrLoadInfIndInfo *loadInfInd + * @return S16 + * -# ROK + **/ +#ifdef ANSI +PUBLIC S16 RgUiRgrLoadInfInd +( + Pst* pst, + SuId suId, + RgrLoadInfIndInfo *loadInfInd + ) +#else +PUBLIC S16 RgUiRgrLoadInfInd(pst, suId, loadInfInd) + Pst* pst; + SuId suId; + RgrLoadInfIndInfo *loadInfInd; +#endif +{ + + TRC3(RgUiRgrLoadInfInd); + + RETVALUE((*RgUiRgrLoadInfIndMt[pst->selector])(pst, suId, loadInfInd)); + +} +/* LTE_ADV_FLAG_REMOVED_END */ + +/** +* @brief UESTA indication from MAC to RGR user. +* +* @details +* +* Function : RgUiRgrUeStaInd +* +* @param[in] Pst* pst +* @param[in] SuId suId +* @param[in] RgrStaIndInfo *staInd +* @return S16 +* -# ROK +**/ +#ifdef ANSI +PUBLIC S16 RgUiRgrUeStaInd +( +Pst *pst, +SuId suId, +RgrUeStaIndInfo *ueStaInd +) +#else +PUBLIC S16 RgUiRgrUeStaInd(pst, suId, ueStaInd) +Pst *pst; +SuId suId; +RgrUeStaIndInfo *ueStaInd; +#endif +{ + + TRC3(RgUiRgrUeStaInd); + + RETVALUE((*RgUiRgrUeStaIndMt[pst->selector])(pst, suId, ueStaInd)); + +} +#endif /*--ifdef RG--*/ + +#ifdef PTRGUICRG + +/** +* @brief Confirmation from MAC to RRC for the bind/Unbind + * request for the interface saps +* +* @details +* +* Function : PtUiCrgBndCfm +* +* @param[in] Pst* pst +* @param[in] SuId suId +* @param[in] U8 status +* @return S16 +* -# ROK +**/ +#ifdef ANSI +PUBLIC S16 PtUiCrgBndCfm +( +Pst* pst, +SuId suId, +U8 status +) +#else +PUBLIC S16 PtUiCrgBndCfm(pst, suId, status) +Pst* pst; +SuId suId; +U8 status; +#endif +{ + + TRC3(PtUiCrgBndCfm); + + UNUSED(pst); + UNUSED(suId); + UNUSED(status); + + RETVALUE(ROK); + +} + + + +/** +* @brief Configuration Confirm from MAC to RRC +* +* @details +* +* Function : PtUiCrgCfgCfm +* +* @param[in] Pst* pst +* @param[in] SuId suId +* @param[in] CrgCfgTransId transId +* @param[in] U8 status +* @return S16 +* -# ROK +**/ +#ifdef ANSI +PUBLIC S16 PtUiCrgCfgCfm +( +Pst* pst, +SuId suId, +CrgCfgTransId transId, +U8 status +) +#else +PUBLIC S16 PtUiCrgCfgCfm(pst, suId, transId, status) +Pst* pst; +SuId suId; +CrgCfgTransId transId; +U8 status; +#endif +{ + + TRC3(PtUiCrgCfgCfm); + + UNUSED(pst); + UNUSED(suId); + UNUSED(transId); + UNUSED(status); + + RETVALUE(ROK); + +} +#endif /*--ifdef PTRGUICRG--*/ + +#ifdef PTRGUIRGU + +/** +* @brief Confirmation from MAC to RLC for the bind/Unbind + * request for the interface saps +* +* @details +* +* Function : PtUiRguBndCfm +* +* @param[in] Pst* pst +* @param[in] SuId suId +* @param[in] U8 status +* @return S16 +* -# ROK +**/ +#ifdef ANSI +PUBLIC S16 PtUiRguBndCfm +( +Pst* pst, +SuId suId, +U8 status +) +#else +PUBLIC S16 PtUiRguBndCfm(pst, suId, status) +Pst* pst; +SuId suId; +U8 status; +#endif +{ + + TRC3(PtUiRguBndCfm); + + UNUSED(pst); + UNUSED(suId); + UNUSED(status); + + RETVALUE(ROK); + +} + + + +/** +* @brief Data Indication from MAC to RLC to + * forward the data received for common channels +* +* @details +* +* Function : PtUiRguCDatInd +* +* @param[in] Pst* pst +* @param[in] SuId suId +* @param[in] RguCDatIndInfo * datInd +* @return S16 +* -# ROK +**/ +#ifdef ANSI +PUBLIC S16 PtUiRguCDatInd +( +Pst* pst, +SuId suId, +RguCDatIndInfo * datInd +) +#else +PUBLIC S16 PtUiRguCDatInd(pst, suId, datInd) +Pst* pst; +SuId suId; +RguCDatIndInfo * datInd; +#endif +{ + + TRC3(PtUiRguCDatInd); + + UNUSED(pst); + UNUSED(suId); + UNUSED(datInd); + + RETVALUE(ROK); + +} + + + +/** +* @brief Data Indication from MAC to RLC to + * forward the data received for dedicated channels +* +* @details +* +* Function : PtUiRguDDatInd +* +* @param[in] Pst* pst +* @param[in] SuId suId +* @param[in] RguDDatIndInfo * datInd +* @return S16 +* -# ROK +**/ +#ifdef ANSI +PUBLIC S16 PtUiRguDDatInd +( +Pst* pst, +SuId suId, +RguDDatIndInfo * datInd +) +#else +PUBLIC S16 PtUiRguDDatInd(pst, suId, datInd) +Pst* pst; +SuId suId; +RguDDatIndInfo * datInd; +#endif +{ + + TRC3(PtUiRguDDatInd); + + UNUSED(pst); + UNUSED(suId); + UNUSED(datInd); + + RETVALUE(ROK); + +} + + + +/** +* @brief Status Indication from MAC to RLC + * as a response to the staRsp primitive from RLC. + * Informs RLC of the totalBufferSize and Timing Info + * for the transmission on common channels. +* +* @details +* +* Function : PtUiRguCStaInd +* +* @param[in] Pst* pst +* @param[in] SuId suId +* @param[in] RguCStaIndInfo * staInd +* @return S16 +* -# ROK +**/ +#ifdef ANSI +PUBLIC S16 PtUiRguCStaInd +( +Pst* pst, +SuId suId, +RguCStaIndInfo * staInd +) +#else +PUBLIC S16 PtUiRguCStaInd(pst, suId, staInd) +Pst* pst; +SuId suId; +RguCStaIndInfo * staInd; +#endif +{ + + TRC3(PtUiRguCStaInd); + + UNUSED(pst); + UNUSED(suId); + UNUSED(staInd); + + RETVALUE(ROK); + +} + + + +/** +* @brief Status Indication from MAC to RLC + * as a response to the staRsp primitive from RLC. + * Informs RLC of the totalBufferSize and Timing Info + * for the transmission on dedicated channels. +* +* @details +* +* Function : PtUiRguDStaInd +* +* @param[in] Pst* pst +* @param[in] SuId suId +* @param[in] RguDStaIndInfo * staInd +* @return S16 +* -# ROK +**/ +#ifdef ANSI +PUBLIC S16 PtUiRguDStaInd +( +Pst* pst, +SuId suId, +RguDStaIndInfo * staInd +) +#else +PUBLIC S16 PtUiRguDStaInd(pst, suId, staInd) +Pst* pst; +SuId suId; +RguDStaIndInfo * staInd; +#endif +{ + + TRC3(PtUiRguDStaInd); + + UNUSED(pst); + UNUSED(suId); + UNUSED(staInd); + + RETVALUE(ROK); + +} +#ifdef LTE_L2_MEAS +/* TODO: Function Header */ +#ifdef ANSI +PUBLIC S16 PtUiRguHqStaInd +( +Pst* pst, +SuId suId, +RguHarqStatusInd *harqStatusInd +) +#else +PUBLIC S16 PtUiRguHqStaInd(pst, suId, harqStatusInd) +Pst* pst; +SuId suId; +RguHarqStatusInd *harqStatusInd; +#endif +{ + + TRC3(PtUiRguHqStaInd); + + UNUSED(pst); + UNUSED(suId); + UNUSED(harqStatusInd); + + RETVALUE(ROK); + +} +#endif /* LTE_L2_MEAS */ + +#ifdef ANSI +PUBLIC S16 PtUiRguFlowCntrlInd +( +Pst* pst, +SuId suId, +RguFlowCntrlInd *flowCntrlInd +) +#else +PUBLIC S16 PtUiRguFlowCntrlInd(pst, suId, flowCntrlInd) +Pst* pst; +SuId suId; +RguHarqStatusInd *flowCntrlInd; +#endif +{ + + TRC3(PtUiRguFlowCntrlInd); + + UNUSED(pst); + UNUSED(suId); + UNUSED(flowCntrlInd); + + RETVALUE(ROK); + +} + +#endif /*--ifdef PTRGUIRGU--*/ + +#ifdef PTRGUIRGR + +/** +* @brief Confirmation from MAC to RRM for the bind/Unbind + * request for the interface saps +* +* @details +* +* Function : PtUiRgrBndCfm +* +* @param[in] Pst* pst +* @param[in] SuId suId +* @param[in] U8 status +* @return S16 +* -# ROK +**/ +#ifdef ANSI +PUBLIC S16 PtUiRgrBndCfm +( +Pst* pst, +SuId suId, +U8 status +) +#else +PUBLIC S16 PtUiRgrBndCfm(pst, suId, status) +Pst* pst; +SuId suId; +U8 status; +#endif +{ + + TRC3(PtUiRgrBndCfm); + + UNUSED(pst); + UNUSED(suId); + UNUSED(status); + + RETVALUE(ROK); + +} + +/* Added for sending TTI tick to RRM */ + +/** +* @brief TTI indication from MAC to RGR user. +* +* @details +* +* Function : PtUiRgrTtiInd +* +* @param[in] Pst* pst +* @param[in] SuId suId +* @param[in] RgrTtiIndInfo *ttiInd +* @return S16 +* -# ROK +**/ +#ifdef ANSI +PUBLIC S16 PtUiRgrTtiInd +( +Pst* pst, +SuId suId, +RgrTtiIndInfo *ttiInd +) +#else +PUBLIC S16 PtUiRgrTtiInd(pst, suId, ttiInd) +Pst* pst; +SuId suId; +RgrTtiIndInfo *ttiInd; +#endif +{ + + TRC3(PtUiRgrTtiInd); + + UNUSED(pst); + UNUSED(suId); + UNUSED(ttiInd); + + RETVALUE(ROK); + +} + + + +/** +* @brief Configuration Confirm from MAC to RRM +* +* @details +* +* Function : PtUiRgrCfgCfm +* +* @param[in] Pst* pst +* @param[in] SuId suId +* @param[in] RgrCfgTransId transId +* @param[in] U8 status +* @return S16 +* -# ROK +**/ +#ifdef ANSI +PUBLIC S16 PtUiRgrCfgCfm +( +Pst* pst, +SuId suId, +RgrCfgTransId transId, +U8 status +) +#else +PUBLIC S16 PtUiRgrCfgCfm(pst, suId, transId, status) +Pst* pst; +SuId suId; +RgrCfgTransId transId; +U8 status; +#endif +{ + + TRC3(PtUiRgrCfgCfm); + + UNUSED(pst); + UNUSED(suId); + UNUSED(transId); + UNUSED(status); + + RETVALUE(ROK); + +} + +/* Added for SI Enhancement*/ +#ifdef RGR_SI_SCH +/** +* @brief SI Configuration Confirm from MAC to RRM +* +* @details +* +* Function : PtUiRgrSiCfgCfm +* +* @param[in] Pst* pst +* @param[in] SuId suId +* @param[in] RgrCfgTransId transId +* @param[in] U8 status +* @return S16 +* -# ROK +**/ +#ifdef ANSI +PUBLIC S16 PtUiRgrSiCfgCfm +( +Pst* pst, +SuId suId, +RgrCfgTransId transId, +U8 status +) +#else +PUBLIC S16 PtUiRgrSiCfgCfm(pst, suId, transId, status) +Pst* pst; +SuId suId; +RgrCfgTransId transId; +U8 status; +#endif +{ + + TRC3(PtUiRgrSiCfgCfm); + + UNUSED(pst); + UNUSED(suId); + UNUSED(transId); + UNUSED(status); + + RETVALUE(ROK); + +} + +/** +* @brief Warning SI Configuration Confirm from MAC to RRM +* +* @details +* +* Function : PtUiRgrWarningSiCfgCfm +* +* @param[in] Pst* pst +* @param[in] SuId suId +* @param[in] RgrCfgTransId transId +* @param[in] U8 siId +* @param[in] U8 status +* @return S16 +* -# ROK +**/ +#ifdef ANSI +PUBLIC S16 PtUiRgrWarningSiCfgCfm +( +Pst* pst, +SuId suId, +RgrCfgTransId transId, +U8 siId, +U8 status +) +#else +PUBLIC S16 PtUiRgrWarningSiCfgCfm(pst, suId, transId, siId, status) +Pst* pst; +SuId suId; +RgrCfgTransId transId; +U8 siId; +U8 status; +#endif +{ + TRC3(PtUiRgrWarningSiCfgCfm); + + UNUSED(pst); + UNUSED(suId); + UNUSED(transId); + UNUSED(siId); + UNUSED(status); + + RETVALUE(ROK); +} +#endif/* RGR_SI_SCH */ + + +/* ccpu00117452 - MOD - Changed macro name from + RGR_RRM_DLPWR_CNTRL to RGR_CQI_REPT */ +#ifdef RGR_CQI_REPT +/** +* @brief STA indication from MAC to RGR user. +* +* @details +* +* Function : PtUiRgrStaInd +* +* @param[in] Pst* pst +* @param[in] SuId suId +* @param[in] RgrStaIndInfo *staInd +* @return S16 +* -# ROK +**/ +#ifdef ANSI +PUBLIC S16 PtUiRgrStaInd +( +Pst* pst, +SuId suId, +RgrStaIndInfo *staInd +) +#else +PUBLIC S16 PtUiRgrStaInd(pst, suId, staInd) +Pst* pst; +SuId suId; +RgrStaIndInfo *staInd; +#endif +{ + + TRC3(PtUiRgrStaInd); + + UNUSED(pst); + UNUSED(suId); + UNUSED(staInd); + + RETVALUE(ROK); + +} +#endif /* End of RGR_CQI_REPT */ +/* LTE_ADV_FLAG_REMOVED_START */ +/** + * @brief LOAD INF indication from MAC to RGR user. + * + * @details + * + * Function : PtUiRgrLoadInfInd + * + * @param[in] Pst* pst + * @param[in] SuId suId + * @param[in] RgrLoadInfIndInfo *loadInfInd + * @return S16 + * -# ROK + **/ +#ifdef ANSI +PUBLIC S16 PtUiRgrLoadInfInd +( + Pst* pst, + SuId suId, + RgrLoadInfIndInfo *loadInfInd + ) +#else +PUBLIC S16 PtUiRgrLoadInfInd(pst, suId, loadInfInd) + Pst* pst; + SuId suId; + RgrLoadInfIndInfo *loadInfInd; +#endif +{ + + TRC3(PtUiRgrLoadInfInd); + + UNUSED(pst); + UNUSED(suId); + UNUSED(loadInfInd); + + RETVALUE(ROK); + +} +/* LTE_ADV_FLAG_REMOVED_END */ + +/** +* @brief STA indication from MAC to RGR user. +* +* @details +* +* Function : PtUiRgrUeStaInd +* +* @param[in] Pst* pst +* @param[in] SuId suId +* @param[in] RgrUeStaIndInfo *ueStaInd +* @return S16 +* -# ROK +**/ +#ifdef ANSI +PUBLIC S16 PtUiRgrUeStaInd +( +Pst* pst, +SuId suId, +RgrUeStaIndInfo *ueStaInd +) +#else +PUBLIC S16 PtUiRgrUeStaInd(pst, suId, ueStaInd) +Pst* pst; +SuId suId; +RgrUeStaIndInfo *ueStaInd; +#endif +{ + + TRC3(PtUiRgrUeStaInd); + + UNUSED(pst); + UNUSED(suId); + UNUSED(ueStaInd); + + RETVALUE(ROK); + +} +#endif /*--ifdef PTRGUIRGR--*/ + + +#ifdef PTRGUIRGM +/** +* @brief Confirmation from MAC to RRM for the bind/Unbind + * request for the interface saps via RGM interface +* +* @details +* +* Function : PtUiRgmBndCfm +* +* @param[in] Pst* pst +* @param[in] SuId suId +* @param[in] U8 status +* @return S16 +* -# ROK +**/ +#ifdef ANSI +PUBLIC S16 PtUiRgmBndCfm +( +Pst* pst, +SuId suId, +U8 status +) +#else +PUBLIC S16 PtUiRgmBndCfm(pst, suId, status) +Pst* pst; +SuId suId; +U8 status; +#endif +{ + + TRC3(PtUiRgmBndCfm); + + UNUSED(pst); + UNUSED(suId); + UNUSED(status); + + RETVALUE(ROK); + +} + +/** +* @brief Average PRB indication from MAC to RRM +* +* @details +* +* Function : PtUiRgmPrbRprtInd +* +* @param[in] Pst* pst +* @param[in] SuId suId +* @param[in] RgrUeStaIndInfo *ueStaInd +* @return S16 +* -# ROK +**/ +#ifdef ANSI +PUBLIC S16 PtUiRgmPrbRprtInd +( +Pst* pst, +SuId suId, +RgmPrbRprtInd *prbRprtInd +) +#else +PUBLIC S16 PtUiRgmPrbRprtInd(pst, suId, prbRprtInd) +Pst* pst; +SuId suId; +RgmPrbRprtInd *prbRprtInd; +#endif +{ + + TRC3(PtUiRgmPrbRprtInd); + + UNUSED(pst); + UNUSED(suId); + UNUSED(prbRprtInd); + + RETVALUE(ROK); + +} + +/** +* @brief Transmission Mode Change indication from MAC to RRM +* +* @details +* +* Function : PtUiRgmTransModeInd +* +* @param[in] Pst* pst +* @param[in] SuId suId +* @param[in] RgmTransModeInd *transModeInd +* @return S16 +* -# ROK +**/ +#ifdef ANSI +PUBLIC S16 PtUiRgmTransModeInd +( +Pst* pst, +SuId suId, +RgmTransModeInd *transModeInd +) +#else +PUBLIC S16 PtUiRgmTransModeInd(pst, suId, transModeInd) +Pst* pst; +SuId suId; +RgmTransModeInd *transModeInd; +#endif +{ + + TRC3(PtUiRgmTransModeInd); + + UNUSED(pst); + UNUSED(suId); + UNUSED(transModeInd); + + RETVALUE(ROK); + +} +#endif + +/** +* @brief Average PRB indication from MAC to RRM +* +* @details +* +* Function : RgUiRgmSendPrbRprtInd +* +* @param[in] Pst* pst +* @param[in] SuId suId +* @param[in] RgmPrbRprtInd prbRprtInd +* @return S16 +* -# ROK +**/ +#ifdef ANSI +PUBLIC S16 RgUiRgmSendPrbRprtInd +( +Pst* pst, +SuId suId, +RgmPrbRprtInd *prbRprtInd +) +#else +PUBLIC S16 RgUiRgmSendPrbRprtInd(pst, suId, prbRprtInd) +Pst* pst; +SuId suId; +RgmPrbRprtInd *prbRprtInd; +#endif + +{ + TRC2(RgUiRgmSendPrbRprtInd); + RETVALUE((*RgUiRgmSendPrbRprtIndMt[pst->selector])(pst, suId, prbRprtInd)); +} + +/** +* @brief Transmission Mode change indication from MAC to RRM +* +* @details +* +* Function : RgUiRgmChangeTransModeInd +* +* @param[in] Pst* pst +* @param[in] SuId suId +* @param[in] RgmTransModeInd transModeInd +* @return S16 +* -# ROK +**/ +#ifdef ANSI +PUBLIC S16 RgUiRgmChangeTransModeInd +( +Pst* pst, +SuId suId, +RgmTransModeInd *transModeInd +) +#else +PUBLIC S16 RgUiRgmChangeTransModeInd(pst, suId, transModeInd) +Pst* pst; +SuId suId; +RgmTransModeInd *transModeInd; +#endif + +{ + TRC2(RgUiRgmChangeTransModeInd); + RETVALUE((*RgUiRgmChangeTransModeIndMt[pst->selector])(pst, suId, transModeInd)); +} + +#if defined(MAC_RLC_UL_RBUF) && !defined(SS_RBUF) +PRIVATE S16 RgUiRguDDatIndRbuf(RguDDatIndInfo *datInd) +{ + S16 ret = ROK; + Void *elem = NULLP; + RguDedDatInd1 *rguDatIndl = NULLP; + elem = SRngGetWIndx(SS_RNG_BUF_ULMAC_TO_ULRLC); + rguDatIndl = (RguDedDatInd1 *) elem; + if (NULLP == elem) + { + SsRngInfoTbl[SS_RNG_BUF_ULMAC_TO_ULRLC].pktDrop++; + U32 i,j; + for(i = 0; i< datInd->numLch; i++) + { + for(j = 0; j < datInd->lchData[i].pdu.numPdu; j++) + { + if(datInd->lchData[i].pdu.mBuf[j]) + { + SPutMsg(datInd->lchData[i].pdu.mBuf[j]); + } + } + } + rgFreeSharableSBuf((Data **)&datInd,sizeof(RguDDatIndInfo)); + ret = RFAILED; + } + else + { + rguDatIndl->msg = datInd; + SRngIncrWIndx(SS_RNG_BUF_ULMAC_TO_ULRLC); + SsRngInfoTbl[SS_RNG_BUF_ULMAC_TO_ULRLC].pktRate++; + } + RETVALUE(ret); +} +#endif +#ifdef RLC_MAC_DAT_REQ_RBUF +#ifdef ANSI +PUBLIC S16 rgDlDatReqBatchProc +( +Void +) +#else +PUBLIC S16 rgDlDatReqBatchProc() +Void; +#endif +{ +/* Read from Ring Buffer and process PDCP packets */ + + U8 rngBufDeqIndx = 0; + PRIVATE Pst rgDDatRbfuPst ={1,1,ENTRG,0,ENTKW,1,PRIOR0,RTESPEC,EVTRGUDDATREQ,0,0,2,0}; + PRIVATE Pst rgCDatRbfuPst ={1,1,ENTRG,0,ENTKW,1,PRIOR0,RTESPEC,EVTRGUCDATREQ,0,0,2,0}; + Void *elmIndx = NULLP; + RguInfoRingElem *datReqRing=NULLP; + elmIndx = SRngGetRIndx(SS_RNG_BUF_DLRLC_TO_DLMAC_DAT_REQ); + while(NULLP != elmIndx) + { + datReqRing= (RguInfoRingElem *)elmIndx; + SsRngInfoTbl[SS_RNG_BUF_DLRLC_TO_DLMAC_DAT_REQ].nPktProc++;;//Number of pkt processed in tti + if(datReqRing->msg) + { + if(datReqRing->event == EVTRGUDDATREQ) + { + RgUiRguDDatReq(&rgDDatRbfuPst, datReqRing->spId, (RguDDatReqInfo *) datReqRing->msg); + } + else + { + // printf("CSHP:*** Received CDatReq in MAC Ring \n"); + RgUiRguCDatReq(&rgCDatRbfuPst, datReqRing->spId, (RguCDatReqInfo *) datReqRing->msg); + } + } + else + { + printf(" Buf Pinter is NULL RBUF Read(%ld) write (%ld) \n",SsRngInfoTbl[SS_RNG_BUF_DLRLC_TO_DLMAC_DAT_REQ].r_addr->read, + SsRngInfoTbl[SS_RNG_BUF_DLRLC_TO_DLMAC_DAT_REQ].r_addr->write); + /* Due to the cache issue we are verifying the mbuf pointer again and sending it to rlc if avilable*/ + if(datReqRing->msg) + { + if(datReqRing->event == EVTRGUDDATREQ) + RgUiRguDDatReq(&rgDDatRbfuPst, datReqRing->spId, (RguDDatReqInfo *) datReqRing->msg); + else + RgUiRguCDatReq(&rgCDatRbfuPst, datReqRing->spId, (RguCDatReqInfo *) datReqRing->msg); + }else + { + printf(" still Buf Pinter is NULL RBUF Read(%ld) write (%ld) \n",SsRngInfoTbl[SS_RNG_BUF_DLRLC_TO_DLMAC_DAT_REQ].r_addr->read, + SsRngInfoTbl[SS_RNG_BUF_DLRLC_TO_DLMAC_DAT_REQ].r_addr->write); + } + } + datReqRing->msg=NULLP; + SRngIncrRIndx(SS_RNG_BUF_DLRLC_TO_DLMAC_DAT_REQ); + datReqRing->event=0; + elmIndx = NULLP; + datReqRing= NULLP; + rngBufDeqIndx++; + + if(rngBufDeqIndx >= SS_RNG_MAX_DLRLC_TO_DLMAC_DAT_REQ_DQ_CNT) + break; + + if((elmIndx = SRngGetRIndx(SS_RNG_BUF_DLRLC_TO_DLMAC_DAT_REQ)) == NULLP) + break; + } + + RETVALUE(ROK); +} +#endif + +#ifdef RLC_MAC_STA_RSP_RBUF +#ifdef ANSI +PUBLIC S16 rgDlStaRspBatchProc +( +Void +) +#else +PUBLIC S16 rgDlStaRspBatchProc() +Void; +#endif +{ +/* Read from Ring Buffer and process PDCP packets */ + + U8 rngBufDeqIndx = 0; + PRIVATE Pst rgDStaRbfuPst ={1,1,ENTRG,0,ENTKW,1,PRIOR0,RTESPEC,EVTRGUDSTARSP,0,0,2,0}; + PRIVATE Pst rgCStaRbfuPst ={1,1,ENTRG,0,ENTKW,1,PRIOR0,RTESPEC,EVTRGUCSTARSP,0,0,2,0}; + Void *elmIndx = NULLP; + RguInfoRingElem *staRspRing=NULLP; + + elmIndx = SRngGetRIndx(SS_RNG_BUF_DLRLC_TO_DLMAC); + while(NULLP != elmIndx) + { + staRspRing= (RguInfoRingElem *)elmIndx; + SsRngInfoTbl[SS_RNG_BUF_DLRLC_TO_DLMAC].nPktProc++;;//Number of pkt processed in tti + + if(staRspRing->msg!= NULLP) + { + if( staRspRing->event == EVTRGUDSTARSP) + { + RgUiRguDStaRsp(&rgDStaRbfuPst, staRspRing->spId, (RguDStaRspInfo *) staRspRing->msg); + } + else + { + RgUiRguCStaRsp(&rgCStaRbfuPst, staRspRing->spId, (RguCStaRspInfo *) staRspRing->msg); + } + } + else + { + printf(" Buf Pinter is NULL RBUF Read(%ld) write (%ld) \n",SsRngInfoTbl[SS_RNG_BUF_DLRLC_TO_DLMAC].r_addr->read, + SsRngInfoTbl[SS_RNG_BUF_DLRLC_TO_DLMAC].r_addr->write); + /* Due to the cache issue we are verifying the mbuf pointer again and sending it to rlc if avilable*/ + if(staRspRing->msg!= NULLP) + { + if( staRspRing->event == EVTRGUDSTARSP) + RgUiRguDStaRsp(&rgDStaRbfuPst, staRspRing->spId, (RguDStaRspInfo *) staRspRing->msg); + else + RgUiRguCStaRsp(&rgCStaRbfuPst, staRspRing->spId, (RguCStaRspInfo *) staRspRing->msg); + }else + { + printf(" still Buf Pinter is NULL RBUF Read(%ld) write (%ld) \n",SsRngInfoTbl[SS_RNG_BUF_DLRLC_TO_DLMAC].r_addr->read, + SsRngInfoTbl[SS_RNG_BUF_DLRLC_TO_DLMAC].r_addr->write); + } + } + staRspRing->msg=NULLP; + SRngIncrRIndx(SS_RNG_BUF_DLRLC_TO_DLMAC); + staRspRing->event =0; + elmIndx = NULLP; + staRspRing= NULLP; + + rngBufDeqIndx++; + + if(rngBufDeqIndx >= SS_RNG_MAX_DLRLC_TO_DLMAC_STA_RSP_DQ_CNT) + break; + + if((elmIndx = SRngGetRIndx(SS_RNG_BUF_DLRLC_TO_DLMAC)) == NULLP) + break; + } + + RETVALUE(ROK); +} +#endif +#ifdef LTE_L2_MEAS +#ifdef MAC_RLC_HARQ_STA_RBUF +#ifdef ANSI +PUBLIC S16 RgUiRguHqStaIndRbuf +( +Pst* pst, +SuId suId, +RguHarqStatusInd *harqStatusInd +) +#else +PUBLIC S16 RgUiRguHqStaIndRbuf(pst, suId, harqStatusInd) +Pst* pst; +SuId suId; +RguHarqStatusInd *harqStatusInd; +#endif +{ + S16 ret = ROK; + Void *elem = NULLP; + RguHarqStaInd *harqStaInd = NULLP; + elem = SRngGetWIndx(SS_RNG_BUF_MAC_HARQ); + harqStaInd = (RguHarqStaInd*) elem; + if (NULLP == elem ) + { + SsRngInfoTbl[SS_RNG_BUF_MAC_HARQ].pktDrop++; + ret = RFAILED; + } + else + { + cmMemcpy((U8 *)&(harqStaInd->hqStatusInd), (U8 *)harqStatusInd, sizeof(RguHarqStatusInd)); + cmMemcpy((U8 *)&(harqStaInd->pst), (U8 *)pst, sizeof(Pst)); + SRngIncrWIndx(SS_RNG_BUF_MAC_HARQ); + SsRngInfoTbl[SS_RNG_BUF_MAC_HARQ].pktRate++; + } + RETVALUE(ret); +} +#endif +#endif + + +/********************************************************************** + + End of file +**********************************************************************/ diff --git a/src/5gnrmac/rg_ram.c b/src/5gnrmac/rg_ram.c new file mode 100755 index 000000000..7ed0d98bf --- /dev/null +++ b/src/5gnrmac/rg_ram.c @@ -0,0 +1,343 @@ +/******************************************************************************* +################################################################################ +# Copyright (c) [2017-2019] [Radisys] # +# # +# 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. # +################################################################################ +*******************************************************************************/ + +/************************************************************************ + + Name: LTE-MAC layer + + Type: C source file + + Desc: C source code for Entry point fucntions + + File: rg_ram.c + +**********************************************************************/ + +/** @file rg_ram.c +@brief This file has APIs to handle the random access procedure functionality. +*/ + +static const char* RLOG_MODULE_NAME="MAC"; +static int RLOG_FILE_ID=132; +static int RLOG_MODULE_ID=4096; + +/* header include files (.h) */ +#include "envopt.h" /* environment options */ +#include "envdep.h" /* environment dependent */ +#include "envind.h" /* environment independent */ + +#include "gen.h" /* general */ +#include "ssi.h" /* system services */ + +#include "cm_tkns.h" /* Common Token Defines */ +#include "cm_llist.h" /* Common Link List Defines */ +#include "cm_hash.h" /* Common Hash List Defines */ +#include "cm_mblk.h" /* common memory link list library */ +#include "cm_lte.h" /* Common LTE */ + +#include "rg_env.h" /* MAC Environment Defines */ +#include "crg.h" /* CRG Interface defines */ +#include "rgu.h" /* RGU Interface defines */ +#include "tfu.h" /* TFU Interface defines */ +#include "rg_sch_inf.h" /* RGR Interface defines */ +#include "lrg.h" /* LRG Interface defines */ + +#include "rg.h" /* MAC defines */ +#include "rg_err.h" /* MAC error defines */ + +/* header/extern include files (.x) */ +#include "gen.x" /* general */ +#include "ssi.x" /* system services */ +#include "cm5.x" /* Timer */ +#include "cm_tkns.x" /* Common Token Definitions */ +#include "cm_llist.x" /* Common Link List Definitions */ +#include "cm_lib.x" /* Common Library Definitions */ +#include "cm_hash.x" /* Common Hash List Definitions */ +#include "cm_mblk.x" /* common memory link list library */ +#include "cm_lte.x" /* Common LTE */ + +#include "crg.x" /* CRG Interface includes */ +#include "rgu.x" /* RGU Interface includes */ +#include "tfu.x" /* TFU Interface includes */ +#include "rg_sch_inf.x" /* SCH Interface includes */ +#include "rg_prg.x" /* PRG Interface includes */ +#include "lrg.x" /* LRG Interface includes */ + +#include "rg.x" /* MAC includes */ + +/* local defines */ + +/* local typedefs */ + +/* forward references */ + +/*********************************************************** + * + * Func : rgRAMFreeUeCb + * + * + * Desc : + * - Processing Steps: + * - Frees UE control block. + * + * Ret : Void + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PUBLIC Void rgRAMFreeUeCb +( +Inst inst, +RgUeCb *ue +) +#else +PUBLIC Void rgRAMFreeUeCb(inst,ue) +Inst inst; +RgUeCb *ue; +#endif +{ + TRC2(rgRAMFreeUeCb); + + rgDHMFreeUe(inst,&ue->dl.hqEnt); + + /*ccpu00117052 - MOD - Passing double pointer for proper NULLP + assignment */ + /* De-allocate the Ue */ + rgFreeSBuf(inst,(Data **)&ue, sizeof(*ue)); + + /* Stack Crash problem for TRACE5 changes. Added the return below */ + RETVOID; + +} /* rgRAMFreeUeCb */ + +/** + * @brief Handler for Random Access control block creation. + * + * @details + * + * Function : rgRAMCreateUeCb + * Creates a raCb and gives the same to scheduler for its updation. + * + * + * @param[in] RgCellCb *cell + * @param[in] CmLteRnti tmpCrnti + * @param[out] RgErrInfo *err + * @return RgUeCb* + **/ +#ifdef ANSI +PUBLIC RgUeCb* rgRAMCreateUeCb +( +RgCellCb *cell, +CmLteRnti tmpCrnti, +Bool insert, +RgErrInfo *err +) +#else +PUBLIC RgUeCb* rgRAMCreateUeCb(cell, tmpCrnti, insert, err) +RgCellCb *cell; +CmLteRnti tmpCrnti; +Bool insert; +RgErrInfo *err; +#endif +{ + Inst inst = cell->macInst - RG_INST_START; + RgUeCb *ueCb = NULLP; + + TRC2(rgRAMCreateUeCb) + + RLOG_ARG1(L_INFO,DBG_CELLID,cell->cellId,"CREATE UECB FOR CRNTI:%d", + tmpCrnti); + /* Allocate the Ue control block */ + if (rgAllocSBuf(inst,(Data **)&ueCb, sizeof(*ueCb)) != ROK) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId, + "Memory allocation FAILED for CRNTI:%d",tmpCrnti); + err->errCause = RGERR_RAM_MEM_EXHAUST; + RETVALUE(NULLP); + } + + /* Inititialize Ue control block */ + ueCb->ueId = tmpCrnti; + + /* Initialize the lists of the UE */ + rgDBMInitUe(ueCb); + + if(insert == TRUE) + { + /* MS_FIX : Remove stale UEs if present */ + RgUeCb *staleUe = NULLP; + /* Insert the created raCb into raCb list of cell */ + ueCb->rachLstEnt.next = NULLP; + ueCb->rachLstEnt.prev = NULLP; + ueCb->rachLstEnt.node = (PTR)(ueCb); + /* MS_FIX : Remove stale UEs if present */ + staleUe = rgDBMGetUeCbFromRachLst (cell, tmpCrnti); + if (staleUe) + { + rgDBMDelUeCbFromRachLst(cell, staleUe); + rgRAMFreeUeCb(inst,staleUe); + } + rgDBMInsUeCbInRachLst(cell, ueCb); + } + + RETVALUE(ueCb); +} /* rgRAMCreateUeCb */ + +/** + * @brief Function for handling cell delete. + * + * @details + * + * Function : rgRAMFreeCell + * + * This function shall be invoked whenever a cell needs to be deleted. + * This shall remove raCbs and raReqs stored in cell. + * + * + * @param[in,out] RgCellCb *cell + * @return S16 + * -# ROK + **/ +#ifdef ANSI +PUBLIC S16 rgRAMFreeCell +( +RgCellCb *cell +) +#else +PUBLIC S16 rgRAMFreeCell(cell) +RgCellCb *cell; +#endif +{ + Inst inst = cell->macInst - RG_INST_START; + RgUeCb *ueCb; + + TRC2(rgRAMFreeCell); + + /* Free CURRENT CRG cfg list */ + while ((ueCb = rgDBMGetNextUeCbFromRachLst(cell, NULLP)) != NULLP) + { + rgDBMDelUeCbFromRachLst(cell, ueCb); + rgRAMFreeUeCb(inst,ueCb); + } + + RETVALUE(ROK); +} /* rgRAMFreeCell */ +/** + * @brief Function for handling RA response scheduled for a subframe. + * + * @details + * + * Function : rgHndlRaResp + * + * This function shall be invoked whenever scheduler is done with the + * allocations of random access responses for a subframe RgSchMacSfAllocReq. + * + * Processing steps : + * + * This shall invoke RAM to create ueCbs for all the rapIds allocated and + * shall invoke MUX to create RAR PDUs for raRntis allocated. + * + * + * @param[in] RgCellCb *cell, + * @param[in] CmLteTimingInfo timingInfo, + * @param[in] RgInfRarInfo *rarInfo + * @param[in/out] RgErrInfo *err + * @return S16 + * -# ROK + **/ +#ifdef ANSI +PUBLIC S16 rgHndlRaResp +( +RgCellCb *cell, +CmLteTimingInfo timingInfo, +RgInfRarInfo *rarInfo, +RgErrInfo *err +) +#else +PUBLIC S16 rgHndlRaResp(cell, timingInfo, rarInfo, err) +RgCellCb *cell; +CmLteTimingInfo timingInfo; +RgInfRarInfo *rarInfo; +RgErrInfo *err; +#endif +{ + U8 idx1,idx2; + Buffer *rarPdu; + RgDlSf *dlSf; + U8 idx; + + TRC2(rgHndlRaResp) + + if(NULLP == rarInfo->raRntiInfo) + { + RETVALUE(RFAILED); + } + + idx = (timingInfo.subframe % RG_NUM_SUB_FRAMES); + dlSf = &cell->subFrms[idx]; + + /* Create RAR PDUs for all the allocated RA-RNTIs */ + for(idx1 = 0; idx1 < rarInfo->numRaRntis; idx1++) + { + if(ROK == (rgMUXBldRarPdu(cell, + &rarInfo->raRntiInfo[idx1], &rarPdu, err))) + { + /* Create RaCbs for all the rapIds allocated */ + for(idx2 = 0; idx2 < rarInfo->raRntiInfo[idx1].numCrnti; idx2++) + { + if(FALSE == rarInfo->raRntiInfo[idx1].crntiInfo[idx2].isContFree) + { + if(rgRAMCreateUeCb(cell, + rarInfo->raRntiInfo[idx1].crntiInfo[idx2].tmpCrnti, + TRUE, err) == NULLP) + { + RETVALUE(RFAILED); + } + } + } + /* Store the created RAR PDU */ + dlSf->raRsp[dlSf->numRaRsp].pdcch.rnti = + rarInfo->raRntiInfo[idx1].raRnti; + + dlSf->raRsp[dlSf->numRaRsp].pdcch.dci = + rarInfo->raRntiInfo[idx1].dciInfo; + + dlSf->raRsp[dlSf->numRaRsp].rar = rarPdu; + /* ccpu00132314-ADD-Adding txPower offset for the PDSCH transmission */ + dlSf->raRsp[dlSf->numRaRsp].txPwrOffset = + rarInfo->txPwrOffset; + + dlSf->numRaRsp++; + } + else + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,"RARNTI:%d Creation of RAR" + "PDU for failed", rarInfo->raRntiInfo[idx1].raRnti); + continue; + } + } /* end of raRntis loop */ + RETVALUE(ROK); +} /* end of rgHndlRaResp */ + +/********************************************************************** + + End of file +**********************************************************************/ diff --git a/src/5gnrmac/rg_rom.c b/src/5gnrmac/rg_rom.c new file mode 100755 index 000000000..30c0efa9f --- /dev/null +++ b/src/5gnrmac/rg_rom.c @@ -0,0 +1,1068 @@ +/******************************************************************************* +################################################################################ +# Copyright (c) [2017-2019] [Radisys] # +# # +# 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. # +################################################################################ +*******************************************************************************/ + +/************************************************************************ + + Name: LTE-MAC layer + + Type: C source file + + Desc: C source code for Entry point fucntions. + + File: rg_rom.c + +**********************************************************************/ + +/** @file rg_rom.c +@brief APIs to handle all the primitives invoked on RGU interface. +*/ + +static const char* RLOG_MODULE_NAME="MAC"; +static int RLOG_FILE_ID=184; +static int RLOG_MODULE_ID=4096; + +/* header include files (.h) */ +#include "envopt.h" /* environment options */ +#include "envdep.h" /* environment dependent */ +#include "envind.h" /* environment independent */ + +#include "gen.h" /* general */ +#include "ssi.h" /* system services */ + +#include "cm_tkns.h" /* Common Token Defines */ +#include "cm_llist.h" /* Common Link List Defines */ +#include "cm_hash.h" /* Common Hash List Defines */ +#include "cm_mblk.h" /* common memory link list library */ +#include "cm_lte.h" /* Common LTE */ + +#include "rg_env.h" /* MAC Environment Defines */ +#include "crg.h" /* CRG Interface defines */ +#include "rgu.h" /* RGU Interface defines */ +#include "tfu.h" /* TFU Interface defines */ +#include "rg_sch_inf.h" /* RGR Interface defines */ +#include "lrg.h" /* LRG Interface defines */ + +#include "rg.h" /* MAC defines */ +#include "rg_err.h" /* MAC error defines */ + +/* header/extern include files (.x) */ +#include "gen.x" /* general */ +#include "ssi.x" /* system services */ +#include "cm5.x" /* Timer */ +#include "cm_tkns.x" /* Common Token Definitions */ +#include "cm_llist.x" /* Common Link List Definitions */ +#include "cm_lib.x" /* Common Library Definitions */ +#include "cm_hash.x" /* Common Hash List Definitions */ +#include "cm_mblk.x" /* common memory link list library */ +#include "cm_lte.x" /* Common LTE */ + +#include "crg.x" /* CRG Interface includes */ +#include "rgu.x" /* RGU Interface includes */ +#include "tfu.x" /* TFU Interface includes */ +#include "rg_sch_inf.x" /* SCH Interface includes */ +#include "rg_prg.x" /* PRG Interface includes */ +#include "lrg.x" /* LRG Interface includes */ + +#include "rg.x" /* MAC includes */ + +/* local defines */ +#define RG_NON_MIMO_IDX 0 + +/* local typedefs */ + +S16 RgMacSchBrdcmDedBoUpdtReq ARGS((Inst inst, CmLteCellId cellId, CmLteRnti rnti, CmLteLcId lcId, S32 bo )); +PRIVATE S16 rgROMHndlCcchDatReq ARGS((RgCellCb *cell, + RgRguCmnDatReq *datReq, RgErrInfo *err)); +PRIVATE S16 rgROMHndlBcchPcchDatReq ARGS((RgCellCb *cell, + RgRguCmnDatReq *datReq, RgErrInfo *err)); +PRIVATE S16 rgROMHndlCcchStaRsp ARGS((RgCellCb *cell, + RgRguCmnStaRsp *staRsp, RgErrInfo *err)); +PRIVATE S16 rgROMHndlBcchPcchStaRsp ARGS((RgCellCb *cell, + RgRguCmnStaRsp *staRsp, RgErrInfo *err)); + +/* ADD Changes for Downlink UE Timing Optimization */ +#ifdef LTEMAC_DLUE_TMGOPTMZ +PRIVATE S16 rgROMUpdDlSfRemDataCnt ARGS((RgCellCb *cellCb, + RgDlSf *dlSf)); +PUBLIC S16 rgTOMUtlProcDlSf ARGS(( RgDlSf *dlSf, + RgCellCb *cellCb, + RgErrInfo *err)); +#endif + +/* forward references */ + +/** + * @brief Handler for dedicated DatReq received on RGU for an UE. + * + * @details + * + * Function : rgROMDedDatReq + * + * This function shall + * -# store the BO reported for the given logical channels. + * -# invoke DL HARQ for further processing. + * + * + * @param[in] Inst inst + * @param[in] RgRguDedDatReq *datReq + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 rgROMDedDatReq +( +Inst inst, +RgRguDedDatReq *datReq +) +#else +PUBLIC S16 rgROMDedDatReq(inst,datReq) +Inst inst; +RgRguDedDatReq *datReq; +#endif +{ + RgCellCb *cell; + RgUeCb *ue; + U8 idx1,idx2; + RgDlHqProcCb *hqProc; + U8 hqPId; + RgErrInfo err; + Pst schPst; + RgInfDedBoRpt boRpt; + CmLteTimingInfo timingInfo; + RgDlSf *sf; +#if (ERRCLASS & ERRCLS_DEBUG) + RgUstaDgn dgn; /* Alarm diagnostics structure */ +#endif +/* ADD Changes for Downlink UE Timing Optimization */ +#ifdef LTEMAC_DLUE_TMGOPTMZ + S16 ret; +#endif + U32 idx; + //U8 datReqFailCnt = 0; + + TRC2(rgROMDedDatReq) + + + if (((cell = rgCb[inst].cell) == NULLP) + || (cell->cellId != datReq->cellId)) + { +#if (ERRCLASS & ERRCLS_INT_PAR) + /* Handle Cell fetch failure */ + RGLOGERROR(inst,ERRCLS_INT_PAR,ERG001,(ErrVal)datReq->cellId, + "rgROMDedDatReq(): Invalid cell Id"); +#endif + err.errType = RGERR_ROM_DEDDATREQ; + err.errCause = RGERR_ROM_INV_CELL_ID; + if(cell != NULLP) + { + /* Update stats */ + rgUpdtRguDedSts(inst,cell->rguDlSap,RG_RGU_SDU_DROP, datReq); + } + RETVALUE(RFAILED); + } + +/* Add loop here to scan for all UEs in the consolidated DDatReq*/ + for(idx = 0; idx < datReq->nmbOfUeGrantPerTti; idx++) + { + + timingInfo.subframe = (U8)((datReq->datReq[idx].transId >> 8) & 0XFF); + timingInfo.sfn = (U16)((datReq->datReq[idx].transId >> 16) & 0xFFFF); + sf = &cell->subFrms[(timingInfo.subframe % RG_NUM_SUB_FRAMES)]; + + if( (sf->txDone == TRUE) || + (!RG_TIMEINFO_SAME(sf->schdTime,timingInfo))) + { +#if (ERRCLASS & ERRCLS_DEBUG) + /* Transmission is already done for this subframe. This is a delayed + * datReq. So discard */ + rgFillDgnParams(inst,&dgn, LRG_USTA_DGNVAL_MEM); + rgLMMStaInd(inst,LCM_CATEGORY_PROTOCOL, LCM_EVENT_UI_INV_EVT, + LRG_CAUSE_DELAYED_DATREQ, &dgn); +#endif + err.errType = RGERR_ROM_DEDDATREQ; + err.errCause = RGERR_ROM_DELAYED_DATREQ; + /* Update stats */ + rgUpdtRguDedSts(inst,cell->rguDlSap,RG_RGU_SDU_DROP, datReq); +#ifdef CA_DBG + { + EXTERN U32 dbgDelayedDatReqInMac; + dbgDelayedDatReqInMac++; + } +#endif /* CA_DBG */ +#ifndef L2_OPTMZ + RG_DROP_RGUDDATREQ_MBUF(datReq->datReq[idx]); +#endif + continue; + // RETVALUE(RFAILED); + } + + if ((ue = rgDBMGetUeCb(cell, datReq->datReq[idx].rnti)) == NULLP) + { +#if (ERRCLASS & ERRCLS_INT_PAR) + /* Handle Ue fetch failure */ + RGLOGERROR(inst,ERRCLS_INT_PAR,ERG002,(ErrVal)datReq->datReq[idx].rnti, + "rgROMDedDatReq(): Invalid ue Id"); +#endif + err.errType = RGERR_ROM_DEDDATREQ; + err.errCause = RGERR_ROM_INV_UE_ID; + /* Update stats */ + rgUpdtRguDedSts(inst,cell->rguDlSap,RG_RGU_SDU_DROP, datReq); + /* ADD Changes for Downlink UE Timing Optimization */ +#ifdef LTEMAC_DLUE_TMGOPTMZ + /* Trying to send the prev successful PDU's + * if present */ + ret = rgROMUpdDlSfRemDataCnt(cell, sf); + if(ret == RFAILED) + { + RLOG0(L_INFO, "Dropping due to no ue \n"); +#ifndef L2_OPTMZ + RG_DROP_RGUDDATREQ_MBUF(datReq->datReq[idx]); +#endif + /* Return from here as above functions found more datReq than expected*/ + /* RETVALUE(ret); */ + } +#endif + /* Conitnue for next UE */ + continue; + } + + hqPId = (U8)(datReq->datReq[idx].transId); + hqPId = hqPId >> 2; + /* get harq process and invoke DHM */ + rgDHMGetHqProcFrmId(ue, hqPId, &hqProc); + + if (rgDHMHndlDedDatReq(inst,hqProc, &datReq->datReq[idx], sf, &err) == RFAILED) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,datReq->cellId, + "Handling of Data request in DHM failedi RNTI:%d", + datReq->datReq[idx].rnti); + err.errType = RGERR_ROM_DEDDATREQ; + /* errcause shall be filled in appropriately by DHM */ + /* Update stats */ + rgUpdtRguDedSts(inst,ue->rguDlSap,RG_RGU_SDU_DROP, datReq); + /* ADD Changes for Downlink UE Timing Optimization */ +#ifdef LTEMAC_DLUE_TMGOPTMZ + /* Trying to send the prev successful PDU's + * if present */ + ret = rgROMUpdDlSfRemDataCnt(cell, sf); + if(ret == RFAILED) + { + RLOG0(L_INFO, "Dropping due to no failure of remCnt update"); +#ifndef L2_OPTMZ + RG_DROP_RGUDDATREQ_MBUF(datReq->datReq[idx]); +#endif + /* Return from here as above functions found more datReq than expected*/ + //RETVALUE(ret); + } +#endif + continue; + } + + /* Merging the updation of statistics of SDUs with for loop below */ + + rgGetPstToInst(&schPst,inst, cell->schInstMap.schInst); + schPst.event = 0; + boRpt.cellSapId = cell->schInstMap.cellSapId; + boRpt.cellId = datReq->cellId; + + boRpt.rnti = datReq->datReq[idx].rnti; + + + /* Fill the DStaRsp struct and send it to scheduler */ + for (idx1 = 0; idx1 < datReq->datReq[idx].nmbOfTbs; idx1++) + { + for(idx2 = 0; idx2 < datReq->datReq[idx].datReqTb[idx1].nmbLch; idx2++) + { + /* Updating dedicated SDUs received statistics without + additional function above for optimization */ + ue->rguDlSap->sapSts.numPduRcvd += + datReq->datReq[idx].datReqTb[idx1].lchData[idx2].pdu.numPdu; + + boRpt.lcId = datReq->datReq[idx].datReqTb[idx1].lchData[idx2].lcId; + boRpt.bo = datReq->datReq[idx].datReqTb[idx1].lchData[idx2].boReport.bo; + boRpt.oldestSduArrTime + = datReq->datReq[idx].datReqTb[idx1].lchData[idx2].boReport.oldestSduArrTime; + boRpt.staPduBo = datReq->datReq[idx].datReqTb[idx1].lchData[idx2].boReport.staPduBo; + + boRpt.setMaxUlPrio= datReq->datReq[idx].datReqTb[idx1].lchData[idx2].setMaxUlPrio; +#ifdef CCPU_OPT + boRpt.setMaxDlPrio= datReq->datReq[idx].datReqTb[idx1].lchData[idx2].boReport.staPduPrsnt; +#endif + RgMacSchDedBoUpdt(&schPst, &boRpt); + } + } + + /* ADD Changes for Downlink UE Timing Optimization */ +#ifdef LTEMAC_DLUE_TMGOPTMZ +// sf->remDatReqCnt -= datReqFailCnt; + /*Presently this function is not returning RFAILED, thus not checking + for failure condition.*/ + ret = rgROMUpdDlSfRemDataCnt(cell, sf); + if(ret == RFAILED) + { + RLOG0(L_INFO, "\n Dropping due to no failure of remCnt update(1) \n"); +#ifndef L2_OPTMZ + RG_DROP_RGUDDATREQ_MBUF(datReq->datReq[idx]); +#endif + /* Return from here as above functions found more datReq than expected*/ + // RETVALUE(ret); + } +#endif + } /* for loop for num of Ue per TTI*/ + + /* Data send successfully to PHY. lets retuns ROK*/ + RETVALUE(ROK); +} /* rgROMDedDatReq */ + + +/** + * @brief Handler for DatReq received on RGU for a common logical channel. + * + * @details + * + * Function : rgROMCmnDatReq + * + * This function shall invoke rgROMHndlCcchDatReq() if datReq is on CCCH + * If not, it shall invoke rgROMHndlBcchPcchDatReq(). + * + * + * @param[in] Inst inst + * @param[in] RgRguCmnDatReq *datReq + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 rgROMCmnDatReq +( +Inst inst, +RgRguCmnDatReq *datReq +) +#else +PUBLIC S16 rgROMCmnDatReq(inst,datReq) +Inst inst; +RgRguCmnDatReq *datReq; +#endif +{ + RgCellCb *cell; + RgErrInfo err; + S16 ret; +/* ADD Changes for Downlink UE Timing Optimization */ +#ifdef LTEMAC_DLUE_TMGOPTMZ + CmLteTimingInfo timingInfo; + RgDlSf *sf; +#endif + + TRC2(rgROMCmnDatReq) + + ret = ROK; + err.errType = RGERR_ROM_CMNDATREQ; + if(((cell = rgCb[inst].cell) == NULLP) + ||(cell->cellId != datReq->cellId)) + { +#if (ERRCLASS & ERRCLS_INT_PAR) + /* Handle Cell fetch failure */ + RGLOGERROR(inst,ERRCLS_INT_PAR,ERG003,(ErrVal)datReq->cellId, + "rgROMCmnDatReq(): Invalid cell Id"); +#endif + err.errCause = RGERR_ROM_INV_CELL_ID; + /* Update stats */ + if(cell != NULLP) + { + rgUpdtRguCmnSts(inst,cell->rguDlSap,RG_RGU_SDU_DROP); + } + RETVALUE(RFAILED); + } + + if (datReq->lcId == cell->dlCcchId) + { + ret = rgROMHndlCcchDatReq(cell, datReq, &err); + + /*Get the timing Info*/ + /* ADD Changes for Downlink UE Timing Optimization */ +#ifdef LTEMAC_DLUE_TMGOPTMZ + timingInfo.subframe = (U8)((datReq->transId >> 8) & 0XFF); + timingInfo.sfn = (U16)((datReq->transId >> 16) & 0xFFFF); +#endif + } + else + { + ret = rgROMHndlBcchPcchDatReq(cell, datReq, &err); + + /*Get the timing Info*/ + /* ADD Changes for Downlink UE Timing Optimization */ +#ifdef LTEMAC_DLUE_TMGOPTMZ + timingInfo.subframe = (U8)(datReq->transId & 0XFF); + timingInfo.sfn = (U16)((datReq->transId >> 8) & 0xFFFF); +#endif + } + + /* Update stats */ + if (ret == RFAILED) + { + rgUpdtRguCmnSts(inst,cell->rguDlSap,RG_RGU_SDU_DROP); + } + else + { + /* Update stats with number of SDUs received */ + rgUpdtRguCmnSts(inst,cell->rguDlSap,RG_RGU_SDU_RCVD); + } + + /* ADD Changes for Downlink UE Timing Optimization */ +#ifdef LTEMAC_DLUE_TMGOPTMZ + RG_ARRAY_BOUND_CHECK(0, cell->subFrms, (timingInfo.subframe % RG_NUM_SUB_FRAMES)); + sf = &cell->subFrms[(timingInfo.subframe % RG_NUM_SUB_FRAMES)]; + + ret = rgROMUpdDlSfRemDataCnt(cell, sf); + /*Added check for RFAILED as above function can return RFAILED*/ +#endif + + RETVALUE(ret); +} /* rgROMCmnDatReq */ + +/** + * @brief Handler for DatReq received on RGU for CCCH. + * + * @details + * + * Function : rgROMHndlCcchDatReq + * + * This function shall fetch the raCb with the given rnti and indicate msg4 + * arrival to RAM. + * + * + * @param[in] RgCellCb *cell + * @param[in] RgRguCmnDatReq *datReq + * @param[out] RgErrInfo *err + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PRIVATE S16 rgROMHndlCcchDatReq +( +RgCellCb *cell, +RgRguCmnDatReq *datReq, +RgErrInfo *err +) +#else +PRIVATE S16 rgROMHndlCcchDatReq(cell, datReq, err) +RgCellCb *cell; +RgRguCmnDatReq *datReq; +RgErrInfo *err; +#endif +{ + Inst inst = cell->macInst - RG_INST_START; + RgUeCb *ue; + U8 hqPId; + RgDlHqProcCb *hqProc; + CmLteTimingInfo timingInfo; + RgDlSf *sf; +#if (ERRCLASS & ERRCLS_DEBUG) + RgUstaDgn dgn; /* Alarm diagnostics structure */ +#endif + + TRC2(rgROMHndlCcchDatReq); + + + err->errType = RGERR_ROM_CMNDATREQ; + + if ((ue = rgDBMGetUeCb(cell, datReq->u.rnti)) == NULLP) + { + if ((ue = rgDBMGetUeCbFromRachLst(cell, datReq->u.rnti)) == NULLP) + { + #if (ERRCLASS & ERRCLS_INT_PAR) + /* Handle Ue fetch failure */ + RGLOGERROR(inst,ERRCLS_INT_PAR,ERG004,(ErrVal)datReq->u.rnti, + "rgROMHndlCcchDatReq(): Invalid ue Id"); + #endif + err->errCause = RGERR_ROM_INV_UE_ID; + RETVALUE(RFAILED); + } + } + + timingInfo.subframe = (U8)((datReq->transId >> 8) & 0XFF); + timingInfo.sfn = (U16)((datReq->transId >> 16) & 0xFFFF); + sf = &cell->subFrms[(timingInfo.subframe % RG_NUM_SUB_FRAMES)]; + + if( (sf->txDone == TRUE) || + (!RG_TIMEINFO_SAME(sf->schdTime,timingInfo))) + { +#if (ERRCLASS & ERRCLS_DEBUG) + /* Transmission is already done for this subframe. This is a delayed + * datReq. So discard */ + rgFillDgnParams(inst,&dgn, LRG_USTA_DGNVAL_MEM); + rgLMMStaInd(inst,LCM_CATEGORY_PROTOCOL, LCM_EVENT_UI_INV_EVT, + LRG_CAUSE_DELAYED_DATREQ, &dgn); +#endif + err->errCause = RGERR_ROM_DELAYED_DATREQ; + RETVALUE(RFAILED); + } + + hqPId = (U8)(datReq->transId); + hqPId = hqPId >> 2; + + /* get harq process and invoke DHM */ + rgDHMGetHqProcFrmId(ue, hqPId, &hqProc); + + /* Changed for CR timer implementation*/ + /* invoke DHM to process CCCH data */ + if (rgDHMHndlCmnDatReq(inst,hqProc, datReq, err) == RFAILED) + { + RLOG_ARG2(L_ERROR,DBG_CELLID,cell->cellId, + "Handling of Data request in DHM failed RNTI:%d LCID:%d", + datReq->u.rnti,datReq->lcId); + /* Release First TB */ + rgDHMRlsHqProcTB(cell, hqProc, 1); + /* err shall be filled in appropriately by DHM */ + RETVALUE(RFAILED); + } + + RETVALUE(ROK); +} /* rgROMHndlCcchDatReq */ + + +/** + * @brief Handler for DatReq received on RGU for BCCH or PCCH. + * + * @details + * + * Function : rgROMHndlBcchPcchDatReq + * + * This function shall store the buffer and time to transmit in lcCb. + * + * + * @param[in] RgCellCb *cell + * @param[in] RgRguCmnDatReq *datReq + * @param[out] RgErrInfo *err + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PRIVATE S16 rgROMHndlBcchPcchDatReq +( +RgCellCb *cell, +RgRguCmnDatReq *datReq, +RgErrInfo *err +) +#else +PRIVATE S16 rgROMHndlBcchPcchDatReq(cell, datReq, err) +RgCellCb *cell; +RgRguCmnDatReq *datReq; +RgErrInfo *err; +#endif +{ + Inst inst = cell->macInst - RG_INST_START; + RgPcchLcCb *pcch; + /* Modified for SI Enhancement*/ +#ifndef RGR_SI_SCH + RgBcchBchLcCb *bch; + RgBcchDlschLcCb *bcch; +#endif/*RGR_SI_SCH*/ + RgDlSf *sf; + CmLteTimingInfo timingInfo; +#if (ERRCLASS & ERRCLS_DEBUG) + RgUstaDgn dgn; /* Alarm diagnostics structure */ +#endif + + TRC2(rgROMHndlBcchPcchDatReq); + + + timingInfo.subframe = (U8)(datReq->transId & 0XFF); + timingInfo.sfn = (U16)((datReq->transId >> 8) & 0xFFFF); + sf = &cell->subFrms[(timingInfo.subframe % RG_NUM_SUB_FRAMES)]; + + if( (sf->txDone == TRUE) || + (!RG_TIMEINFO_SAME(sf->schdTime,timingInfo))) + { +#if (ERRCLASS & ERRCLS_DEBUG) + /* Transmission is already done for this subframe. This is a delayed + * datReq. So discard */ + rgFillDgnParams(inst,&dgn, LRG_USTA_DGNVAL_MEM); + rgLMMStaInd(inst,LCM_CATEGORY_PROTOCOL, LCM_EVENT_UI_INV_EVT, + LRG_CAUSE_DELAYED_DATREQ, &dgn); +#endif + err->errCause = RGERR_ROM_DELAYED_DATREQ; + RETVALUE(RFAILED); + } + +#ifndef RGR_SI_SCH + bcch = rgDBMGetBcchOnDlsch(cell,datReq->lcId); + if (bcch ) + { + /* Store BCCH-DLSCH data received in Scheduled subframe */ + sf->bcch.tb = datReq->pdu; + + SCpyMsgMsg(datReq->pdu, RG_GET_MEM_REGION(rgCb[inst]), + RG_GET_MEM_POOL(rgCb[inst]), &bcch->tb); + + RETVALUE(ROK); + } + + bch = rgDBMGetBcchOnBch(cell); + if ((bch) && (bch->lcId == datReq->lcId)) + { + /* Store BCH data received in Scheduled subframe */ + sf->bch.tb = datReq->pdu; + RETVALUE(ROK); + } +#endif/*RGR_SI_SCH*/ + + pcch = rgDBMGetPcch(cell); + if ((pcch) && (pcch->lcId == datReq->lcId)) + { + /* Store PCCH-DLSCH data received in Scheduled subframe */ + sf->pcch.tb = datReq->pdu; + RETVALUE(ROK); + } + + /* Handle lcCb fetch failure */ + RGLOGERROR(inst,ERRCLS_INT_PAR,ERG005,(ErrVal)datReq->lcId, + "rgROMHndlBcchPcchDatReq(): Invalid Lc Id"); + err->errCause = RGERR_ROM_INV_LC_ID; + + RETVALUE(RFAILED); +} /* rgROMHndlBcchPcchDatReq */ + +/** + * @brief Handler for StaRsp received on RGU for a dedicated logical channel. + * + * @details + * + * Function : rgROMDedStaRsp + * + * This fucntion shall store the BO reported for the given logical + * channel. + * + * + * @param[in] Inst inst + * @param[in] RgRguDedStaRsp *staRsp + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 rgROMDedStaRsp +( +Inst inst, +RgRguDedStaRsp *staRsp +) +#else +PUBLIC S16 rgROMDedStaRsp(inst,staRsp) +Inst inst; +RgRguDedStaRsp *staRsp; +#endif +{ + RgCellCb *cell; + + /* Moving the error variables and assignments to available scope */ + + TRC2(rgROMDedStaRsp) + + /* Avoiding memset, as the variables of this are getting + initialized */ + + + if(((cell = rgCb[inst].cell) != NULLP) + && (cell->cellId == staRsp->cellId)) + { + RgInfDedBoRpt boRpt; + Pst schPst; + boRpt.cellSapId = cell->schInstMap.cellSapId; + boRpt.cellId = staRsp->cellId; + boRpt.rnti = staRsp->rnti; + boRpt.lcId = staRsp->lcId; + boRpt.bo = staRsp->boReport.bo; + boRpt.oldestSduArrTime = staRsp->boReport.oldestSduArrTime; + boRpt.staPduBo = staRsp->boReport.staPduBo; + boRpt.oldestSduArrTime = staRsp->boReport.oldestSduArrTime; + rgGetPstToInst(&schPst,inst, cell->schInstMap.schInst); + schPst.event = 0; + RgMacSchDedBoUpdt(&schPst, &boRpt); + RETVALUE(ROK); + } + RLOG_ARG2(L_ERROR,DBG_CELLID,staRsp->cellId,"Invalid cell for CRNTI:%d LCID:%d ", + staRsp->rnti,staRsp->lcId); + + RETVALUE(RFAILED); +} /* rgROMDedStaRsp */ + +S16 RgMacSchBrdcmDedBoUpdtReq( +Inst inst, +CmLteCellId cellId, +CmLteRnti rnti, +CmLteLcId lcId, +S32 bo +) +{ + RgInfDedBoRpt boRpt; + RgCellCb *cell; + //if ((cell = rgDBMGetCellCb(cellId)) != NULLP) + if (((cell = rgCb[inst].cell) != NULLP) && + (cell->cellId == cellId)) + { + Pst schPst; + boRpt.cellSapId = cell->schInstMap.cellSapId; + boRpt.cellId = cellId; + boRpt.rnti = rnti; + boRpt.lcId = lcId; + boRpt.bo = bo; + rgGetPstToInst(&schPst,inst, cell->schInstMap.schInst); + schPst.event = 0; + RgMacSchDedBoUpdtReq (&schPst,&boRpt); + } + RETVALUE(ROK); +} +/** + * @brief Handler for StaRsp received on RGU for a common logical channel. + * + * @details + * + * Function : rgROMCmnStaRsp + * + * This fucntion shall invoke rgROMHndlCcchStaRsp() for status response on + * CCCH and shall invoke rgROMHndlBcchPcchStaRsp() for status response on + * BCCH or PCCH. + * + * + * @param[in] Inst inst + * @param[in] RgRguCmnStaRsp *staRsp + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 rgROMCmnStaRsp +( +Inst inst, +RgRguCmnStaRsp *staRsp +) +#else +PUBLIC S16 rgROMCmnStaRsp(inst,staRsp) +Inst inst; +RgRguCmnStaRsp *staRsp; +#endif +{ + RgCellCb *cell; + RgErrInfo err; + + TRC2(rgROMCmnStaRsp) + + + if(((cell = rgCb[inst].cell) == NULLP) + || (cell->cellId != staRsp->cellId)) + { + /* Handle Cell fetch failure */ + RLOG_ARG2(L_ERROR,DBG_CELLID,staRsp->cellId, + "Invalid cell for CRNTI:%d LCID:%d",staRsp->u.rnti,staRsp->lcId); + err.errType = RGERR_ROM_CMNSTARSP; + err.errCause = RGERR_ROM_INV_CELL_ID; + RETVALUE(RFAILED); + } + + /* handle status response on CCCH */ + if(staRsp->lcId == cell->dlCcchId) + { + rgROMHndlCcchStaRsp(cell, staRsp, &err); + } + else + { + rgROMHndlBcchPcchStaRsp(cell, staRsp, &err); + } + + RETVALUE(ROK); +} /* rgROMCmnStaRsp */ + +#ifdef LTE_L2_MEAS + +/** + * @brief Handler for Request received on RGU for a UL Throughput measurement + * enabled logical channel. + * + * @details + * + * Function :rgROML2MUlThrpMeasReq + * + * This function shall store the L2M UL Throughput Measurement status information + * for the given logical channel. + * + * + * @param[in] Inst inst + * @param[in] RgRguL2MUlThrpMeasReq *measReq + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 rgROML2MUlThrpMeasReq +( +Inst inst, +RgRguL2MUlThrpMeasReq *measReq +) +#else +PUBLIC S16 rgROML2MUlThrpMeasReq(inst,measReq) +Inst inst; +RgRguL2MUlThrpMeasReq *measReq; +#endif +{ + RgCellCb *cell; + RgUeCb *ue; + U8 lcgId; + U8 loop; + TRC2(rgROML2MUlThrpMeasReq) + + + + if(((cell = rgCb[inst].cell) != NULLP) + &&(cell->cellId == measReq->cellId)) + { + if ((ue = rgDBMGetUeCb(cell, measReq->rnti)) != NULLP) + { + for(loop=0; loopnumLcId;loop++) + { + if ((rgDBMGetUlDedLcCb(ue, measReq->lcId[loop])) != NULLP) + { + ue->ul.lcCb[measReq->lcId[loop]].measOn = measReq->enbMeas; + if(ue->ul.lcCb[measReq->lcId[loop]].measOn == FALSE) + { + lcgId=ue->ul.lcCb[measReq->lcId[loop]].lcgId; + ue->ul.lcgArr[lcgId].lcgBsInfo.outStndngBs = 0; + ue->ul.lcgArr[lcgId].lcgBsInfo.firstDatSegRcvd = FALSE; + } + } + } + RETVALUE(ROK); + } + } + RLOG_ARG1(L_ERROR,DBG_CELLID,measReq->cellId,"Invalid cell CRNTI:%d", + measReq->rnti); + RETVALUE(RFAILED); +} /* rgROML2MUlThrpMeasReq */ + +#endif + +/** + * @brief Handler for StaRsp received on RGU for CCCH. + * + * @details + * + * Function : rgROMHndlCcchStaRsp + * + * This function shall fetch the raCb with the given RNTI and ask RAM to + * update BO. + * + * + * @param[in] RgCellCb *cell + * @param[in] RgRguCmnStaRsp *staRsp + * @param[out] RgErrInfo *err + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PRIVATE S16 rgROMHndlCcchStaRsp +( +RgCellCb *cell, +RgRguCmnStaRsp *staRsp, +RgErrInfo *err +) +#else +PRIVATE S16 rgROMHndlCcchStaRsp(cell, staRsp, err) +RgCellCb *cell; +RgRguCmnStaRsp *staRsp; +RgErrInfo *err; +#endif +{ + Pst schPst; + Inst macInst = cell->macInst - RG_INST_START; + RgInfCmnBoRpt boRpt; + + TRC2(rgROMHndlCcchStaRsp); + + + boRpt.cellSapId = cell->schInstMap.cellSapId; + boRpt.cellId = staRsp->cellId; + boRpt.u.rnti = staRsp->u.rnti; + boRpt.lcId = staRsp->lcId; + boRpt.lcType = staRsp->lcType; + boRpt.bo = staRsp->bo; + rgGetPstToInst(&schPst,macInst, cell->schInstMap.schInst); + RgMacSchCmnBoUpdt(&schPst, &boRpt); + + RETVALUE(ROK); +} /* rgROMHndlCcchStaRsp */ + + +/** + * @brief Handler for StaRsp received on RGU for BCCH or PCCH. + * + * @details + * + * Function : rgROMHndlBcchPcchStaRsp + * + * This function shall store the buffer and time to transmit in lcCb. + * + * + * @param[in] RgCellCb *cell + * @param[in] RgRguCmnStaRsp *staRsp + * @param[out] RgErrInfo *err + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PRIVATE S16 rgROMHndlBcchPcchStaRsp +( +RgCellCb *cell, +RgRguCmnStaRsp *staRsp, +RgErrInfo *err +) +#else +PRIVATE S16 rgROMHndlBcchPcchStaRsp(cell, staRsp, err) +RgCellCb *cell; +RgRguCmnStaRsp *staRsp; +RgErrInfo *err; +#endif +{ + Pst schPst; + RgInfCmnBoRpt boRpt; + Inst macInst = cell->macInst - RG_INST_START; + + TRC2(rgROMHndlBcchPcchStaRsp); + cmMemset((U8*)&schPst, (U8)0, sizeof(Pst)); + + if (rgDBMChkCmnLcCb(cell, staRsp->lcId) != ROK) + { + /* Handle lcCb fetch failure */ + RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,"Invalid LCID:%d",staRsp->lcId); + err->errCause = RGERR_ROM_INV_LC_ID; + RETVALUE(RFAILED); + } + /* MS_WORKAROUND : This is to ensure that the queue for BCH is not filled with old BO requests : + This assumes that BO is not received more than 4 frames in advance from the enodeb application */ + if (cell->bcchBchInfo.lcId == staRsp->lcId) + { + U16 nextBchSfn; + + nextBchSfn = (cell->crntTime.sfn + 4 - (cell->crntTime.sfn%4)) % RG_MAX_SFN; + if ((staRsp->u.timeToTx.sfn != nextBchSfn) || + ((staRsp->u.timeToTx.sfn == cell->crntTime.sfn) && (cell->crntTime.subframe >= 7))) + { + RETVALUE(ROK); + } + } + + boRpt.cellSapId = cell->schInstMap.cellSapId; + boRpt.cellId = staRsp->cellId; + boRpt.u.timeToTx = staRsp->u.timeToTx; + boRpt.lcId = staRsp->lcId; + boRpt.lcType = staRsp->lcType; + boRpt.bo = staRsp->bo; +#ifdef EMTC_ENABLE + if(cell->emtcEnable) + { + if(boRpt.lcType == CM_LTE_LCH_PCCH) + { + boRpt.emtcDIReason = staRsp->emtcDiReason; + boRpt.pnb = staRsp->pnb; + } + } +#endif + rgGetPstToInst(&schPst,macInst, cell->schInstMap.schInst); + RgMacSchCmnBoUpdt(&schPst, &boRpt); + + RETVALUE(ROK); +} /* rgROMHndlBcchPcchStaRsp */ + +/* ADD Changes for Downlink UE Timing Optimization */ +#ifdef LTEMAC_DLUE_TMGOPTMZ +/** + * @brief Handler for updating DL SF information on receiving + * DL dedicated data, CCCH, BCCH/PCCH data request. + * + * @details + * + * Function : rgROMUpdDLSfRemDataCnt + * + * + * @param[in] RgCellCb *cell + * @param[in] RgDlSf *dlSf; + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PRIVATE S16 rgROMUpdDlSfRemDataCnt +( +RgCellCb *cellCb, +RgDlSf *dlSf +) +#else +PRIVATE S16 rgROMUpdDlSfRemDataCnt(cellCb, dlSf) +RgCellCb *cellCb; +RgDlSf *dlSf; +#endif +{ + RgErrInfo err; + //Inst inst = cellCb->macInst - RG_INST_START; + + TRC2(rgROMUpdDlSfRemDataCnt); + + + if(!dlSf->remDatReqCnt) + { + /*This is an error scenario of RLC generating more data + * request than the allocation. Do nothing for this. */ + RLOG_ARG0(L_ERROR,DBG_CELLID,cellCb->cellId, + "RX new data while remDatReqCnt is 0 for cell"); + RETVALUE(RFAILED); + } + + /*Decrement the remaining data request to be received countter + for this SF. + Check if this was the last pending data request for this DL SF.*/ + /* Fix[ccpu00126310]: Tracks Data Requests from RLC for both loosely and tight coupled + RLC-MAC */ + if((0 == --dlSf->remDatReqCnt) && !(dlSf->txDone) && + (RG_TIMEINFO_SAME(cellCb->crntTime, dlSf->schdTime)) && (dlSf->statIndDone)) + { + /*Check if we have already received a TTI for this Data, + if that is the case then we need to send TFU Data request + to PHY */ + + if (ROK != rgTOMUtlProcDlSf (dlSf, cellCb, &err)) + { + RLOG_ARG0(L_ERROR,DBG_CELLID,cellCb->cellId, + "Unable to process downlink subframe for cell"); + err.errType = RGERR_ROM_DEDDATREQ; + } + + /* Mark this frame as sent */ + dlSf->txDone = TRUE; + } + + RETVALUE(ROK); +} /* rgROMUpdDlSfRemDataCnt*/ +#endif + +/********************************************************************** + + End of file +**********************************************************************/ diff --git a/src/5gnrmac/rg_sch.c b/src/5gnrmac/rg_sch.c new file mode 100755 index 000000000..db5e0c826 --- /dev/null +++ b/src/5gnrmac/rg_sch.c @@ -0,0 +1,3086 @@ +/******************************************************************************* +################################################################################ +# Copyright (c) [2017-2019] [Radisys] # +# # +# 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. # +################################################################################ +*******************************************************************************/ + +/************************************************************************ + + Name: LTE-MAC layer + + Type: C source file + + Desc: C source code for Entry point fucntions + + File: rg_sch.c + +**********************************************************************/ + +/** @file rg_sch.c +@brief This file implements the schedulers main access to MAC layer code. +*/ + +static const char* RLOG_MODULE_NAME="MAC"; +static int RLOG_FILE_ID=185; +static int RLOG_MODULE_ID=4096; + +/* header include files -- defines (.h) */ +#include "envopt.h" /* environment options */ +#include "envdep.h" /* environment dependent */ +#include "envind.h" /* environment independent */ +#include "gen.h" /* general layer */ +#include "ssi.h" /* system service interface */ +#include "cm_hash.h" /* common hash list */ +#include "cm_llist.h" /* common linked list library */ +#include "cm_err.h" /* common error */ +#include "cm_lte.h" /* common LTE */ +#include "lrg.h" +#include "rgr.h" +#include "tfu.h" +#include "rgm.h" +#include "rg_env.h" +#include "rg_sch_inf.h" +#include "rg_sch.h" +#include "rg_sch_err.h" +#include "rg_sch_cmn.h" +#include "rl_interface.h" +#include "rl_common.h" + +/* header/extern include files (.x) */ +#include "gen.x" /* general layer typedefs */ +#include "ssi.x" /* system services typedefs */ +#include "cm5.x" /* common timers */ +#include "cm_hash.x" /* common hash list */ +#include "cm_lib.x" /* common library */ +#include "cm_llist.x" /* common linked list */ +#include "cm_mblk.x" /* memory management */ +#include "cm_tkns.x" /* common tokens */ +#include "cm_lte.x" /* common tokens */ +#include "tfu.x" /* TFU types */ +#include "lrg.x" /* layer management typedefs for MAC */ +#include "rgr.x" /* layer management typedefs for MAC */ +#include "rgm.x" /* layer management typedefs for MAC */ +#include "rg_sch_inf.x" /* typedefs for Scheduler */ +#include "rg_sch.x" /* typedefs for Scheduler */ +#include "rg_sch_cmn.x" + +#ifdef EMTC_ENABLE +EXTERN S16 rgEmtcMacSchUeDelInd ARGS((RgSchCellCb *cell,RgInfUeDelInd *ueDelInd)); +EXTERN S16 rgSCHGomEmtcHndlSiCfg ARGS(( +Region reg, +Pool pool, +RgSchCb *instCb, +SpId spId, +RgrCfgTransId transId, +RgrSiCfgReqInfo *cfgReqInfo +)); +EXTERN S16 rgSCHGomEmtcHndlWarningSiCfg ARGS(( +Region reg, +Pool pool, +RgSchCb *instCb, +SpId spId, +RgrCfgTransId transId, +RgrWarningSiCfgReqInfo *warningSiCfgReqInfo +)); +#endif +/* local defines */ +/************** LRG Interface ****************/ +/** + * @brief Layer Manager Configuration request handler. + * + * @details + * + * Function : RgMiLrgSchCfgReq + * + * This function handles the configuration + * request received at scheduler instance from the Layer Manager. + * -# Based on the cfg->hdr.elmId.elmnt value it invokes one of the + * functions rgHdlGenCfg() or rgHdlSapCfg(). + * -# Invokes RgMiLrgSchCfgCfm() to send back the confirmation to the LM. + * + * @param[in] Pst *pst, the post structure + * @param[in] RgMngmt *cfg, the configuration parameter's structure + * @return S16 + * -# ROK + **/ +#ifdef ANSI +PUBLIC S16 RgMiLrgSchCfgReq +( +Pst *pst, /* post structure */ +RgMngmt *cfg /* config structure */ +) +#else +PUBLIC S16 RgMiLrgSchCfgReq(pst, cfg) +Pst *pst; /* post structure */ +RgMngmt *cfg; /* config structure */ +#endif +{ + U16 ret = LCM_PRIM_OK; + U16 reason = LCM_REASON_NOT_APPL; + RgMngmt cfm; + Pst cfmPst; +#ifdef DEBUGP + Inst inst = (pst->dstInst - RGSCH_INST_START); +#endif + + TRC3(RgMiLrgSchCfgReq) + + + //if(pst->dstInst < RGSCH_INST_START) + //{ + RLOG_ARG0(L_ERROR,DBG_INSTID,inst, "Invalid inst ID"); + RLOG_ARG2(L_DEBUG,DBG_INSTID,inst, "RgMiLrgSchCfgReq(): " + "pst->dstInst=%d RGSCH_INST_START=%d", pst->dstInst,RGSCH_INST_START); + //RETVALUE(ROK); + //} + + /* Fill the post structure for sending the confirmation */ + rgSCHLmmFillCfmPst(pst, &cfmPst, cfg); + + /* Initialize the cfg cfm structure + if (SGetSBuf(cfmPst.region, cfmPst.pool, (Data **)&cfm, sizeof(RgMngmt)) + != ROK) + { + RLOG_ARG0(L_ERROR,DBG_INSTID,inst, "Memory Unavailable for Confirmation"); + RETVALUE(ROK); + } */ + cmMemset((U8 *)&cfm, 0, sizeof(RgMngmt)); + +#ifdef LMINT3 + cfm.hdr.transId = + cfg->hdr.transId; +#endif + + cfm.hdr.elmId.elmnt = cfg->hdr.elmId.elmnt; + switch(cfg->hdr.elmId.elmnt) + { + case STSCHINST: + reason = rgSCHLmmInstCfg(&cfg->t.cfg,pst->dstInst ); + break; + default: + ret = LCM_PRIM_NOK; + reason = LCM_REASON_INVALID_ELMNT; + RLOG_ARG1(L_ERROR,DBG_INSTID,inst, "Invalid Elmnt=%d", cfg->hdr.elmId.elmnt); + break; + } + + if (reason != LCM_REASON_NOT_APPL) + { + ret = LCM_PRIM_NOK; + } + + cfm.cfm.status = ret; + cfm.cfm.reason = reason; + + RgMiLrgSchCfgCfm(&cfmPst, &cfm); + /* SPutSBuf(pst->region, pst->pool, (Data *)cfg, sizeof(RgMngmt)); */ + + RETVALUE(ROK); +}/*-- RgMiLrgSchCfgReq --*/ + + +/** + * @brief Layer Manager Control request handler. + * + * @details + * + * Function : RgMiLrgSchCntrlReq + * + * This function handles the control + * request received from the Layer Manager. + * -# Based on cntrl->hdr.elmId.elmnt, cntrl->t.cntrl.action + * and cntrl->t.cntrl.subAction, it performs the appropriate control action + * of SAP (enable/disable) and layer shutdown. + * -# Invokes the RgMiLrgSchCntrlCfm to send back the confirmation to LM. + * + * @param[in] Pst *pst, the post structure + * @param[in] RgMngmt *cntrl, the control parameter's structure + * @return S16 + * -# ROK + **/ +#ifdef ANSI +PUBLIC S16 RgMiLrgSchCntrlReq +( +Pst *pst, /* post structure */ +RgMngmt *cntrl /* control structure */ +) +#else +PUBLIC S16 RgMiLrgSchCntrlReq(pst, cntrl) +Pst *pst; /* post structure */ +RgMngmt *cntrl; /* control structure */ +#endif +{ + S16 ret = ROK; /* return value */ + Pst cfmPst; + RgMngmt cfm; + + Inst inst = (pst->dstInst - RGSCH_INST_START); /* Scheduler instance Id */ + TRC3(RgMiLrgSchCntrlReq) + + + /* Fill the post structure for sending the confirmation */ + rgSCHLmmFillCfmPst(pst, &cfmPst, cntrl); + + /* Initialize the cfg cfm structure + if (SGetSBuf(cfmPst.region, cfmPst.pool, (Data **)&cfm, sizeof(RgMngmt)) + != ROK) + { + RLOG_ARG0(L_ERROR,DBG_INSTID,inst, "Memory Unavailable for Confirmation"); + SPutSBuf(pst->region, pst->pool, (Data *)cntrl, sizeof(RgMngmt)); + RETVALUE(ROK); + } */ + cmMemset((U8 *)&cfm, 0, sizeof(RgMngmt)); + +#ifdef LMINT3 + cfm.hdr.transId = + cntrl->hdr.transId; +#endif + + cfm.hdr.elmId.elmnt = cntrl->hdr.elmId.elmnt; + cfm.t.cntrl.action = cntrl->t.cntrl.action; + cfm.t.cntrl.subAction = cntrl->t.cntrl.subAction; + + /* Check if General Config Done*/ + if(rgSchCb[inst].rgSchInit.cfgDone != TRUE) + { + cfm.cfm.status = LCM_PRIM_NOK; + cfm.cfm.reason = LCM_REASON_GENCFG_NOT_DONE; + cfm.hdr.elmId.elmnt = cntrl->hdr.elmId.elmnt; + RgMiLrgSchCntrlCfm(&cfmPst, &cfm); + RLOG_ARG0(L_ERROR,DBG_INSTID,inst, "Gen Cfg not done."); + /* SPutSBuf(pst->region, pst->pool, (Data *)cntrl, sizeof(RgMngmt)); */ + RETVALUE(ROK); + } + + /* General Config done, process the Control request */ + switch(cntrl->hdr.elmId.elmnt) + { + case STGEN: + rgSCHLmmGenCntrl(cntrl, &cfm, &cfmPst); + break; + case STTFUSAP: + case STRGRSAP: + rgSCHLmmSapCntrl(cntrl, &cfm, &cfmPst); + break; + default: + cfm.cfm.status = LCM_PRIM_NOK; + cfm.cfm.reason = LCM_REASON_INVALID_PAR_VAL; + RgMiLrgSchCntrlCfm(&cfmPst, &cfm); + RLOG_ARG1(L_ERROR,DBG_INSTID,inst, "invalid elmnt=%d", + cntrl->hdr.elmId.elmnt); + break; + } + /* SPutSBuf(pst->region, pst->pool, (Data *)cntrl, sizeof(RgMngmt)); */ + RETVALUE(ret); +}/*-- RgMiLrgSchCntrlReq --*/ + +#ifdef LTE_L2_MEAS +/** + * @brief Layer Manager L2 Measurement request handler. + * + * @details + * + * Function : RgMiLrgSchL2MeasReq + * + * This function handles the control + * measurement request received from the Layer Manager. + * + * @param[in] Pst *pst, the post structure + * @param[in] LrgSchMeasReqInfo *measInfo, measurement request info + * @return S16 + * -# ROK + **/ +#ifdef ANSI +PUBLIC S16 RgMiLrgSchL2MeasReq +( +Pst *pst, /* post structure */ +LrgSchMeasReqInfo *measInfo /* Meas Req Info */ +) +#else +PUBLIC S16 RgMiLrgSchL2MeasReq(pst, measInfo) + Pst *pst; /* post structure */ + LrgSchMeasReqInfo *measInfo; /* Meas Req Info */ +#endif +{ + Pst cfmPst; + RgSchCellCb *cell; + RgSchErrInfo err; + S16 ret = ROK; + RgSchCb *instCb = &rgSchCb[(pst->dstInst - RGSCH_INST_START)]; +#if (ERRCLASS & ERRCLS_ADD_RES) + CmLList *lnk; +#endif + U32 idx; + RgSchL2MeasCb *measCb = NULLP; +#ifdef DEBUGP + Inst inst = (pst->dstInst - RGSCH_INST_START); /* Scheduler instance Id */ +#endif + + err.errType = 0; + err.errCause = 0; + + TRC3(RgMiLrgSchL2MeasReq) + + + /* Find the cellCb using cellId in measInfo. Iterate through all cells + * in rgrsapCb in RgschCb */ + cell = NULLP; + for (idx = 0; idx < instCb->numSaps; idx++) + { + if ( instCb->rgrSap[idx].cell->cellId == measInfo->cellId) + { + /* got the cell break the loop */ + cell = instCb->rgrSap[idx].cell; + break; + } + } + /* If no cellCb return Err with Invalid Cell Id */ + if (cell == NULLP) + { + rgSchL2mFillCfmPst(pst, &cfmPst, measInfo); + RGSCHFILLERR(err, RGSCHERR_L2M_MEASREQ, RGSCHERR_SCH_INVALID_CELLID); + rgSchL2mSndCfm(&cfmPst, NULLP, measInfo, TRUE); + RLOG_ARG2(L_ERROR,DBG_INSTID,inst, + "Meas req Failed.Invalid Cell Id errType(%d) errCause(%d)", + err.errType, err.errCause); + RETVALUE(RFAILED); + } + /* Validate for Meas Types */ + if ( (ret = rgSCHUtlValidateMeasReq(cell, measInfo, &err)) != ROK) + { + rgSchL2mFillCfmPst(pst, &cfmPst, measInfo); + RGSCHFILLERR(err, RGSCHERR_L2M_MEASREQ, RGSCHERR_SCH_INVALID_MEASTYPE); + rgSchL2mSndCfm(&cfmPst, NULLP, measInfo, TRUE); + RLOG_ARG2(L_ERROR,DBG_CELLID,cell->cellId, + "Meas req Failed.Invalid Measurement Type" + "errCasue(%d) errType(%d)", err.errType, err.errCause); + RETVALUE(RFAILED); + } + /* Iterate through all meas requests in l2mList in cellCb */ +#if (ERRCLASS & ERRCLS_ADD_RES) + lnk = cell->l2mList.first; + while(lnk != NULLP) + { + /* Get the MeasCb : RgSchL2MeasCb */ + measCb = (RgSchL2MeasCb *)lnk->node; + lnk = lnk->next; + if (measCb->measReq.hdr.transId == measInfo->hdr.transId) + { + rgSchL2mFillCfmPst(pst, &cfmPst, measInfo); + RGSCHFILLERR(err, RGSCHERR_L2M_MEASREQ, RGSCHERR_SCH_DUP_TRANSID); + rgSchL2mSndCfm(&cfmPst, measCb, measInfo, TRUE); + RLOG_ARG2(L_ERROR,DBG_CELLID,cell->cellId, + "Meas req Failed.Dublicate TransId" + "errType(%d) errCause(%d)", err.errType, err.errCause); + RETVALUE(RFAILED); + } + } +#endif + /* Call L2M Function to store Meas req */ + ret = rgSchL2mMeasReq(cell, measInfo, err); + if (ret != ROK) + { + rgSchL2mFillCfmPst(pst, &cfmPst, measInfo); + RGSCHFILLERR(err, RGSCHERR_L2M_MEASREQ, RGSCHERR_SCH_L2MEAS_FAILED); + rgSchL2mSndCfm(&cfmPst, measCb, measInfo, TRUE); + RLOG_ARG2(L_ERROR,DBG_CELLID,cell->cellId, + "Meas req Failed.errType(%d) errCause(%d)", + err.errType, err.errCause); + RETVALUE(RFAILED); + } + RETVALUE(ret); +} /* -- RRgMiLrgSchL2MeasReq-- */ + +/** + * @brief Layer Manager L2 Measurement Stop request handler. + * + * @details + * + * Function : RgMiLrgSchL2MeasStopReq + * + * This function handles the control + * measurement stop request received from the Layer Manager. + * + * @param[in] Pst *pst, the post structure + * @param[in] LrgSchMeasReqInfo *measInfo, measurement stop request info + * @return S16 + * -# ROK + **/ +#ifdef ANSI +PUBLIC S16 RgMiLrgSchL2MeasStopReq +( +Pst *pst, /* post structure */ +LrgSchMeasStopReqInfo *measInfo /* Meas Req Info */ +) +#else +PUBLIC S16 RgMiLrgSchL2MeasStopReq(pst, measInfo) + Pst *pst; /* post structure */ + LrgSchMeasStopReqInfo *measInfo; /* Meas Req Info */ +#endif +{ + S16 ret = ROK; + RgSchCellCb *cell = NULLP; + RgSchCb *instCb = &rgSchCb[(pst->dstInst - RGSCH_INST_START)]; + CmLList *node = NULLP; + RgSchL2MeasCb *measCb = NULLP; + LrgSchMeasCfmInfo measCfm; + U8 idx; + + + TRC3(RgMiLrgSchL2MeasStopReq) + + + for (idx = 0; idx < instCb->numSaps; idx++) + { + if ( instCb->rgrSap[idx].cell->cellId == measInfo->cellId) + { + /* got the cell break the loop */ + cell = instCb->rgrSap[idx].cell; + break; + } + } + if (cell == NULLP) + { + RLOG_ARG0(L_ERROR,DBG_CELLID,measInfo->cellId, + "Stop req Failed.Invalid Cell Id "); + RETVALUE(RFAILED); + } + cmMemset((U8 *)&measCfm, 0, sizeof(LrgSchMeasCfmInfo)); + node = cell->l2mList.first; + while(node != NULLP) + { + measCb = (RgSchL2MeasCb *)(node)->node; + + node = (node)->next; + cmLListDelFrm(&cell->l2mList, &measCb->measLnk); + rgSCHUtlFreeSBuf(cell->instIdx, (Data **)&measCb, + sizeof(RgSchL2MeasCb)); + } + + if(measInfo->measType & LRG_L2MEAS_AVG_PRB_PER_QCI_UL) + { + RgInfL2MeasStopReq measStopReq; + Pst pstMac; + cmMemset((U8 *)&measStopReq, 0, sizeof(RgInfL2MeasStopReq)); + measStopReq.transId = measInfo->hdr.transId; + measStopReq.measType = measInfo->measType; + /* measReq.timePrd = measInfo->timePrd; */ + measStopReq.cellId = measInfo->cellId; + rgSCHUtlGetPstToLyr(&pstMac, &rgSchCb[cell->instIdx], cell->macInst); + RgSchMacL2MeasStop(&pstMac,&measStopReq); + } + else + { + RgMiLrgSchL2MeasStopCfm(&(rgSchCb[cell->instIdx].rgSchInit.lmPst), + &measCfm); + } + RETVALUE(ret); +}/*RgMiLrgSchL2MeasStopReq*/ +/** + * @brief Layer Manager L2 Measurement request handler. + * for Send l2 measurement req + * @details + * + * Function : RgMiLrgSchL2MeasSendReq + * + * This function handles the control + * measurement send request received from the Layer Manager. + * + * @param[in] Pst *pst, the post structure + * @param[in] LrgSchMeasReqInfo *measInfo, measurement stop request info + * @return S16 + * -# ROK + **/ +#ifdef ANSI +PUBLIC S16 RgMiLrgSchL2MeasSendReq +( +Pst *pst, /* post structure */ +LrgSchMeasSndReqInfo *measInfo /* Meas Req Info */ +) +#else +PUBLIC S16 RgMiLrgSchL2MeasSendReq(pst, measInfo) + Pst *pst; /* post structure */ + LrgSchMeasSndReqInfo *measInfo; /* Meas Req Info */ +#endif +{ + S16 ret = ROK; + RgSchCellCb *cell; + RgSchCb *instCb = &rgSchCb[(pst->dstInst - RGSCH_INST_START)]; + U8 idx; + + TRC3(RgMiLrgSchL2MeasSendReq) + + + + cell = NULLP; + for (idx = 0; idx < instCb->numSaps; idx++) + { + if ( instCb->rgrSap[idx].cell->cellId == measInfo->cellId) + { + /* got the cell break the loop */ + cell = instCb->rgrSap[idx].cell; + break; + } + } + if (cell == NULLP) + { + RLOG_ARG0(L_ERROR,DBG_CELLID,measInfo->cellId, + "Send req Failed.Invalid Cell Id"); + RETVALUE(RFAILED); + } + + if(measInfo->measType & LRG_L2MEAS_AVG_PRB_PER_QCI_UL) + { + RgInfL2MeasSndReq measSndReq; + Pst pstMac; + cmMemset((U8 *)&measSndReq, 0, sizeof(RgInfL2MeasSndReq)); + measSndReq.transId = measInfo->hdr.transId; + measSndReq.measType = measInfo->measType; + measSndReq.timePrd = measInfo->timePrd; + measSndReq.cellId = measInfo->cellId; + rgSCHUtlGetPstToLyr(&pstMac, &rgSchCb[cell->instIdx], cell->macInst); + RgSchMacL2MeasSend(&pstMac, &measSndReq); + } + else + { + cell->sndL2Meas = TRUE; + } + + RETVALUE(ret); +}/*RgMiLrgSchL2MeasSendReq*/ +#endif /* LTE_L2_MEAS */ + + + + +/************* RGR Interface ****************/ +/** + * @brief API for bind request from RRM towards MAC. + * + * @details + * + * Function: RgUiRgrBndReq + * + * This API is invoked by RRM towards MAC to bind RGR SAP. + * These API validates the Pst, spId, suId and sends the bind confirm to + * RRM. + * + * + * @param[in] Pst *pst + * @param[in] SuId suId + * @param[in] SpId spId + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 RgUiRgrBndReq +( + Pst *pst, + SuId suId, + SpId spId + ) +#else +PUBLIC S16 RgUiRgrBndReq(pst, suId, spId) + Pst *pst; + SuId suId; + SpId spId; +#endif +{ + S16 ret = ROK; + Pst tmpPst; /* Temporary Post Structure */ + Inst instId = pst->dstInst-RGSCH_INST_START; + RgUstaDgn dgn; /* Alarm diagnostics structure */ + + TRC3(RgUiRgrBndReq) + + + tmpPst.prior = pst->prior; + tmpPst.route = pst->route; + tmpPst.selector = pst->selector; + tmpPst.region = rgSchCb[instId].rgSchInit.region; + tmpPst.pool = rgSchCb[instId].rgSchInit.pool; + tmpPst.srcProcId = rgSchCb[instId].rgSchInit.procId; + tmpPst.srcEnt = rgSchCb[instId].rgSchInit.ent; + tmpPst.srcInst = rgSchCb[instId].rgSchInit.inst + RGSCH_INST_START; + tmpPst.event = EVTNONE; + tmpPst.dstProcId = pst->srcProcId; + tmpPst.dstEnt = pst->srcEnt; + tmpPst.dstInst = pst->srcInst; + + if(spId < rgSchCb[instId].numSaps) + { + /* Check the state of the SAP */ + switch (rgSchCb[instId].rgrSap[spId].sapSta.sapState) + { + /* This case might not be needed if SAP not configured then it will go + * to else of above if condition */ + case LRG_UNBND: /* SAP is not bound */ + RLOG0(L_DEBUG,"SAP Not yet bound"); + rgSchCb[instId].rgrSap[spId].sapSta.sapState = LRG_BND; + rgSchCb[instId].rgrSap[spId].sapCfg.suId = suId; + /* Send Bind Confirm with status as SUCCESS */ + ret = rgSCHUtlRgrBndCfm(instId, suId, CM_BND_OK); + /*Indicate to Layer manager */ + rgSCHUtlFillDgnParams(instId, &dgn, LRG_USTA_DGNVAL_MEM); + ret = rgSCHLmmStaInd(instId, LCM_CATEGORY_INTERFACE, + LRG_EVENT_RGRSAP_ENB, LCM_CAUSE_UNKNOWN, &dgn); + break; + case LRG_BND: /* SAP is already bound*/ + RLOG0(L_DEBUG,"SAP is already bound"); + ret = rgSCHUtlRgrBndCfm(instId, suId, CM_BND_OK); + break; + default: /* Should Never Enter here */ +#if (ERRCLASS & ERRCLS_ADD_RES) + RGSCHLOGERROR(instId, ERRCLS_INT_PAR, ERG001, + (ErrVal)rgSchCb[instId].rgrSap[spId].sapSta.sapState, + "Invalid SAP State:RgUiRrgBndReq failed\n"); +#endif + ret = rgSCHUtlRgrBndCfm(instId, suId, CM_BND_NOK); + break; + } + } + else + { +#if (ERRCLASS & ERRCLS_ADD_RES) + /* ccpu00117035 - MOD - Changed ErrVal argument from accessing sap state + to spId to avoid seg fault due to invalid sapID */ + RGSCHLOGERROR(instId, ERRCLS_INT_PAR, ERG002, + (ErrVal)spId, "Invalid SAP Id:RgUiRrgBndReq failed\n"); +#endif + ret = RgUiRgrBndCfm(&tmpPst, suId, CM_BND_NOK); + } + RETVALUE(ret); +} /* RgUiRgrBndReq */ + +/** + * @brief API for unbind request from RRM towards MAC. + * + * @details + * + * Function: RgUiRgrUbndReq + * + * This API is invoked by RRM towards MAC to unbind RGR SAP. + * These API validates the Pst, spId, suId and transfers the unbind request + * specific information to corresponding ownership module (GOM) API. + * + * + * @param[in] Pst *pst + * @param[in] SuId suId + * @param[in] Reason reason + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 RgUiRgrUbndReq +( + Pst *pst, + SpId spId, + Reason reason + ) +#else +PUBLIC S16 RgUiRgrUbndReq(pst, spId, reason) + Pst *pst; + SpId spId; + Reason reason; +#endif +{ + Inst instId = pst->dstInst-RGSCH_INST_START; + TRC3(RgUiRgrUbndReq) + + + /* SAP Id validation */ + if (spId < rgSchCb[instId].numSaps) + { + switch(rgSchCb[instId].rgrSap[spId].sapSta.sapState) + { + case LRG_BND: /* SAP is already bound*/ + RLOG0(L_DEBUG,"SAP is already bound"); + /* setting SAP state to UN BOUND */ + rgSchCb[instId].rgrSap[spId].sapSta.sapState = LRG_UNBND; + break; + default: +#if (ERRCLASS & ERRCLS_ADD_RES) + RGSCHLOGERROR(instId, ERRCLS_INT_PAR, ERG003, + (ErrVal)rgSchCb[instId].rgrSap[spId].sapSta.sapState, + "Invalid SAP State: RgUiRgrUbndReq failed\n"); +#endif + RETVALUE(RFAILED); + } + } + else + { +#if (ERRCLASS & ERRCLS_ADD_RES) + RGSCHLOGERROR(instId,ERRCLS_INT_PAR, ERG004, + (ErrVal)rgSchCb[instId].rgrSap[spId].sapSta.sapState, + "Invalid SAP Id:RgUiRgrUbndReq failed\n"); +#endif + RETVALUE(RFAILED); + } + RETVALUE(ROK); +} /* RgUiRgrUbndReq */ + +/** + * @brief API for configuration request from RRM towards MAC. + * + * @details + * + * Function: RgUiRgrCfgReq + * + * This API is invoked by RRM towards MAC to configure MAC. + * These API validates the Pst, spId, suId and transfers the config request + * specific information to corresponding ownership module (GOM) API. + * + * + * @param[in] Pst *pst + * @param[in] SpId spId + * @param[in] RgrCfgTransId transId + * @param[in] RgrCfgReqInfo *cfgReqInfo + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 RgUiRgrCfgReq +( + Pst *pst, + SpId spId, + RgrCfgTransId transId, + RgrCfgReqInfo *cfgReqInfo + ) +#else +PUBLIC S16 RgUiRgrCfgReq(pst, spId, transId, cfgReqInfo) + Pst *pst; + SpId spId; + RgrCfgTransId transId; + RgrCfgReqInfo *cfgReqInfo; +#endif +{ + + S16 ret = ROK; + U8 cfmStatus = 0x00ff; + U8 prntTrans[RGR_CFG_TRANSID_SIZE+1]; + Inst instId = pst->dstInst-RGSCH_INST_START; + + TRC3(RgUiRgrCfgReq); + + cmMemcpy((U8 *)prntTrans, (U8 *)transId.trans, RGR_CFG_TRANSID_SIZE); + prntTrans[RGR_CFG_TRANSID_SIZE] = '\0'; + + + if (cfgReqInfo == NULLP) + { + RLOG_ARG0(L_ERROR,DBG_INSTID,instId,"Input Message Buffer is NULL"); + rgSCHUtlRgrCfgCfm(instId, spId, transId, cfmStatus); + RETVALUE(RFAILED); + } + + if (spId < rgSchCb[instId].numSaps) + { + switch(rgSchCb[instId].rgrSap[spId].sapSta.sapState) + { + case LRG_BND: /* SAP is already bound */ + RLOG0(L_DEBUG,"SAP is already bound"); + break; + default: /* Should never reach here */ +#if (ERRCLASS & ERRCLS_ADD_RES) + RGSCHLOGERROR(instId, ERRCLS_INT_PAR, ERG005, + (ErrVal)rgSchCb[instId].rgrSap[spId].sapSta.sapState, + "Invalid SAP State: RgUiRgrCfgReq failed\n"); +#endif + SPutSBuf(pst->region, pst->pool, (Data *)cfgReqInfo, + (Size)sizeof(*cfgReqInfo)); + rgSCHUtlRgrCfgCfm(instId, spId, transId, cfmStatus); + RETVALUE(RFAILED); + } + } + else + { +#if (ERRCLASS & ERRCLS_ADD_RES) + RGSCHLOGERROR(instId, ERRCLS_INT_PAR, ERG006, + (ErrVal)rgSchCb[instId].rgrSap[spId].sapCfg.spId, + "Invalid SAP Id:RgUiRgrCfgReq failed\n"); +#endif + SPutSBuf(pst->region, pst->pool, (Data *)cfgReqInfo, + (Size)sizeof(*cfgReqInfo)); + rgSCHUtlRgrCfgCfm(instId, spId, transId, cfmStatus); + RETVALUE(RFAILED); + } + + /* Handle configuration */ + ret = rgSCHGomHndlCfg(pst->region, pst->pool, + &rgSchCb[instId], spId, transId, + cfgReqInfo); + if (ret != ROK) + { + RLOG_ARG0(L_ERROR,DBG_INSTID,instId,"Configuration Request Handling Failed"); + RETVALUE(RFAILED); + } + + RETVALUE(ROK); +} /* RgUiRgrCfgReq */ + +#ifdef RGR_SI_SCH +/** + * @brief API for SI configuration request from RRM towards MAC. + * + * @details + * + * Function: RgUiRgrSiCfgReq + * + * This API is invoked by RRM towards MAC to configure SI at MAC. + * These API validates the Pst, spId, suId and transfers the + * config request specific information to corresponding ownership + * module (GOM) API. + * + * + * @param[in] Pst *pst + * @param[in] SpId spId + * @param[in] RgrCfgTransId transId + * @param[in] RgrSiCfgReqInfo *cfgReqInfo + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 RgUiRgrSiCfgReq +( +Pst *pst, +SpId spId, +RgrCfgTransId transId, +RgrSiCfgReqInfo *cfgReqInfo +) +#else +PUBLIC S16 RgUiRgrSiCfgReq(pst, spId, transId, cfgReqInfo) +Pst *pst; +SpId spId; +RgrCfgTransId transId; +RgrSiCfgReqInfo *cfgReqInfo; +#endif +{ + S16 ret = ROK; + U8 cfmStatus = RGR_CFG_CFM_NOK; + U8 prntTrans[RGR_CFG_TRANSID_SIZE+1]; + Inst instId = pst->dstInst-RGSCH_INST_START; + + TRC2(RgUiRgrSiCfgReq); + + cmMemcpy((U8 *)prntTrans, (U8 *)transId.trans, RGR_CFG_TRANSID_SIZE); + prntTrans[RGR_CFG_TRANSID_SIZE] = '\0'; + + + if (cfgReqInfo == NULLP) + { + RLOG_ARG0(L_ERROR,DBG_INSTID,instId,"Input Message Buffer " + "is NULL"); + rgSCHUtlRgrSiCfgCfm(instId, spId, transId, cfmStatus); + RETVALUE(RFAILED); + } + + if (spId < rgSchCb[instId].numSaps) + { + if(LRG_BND != rgSchCb[instId].rgrSap[spId].sapSta.sapState) + { +#if (ERRCLASS & ERRCLS_ADD_RES) + RGSCHLOGERROR(instId, ERRCLS_INT_PAR, ERG007, + (ErrVal)rgSchCb[instId].rgrSap[spId].sapSta.sapState, + "Invalid SAP State: RgUiRgrSiCfgReq failed\n"); +#endif + SPutSBuf(pst->region, pst->pool, (Data *)cfgReqInfo, + (Size)sizeof(*cfgReqInfo)); + rgSCHUtlRgrSiCfgCfm(instId, spId, transId, cfmStatus); + RETVALUE(RFAILED); + } + } + else + { +#if (ERRCLASS & ERRCLS_ADD_RES) + RGSCHLOGERROR(instId, ERRCLS_INT_PAR, ERG008, + (ErrVal)rgSchCb[instId].rgrSap[spId].sapCfg.spId, + "Invalid SAP Id:RgUiRgrSiCfgReq failed\n"); +#endif + SPutSBuf(pst->region, pst->pool, (Data *)cfgReqInfo, + (Size)sizeof(*cfgReqInfo)); + rgSCHUtlRgrSiCfgCfm(instId, spId, transId, cfmStatus); + RETVALUE(RFAILED); + } + + /* Handle configuration */ +#ifdef EMTC_ENABLE +if(rgSchCb[instId].rgrSap[spId].cell->emtcEnable) +{ + ret = rgSCHGomEmtcHndlSiCfg(pst->region, pst->pool, + &rgSchCb[instId], spId, transId, + cfgReqInfo); +} +else +{ + ret = rgSCHGomHndlSiCfg(pst->region, pst->pool, + &rgSchCb[instId], spId, transId, + cfgReqInfo); +} + #else + ret = rgSCHGomHndlSiCfg(pst->region, pst->pool, + &rgSchCb[instId], spId, transId, + cfgReqInfo); + #endif + if (ret != ROK) + { + RLOG_ARG0(L_ERROR,DBG_INSTID,instId,"RgUiRgrSiCfgReq:" + "Configuration Request Handling Failed"); + RETVALUE(RFAILED); + } + + RETVALUE(ROK); +} /* RgUiRgrSiCfgReq */ + + +/** + * @brief API for Warning SI configuration request from RRM towards MAC. + * + * @details + * + * Function: RgUiRgrWarningSiCfgReq + * + * This API is invoked by RRM towards MAC to configure SI at MAC. + * These API validates the Pst, spId, suId and transfers the + * config request specific information to corresponding ownership + * module (GOM) API. + * + * + * @param[in] Pst *pst + * @param[in] SpId spId + * @param[in] RgrCfgTransId transId + * @param[in] RgrWarningSiCfgReqInfo *warningSiCfgReqInfo + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 RgUiRgrWarningSiCfgReq +( +Pst *pst, +SpId spId, +RgrCfgTransId transId, +RgrWarningSiCfgReqInfo *warningSiCfgReqInfo +) +#else +PUBLIC S16 RgUiRgrWarningSiCfgReq(pst, spId, transId, warningSiCfgReqInfo) +Pst *pst; +SpId spId; +RgrCfgTransId transId; +RgrWarningSiCfgReqInfo *warningSiCfgReqInfo; +#endif +{ + Inst instId = pst->dstInst-RGSCH_INST_START; + S16 ret = ROK; + U8 cfmStatus = RGR_CFG_CFM_NOK; + U8 prntTrans[RGR_CFG_TRANSID_SIZE+1]; + + TRC2(RgUiRgrWarningSiCfgReq); + + cmMemcpy((U8 *)prntTrans, (U8 *)transId.trans, RGR_CFG_TRANSID_SIZE); + prntTrans[RGR_CFG_TRANSID_SIZE] = '\0'; + + + + if (warningSiCfgReqInfo == NULLP) + { + RLOG_ARG0(L_ERROR,DBG_INSTID,instId,"Input Message Buffer " + "is NULL"); + rgSCHUtlRgrWarningSiCfgCfm(instId, spId, 0, transId, cfmStatus); + RETVALUE(RFAILED); + } + + if (spId < rgSchCb[instId].numSaps) + { + if(LRG_BND != rgSchCb[instId].rgrSap[spId].sapSta.sapState) + { +#if (ERRCLASS & ERRCLS_ADD_RES) + RGSCHLOGERROR(instId, ERRCLS_INT_PAR, ERG023, + (ErrVal)rgSchCb[instId].rgrSap[spId].sapSta.sapState, + "Invalid SAP State: warningSiCfgReqInfo failed\n"); +#endif + rgSCHUtlFreeWarningSiSeg(pst->region, pst->pool, + &warningSiCfgReqInfo->siPduLst); + SPutSBuf(pst->region, pst->pool, (Data *)warningSiCfgReqInfo, + sizeof(RgrWarningSiCfgReqInfo)); + rgSCHUtlRgrWarningSiCfgCfm(instId, spId, warningSiCfgReqInfo->siId, + transId, cfmStatus); + RETVALUE(RFAILED); + } + } + else + { +#if (ERRCLASS & ERRCLS_ADD_RES) + RGSCHLOGERROR(instId, ERRCLS_INT_PAR, ERG024, + (ErrVal)rgSchCb[instId].rgrSap[spId].sapCfg.spId, + "Invalid SAP Id:warningSiCfgReqInfo failed\n"); +#endif + rgSCHUtlFreeWarningSiSeg(pst->region, pst->pool, + &warningSiCfgReqInfo->siPduLst); + SPutSBuf(pst->region, pst->pool, (Data *)warningSiCfgReqInfo, + sizeof(RgrWarningSiCfgReqInfo)); + rgSCHUtlRgrWarningSiCfgCfm(instId, spId, warningSiCfgReqInfo->siId, + transId, cfmStatus); + RETVALUE(RFAILED); + } + + /* Handle configuration */ +#ifdef EMTC_ENABLE +if(rgSchCb[instId].rgrSap[spId].cell->emtcEnable) +{ + ret = rgSCHGomEmtcHndlWarningSiCfg(pst->region, pst->pool, + &rgSchCb[instId], spId, transId, warningSiCfgReqInfo); +} +else +{ + ret = rgSCHGomHndlWarningSiCfg(pst->region, pst->pool, + &rgSchCb[instId], spId, transId, warningSiCfgReqInfo); +} +#else + ret = rgSCHGomHndlWarningSiCfg(pst->region, pst->pool, + &rgSchCb[instId], spId, transId, warningSiCfgReqInfo); +#endif + if(ret != ROK) + { + RLOG_ARG0(L_ERROR,DBG_INSTID,instId, + "Configuration Request Handling Failed"); + RETVALUE(RFAILED); + } + + RETVALUE(ROK); +} + + +/** + * @brief API for Warning SI Stop request from RRM towards MAC. + * + * @details + * + * Function: RgUiRgrWarningSiStopReq + * + * This API is invoked by RRM towards MAC to Stop warning SI at MAC. + * These API validates the Pst, spId, suId and transfers the + * stop request specific information to corresponding ownership + * module (GOM) API. + * + * + * @param[in] Pst *pst + * @param[in] SpId spId + * @param[in] RgrWarningSiCfgReqInfo *warningSiCfgReqInfo + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 RgUiRgrWarningSiStopReq +( +Pst *pst, +SpId spId, +RgrCfgTransId transId, +U8 siId +) +#else +PUBLIC S16 RgUiRgrWarningSiStopReq(pst,spId, transId, siId) +Pst *pst; +SpId spId; +RgrCfgTransId transId; +U8 siId; +#endif +{ + Inst instId = pst->dstInst-RGSCH_INST_START; + + TRC3(RgUiRgrWarningSiStopReq) + + + + if (spId < rgSchCb[instId].numSaps) + { + if(LRG_BND != rgSchCb[instId].rgrSap[spId].sapSta.sapState) + { +#if (ERRCLASS & ERRCLS_ADD_RES) + RGSCHLOGERROR(instId, ERRCLS_INT_PAR, ERG025, + (ErrVal)rgSchCb[instId].rgrSap[spId].sapSta.sapState, + "Invalid SAP State: RgUiRgrWarningSiStopReq failed\n"); +#endif + RETVALUE(RFAILED); + } + } + else + { +#if (ERRCLASS & ERRCLS_ADD_RES) + RGSCHLOGERROR(instId, ERRCLS_INT_PAR, ERG026, + (ErrVal)rgSchCb[instId].rgrSap[spId].sapCfg.spId, + "Invalid SAP Id:RgUiRgrWarningSiStopReq failed\n"); +#endif + RETVALUE(RFAILED); + } + + rgSCHGomHndlWarningSiStopReq(pst->region, pst->pool, + &rgSchCb[instId], siId, transId, spId); + + RETVALUE(ROK); +} +#endif /*RGR_SI_SCH */ + +/* LTE_ADV_FLAG_REMOVED_START */ + +/** + * @brief API for LOAD INF request from RRM towards MAC. + * + * @details + * + * Function: RgUiRgrLoadInfReq + * + * This API is invoked by RRM towards MAC to configure LOAD INF Parameters at MAC. + * These API validates the Pst, spId, suId and transfers the + * LOAD INF request to corresponding ownership + * module (GOM) API. + * + * + * @param[in] Pst *pst + * @param[in] SpId spId + * @param[in] RgrCfgTransId transId + * @param[in] RgrLoadInfReqInfo *loadInfReq + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 RgUiRgrLoadInfReq +( + Pst *pst, + SpId spId, + RgrCfgTransId transId, + RgrLoadInfReqInfo *loadInfReq + ) +#else +PUBLIC S16 RgUiRgrLoadInfReq(pst, spId, transId, loadInfReq) + Pst *pst; + SpId spId; + RgrCfgTransId transId; + RgrLoadInfReqInfo *loadInfReq; +#endif +{ + S16 ret = ROK; + U8 prntTrans[RGR_CFG_TRANSID_SIZE+1]; + Inst instId = pst->dstInst-RGSCH_INST_START; + + TRC2(RgUiRgrLoadInfReq); + + cmMemcpy((U8 *)prntTrans, (U8 *)transId.trans, RGR_CFG_TRANSID_SIZE); + prntTrans[RGR_CFG_TRANSID_SIZE] = '\0'; + + + if (loadInfReq == NULLP) + { + RLOG_ARG0(L_ERROR,DBG_INSTID,instId,"Input Message Buffer " + "is NULL"); + RETVALUE(RFAILED); + } + + if (spId < rgSchCb[instId].numSaps) + { + if(LRG_BND != rgSchCb[instId].rgrSap[spId].sapSta.sapState) + { +#if (ERRCLASS & ERRCLS_ADD_RES) + RGSCHLOGERROR(instId, ERRCLS_INT_PAR, ERG007, + (ErrVal)rgSchCb[instId].rgrSap[spId].sapSta.sapState, + "Invalid SAP State: RgUiRgrLoadInfReq failed\n"); +#endif + SPutSBuf(pst->region, pst->pool, (Data *)loadInfReq, + (Size)sizeof(*loadInfReq)); + RETVALUE(RFAILED); + } + } + else + { +#if (ERRCLASS & ERRCLS_ADD_RES) + RGSCHLOGERROR(instId, ERRCLS_INT_PAR, ERG008, + (ErrVal)rgSchCb[instId].rgrSap[spId].sapCfg.spId, + "Invalid SAP Id:RgUiRgrLoadInfReq failed\n"); +#endif + SPutSBuf(pst->region, pst->pool, (Data *)loadInfReq, + (Size)sizeof(*loadInfReq)); + RETVALUE(RFAILED); + } + + /* Handle configuration */ + ret = rgSCHGomHndlLoadInf(pst->region, pst->pool, + &rgSchCb[(pst->dstInst - RGSCH_INST_START)], spId, transId, + loadInfReq); + if (ret != ROK) + { + RLOG_ARG0(L_ERROR,DBG_INSTID,instId, + "Configuration Request Handling Failed"); + RETVALUE(RFAILED); + } + + RETVALUE(ROK); +} /* RgUiRgrLoadInfReq */ +/* LTE_ADV_FLAG_REMOVED_END */ + +/************** MAC SCH Interface **************/ +/** + * @brief Function for updating dedicated channel BO at scheduler from MAC. + * + * @details + * + * Function : rgMacSchDedBoUpdtReq + * + * This function shall be invoked whenever MAC gets staRsp from RLC + * Scheduler shall update BO in its dedicated logical channel control block. + * + * @param[in] Pst* pst + * @param[in] S16 cellSapId + * @param[in] RgInfDedBoRpt *boRpt + * @return S16 + * -# ROK + **/ +#ifdef ANSI +PUBLIC S16 RgMacSchDedBoUpdtReq +( +Pst* pst, +RgInfDedBoRpt *boRpt +) +#else +PUBLIC S16 RgMacSchDedBoUpdtReq(pst, boRpt) +Pst* pst; +RgInfDedBoRpt *boRpt; +#endif +{ + RgSchCellCb *cell; + RgSchUeCb *ue; +#ifdef SCH_STATS + RgSchCmnDlUe *dlUe; +#endif + + + Inst inst = (pst->dstInst - RGSCH_INST_START); + S16 cellSapId = boRpt->cellSapId; + + TRC3(RgMacSchDedBoUpdtReq) +/* + RLOG_ARG2(L_DEBUG,DBG_CELLID,boRpt->cellId,"rgMacSchDedBoUpdtReq():" + " boRpt->rnti = %u boRpt->lcId = %u",boRpt->rnti, boRpt->lcId); +*/ + /* No need to chk for cell being NULL as MAC wouldn't have found instance if + * it doesnt exist */ + cell = rgSchCb[inst].rgrSap[cellSapId].cell; + +#ifndef NO_ERRCLS + if (cell->cellId != boRpt->cellId) + { + /* Handle Cell fetch failure */ + RGSCHLOGERROR(inst, ERRCLS_INT_PAR,ERG009,(ErrVal)boRpt->cellId, + "rgMacSchDedBoUpdtReq(): Invalid cell Id"); + RETVALUE(RFAILED); + } +#endif + + /* Update Bo in the given logical channel of the UE */ + if ((ue = rgSCHDbmGetUeCb(cell, boRpt->rnti)) != NULLP) + { + RgSchDlLcCb *dlLc; + /* Honor BO Reports only from PCELL */ +#ifdef LTE_ADV + if (cell != ue->cell) + { + RETVALUE(RFAILED); + } +#endif + if ((dlLc = rgSCHDbmGetDlDedLcCb(ue, boRpt->lcId)) != NULLP) + { +#ifdef LTE_L2_MEAS + if(dlLc->lcType == CM_LTE_LCH_DTCH) + { + if((dlLc->bo == 0) &&(boRpt->bo != 0)) + { + /* UE is active */ + if(!(ue->qciActiveLCs[dlLc->qciCb->qci])) + { + dlLc->qciCb->dlUeCount++; + } + ue->qciActiveLCs[dlLc->qciCb->qci]++; + } + else if((dlLc->bo != 0) && (boRpt->bo == 0) && (dlLc->qciCb->dlUeCount)) + { + /* UE is inactive */ + if (ue->qciActiveLCs[dlLc->qciCb->qci]) + { + ue->qciActiveLCs[dlLc->qciCb->qci]--; + if (!(ue->qciActiveLCs[dlLc->qciCb->qci])) + { + dlLc->qciCb->dlUeCount--; + } + } + } + } +#endif +#ifdef SCH_STATS + dlUe = RG_SCH_CMN_GET_DL_UE(ue, cell); + if (boRpt->bo > dlLc->bo) + { + dlUe->boReported += (boRpt->bo - dlLc->bo); + } +#endif +#ifdef TENB_STATS + if (boRpt->bo > dlLc->bo) + { + ue->tenbStats->stats.nonPersistent.sch[RG_SCH_CELLINDEX(cell)].dlBo += ((boRpt->bo - dlLc->bo)<<3); + } +#endif + /* RLC provides cumulative BO for each LC. + * Reduce the left out unscheduled bo from total bo and + * update the new BO to the total bo */ + if(ue->totalBo >= dlLc->bo) + { + ue->totalBo -= dlLc->bo; + } + else + { + ue->totalBo = 0; /* this case should not arise + * Resetting for safety */ + } + + ue->totalBo += boRpt->bo; + dlLc->bo = boRpt->bo; + dlLc->oldestSduArrTime = boRpt->oldestSduArrTime; + dlLc->staPduBo = boRpt->staPduBo; + + dlLc->setMaxUlPrio = boRpt->setMaxUlPrio; + dlLc->setMaxDlPrio = boRpt->setMaxDlPrio; + /* Update the scheduler */ + rgSCHUtlDlDedBoUpd(cell, ue, dlLc); + RETVALUE(ROK); + } + } + RETVALUE(RFAILED); + +} /* end of rgMacSchDedBoUpdtReq */ + + +/** + * @brief Function for updating common channel BO at scheduler from MAC. + * + * @details + * + * Function : RgMacSchCmnBoUpdtReq + * + * This function shall be invoked whenever MAC gets staRsp from RLC + * Scheduler shall update BO in its common logical channel control block. + * + * @param[in] Pst* pst + * @param[in] S16 cellSapId + * @param[in] RgInfCmnBoRpt *boRpt + * @return S16 + * -# ROK + **/ +#ifdef ANSI +PUBLIC S16 RgMacSchCmnBoUpdtReq +( +Pst* pst, +RgInfCmnBoRpt *boRpt +) +#else +PUBLIC S16 RgMacSchCmnBoUpdtReq(pst, boRpt) +Pst* pst; +RgInfCmnBoRpt *boRpt; +#endif +{ + RgSchCellCb *cell; + Inst inst = (pst->dstInst - RGSCH_INST_START); + S16 cellSapId = boRpt->cellSapId; + + TRC3(RgMacSchCmnBoUpdtReq) + + /* No need to chk for cell being NULL as MAC would not have found instance if + * it doesnt exist */ + cell = rgSchCb[inst].rgrSap[cellSapId].cell; + if (cell->cellId != boRpt->cellId) + { + RLOG_ARG1(L_DEBUG,DBG_CELLID,cell->cellId,"RgMacSchCmnBoUpdtReq():" + "Invalid boRpt cell Id:%d",boRpt->cellId); + RETVALUE(RFAILED); + } + + /* handle status response on CCCH */ + if(boRpt->lcId == cell->dlCcchId) + { + RLOG_ARG0(L_DEBUG,DBG_CELLID,cell->cellId,"RgMacSchCmnBoUpdtReq():" + " BO update for CCCH"); + rgSCHUtlHndlCcchBoUpdt(cell, boRpt); + } + else + { + rgSCHUtlHndlBcchPcchBoUpdt(cell, boRpt); + } + + RETVALUE(ROK); +} /* end of RgMacSchCmnBoUpdtReq */ +/*Fix: start: Inform UE delete to scheduler*/ +/** + * @brief This API is used to send data indication to Scheduler instance from MAC. + * + * @details + * + * Function : rgMacSchUeDelInd + * + * This function shall be invoked whenever MAC gets Ue delete request. + * + * + * @param[in] Pst* pst + * @param[in] RgInfUeDelInd *ueDelInd + * @return S16 + * -# ROK + **/ +#ifdef ANSI +PUBLIC S16 RgMacSchUeDelInd +( +Pst* pst, +RgInfUeDelInd *ueDelInd +) +#else +PUBLIC S16 RgMacSchUeDelInd(pst, ueDelInd) +Pst* pst; +RgInfUeDelInd *ueDelInd; +#endif +{ + RgSchCellCb *cell; + Inst inst = (pst->dstInst - RGSCH_INST_START); + S16 cellSapId = ueDelInd->cellSapId; + CmLList *tmp; + RgSchRntiLnk *rntiLnk=NULL; + + TRC3(RgMacSchUeDelInd) + + if (rgSchCb[inst].rgrSap == NULLP || rgSchCb[inst].rgrSap[cellSapId].cell == NULLP) + { + RLOG_ARG0(L_ERROR,DBG_CELLID,ueDelInd->cellId,"rgrSap or cell is not configured"); + RETVALUE(ROK); + } + cell = rgSchCb[inst].rgrSap[cellSapId].cell; +#ifndef NO_ERRCLS + if (cell->cellId != ueDelInd->cellId) + { + /* Handle Cell fetch failure */ + RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId, + "rgMacSchUeDelInd(): Invalid ueDelInd cell Id:%d", + ueDelInd->cellId); + RETVALUE(ROK); + } +#endif + + CM_LLIST_FIRST_NODE(&cell->rntiDb.rntiGuardPool, tmp); + + while(tmp) + { + rntiLnk = (RgSchRntiLnk *)(tmp->node); + if(rntiLnk->rnti == ueDelInd->rnti) + { + cmLListDelFrm(&cell->rntiDb.rntiGuardPool, tmp); + tmp->node = NULLP; + rgSCHDbmRlsRnti(cell, rntiLnk); + RLOG_ARG2(L_DEBUG,DBG_CELLID,cell->cellId, + "RNTI:%d Released from the Guard pool(%ld)", + ueDelInd->rnti, cell->rntiDb.rntiGuardPool.count); + + break; + } + CM_LLIST_NEXT_NODE(&cell->rntiDb.rntiGuardPool, tmp); + } + +#ifdef EMTC_ENABLE + rgEmtcMacSchUeDelInd(cell,ueDelInd); +#endif + + if(tmp == NULLP) + { + /* Fix : syed HO UE does not have a valid ue->rntiLnk */ + RLOG_ARG2(L_INFO,DBG_CELLID,ueDelInd->cellId,"HO CRNTI:%d not present in the" + "Guard Pool:%ld", ueDelInd->rnti, cell->rntiDb.rntiGuardPool.count); + } + + RETVALUE(ROK); +} /* rgMacSchUeDelInd */ +/*Fix: end: Inform UE delete to scheduler*/ +/** + * @brief This API is used to send data indication to Scheduler instance from MAC. + * + * @details + * + * Function : rgMacSchSfRecpInd + * + * This function shall be invoked whenever MAC gets datInd on TFU + * Scheduler shall act on the CEs and data that are received as part of + * datInd. + * + * @param[in] Pst* pst + * @param[in] S16 cellSapId + * @param[in] CmLteRnti rnti + * @param[in] DatIndInfo *datInd + * @return S16 + * -# ROK + **/ +#ifdef ANSI +PUBLIC S16 RgMacSchSfRecpInd +( +Pst* pst, +RgInfSfDatInd *subfrmInfo +) +#else +PUBLIC S16 RgMacSchSfRecpInd(pst, subfrmInfo) +Pst* pst; +RgInfSfDatInd *subfrmInfo; +#endif +{ + S16 ret = RFAILED; + RgSchErrInfo err; + RgSchUeCb *ue; + RgInfUeDatInd *datInd; + RgSchCellCb *cell; + Inst inst = (pst->dstInst - RGSCH_INST_START); + CmLteRnti rnti; + CmLListCp *lnkLst; + CmLList *tmp; + S16 cellSapId = subfrmInfo->cellSapId; + RgrUeStaIndInfo *ueStaInd; +#ifdef RG_UNUSED +//#ifdef LTEMAC_SPS + RgSchCmnUlUeSpsInfo *ulSpsUe ; +#endif + /* RRM_RBC_X */ + U32 idx; + /* RRM_RBC_Y */ + +#ifdef LTE_L2_MEAS + U8 qci; + U16 datIndActQci = 0; + U16 combDatIndActQci = 0; /* Prev and Latest Dat Ind combined */ + U16 tempUeActQci = 0; /* UE specific Active QCIs */ + U16 diffBits = 0; + U8 lcCount; +#endif + TRC3(RgMacSchSfRecpInd) + + /* No need to chk for cell being NULL as MAC wouldn't have found instance if + * it doesnt exist */ + cell = rgSchCb[inst].rgrSap[cellSapId].cell; + + /* lnkLst assignment */ + lnkLst = &(subfrmInfo->ueLst); + + CM_LLIST_FIRST_NODE(lnkLst, tmp); + + while((NULLP != tmp) && ((RgInfUeDatInd *)tmp->node != NULLP)) + { + ue = NULLP; +#ifdef LTE_L2_MEAS + qci = 0; +#endif + datInd = (RgInfUeDatInd *)tmp->node; + rnti = datInd->rnti; + + /* We shall try and find + * out the RaCb based on the following - + * 1. If the incoming PDU contained a CCCH SDU i.e. this is message 3. + * 2. If the incoming PDU contained a CRNTI control element, i.e. we should + * have a ueCb also for this + */ + + /* It could be that a non-msg3 pdu contains a CRNTI Control element. We + * should check for CRNTI CE and if it exists the UECb must exist, also an + * if the CRNTI in the CE and the one with which the message came in are + * different we shall look for an raCb as well. + */ + if (datInd->ceInfo.bitMask & RGSCH_CRNTI_CE_PRSNT) + { + /* SR_RACH_STATS : CRNTI CE*/ + rgNumMsg3CrntiCE++; + + if (datInd->ceInfo.bitMask & RGSCH_CCCH_SDU_PRSNT) + { + RGSCH_FREE_MEM(subfrmInfo); + err.errType = RGSCHERR_TOM_DATIND; + RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId, + "Received MSG3 with CRNTI:%d and also CCCH ", + datInd->ceInfo.ces.cRnti); + RETVALUE(RFAILED); + } + ue = rgSCHDbmGetUeCb (cell, datInd->ceInfo.ces.cRnti); + if (ue == NULLP) + { + /* SR_RACH_STATS : CRNTI CE UECB NOT FOUND*/ + rgNumCrntiCeCrntiNotFound++; + /* ccpu00141318 - Removed condition for SPS rnti checking*/ + RGSCH_FREE_MEM(subfrmInfo); + err.errType = RGSCHERR_TOM_DATIND; + RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId, "Received MSG3 " + "with CRNTI:%d unable to find ueCb", + datInd->ceInfo.ces.cRnti); + RETVALUE(RFAILED); + } + + if ((ret = rgSCHUtlProcMsg3 (subfrmInfo, cell, ue, + rnti, datInd, &err)) != ROK) + { + RGSCH_FREE_MEM(subfrmInfo); + err.errType = RGSCHERR_TOM_DATIND; + RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId, "Processing for MSG3 failed for CRNTI:%d", + datInd->rnti); + RETVALUE(RFAILED); + } + +#ifdef LTEMAC_SPS + rgSCHUtlHdlCrntiCE (cell, ue); +#endif + ret = rgSCHUtlAllocSBuf (cell->instIdx,(Data**)&ueStaInd, + sizeof(RgrUeStaIndInfo)); + if(ret == ROK) + { + ueStaInd->status = RGR_UESTA_MAC_CRNTI_CE_RECVD; +#ifdef RG_UNUSED +//#ifdef LTEMAC_SPS + ulSpsUe = RG_SCH_CMN_GET_UL_SPS_UE(ue); + if(ulSpsUe->isUlSpsActv) + { + ueStaInd->status = RGR_UESTA_MAC_CRNTI_CE_RECVD_IN_SPS_ACTIVE; + ue->ul.ulSpsCfg.isLcSRMaskEnab = FALSE; + } +#endif + ret = rgSCHUtlFillSndUeStaInd(cell, ue, ueStaInd); + if(ret != ROK) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId, + "Could not Send Ue Sta Ind UEID:%d",ue->ueId); + } + } + CM_LLIST_NEXT_NODE(lnkLst, tmp); + continue; + } /* end of CRNTI based message */ + else if (datInd->ceInfo.bitMask & RGSCH_CCCH_SDU_PRSNT) + { + /* SR_RACH_STATS : CCCH SDU */ + rgNumMsg3CCCHSdu++; + /* SR_RACH_STATS : CCCH SDU RACB NOT FOUND*/ + if (NULLP == rgSCHDbmGetRaCb (cell, rnti)) + { + rgNumCCCHSduCrntiNotFound++; + } + + if ((ret = rgSCHUtlProcMsg3 (subfrmInfo, cell, ue, + rnti, datInd, &err)) != ROK) + { + RGSCH_FREE_MEM(subfrmInfo); + err.errType = RGSCHERR_TOM_DATIND; + RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,"Processing for MSG3 failed for CRNTI:%d", + datInd->rnti); + RETVALUE(RFAILED); + } + /* fix */ + CM_LLIST_NEXT_NODE(lnkLst, tmp); + continue; + } /* end of Msg3 processing */ + + if (ue == NULLP) + { + ue = rgSCHDbmGetUeCb (cell, datInd->rnti); + if (ue == NULLP) + { +#ifdef LTEMAC_SPS + if((ue = rgSCHDbmGetSpsUeCb (cell, datInd->rnti)) == NULLP) +#endif + { + RGSCH_FREE_MEM(subfrmInfo); + err.errType = RGSCHERR_TOM_DATIND; + RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,"Unable to get the UE CB for CRNTI:%d", + datInd->rnti); + RETVALUE(RFAILED); + } + } + } +/* L2_COUNTERS */ +#ifdef LTE_L2_MEAS + /* The LCs for which data is received at MAC is provided to SCH. + This information is used to estimate the Active LCs at UE + since estimates based on only BSR is not accurate */ + if (datInd->ceInfo.bitMask & RGSCH_ACTIVE_LC_PRSNT) + { + + /* Compose a Bitmask with for the QCI's for which Data + is received */ + for (lcCount = 0; lcCount < RGINF_MAX_NUM_DED_LC; lcCount++) + { + if ((datInd->ceInfo.ulActLCs[lcCount] == TRUE) && (TRUE == ue->ul.lcCb[lcCount].isValid)) + { + datIndActQci |= (1 << (ue->ul.lcCb[lcCount].qciCb->qci -1)); + } + } + if (ue->ulActiveLCs && ue->lastDatIndLCs) + { + /* Combine previous Dat Ind and current Dat Ind to + estimate active LCs at UE */ + combDatIndActQci = ue->lastDatIndLCs | datIndActQci; + tempUeActQci = ue->ulActiveLCs; + ue->ulActiveLCs = combDatIndActQci; + diffBits = combDatIndActQci ^ tempUeActQci; + while (diffBits) + { + qci++; + if (0x1 & diffBits) + { + if (0x1 & tempUeActQci) + { + /* An active QCI has become inactive */ + cell->qciArray[qci].ulUeCount--; + } + else + { + /* An Inactive QCI has become active */ + cell->qciArray[qci].ulUeCount++; + } + } + diffBits >>= 1; + tempUeActQci >>= 1; + } + } + ue->lastDatIndLCs = datIndActQci; + + } + +#endif /* LTE_L2_MEAS */ + /* Just copy the timing information from the dat indication into the one + * stored in the UE CB, will be later utilized to handle Timing advance + */ + + if ((ret = rgSCHUtlUpdSch (subfrmInfo, cell, ue, datInd, &err)) != ROK) + { + RGSCH_FREE_MEM(subfrmInfo); + err.errType = RGSCHERR_TOM_DATIND; + RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,"Unable to handle Data" + " Indication for UEID:%d",ue->ueId); + RETVALUE(RFAILED); + } + + CM_LLIST_NEXT_NODE(lnkLst, tmp); + } + /* RRM_RBC_X */ + /* update the UL PRB usage for all GBR QCIs*/ + for (idx = 0; idx < RGM_MAX_QCI_REPORTS; idx++) + { + cell->prbUsage.qciPrbRpts[idx].ulTotPrbUsed += subfrmInfo->qcisUlPrbCnt[idx]; + } + /* RRM_RBC_Y */ + + /* chk if Sch needs to dealloc datInd after unpk */ + RGSCH_FREE_MEM(subfrmInfo); + RETVALUE(ret); +} /* rgMacSchSfRecpInd */ + +#ifdef LTEMAC_SPS +/** + * @brief Function to handle relInd from MAC for a UE + * + * @details + * + * Function: RgMacSchSpsRelInd + * + * Handler for processing relInd for UL SPS of a UE + * + * Invoked by: + * MAC + * + * Processing Steps: + * + * @param[in] Pst *pst + * @param[in] RgInfSpsRelInfo *relInfo + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 RgMacSchSpsRelInd +( +Pst *pst, +RgInfSpsRelInfo *relInfo +) +#else +PUBLIC S16 RgMacSchSpsRelInd(pst, relInfo) +Pst *pst; +RgInfSpsRelInfo *relInfo; +#endif +{ + RgSchUeCb *ue; + RgSchCellCb *cell; + Inst inst = (pst->dstInst - RGSCH_INST_START); + + TRC2(RgMacSchSpsRelInd); + + /* No need to chk for cell being NULL as MAC wouldn't have found instance if + * it doesnt exist */ + cell = rgSchCb[inst].rgrSap[relInfo->cellSapId].cell; + + if ((ue = rgSCHDbmGetUeCb(cell, relInfo->cRnti)) == NULLP) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId, + "No Ue exists with CRNTI:%d",relInfo->cRnti); + RETVALUE(RFAILED); + } + + if ((rgSCHUtlSpsRelInd(cell, ue, relInfo->isExplRel)) != ROK) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId, + "RelInd processing for CRNTI:%d failed",relInfo->cRnti); + RETVALUE(RFAILED); + } + RETVALUE(ROK); +} /* end of RgMacSchSpsRelInd */ +#endif /* LTEMAC_SPS */ + +#ifdef LTE_L2_MEAS + +/** + * @brief Function to handle L2MeasCfm from MAC + * + * @details + * + * Function: RgMacSchL2MeasCfm + * + * Handler for processing L2 measurement confirm + * + * Invoked by: + * MAC + * + * Processing Steps: + * + * @param[in] Pst *pst + * @param[in] RgInfL2MeasCfm *measCfm + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 RgMacSchL2MeasCfm +( +Pst *pst, +RgInfL2MeasCfm *measCfm +) +#else +PUBLIC S16 RgMacSchL2MeasCfm(pst, measCfm) +Pst *pst; +RgInfL2MeasCfm *measCfm; +#endif +{ + RgSchCellCb *cell = NULLP; + Inst inst = (pst->dstInst - RGSCH_INST_START); + CmLList *lnk; + RgSchL2MeasCb *measCb = NULLP; + RgSchCb *instCb = &rgSchCb[inst]; + U32 idx; + LrgSchMeasCfmInfo schMeasCfm; + U8 qciVal; + U8 idx1; /*LTE_L2_MEAS_PHASE2*/ + U8 qciVal1; + TRC2(RgMacSchL2MeasCfm); + + /* Find the cellCb using cellId in measInfo. Iterate through all cells + * in rgrsapCb in RgschCb */ + for (idx = 0; idx < instCb->numSaps; idx++) + { + if ( instCb->rgrSap[idx].cell->cellId == measCfm->cellId) + { + /* got the cell break the loop */ + cell = instCb->rgrSap[idx].cell; + break; + } + } + /* If no cellCb return Err with Invalid Cell Id */ + if (cell == NULLP) + { + RLOG_ARG0(L_ERROR,DBG_CELLID,measCfm->cellId, + "Meas Cfm Failed.Invalid Cell Id"); + RETVALUE(RFAILED); + } + + + /* Iterate through all meas requests in l2mList in cellCb */ + lnk = cell->l2mList.first; + while(lnk != NULLP) + { + /* Get the MeasCb : RgSchL2MeasCb */ + measCb = (RgSchL2MeasCb *)lnk->node; + lnk = lnk->next; + if (measCb->measReq.hdr.transId == measCfm->transId) + { + break; + } + } + if ( measCb == NULLP ) + { + RETVALUE( RFAILED ); + } + + + if(measCfm->cfm.status != LCM_PRIM_OK) + { + for (idx = 0; idx < measCb->measReq.avgPrbQciUl.numQci; idx++) + { + qciVal = measCb->measReq.avgPrbQciUl.qci[idx]; + cell->qciArray[qciVal].qci = 0; + } + /* Delete this measCb, send the negative confirmation to + * stack manager */ + cmLListDelFrm(&cell->l2mList, &measCb->measLnk); + /* ccpu00117052 - MOD - Passing double pointer + for proper NULLP assignment*/ + rgSCHUtlFreeSBuf(cell->instIdx, (Data **)&measCb, sizeof(RgSchL2MeasCb)); + cmMemset((U8 *)&schMeasCfm, 0, sizeof(LrgSchMeasCfmInfo)); + schMeasCfm.measType = measCfm->measType; + schMeasCfm.cfm = measCfm->cfm; + schMeasCfm.hdr.transId = measCfm->transId; + schMeasCfm.cellId = measCfm->cellId; + RgMiLrgSchL2MeasCfm(&(instCb->rgSchInit.lmPst), &schMeasCfm); + RETVALUE(ROK); + } + for(idx = 0; idx < measCfm->u.prbCfm.numQci; idx++) + { + measCb->avgPrbQciUl.prbUsage[idx].prbUsage = measCfm->u.prbCfm.prbUsage[idx].prbUsage; + measCb->avgPrbQciUl.prbUsage[idx].qciValue = measCfm->u.prbCfm.prbUsage[idx].qciValue; + /*LTE_L2_MEAS_PHASE2*/ + qciVal1 = measCfm->u.prbCfm.prbUsage[idx].qciValue; + for(idx1=0;idx1measReq.avgPrbQciUl.numQci;idx1++) + { + if(measCb->measReq.avgPrbQciUl.qci[idx1] == qciVal1) + { + break; + } + } + if(idx1 == measCb->measReq.avgPrbQciUl.numQci) + { + measCb->measReq.avgPrbQciUl.qci[measCb->measReq.avgPrbQciUl.numQci++] = qciVal1; + } + } + measCb->avgPrbQciUl.numQci = measCfm->u.prbCfm.numQci; + measCb->cfmRcvd = TRUE; + cell->sndL2Meas = TRUE; + RETVALUE(ROK); +} /* end of RgMacSchL2MeasCfm */ + +/** + * @brief Function to handle L2MeasStopCfm from MAC + * + * @details + * + * Function: RgMacSchL2MeasStopCfm + * + * Handler for processing L2 measurement confirm + * + * Invoked by: + * MAC + * + * Processing Steps: + * + * @param[in] Pst *pst + * @param[in] RgInfL2MeasCfm *measCfm + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 RgMacSchL2MeasStopCfm +( +Pst *pst, +RgInfL2MeasCfm *measCfm +) +#else +PUBLIC S16 RgMacSchL2MeasStopCfm(pst, measCfm) +Pst *pst; +RgInfL2MeasCfm *measCfm; +#endif +{ + LrgSchMeasCfmInfo schMeasCfm; + Inst inst = (pst->dstInst - RGSCH_INST_START); + RgSchCb *instCb = &rgSchCb[inst]; + + TRC2(RgMacSchL2MeasStopCfm); + + cmMemset((U8 *)&schMeasCfm, 0, sizeof(LrgSchMeasCfmInfo)); + schMeasCfm.measType = measCfm->measType; + schMeasCfm.cfm = measCfm->cfm; + schMeasCfm.hdr.transId = measCfm->transId; + schMeasCfm.cellId = measCfm->cellId; + RgMiLrgSchL2MeasStopCfm(&(instCb->rgSchInit.lmPst), &schMeasCfm); + RETVALUE(ROK); +} +#endif + +/************** TFU Interface *************/ + +/** + * @brief Bind confirm API for TFU SAP on scheduler instance. + * + * @details + * + * Function : RgLiTfuSchBndCfm + * + * This API is invoked by PHY to confirm TFU SAP bind. + * + * + * @param[in] Pst *pst + * @param[in] SuId suId + * @param[in] U8 status + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 RgLiTfuSchBndCfm +( +Pst *pst, +SuId suId, +U8 status +) +#else +PUBLIC S16 RgLiTfuSchBndCfm(pst, suId, status) +Pst *pst; +SuId suId; +U8 status; +#endif +{ + S16 ret; + RgSchLowSapCb *tfuSap; + Inst instId = pst->dstInst - RGSCH_INST_START; + + TRC3(RgLiTfuSchBndCfm); + + + if(suId >= rgSchCb[instId].numSaps) + { + RLOG_ARG0(L_ERROR,DBG_INSTID,instId, "Incorrect SuId"); + RETVALUE(RFAILED); + } + /* Lets validate suId first */ + tfuSap = &(rgSchCb[instId].tfuSap[suId]); + + if (suId != tfuSap->sapCfg.suId) + { + RLOG_ARG2(L_ERROR,DBG_INSTID,instId, "Incorrect SuId. Configured (%d)" + "Recieved (%d)", tfuSap->sapCfg.suId, suId); + RETVALUE(RFAILED); + } + ret = rgSCHLmmBndCfm (pst, suId, status); + RETVALUE(ret); +} /* RgLiTfuSchBndCfm */ + +/** + * @brief Random Access Request indication from PHY. + * + * @details + * + * Function : RgLiTfuRaReqInd + * + * This API is invoked by PHY to send Random Access Request to Scheduler. + * This API contains information for Random Access Request including + * raRnti, list of associated RAPIDs and related information. + * + * @param[in] Pst *pst + * @param[in] SuId suId + * @param[in] TfuRaReqIndInfo *raReqInd + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 RgLiTfuRaReqInd +( +Pst *pst, +SuId suId, +TfuRaReqIndInfo *raReqInd +) +#else +PUBLIC S16 RgLiTfuRaReqInd(pst, suId, raReqInd) +Pst *pst; +SuId suId; +TfuRaReqIndInfo *raReqInd; +#endif +{ + S16 ret; + Inst inst = pst->dstInst-RGSCH_INST_START; + + TRC3(RgLiTfuRaReqInd); + + if ((ret = rgSCHUtlValidateTfuSap (inst, suId)) != ROK) + { + RLOG_ARG1(L_ERROR,DBG_INSTID,inst,"SAP Validation failed SuId(%d)", suId); + /* Free up the memory for the request structure */ + RGSCH_FREE_MEM(raReqInd); + RETVALUE(ret); + } + + if(raReqInd == NULLP) + { + RLOG_ARG0(L_ERROR,DBG_INSTID,inst,"Invalid input pointer for raReqInd Failed"); + RETVALUE(RFAILED); + } + + if (rgSchCb[inst].tfuSap[suId].cell == NULLP) + { + RLOG_ARG0(L_ERROR,DBG_CELLID,raReqInd->cellId,"No cell exists"); + RETVALUE(RFAILED); + } + + ret = rgSCHTomRaReqInd(rgSchCb[inst].tfuSap[suId].cell, raReqInd); + /* Free up the memory for the request structure */ + RGSCH_FREE_MEM(raReqInd); + /*SPutSBuf (pst->region, pst->pool, (Data *)raReqInd, + sizeof(TfuRaReqIndInfo)); */ + RETVALUE(ret); +} /* RgLiTfuRaReqInd */ + +/** + * @brief Uplink CQI indication from PHY. + * + * @details + * + * Function : RgLiTfuUlCqiInd + * + * This API is invoked by PHY to send Uplink CQI to Scheduler. + * This API contains Uplink CQI information reported per UE. + * + * @param[in] Pst *pst + * @param[in] SuId suId + * @param[in] TfuUlCqiIndInfo *ulCqiInd + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 RgLiTfuUlCqiInd +( +Pst *pst, +SuId suId, +TfuUlCqiIndInfo *ulCqiInd +) +#else +PUBLIC S16 RgLiTfuUlCqiInd(pst, suId, ulCqiInd) +Pst *pst; +SuId suId; +TfuUlCqiIndInfo *ulCqiInd; +#endif +{ + S16 ret; + Inst inst = pst->dstInst-RGSCH_INST_START; + + TRC3(RgLiTfuUlCqiInd); + + if ((ret = rgSCHUtlValidateTfuSap (inst, suId)) != ROK) + { + RLOG_ARG0(L_ERROR,DBG_INSTID,inst,"SAP Validation failed"); + /* Free up the memory for the request structure */ + RGSCH_FREE_MEM(ulCqiInd); + RETVALUE(ret); + } + + if (rgSchCb[inst].tfuSap[suId].cell == NULLP) + { + RLOG_ARG0(L_ERROR,DBG_INSTID,inst,"No cell exists"); + /* Free up the memory for the request structure */ + RGSCH_FREE_MEM(ulCqiInd); + RETVALUE(RFAILED); + } + ret = rgSCHTomUlCqiInd (rgSchCb[inst].tfuSap[suId].cell, ulCqiInd); + /* Free up the memory for the request structure */ + RGSCH_FREE_MEM(ulCqiInd); + RETVALUE(ret); +} /* RgLiTfuUlCqiInd */ + +/** + * @brief PUCCH power adjustment indication. + * + * @details + * + * Function : RgLiTfuPucchDeltaPwrInd + * + * This API is invoked by PHY to send PUCCH power adjustment + * indication. + * + * @param[in] Pst *pst + * @param[in] SuId suId + * @param[in] TfuPucchDeltaPwrIndInfo *pucchDeltaPwr + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 RgLiTfuPucchDeltaPwrInd +( +Pst *pst, +SuId suId, +TfuPucchDeltaPwrIndInfo *pucchDeltaPwr +) +#else +PUBLIC S16 RgLiTfuPucchDeltaPwrInd(pst, suId, pucchDeltaPwr) +Pst *pst; +SuId suId; +TfuPucchDeltaPwrIndInfo *pucchDeltaPwr; +#endif +{ + S16 ret; + Inst inst = pst->dstInst-RGSCH_INST_START; + + TRC3(RgLiTfuPucchDeltaPwrInd); + + if ((ret = rgSCHUtlValidateTfuSap (inst, suId)) != ROK) + { + RLOG_ARG0(L_ERROR,DBG_INSTID,inst,"SAP Validation failed"); + /* Free up the memory for the request structure */ + RGSCH_FREE_MEM(pucchDeltaPwr); + RETVALUE(ret); + } + + if (rgSchCb[inst].tfuSap[suId].cell == NULLP) + { + RLOG_ARG0(L_ERROR,DBG_INSTID,inst,"No cell exists"); + RETVALUE(RFAILED); + } + ret = rgSCHTomPucchDeltaPwrInd (rgSchCb[inst].tfuSap[suId].cell, pucchDeltaPwr); + /* Free up the memory for the request structure */ + RGSCH_FREE_MEM(pucchDeltaPwr); + RETVALUE(ret); +} /* RgLiTfuPucchDeltaPwrInd */ + + +/** + * @brief HARQ ACK indication from PHY for Downlink transmissions. + * + * @details + * + * Function : RgLiTfuHqInd + * + * This API is invoked by PHY to send HARQ ACK information to Scheduler + * on recieving HARQ ACK/NACK from UEs. + * This API contains HARQ ACK information recieved by PHY for downlink + * transmissions. + * + * @param[in] Pst *pst + * @param[in] SuId suId + * @param[in] TfuHqIndInfo *harqAckInd + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 RgLiTfuHqInd +( +Pst *pst, +SuId suId, +TfuHqIndInfo *harqAckInd +) +#else +PUBLIC S16 RgLiTfuHqInd(pst, suId, harqAckInd) +Pst *pst; +SuId suId; +TfuHqIndInfo *harqAckInd; +#endif +{ + S16 ret; + Inst inst = (pst->dstInst - RGSCH_INST_START); + + TRC3(RgLiTfuHqInd); + +#ifndef NO_ERRCLS + if ((ret = rgSCHUtlValidateTfuSap (inst, suId)) != ROK) + { + RLOG_ARG0(L_ERROR,DBG_INSTID,inst,"SAP Validation failed"); + RGSCH_FREE_MEM(harqAckInd); + RETVALUE(ret); + } + + if (rgSchCb[inst].tfuSap[suId].cell == NULLP) + { + RLOG_ARG0(L_ERROR,DBG_INSTID,inst,"No cell exists"); + RETVALUE(RFAILED); + } +#endif + + /* Now call the TOM (Tfu ownership module) primitive to process further */ + ret = rgSCHTomHarqAckInd (rgSchCb[inst].tfuSap[suId].cell, harqAckInd); + /* Free up the memory for the request structure */ + RGSCH_FREE_MEM(harqAckInd); + RETVALUE(ret); +} /* RgLiTfuHqInd */ + + +/** + * @brief Scheduling request(SR) indication from PHY for an UE. + * + * @details + * + * Function : RgLiTfuSrInd + * + * This API is invoked by PHY to send Scheduling request information to + * Scheduler on recieving SR from a list of UEs. + * This API contains scheduling request information recieved by PHY for UEs. + * + * @param[in] Pst *pst + * @param[in] SuId suId + * @param[in] TfuSrIndInfo *srInd + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 RgLiTfuSrInd +( +Pst *pst, +SuId suId, +TfuSrIndInfo *srInd +) +#else +PUBLIC S16 RgLiTfuSrInd(pst, suId, srInd) +Pst *pst; +SuId suId; +TfuSrIndInfo *srInd; +#endif +{ + S16 ret; + Inst inst = pst->dstInst-RGSCH_INST_START; + + TRC3(RgLiTfuSrInd); + +#ifndef NO_ERRCLS + if ((ret = rgSCHUtlValidateTfuSap (inst, suId)) != ROK) + { + RLOG_ARG0(L_ERROR,DBG_INSTID,inst,"() SAP Validation failed"); + RGSCH_FREE_MEM(srInd); + RETVALUE(ret); + } + + if (rgSchCb[inst].tfuSap[suId].cell == NULLP) + { + RLOG_ARG0(L_ERROR,DBG_INSTID,inst,"RgLiTfuSrInd()No cell exists"); + RETVALUE(RFAILED); + } +#endif + /* Now call the TOM (Tfu ownership module) primitive to process further */ + ret = rgSCHTomSrInd (rgSchCb[inst].tfuSap[suId].cell, srInd); + /* Free up the memory for the request structure */ + RGSCH_FREE_MEM(srInd); + RETVALUE(ret); +} /* RgLiTfuSrInd */ + + +/** + * @brief Downlink CQI indication from PHY for an UE. + * + * @details + * + * Function : RgLiTfuDlCqiInd + * + * This API is invoked by PHY to send Downlink CQI indication to Scheduler + * on recieving downlink CQI from UE. + * This API contains downlink CQI information recieved by PHY for an UE. + * + * @param[in] Pst *pst + * @param[in] SuId suId + * @param[in] TfuDlCqiIndInfo *dlCqiInd + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 RgLiTfuDlCqiInd +( +Pst *pst, +SuId suId, +TfuDlCqiIndInfo *dlCqiInd +) +#else +PUBLIC S16 RgLiTfuDlCqiInd(pst, suId, dlCqiInd) +Pst *pst; +SuId suId; +TfuDlCqiIndInfo *dlCqiInd; +#endif +{ + S16 ret; + Inst inst = pst->dstInst-RGSCH_INST_START; + + TRC3(RgLiTfuDlCqiInd); + + if ((ret = rgSCHUtlValidateTfuSap (inst, suId)) != ROK) + { + RLOG_ARG0(L_ERROR,DBG_INSTID,inst," SAP Validation failed"); + /* Free up the memory for the request structure */ + RGSCH_FREE_MEM(dlCqiInd); + RETVALUE(ret); + } + + if (rgSchCb[inst].tfuSap[suId].cell == NULLP) + { + RLOG_ARG0(L_ERROR,DBG_INSTID,inst,"No cell exists"); + RETVALUE(RFAILED); + } + ret = rgSCHTomDlCqiInd (rgSchCb[inst].tfuSap[suId].cell, dlCqiInd); + /* Free up the memory for the request structure */ + RGSCH_FREE_MEM(dlCqiInd); + RETVALUE(ret); +} /* RgLiTfuDlCqiInd */ +#ifdef TFU_UPGRADE + +/** + * @brief Raw CQI indication from PHY for an UE. + * + * @details + * + * Function : RgLiTfuRawCqiInd + * + * This API is invoked by PHY to send Raw CQI indication to Scheduler + * on receiving Raw CQI from UE. + * This API contains Raw CQI information recieved by PHY for an UE. + * + * @param[in] Pst *pst + * @param[in] SuId suId + * @param[in] TfuRawCqiIndInfo *rawCqiInd + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 RgLiTfuRawCqiInd +( +Pst *pst, +SuId suId, +TfuRawCqiIndInfo *rawCqiInd +) +#else +PUBLIC S16 RgLiTfuRawCqiInd(pst, suId, rawCqiInd) +Pst *pst; +SuId suId; +TfuRawCqiIndInfo *rawCqiInd; +#endif +{ + S16 ret; + Inst inst = pst->dstInst-RGSCH_INST_START; + + TRC3(RgLiTfuRawCqiInd); + +#ifdef NO_ERRCLS + if ((ret = rgSCHUtlValidateTfuSap (inst, suId)) != ROK) + { + RLOG_ARG0(L_ERROR,DBG_INSTID,inst,"SAP Validation failed"); + /* Free up the memory for the request structure */ + RGSCH_FREE_MEM(rawCqiInd); + RETVALUE(ret); + } + + if (rgSchCb[inst].tfuSap[suId].cell == NULLP) + { + RLOG_ARG0(L_ERROR,DBG_INSTID,inst," No cell exists"); + RETVALUE(RFAILED); + } +#endif + ret = rgSCHTomRawCqiInd (rgSchCb[inst].tfuSap[suId].cell, rawCqiInd); + /* Free up the memory for the request structure */ + RGSCH_FREE_MEM(rawCqiInd); + RETVALUE(ret); +} /* RgLiTfuRawCqiInd */ + +/** + * @brief SRS indication from PHY for an UE. + * + * @details + * + * Function : RgLiTfuSrsInd + * + * This API is invoked by PHY to send UL SRS indication to Scheduler + * on receiving a SRS from UE. + * This API contains SRS information recieved by PHY for an UE. + * + * @param[in] Pst *pst + * @param[in] SuId suId + * @param[in] TfuSrsIndInfo *srsInd + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 RgLiTfuSrsInd +( +Pst *pst, +SuId suId, +TfuSrsIndInfo *srsInd +) +#else +PUBLIC S16 RgLiTfuSrsInd(pst, suId, srsInd) +Pst *pst; +SuId suId; +TfuSrsIndInfo *srsInd; +#endif +{ + S16 ret; + Inst inst = pst->dstInst-RGSCH_INST_START; + + TRC3(RgLiTfuSrsInd); + + if ((ret = rgSCHUtlValidateTfuSap (inst, suId)) != ROK) + { + RLOG_ARG0(L_ERROR,DBG_INSTID,inst," SAP Validation failed"); + /* Free up the memory for the request structure */ + RGSCH_FREE_MEM(srsInd); + RETVALUE(ret); + } + + if (rgSchCb[inst].tfuSap[suId].cell == NULLP) + { + RLOG_ARG0(L_ERROR,DBG_INSTID,inst,"No cell exists"); + RETVALUE(RFAILED); + } + ret = rgSCHTomSrsInd (rgSchCb[inst].tfuSap[suId].cell, srsInd); + /* Free up the memory for the request structure */ + RGSCH_FREE_MEM(srsInd); + RETVALUE(ret); +} /* RgLiTfuSrsInd */ + +#endif + +/** + * @brief DOA indication from PHY for an UE. + * + * @details + * + * Function : RgLiTfuDoaInd + * + * This API is invoked by PHY to send Direction Of Arrival to Scheduler + * on calculating DOA at PHYSICAL LAYER for an UE. + * This API contains DOA information calculated by PHY for an UE. + * + * @param[in] Pst *pst + * @param[in] SuId suId + * @param[in] TfuDoaIndInfo *doaInd + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 RgLiTfuDoaInd +( +Pst *pst, +SuId suId, +TfuDoaIndInfo *doaInd +) +#else +PUBLIC S16 RgLiTfuDoaInd(pst, suId, doaInd) +Pst *pst; +SuId suId; +TfuDoaIndInfo *doaInd; +#endif +{ + S16 ret; + Inst inst = pst->dstInst-RGSCH_INST_START; + + TRC2(RgLiTfuDoaInd); + + if ((ret = rgSCHUtlValidateTfuSap (inst, suId)) != ROK) + { + RLOG_ARG0(L_ERROR,DBG_INSTID,inst,"SAP Validation failed"); + /* Free up the memory for the request structure */ + RGSCH_FREE_MEM(doaInd); + RETVALUE(ret); + } + + if (rgSchCb[inst].tfuSap[suId].cell == NULLP) + { + RLOG_ARG0(L_ERROR,DBG_INSTID,inst,"No cell exists"); + RETVALUE(RFAILED); + } + ret = rgSCHTomDoaInd (rgSchCb[inst].tfuSap[suId].cell, doaInd); + /* Free up the memory for the request structure */ + RGSCH_FREE_MEM(doaInd); + RETVALUE(ret); +} /* RgLiTfuDlCqiInd */ + +/** + * @brief CRC indication from PHY. + * + * @details + * + * Function : RgLiTfuCrcInd + * + * This API is invoked by PHY to give CRC indication to scheduler. + * + * @param[in] Pst *pst + * @param[in] SuId suId + * @param[in] TfuCrcIndInfo *crcInd + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 RgLiTfuCrcInd +( +Pst *pst, +SuId suId, +TfuCrcIndInfo *crcInd +) +#else +PUBLIC S16 RgLiTfuCrcInd (pst, suId, crcInd) +Pst *pst; +SuId suId; +TfuCrcIndInfo *crcInd; +#endif +{ + S16 ret; + Inst inst = pst->dstInst-RGSCH_INST_START; + + TRC3(RgLiTfuCrcInd); +#ifdef XEON_SPECIFIC_CHANGES +struct timeval start6, end6; +gettimeofday(&start6, NULL); +#endif +#ifndef NO_ERRCLS + if ((ret = rgSCHUtlValidateTfuSap (inst, suId)) != ROK) + { + RLOG_ARG0(L_ERROR,DBG_INSTID,inst,"SAP Validation failed"); + RGSCH_FREE_MEM(crcInd); + RETVALUE(ret); + } + + if (rgSchCb[inst].tfuSap[suId].cell == NULLP) + { + RLOG_ARG0(L_ERROR,DBG_INSTID,inst,"No cell exists"); + RETVALUE(RFAILED); + } +#endif + + /* Now call the TOM (Tfu ownership module) primitive to process further */ + ret = rgSCHTomCrcInd(rgSchCb[inst].tfuSap[suId].cell, crcInd); + /* Free up the memory for the request structure */ + RGSCH_FREE_MEM(crcInd); +#ifdef XEON_SPECIFIC_CHANGES +gettimeofday(&end6, NULL); +#endif + RETVALUE(ret); +} /* RgLiTfuCrcInd */ + +/** + * @brief Timing Advance indication from PHY. + * + * @details + * + * Function : RgLiTfuTimingAdvInd + * + * This API is invoked by PHY to indicate timing advance to Scheduler for + * an UE. + * + * @param[in] Pst *pst + * @param[in] SuId suId + * @param[in] TfuTimingAdvIndInfo *timingAdvInd + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 RgLiTfuTimingAdvInd +( +Pst *pst, +SuId suId, +TfuTimingAdvIndInfo *timingAdvInd +) +#else +PUBLIC S16 RgLiTfuTimingAdvInd(pst, suId, timingAdvInd) +Pst *pst; +SuId suId; +TfuTimingAdvIndInfo *timingAdvInd; +#endif +{ + S16 ret; + Inst inst = pst->dstInst-RGSCH_INST_START; + + TRC3(RgLiTfuTimingAdvInd); + + if ((ret = rgSCHUtlValidateTfuSap (inst, suId)) != ROK) + { + RLOG_ARG0(L_ERROR,DBG_INSTID,inst,"SAP Validation failed"); + /* Free up the memory for the request structure */ + RGSCH_FREE_MEM(timingAdvInd); + RETVALUE(ret); + } + + if (rgSchCb[inst].tfuSap[suId].cell == NULLP) + { + RLOG_ARG0(L_ERROR,DBG_INSTID,inst,"No cell exists"); + RETVALUE(RFAILED); + } + /* Now call the TOM (Tfu ownership module) primitive to process further */ + ret = rgSCHTomTimingAdvInd(rgSchCb[inst].tfuSap[suId].cell, timingAdvInd); + /* Free up the memory for the request structure */ + RGSCH_FREE_MEM(timingAdvInd); + RETVALUE(ret); +} /* RgLiTfuTimingAdvInd */ + + +/** + * @brief Transmission time interval indication from PHY. + * + * @details + * + * Function : RgLiTfuSchTtiInd + * + * This API is invoked by PHY to indicate TTI indication to Scheduler for + * a cell. + * + * @param[in] Pst *pst + * @param[in] SuId suId + * @param[in] TfuTtiIndInfo *ttiInd + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 RgLiTfuSchTtiInd +( +Pst *pst, +SuId suId, +TfuTtiIndInfo *ttiInd +) +#else +PUBLIC S16 RgLiTfuSchTtiInd(pst, suId, ttiInd) +Pst *pst; +SuId suId; +TfuTtiIndInfo *ttiInd; +#endif +{ + S16 ret = ROK; + Inst inst = pst->dstInst-RGSCH_INST_START; + + TRC3(RgLiTfuSchTtiInd); + + + /* Removing the validation with every TTI - for optimization */ +#ifndef NO_ERRCLS + if ((ret = rgSCHUtlValidateTfuSap (inst, suId)) != ROK) + { + RLOG_ARG0(L_ERROR,DBG_INSTID,inst,"SAP Validation failed"); + RETVALUE(ret); + } +#endif + /* Moved check for cell outside ERRCLS*/ + + /* Now call the TOM (Tfu ownership module) primitive to process further */ + rgSCHTomTtiInd(ttiInd, inst); + + RETVALUE(ret); +} /* RgLiTfuSchTtiInd */ + +/************* RGM Interface ****************/ +/** + * @brief API for bind request from RRM towards MAC. + * + * @details + * + * Function: RgUiRgmBndReq + * + * This API is invoked by RRM towards MAC to bind RGM SAP. + * These API validates the Pst, spId, suId and sends the bind confirm to + * RRM. + * + * + * @param[in] Pst *pst + * @param[in] SuId suId + * @param[in] SpId spId + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 RgUiRgmBndReq +( +Pst *pst, +SuId suId, +SpId spId +) +#else +PUBLIC S16 RgUiRgmBndReq(pst, suId, spId) +Pst *pst; +SuId suId; +SpId spId; +#endif +{ + S16 ret = ROK; + Pst tmpPst; /* Temporary Post Structure */ + Inst instId = pst->dstInst-RGSCH_INST_START; + + TRC3(RgUiRgmBndReq) + + + tmpPst.prior = pst->prior; + tmpPst.route = pst->route; + tmpPst.selector = pst->selector; + tmpPst.region = rgSchCb[instId].rgSchInit.region; + tmpPst.pool = rgSchCb[instId].rgSchInit.pool; + + tmpPst.srcProcId = rgSchCb[instId].rgSchInit.procId; + tmpPst.srcEnt = rgSchCb[instId].rgSchInit.ent; + tmpPst.srcInst = rgSchCb[instId].rgSchInit.inst + RGSCH_INST_START; + + tmpPst.event = EVTNONE; + + tmpPst.dstProcId = pst->srcProcId; + tmpPst.dstEnt = pst->srcEnt; + tmpPst.dstInst = pst->srcInst; + + /*TODO remove follo statement*/ + rgSchCb[instId].rgmSap[spId].sapSta.sapState = LRG_UNBND; + + if(spId < rgSchCb[instId].numSaps) + { + /* Check the state of the SAP */ + switch (rgSchCb[instId].rgmSap[spId].sapSta.sapState) + { + /* This case might not be needed if SAP not configured then it will go + * to else of above if condition */ + case LRG_UNBND: /* SAP is not bound */ + RLOG0(L_DEBUG,"SAP is not yet bound"); + rgSchCb[instId].rgmSap[spId].sapSta.sapState = LRG_BND; + rgSchCb[instId].rgmSap[spId].sapCfg.suId = suId; + /* Send Bind Confirm with status as SUCCESS */ + ret = rgSCHUtlRgmBndCfm(instId, suId, CM_BND_OK); + /*Indicate to Layer manager */ + break; + case LRG_BND: /* SAP is already bound*/ + RLOG0(L_DEBUG,"SAP is already bound"); + ret = rgSCHUtlRgmBndCfm(instId, suId, CM_BND_OK); + break; + default: /* Should Never Enter here */ +#if (ERRCLASS & ERRCLS_ADD_RES) + RGSCHLOGERROR(instId, ERRCLS_INT_PAR, ERG001, + (ErrVal)rgSchCb[instId].rgmSap[spId].sapSta.sapState, + "Invalid SAP State:RgUiRgmBndReq failed\n"); +#endif + ret = rgSCHUtlRgmBndCfm(instId, suId, CM_BND_NOK); + break; + } + } + else + { +#if (ERRCLASS & ERRCLS_ADD_RES) +/* ccpu00117035 - MOD - Changed ErrVal argument from accessing sap state + to spId to avoid seg fault due to invalid sapID */ + RGSCHLOGERROR(instId, ERRCLS_INT_PAR, ERG002, + (ErrVal)spId, "Invalid SAP Id:RgUiRrmBndReq failed\n"); +#endif + ret = RgUiRgmBndCfm(&tmpPst, suId, CM_BND_NOK); + } + RETVALUE(ret); +} /* RgUiRgmBndReq */ + +/** + * @brief API for unbind request from RRM towards MAC. + * + * @details + * + * Function: RgUiRgmUbndReq + * + * This API is invoked by RRM towards MAC to unbind RGM SAP. + * These API validates the Pst, spId, suId and transfers the unbind request + * specific information to corresponding ownership module (GOM) API. + * + * + * @param[in] Pst *pst + * @param[in] SuId suId + * @param[in] Reason reason + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 RgUiRgmUbndReq +( +Pst *pst, +SpId spId, +Reason reason +) +#else +PUBLIC S16 RgUiRgmUbndReq(pst, spId, reason) +Pst *pst; +SpId spId; +Reason reason; +#endif +{ + Inst instId = pst->dstInst-RGSCH_INST_START; + TRC3(RgUiRgmUbndReq) + + + /* SAP Id validation */ + if (spId < rgSchCb[instId].numSaps) + { + switch(rgSchCb[instId].rgmSap[spId].sapSta.sapState) + { + case LRG_BND: /* SAP is already bound*/ + /* setting SAP state to UN BOUND */ + RLOG0(L_DEBUG,"SAP is already bound"); + rgSchCb[instId].rgmSap[spId].sapSta.sapState = LRG_UNBND; + break; + default: +#if (ERRCLASS & ERRCLS_ADD_RES) + RGSCHLOGERROR(instId, ERRCLS_INT_PAR, ERG003, + (ErrVal)rgSchCb[instId].rgmSap[spId].sapSta.sapState, + "Invalid SAP State: RgUiRgmUbndReq failed\n"); +#endif + RETVALUE(RFAILED); + } + } + else + { +#if (ERRCLASS & ERRCLS_ADD_RES) + RGSCHLOGERROR(instId,ERRCLS_INT_PAR, ERG004, + (ErrVal)rgSchCb[instId].rgmSap[spId].sapSta.sapState, + "Invalid SAP Id:RgUiRgmUbndReq failed\n"); +#endif + RETVALUE(RFAILED); + } + RETVALUE(ROK); +} /* RgUiRgmUbndReq */ + + +/** + * @brief API for start or stop PRB reporting from RRM towards MAC. + * + * @details + * + * Function: RgUiRgmCfgPrbRprt + * + * This API is invoked by RRM towards MAC to start or stop calculating + * Average PRB usage in downlink and uplink. The average PRB usage will + * be reported to RRM based on confiured periodicity. + * + * + * @param[in] Pst *pst + * @param[in] SuId suId + * @param[in] SpId spId + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 RgUiRgmCfgPrbRprt +( +Pst *pst, +SpId spId, +RgmPrbRprtCfg *prbRprtCfg +) +#else +PUBLIC S16 RgUiRgmCfgPrbRprt(pst, spId, prbRprtCfg) +Pst *pst; +SpId spId; +RgmPrbRprtCfg *prbRprtCfg; +#endif +{ +/* Initalize*/ + RgSchCellCb *cell; + RgSchPrbUsage *prbUsage; + Inst inst = (pst->dstInst - RGSCH_INST_START); + + TRC2(RgUiRgmCfgPrbRprt); + cell = rgSchCb[inst].rgmSap[spId].cell; + prbUsage = &cell->prbUsage; + prbUsage->prbRprtEnabld = prbRprtCfg->bConfigType; + prbUsage->rprtPeriod = prbRprtCfg->usPrbAvgPeriodicty; + RG_SCH_ADD_TO_CRNT_TIME(cell->crntTime, prbUsage->startTime, 1); + + /* clear the qciPrbRpts for all GBR QCIs */ + cmMemset((U8*)&prbUsage->qciPrbRpts[0], 0, + (RGM_MAX_QCI_REPORTS * sizeof(RgSchQciPrbUsage))); + + RLOG_ARG2(L_DEBUG,DBG_CELLID,cell->cellId, + "RgUiRgmCfgPrbRprt config type %d with the report period %d", + prbUsage->prbRprtEnabld,prbUsage->rprtPeriod); + + /* ccpu00134393 : mem leak fix */ + SPutSBuf(pst->region, pst->pool, (Data *)prbRprtCfg, sizeof(RgmPrbRprtCfg)); + + RETVALUE(ROK); +} +/** + * @brief ERROR INDICATION from PHY for the i failed unlicensed Scell transmission. + * + * @details + * + * Function : RgLiTfuErrInd + * + * This API is invoked by PHY to send ERROR INDICATION to scheduler + * Currently invoked in the cases when the Unlicensed SCell transmission + * fails. + * This API contains the Cell and subframe information for which the + * transmission failed. + * + * @param[in] Pst *pst + * @param[in] SuId suId + * @param[in] TfuErrIndInfo *errIndInfo + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 RgLiTfuErrInd +( +Pst *pst, +SuId suId, +TfuErrIndInfo *errInd +) +#else +PUBLIC S16 RgLiTfuErrInd(pst, suId, errInd) +Pst *pst; +SuId suId; +TfuErrIndInfo *errInd; +#endif +{ + S16 ret = ROK; +#ifdef LTE_ADV + Inst inst = (pst->dstInst - RGSCH_INST_START); +#endif + + TRC3(RgLiTfuErrInd); + +#ifndef NO_ERRCLS + if ((ret = rgSCHUtlValidateTfuSap (inst, suId)) != ROK) + { + + RLOG_ARG0(L_ERROR,DBG_INSTID,inst,"SAP Validation failed"); + RETVALUE(ret); + } + + if (rgSchCb[inst].tfuSap[suId].cell == NULLP) + { + RLOG_ARG0(L_ERROR,DBG_INSTID,inst,"No cell exists"); + RETVALUE(RFAILED); + } +#endif + +#ifdef LTE_ADV + /* Now call the TOM (Tfu ownership module) primitive to process further */ + ret = rgSCHLaaErrInd(rgSchCb[inst].tfuSap[suId].cell, errInd); +#endif + RETVALUE(ret); +} /* RgLiTfuErrInd */ + + + +/********************************************************************** + + End of file +**********************************************************************/ diff --git a/src/5gnrmac/rg_sch.h b/src/5gnrmac/rg_sch.h new file mode 100755 index 000000000..ede35a8f0 --- /dev/null +++ b/src/5gnrmac/rg_sch.h @@ -0,0 +1,1507 @@ +/******************************************************************************* +################################################################################ +# Copyright (c) [2017-2019] [Radisys] # +# # +# 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. # +################################################################################ +*******************************************************************************/ + +/********************************************************************** + + Name: RRC layer + + Type: C include file + + Desc: Defines required by LTE-MAC + + File: rg_sch.h + +**********************************************************************/ + +#ifndef __RGSCH__ +#define __RGSCH__ + +#define RGSCHLAYERNAME "MAC Scheduler" +#ifdef RG_5GTF +#define MAX_5GTF_CELL 8 +#define MAX_5GTF_GROUP 1 +#define MAX_5GTF_BEAMS 4 +#define MAX_5GTF_SUBFRAME_INFO 10 +#define MAX_5GTF_VRBG_SIZE 4 +#define MAX_5GTF_PRBS 100 +#define MAX_5GTF_MCS 15 +#define MAX_5GTF_VRBG 25 +#define MAX_5GTF_TB_SIZE 66392 +/* Total number of UEs scheduled per cell in a subframe */ +#define MAX_5GTF_UE_SCH 4 +#define MAX_5GTF_DCIA1B1_SIZE 60 +#define MAX_5GTF_XPUSCH_RANGE 2 +#endif +/* This variables must moved into cell context finally. Since this requires replacing + * all macros in the code with these cell specific variables, this will taken as part of + * delta cleanup activity in MAC. Untill then, since we only support one cell, this should be fine + */ +#ifdef RG_SCH_DYNDLDELTA +#define RGSCH_UPDATE_DELTA(_inst, delta)\ +{\ +rgSchCb[_inst].rgSchDlDelta = RG_ENV_DL_DELTA + delta;\ +rgSchCb[_inst].rgSchCmnDlDelta = RG_ENV_SCH_CMN_DL_DELTA + delta;\ +rgSchCb[_inst].rgSchUlDelta = TFU_ENV_HQFBKIND_ULDELTA + delta;\ +} +#else +#define RGSCH_UPDATE_DELTA(_inst, delta) +#endif + +#ifdef RG_SCH_DYNDLDELTA +/* 4UE_TTI_DELTA */ +#ifdef CA_PHY_BRDCM_61765 +#define RG_DL_DELTA rgSchCb[1].rgSchDlDelta +#define RG_SCH_CMN_DL_DELTA (rgSchCb[1].rgSchCmnDlDelta) +#define TFU_HQFBKIND_ULDELTA (rgSchCb[1].rgSchUlDelta) +#else +#define RG_DL_DELTA rgSchCb[0].rgSchDlDelta +#define RG_SCH_CMN_DL_DELTA (rgSchCb[0].rgSchCmnDlDelta) +#define TFU_HQFBKIND_ULDELTA (rgSchCb[0].rgSchUlDelta) +#endif +#else +#ifdef SPLIT_RLC_DL_TASK +#define RG_DL_DELTA (RG_ENV_DL_DELTA + 1 ) +#define RG_SCH_CMN_DL_DELTA (RG_ENV_SCH_CMN_DL_DELTA + 1) +#define TFU_HQFBKIND_ULDELTA (TFU_ENV_HQFBKIND_ULDELTA + 1) +#else +#define RG_DL_DELTA RG_ENV_DL_DELTA +#define RG_SCH_CMN_DL_DELTA RG_ENV_SCH_CMN_DL_DELTA +#define TFU_HQFBKIND_ULDELTA TFU_ENV_HQFBKIND_ULDELTA +#endif +#endif + +/* Tunable parameter */ +#define RGSCH_MAX_NUM_DED_LC 10 /* maximum dedicated logical channels in a UE */ +#define RGSCH_MAX_NUM_CMN_LC 5 /* maximum number of common logical + channels in a cell */ +#define RG_SCH_LCG0 0 +#define RG_SCH_QCI5 5 +#define RGSCH_MAX_LCG_PER_UE 4 +#define RGSCH_CON_RES_ID_SZ 6 +#ifdef LTE_TDD +#define RGSCH_MAX_RA_RNTI 60 +#else +#define RGSCH_MAX_RA_RNTI 10 +#define RGSCH_RAREQ_ARRAY_SIZE (2*RGSCH_MAX_RA_RNTI) +#endif + +#define RGSCH_MAX_RAPID 64 /* XXX: For RACH Module */ +/* Below two temps added by nagaraja S */ +#define RG_MEAS_GAPPRD_40 40 +#define RG_MEAS_GAPPRD_80 80 +/* Added support for SPS*/ + +/* LTEMAC_SPS changes */ +#define RG_SCH_NUM_RATYPE1_SUBSETS 4 +#define RG_SCH_NUM_RATYPE2_32BIT_MASK 4 +#define RG_SCH_NUM_RATYPE1_32BIT_MASK RG_SCH_NUM_RATYPE1_SUBSETS + +#define RGSCH_SPS_ULBW_MASK_LEN 4 +#define RGSCH_SPS_MG_MASK_LEN 10 +/* MAX number of feedbacks in case of LTE_TDD */ +#ifdef LTEMAC_SPS +#ifdef LTE_TDD +#define RGSCH_TDD_MAX_FDBK 4 +#endif /* LTE_TDD */ +/* DL SPS States of UE */ +#define RGSCH_DL_SPS_IDLE 0x00 +#define RGSCH_DL_SPS_ACTVTN_PENDING 0x01 +#define RGSCH_DL_SPS_WAITING_FOR_ACTV_CFM 0x02 +#define RGSCH_DL_SPS_ACTV 0x03 +#define RGSCH_DL_SPS_RELEASE_TRIGGERED 0x04 +#define RGSCH_DL_SPS_REACTVTN_PENDING 0x05 + +/* UL SPS States of UE */ +#define RGSCH_SPS_IDLE 0x00 +#define RGSCH_SPS_TO_BE_ACTV 0x01 +#define RGSCH_SPS_TO_BE_REACTV 0x02 +#define RGSCH_SPS_TO_BE_REL 0x03 +#define RGSCH_SPS_ACTV_PDCCH_SENT 0x04 +#define RGSCH_SPS_REL_SENT 0x05 +#define RGSCH_SPS_ACTV 0x06 + +#define RG_SCH_SPS_LCG_ID 1 +#define RG_SCH_MAX_N1PUCCH_VAL 2047 +#define RGSCH_INVALID_SUBFRAME 0xFF +#define RGSCH_INVALID_SFN 0xFFFF +#endif + +#define RG_SCH_MAX_NUM_N1PUCCH_PER_UE 4 +#define RG_SCH_MAX_NUM_N3PUCCH_PER_UE 4 +#define RGSCH_MAX_DL_HQ_PROC 8 + +/* This is the delta that MAC works on Schedule's DELTA should be a function of + * this. + */ + +/* Well known RNTIS */ +#define RGSCH_SI_RNTI 0xffff +#define RGSCH_P_RNTI 0xfffe + +#define RGSCH_MAX_UPPERSAP 3 +#define RGSCH_MAX_LOWERSAP 1 +#define RGSCH_TQ_SIZE 100 /* Timing Queue Size */ +#define RGSCH_MAX_TIMER RGSCH_MAX_LOWERSAP /* MAX number of MAC timers */ +#define RGSCH_NMB_CELL_HASHBIN 10 /* Number of Hash Bins for cell hash + table */ +#define RGSCH_NMB_UE_HASHBIN 10 /* Number of Hash Bins for UE hash + table */ +#define RGSCH_BNDREQ_TMR 1 /* Bind Request timer event value */ +#define RGSCH_MAX_BNDRETRY 2 /* Max number of Bind Retries for TFU SAP */ + + +#define RGSCH_UE_TQ_SIZE 10 /* Timing Queue Size */ + +#define RGSCH_INVALID_SCHD_TYPE 255 +#define RGSCH_MAX_UE_PER_CELL 0xFFFF /*!< Maximum number of UEs per cell */ +#define RGSCH_MAX_UE_BIN_PER_CELL 128 /*!< Maximum number of UE bins per cell */ +#define RGSCH_MIN_DL_BW 6 /*!< Minimum Downlink bandwidth in RBs */ +#define RGSCH_MAX_DL_BW 110 /*!< Maximum Downlink bandwidth in RBs */ +#define RGSCH_MIN_UL_BW 6 /*!< Minimum Uplink bandwidth in RBs */ +#define RGSCH_MAX_UL_BW 110 /*!< Maximum Uplink bandwidth in RBs */ +#define RGSCH_NUM_SC_IN_RB 12 /*!< Number of sub carriers in a RB */ +#define RGSCH_NUM_PBCH_SYM 4 /*!< Number of PBCH symbols in subframe0.Section 6.6,36.211 */ +#define RGSCH_NUM_PSS_SSS_SYM 2 /*!< Number of primary and secondary Synchronization symbols in subframe 0 and subframe 5 */ +#define RGSCH_NUM_CELL_RS_ONE_ANT_PORT 8 /*!< Number of cell specific reference symbols in a Subframe */ +#define RGSCH_NUM_CELL_RS_TWO_ANT_PORT 16 /*!< Number of cell specific reference symbols in a Subframe */ +#define RGSCH_NUM_CELL_RS_FOUR_ANT_PORT 24 /*!< Number of cell specific reference symbols in a Subframe */ +#define RGSCH_TOT_NUM_SYM_NORCP 168 /*!< Total number of symbols in a RB in case of Normal CP */ +#define RGSCH_TOT_NUM_SYM_EXTCP 144 /*!< Total number of symbols in a RB in case of Extended CP */ + +#define RGSCH_MAX_NUM_CSRS_ONE_SYMBOL_RB 4 +#define RGSCH_NUM_ANT_PORT_FOUR 4 +#define RGSCH_MIN_NUM_ANT_PORT 1 +#define RGSCH_NUM_REGS_1ST_SYM 2 +#define RGSCH_NUM_REGS_2ND_SYM_FOUR_ANT_PORT 2 +#define RGSCH_NUM_REGS_2ND_SYM_1OR2_ANT_PORT 3 +#define RGSCH_NUM_REGS_3RD_SYM 3 +#define RGSCH_NUM_REGS_4TH_SYM_NOR_CP 3 +#define RGSCH_NUM_REGS_4TH_SYM_EXT_CP 2 + +#define RGSCH_MIN_CFI_VAL 1 /*!< Minimum value for CFI */ +#define RGSCH_MAX_CFI_VAL 3 /*!< Maximum value for CFI */ +#define RGSCH_QM_BPSK 2 /*!< Qm value for BPSK */ +#define RGSCH_QM_QPSK 4 /*!< Qm value for QPSK */ +#define RGSCH_QM_64QAM 6 /*!< Qm value for 64QAM */ +#define RGSCH_MIN_SRS_SFCFG_IDX 0 /*!< Minimum value for SRS subframe + configurtion index */ +#define RGSCH_MAX_SRS_SFCFG_IDX 15 /*!< Maximum value for SRS subframe + configurtion index */ +#define RGSCH_MAX_SRS_TX_OFFSET 8 /*!< Maximum number of SRS transmission + offsets per cell */ +#ifdef LTE_TDD +#define RGSCH_MIN_MAC_RNTI 61 /*!< Minimum value of RNTI to be managed by + MAC */ +#else +#define RGSCH_MIN_MAC_RNTI 11 /*!< Minimum value of RNTI to be managed by + MAC */ +#endif + +#define RG_SCH_DL_MAX_ITBS 13 +#define RG_SCH_UL_MAX_ITBS 13 + +#define RG_TIME_DIFF(_currTime,_prevTime) \ + (_currTime < _prevTime ? ((0xffffffff - _prevTime) + _currTime ): (_currTime - _prevTime)) + +#define RGSCH_TYPE_SC1 RGR_SCH_TYPE_SC1 +#define RGSCH_TYPE_PFS RGR_SCH_TYPE_PFS +#define RGSCH_TYPE_RR RGR_SCH_TYPE_RR +#define RGSCH_TYPE_MAXCI RGR_SCH_TYPE_MAXCI +/* HARQ related MACROs */ +#ifdef TFU_TDD +#define RGSCH_NUM_DL_HQ_PROC 15 +#else +#define RGSCH_NUM_DL_HQ_PROC 8 +#endif +#define RGSCH_NUM_UL_HQ_PROC 8 +#define RGSCH_MIN_HQ_TX 1 + +/* Group power related MACROs */ +#define RGSCH_MAX_GRP_PWR_FMT3_IDX 15 /*!< Maximum index value for group power format 3 */ +#define RGSCH_MAX_GRP_PWR_FMT3A_IDX 31 /*!< Maximum index value for group power format 3A */ + +/* MACROs to indicate cell specific config for cell to be active */ +#define RGSCH_BCCH_BCH_CFG (1<<0) +#define RGSCH_BCCH_DLSCH_CFG1 (1<<1) +#define RGSCH_BCCH_DLSCH_CFG2 (1<<2) +#define RGSCH_PCCH_CFG (1<<3) +#define RGSCH_UL_CCCH_CFG (1<<4) +#define RGSCH_DL_CCCH_CFG (1<<5) +#define RGSCH_SCHD_CFG (1<<6) + +#define RGSCH_CELL_ACTIVE_CFG (RGSCH_BCCH_BCH_CFG | RGSCH_BCCH_DLSCH_CFG1 | RGSCH_BCCH_DLSCH_CFG2 | RGSCH_PCCH_CFG | RGSCH_UL_CCCH_CFG | RGSCH_DL_CCCH_CFG) + +/* Logical channel realated MACROs */ +#define RGSCH_INVALID_LCG_ID 255 +#define RGSCH_INVALID_LC_ID 255 +#define RGSCH_BCCH_BCH_IDX 0 +#define RGSCH_BCCH_DLSCH_IDX1 1 +#define RGSCH_BCCH_DLSCH_IDX2 2 +#define RGSCH_PCCH_IDX 3 + +/* PUCCH related macros */ +#define RGSCH_PUCCH_MAXVAL_CS 7 /*!< Maximum value for cyclic shift of PUCCH */ +#define RGSCH_PUCCH_MINVAL_DS 1 /*!< Mininmum value for delta shift of PUCCH */ +#define RGSCH_PUCCH_MAXVAL_DS 3 /*!< Maximum value for delta shift of PUCCH */ + +/* DUX related macros */ +#define RGSCH_LCID_MASK 0x1F +#define RGSCH_LCID_LEN 0x5 +#define RGSCH_CCCH_LCID 0x00 +#define RGSCH_DEDLC_MIN_LCID 0x01 +#define RGSCH_DEDLC_MAX_LCID 0x0A +#define RGSCH_RES_MIN_LCID 0x0B +#define RGSCH_RES_MAX_LCID 0x19 +#define RGSCH_PHR_LCID 0x1A +#define RGSCH_CRNTI_LCID 0X1B +#define RGSCH_TRUNC_BSR_LCID 0X1C +#define RGSCH_SHORT_BSR_LCID 0X1D +#define RGSCH_LONG_BSR_LCID 0X1E +#define RGSCH_PAD_LCID 0x1F +/* Fix: If only TA is scheduled, use some dummy LCID */ +#define RG_TA_LCID 0x20 +#define RGSCH_MAX_EXTN_PAD_SUBHDRS 0x02 + +#define RGSCH_CCCH_SDU_PRSNT (1<<0) +#define RGSCH_CRNTI_CE_PRSNT (1<<1) +#define RGSCH_PHR_CE_PRSNT (1<<2) +#ifndef MAC_5GTF_UPDATE +#define RGSCH_TRUNC_BSR_CE_PRSNT (1<<3) +#define RGSCH_SHORT_BSR_CE_PRSNT (1<<4) +#define RGSCH_LONG_BSR_CE_PRSNT (1<<5) +#else +#define RGSCH_BSR_CE_PRSNT (1<<5) +#endif +/* L2_COUNTERS */ +#define RGSCH_ACTIVE_LC_PRSNT (1<<6) +#ifdef LTEMAC_SPS +#define RGSCH_UL_SPS_ACT_PRSENT (1<<7) +#endif +#define RGSCH_EXT_PHR_CE_PRSNT (1<<8) + +/* LOGICAL CHANNEL */ +#define RGSCH_MAX_LC_PER_UE 10 +/* Maximum number of common logical channel control blocks */ +#define RGSCH_MAX_CMN_LC_CB 4 + +/* Random access related MACROs */ +#define RGSCH_MAX_RA_PREAMBLE_FMT 3 /*!< Maximun value of Random access preamble + format */ +#define RGSCH_MAX_RA_WINSIZE 10 /*!< Maximum size of Random access response + window in subframes */ +#define RGSCH_MIN_RA_WINSIZE 2 /*!< Minimum size of Random access response + window in subframes */ +#define RGSCH_MIN_NUM_RA_PREAMBLE 4 /*!< Minimum number of Random access + preambles */ +#define RGSCH_MAX_NUM_RA_PREAMBLE 64 /*!< Maximim number of Random access + preambles */ +#define RGSCH_NUM_RA_RB 6 + +#define RGSCH_MAX_UL_RB 110 /*!< MAX Uplink RBs */ + +#define RGSCH_MAX_RA_RSP_ALLOC 4 /*!< Maximum number of Random access + allocations */ + +#define RGSCH_MAX_RA_RNTI_PER_SUBFRM 6 +#define RGSCH_MAX_TDD_RA_RSP_ALLOC 6 +#define RGSCH_MAX_TDD_RA_PREAMBLE_FMT 4 +#define RGSCH_MAX_TDD_UL_DL_CFG 7 +#define RGSCH_MAX_TDD_SPL_SUBFRM_CFG 9 +#define RGSCH_INVALID_INFO 0xff + +#define RGSCH_RGR_CFG 1 /* RGR configuration element */ + +/*CA_SPECIFIC MACROS*/ +/*CA_DEV_DS_FIX*/ +#define RGSCH_INVALID_CELL_IDX 255 +#define RGSCH_PCELL_INDEX 0 +#define RG_SCH_CELLINDEX(_cell) (U8)((_cell->cellId >= rgSchCb[_cell->instIdx].genCfg.startCellId) ?\ + (_cell->cellId - rgSchCb[_cell->instIdx].genCfg.startCellId)&(CM_LTE_MAX_CELLS-1): 0) +#define RG_SCH_GET_SCELL_INDEX(_ueCb, _cell) _ueCb->cellIdToCellIdxMap[RG_SCH_CELLINDEX(_cell)] +/* RACHO */ +#define RGSCH_MIN_MSG3_GRNT_SZ 7 /*!< Minimum msg3 grant size in bytes */ + +#define RGSCH_NUM_ITBS 27 +#define RGSCH_MAX_NUM_RB 110 +/* Max number of layers per CW */ +#define RGSCH_MAX_NUM_LYR_PERCW 2 + +/* New hash define for TA. Refer to 36.213, 4.2.3*/ +#define RGSCH_NO_TA_RQD 31 + +/* ccpu00133680: Expcted alloc per LC at the end of scheduling + * 2 bytes for minimum RLC Header+ 1 byte for minimal MAC header + * + 1 byte for minimal RLC SDU*/ +#define RGSCH_MIN_ALLOC_PER_LC 4 +#define RGSCH_MAX_REFRESH_GRPSZ 4 /*! Max number of UEs refreshed per subframe */ +#define RGSCH_MAX_REFRESH_OFFSET 16 /*! Max number of subframes used for UE refresh */ + +#define RGSCH_NUM_PDB_SEV_LEVELS 4 /*Number of Severity Levels the PDB can be classified as */ +#define RG_SCH_MAX_PDB_TIME 280 /*Maximum PDB time */ +#define RGSCH_LCG_ISCFGD(lcg) ((lcg)->lcgId != RGSCH_INVALID_LCG_ID) +/* Corrected the check for dlCcchId */ +#define RGSCH_DLCCCH_ISCFGD(cell) ((cell)->dlCcchId != RGSCH_INVALID_LC_ID) +#define RGSCH_ULCCCH_ISCFGD(cell) ((cell)->ulCcchId != RGSCH_INVALID_LC_ID) + +#ifdef EMTC_ENABLE +/* Note: In RGSCH_CALC_SF_DIFF, _time1 should be the latest */ +#define RGSCH_CALC_SF_DIFF_EMTC(_time1, _time2)\ + (_time1.hSfn*10240+_time1.sfn*10+_time1.subframe) < (_time2.hSfn*10240+_time2.sfn*10+_time2.subframe)?\ + ((_time1.hSfn+RGSCH_MAX_SFN)*10240+_time1.sfn*10+_time1.subframe) -\ + (_time2.hSfn*10240+_time2.sfn*10+_time2.subframe) : \ + (_time1.hSfn*10240+_time1.sfn*10+_time1.subframe) - (_time2.hSfn*10240+_time2.sfn*10+_time2.subframe)\ + +/*Addef for L2Meas*/ +/*LTE_L2_MEAS_PHASE2*/ +/*#define RGSCH_CALC_SFN_SF_DIFF(_time1,_sfnCycle, _time2)\ +(((_time1.sfn+RGSCH_MAX_SFN * _sfnCycle)*10) + _time1.subframe -\ +(_time2.sfn*10 + _time2.subframe))*/ + +#define RG_SCH_ADD_TO_CRNT_TIME_EMTC(crntTime, toFill, incr) \ + if ((crntTime.subframe + (incr)) >= RGSCH_NUM_SUB_FRAMES) \ + toFill.sfn = (crntTime.sfn + \ + (crntTime.subframe + (incr)) / RGSCH_NUM_SUB_FRAMES); \ + else \ + toFill.sfn = crntTime.sfn; \ + toFill.subframe = (crntTime.subframe + (incr)) % RGSCH_NUM_SUB_FRAMES; \ + if (toFill.sfn >= RGSCH_MAX_SFN) \ + { \ + toFill.hSfn = (crntTime.hSfn + 1) % RGSCH_MAX_SFN; \ + toFill.sfn = toFill.sfn % RGSCH_MAX_SFN; \ + } \ + else \ + { \ + toFill.hSfn = crntTime.hSfn; \ + } + +#define RGSCHDECRFRMCRNTTIME_EMTC(_crntDl, _prevDl, decr) \ +do \ +{ \ + S32 _subframe;\ + _subframe = _crntDl.hSfn*10240 + _crntDl.sfn * RGSCH_NUM_SUB_FRAMES + _crntDl.subframe; \ + _subframe = _subframe - decr; \ + if(_subframe < 0) \ + { \ + _subframe = (RGSCH_MAX_SFN * RGSCH_MAX_SFN * RGSCH_NUM_SUB_FRAMES) + _subframe; \ + } \ + _prevDl.hSfn = _subframe / (10240); \ + _subframe = _subframe % 10240; \ + _prevDl.sfn = _subframe / RGSCH_NUM_SUB_FRAMES; \ + _prevDl.subframe = _subframe % RGSCH_NUM_SUB_FRAMES; \ +} while(0) + +/* ccpu00133109: Removed RGSCHSUBFRMCRNTTIME as it is not giving proper output + * if diff is more than 10. Instead using RGSCHDECRFRMCRNTTIME() as it is + * serving the purpose */ + +#define RGSCHCPYTIMEINFO_EMTC(src, dst) \ + dst.hSfn = src.hSfn; \ + dst.sfn = src.sfn; \ + dst.subframe = src.subframe; + +#define RGSCH_SUBFRAME_INDEX(x) ( ( ( ((x).hSfn * RGSCH_MAX_SFN )+ (x).sfn) * RGSCH_NUM_SUB_FRAMES ) + (x).subframe ) + +#define RGSCH_TIMEINFO_SAME_EMTC(x, y) (((x).sfn == (y).sfn) && ((x).subframe == (y).subframe)) + +/* Added support for SPS*/ +#ifdef LTEMAC_SPS +/*Compares time difference and returns 0 if same, - 1 if x < y, 1 if x > y + Special check for RGSCH_MAX_SFN is to take care of the wrap around case */ +#define RGSCH_TIMEINFO_CMP_EMTC(_x, _y, _ret)\ +{\ + if (RGSCH_TIMEINFO_SAME_EMTC(_x, _y))\ + {*_ret = 0;}\ + else if ((_x).hSfn > (_y).hSfn)\ + {if ((((_x).hSfn - (_y).hSfn)) == (RGSCH_MAX_SFN -1)) *_ret = -1; else *_ret = 1; }\ + else if ((_x).hSfn < (_y).hSfn)\ + {if ((((_y).hSfn - (_x).hSfn)) == (RGSCH_MAX_SFN -1)) *_ret = 1; else *_ret = -1; }\ + else if ((_x).sfn > (_y).sfn)\ + {*_ret = 1;}\ + else if ((_x).sfn < (_y).sfn)\ + {*_ret = -1; }\ + else if ((_x).sfn == (_y).sfn)\ + {\ + if ((_x).subframe > (_y).subframe)\ + { *_ret = 1; }\ + else\ + {*_ret = -1; }\ + }\ + else\ + { *_ret = -1; }\ +} +#endif + +#define RGSCH_INCR_SUB_FRAME_EMTC(x,y) do { \ + if ((x.subframe += y) > 9) {\ + x.sfn += (x.subframe/10); x.subframe = (x.subframe%10);\ + if (x.sfn >= RGSCH_MAX_SFN) \ + { \ + x.hSfn=(x.hSfn + 1)%RGSCH_MAX_SFN; \ + x.sfn %= RGSCH_MAX_SFN; \ + } \ + }\ +}while(0) + +#else + +#define RGSCH_SUBFRAME_INDEX(x) ( ( ((x).sfn) * RGSCH_NUM_SUB_FRAMES_5G ) + (x).subframe ) +#endif +/* Note: In RGSCH_CALC_SF_DIFF, _time1 should be the latest */ +#define RGSCH_CALC_SF_DIFF(_time1, _time2)\ + (_time1.sfn*RGSCH_NUM_SUB_FRAMES_5G+_time1.subframe) < (_time2.sfn*RGSCH_NUM_SUB_FRAMES_5G +_time2.subframe)?\ + (_time1.sfn*RGSCH_NUM_SUB_FRAMES_5G+_time1.subframe) -\ + (_time2.sfn*RGSCH_NUM_SUB_FRAMES_5G+_time2.subframe) : \ + (_time1.sfn*RGSCH_NUM_SUB_FRAMES_5G+_time1.subframe) - (_time2.sfn*RGSCH_NUM_SUB_FRAMES_5G +_time2.subframe)\ + +/*Addef for L2Meas*/ +/*LTE_L2_MEAS_PHASE2*/ +#define RGSCH_CALC_SFN_SF_DIFF(_time1,_sfnCycle, _time2)\ +(((_time1.sfn+RGSCH_MAX_SFN * _sfnCycle)*RGSCH_NUM_SUB_FRAMES_5G) + _time1.subframe -\ +(_time2.sfn*RGSCH_NUM_SUB_FRAMES_5G + _time2.subframe)) + +#define RG_SCH_ADD_TO_CRNT_TIME(crntTime, toFill, incr) \ + if ((crntTime.subframe + (incr)) >= RGSCH_NUM_SUB_FRAMES_5G) \ + toFill.sfn = (crntTime.sfn + \ + (crntTime.subframe + (incr)) / RGSCH_NUM_SUB_FRAMES_5G); \ + else \ + toFill.sfn = crntTime.sfn; \ + toFill.subframe = (crntTime.subframe + (incr)) % RGSCH_NUM_SUB_FRAMES_5G; \ + if (toFill.sfn >= RGSCH_MAX_SFN) \ + { \ + toFill.sfn = toFill.sfn % RGSCH_MAX_SFN; \ + } + +#define RGSCHDECRFRMCRNTTIME(_crntDl, _prevDl, decr) \ +do \ +{ \ + S32 _subframe;\ + _subframe = _crntDl.sfn * RGSCH_NUM_SUB_FRAMES_5G + _crntDl.subframe; \ + _subframe = _subframe - decr; \ + if(_subframe < 0) \ + { \ + _subframe = (RGSCH_MAX_SFN * RGSCH_MAX_SFN * RGSCH_NUM_SUB_FRAMES_5G) + _subframe; \ + } \ + _subframe = _subframe % RGSCH_MAX_SUBFRM_5G; \ + _prevDl.sfn = _subframe / RGSCH_NUM_SUB_FRAMES_5G; \ + _prevDl.subframe = _subframe % RGSCH_NUM_SUB_FRAMES_5G; \ +} while(0) + +/* ccpu00133109: Removed RGSCHSUBFRMCRNTTIME as it is not giving proper output + * if diff is more than 10. Instead using RGSCHDECRFRMCRNTTIME() as it is + * serving the purpose */ + +#define RGSCHCPYTIMEINFO(src, dst) \ + dst.sfn = src.sfn; \ + dst.subframe = src.subframe; \ + + +#define RGSCH_TIMEINFO_SAME(x, y) (((x).sfn == (y).sfn) && ((x).subframe == (y).subframe)) + +/* Added support for SPS*/ +#ifdef LTEMAC_SPS +/*Compares time difference and returns 0 if same, - 1 if x < y, 1 if x > y + Special check for RGSCH_MAX_SFN is to take care of the wrap around case */ +#define RGSCH_TIMEINFO_CMP(_x, _y, _ret)\ +{\ + if (RGSCH_TIMEINFO_SAME(_x, _y))\ + {*_ret = 0;}\ + else if ((_x).sfn > (_y).sfn)\ + {*_ret = 1;}\ + else if ((_x).sfn < (_y).sfn)\ + {*_ret = -1; }\ + else if ((_x).sfn == (_y).sfn)\ + {\ + if ((_x).subframe > (_y).subframe)\ + { *_ret = 1; }\ + else\ + {*_ret = -1; }\ + }\ + else\ + { *_ret = -1; }\ +} + +#define RGSCH_INCR_SUB_FRAME(x,y) do { \ + if ((x.subframe += y) > (RGSCH_NUM_SUB_FRAMES_5G - 1)) {\ + x.sfn += (x.subframe/RGSCH_NUM_SUB_FRAMES_5G); x.subframe = (x.subframe%RGSCH_NUM_SUB_FRAMES_5G);\ + if (x.sfn >= RGSCH_MAX_SFN) \ + { \ + x.sfn %= RGSCH_MAX_SFN; \ + } \ + }\ +}while(0) + + + +#endif /* EMTC_ENABLE */ + +/* RACHO : TRUE if rapId is a ded preamble */ +#define RGSCH_IS_DEDPRM(cell, rapId) ((rapId) >= (cell->rachCfg.numRaPreamble)) + +#define rgSchPBuf(inst) rgSchCb[inst].rgSchInit.prntBuf + +/* Debug Prints for MAC */ +#ifdef DEBUGP +#define RGSCHDBGERRNEW(inst, _args) \ + DBGP(&rgSchCb[inst].rgSchInit, RGSCHLAYERNAME, DBGMASK_ERR, _args) +#define RGSCHDBGINFONEW(inst, _args) \ + DBGP(&rgSchCb[inst].rgSchInit, RGSCHLAYERNAME, DBGMASK_INFO, _args) +#define RGSCHDBGPRM(inst, _args) UNUSED(inst); +#define RGSCHDBGERR(inst, _args) \ + DBGP(&rgSchCb[inst].rgSchInit, RGSCHLAYERNAME, DBGMASK_ERR, _args) +#define RGSCHDBGINFO(inst, _args) UNUSED(inst); +#else +#define RGSCHDBGERRNEW(inst, _args) +#define RGSCHDBGINFONEW(inst, _args) +#define RGSCHDBGPRM(inst, _args) +#define RGSCHDBGERR(inst, _args) +#define RGSCHDBGINFO(inst, _args) +#endif /* #ifdef DEBUGP */ + +#define RGSCH_IS_GBR_BEARER(cfgdGbr) ((cfgdGbr) != 0) + +#ifdef ERRCLS_KW +#define RGSCH_ARRAY_BOUND_CHECK(_inst, _array, _idxVal) \ + if((_idxVal) >= (sizeof(_array)/sizeof(_array[0]))) \ + { \ + RGSCHDBGERRNEW((_inst), (rgSchPBuf(_inst), "Array Bound Check Failed"));\ + SExit();\ + }\ + +#define RGSCH_NULL_CHECK(_inst, _ptr ) \ + if((_ptr) == NULLP) \ + { \ + RGSCHDBGERRNEW((_inst), (rgSchPBuf(_inst), "Null Pointer detected"));\ + SExit();\ + } +#define RGSCH_ARRAY_BOUND_CHECK_WITH_POS_IDX(_inst, _array, _idxVal) \ + if(((_idxVal) >= (sizeof(_array)/sizeof(_array[0])))|| (_idxVal < 0)) \ + { \ + RGSCHDBGERRNEW((_inst), (rgSchPBuf(_inst), "Array Bound Check Failed"));\ + SExit();\ + } + +#define RGSCH_PFS_AMBR_ARRAY_BOUND_CHECK(_inst, _pfsCell, _qId, _ue ) \ +{\ + if (_ue->csgMmbrSta == TRUE)\ + {\ + RGSCH_ARRAY_BOUND_CHECK(_inst, _pfsCell->txQueues.prioAmbrLst, _qId);\ + }\ + else\ + {\ + RGSCH_ARRAY_BOUND_CHECK(_inst, _pfsCell->txQueues.normAmbrLst, _qId);\ + }\ +} +#else +#define RGSCH_ARRAY_BOUND_CHECK(_inst, _array, _idxVal) +#define RGSCH_NULL_CHECK( _inst, _ptr ) +#define RGSCH_ARRAY_BOUND_CHECK_WITH_POS_IDX(_inst, _array, _idxVal) +#define RGSCH_PFS_AMBR_ARRAY_BOUND_CHECK(_inst, _pfsCell, _qId, _ue ) +#endif + +/* Macro to free the message buffer and initialize it to zero */ +/*********************************************************** + * + * Name : RGSCH_FREE_MSG + * + * Desc : Macro to free the message buffer and initialize it to zero + * + * Input : mBuf - message buffer pointer to be retunrned + * + * Output : None. + * + * Notes: None + * + **********************************************************/ +#define RGSCH_FREE_MSG(_buf)\ +{\ + if (NULLP != (_buf)) \ + { \ + SPutMsg((_buf)); \ + _buf = NULLP; \ + } \ +} + +#define RGSCH_FREE_MEM(_mem)\ +{\ + if (NULLP != (_mem)) \ + { \ + cmFreeMem((Ptr)(_mem)); \ + _mem = NULLP; \ + } \ +} +/*********************************************************** + * + * Name : RGSCH_DROP_RGUDDATREQ_MBUF + * + * Desc : Macro to free the message buffers and initialize them to zero + * + * Input : _datreq - Dedicated Data Request pointer which has mBufs + * to be freed + * + * Output : None. + * + * Notes: None + * + **********************************************************/ + +#define RGSCH_DROP_RGUDDATREQ_MBUF(_datReq)\ +{\ + U32 idx1,idx2,idx;\ + if (_datReq != NULLP)\ + {\ + for (idx=0; idx < _datReq->numLch; idx++)\ + {\ + for (idx1=0; idx1 < RGU_MAX_PDUSET; idx1++)\ + {\ + for (idx2=0; idx2 < _datReq->lchData[idx].pdu[idx1].numPdu; idx2++)\ + {\ + RGSCH_FREE_MSG(_datReq->lchData[idx].pdu[idx1].mBuf[idx2]);\ + }\ + }\ + }\ + }\ +} +/*********************************************************** + * + * Name : RGSCH_DROP_RGUCDATREQ_MBUF + * + * Desc : Macro to free the message buffers and initialize them to zero + * + * Input : _datreq - Common Data Request pointer which has mBufs + * to be freed + * + * Output : None. + * + * Notes: None + * + **********************************************************/ +#define RGSCH_DROP_RGUCDATREQ_MBUF(_datReq)\ +{\ + U32 idx1;\ + if (_datReq != NULLP)\ + {\ + for (idx1 = 0; idx1 < RGU_MAX_PDUSET; idx1++)\ + {\ + if (_datReq->pdu != NULLP)\ + {\ + RGSCH_FREE_MSG(_datReq->pdu[idx1]);\ + }\ + }\ + }\ +} + + +/* Macros for memory region and pool determination */ +#define RGSCH_GET_MEM_REGION(rgCb) (rgCb.rgInit.region) +#define RGSCH_GET_MEM_POOL(rgCb) (rgCb.rgInit.pool) + +#ifdef LTE_TDD +#define RGSCH_UPD_HQAN_FDBKTIME(_tbInfo, _dlSf, _timingInfo) \ +do \ +{ \ + (_tbInfo)->m = 0; \ + (_tbInfo)->fdbkTime.sfn = (_timingInfo.sfn + \ + _dlSf->dlFdbkInfo.sfnOffset) % RGSCH_MAX_SFN; \ + (_tbInfo)->fdbkTime.subframe = _dlSf->dlFdbkInfo.subframe; \ + (_tbInfo)->timingInfo = _timingInfo; \ +} while(0) + +#define RGSCH_UPD_ANINFO_WITH_HQ(_anInfo, _tbInfo) \ +do \ +{ \ + _anInfo->sfn = (_tbInfo)->fdbkTime.sfn; \ + _anInfo->subframe = (_tbInfo)->fdbkTime.subframe; \ + _anInfo->latestMIdx = (_tbInfo)->m; \ +} while(0) +/* Support for iPhich=1 for TDD*/ + +#define RGSCH_UPD_PHICH(_ulDlCfgIdx, _subframe, _hqProc) \ + if(_ulDlCfgIdx == 0 && ((_subframe == 4) ||( _subframe == 9)))\ + {\ + _hqProc->iPhich = 1;\ + }\ + else\ + {\ + _hqProc->iPhich = 0;\ + } +#endif + + +/* MUX related macros */ +#define RGSCH_HDR_TYPE_CRES 1 +#define RGSCH_HDR_TYPE_TA 2 + +#define RGSCH_SDU_SHDR_LEN 1 +#define RGSCH_CE_SHDR_LEN 1 +#define RGSCH_CRES_LEN 6 +#define RGSCH_TA_LEN 1 +#define RGSCH_CRES_ELM_LEN RGSCH_CE_SHDR_LEN+RGSCH_CRES_LEN +#define RGSCH_TA_ELM_LEN RGSCH_CE_SHDR_LEN+RGSCH_TA_LEN + +#define RGSCH_CRES_LCID_IDX 0x1C +#define RGSCH_TA_LCID_IDX 0x1D + +#define RGSCH_MAX_SUBFRAMES_IN_SFN 9 +#define RGSCH_MAX_SFN 1024 +#define RGSCH_NUM_SUB_FRAMES 10 + +#define RGSCH_NUM_SUB_FRAMES_5G 50 + +#ifdef LTE_TDD +#define RGSCH_ULCTRL_RECP_DIST 7 +#else +#define RGSCH_ULCTRL_RECP_DIST 4 +#endif +/* Definig the Macro for the Size SF alloc Info Structure + * The Value is defines the number of subframes the Alloc Info is maintained + * The SF alloc Info is used to send the scheduled Allocation Info + * to MAC from Scheduler + */ +#define RGSCH_SF_ALLOC_SIZE 4 + +/* Defining new MACRO for DL subframes */ +#define RGSCH_NUM_DL_SUBFRAMES 20 +/* Define for the block size for memory allocation */ +#define RGSCH_BLKSZ 2048 + +/* Defines for RGU Statistics types */ +#define RGSCH_RGU_SDU_DROP 1 +#define RGSCH_RGU_SDU_RCVD 2 + +/* MACROS for General Statistics */ +#define RGSCH_CFG_ADD 1 +#define RGSCH_CFG_DEL 2 + +#define RGSCH_HQ_FDB_IND_CB_TYPE_HQ_ENT 1 +#define RGSCH_HQ_FDB_IND_CB_TYPE_RA_CB 2 + +/* The value of RGSCH_TDD_MAX_P_VAL is 4, since we need the table for + * P+1 value the below Macro is defined and used + */ +#define RGSCH_TDD_MAX_P_PLUS_ONE_VAL 5 +#define RGSCH_TDD_MAX_FREQ_RSRC 6 + +/* + * RG_TFU_HQ_IND_DELTA is replaced with + * TFU_HQFBKIND_ULDELTA and moved into envopt.h. + */ + +/* Macro for selecting the subframe index to be deleted */ + +#define RGSCH_RLS_SF_IDX (RG_SCH_CMN_HARQ_INTERVAL + TFU_HQFBKIND_ULDELTA) + +/* Macro for max random access responses */ +#define RGSCH_MAX_RA_RSP_ALLOC 4 + +/* Value used to set nDmrs in uplink grant if nDmrs is not applicable */ +#define RGSCH_INVALID_NDMRS 10 + +/* comcodsepa : start */ +#define RGSCH_MIN(x, y) ((x) <= (y) ? (x) : (y)) +#define RGSCH_MAX(x, y) ((x) >= (y) ? (x) : (y)) +#define RGSCH_CEIL(x, y) (((x) + (y)-1) / (y)) +#define RGSCH_FLOOR(x, y) ((x) / (y)) +#define RGSCH_CEILING(x) (((x) - (U8)(x)) ? (U8)(x+1) : (U8)x) +#define RGSCH_DIV_ROUND(x, y) (((x) + (y)/2) / (y)) + +#define RGSCH_RARSP_WAIT_PERIOD 3 +#define RGSCH_INCR_FRAME(x) x = ((x) + 1) & 0x03ff + +#define RG_SCH_TDD_DL_SUBFRAME 1 +#define RG_SCH_TDD_UL_SUBFRAME 2 +#define RG_SCH_TDD_SPL_SUBFRAME 3 + +#define RG_SCH_MAX_DAI_IDX 4 +#define RG_SCH_DAI_MAX_BIT_VAL 3 +/* Since DAI bit value is stored and its range is 0-3 in SCH, + * So Invalid is Set to 0xFF */ +/* ccpu00139414 */ +#define RG_SCH_INVALID_DAI_VAL 0x00 +/* Valid Range is 0-8, So Invalid is Set to 99 */ +#define RG_SCH_INVALID_M_VAL 0xFF + +/* Below macro used to get the DAI value (1 -4) for the total DL transmission + * made + */ +#define RG_SCH_GET_DAI_VALUE(dai) ((((dai) - 1) & RG_SCH_DAI_MAX_BIT_VAL) + 1) +/* below Macro indicates the max number of DL transmissions that can be made in + * a single FeedBak period + */ +#define RG_SCH_MAX_NUM_EXPECTED_ACKS 9 +/* The below macro indicates the max number of feedback report + */ +#define RG_SCH_NUM_FDBK_VALUE 3 + +#define RG_SCH_ULIDX_LSB 1 +#define RG_SCH_ULIDX_MSB 2 +#define RG_SCH_ULIDX_BOTH 3 + +#ifdef MAC_5GTF_UPDATE +#define RGSCH_ONE_RAR_SIZE 8 +#else +#define RGSCH_ONE_RAR_SIZE 7 +#endif + +#define RGSCH_MSG4_HDRSIZE 1 +#define RGSCH_CONT_RESID_SIZE 7 +/* CR timer change*/ +#ifdef RGR_V1 +#define RGSCH_CCCH_SDU_HDRSIZE 1 +#define RGSCH_CONTRES_EXP 0xffff +#endif +/* Corrected allocation for common channels */ +#define RGSCH_ONE_BIHDR_SIZE 1 + +#define RGSCH_TA_SIZE 2 +#ifdef LTE_ADV +#define RGSCH_SCELL_ACT_CE_SIZE 2 +#define RGSCH_INVALID_PUCCH3_RES 550 +#endif + +#define RGSCH_GET_RAR_BYTES(x) ((x) * RGSCH_ONE_RAR_SIZE) + +#define RG_SCH_CMN_MEAS_GAPPRD40 40 +#define RG_SCH_CMN_MEAS_GAPPRD80 80 +#define RG_MEAS_GAPPRD_40 40 +#define RG_MEAS_GAPPRD_80 80 +#define RG_MAX_NUM_DLSF 10 /* Maximum number of Subframes */ +#define RG_MEASGAP_INACTIVE 0x01 +#define RG_ACKNAKREP_INACTIVE 0x02 +#define RG_PDCCHODR_INACTIVE 0x04 +#define RG_DRX_INACTIVE 0x08 /*UE is DRX inactive */ + +#define RG_SCH_DRX_UL 0 /*UE is DRX active in uplink*/ +#define RG_SCH_DRX_DL 1 /*UE is DRX active in downlink*/ +/*Fix:Inform UE delete to scheduler*/ +#define RG_MACUEDEL_INACTIVE 0x10 +/* Fix : syed set UE inactive for scheduling if it is not completely + * initialized */ +#define RG_HQENT_INACTIVE 0x20 +/* Timer events */ +#define RG_SCH_TMR_ACKNACK_REP 1 /* Timer event for ACK NACK Rep */ +#define RG_SCH_TMR_MEASGAP 2 /* Timer event for Measurement gap */ +#define RG_SCH_TMR_UL_ACKNACK 3 /* Timer event for Ul Inactivity due to ack-nack */ +#define RG_SCH_TMR_DL_ACKNACK 4 /* Timer event for Dl Inactivity due to ack-nack */ +#define RG_SCH_TMR_UL_MEASGAP 5 /* Timer event for Ul Inactivity due to Measurement gap */ +#define RG_SCH_TMR_DL_MEASGAP 6 /* Timer event for Dl Inactivity due to Measurement gap */ +#define RG_SCH_TMR_TA 7 /* Timer event for Timing Alignment */ +/* Added periodic BSR timer */ +#ifndef RGR_V1 +#define RG_SCH_TMR_BSR 8 /* Timer event for Periodic BSR */ +#else +#define RG_SCH_TMR_BSR 8 /* Timer event for Periodic BSR */ +#endif + +#define RG_SCH_TMR_TXMODE_TRNSTN 9 /* Timer event for TX Mode Transition */ +#ifdef LTE_ADV +#define RG_SCH_TMR_SCELL_DEACT 10 /* Timer event for Secondary Cell Deactivation */ +#define RG_SCH_TMR_SCELL_ACT_DELAY 11 /* Timer event for Secondary Cell Activation Delay */ +#endif + +#define RG_SCH_TXMODE_TRANS_TIMER 1000 /* Timer length for Tx Mode Transition + Completion */ + +#define RG_SCH_TMR_DLINACTV 2 /* Timer event for DL Inactivity */ +#define RG_SCH_MEAS_GAP_LEN 6 /* Timer event for measurement GAP */ + +#define RGSCH_SCELL_DEACT_TMR_INFINITY_VAL 3840 /* In millisecond, thrice the maximum + value of deactivation timer */ + +#define RG_SCH_DRX_DL_DELTA (RG_DL_DELTA) /*!< look at timer queue + for DL + RG_SCH_DRX_DL_DELTA + in advance */ + +/* Introduced UL control timing delta in FDD */ +#define RG_SCH_DRX_UL_DELTA (TFU_ULCNTRL_DLDELTA) +/*Assigning RG_SCH_DRX_MAX_DELTA to the higher delta of uplink delta and + * downlink delta.*/ +#define RG_SCH_DRX_MAX_DELTA ((RG_SCH_DRX_DL_DELTA < RG_SCH_DRX_UL_DELTA)?\ +RG_SCH_DRX_UL_DELTA:RG_SCH_DRX_DL_DELTA) + +#define RG_SCH_NO_DELTA 0 /*Consider no delta */ +/** @brief The lenght of array we maintain to track DRX Cycles. + * @details + * The periodicity of LONG DRX Cycle has a maximum value of 2560. The ideal and + * the fastest way would be to have an array of this size. However having an + * Array this large would make the cellCb a huge structure and may have + * performance implications as well. + * Hence the defined size and lower values are a multiple of the larger sizes. + * A distance based approach is used to get to the correct value. + * @sa RgSchDRXCellCb. + * For decreased processing hit this value maybe increased to + * [320, 640, 1024, 2560] + */ +#define RG_SCH_MAX_DRXQ_SIZE 256 /*!< Length of the DRQ queue maintained + at the cell level. */ +#define RG_SCH_MIN_HARQ_RTT 8 /*!< Minimum round trip time for Harq + feedback*/ +#ifdef EMTC_ENABLE +#define RG_SCH_MIN_UL_HARQ_RTT 4 /*!< Minimum round trip time for UlHarq feedback */ +#endif + +/* MASKs for tracking DRX activity */ + +#define DRX_UE_INACTIVE 0xFFFFFFFF +#define DRX_INVALID 0xFFFF +#define DRX_TMR_EXPRD -1 + +#define RG_SCH_DRX_SR_BITMASK 0x00000001 /*DRX SR Bitmask*/ +#define RG_SCH_DRX_RA_BITMASK 0x00000002 /*DRX RA Bitmask*/ +#define RG_SCH_DRX_ONDUR_BITMASK 0x00000004 /*DRX on-duration bitmask */ +#define RG_SCH_DRX_INACTVTMR_BITMASK 0x00000008 /*DRX inactive timer bitmask */ +/* DLHQ Bitmask should always be the last */ +#define RG_SCH_DRX_DLHQ_BITMASK 0x00000010 /*DRX DL harq bitmask*/ + +#ifdef EMTC_ENABLE +#define RG_SCH_DRX_ULHQ_BITMASK (RG_SCH_DRX_DLHQ_BITMASK << 8) +#endif + +#ifdef LTE_ADV +#define RG_SCH_MAX_SCELL (CM_LTE_MAX_CELLS - 1) /*!< Max number of sec cells per ue. + -1 done for Primary cell */ +#define RG_SCH_ACTIVATION_COUNT 10 /*!< Maximum count for SCELL Activation */ +#endif + + +/*if any bit in the mask is 0, ue is active */ +#define RG_SCH_DRX_DL_IS_UE_ACTIVE(drxCb)\ + (drxCb->drxDlInactvMask ^ DRX_UE_INACTIVE) + +/*if any bit in the mask is 0, ue is active */ +#define RG_SCH_DRX_UL_IS_UE_ACTIVE(drxCb)\ + (drxCb->drxUlInactvMask ^ DRX_UE_INACTIVE) +/*if UE is in DL DRX on-duration */ +#define RG_SCH_DRX_DL_IS_UE_ONDUR_INACTIVE(drxCb) \ + (drxCb->drxDlInactvMask & RG_SCH_DRX_ONDUR_BITMASK) +/*if UE is in UL DRX onduration */ +#define RG_SCH_DRX_UL_IS_UE_ONDUR_INACTIVE(drxCb) \ + (drxCb->drxUlInactvMask & RG_SCH_DRX_ONDUR_BITMASK) +/*if ue is in DL DRX Inactive timer period */ +#define RG_SCH_DRX_DL_IS_UE_INACTVTMR_INACTIVE(drxCb) \ + (drxCb->drxDlInactvMask & RG_SCH_DRX_INACTVTMR_BITMASK) + +/*if ue is in UL DRX Inactive timer period */ +#define RG_SCH_DRX_UL_IS_UE_INACTVTMR_INACTIVE(drxCb) \ + (drxCb->drxUlInactvMask & RG_SCH_DRX_INACTVTMR_BITMASK) +/*get DRX cell */ +#define RG_SCH_DRX_GET_CELL(_cell) ((_cell)->drxCb) +/*get DRX UE */ +#define RG_SCH_DRX_GET_UE(_ue) ((_ue)->drxCb) +/*get DRX DL HARQ */ +#define RG_SCH_DRX_GET_DL_HQ(_hqProc) &((_hqProc)->drxCb) + + + +#ifdef LTE_TDD + +#define RGSCH_MAX_SFCFG 2 /* refer to rgSchDrxDlSfTddcfg in rg_sch.h to + understand why this is 2 */ +#define RGSCH_MAX_TDD_CFG 7 + +#define RGSCH_NUM_SFRAMES 10 /* number of subframes in a RF */ + +#endif /* LTE_TDD */ + +#ifndef LTE_TDD +/* Introduced UL control timing delta in FDD */ +/* Number of subframes in advance UL control (DCI/PHICH) should be sent from SCH */ +#define TFU_ULCNTRL_DLDELTA (RG_SCH_CMN_HARQ_INTERVAL - TFU_CRCIND_ULDELTA) +#endif/*ndef LTE_TDD*/ + +/* Added for SI Enhancement*/ +#ifdef RGR_SI_SCH +/* SI Re-configuration related bit masks */ +#define RGSCH_SI_DFLT 0 /* Default */ +#define RGSCH_SI_SICFG_UPD (1<<0) /* SI CFG Updated */ +#define RGSCH_SI_MIB_UPD (1<<1) /* MIB CFG Updated */ +#define RGSCH_SI_SIB1_UPD (1<<2) /* SIB1 CFG Updated */ +#define RGSCH_SI_SI_UPD (1<<3) /* SI PDU CFG Updated */ +#define RGSCH_SI_SIB1_PWS_UPD (1<<4) /* SIB1 PWS CFG Updated */ +#ifdef EMTC_ENABLE +#define RGSCH_SI_EMTC_TYPE_SIB1_BR_UPD (1<<5) /* EMTC SIB1 BR CFG Updated */ +#define RGSCH_SI_EMTC_TYPE_SI_UPD (1<<6) /* EMTC SI PDU CFG Updated */ +#endif +/*SI Scheduling Specific */ +#define RGSCH_MIB_PERIODICITY 4 /*!< MIB Periodicity */ +#define RGSCH_SIB1_PERIODICITY 8 /*!< SIB1 Periodicity */ +#define RGSCH_SIB1_RPT_PERIODICITY 2 /*!< SIB1 Repeat Periodicity */ +#define RGSCH_MIB_TX_SF_NUM 0 /*!< MIB TX SF Number */ +#define RGSCH_SIB1_TX_SF_NUM 5 /*!< SIB1 TX SF Number */ +/*rg009.lpr-ccpu00116647 - Added siId validation for lower limit */ +#define RGSCH_SI_SIID_LOWER_LMT 1 /*!< Least usabel siId number */ +#define RGR_MAX_NUM_WARNING_SI 3 /*!< Max no. of Warning SI*/ +#define RGSCHCHKNUPDSIPDU(_CRNTINFO,_NEWINFO,_NEWPDU,_BITMSK, _BITFLG) \ +do\ +{\ + if(NULLP == _CRNTINFO)\ + {\ + _CRNTINFO = _NEWPDU; \ + }\ + else\ + {\ + if(NULLP != _NEWINFO)\ + {\ + RGSCH_FREE_MSG(_NEWINFO);\ + _NEWINFO = NULLP;\ + }\ + _NEWINFO = _NEWPDU;\ + _BITMSK |= _BITFLG;\ + }\ +}while(0) + +#define RGSCH_SET_SI_INFO(_CRNTPTR,_NEWPTR)\ +do\ +{\ + if(NULLP != _CRNTPTR)\ + RGSCH_FREE_MSG(_CRNTPTR);\ + _CRNTPTR = _NEWPTR;\ + _NEWPTR = NULLP;\ +}while(0) +#endif /*RGR_SI_SCH */ +/* Added changes of TFU_UPGRADE */ +#ifdef TFU_UPGRADE +/*********************************************************************** + Macro Definitions + ***********************************************************************/ + /* Array Based List size to store next active Periodic CQI, SRS and SR + tranmission instances at cell Cb */ + + /* Periodic CQI max periodicity = 160 Ref: 36.213 (Table 7.2.2-1A For FDD + and 1C for TDD) */ + /* SRS max periodicity = 320 Ref: 36.213 (Table 8.2-1) */ + /* SR max periodicity = 80 Ref: 36.213 (Table 10.1-5 ) */ + /* Modifying Queue Size from 320 to 321. 320 is a possible periodicity for RI + * and SRS. If it is 320, then while moving to next occassion it is being added + * same queue. If more than one node is available in the queue then same UE's + * node is adding to the same queue and processed in same TTI. This is happening + * in infinite loop. Hence modifying it to 321, which is not a possible periodicity. + */ +/* Changing this back to 320 as it was causing + * problem in TDD attach and stability + */ +#define RG_SCH_PCQI_SRS_SR_TRINS_SIZE 320 + + +#ifdef LTE_TDD + +/* Ref 36.213 Table 8.2-2: */ +#define RG_SCH_ISRS_MAX_SUPP 644 +/* Note: <= 10 ms periodicity is not supported */ +#define RG_SCH_ISRS_MIN_SUPP 10 + +/* Ref 36.213 Table 7.2.2-1C */ + +#define RG_SCH_ICQI_MAX_SUPP 315 +#define RG_SCH_ICQI_MIN_SUPP 0 + +#else +/* Ref 36.213 Table 8.2-1: */ +#define RG_SCH_ISRS_MAX_SUPP 636 +/* Note: <= 10 ms periodicity is not supported */ +#define RG_SCH_ISRS_MIN_SUPP 0 + + +#define RG_SCH_ICQI_MAX_SUPP 541 +#define RG_SCH_ICQI_MIN_SUPP 0 + +#define RG_SCH_ICQI_RESV_FDD 317 + +#endif + +/*Refer Table 7.2.1-5: for max BW configuration M=6*/ +#define RG_SCH_MAX_NUM_UE_SEL_SUBBANDS 6 + +/*Refer Table 7.2.1-5: for max BW configuration k =4, ceil(110/4) = 28*/ +#define RG_SCH_MAX_TOT_NUM_SUBBANDS 28 + +/* 36.213 Table 7.2.2-1B: */ +#define RG_SCH_IRI_MAX_SUPP 965 +#define RG_SCH_IRI_MIN_SUPP 0 + +/*K value in CQI table min and max values*/ +#define RG_SCH_CQI_K_MAX 4 +#define RG_SCH_CQI_K_MIN 1 + +#define RG_SCH_PUCCH_RES_MAX_SUPP 1185 /* TODO: Need to check value */ + +#define RG_SCH_IRI_MAX_SUPP 965 + + +#define RG_SCH_ISR_MAX_SUPP 154 +#define RG_SCH_ISR_MIN_SUPP 0 + +#define RG_SCH_SRS_FREQDOM_POS_MIN 0 +#define RG_SCH_SRS_FREQDOM_POS_MAX 23 + +#define RG_SCH_SRS_TXCOMB_MIN 0 +#define RG_SCH_SRS_TXCOMB_MAX 1 + +#define RG_SCH_SR_RES_IDX 2047 /* TODO: Need to check */ +/*Reference: 36.213 Table:7.2.2-1A */ +#define RG_SCH_CQIPMI_CFGIDX_MAX_FDD 10 + +/* Reference: 36.213 Table:7.2.2-1C */ +#define RG_SCH_CQIPMI_CFGIDX_MAX_TDD 7 + + +/* Note: RI table is same for FDD and TDD */ +/*Reference: 36.213 Table:7.2.2-1B */ +#define RG_SCH_RI_CFGIDX_MAX 6 + + +/*Reference: 36.213 Table:7.2.2-2 */ +#define RG_SCH_BW_SUBSZ_BWPARTS_MAX 5 + +/* Reference : 36.213 Table 8.2-1 */ +#define RG_SCH_SRS_ISRS_INDX_MAX_FDD 8 + +/* Reference : 36.213 Table 8.2-2 */ +#define RG_SCH_SRS_ISRS_INDX_MAX_TDD 7 + +/* Reference : 36.213 Table 10.1-5 */ +/* Note: SR is same table for TDD and FDD */ +#define RG_SCH_ISR_INDX_MAX 5 + + +/* This use used to mark as invalid index value */ +#define RG_SCH_INVALID_IDX 0xffff + +/*ccpu00116923 - ADD - SRS present support*/ +#define RGSCH_CELLSP_SRS_SF_CONFIGS 16 + +/*Used for Periodic CQI. */ +#define RG_SCH_GET_CQI_J_VAL(_dlBw, _j) \ +{\ + if(_dlBw >= 64)\ + {\ + _j = 4;\ + }\ + else if(_dlBw >= 27)\ + {\ + _j = 3;\ + }\ + else if(_dlBw >= 11 )\ + {\ + _j = 2;\ + }\ + else\ + {\ + _j = 1;\ + }\ +} + +#define RG_SCH_GET_CQI_K_VAL(_dlBw, _k) \ +{\ + if(_dlBw >= 64)\ + {\ + _k = 8;\ + }\ + else if(_dlBw >= 27)\ + {\ + _k = 6;\ + }\ + else if(_dlBw >= 11 )\ + {\ + _k = 4;\ + }\ + else\ + {\ + _k = 4;\ + }\ +} + + +#define RG_SCH_GET_SBCQI_M_K_VAL(_dlBw, _m, _k) \ +{\ + if(_dlBw >= 64)\ + {\ + _m = 6;\ + _k = 4;\ + }\ + else if(_dlBw >= 27)\ + {\ + _m = 5;\ + _k = 3;\ + }\ + else if(_dlBw >= 11 )\ + {\ + _m = 3;\ + _k = 2;\ + }\ + else\ + {\ + _m= 1;\ + _k = 2;\ + }\ +} + + +/* To Get the Idx to pCqiSrsSrLst in RgSchCellCb*/ +#define RG_SCH_GET_IDX_PCQISRSSR(_time, _indexId)\ +{\ + (_indexId) = (_time.sfn)* RGSCH_NUM_SUB_FRAMES_5G + (_time.subframe); \ + (_indexId) = (_indexId)%RG_SCH_PCQI_SRS_SR_TRINS_SIZE;\ +} + +#define RG_SCH_GET_UE_CELL_CQI_CB(_ueCb, _cell) &((_ueCb)->cellInfo\ + [_ueCb->cellIdToCellIdxMap[RG_SCH_CELLINDEX(_cell)]]->cqiCb) + +/* To Get UE Next Active Periodic RI Idx to the table pCqiSrsSrLst */ +/* Caller should check the periodic RI is RG_SCH_INVALID_IDX or not */ +#define RG_SCH_GET_IDX_RI(_ueCb, _cell, _riIdx)\ +{\ + (_riIdx) = (_ueCb)->cellInfo[_ueCb->cellIdToCellIdxMap\ + [RG_SCH_CELLINDEX(_cell)]].cqiCb.nRiTrIdx;\ +} + + +/* To Get UE Next Active SR Idx to the table pCqiSrsSrLst */ +/* Caller should check the periodic SR is RG_SCH_INVALID_IDX or not */ +#define RG_SCH_GET_IDX_SR(_ueCb, _srIdx)\ +{\ + (_srIdx) = (_ueCb)->srCb..nSrTrIdx;\ +} + +/* To Get UE Next Active SRS Idx to the table pCqiSrsSrLst */ +/* Caller should check the SRS is RG_SCH_INVALID_IDX or not */ +#define RG_SCH_GET_IDX_SRS(_ueCb, _ssrIdx)\ +{\ + (_srsIdx) = (_ueCb)->srsCb..nSrsTrIdx;\ +} + + + +/* To Get UE Next Active Periodic CQI Idx to the table pCqiSrsSrLst */ +/* Caller should check the periodic CQI is RG_SCH_INVALID_IDX or not */ +#define RG_SCH_GET_IDX_PCQI(_ueCb, _cell, _pCqiIdx)\ +{\ + (_pCqiIdx) = (_ueCb)->cellInfo[_ueCb->cellIdToCellIdxMap\ + [RG_SCH_CELLINDEX(_cell)]].cqiCb.nCqiTrIdx;\ +} + +/** + * @def RG_SCH_PARSE_MULTI_PMI + * + * This macro is used to parse RAW PMI + * + * + * @param[in] _bitLen bit length + * @param[in] _totPmiBitLen total PMI bit length + * @param[in] _ueCb ue control block + * @param[in] _revArray reverse array + * @param[out] _psMode12 Period mode 12 + * @param[out] _sbOffst subband offset + * + */ +#define RG_SCH_PARSE_MULTI_PMI(_bitLen, _totPmiBitLen, _psMode12,\ + _acqiCb, _revArray,_sbOffst )\ +{\ + U8 _loop =0;\ + for(_loop =0; _loop<(_totPmiBitLen/_bitLen); _loop++)\ + {\ + (_psMode12)->subbandArr[_loop].pmi = (U8)rgSCHUtlParse(_revArray,\ + _sbOffst,(U8)(_sbOffst+_bitLen), (U8)TFU_MAX_CQI_BYTES);\ + _sbOffst+=_bitLen;\ + (_psMode12)->subbandArr[_loop].subBand.numRb = (_acqiCb).k;\ + (_psMode12)->subbandArr[_loop].subBand.rbStart = \ + (U8) ((_acqiCb).k * (_loop));\ + }\ +} + +/* Removed the MACRO RG_SCH_GET_PERIODICITY_TBL + * The function rgSCHUtlGetPcqiSrsSrRiTbl will do the same task as this + * MACRO*/ + +#endif + + + + +#ifdef LTEMAC_HDFDD +/* Half Duplex Specific defines */ +/* Number of subframes information managed */ +#define RG_SCH_HDFDD_NUMSFINFO 20 +/* Subframe States */ +#define RG_SCH_HDFDD_NOSCHD 0x00 +#define RG_SCH_HDFDD_DLDATA 0x01 +#define RG_SCH_HDFDD_DLCNTRL 0x02 +#define RG_SCH_HDFDD_UL 0x04 + +#define RG_SCH_HDFDD_INVSFN (RGSCH_MAX_SFN + 100) /* Add some arbitrary number to make it invalide */ + +#define RG_SCH_HDFDD_GRDTIM_DUR 1 +#define RG_SCH_HDFDD_DELTA 10 + +/* To get the BCH is present or not at subframe */ +#define RG_SCH_BCCH_TRUE_FALSE( _time, _bchTrue)\ +{\ + _bchTrue = FALSE;\ + /* Call the API is provided by SI module */ \ +} + +/* Mark the subframe */ +#define RG_SCH_HDFDD_MARKSTATE(_ueCb, _state, _sfn, _sfi)\ +{\ + (_ueCb)->hdFddCb->subfrm[(_sfi)].subFrmDir = _state;\ + (_ueCb)->hdFddCb->subfrm[(_sfi)].sfn = _sfn;\ +} + +/* validate the ueCb and mark */ +#define RG_SCH_HDFDD_VLDTANDMARK(_ueCb, _state, _sfn, _sfi)\ +{\ + if( (_ueCb) != NULLP && (_ueCb)->hdFddCb)\ + {\ + RG_SCH_HDFDD_MARKSTATE(_ueCb, _state, _sfn, _sfi);\ + }\ +}\ + +/* Get SFN and SFI from tti numbers */ +#define RG_SCH_HDFDD_GETPTI(_time) ((((_time).sfn * RGSCH_NUM_SUB_FRAMES + \ + (_time).subframe) + RG_SCH_HDFDD_DELTA) % RG_SCH_PCQI_SRS_SR_TRINS_SIZE) + +/* Get SFI and SFN from given time and subframe offset */ +#define RG_SCH_HDFDD_GETSFN(_sfn, _time, _offset)\ + rgSCHHdFddGetSfn(&(_sfn), (_time), (_offset)) + +/* Get SFI and SFN from given time and subframe offset */ +#define RG_SCH_HDFDD_GETSFI(_sfi, _time, _offset)\ + (_sfi) = (((_time).sfn * RGSCH_NUM_SUB_FRAMES) + \ + ((_time).subframe + _offset))% RG_SCH_HDFDD_NUMSFINFO + +/*If UE is HDFDD enabled */ +#define RG_SCH_HDFDD_UE_ENBLD(_ue) ((_ue)->hdFddEnbld) +/*If HDFDD UE is scheduled */ +#define RG_SCH_HDFDD_ISCMN_SCHED(_dlSf) ((_dlSf)->bch.tbSize || \ + (_dlSf)->bcch.tbSize || (_dlSf)->pcch.tbSize) + +#define RG_SCH_HDFDD_ROLLSFN(_sfCount, _sfn)\ +do{\ + if (_sfCount < -RGSCH_NUM_SUB_FRAMES) \ + {\ + _sfn = (_sfn + (_sfCount/RGSCH_NUM_SUB_FRAMES)) & (RGSCH_MAX_SFN - 1);\ + } \ +}while(0); + +#endif /* LTEMAC_HDFDD */ + +/* ccpu00117452 - MOD - Changed macro name from + RGR_RRM_DLPWR_CNTRL to RGR_CQI_REPT */ +#ifdef RGR_CQI_REPT + +/* Macro to check if expected CQI report collation has been done */ +#define RG_SCH_CQIR_IS_TIMTOSEND_CQIREPT(_ue)\ + ((_ue)->schCqiInfo.cqiCount >= \ + (_ue)->cqiReptCfgInfo.numColltdCqiRept ) + +/* Macro to check if PUSH N CQI Reporting is still active */ +#define RG_SCH_CQIR_IS_PUSHNCQI_ENBLE(_ue)\ + ((_ue)->cqiReptCfgInfo.numColltdCqiRept != 0) +#endif /* ifdef RGR_CQI_REPT */ + +#ifdef TFU_UPGRADE +/* Macro to check if Pa has valid value */ +#define RG_SCH_IS_PAPRSNT(_ue,_cell) (_ue->cellInfo[_ue->cellIdToCellIdxMap\ + [RG_SCH_CELLINDEX(_cell)]]->pA.pres == TRUE) +#endif + +/* Macro to check if Pa has been configured by RRM */ +#define RG_SCH_UE_CFG_ISPAPRSNT(_info) ((_info).pAPrsnt == TRUE) + +/* Macro to get absolute difference between two INT */ +#define RG_ABSLT_DIFF(x, y) ((x > y)? (x-y):(y-x)) + +/* MIB transmission Count for DL TB counter */ +#ifdef LTE_L2_MEAS +#define RG_SCH_MIB_CNT 4 +#endif + +#define RG_SCH_PFS_FLW_CTRL_TRIG_TIME 64 + +/* Interval between Transmission and feedback */ +#define RG_SCH_CMN_HARQ_INTERVAL 4 +#define RG_SCH_MAX_MPHICH 3 +#define RG_SCH_CMN_MAX_CFI 4 + +#define RGSCH_GET_SPS_SF_CFI(_dlTotalBw, _cfi)\ +{\ + if(_dlTotalBw <= 10)\ + { \ + _cfi= 2; \ + } \ + else \ + { \ + _cfi = RGSCH_MIN(2, _cfi); \ + } \ +} + +#ifdef TFU_UPGRADE +#define RG_UPD_ACQI_TRIG_WT(_ue, _cell,_isAck)\ +{\ + RgSchUeCellInfo *sCellInfo = RG_SCH_CMN_GET_SCELL_INFO(_ue,_cell);\ + if(sCellInfo->acqiCb.aCqiCfg.pres)\ + {\ + rgSCHUtlUpdACqiTrigWt(_ue, sCellInfo, _isAck);\ + }\ +} +#else +#define RG_UPD_ACQI_TRIG_WT(_ue, _cell, _isAck){} +#endif + +#define RG_SCH_MAX_HQP_SHIFT_Q_SZ 128 /*!< Length of the HqP Shift Q sizes maintained to + maintain which HqPs shall be tried on LAA SCELL + and which HqPs shall be move to PCELL */ +#define RG_SCH_HQP_TIME_ON_PCELL 32 /*!< Time in milliseconds to be allowed + for transmission of TB on PCell*/ +/* SR_RACH_STATS */ +EXTERN U32 rgNumPrachRecvd; /* Num of Rach Req received including dedicated preambles */ +EXTERN U32 rgNumRarSched; /* Num of RARs sent */ +EXTERN U32 rgNumBI; /* Num of BackOff Ind sent */ +EXTERN U32 rgNumMsg3CrcPassed; /* Num of CRC success for Msg3 */ +EXTERN U32 rgNumMsg3CrcFailed ; /* Num of CRC fail for Msg 3 */ +EXTERN U32 rgNumMsg3FailMaxRetx ; /* Num of Msg3 fail after Max Retx attempts */ +EXTERN U32 rgNumMsg4Ack ; /* Num of Acks for Msg4 Tx */ +EXTERN U32 rgNumMsg4Nack ; + /* Num of Nacks for Msg4 Tx */ +EXTERN U32 rgNumMsg4FailMaxRetx ; /* Num of Msg4 Tx failed after Max Retx attempts */ +EXTERN U32 rgNumSrRecvd; /* Num of Sched Req received */ +EXTERN U32 rgNumSrGrant; /* Num of Sched Req Grants sent */ +EXTERN U32 rgNumMsg3CrntiCE; /* Num of Msg 3 CRNTI CE received */ +EXTERN U32 rgNumDedPream ; /* Num of Dedicated Preambles recvd */ +EXTERN U32 rgNumMsg3CCCHSdu; /* Num of Msg 3 CCCH Sdus recvd */ +EXTERN U32 rgNumCCCHSduCrntiNotFound ; /*UE Ctx not found for CCCH SDU Msg 3 */ +EXTERN U32 rgNumCrntiCeCrntiNotFound ; /*UE Ctx not found for CRNTI CE Msg 3 */ +EXTERN U32 rgNumMsg4WithCCCHSdu ; /* Num of Msg4 with CCCH Sdu */ +EXTERN U32 rgNumMsg4WoCCCHSdu ; /* Num of Msg4 without CCCH Sdu */ +EXTERN U32 rgNumMsg4Dtx ; /* Num of DTX received for Msg 4 */ +EXTERN U32 rgNumMsg3AckSent ; /* Num of PHICH Ack sent for Msg 3 */ +EXTERN U32 rgNumMsg3NackSent ; /* Num of PHICH Nack sent for Msg 3 */ +EXTERN U32 rgNumMsg4PdcchWithCrnti ; /* Num of PDCCH for CRNTI based contention resolution */ +EXTERN U32 rgNumRarFailDuetoRntiExhaustion ; /* Num of RACH Failures due to RNTI pool exhaution */ +EXTERN U32 rgNumTAModified ; /* Num of times TA received is different from prev value */ +EXTERN U32 rgNumTASent ; /* Num of TA Command sent */ +EXTERN U32 rgNumMsg4ToBeTx ; /* Num of times MSG4 that should be sent */ +EXTERN U32 rgNumMsg4Txed ; /* Num of MSG4 actually sent *//* ysNumMsg4ToBeTx -ysNumMsg4Txed == Failed MSG4 TX */ +EXTERN U32 rgNumMsg3DtxRcvd; /* CRC Fail with SINR < 0 */ + +EXTERN U32 rgNumDedPreamUECtxtFound; +#endif /* __RGSCH__ */ + +/********************************************************************** + End of file +**********************************************************************/ diff --git a/src/5gnrmac/rg_sch.x b/src/5gnrmac/rg_sch.x new file mode 100755 index 000000000..ae310fb32 --- /dev/null +++ b/src/5gnrmac/rg_sch.x @@ -0,0 +1,5564 @@ +/******************************************************************************* +################################################################################ +# Copyright (c) [2017-2019] [Radisys] # +# # +# 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. # +################################################################################ +*******************************************************************************/ + +/********************************************************************** + + Name: LTE MAC layer + + Type: C include file + + Desc: Defines required by LTE MAC + + File: rg_sch.x + +**********************************************************************/ +/** @file rg_sch.x +@brief This file contains basic data structures for the scheuler. +*/ + +#ifdef TENB_STATS +#include "pj_tenb_stats.x" +#endif + +#ifndef __SCH__ +#define __SCH__ + +#ifdef TENB_STATS +#include "l2_tenb_stats.x" +#endif + +#ifdef EMTC_ENABLE +#include "rg_sch_emtc.x" +#endif + +typedef struct rgSchHistNode +{ + U32 line; + S8* file; + const S8* func; + Void * dbgVal; /* This is specific to the data struct being debug + for example if the debugging is done fo list + then this should contain the node address */ + U32 action; +}RgSchHistNode; + +#define MAX_HIST_NODES 50 + +#define RGSCH_ACTION_ADD 11 +#define RGSCH_ACTION_DEL 12 + +typedef struct rgSchHistInfo +{ + U32 histCount; + RgSchHistNode hist[MAX_HIST_NODES]; +}RgSchHistInfo; + +#define RG_SCH_RECORD(_histInfo,_action,_dbgVal)\ +{\ + (_histInfo)->hist[(_histInfo)->histCount%MAX_HIST_NODES].file = __FILE__;\ + (_histInfo)->hist[(_histInfo)->histCount%MAX_HIST_NODES].func = __FUNCTION__;\ + (_histInfo)->hist[(_histInfo)->histCount%MAX_HIST_NODES].line = __LINE__;\ + (_histInfo)->hist[(_histInfo)->histCount%MAX_HIST_NODES].action = _action;\ + (_histInfo)->hist[(_histInfo)->histCount%MAX_HIST_NODES].dbgVal = _dbgVal;\ + (_histInfo)->histCount++;\ +} + + + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +typedef TfuDciFormat1aInfo RgDciFmt1AInfo; +typedef TfuRaReqInfo RgTfuRaReqInfo; +typedef TfuSubbandCqiInfo RgSchSubbandCqiInfo; +typedef TfuHqIndInfo RgTfuHqIndInfo; +typedef TfuHqInfo RgTfuHqInfo; +typedef TfuCntrlReqInfo RgTfuCntrlReqInfo; + +/* Forward declarations for some structures */ +#ifdef LTE_L2_MEAS +typedef struct rgSchL2MeasCb RgSchL2MeasCb; +#endif /* LTE_L2_MEAS */ +typedef struct rgSchQciCb RgSchQciCb; +typedef struct rgSchUeCb RgSchUeCb; +typedef struct rgSchCellCb RgSchCellCb; +typedef struct rgSchErrInfo RgSchErrInfo; +typedef struct rgSchUlAlloc RgSchUlAlloc; +typedef struct rgSchUlRetxAlloc RgSchUlRetxAlloc; +typedef struct rgSchUlHqProcCb RgSchUlHqProcCb; +typedef struct rgSchDlHqProcCb RgSchDlHqProcCb; +/* Changes for MIMO feature addition */ +/* Removed dependency on MIMO compile-time flag */ +typedef struct rgSchDlHqTbCb RgSchDlHqTbCb; +typedef struct rgSchLcgCb RgSchLcgCb; +typedef struct rgSchDlHqEnt RgSchDlHqEnt; +typedef struct rgSchRaCb RgSchRaCb; +typedef struct _rgSchCb RgSchCb; +typedef struct rgSchUlLcCb RgSchUlLcCb; +typedef struct rgSchDlLcCb RgSchDlLcCb; +typedef struct _rgSchdApis RgSchdApis; +#ifdef LTE_TDD +typedef struct rgSchTddPhichOffInfo RgSchTddPhichOffInfo; +typedef U8 RgSchTddNpValTbl[RGSCH_TDD_MAX_P_PLUS_ONE_VAL]; +#endif +/* Added support for SPS*/ +#ifdef LTEMAC_SPS +typedef struct rgSchDlSfAllocInfo RgSchDlSfAllocInfo; +#endif + +typedef struct rgSchUeCellInfo RgSchUeCellInfo; +/** + * @brief + * Scheduler APIs + */ +struct _rgSchdApis +{ + S16 (*rgSCHRgrUeCfg) ARGS((RgSchCellCb *cell, RgSchUeCb *ue, RgrUeCfg *cfg, + RgSchErrInfo *err)); + S16 (*rgSCHRgrUeRecfg) ARGS((RgSchCellCb *cell, RgSchUeCb *ue, RgrUeRecfg *recfg, + RgSchErrInfo *err)); + Void (*rgSCHFreeUe) ARGS((RgSchCellCb *cell, RgSchUeCb *ue)); + S16 (*rgSCHRgrCellCfg) ARGS((RgSchCellCb *cell, RgrCellCfg *cfg, + RgSchErrInfo *err)); + S16 (*rgSCHRgrCellRecfg) ARGS((RgSchCellCb *cell, RgrCellRecfg *recfg, + RgSchErrInfo *err)); + Void (*rgSCHFreeCell) ARGS((RgSchCellCb *cell)); + S16 (*rgSCHRgrLchCfg) ARGS((RgSchCellCb *cell, RgSchUeCb *ue, + RgSchDlLcCb *dl, RgrLchCfg *cfg, RgSchErrInfo *errInfo)); + S16 (*rgSCHRgrLcgCfg) ARGS((RgSchCellCb *cell, RgSchUeCb *ue, + RgSchLcgCb *lcg, RgrLcgCfg *cfg, RgSchErrInfo *errInfo)); + S16 (*rgSCHRgrLchRecfg) ARGS((RgSchCellCb *cell, RgSchUeCb *ue, + RgSchDlLcCb *dl, RgrLchRecfg *recfg, + RgSchErrInfo *errInfo)); + S16 (*rgSCHRgrLcgRecfg) ARGS((RgSchCellCb *cell, RgSchUeCb *ue, + RgSchLcgCb *lcg, RgrLcgRecfg *recfg, RgSchErrInfo *errInfo)); + Void (*rgSCHFreeDlLc) ARGS((RgSchCellCb *cell, RgSchUeCb *ue, RgSchDlLcCb *dlLc)); + Void (*rgSCHFreeLcg) ARGS((RgSchCellCb *cell, RgSchUeCb *ue, RgSchLcgCb *lcg)); + S16 (*rgSCHRgrLchDel) ARGS((RgSchCellCb *cell, RgSchUeCb *ue,CmLteLcId lcId, \ + U8 lcgId)); + Void (*rgSCHActvtUlUe) ARGS((RgSchCellCb *cell, RgSchUeCb *ue)); + Void (*rgSCHActvtDlUe) ARGS((RgSchCellCb *cell, RgSchUeCb *ue)); + Void (*rgSCHHdlUlTransInd) ARGS((RgSchCellCb *cell, RgSchUeCb *ue, + CmLteTimingInfo timingInfo)); + Void (*rgSCHUeReset) ARGS((RgSchCellCb *cell, RgSchUeCb *ue)); + S16 (*rgSCHUpdBsrShort) ARGS((RgSchCellCb *cell, RgSchUeCb *ue, RgSchLcgCb *ulLcg, U8 bsr, RgSchErrInfo *err)); + S16 (*rgSCHUpdBsrTrunc) ARGS((RgSchCellCb *cell, RgSchUeCb *ue, RgSchLcgCb *ulLcg, U8 bsr, RgSchErrInfo *err)); + S16 (*rgSCHUpdBsrLong) ARGS((RgSchCellCb *cell, RgSchUeCb *ue, U8 bsArr[], RgSchErrInfo *err)); + S16 (*rgSCHUpdPhr) ARGS((RgSchCellCb *cell, RgSchUeCb *ue, U8 phr, RgSchErrInfo *err)); + S16 (*rgSCHUpdExtPhr) ARGS((RgSchCellCb *cell, RgSchUeCb *ue, RgInfExtPhrCEInfo * extPhr, RgSchErrInfo *err)); +#ifdef RG_UNUSED + S16 (*rgSCHUpdUlHqProc) ARGS((RgSchCellCb *cell, RgSchUlHqProcCb *curProc, + RgSchUlHqProcCb *oldProc)); +#endif + S16 (*rgSCHContResUlGrant) ARGS((RgSchCellCb *cell, RgSchUeCb *ue, RgSchErrInfo *err)); + S16 (*rgSCHSrRcvd) ARGS((RgSchCellCb *cell, RgSchUeCb *ue, CmLteTimingInfo, RgSchErrInfo *err)); + S16 (*rgSCHTti) ARGS((RgSchCellCb *cell, RgSchErrInfo *err)); + Void (*rgSCHUlCqiInd) ARGS(( RgSchCellCb *cell, RgSchUeCb *ue, TfuUlCqiRpt *ulCqiInfo)); + Void (*rgSCHPucchDeltaPwrInd) ARGS(( RgSchCellCb *cell, + RgSchUeCb *ue, S8 delta)); + S16 (*rgSCHlUeReset) ARGS(( RgSchCellCb *cell, RgSchUeCb *ue)); + Void (*rgSCHDlDedBoUpd) ARGS((RgSchCellCb *cell, RgSchUeCb *ue, RgSchDlLcCb *svc)); + /* ccpu00105914: PHR handling for MSG3 */ + Void (*rgSCHUlRecMsg3Alloc) ARGS((RgSchCellCb *cell, RgSchUeCb *ue, + RgSchRaCb *raCb)); + Void (*rgSCHUlHqProcForUe) ARGS((RgSchCellCb *cell, CmLteTimingInfo frm, + RgSchUeCb *ue, RgSchUlHqProcCb **procRef)); + RgSchUlAlloc *(*rgSCHFirstRcptnReq) ARGS((RgSchCellCb *cell)); + RgSchUlAlloc *(*rgSCHNextRcptnReq) ARGS((RgSchCellCb *cell, + RgSchUlAlloc *alloc)); + RgSchUlAlloc *(*rgSCHFirstHqFdbkAlloc) ARGS((RgSchCellCb *cell, U8 idx)); + RgSchUlAlloc *(*rgSCHNextHqFdbkAlloc) ARGS((RgSchCellCb *cell, + RgSchUlAlloc *alloc,U8 idx)); + Void (*rgSCHDlProcAddToRetx) ARGS((RgSchCellCb *cell,RgSchDlHqProcCb *hqP)); + Void (*rgSCHDlCqiInd) ARGS((RgSchCellCb *cell, RgSchUeCb *ue, + Bool isPucchInfo, Void *dlCqi, CmLteTimingInfo timingInfo)); +/* Added changes of TFU_UPGRADE */ +#ifdef TFU_UPGRADE +Void (*rgSCHSrsInd) ARGS((RgSchCellCb *cell, RgSchUeCb *ue, + TfuSrsRpt* srsInd, CmLteTimingInfo timingInfo)); +#endif + + Void (*rgSCHDlTARpt) ARGS((RgSchCellCb *cell, RgSchUeCb *ue)); + /* Changes for MIMO feature addition */ + /* Removed dependency on MIMO compile-time flag */ + Void (*rgSCHDlRlsSubFrm) ARGS((RgSchCellCb *cell, CmLteTimingInfo subFrm)); + /* Added support for SPS*/ +#ifdef LTEMAC_SPS + Void (*rgSCHHdlCrntiCE) ARGS((RgSchCellCb *cell, RgSchUeCb * ue)); + Void (*rgSCHDlProcAck) ARGS((RgSchCellCb *cell, RgSchDlHqProcCb *hqP)); + Void (*rgSCHDlProcDtx) ARGS((RgSchCellCb *cell, RgSchDlHqProcCb *hqP)); + Void (*rgSCHDlRelPdcchFbk) ARGS((RgSchCellCb *cell, RgSchUeCb * ue, + U8 isAck)); + Void (*rgSCHUlSpsRelInd) ARGS((RgSchCellCb *cell, RgSchUeCb * ue, + Bool isExplRel)); + + Void (*rgSCHUlSpsActInd) ARGS((RgSchCellCb *cell, RgSchUeCb * ue, + U16 sduSuze)); + + Void (*rgSCHUlCrcFailInd) ARGS((RgSchCellCb *cell, RgSchUeCb * ue, + CmLteTimingInfo crcTime)); + Void (*rgSCHUlCrcInd) ARGS((RgSchCellCb *cell, RgSchUeCb * ue, + CmLteTimingInfo crcTime)); +#endif /* LTEMAC_SPS */ + Void (*rgSCHDrxStrtInActvTmrInUl) ARGS((RgSchCellCb *cell)); + Void (*rgSCHUpdUeDataIndLcg) ARGS((RgSchCellCb *cell, RgSchUeCb * ue, RgInfUeDatInd *datInd)); +#ifdef LTE_ADV + S16 (*rgSCHRgrSCellUeCfg) ARGS((RgSchCellCb *cell, RgSchUeCb *ue ,RgrUeSecCellCfg *sCellInfoCfg, + RgSchErrInfo *err)); + S16 (*rgSCHRgrSCellUeDel) ARGS((RgSchUeCellInfo *sCellInfo, RgSchUeCb *ue)); +#endif +#ifdef EMTC_ENABLE + Void (*rgSCHUlProcAddToRetx) ARGS((RgSchCellCb *cell,RgSchUlHqProcCb *hqP)); +#endif +}; + +/* Added changes of TFU_UPGRADE */ +#ifdef TFU_UPGRADE + +/** +* @brief Periodic CQI/PMI/RI configuration parameters information +*/ +typedef RgrUePrdDlCqiCfg RgSchUeDlPCqiCfg; + +/** +* @brief Periodic CQI Setup configuration parameters information +*/ +/* Reference: 36.313: CQI-ReportPeriodic */ +typedef RgrUeDlPCqiSetup RgSchUeDlPCqiSetup; + +/** +* @brief SRS configuration parameters information +*/ +/* Reference 36.313 SoundingRS-UL-Config */ + +typedef RgrUeUlSrsCfg RgSchUeUlSrsCfg; + + +/** +* @brief SRS configuration setup parameters information +*/ +/* Reference 36.313 SoundingRS-UL-Config */ + +typedef RgrUeUlSrsSetupCfg RgSchUeSrsUlSetupCfg; + +/** +* @brief SR configuration parameters information +*/ + +typedef RgrUeSrCfg RgSchUeSrCfg; + +/** +* @brief SR Setup configuration parameters information +*/ + +typedef RgrUeSrSetupCfg RgSchUeSrSetupCfg; + +#define IOT_INVALID_FREQSTART 0xffffffff +#define IOT_INFINITE_SIZE 0xffffffff +#define RGSCH_IOT_PDCCH_POOLSZ 100 +#define RGSCH_IOT_PDSCH_POOLSZ 100 +#define RGSCH_IOT_PUSCH_POOLSZ 100 +#define RGSCH_IOT_PUCCH_POOLSZ 100 +#define RGSCH_IOT_SCHED_POOLSZ 100 +/* TODO: Minimum Delta between CRNT Time and TX time */ +#define RGSCH_IOT_PDCCH_DELTA RG_SCH_CMN_DL_DELTA +#define RGSCH_IOT_PDSCH_DELTA RG_SCH_CMN_DL_DELTA - 1 /* UL_CNTRL_DELTA value is 2*/ +#define RGSCH_IOT_PUCCH_DELTA 6 +#define RGSCH_IOT_PUSCH_DELTA 6 +#define RGSCH_IOT_PDCCH_MAXFREQSZ 24 /* MAX num of eCCEs per SF */ +#define RGSCH_IOT_PDSCH_MAXFREQSZ 100 /* MAX num of PDSCH RB per SF */ +#define RGSCH_IOT_PUCCH_MAXFREQSZ 2048 /* MAx num of PUCCH resource per SF */ +#define RGSCH_IOT_PUSCH_MAXFREQSZ 100 /* MAx num of PUSCh RB per SF */ +#define RGSCH_IOT_SCHED_MAXFREQSZ 1 /*Resource only in Time domain */ +#define RGSCH_IOT_PUCCH_INVALID_FREQ 2049 +/** + * @brief + * IoT PDCCH/PDSCH/PUSCH/PUCCH resource definition. + * For Iot Devices resource can span multiple subframes + * Hence resource is defined as a set of freq resources + * over a set of consecutive valid subframes + */ +typedef struct rgSchIotRes +{ + U32 resType; + PTR allctdBy; + CmLteTimingInfo timeStart; + CmLteTimingInfo timeEnd; + U32 tSize; + U8 freqStart; + U8 freqEnd; + U32 fSize; + CmLList lnk; /*!< Link to other Fragments or Allocs in resMngmt */ + CmLList cbLnk; /*!< Link to other allocs in a given control block (ueCb) */ + CmLList resLnk;/*! 1*/ + U32 aCqiTrigWt; /* Metric to track Aperiodic CQI Trigger occassion */ + RgSchCqiReqField cqiReqField; /* Cqi Request field. This Value can be 00 01 10 11, based upon + the cell present in which trigger list form App */ +}RgSchUeACqiCb; + +typedef enum +{ + RG_SCH_FDD_PCQI_TBL = 0, + RG_SCH_TDD_PCQI_TBL, + RG_SCH_RI_TBL, + RG_SCH_FDD_SRS_TBL, + RG_SCH_TDD_SRS_TBL, + RG_SCH_SR_TBL +} RgSchPerTbl; + +/*ccpu00116923 - ADD - SRS present support*/ +#ifdef LTE_TDD +typedef U8 RgSchTddCellSpSrsSubfrmTbl[RGSCH_CELLSP_SRS_SF_CONFIGS][RGSCH_NUM_SUB_FRAMES]; +#else +typedef U8 RgSchFddCellSpSrsSubfrmTbl[RGSCH_CELLSP_SRS_SF_CONFIGS][RGSCH_NUM_SUB_FRAMES]; +#endif + + +#endif + + + +#ifdef LTE_TDD +/** + * @brief + * Enum to define the type of Downlink subframe. + */ +typedef enum +{ + RG_SCH_SPL_SF_NO_DATA = 0, + RG_SCH_SPL_SF_DATA, + RG_SCH_DL_SF_0, + RG_SCH_DL_SF +}RgSchTddSfType; +/** + * @brief + * TDD UE specific PUCCH recpetion information. + */ +typedef struct rgSchUePucchRecpInfo +{ + CmHashListEnt hashLstEnt; /*!< List of PUCCH for receiving + ACK/NACK feedback information */ + TfuUeRecpReqInfo *pucchRecpInfo; /*!< UE PUCCH Reception information */ +} RgSchUePucchRecpInfo; + +/** + * @brief + * TDD switch point information. + */ +typedef struct rgSchTddSubfrmInfo +{ + U8 switchPoints; /*!< Number of DL-UL switch points */ + U8 numFrmHf1; /*!< Number of subframes for half frame 1 + Present for both 5ms and 10ms periodicity */ + U8 numFrmHf2; /*!< Number of subframes for half frame 2 + Present only for 5ms periodicity */ +} RgSchTddSubfrmInfo; + +/** + * @brief + * TDD DL Association Set information. + */ +typedef struct rgSchTddDlAscSetIdxK +{ + U8 numFdbkSubfrms; /*!< Number of Feedbacks for DL Subframes */ + U8 subfrmNum[RGSCH_NUM_SUB_FRAMES-1]; /*!< List of Subframe Number */ +} RgSchTddDlAscSetIdxK; + +/** @brief PRACH Information for a frequency resource. */ +typedef struct rgrSchTddPrachInfo +{ + U8 freqIdx; /*!< Frequency Index */ + U8 sfn; /*!< Even/Odd/All Radio Frames */ + U8 halfFrm; /*!< First/Second Half Frame */ + U8 ulStartSfIdx; /*!< Uplink Start Subframe Index*/ +} RgSchTddPrachInfo; + +/** @brief PRACH resource Information for each of the + * frequency resources. */ +typedef struct rgrSchTddPrachRscInfo +{ + U8 numRsc; /*!< Number of frequency resources*/ + RgSchTddPrachInfo prachInfo[RGSCH_TDD_MAX_FREQ_RSRC]; /*!< PRACH Information */ +} RgSchTddPrachRscInfo; + +/** + * @brief + * TDD Special subframe configuration information. + */ +struct rgSchTddSplSubfrmInfo +{ + U8 norDlDwPts; /*!< DL Normal CP: DwPTS in Ts */ + U8 norDlNorUpPts; /*!< DL Normal CP: UL Normal CP:UpPTS in Ts */ + U8 norDlExtUpPts; /*!< DL Normal CP: UL Extended CP: UpPTS in Ts */ + U8 extDlDwPts; /*!< DL Extended CP: DwPTS in Ts */ + U8 extDlNorUpPts; /*!< DL Extended CP: UL Normal CP:UpPTS in Ts */ + U8 extDlExtUpPts; /*!< DL Extended CP: UL Extended CP: UpPTS in Ts */ +}; + +/** + * @brief + * RACH response awaiting scheduling from the current time is + * identified with sfn offset and subframe. + */ +typedef struct rgSchTddRachRspInfo +{ + U8 sfnOffset; /*!< SFN offset with respect to + expected RACH available for + scheduling */ + U8 numSubfrms; /* Number of subframes present */ + U8 subframe[RGSCH_NUM_SUB_FRAMES]; /*!< List of Subframe numbers */ +} RgSchTddRachRspInfo; + +typedef RgSchTddRachRspInfo RgSchTddRachDelInfo; + +/** + * @brief + * List of awaiting RACH responses for scheduling across radio frames. + * + */ +typedef struct rgSchTddRachRspLst +{ + U8 numRadiofrms; /*!< Number of radio frames */ + RgSchTddRachRspInfo rachRsp[2]; /*!< RACH Occasions for which response + can be sent */ + RgSchTddRachDelInfo delInfo; /*!< Previous RACH responses for + which the scheduling deadline + has expired. So those responses + can be deleted */ +} RgSchTddRachRspLst; + +/** + * @brief + * Uplink association index information indicates the SFN offset and + * subframe in which DL HARQ ACK/NACK is expected. + */ +typedef struct rgSchTddUlAscInfo +{ + U8 subframe; /*!< Subframe number */ + U8 sfnOffset; /*!< SFN offset with respect to expected + UL data reception time */ +} RgSchTddUlAscInfo; + +/** + * @brief + * PUSCH information indicates the SFN offset and + * subframe in which UL data is scheduled. + */ +typedef struct rgSchTddPuschOffInfo +{ + U8 subframe; /*!< Subframe number */ + U8 sfnOffset; /*!< SFN offset with respect to expected + UL data reception time */ +} RgSchTddPuschOffInfo; + +/** + * @brief + * PHICH information indicates the SFN offset and + * subframe for which PHICH should be sent. + */ +struct rgSchTddPhichOffInfo +{ + U8 numSubfrms; /*!< Number of subframes */ +/* ACC-TDD */ + U8 subframe; /*!< The Uplink Subframe number corresponding + to the phich */ + U8 sfnOffset; /*!< SFN offset with respect to expected + UL data reception time */ +}; + +/** + * @brief + * DL feedback reception information indicates the SFN offset + * and subframe at which feedback is expected. + */ +typedef struct rgSchTddDlFdbkInfo +{ + U8 subframe; /*!< Subframe number */ + U8 sfnOffset; /*!< SFN offset with respect to current + scheduled time */ + U8 m; /*!< m factor used in Downlink Association + Set Index */ +#ifdef LTE_ADV /*Naw:: This is not correct */ + CmLListCp n1PucchResLst; /*!< List for storing the used N1 resource */ +#endif +} RgSchTddDlFdbkInfo; + + +/** + * @brief + * Special subframe configuration index. + */ +typedef struct rgSchTddSplSubfrmCfg +{ + U16 dwPts; /*!< DwPTS in OFDM Symbol Duration */ + U16 upPts; /*!< UpPTS in OFDM Symbol Duration */ + Bool isDlDataAllowed; /*!< To allow scheduling of DL data on + special subframe */ +} RgSchTddSplSubfrmCfg; + +/** + * @brief + * ACK/NACK information to be used for ACK/NACK bundling mode. + */ +typedef struct rgSchTddANInfo +{ + U16 sfn; /*!< ACK/NACK is sent for PDU in this SFN */ + U8 subframe; /*!< ACK/NACK is sent for PDU in this subframe */ + U8 dlDai; /*!< Downlink Assignment Index for + UL-DL Configuration 1-6 */ + U8 ulDai; /*!< DAI for uplink */ + U8 latestMIdx; /*!< Last transmitted DL subframe 'm' index */ + U8 n1ResTpcIdx; /*!< N1 Res idx for scell assigned in TPC command */ + Bool isSpsOccasion; /*!< To indicate the presence of SPS occasion */ +#ifdef LTE_ADV + U8 wUlDai; /*!< Max Ul dai in all the cells */ +#endif +} RgSchTddANInfo; +#endif + +/** + * @brief + * Information about one MCS entry. + */ +typedef struct rgSchUlIMcsInfo +{ + U8 qm; + U8 iTbs; +} RgSchUlIMcsTbl[29]; +EXTERN RgSchUlIMcsTbl rgUlIMcsTbl; + +typedef struct rgSchUeCatTbl +{ + U32 maxUlBits;/*Maximum number of + bits of an UL-SCH + transport block + transmitted within a + TTI*/ + U32 maxDlBits[4];/*Maximum number of + bits of a DLSCH + transport block + received within a TTI*/ +/* correcting DL harq softbuffer limitation logic */ + U32 maxSftChBits;/*Total number of soft channel bits*/ + Bool ul64qamSup;/*Support for 64QAM in UL*/ +/* Changes for MIMO feature addition */ +/* Removed dependency on MIMO compile-time flag */ + U32 maxDlTbBits;/*Maximum number of DL-SCH + transport block bits + received within a TTI*/ + U8 maxTxLyrs;/*Maximum number of supported + layers for spatial multiplexing + in DL*/ +} RgSchUeCatTbl[CM_MAX_UE_CAT_SUPP + 1]; +EXTERN RgSchUeCatTbl rgUeCatTbl; + +/* Changes for MIMO feature addition */ +/* Removed dependency on MIMO compile-time flag */ +typedef U32 RgSchTbSzTbl[RGSCH_MAX_NUM_LYR_PERCW][RGSCH_NUM_ITBS][RGSCH_MAX_NUM_RB]; + +#ifdef LTE_TDD +typedef U8 RgSchRaPrmblToRaFrmTbl[RGSCH_MAX_TDD_RA_PREAMBLE_FMT+1]; +#else +/* Added matrix 'rgRaPrmblToRaFrmTbl' for computation of RA + sub-frames from preamble format */ +typedef U8 RgSchRaPrmblToRaFrmTbl[RGSCH_MAX_RA_PREAMBLE_FMT+1]; +#endif +EXTERN RgSchRaPrmblToRaFrmTbl rgRaPrmblToRaFrmTbl; + +EXTERN U8 rgRvTable[4]; + +typedef struct rgDciFmt +{ + U8 dciType; + union + { + RgDciFmt1AInfo dci1a; + } dci; +} RgDciFmt; + +typedef enum rgSchPdcchSearchSpace +{ + RG_SCH_UE_SPECIFIC_SEARCH_SPACE, + RG_SCH_CMN_SEARCH_SPACE, +}RgSchPdcchSearchSpace; + +/** + * @brief + * Information about one PDCCH. + */ +typedef struct rgSchPdcch { + U8 nCce; /*!< CCE index */ + CmLteAggrLvl aggrLvl; /*!< Aggregation level */ + TfuDciInfo dci; /*!< PDCCH format */ + U16 rnti; /*!< RNTI to who the PDCCH is allocated */ +#if (defined (LTE_TDD)) + U8 dlDai; /*!< DAI associated with this PDCCH. + THis is used for F1BCS resource calulcation */ +#endif + /* Added support for SPS*/ +#ifdef LTEMAC_SPS + CmLteTimingInfo relFbkTiming; /*!< Feebback timing information for release + PDCCH */ + Bool isSpsRnti; /*!< TRUE if rnti is SPS RNTI */ + U16 crnti; /*!< CRNTI to who the PDCCH is allocated */ +#endif + CmLList lnk; /*!< To link PDCCHs in a subframe */ +#ifdef EMTC_ENABLE + Void *emtcPdcch; +#endif + RgSchUeCb *ue; /*!< Pointer to the UE Control Block */ + RgSchPdcchSearchSpace pdcchSearchSpace; /*!< Search Space from this PDCCH allocated */ + U8 dciNumOfBits; /*!< Size of DCI in bits */ +} RgSchPdcch; + +/** + * @brief + * PDCCH information for cell. + */ +typedef struct rgSchPdcchInfo { + U8 *map; /*!< Bit map of PDCCHs */ + U8 currCfi; /*!< Number of CCEs */ + U16 nCce; /*!< Total CCEs */ + CmLListCp pdcchs; /*!< List of RgSchPdcch */ +} RgSchPdcchInfo; + +typedef struct rgSchPhich +{ + CmLList lnk; /*!< To link PHICHs in a subframe */ + U8 hqFeedBack; /*!< Harq Feed Back */ + U8 rbStart; /*!< Starting RB */ + U8 nDmrs; /*!< 3 bits for DMRS cyclic shift */ + /* changes for passing iphich at TFU;*/ + Bool isForMsg3; /*! < Phich Ack/Nack conveyed for MSG 3 */ +#ifdef LTE_TDD + U8 iPhich; /*!< For determining phich group */ +#endif +} RgSchPhich; + +typedef struct rgSchPhichInfo +{ + CmLListCp phichs; /*!< List of RgSchPhich */ +} RgSchPhichInfo; + +typedef struct rgSchBcchTb +{ + RgSchPdcch *pdcch; + Buffer *tb; + U16 tbSize; +} RgSchBcchTb; + +typedef struct rgSchPcchTb +{ + RgSchPdcch *pdcch; + Buffer *tb; + U16 tbSize; +} RgSchPcchTb; + +typedef struct rgSchRaRspAlloc +{ + U16 raRnti; + U32 tbSz; + TknU8 backOffInd; /*!< Backoff index value */ + CmLListCp raRspLst; /*!< List of RaCbs */ + CmLListCp contFreeUeLst; /*! List of HandOver or PdcchOrder UEs */ + RgSchPdcch *pdcch; /*!< NULLP if no Rsp allocation done for raRnti*/ +}RgSchRaRspAlloc; + +typedef struct rgSchBchTb +{ + Buffer *tb; /*!< BCH data for this frame */ + U16 tbSize; /*!< Non-Zero if bch data is scheduled for this SF */ +}RgSchBchTb; + +/* Added support for SPS*/ +#ifdef LTEMAC_SPS +/** + * TODO: check compilation + @brief Downlink Resource allocation type information. */ +struct rgSchDlSfAllocInfo +{ + U32 raType0Mask; /*!< RBG allocation mask for type 0*/ + U32 raType1Mask[RG_SCH_NUM_RATYPE1_32BIT_MASK]; /*!< RA Type 1 + allocation mask */ + U32 raType1UsedRbs[RG_SCH_NUM_RATYPE1_32BIT_MASK];/*!< RA Type 1 Used RBs + per subset */ + U32 nxtRbgSubset; /*!< Next RBG subset to be used for allocation */ + U32 raType2Mask[RG_SCH_NUM_RATYPE2_32BIT_MASK]; + /*!< Mask for resource allocation type 2 */ +}; +#endif /* LTEMAC_SPS */ + +/* LTE_ADV_FLAG_REMOVED_START */ +/** + @brief RGR RB range for SFR */ +typedef struct rgrPwrHiCCRange +{ + U8 startRb; /*ueLst */ + Void * laaCb; + CmLListCp hqPLst; /*!< This is a list of hq proc per DL + SF which are scheduled in that SF. + The number of harq procs awaiting + feedback for the same subframe depends on + mode TDD or FDD and max number of Carriers + that can be aggregated */ +#ifdef LTE_ADV + RgSchN3PucchRes n3ScellPucch; +#endif +}RgSchDlHqInfo; + +/*CA Dev End*/ +/** @brief This structure contains the Measurement gap configuration for an UE. + */ +typedef struct rgUeMeasGapCfg +{ + Bool isMesGapEnabled; /*!< Is Measuremnet gap enabled or disabled */ + U8 gapPrd; /*!< Gap period 40ms/80ms */ + U8 gapOffst; /*!< Gap offset - Vaue is 0 to 1*/ +} RgUeMeasGapCfg; + +/** + @brief Measurement Gap related information per UE. */ +typedef struct rgSchUeMeasGapCb +{ + Bool isMesGapEnabled;/*!< TRUE if Measurement gap is enabled for this UE */ + U8 isMeasuring; /*!< Set to TRUE during measurement gap */ + U8 gapPrd; /*!< Measurement gap period configuration for the UE */ + U8 gapOffst; /*!< Measurement gap offset for the UE */ + CmLList measQLnk; /*!< To Link to the measurement gap list */ + CmLList ackNakQLnk; /*!< To Link to the ACK NACK Rep list */ + CmTimer measGapTmr; /*!< Timer for Measurement Gap */ + CmTimer measGapUlInactvTmr; /*!< UL Inactive timer for measurement gap */ + CmTimer measGapDlInactvTmr; /*!< DL Inactive timer for measurement gap */ +} RgSchUeMeasGapCb; + +/** + @brief ACK-NACK repetition related information per UE. */ +typedef struct rgSchUeAckNakRepCb +{ + Bool isAckNackEnabled; /*!< Is ACK/NACK Enabled*/ + U8 isAckNakRep; /*!< Set to TRUE during ACK-NACK repetition prd */ + U8 cfgRepCnt; /*!< Configured value for the repetition counter */ + U8 repCntr; /*!< Actual repetition counter */ + U16 pucchRes; /*!< PUCCH resource for repetition */ + CmTimer ackNakRepUlInactvTmr; /*!< UL Inactive timer for ack-nack repetition */ + CmTimer ackNakRepDlInactvTmr; /*!< DL Inactive timer for ack-nack repetition */ + CmTimer ackNakRepTmr; /*!< Timer for ack-nack repetition */ + CmLList ackNakRepLnk; /*!< ACK NACK repetition queue link */ + CmLListCp *prsntQ; /*!< Pointer to the Queue that this UE is current + present in. */ +} RgSchUeAckNakRepCb; + +/** + * @brief + * UE's MIMO specific information. + */ +typedef struct rgSchUeMimoInfo +{ + RgrTxMode oldTMode; /*!< UE's Previous Transmission Mode */ + RgrTxMode txMode; /*!< UE's Transmission Mode */ + TknU32 doa; /*!< DOA indicator for this UE */ + Bool puschFdbkVld; /*!< True if Precoding Info in PDCCH has to be + in-accordance with the latest PUSCH report */ + TfuDlCqiPuschInfo puschPmiInfo; /*!< PUSCH report details for explicit PMI + * information to PHY during a PDSCH */ + RgrCodeBookRstCfg cdbkSbstRstrctn; /*!< Codebook subset restriction defined as per + * 36.331 section 6.3.2. As of now, this info + * is not processed by MAC. SCH shall use the + * PMI reported by UE unconditionally.*/ +#ifdef DL_LA + S32 txModUpChgFactor; /*!< tx mode chnage factor for step up*/ + S32 txModDownChgFactor; /*!< tx mode chnage factor for step + Down*/ +#endif +}RgSchUeMimoInfo; + +/* Added changes of TFU_UPGRADE */ +#ifdef TFU_UPGRADE + +/** @brief This structure that stores the length of Bits that +* will be received over PUSCH for Aperiodic Mode 3-1. +*/ +typedef struct rgSchCqiRawPuschMode31 +{ + U8 wideBCqiCw0; /*!< Length of Wideband CQI Codeword 0 */ + U8 totLenSbDiffCqiCw0; /*!< Length of SubBand Differential CQI Codeword 0 */ + U8 r1WideBCqiCw1; /*!< Length of Wideband CQI Codeword 1 for Rank =1*/ + U8 r1TotLenSbDiffCqiCw1; /*!< Length of SubBand Differential CQI Codeword 1 for Rank = 1*/ + U8 rg1WideBCqiCw1; /*!< Length of Wideband CQI Codeword 1 for Rank > 1*/ + U8 rg1TotLenSbDiffCqiCw1; /*!< Length of SubBand Differential CQI Codeword 1 for Rank > 1*/ + U8 r1PmiBitLen; /*!< Length of PMI Bits for Rank = 1*/ + U8 rg1PmiBitLen; /*!< Length of PMI Bits for Rank > 1*/ +} RgSchCqiRawPuschMode31; + +/** @brief This structure that stores the length of Bits that +* will be received over PUSCH for Aperiodic Mode 3-0. +*/ +typedef struct rgSchCqiRawPuschMode30 +{ + U8 wideBCqiCw; /*!< Length of Wideband CQI */ + U8 totLenSbDiffCqi; /*!< Length of SubBand Differential CQI */ +} RgSchCqiRawPuschMode30; + +/** @brief This structure that stores the length of Bits that +* will be received over PUSCH for Aperiodic Mode 2-2. +*/ +typedef struct rgSchCqiRawPuschMode22 +{ + U8 wideBCqiCw0; /*!< Length of Wideband CQI Codeword 0 */ + U8 sBDiffCqiCw0; /*!< Length of SubBand Differential CQI Codeword 0 */ + U8 r1WideBCqiCw1; /*!< Length of Wideband CQI Codeword 1 for Rank =1 */ + U8 r1SbDiffCqiCw1; /*!< Length of SubBand Differential CQI Codeword 1 for Rank =1*/ + U8 rg1WideBCqiCw1; /*!< Length of Wideband CQI Codeword 1 for Rank > 1*/ + U8 rg1SbDiffCqiCw1; /*!< Length of SubBand Differential CQI Codeword 1 for Rank >1*/ + U8 posOfM; /*!< Position of M selected SubBands */ + U8 r1PmiBitLen; /*!< Length of PMI Bits for Rank =1*/ + U8 rg1PmiBitLen; /*!< Length of PMI Bits for Rank >1*/ +} RgSchCqiRawPuschMode22; + +/** @brief This structure that stores the length of Bits that +* will be received over PUSCH for Aperiodic Mode 2-0. +*/ +typedef struct rgSchCqiRawPuschMode20 +{ + U8 wideBCqiCw; /*!< Length of Wideband CQI */ + U8 subBandDiffCqi; /*!< Length of SubBand Differential CQI */ + U8 posOfM; /*!< Position of M selected SubBands */ +} RgSchCqiRawPuschMode20; + +/** @brief This structure that stores the length of Bits that +* will be received over PUSCH for Aperiodic Mode 1-2. +*/ +typedef struct rgSchCqiRawPuschMode12 +{ + U8 wideBCqiCw0; /*!< Length of Wideband CQI Codeword 0 */ + U8 r1WideBCqiCw1; /*!< Length of Wideband CQI Codeword 1 for Rank =1*/ + U8 rg1WideBCqiCw1; /*!< Length of Wideband CQI Codeword for Rank > 1 */ + U8 r1TotalPmiBitLen; /*!< Aggregate length of PMI Bits for Rank =1 */ + U8 rg1TotalPmiBitLen; /*!< Aggregate length of PMI Bits for Rank > 1 */ +} RgSchCqiRawPuschMode12; + + +/** @brief This structure that stores the length of Bits that +* will be received over PUSCH. +*/ +typedef struct rgSchDlCqiRawPusch +{ + TfuDlCqiPuschMode mode; /*!< PUSCH CQI mode */ + TknU8 ri; /*!< Rank Indicator for TM 3,4 */ + union + { + RgSchCqiRawPuschMode12 mode12Info; /*!< Mode 1-2 information */ + RgSchCqiRawPuschMode20 mode20Info; /*!< Mode 2-0 information */ + RgSchCqiRawPuschMode22 mode22Info; /*!< Mode 2-2 information */ + RgSchCqiRawPuschMode30 mode30Info; /*!< Mode 3-0 information */ + RgSchCqiRawPuschMode31 mode31Info; /*!< Mode 3-1 information */ + }u; +} RgSchDlCqiRawPusch; + +typedef struct rgSchPuschRawCqiInfoPerCell +{ + U8 sCellIdx; /*!< Serving cell idx of the cell for + this cqi info*/ + RgSchDlCqiRawPusch puschRawCqiInfo; /*!< Raw CQI Bit Width for PUSCH */ +} RgSchPuschRawCqiInfoPerCell; + +typedef struct rgSchPuschRawCqiInfoForSCells +{ + U8 numOfCells; /* Num of cells for which Apcqi is comming*/ + RgSchPuschRawCqiInfoPerCell cqiBitWidth[CM_LTE_MAX_CELLS]; +} RgSchPuschRawCqiInfoForSCells; + +typedef struct rgSchPucchRawCqiInfoPerCell +{ + U8 sCellIdx; /*!< Serving cell idx of the cell for + this cqi info*/ + TfuDlCqiPucch pucchRawCqiInfo; /*!< Raw CQI Bit Width for PUCCH */ +} RgSchPucchRawCqiInfoPerCell; + +typedef struct rgSchUeRawCqiBitWidthInfo +{ + TfuRecpReqType type; /*!< Type indicating PUCCH or PUSCH */ + CmLteTimingInfo recvTime; + union + { + RgSchPucchRawCqiInfoPerCell pucch; + RgSchPuschRawCqiInfoForSCells pusch; + }u; +} RgSchUeRawCqiBitWidthInfo; +#endif + + +/* CaDev start */ +#ifdef LTE_ADV + +/** + * @brief + * Enum for storing the different states of a Scell + * RG_SCH_SCELL_INACTIVE : SCell is added but not activate + * RG_SCH_SCELL_TOBE_ACTIVATED : SCell Activation trigger condition is met + Need to be scheduled. + * RG_SCH_SCELL_ACTVTN_IN_PROG : Waiting for Harq feedback for the scell activation + * RG_SCH_SCELL_ACTIVE : SCell is activated succesfully + */ +typedef enum +{ + RG_SCH_SCELL_INACTIVE = 0, /*!sfInfo[(_sfi)].sfType = _state;\ +} + +/* Mark sfi as UL Subframe */ +#define RG_SCH_DYN_TDD_MARKTYPE_UL(_dynTdd, _sfi)\ +{\ + RG_SCH_DYN_TDD_MARKTYPE(_dynTdd, _sfi, RG_SCH_DYNTDD_DLC_ULD);\ +} + +/* Mark sfi as DL Subframe */ +#define RG_SCH_DYN_TDD_MARKTYPE_DL(_dynTdd, _sfi)\ +{\ + RG_SCH_DYN_TDD_MARKTYPE(_dynTdd, _sfi, RG_SCH_DYNTDD_DLC_DLD);\ +} + +/* Get SFI and SFN from given time and subframe offset */ +#define RG_SCH_DYN_TDD_GET_SFIDX(_sfi, _crntSfIdx, _offset)\ + (_sfi) = (_crntSfIdx + _offset)% RG_SCH_DYNTDD_MAX_SFINFO + +/** + @brief Dynamic TDD subframe type. */ + +typedef struct rgSchDynTddSfType +{ + U8 sfType; /*!< 0= NOT Defined + 1= DL Cntrl + DL Data + 2= DL Cntrl + DL Data + UL Cntrl + 3= DL Cntrl + UL Data + 4= DL Cntrl + UL Data + UL Cntrl + */ + +}RgSchDynTddSfType; +/** + @brief Dynamic TDD control Block */ + +typedef struct rgSchDynTddCb +{ + Bool isDynTddEnbld; /*!< Is dynamic TDD enabled */ + U8 crntDTddSfIdx; /*!< Pivot Index corresponding + cell's current subframe */ + RgSchDynTddSfType sfInfo[RG_SCH_DYNTDD_MAX_SFINFO]; +}RgSchDynTddCb; + +#endif + +/** + * @brief + * Global Control block for LTE-MAC. + */ +struct _rgSchCb +{ + TskInit rgSchInit; /*!< Task Init info */ + RgSchGenCb genCfg; /*!< General Config info */ + U8 numSaps; /*!< Num RGR Saps = Num TFU Saps */ + RgSchUpSapCb *rgrSap; /*!< RGR SAP Control Block */ + RgSchLowSapCb *tfuSap; /*!< TFU SAP Control Block */ + RgSchUpSapCb *rgmSap; /*!< TFU SAP Control Block */ + CmTqCp tmrTqCp; /*!< Timer Task Queue Cntrl Point */ + CmTqType tmrTq[RGSCH_TQ_SIZE]; /*!< Timer Task Queue */ + U8 rgSchDlDelta; /* 4UE_TTI_DELTA */ + U8 rgSchCmnDlDelta; + U8 rgSchUlDelta; + RgSchCellCb *cells[CM_LTE_MAX_CELLS]; /* Array to store cellCb ptr */ + RgrSchedEnbCfg rgrSchedEnbCfg; /*!< eNB level RR/PFS Config */ + Void *rgSchEnbPfsDl; /*!< eNB level PFS DL Block */ + + Void * laaCb; +#ifdef RG_5GTF + RgSchDynTddCb rgSchDynTdd; /*!< Dynamic TDD Control Block */ +#endif +}; + +/* Declaration for scheduler control blocks */ +EXTERN RgSchCb rgSchCb[RGSCH_MAX_INST]; + +/* + * Data structures for RAM + */ + +/** + * @brief + * Random Access Req Info to be stored in cellCb. + */ +typedef struct rgSchRaReqInfo +{ + CmLList raReqLstEnt; /*!< Linked list entity for RaReq List */ + CmLteTimingInfo timingInfo; /*!< RACHO: Time of RaReq Reception */ + RgTfuRaReqInfo raReq; /*!< Random Access Request Information */ + RgSchUeCb *ue; /*!< UECB if RAP ID is a dedicated one */ +} RgSchRaReqInfo; + +/** + * @enum rgSchRaState + * Enumeration of random access states. + */ +typedef enum rgSchRaState +{ + RGSCH_RA_MSG3_PENDING, /*!< Msg3 reception pending */ + RGSCH_RA_MSG4_PENDING, /*!< Msg4 transmission pending */ + RGSCH_RA_MSG4_DONE /*!< Msg4 transmission successful */ +} RgSchRaState; + +/** + * @brief + * Control block for Random Access. + */ +struct rgSchRaCb +{ + CmLList raCbLnk; /*!< To link to the raCb list */ + CmLList schdLnk; /*!< To link raCb to the "to be scheduled" + list */ + CmLteRnti tmpCrnti; /*!< Temporary C-RNTI */ + CmLteTimingInfo timingInfo; /*!< Timing information */ + RgSchRntiLnk *rntiLnk; /*!< Link to RNTI for raCb */ + RgSchRaState raState; /*!< Random access state */ + struct + { + U32 bo; /*!< Buffer occupancy for CCCH */ + } dlCcchInfo; /*!< Params for DL CCCH */ + U8 msg3HqProcId; /*!< Msg3 Harq Process ID */ + /*ccpu00128820 - DEL - msg3HqProcRef is delete for Msg3 alloc double delete issue*/ + RgSchUlHqProcCb msg3HqProc; /*!< msg3HqProcRef points to this initially */ + RgSchUeCb *ue; /*!< NULL initially */ + Bool toDel; /*!< To delete this RaCb after msg4 reject */ + TknU8 phr; /*!< To store the PHR, if received along with + Msg3 */ + CmLList rspLnk; /*!< Used to link RACB to a frame for resp */ + U8 rapId; /*!< RAP ID */ + TknU16 ta; /*!< Timing Adjustment */ + RgSchUlGrnt msg3Grnt; /*!< Msg3 grant as given by the UL Sched */ + U32 y[RGSCH_NUM_SUB_FRAMES]; /*!< y values using tmpCrnti by DLSCHED */ + RgSchDlHqEnt *dlHqE; /*!< DL HARQ module */ + U8 ccchCqi; /*!< DL Cqi obtained from RaReq and Used for CCCH */ + RgSchDlRbAlloc rbAllocInfo; /*!< RB Allocation Info for MSG4 Trans/Retrans */ + /* PHR handling for MSG3 */ + CmLteTimingInfo msg3AllocTime; /*!< Allocation time for msg3 grant */ +#ifdef RGR_V1 + /* CR timer changes*/ + CmLList contResTmrLnk; /*!< To link raCb to the + Guard Timer/Contention Resolution timer list*/ + CmLteTimingInfo expiryTime; /*!< Expiry time for Guard/Contention + Resolution timers */ + + U32 ccchSduBo; /*!rntiLnk */ +EXTERN Void rgSCHUtlIndRntiRls2Mac ARGS(( RgSchCellCb *cell, CmLteRnti rnti, + Bool ueIdChng, CmLteRnti newRnti)); + +/*rg008.201 - Added support for SPS*/ +#ifdef LTEMAC_SPS +EXTERN S16 rgSCHDbmDeInitSpsUeCbLst ARGS((RgSchCellCb *cellCb)); +EXTERN S16 rgSCHDbmInsSpsUeCb ARGS((RgSchCellCb *cellCb, RgSchUeCb *ueCb)); +EXTERN RgSchUeCb* rgSCHDbmGetSpsUeCb ARGS((RgSchCellCb *cellCb, CmLteRnti ueId)); +EXTERN RgSchUeCb* rgSCHDbmGetNextSpsUeCb ARGS((RgSchCellCb *cellCb, RgSchUeCb *ueCb)); +EXTERN S16 rgSCHDbmDelSpsUeCb ARGS((RgSchCellCb *cellCb,RgSchUeCb *ueCb)); +#endif /* LTEMAC_SPS */ + +#ifdef LTE_L2_MEAS +/* + * L2M APIs + */ +EXTERN S16 rgSchL2mMeasReq ARGS (( + RgSchCellCb *cell, + LrgSchMeasReqInfo *measInfo, + RgSchErrInfo err)); +EXTERN S16 RgSchMacL2MeasSend ARGS +(( +Pst* pst, +RgInfL2MeasSndReq *measInfo +)); + +EXTERN S16 RgSchMacL2MeasStop ARGS +(( +Pst* pst, +RgInfL2MeasStopReq *measInfo +)); +#endif /* LTE_L2_MEAS */ +/* + * DHM APIs + */ +/* LTE_ADV_FLAG_REMOVED_START */ +EXTERN S16 rgSchSFRTotalPoolInit ARGS((RgSchCellCb *cell, RgSchDlSf *sf)); +/* LTE_ADV_FLAG_REMOVED_END */ +EXTERN Void rgSCHDhmHqPAdd2FreeLst ARGS (( RgSchDlHqProcCb *hqP)); +EXTERN Void rgSCHDhmHqPAdd2InUseLst ARGS (( RgSchDlHqProcCb *hqP)); +EXTERN Void rgSCHDhmHqPDelFrmFreeLst ARGS (( RgSchDlHqProcCb *hqP)); +EXTERN Void rgSCHDhmHqPDelFrmInUseLst ARGS (( RgSchDlHqProcCb *hqP)); + +EXTERN RgSchDlHqEnt *rgSCHDhmHqEntInit ARGS((RgSchCellCb *cell)); +EXTERN S16 rgSCHDhmGetAvlHqProc ARGS((RgSchCellCb *cell, RgSchUeCb *ue, CmLteTimingInfo timingInfo, + RgSchDlHqProcCb **hqP)); +EXTERN Void rgSCHDhmHqRetx ARGS((RgSchDlHqEnt *hqE, CmLteTimingInfo timeInfo, + RgSchDlHqProcCb *hqP)); +EXTERN RgSchDlHqProcCb * rgSCHDhmLastSchedHqProc ARGS((RgSchDlHqEnt *hqE)); +/* CR timer changes*/ +EXTERN S16 rgSCHDhmGetCcchSduHqProc ARGS((RgSchUeCb *ueCb, CmLteTimingInfo timeInfo, + RgSchDlHqProcCb **hqP)); +EXTERN S16 rgSCHDhmGetMsg4HqProc ARGS((RgSchRaCb *raCb, CmLteTimingInfo timeInfo)); +EXTERN Void rgSCHDhmRlsHqProc ARGS((RgSchDlHqProcCb *hqP)); +/* ccpu00118350 : Correcting NDI manipulation of Harq */ +EXTERN Void rgSCHDhmRlsHqpTb ARGS((RgSchDlHqProcCb *hqP, U8 tbIdx, Bool togNdi)); +EXTERN Void rgSCHUtlDlHqPTbAddToTx ARGS((RgSchDlSf *subFrm, +RgSchDlHqProcCb *hqP, U8 tbIdx )); +EXTERN Void rgSCHDhmHqTbRetx ARGS(( RgSchDlHqEnt *hqE, +CmLteTimingInfo timingInfo, RgSchDlHqProcCb *hqP, U8 tbIdx)); +EXTERN Void rgSCHUtlDlHqPTbAddToTx ARGS((RgSchDlSf *subFrm, +RgSchDlHqProcCb *hqP, U8 tbIdx )); +EXTERN Void rgSCHDhmHqTbRetx ARGS(( RgSchDlHqEnt *hqE, +CmLteTimingInfo timingInfo, RgSchDlHqProcCb *hqP, U8 tbIdx)); +#ifdef RG_UNUSED +EXTERN S16 rgSCHDhmGetHqProcFrmId ARGS((RgSchCellCb *cell, RgSchUeCb *ue, U8 idx, + RgSchDlHqProcCb **hqP)); +#endif +/* Changes for MIMO feature addition */ +EXTERN Void rgSCHDhmSchdTa ARGS((RgSchUeCb *ueCb, RgSchDlHqTbCb *tbInfo)); +EXTERN S16 rgSCHDhmHqFdbkInd ARGS((Void *cb, U8 cbType, RgSchCellCb *cellCb, + CmLteTimingInfo timingInfo, RgTfuHqInfo *fdbk, RgInfRlsHqInfo + *rlsHqBufs,RgSchErrInfo *err)); +#ifdef EMTC_ENABLE +EXTERN S16 rgSCHDhmEmtcHqFdbkInd ARGS((Void *cb, U8 cbType, RgSchCellCb *cellCb, + CmLteTimingInfo timingInfo, RgTfuHqInfo *fdbk, RgInfRlsHqInfo + *rlsHqBufs,RgSchErrInfo *err)); +EXTERN PUBLIC S16 rgSCHUtlAddToResLst +( + CmLListCp *cp, + RgSchIotRes *iotRes + ); +#endif +/*CA Dev Start */ +EXTERN S16 rgSCHDhmPrcFdbkForTb(RgSchCellCb *cell,RgSchUeCb *ue, + RgSchDlHqProcCb *hqP,RgSchDlSf *sf,Bool isMsg4, + U16 rnti,U8 tbCnt,CmLteTimingInfo timingInfo, U8 isAck, + RgInfRlsHqInfo *rlsHqBufs,RgSchErrInfo *err + ); +/*CA Dev End */ +EXTERN Void rgSCHDhmRgrUeCfg ARGS((RgSchCellCb *cellCb, RgSchUeCb *ueCb, + RgrUeCfg *ueCfg, RgSchErrInfo *err)); +EXTERN Void rgSCHDhmRgrUeRecfg ARGS((RgSchCellCb *cellCb, RgSchUeCb *ueCb, + RgrUeRecfg *ueCfg, RgSchErrInfo *err)); +EXTERN Void rgSCHDhmRgrCellCfg ARGS((RgSchCellCb *cellCb, RgrCellCfg *cellCfg, + RgSchErrInfo *err)); +EXTERN Void rgSCHDhmRgrCellRecfg ARGS((RgSchCellCb *cellCb, RgrCellRecfg + *cellRecfg, RgSchErrInfo *err)); +EXTERN Void rgSCHDhmFreeUe ARGS((RgSchUeCb *ueCb)); +EXTERN Void rgSCHDhmUpdTa ARGS((RgSchCellCb *cellCb, RgSchUeCb *ueCb, U8 ta)); +EXTERN Void rgSCHDhmProcTAExp ARGS((RgSchUeCb *ue)); +/* Changes for MIMO feature addition */ +EXTERN S16 rgSCHDhmAddLcData ARGS((Inst inst, RgSchLchAllocInfo *lchData, + RgSchDlHqTbCb *tbInfo)); +EXTERN S16 rgSCHDhmRlsDlsfHqProc ARGS((RgSchCellCb *cellCb, CmLteTimingInfo +timingInfo)); + +#ifdef LTE_TDD +EXTERN S16 rgSCHDhmTddRlsSubFrm ARGS((RgSchCellCb *cell, CmLteTimingInfo uciTimingInfo)); +EXTERN S16 rgSCHCfgVldtTddDrxCycCfg ARGS((RgSchCellCb *cell, U16 drxCycle, + U8 onDurTmr, U16 offSet)); +#endif +/* Added support for SPS*/ +#ifdef LTEMAC_SPS +EXTERN S16 rgSCHDhmGetHqProcFrmId ARGS(( +RgSchCellCb *cell, +RgSchUeCb *ue, +U8 idx, +RgSchDlHqProcCb **hqP +)); +#endif /* LTEMAC_SPS */ +/* Freeing up the HARQ proc blocked for + * indefinite time in case of Retx */ +EXTERN S16 rgSCHDhmDlRetxAllocFail ARGS(( +RgSchUeCb *ue, +RgSchDlHqProcCb *proc +)); +/* MS_WORKAROUND for ccpu00122893 temp fix Incorrect HqProc release was done instead of + * a Harq Entity reset. Fixing the same */ +EXTERN Void rgSCHDhmHqEntReset ARGS(( + RgSchDlHqEnt *hqE +)); +/* Measurement GAP and ACK NACK */ + +EXTERN S16 rgSCHMeasGapANRepUeCfg ARGS(( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgrUeCfg *ueCfg +)); +EXTERN S16 rgSCHMeasGapANRepUeRecfg ARGS(( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgrUeRecfg *ueRecfg +)); +/* ccpu00133470- Added extra argument to identify UE DEL*/ +EXTERN Void rgSCHMeasGapANRepUeDel ARGS(( +RgSchCellCb *cell, +RgSchUeCb *ue, +Bool isUeDel +)); +EXTERN S16 rgSCHMeasGapANRepTtiHndl ARGS(( +RgSchCellCb *cell +)); +EXTERN S16 rgSCHMeasGapANRepGetDlInactvUe ARGS(( +RgSchCellCb *cell, +CmLListCp *dlInactvUeLst +)); +EXTERN S16 rgSCHMeasGapANRepGetUlInactvUe ARGS(( +RgSchCellCb *cell, +CmLListCp *ulInactvUeLst +)); +EXTERN Void rgSCHMeasGapANRepDlInactvTmrExpry ARGS(( +RgSchUeCb *ue, +U8 tmrEvnt +)); +EXTERN Void rgSCHMeasGapANRepUlInactvTmrExpry ARGS(( +RgSchUeCb *ue, +U8 tmrEvnt +)); +EXTERN Void rgSCHMeasGapANRepTmrExpry ARGS(( +RgSchUeCb *ue +)); +EXTERN Void rgSCHAckNakRepTmrExpry ARGS(( +RgSchUeCb *ue +)); +EXTERN Void rgSCHAckNakRepSndHqFbkRcpReq ARGS(( +RgSchCellCb *cell, +RgSchDlSf *dlSf, +CmLteTimingInfo timingInfo)); + +EXTERN Void rgSCHAckNakRepAddToQ ARGS(( +RgSchCellCb *cell, +RgSchDlSf *crntDlSf)); + +/* + * SCH Util APIs + */ +#ifdef LTEMAC_SPS +EXTERN Void rgSCHUtlHdlCrcInd ARGS(( +RgSchCellCb *cell, +RgSchUeCb *ue, +CmLteTimingInfo timingInfo +)); +#endif + +#ifdef LTE_L2_MEAS +EXTERN S16 rgSCHUtlValidateMeasReq ARGS ((RgSchCellCb *cellCb, + LrgSchMeasReqInfo *schL2MeasInfo, + RgSchErrInfo *err + )); +EXTERN S16 rgSchL2mSndCfm ARGS((Pst *pst, + RgSchL2MeasCb *measCb, + LrgSchMeasReqInfo *measInfo, + Bool isErr +)); +EXTERN S16 rgSchFillL2MeasCfm ARGS(( + RgSchCellCb *cell, + RgSchL2MeasCb *measCb, + LrgSchMeasCfmInfo *cfm, + U32 measTime +)); +EXTERN Void rgSchL2mFillCfmPst ARGS(( + Pst *pst, + Pst *cfmPst, + LrgSchMeasReqInfo *measInfo +)); +EXTERN S16 rgSCHL2Meas ARGS(( + RgSchCellCb *cell, + U8 isCalrCrcInd +)); +#endif /* LTE_L2_MEAS */ +/* Added changes of TFU_UPGRADE */ +#ifdef TFU_UPGRADE +EXTERN F64 rgSCHUtlPower ARGS +(( +F64 x, +F64 n +)); + + EXTERN U32 rgSCHUtlParse ARGS + (( + U8 *buff, + U8 startPos, + U8 endPos, + U8 buffSize + )); + + EXTERN U8 rgSCHUtlFindDist ARGS +(( +U16 crntTime, +U16 tempIdx +)); +#endif +EXTERN Bool rgSCHUtlPdcchAvail ARGS((RgSchCellCb *cell, RgSchPdcchInfo + *pdcchInfo, CmLteAggrLvl aggrLvl, RgSchPdcch **pdcch)); +EXTERN Void rgSCHUtlPdcchPut ARGS((RgSchCellCb *cell, RgSchPdcchInfo *pdcchInfo, + RgSchPdcch *pdcch)); +#ifdef LTE_TDD +/* Changes for passing iPhich at TFU interface*/ +EXTERN S16 rgSCHUtlAddPhich ARGS((RgSchCellCb *cellCb, CmLteTimingInfo frm, + U8 hqFeedBack, U8 nDmrs, U8 rbStart, U8 iPhich)); +#else +EXTERN S16 rgSCHUtlAddPhich ARGS((RgSchCellCb *cellCb, CmLteTimingInfo frm, + U8 hqFeedBack, U8 nDmrs, U8 rbStart,Bool isForMsg3)); +#endif +EXTERN RgSchDlSf* rgSCHUtlSubFrmGet ARGS((RgSchCellCb *cell, + CmLteTimingInfo frm)); +EXTERN Void rgSCHUtlSubFrmPut ARGS((RgSchCellCb *cell, RgSchDlSf *sf)); +EXTERN U8 rgSCHUtlLog32bitNbase2 ARGS((U32 n)); +/* Added support for SPS*/ + + +#ifdef LTEMAC_SPS +EXTERN RgSchDlHqProcCb * rgSCHDhmSpsDlGetHqProc ARGS((RgSchCellCb *cell, RgSchUeCb *ue, +CmLteTimingInfo timingInfo)); +#endif +#ifdef LTE_TDD +EXTERN U8 rgSCHUtlCalcNCce ARGS((U8 bw, RgrPhichNg ng, U8 cfi, U8 mPhich, + U8 numAntna, Bool isEcp)); +#else +EXTERN U8 rgSCHUtlCalcNCce ARGS((U8 bw, RgrPhichNg ng, U8 cfi, U8 numAntna, Bool +isEcp)); +#endif +#ifdef LTE_TDD +/* Changes for passing iPhich at TFU interface*/ +EXTERN S16 rgSCHUtlGetPhichInfo ARGS((RgSchUlHqProcCb *hqProc, U8 *rbStartRef, + U8 *nDmrsRef, U8 *iPhich)); +#else +EXTERN S16 rgSCHUtlGetPhichInfo ARGS((RgSchUlHqProcCb *hqProc, U8 *rbStartRef, + U8 *nDmrsRef)); +#endif +/* Added changes of TFU_UPGRADE */ +#ifndef TFU_UPGRADE +/* To include the length and ModOrder in DataRecp Req. */ +/* Updating NDI and HARQ proc Id */ +EXTERN S16 rgSCHUtlAllocRcptInfo ARGS((RgSchUlAlloc *alloc, CmLteRnti *rnti, + U8 *iMcsRef, U8 *rbStartRef, U8 *numRbRef, U8 *rvRef, U16 *size, + TfuModScheme *modType,Bool *isRtx, +U8 *nDmrs, +Bool *ndi, +U8 *hqPId)); +#else +EXTERN S16 rgSCHUtlAllocRcptInfo ARGS(( + RgSchCellCb *cell, + RgSchUlAlloc *alloc, + CmLteTimingInfo *timeInfo, + TfuUeUlSchRecpInfo *recpReq + )); +#endif /* TFU_UPGRADE */ + +EXTERN S16 rgSCHUtlRgrCellCfg ARGS((RgSchCellCb *cell, RgrCellCfg *cellCfg, + RgSchErrInfo *errInfo)); +EXTERN S16 rgSCHUtlRgrCellRecfg ARGS((RgSchCellCb *cell, RgrCellRecfg *recfg, + RgSchErrInfo *errInfo)); +EXTERN S16 rgSCHUtlFreeCell ARGS((RgSchCellCb *cell)); +EXTERN S16 rgSCHUtlRgrUeCfg ARGS((RgSchCellCb *cell, RgSchUeCb *ue, + RgrUeCfg *cfg, RgSchErrInfo *err)); +EXTERN S16 rgSCHUtlRgrLcCfg ARGS((RgSchCellCb *cell, RgSchUeCb *ue, + RgSchDlLcCb *dl, RgrLchCfg *cfg,RgSchErrInfo *errInfo)); +EXTERN S16 rgSCHUtlRgrLcDel ARGS((RgSchCellCb *cell, RgSchUeCb *ue, + CmLteLcId lcId, U8 lcgId)); +EXTERN S16 rgSCHUtlRgrLcRecfg ARGS ((RgSchCellCb *cell,RgSchUeCb *ue, + RgSchDlLcCb *dlLc,RgrLchRecfg *recfg,RgSchErrInfo *err)); +EXTERN S16 rgSCHUtlRgrLcgCfg ARGS ((RgSchCellCb *cell,RgSchUeCb *ue, + RgrLcgCfg *cfg,RgSchErrInfo *errInfo)); +EXTERN S16 rgSCHUtlRgrLcgRecfg ARGS ((RgSchCellCb *cell,RgSchUeCb *ue, + RgrLcgRecfg *recfg,RgSchErrInfo *err)); +EXTERN Void rgSCHUtlRgrLcgDel ARGS ((RgSchCellCb *cell,RgSchUeCb *ue, + U8 lcgId)); +EXTERN Void rgSCHUtlDlCqiInd ARGS((RgSchCellCb *cell, RgSchUeCb *ue, + TfuDlCqiRpt *dlCqiInd, CmLteTimingInfo timingInfo)); + +/* Added changes of TFU_UPGRADE */ +#ifdef TFU_UPGRADE +EXTERN Void rgSCHUtlRawCqiInd ARGS +(( +RgSchCellCb *cell, +RgSchUeCb *ue, +TfuRawCqiRpt* rawCqiRpt, +CmLteTimingInfo timingInfo +)); + +EXTERN Void rgSCHUtlSrsInd ARGS +(( +RgSchCellCb *cell, +RgSchUeCb *ue, +TfuSrsRpt* srsRpt, +CmLteTimingInfo timingInfo +)); +EXTERN S16 rgSCHUtlGetCfgPerOff ARGS +(( +RgSchPerTbl tbl, +U16 cfgIdx, +U16 *peri, +U16 *offset +)); +#endif + +EXTERN Void rgSCHUtlDoaInd ARGS((RgSchCellCb *cell, RgSchUeCb *ue, + TfuDoaRpt *doaInd)); +EXTERN Void rgSCHUtlDlTARpt ARGS((RgSchCellCb *cell, RgSchUeCb *ue)); +/* Changes for MIMO feature addition */ +EXTERN Void rgSCHUtlDlRlsSubFrm ARGS((RgSchCellCb *cell, CmLteTimingInfo subFrm)); +EXTERN Void rgSCHUtlDlProcAddToRetx ARGS((RgSchCellCb *cell, + RgSchDlHqProcCb *hqP)); +EXTERN S16 rgSCHUtlRegSch ARGS((U8 schIdx, RgSchdApis *apis)); +EXTERN Void rgSCHUtlDlHqProcAddToTx ARGS((RgSchDlSf *subFrm, RgSchDlHqProcCb *hqP)); +/* Changes for MIMO feature addition */ +EXTERN Void rgSCHUtlDlHqPTbRmvFrmTx ARGS((RgSchDlSf *subFrm, + RgSchDlHqProcCb *hqP, U8 tbIdx, Bool isRepeating)); +EXTERN S16 rgSCHUtlRgrUeRecfg ARGS((RgSchCellCb *cell, RgSchUeCb *ue, + RgrUeRecfg *recfg, RgSchErrInfo *err)); +EXTERN Void rgSCHUtlFreeDlLc ARGS((RgSchCellCb *cell, RgSchUeCb *ue, + RgSchDlLcCb *dlLc)); +EXTERN Void rgSCHUtlFreeUlLc ARGS((RgSchCellCb *cell, RgSchUeCb *ue, + RgSchUlLcCb *ulLc)); +EXTERN Void rgSCHUtlFreeUe ARGS((RgSchCellCb *cell, RgSchUeCb *ue)); +EXTERN Void rgSCHUtlDlDedBoUpd ARGS((RgSchCellCb *cell, RgSchUeCb *ue, + RgSchDlLcCb *svc)); +#ifdef RG_UNUSED +EXTERN S16 rgSCHUtlUpdUlHqProc ARGS((RgSchCellCb *cell, RgSchUlHqProcCb *curProc, + RgSchUlHqProcCb *oldProc)); +#endif +/* PHR handling for MSG3 */ +EXTERN Void rgSCHUtlRecMsg3Alloc ARGS((RgSchCellCb *cell, RgSchUeCb *ue, + RgSchRaCb *raCb)); +EXTERN S16 rgSCHUtlContResUlGrant ARGS((RgSchCellCb *cell, RgSchUeCb *ue, + RgSchErrInfo *err)); +EXTERN S16 rgSCHUtlSrRcvd ARGS((RgSchCellCb *cell, RgSchUeCb *ue, + CmLteTimingInfo, RgSchErrInfo *err)); +EXTERN Void rgSCHUtlUpdBsrShort ARGS((RgSchCellCb *cell, RgSchUeCb *ue, U8 lcgId, + U8 bsr, RgSchErrInfo *err)); +EXTERN Void rgSCHUtlUpdBsrTrunc ARGS((RgSchCellCb *cell, RgSchUeCb *ue, U8 lcgId, + U8 bsr, RgSchErrInfo *err)); +EXTERN Void rgSCHUtlUpdBsrLong ARGS((RgSchCellCb *cell, RgSchUeCb *ue, + U8 bsr1,U8 bsr2,U8 bsr3,U8 bsr4, RgSchErrInfo *err)); +EXTERN S16 rgSCHUtlUpdPhr ARGS((RgSchCellCb *cell, RgSchUeCb *ue, + U8 phr, RgSchErrInfo *err)); +EXTERN S16 rgSCHUtlUpdExtPhr ARGS(( RgSchCellCb *cell, RgSchUeCb *ue, +RgInfExtPhrCEInfo * extPhr, RgSchErrInfo *err)); +EXTERN S16 rgSCHUtlDataRcvd ARGS((RgSchCellCb *cell, RgSchUeCb *ue, U8 numLc, + RgSchUlLcCb *lcArr[], U16 bytesArr[], RgSchErrInfo *err)); +EXTERN Void rgSCHUtlUlCqiInd ARGS(( RgSchCellCb *cell, RgSchUeCb *ue, + TfuUlCqiRpt *ulCqiInfo)); +EXTERN Void rgSCHUtlPucchDeltaPwrInd ARGS(( RgSchCellCb *cell, RgSchUeCb *ue, + S8 delta)); +EXTERN Void rgSCHUtlUeReset ARGS(( RgSchCellCb *cell, RgSchUeCb *ue)); +EXTERN Void rgSCHUtlUlHqProcForUe ARGS((RgSchCellCb *cell, CmLteTimingInfo frm, + RgSchUeCb *ue, RgSchUlHqProcCb **procRef)); +EXTERN RgSchUlAlloc *rgSCHUtlFirstRcptnReq ARGS((RgSchCellCb *cell)); +EXTERN RgSchUlAlloc *rgSCHUtlNextRcptnReq ARGS((RgSchCellCb *cell, + RgSchUlAlloc *alloc)); +EXTERN RgSchUlAlloc *rgSCHUtlFirstHqFdbkAlloc ARGS((RgSchCellCb *cell, U8 idx)); +EXTERN RgSchUlAlloc *rgSCHUtlNextHqFdbkAlloc ARGS((RgSchCellCb *cell, + RgSchUlAlloc *alloc, U8 idx)); +EXTERN S16 rgSCHUtlTfuBndReq ARGS((Inst inst, SuId suId, SpId spId)); +EXTERN S16 rgSCHUtlTfuUBndReq ARGS((Inst inst, RgSchLowSapCfgInfo sapCfg, Reason reason)); +#ifdef EMTC_ENABLE +EXTERN S16 rgSCHEmtcUtlResetSfAlloc ARGS((RgInfSfAlloc *sfAlloc, + Bool resetCmnLcInfo, Bool restAlloc)); +#endif +EXTERN S16 rgSCHUtlResetSfAlloc ARGS((RgInfSfAlloc *sfAlloc, + Bool resetCmnLcInfo, Bool restAlloc)); +EXTERN S16 rgSCHUtlGetSfAlloc ARGS((RgSchCellCb *cell)); +EXTERN S16 rgSCHUtlPutSfAlloc ARGS((RgSchCellCb *cell)); +EXTERN S16 rgSCHUtlAllocSBuf ARGS((Inst inst, Data **pData, Size size)); +/* ccpu00117052 - MOD - Passing double pointer +for proper NULLP assignment*/ +EXTERN Void rgSCHUtlFreeSBuf ARGS((Inst inst, Data **data, Size size)); +EXTERN Void rgSCHUtlFillDgnParams ARGS((Inst inst, RgUstaDgn *dgn,U8 dgnType)); +EXTERN Void rgSCHUtlGetPstToLyr ARGS((Pst *pst,RgSchCb *schCb,Inst macInst)); +EXTERN S16 rgSCHUtlFillRgInfCmnLcInfo ARGS((RgSchDlSf *sf,RgInfSfAlloc *sfAlloc, + CmLteLcId lcId, Bool sendInd)); +EXTERN S16 rgSCHUtlFillRgInfRarInfo ARGS((RgSchDlSf *sf,RgInfSfAlloc *sfAlloc,RgSchCellCb *cell)); +EXTERN S16 rgSCHUtlFillPdschDciInfo ARGS((TfuPdschDciInfo *pdschDci,TfuDciInfo + *pdcchDci)); + /* CA dev Start */ +EXTERN Void rgSCHUtlFillRgInfUeInfo ARGS((RgSchDlSf*, RgSchCellCb *cell, CmLListCp *dlDrxInactvTmrLst, + CmLListCp *dlInActvLst, CmLListCp *ulInActvLst)); + /* CA dev End */ +EXTERN S16 rgSCHUtlUpdSch ARGS((RgInfSfDatInd *subfrmInfo, RgSchCellCb *cellCb, + RgSchUeCb *ueCb, RgInfUeDatInd *pdu,RgSchErrInfo *err)); +EXTERN S16 rgSCHUtlHndlCcchBoUpdt ARGS((RgSchCellCb *cell,RgInfCmnBoRpt *boRpt)); +EXTERN S16 rgSCHUtlHndlBcchPcchBoUpdt ARGS((RgSchCellCb *cell,RgInfCmnBoRpt + *boUpdt)); +EXTERN S16 rgSCHUtlRgrBndCfm ARGS ((Inst inst, SuId suId,U8 status)); +/* Added for sending TTI tick to RRM */ +#ifdef RGR_RRM_TICK +EXTERN S16 rgSCHUtlRgrTtiInd ARGS ((RgSchCellCb *cell, RgrTtiIndInfo *ttiInd)); +#endif +EXTERN S16 rgSCHUtlRgrCfgCfm ARGS ((Inst inst, SpId spId, + RgrCfgTransId transId,U8 status)); +EXTERN S16 rgSCHUtlProcMsg3 ARGS((RgInfSfDatInd *subfrmInfo, RgSchCellCb *cellCb, + RgSchUeCb *ueCb, CmLteRnti rnti,RgInfUeDatInd *pdu, + RgSchErrInfo *err )); +#ifdef RG_PHASE_2 +EXTERN S16 rgSCHUtlTfuGrpPwrCntrlReq ARGS((Inst inst,S16 sapId, + TfuGrpPwrCntrlReqInfo *grpPwrCntrlReq)); +#endif +EXTERN S16 rgSCHUtlTfuCntrlReq ARGS((Inst inst, S16 sapId, + TfuCntrlReqInfo *cntrlReq)); +EXTERN S16 rgSCHUtlTfuRecpReq ARGS((Inst inst, S16 sapId, + TfuRecpReqInfo *recpReq)); +EXTERN S16 rgSCHUtlValidateTfuSap ARGS((Inst inst,SuId suId)); +EXTERN S16 rgSCHUtlAllocEventMem ARGS((Inst inst,Ptr *memPtr,Size memSize)); +EXTERN S16 rgSCHUtlGetEventMem ARGS((Ptr *ptr,Size len,Ptr memCpa)); +EXTERN S16 rgSCHUtlGetRlsHqAlloc ARGS((RgSchCellCb *cell)); +EXTERN S16 rgSCHUtlPutRlsHqAlloc ARGS((RgSchCellCb *cell)); + +EXTERN S16 rgSCHUtlDlActvtUe ARGS((RgSchCellCb *cell, RgSchUeCb *ue)); +EXTERN S16 rgSCHUtlUlActvtUe ARGS((RgSchCellCb *cell, RgSchUeCb *ue)); +EXTERN Void rgSCHUtlHdlUlTransInd ARGS((RgSchCellCb *cell, RgSchUeCb *ue, + CmLteTimingInfo timingInfo)); +#ifdef TFU_UPGRADE +EXTERN Void rgSCHUtlUpdACqiTrigWt ARGS((RgSchUeCb *ue,RgSchUeCellInfo *sCellInfo, U8 isAck)); +#endif +/* Nprb indication at PHY for common Ch */ +/* Corrected allocation for common channels */ +EXTERN PUBLIC S32 rgSCHUtlGetAllwdCchTbSz ARGS((U32 bo, U8 *nPrb, U8 *mcs +)); +/* CR timer changes*/ +EXTERN PUBLIC S16 rgSCHUtlUpdtBo ARGS((RgSchCellCb *cell, + RgInfCmnBoRpt *staRsp)); +EXTERN PUBLIC S16 rgSCHUtlAddUeToCcchSduLst ARGS( + (RgSchCellCb *cell, + RgSchUeCb *ueCb)); +#ifdef EMTC_ENABLE +EXTERN PUBLIC S16 rgSCHUtlAddUeToEmtcCcchSduLst ARGS( + (RgSchCellCb *cell, + RgSchUeCb *ueCb)); + +EXTERN S16 rgSCHRamRmvFrmEmtcRaInfoSchdLst ARGS((RgSchCellCb *cell, RgSchRaCb *raCb)); +EXTERN Void rgSCHRamEmtcDelRaCb ARGS((RgSchCellCb *cell, RgSchRaCb *raCb)); +EXTERN S16 rgSCHRamEmtcUpdtBo ARGS((RgSchCellCb *cell, RgSchRaCb *raCb, + RgInfCmnBoRpt *staRsp)); +#endif +/* Added for SI Enhancement*/ +#ifdef RGR_SI_SCH +EXTERN Void rgSCHUtlPutSiInfo ARGS((RgSchCellCb *cell)); +EXTERN Void rgSCHUtlFreeWarningSiSeg ARGS((Region reg,Pool pool, + CmLListCp *siPduLst)); +EXTERN Void rgSCHUtlFreeWarningSiPdu ARGS((RgSchCellCb *cell)); +EXTERN Buffer *rgSCHUtlGetWarningSiPdu ARGS((RgSchCellCb *cell)); +EXTERN S16 rgSCHUtlGetMcsAndNPrb ARGS((RgSchCellCb *cell, U8 *nPrb, U8 *mcs, MsgLen *msgLen)); +EXTERN S16 rgSCHUtlCalMcsAndNPrb ARGS((RgSchCellCb *cell, U8 cfgType, MsgLen msgLen, U8 siId)); +#endif/*RGR_SI_SCH*/ + +#ifdef LTE_TDD +EXTERN S16 rgSCHUtlAllocUeANFdbkInfo ARGS((RgSchUeCb *ue,U8 servCellIdx)); +EXTERN Void rgSCHUtlDelUeANFdbkInfo ARGS((RgSchUeCb *ue,U8 servCellIdx)); +EXTERN S16 rgSCHUtlInitUeANFdbkInfo ARGS((RgSchTddANInfo *anInfo)); +EXTERN RgSchTddANInfo* rgSCHUtlGetUeANFdbkInfo ARGS((RgSchUeCb *ueCb, CmLteTimingInfo *timeInfo,U8 servCellIdx)); +EXTERN U8 rgSCHUtlGetDlSfIdx ARGS((RgSchCellCb *cell, CmLteTimingInfo *timeInfo)); +EXTERN Void rgSCHUtlPrachCfgInit ARGS((RgSchCellCb *cell, RgrCellCfg *cellCfg )); +EXTERN Void rgSCHUtlGetNxtDlSfInfo ARGS((CmLteTimingInfo curDlTime, RgSchCellCb *cell, RgSchDlSf *dlSf, RgSchDlSf **nxtDlsf, CmLteTimingInfo *nxtDlTime)); +EXTERN Void rgSCHUtlGetPrevDlSfInfo ARGS((RgSchCellCb * cell, CmLteTimingInfo curDlTime, CmLteTimingInfo *prevDlTime, U8 *numSubfrm)); +#endif +EXTERN Void rgSCHCmnDlSch ARGS +(( +RgSchCellCb *cell +)); +EXTERN Void rgSCHCmnSndCnsldtInfo ARGS +(( +RgSchCellCb *cell +)); +EXTERN Void rgSCHCmnCnsldtSfAlloc ARGS +(( +RgSchCellCb *cell +)); + +/* Added support for SPS*/ +EXTERN Void rgSCHCmnDlAllocFnlz ARGS +(( +RgSchCellCb *cell +)); + +#ifdef LTEMAC_SPS +EXTERN Void rgSCHUtlDlRelPdcchFbk ARGS(( +RgSchCellCb *cell, +RgSchUeCb *ue, +Bool isAck +)); + +EXTERN Void rgSCHUtlDlProcAck ARGS(( +RgSchCellCb *cell, +RgSchDlHqProcCb *hqP +)); +EXTERN S16 rgSCHUtlSpsRelInd ARGS(( +RgSchCellCb *cellCb, +RgSchUeCb *ueCb, +Bool isExplRel +)); + +EXTERN Void rgSCHCmnDlSch ARGS +(( +RgSchCellCb *cell +)); + +EXTERN S16 rgSCHUtlSpsActInd ARGS(( +RgSchCellCb *cellCb, +RgSchUeCb *ueCb, +U16 spsSduSize +)); + +EXTERN Void rgSCHUtlHdlCrcFailInd ARGS(( +RgSchCellCb *cell, +RgSchUeCb *ue, +CmLteTimingInfo timingInfo +)); + +EXTERN Void rgSCHUtlHdlCrntiCE ARGS(( +RgSchCellCb *cell, +RgSchUeCb *ue +)); + +#endif /* LTEMAC_SPS*/ + +/******* : START *****/ +EXTERN S16 rgSCHUtlUlSfInit ARGS(( + RgSchCellCb *cell, + RgSchUlSf *sf, + U8 idx, + U8 maxUePerSf + )); +EXTERN Void rgSCHUtlUlSfDeinit ARGS(( + RgSchCellCb *cell, + RgSchUlSf *sf + )); +EXTERN RgSchUlAlloc *rgSCHUtlUlAllocGetHole ARGS(( + RgSchUlSf *sf, + U8 numRb, + RgSchUlHole *hole + )); +EXTERN RgSchUlAlloc *rgSCHUtlUlAllocGetCompHole ARGS(( + RgSchUlSf *sf, + RgSchUlHole *hole + )); +EXTERN RgSchUlAlloc *rgSCHUtlUlAllocGetPartHole ARGS(( + RgSchUlSf *sf, + U8 numRb, + RgSchUlHole *hole + )); +EXTERN Void rgSCHUtlUlAllocRls ARGS(( + RgSchUlSf *sf, + RgSchUlAlloc *alloc + )); + +/* UL_ALLOC_ENHANCEMENT */ +EXTERN Void rgSCHUtlUlAllocRelease ARGS(( + RgSchUlAlloc *alloc + )); +EXTERN RgSchUlAlloc *rgSCHUtlUlAllocFirst ARGS(( + RgSchUlSf *sf + )); +EXTERN RgSchUlAlloc *rgSCHUtlUlAllocNxt ARGS(( + RgSchUlSf *sf, + RgSchUlAlloc *alloc + )); +EXTERN RgSchUlHole *rgSCHUtlUlHoleFirst ARGS(( + RgSchUlSf *sf + )); +EXTERN RgSchUlHole *rgSCHUtlUlHoleNxt ARGS(( + RgSchUlSf *sf, + RgSchUlHole *hole + )); +EXTERN RgSchUlAlloc *rgSCHUtlUlAllocGetAdjNxt ARGS(( + RgSchUlAllocDb *db, + RgSchUlAlloc *prv + )); +EXTERN RgSchUlAlloc *rgSCHUtlUlAllocGetFirst ARGS(( + RgSchUlAllocDb *db + )); +EXTERN Void rgSCHUtlUlHoleAddAlloc ARGS(( + RgSchUlSf *sf, + RgSchUlAlloc *alloc + )); +/* UL_ALLOC_ENHANCEMENT */ +EXTERN Void rgSCHUtlUlHoleAddAllocation ARGS(( + RgSchUlAlloc *alloc + )); + +EXTERN Void rgSCHUtlUlHoleJoin ARGS(( + RgSchUlHoleDb *db, + RgSchUlHole *prv, + RgSchUlHole *nxt, + RgSchUlAlloc *alloc + )); +EXTERN Void rgSCHUtlUlHoleExtndRight ARGS(( + RgSchUlHoleDb *db, + RgSchUlHole *prv, + RgSchUlAlloc *alloc + )); +EXTERN Void rgSCHUtlUlHoleExtndLeft ARGS(( + RgSchUlHoleDb *db, + RgSchUlHole *nxt, + RgSchUlAlloc *alloc + )); +EXTERN Void rgSCHUtlUlHoleNew ARGS(( + RgSchUlHoleDb *db, + RgSchUlAlloc *alloc + )); +EXTERN Void rgSCHUtlUlHoleUpdAllocLnks ARGS(( + RgSchUlHole *hole, + RgSchUlAlloc *prvAlloc, + RgSchUlAlloc *nxtAlloc + )); +EXTERN Void rgSCHUtlUlHoleIns ARGS(( + RgSchUlHoleDb *db, + RgSchUlHole *hole + )); +EXTERN Void rgSCHUtlUlHoleIncr ARGS(( + RgSchUlHoleDb *db, + RgSchUlHole *hole + )); +EXTERN Void rgSCHUtlUlHoleDecr ARGS(( + RgSchUlHoleDb *db, + RgSchUlHole *hole + )); +EXTERN Void rgSCHUtlUlHoleRls ARGS(( + RgSchUlHoleDb *db, + RgSchUlHole *hole + )); +EXTERN S16 rgSCHUtlUlAllocMemInit ARGS(( + RgSchCellCb *cell, + RgSchUlAllocMem *mem, + U8 maxAllocs + )); +EXTERN Void rgSCHUtlUlAllocMemDeinit ARGS(( + RgSchCellCb *cell, + RgSchUlAllocMem *mem + )); +EXTERN S16 rgSCHUtlUlHoleMemInit ARGS(( + RgSchCellCb *cell, + RgSchUlHoleMem *mem, + U8 maxHoles, + RgSchUlHole **holeRef + )); +EXTERN Void rgSCHUtlUlHoleMemDeinit ARGS(( + RgSchCellCb *cell, + RgSchUlHoleMem *mem + )); +EXTERN RgSchUlAlloc *rgSCHUtlUlAllocMemGet ARGS(( + RgSchUlAllocMem *mem + )); +EXTERN Void rgSCHUtlUlAllocMemRls ARGS(( + RgSchUlAllocMem *mem, + RgSchUlAlloc *alloc + )); +EXTERN RgSchUlHole *rgSCHUtlUlHoleMemGet ARGS(( + RgSchUlHoleMem *mem + )); +EXTERN Void rgSCHUtlUlHoleMemRls ARGS(( + RgSchUlHoleMem *mem, + RgSchUlHole *hole + )); +EXTERN RgSchUlAlloc *rgSCHUtlUlGetSpfcAlloc ARGS(( + RgSchUlSf *sf, + U8 startSb, + U8 numSb +)); +/******* : END *****/ + +/* DRX function declarations */ +EXTERN S16 rgSCHDrxCellCfg ARGS((RgSchCellCb *cell, RgrCellCfg *cellCfg)); +EXTERN Void rgSCHDrxCellDel ARGS((RgSchCellCb *cell)); +EXTERN S16 rgSCHDrxUeCfg ARGS((RgSchCellCb *cell, RgSchUeCb *ue, + RgrUeCfg *ueCfg)); +#ifdef RGR_V2 +EXTERN S16 rgSCHDrxUeReCfg ARGS((RgSchCellCb *cell, RgSchUeCb *ue, + RgrUeRecfg *ueCfg)); +#endif +EXTERN S16 rgSCHDrxUeDel ARGS((RgSchCellCb *cell,RgSchUeCb *ue)); +EXTERN Void rgSCHDrxTtiInd ARGS ((RgSchCellCb *cell)); + +EXTERN S16 rgSCHDrxSfAlloc ARGS ((RgSchCellCb *cellCb, RgSchDlSf + *dlSf)); +EXTERN S16 rgSCHDrxDlTrnsFail ARGS((RgSchCellCb *cell, RgSchDlHqProcCb + *dlHq)); +EXTERN Void rgSCHDrxDedRa ARGS((RgSchCellCb *cellCb, RgSchUeCb* ueCb)); +EXTERN S16 rgSCHDrxSrInd ARGS((RgSchCellCb *cell,RgSchUeCb *ue)); + +EXTERN Void rgSCHDrxStrtInActvTmr ARGS((RgSchCellCb *cell, + CmLListCp *ueLst, + U8 direction)); +EXTERN S16 rgSCHUtlGetDrxSchdUesInDl ARGS((RgSchCellCb *cellCb, + RgSchUeCb *ueCb, + RgSchDlHqProcCb *dlHq, + RgInfUeAlloc *allocInfo, + CmLListCp *dlDrxInactvTmrLst, + CmLListCp *dlInActvLst, + CmLListCp *ulInActvLst)); +EXTERN Void rgSCHDrxStartHarqRTTTmr ARGS((RgSchCellCb *cell, + RgSchDlHqProcCb *hqP, + U8 tbCnt)); +EXTERN Void rgSCHDrxUeHqReset ARGS((RgSchCellCb *cell, + RgSchUeCb *ue, + RgSchDlHqEnt *hqE, + U8 cellIdx)); + +#ifdef TFU_UPGRADE +#ifdef LTE_TDD +EXTERN CONSTANT PUBLIC RgSchTddCellSpSrsSubfrmTbl rgSchTddCellSpSrsSubfrmTbl; +#else +EXTERN CONSTANT PUBLIC RgSchFddCellSpSrsSubfrmTbl rgSchFddCellSpSrsSubfrmTbl; +#endif +#endif + +#ifdef LTEMAC_HDFDD +EXTERN S16 rgSCHHdFddUeCfg ARGS(( + RgSchCellCb *cellCb, + RgSchUeCb *ueCb, + Bool hdFdd)); +EXTERN S16 rgSCHHdFddUeDel ARGS(( + RgSchCellCb *cellCb, + RgSchUeCb *ueCb)); +EXTERN Void rgSCHCmnHdFddPtUlMrk ARGS(( + RgSchCellCb *cellCb)); +EXTERN Void rgSCHCmnHdFddChkUlAllow ARGS(( + RgSchCellCb *cellCb, + RgSchUeCb *ueCb, + U8 *flag)); +EXTERN Void rgSCHCmnHdFddChkDlAllow ARGS(( + RgSchCellCb *cellCb, + RgSchUeCb *ueCb, + Bool *flag)); +EXTERN Void rgSCHCmnHdFddChkNackAllow ARGS(( + RgSchCellCb *cellCb, + RgSchUeCb *ueCb, + CmLteTimingInfo timInfo, + Bool *flag)); +EXTERN Void rgSCHCmnHdFddUpdULMark ARGS(( + RgSchCellCb *cellCb, + RgSchUeCb *ueCb)); +EXTERN Void rgSCHCmnHdFddUpdDLMark ARGS(( + RgSchCellCb *cellCb, + RgSchUeCb *ueCb)); +EXTERN Void rgSCHHdFddGetSfn ARGS(( + U16 *sfn, + CmLteTimingInfo timeInfo, + S16 offset)); +#endif /* ifdef LTEMAC_HDFDD */ + +/* ccpu00117452 - MOD - Changed macro name from + RGR_RRM_DLPWR_CNTRL to RGR_CQI_REPT */ +#ifdef RGR_CQI_REPT +PUBLIC S16 rgSCHUtlRgrStaInd ARGS(( +RgSchCellCb *cell, +RgrStaIndInfo *rgrSta +)); + +PUBLIC S16 rgSCHUtlFillSndStaInd ARGS(( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgrStaIndInfo *staInfo, +U8 numCqiRept +)); +#endif /* End of RGR_CQI_REPT */ +PUBLIC S16 rgSCHUtlRgrUeStaInd ARGS(( +RgSchCellCb *cell, +RgrUeStaIndInfo *rgrUeSta +)); + +PUBLIC S16 rgSCHUtlFillSndUeStaInd ARGS(( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgrUeStaIndInfo *ueStaInfo +)); + + +/* LTE_ADV_FLAG_REMOVED_START */ +PUBLIC S16 rgSCHUtlRgrLoadInfInd ARGS(( +RgSchCellCb *cell, +RgrLoadInfIndInfo *rgrLoadInf +)); +/* LTE_ADV_FLAG_REMOVED_END */ +#ifdef LTE_ADV +#ifdef TFU_UPGRADE +PUBLIC TfuAckNackMode rgSchUtlGetFdbkMode ARGS(( +RgrSchFrmt1b3TypEnum fdbkType +)); + +EXTERN TfuAckNackMode rgSchUtlGetFdbkMode ARGS(( +RgrSchFrmt1b3TypEnum fdbkType +)); + +#endif /*TFU_UPGRADE */ +#endif /* LTE_ADV */ +/* FIX */ +PUBLIC Void rgSCHUtlRlsRnti ARGS(( +RgSchCellCb *cellCb, +RgSchRntiLnk *rntiLnk, +Bool ueIdChngd, +CmLteRnti newRnti +)); +PUBLIC S16 rgSCHUtlRgmBndCfm ARGS(( +Inst instId, +SuId suId, +U8 status +)); +PUBLIC Void rgSCHDhmDelHqEnt ARGS(( +RgSchCellCb *cell, +RgSchDlHqEnt **hqE +)); +PUBLIC Void rgSCHDhmAssgnUeHqEntFrmRaCb ARGS(( +RgSchUeCb *ue, +RgSchRaCb *raCb +)); +PUBLIC Void rgSCHUtlReTxTa ARGS(( +RgSchCellCb *cellCb, +RgSchUeCb *ueCb)); +/* LTE_ADV_FLAG_REMOVED_START */ +PUBLIC Void rgSchSFRTotalPoolFree ARGS(( +RgSchSFRTotalPoolInfo *sfrTotalPoolInfo, +RgSchCellCb *cell)); +PUBLIC Void rgSchDSFRPwrCheck ARGS(( +RgSchDlSf *sf, +Bool *isAllUePwrHigh)); +/* LTE_ADV_FLAG_REMOVED_END */ + +PUBLIC S16 rgSCHUtlUpdAvgPrbUsage ARGS(( +RgSchCellCb *cell +)); + +PUBLIC U8 rgSchUtlCfg0ReTxIdx ARGS(( +RgSchCellCb *cell, +CmLteTimingInfo phichTime, +U8 hqFdbkIdx +)); + +EXTERN S16 rgSCHUtlBuildNSendLcgReg ARGS(( +RgSchCellCb *cell, +CmLteRnti crnti, +U8 lcgId, +Bool isGbr +)); + +EXTERN Void rgSCHUtlPdcchInit ARGS(( + RgSchCellCb *cell, + RgSchDlSf *subFrm, + U16 nCce)); +EXTERN Void rgSCHDynCfiReCfg ARGS(( + RgSchCellCb *cell, + Bool isDynCfiEnb +)); +PUBLIC Void rgSchUtlCalcTotalPrbReq ARGS((RgSchCellCb *cell, + RgSchUeCb *ue, + U32 bo, + U32 *prbReqrd)); +EXTERN U8 rgSchUtlGetNumSbs ARGS(( +RgSchCellCb *cell, +RgSchUeCb *ue, +U32 *numSbs +)); + +EXTERN U8 rgSchUtlSortInsUeLst ARGS(( +RgSchCellCb *cell, +CmLListCp *ueLst, +CmLList *node, +U8 subbandRequired +)); +EXTERN S16 rgSCHUtlResetCpuOvrLdState ARGS(( + RgSchCellCb *cell, + U8 cnrtCpuOvrLdIns +)); +EXTERN Void rgSCHUtlCpuOvrLdAdjItbsCap ARGS(( + RgSchCellCb *cell +)); +#ifdef TFU_UPGRADE +EXTERN S16 rgSCHTomUtlPcqiSbCalcBpIdx ARGS(( +CmLteTimingInfo crntTimInfo, +RgSchUeCb *ueCb, +RgSchUePCqiCb *cqiCb +)); + +#ifdef LTE_ADV +EXTERN S16 rgSCHUtlSCellHndlCqiCollsn ARGS(( +RgSchUePCqiCb *cqiCb +)); + +EXTERN S16 rgSCHUtlSCellHndlRiCollsn ARGS(( +RgSchUePCqiCb *cqiCb +)); + +#endif/*LTE_ADV*/ +#endif/*TFU_UPGRADE*/ + +EXTERN Void rgSCHTomUtlGetTrigSet ARGS(( + RgSchCellCb *cell, + RgSchUeCb *ueCb, + U8 cqiReq, + U8 *triggerSet +)); + +EXTERN Void rgSCHUtlUpdUeDciSize ARGS(( +RgSchCellCb *cell, +RgSchUeCb *ueCb, +Bool isCsi2Bit +)); +EXTERN Void rgSCHUtlCalcDciSizes ARGS(( +RgSchCellCb *cell +)); + +EXTERN Void rgSchCmnPreDlSch ARGS (( + RgSchCellCb **cell, + U8 nCell, + RgSchCellCb **cellLst + )); + +EXTERN Void rgSchCmnPstDlSch ARGS (( + RgSchCellCb *cell + )); + +EXTERN PUBLIC U8 rgSCHCmnGetBiIndex ARGS (( +RgSchCellCb *cell, +U32 ueCount +)); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* __SCH__ */ + + +/********************************************************************** + End of file +**********************************************************************/ diff --git a/src/5gnrmac/rg_sch_cfg.c b/src/5gnrmac/rg_sch_cfg.c new file mode 100755 index 000000000..559d30f95 --- /dev/null +++ b/src/5gnrmac/rg_sch_cfg.c @@ -0,0 +1,10459 @@ +/******************************************************************************* +################################################################################ +# Copyright (c) [2017-2019] [Radisys] # +# # +# 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. # +################################################################################ +*******************************************************************************/ + +/************************************************************************ + + Name: LTE-MAC layer + + Type: C source file + + Desc: C source code for Entry point functions. + + File: rg_sch_cfg.c + +**********************************************************************/ + +/** @file rg_sch_cfg.c +@brief This module handles the configuration of SCH by RRC and RRM. +*/ + +static const char* RLOG_MODULE_NAME="MAC"; +static int RLOG_FILE_ID=186; +static int RLOG_MODULE_ID=4096; + +/* header include files -- defines (.h) */ +#include "envopt.h" /* environment options */ +#include "envdep.h" /* environment dependent */ +#include "envind.h" /* environment independent */ +#include "gen.h" /* general layer */ +#include "ssi.h" /* system service interface */ +#include "cm_hash.h" /* common hash list */ +#include "cm_mblk.h" /* common memory link list library */ +#include "cm_llist.h" /* common linked list library */ +#include "cm_err.h" /* common error */ +#include "cm_lte.h" /* common LTE */ +#include "lrg.h" +#include "rgr.h" +#include "rgm.h" +#include "tfu.h" +#include "rg_env.h" +#include "rg_sch_inf.h" +#include "rg_sch.h" +#include "rg_sch_err.h" +#include "rg_sch_cmn.h" +#include "rl_interface.h" +#include "rl_common.h" + +/* header/extern include files (.x) */ +#include "gen.x" /* general layer typedefs */ +#include "ssi.x" /* system services typedefs */ +#include "cm5.x" /* common timers */ +#include "cm_hash.x" /* common hash list */ +#include "cm_lib.x" /* common library */ +#include "cm_llist.x" /* common linked list */ +#include "cm_mblk.x" /* memory management */ +#include "cm_tkns.x" /* common tokens */ +#include "cm_lte.x" /* common tokens */ +#include "tfu.x" /* TFU types */ +#include "lrg.x" /* layer management typedefs for MAC */ +#include "rgr.x" /* layer management typedefs for MAC */ +#include "rgm.x" /* layer management typedefs for MAC */ +#include "rg_sch_inf.x" /* typedefs for MAC */ +#include "rg_sch.x" /* typedefs for MAC */ +/* [ccpu00124018]-MOD- Retrieving CQI value from cell config*/ +#include "rg_sch_cmn.x" +#include "rg_sch_clist.x" + + +/* LTE-MAC Scheduler instance control block structures */ +PUBLIC RgSchCb rgSchCb[RGSCH_MAX_INST]; + +#ifdef PHY_ERROR_LOGING +PUBLIC RgSchUlAllocCntr rgSchUlAllocCntr; +#endif + +#ifdef EMTC_ENABLE +EXTERN Void rgSCHEmtcPOTrigger ARGS (( +RgSchCellCb *cell, +RgSchUeCb *ue +)); + +EXTERN S16 rgSchEmtcUpdSiCfg ARGS (( +RgSchCellCb *cell, +RgrCellRecfg *cellRecfg +)); + +EXTERN S16 rgSCHEmtcCfgVldtDrxReTxCfg ARGS(( +U16 reTxTmr +)); + +EXTERN S16 rgSCHEmtcCfgVldtDrxUlReTxCfg ARGS(( +U16 reTxTmr +)); +#endif + +PUBLIC S16 rgSCHEnbPfsDlCfg ARGS(( + Inst instIdx, + RgSchErrInfo *err + )); +/* local defines */ +PRIVATE S16 rgSCHCfgRgrUeRecfgRntiChg ARGS (( RgSchCellCb *cell, + RgSchUeCb *ue, RgrUeRecfg *ueRecfg, RgSchErrInfo *errInfo)); +PRIVATE S16 rgSCHCfgVldtUePwrCfg ARGS((RgSchCellCb *cell, + RgrUeUlPwrCfg *pwrCfg)); +PRIVATE S16 rgSCHCfgVldtUeGrpPwrCfg ARGS((RgSchCellCb *cell, + RgrUeGrpPwrCfg *grpPwrCfg)); +#ifdef LTEMAC_SPS +PRIVATE S16 rgSCHCfgVldtUeDlSpsCfg ARGS((RgSchCellCb *cell, + RgrUeSpsDlCfg *dlSpsCfg)); +PRIVATE S16 rgSCHCfgVldtSpsReCfg ARGS ((RgSchCellCb *cell, + RgSchUeCb *ue, RgrUeRecfg *ueRecfg)); +#endif /*LTEMAC_SPS*/ +PRIVATE S16 rgSCHCfgVldtUeCqiModeCfg ARGS((RgSchCellCb *cell,RgrUeDlCqiCfg *ueDlCqiCfg)); +PRIVATE S16 rgSCHCfgVldtUeMeasGapAckNakRepCfg ARGS ((RgSchCellCb *cell, + RgrUeCfg *ueCfg)); +PRIVATE S16 rgSCHCfgVldtUeMeasGapAckNakRepRecfg ARGS ((RgSchCellCb *cell, + RgrUeRecfg *ueRecfg)); +PRIVATE Void rgSCHCfgFreeDlDedLcCb ARGS((RgSchCellCb *cell, RgSchUeCb *ue, + RgSchDlLcCb *dlLc)); +PRIVATE Void rgSCHCfgFreeDlCmnLcCb ARGS((RgSchClcDlLcCb *cmnDlLc)); +PRIVATE Void rgSCHCfgFreeUeCb ARGS((RgSchCellCb *cell, RgSchUeCb *ue)); +PRIVATE Void rgSCHCfgFreeRgrCfgLst ARGS((RgSchCellCb *cell)); +PRIVATE Void rgSCHCfgFreeCmnLcLst ARGS((RgSchCellCb *cell)); +PRIVATE Void rgSCHCfgFreeUeLst ARGS((RgSchCellCb *cell)); +#ifdef LTEMAC_SPS +PRIVATE Void rgSCHCfgFreeSpsUeLst ARGS((RgSchCellCb *cell)); +#endif +PRIVATE S16 rgSCHCfgVldtRgrCmnLcCfg ARGS((Inst inst, RgrCellCfg *cellCfg, + RgSchErrInfo *errInfo)); +PRIVATE S16 rgSCHCfgVldtRgrCellPwrCfg ARGS((Inst inst, RgrCellCfg *cellCfg, + RgSchErrInfo *errInfo)); +PRIVATE S16 rgSCHCfgVldtRgrCellSchCfg ARGS((Inst inst, RgrCellCfg *cellCfg)); +PRIVATE S16 rgSCHCfgVldtRgrSchCfg ARGS((Inst inst, RgrSchedEnbCfg *schedEnbCfg)); +PRIVATE S16 rgSCHCfgVldtRgrCellRACfg ARGS((Inst inst, RgrCellCfg *cellCfg)); +PRIVATE Void rgSCHCfgRgrUePhrMsg3 ARGS(( RgSchCellCb *cell, + RgSchRaCb *raCb,RgSchUeCb *ue, RgSchErrInfo *errInfo)); +PRIVATE S16 rgSCHCfgRgrCmnLcCfg ARGS((RgSchCellCb *cell, RgrCmnLchCfg *lcCfg, + RgSchErrInfo *errInfo)); +PUBLIC Void rgSCHSCellFreeBuf ARGS((Inst inst,RgSchUeCb *ue,RgrUeRecfg *ueRecfg,U8 idx)); +#ifdef RGR_SI_SCH +PRIVATE S16 rgSCHCfgVldtRgrCellSiCfg ARGS(( Inst inst, RgrSiCfg *siCfg)); +#endif/*RGR_SI_SCH */ + +/* LTE_ADV_FLAG_REMOVED_START */ +PRIVATE S16 rgSCHCfgVldtRgrCellLteAdvCfg ARGS(( Inst inst, + RgrLteAdvancedCellConfig *lteAdvCfg, U8 dlTotalBw)); +/* LTE_ADV_FLAG_REMOVED_END */ + +PRIVATE S16 rgSCHCfgVldtDrxUeCfg ARGS ((RgSchCellCb *cell, + RgrUeDrxCfg *ueDrxCfg)); +PRIVATE S16 rgSCHCfgVldtDrxOnDurCfg ARGS((U8 onDurTmr)); +PRIVATE S16 rgSCHCfgVldtDrxInActvCfg ARGS((U16 inActvTmr)); +PRIVATE S16 rgSCHCfgVldtDrxReTxCfg ARGS((U8 reTxTmr)); +PRIVATE S16 rgSCHCfgVldtDrxLngCycCfg ARGS((RgrDrxLongCycleOffst lngCycleOffst)); +PRIVATE S16 rgSCHCfgVldtDrxLngCyclTmrs ARGS((U16 val)); +PRIVATE S16 rgSCHCfgVldtDrxShrtCycCfg ARGS((RgrDrxShortDrx shrtCycCfg)); +PRIVATE S16 rgSCHCfgVldtRgrCellCsgParamCfg ARGS((Inst inst, + RgrCellCsgParamCfg *csgParam)); +#ifdef TFU_UPGRADE + +PUBLIC S16 rgSCHCfgACqiUeCfg ARGS(( RgSchCellCb *cellCb,RgSchUeCb *ue, RgSchUeACqiCb *aCqiCb, + RgrTxMode ueTxMode,RgrUeAprdDlCqiCfg *aCqiCfg, CmLteUeCategory ueCat )); + +PUBLIC S16 rgSCHCfgAcqiUeReCfg ARGS(( RgSchCellCb *cellCb, RgSchUeCb *ueCb, + RgrUeAprdDlCqiCfg *acqiCfg, CmLteUeCategory ueCat )); + +PUBLIC S16 rgSCHUtlGetCfgPerOff ARGS(( RgSchPerTbl tbl, U16 cfgIdx, + U16 *peri, U16 *offset )); + +PUBLIC S16 rgSCHCfgRiUeCfg ARGS((RgSchCellCb *cellCb, RgSchUeCb *ueCb, + RgrUePrdDlCqiCfg *cqiCfg, CmLteUeCategory ueCat )); + +PUBLIC S16 rgSCHCfgPCqiUeCfg ARGS((RgSchCellCb *cellCb, RgSchUeCb *ueCb, + RgrUePrdDlCqiCfg *cqiCfg,CmLteUeCategory ueCat )); + +PUBLIC S16 rgSCHCfgSrsUeCfg ARGS((RgSchCellCb *cellCb,RgSchUeCb *ueCb, + RgrUeUlSrsCfg *srsCfg )); + +PUBLIC S16 rgSCHCfgSrUeCfg ARGS((RgSchCellCb *cellCb,RgSchUeCb *ueCb, + RgrUeSrCfg *srCfg)); + +PUBLIC S16 rgSCHCfgPCqiUeReCfg ARGS((RgSchCellCb *cellCb, RgSchUeCb *ueCb, + RgrUePrdDlCqiCfg *cqiCfg,CmLteUeCategory ueCat)); + +PUBLIC S16 rgSCHCfgSrsUeReCfg ARGS((RgSchCellCb *cellCb, RgSchUeCb *ueCb, + RgrUeUlSrsCfg *srsCfg)); + +PUBLIC S16 rgSCHCfgSrUeReCfg ARGS((RgSchCellCb *cellCb, RgSchUeCb *ueCb, + RgrUeSrCfg *srCfg)); + +PUBLIC S16 rgSCHCfgVldtRgrTxmodePuschMode ARGS((RgSchCellCb *cellCb, + RgrTxMode txMde, RgrAprdCqiMode puschMode,RgSchErrInfo *errInfo)); + +PUBLIC S16 rgSCHCfgVldtRgrUeACqiCfg ARGS(( RgSchCellCb *cellCb, + CmLteRnti crnti, RgrUeAprdDlCqiCfg *acqiCfg, RgrUeTxModeCfg txMode, + RgSchErrInfo *errInfo )); + +PUBLIC S16 rgSCHCfgVldtRgrTxmodePucchMode ARGS((RgSchCellCb *cellCb, + RgrTxMode txMde, RgrPrdCqiMode pucchMode,RgSchErrInfo *errInfo)); + +#ifdef LTEMAC_HDFDD +PUBLIC S16 rgSCHCfgVldtRgrUePCqiCfg ARGS(( RgSchCellCb *cellCb, + CmLteRnti crnti, RgrUePrdDlCqiCfg *cqiCfg, Bool hdFdd, + RgrUeTxModeCfg txMode, RgSchErrInfo *errInfo)); +#else +PUBLIC S16 rgSCHCfgVldtRgrUePCqiCfg ARGS(( RgSchCellCb *cellCb, + CmLteRnti crnti, RgrUePrdDlCqiCfg *cqiCfg, RgrUeTxModeCfg txMode, + RgSchErrInfo *errInfo)); +#endif +#ifdef LTEMAC_HDFDD +PUBLIC S16 rgSCHCfgVldtRgrUeUlSrsCfg ARGS ((RgSchCellCb *cellCb, + CmLteRnti crnti, RgrUeUlSrsCfg *srsCfg, Bool hdFdd, + RgSchErrInfo *errInfo)); +#else +PUBLIC S16 rgSCHCfgVldtRgrUeUlSrsCfg ARGS ((RgSchCellCb *cellCb, + CmLteRnti crnti, RgrUeUlSrsCfg *srsCfg, + RgSchErrInfo *errInfo)); +#endif + +#ifdef LTEMAC_HDFDD +PUBLIC S16 rgSCHCfgVldtRgrUeSrCfg ARGS((RgSchCellCb *cellCb, CmLteRnti crnti, + RgrUeSrCfg *srCfg, Bool hdFdd, RgSchErrInfo *errInfo)); +#else +PUBLIC S16 rgSCHCfgVldtRgrUeSrCfg ARGS((RgSchCellCb *cellCb, CmLteRnti crnti, + RgrUeSrCfg *srCfg, RgSchErrInfo *errInfo)); +#endif +PRIVATE S16 rgSCHCfgVldtCqiSrSrsUeCfg ARGS (( RgSchCellCb *cellCb, + RgrUeCfg *ueCfg, + RgSchErrInfo *errInfo)); + +PRIVATE S16 rgSCHCfgVldtCqiSrSrsUeReCfg ARGS (( RgSchCellCb *cellCb, + RgSchUeCb *ueCb, + RgrUeRecfg *ueReCfg, + RgSchErrInfo *errInfo )); + +PUBLIC S16 rgSCHCfgPCqiSrsSrUeDel ARGS ((RgSchCellCb *cellCb, + RgSchUeCb *ueCb)); + +PRIVATE Void rgSCHCfgUtlFetchAcqiBitSz ARGS (( RgSchUeACqiCb *acqiCb,U8 numTxAnt, + U8* cqiPmiSzR1,U8* cqiPmiSzRn1 )); + +/* Added the function to be used instead of the + * MACRO RG_SCH_GET_PERIODICITY_TBL */ +PRIVATE CONSTANT RgSchUePCqiSrsSrCfgIdxTbl* rgSCHCfgUtlGetPcqiSrsSrRiTbl ARGS (( + RgSchPerTbl tblType, + U8 * min, + U8 * max)); + +#endif /* TFU_UPGRADE */ +PRIVATE Void rgSCHCfgUeTaRecfg ARGS (( RgSchCellCb *cellCb, + RgSchUeCb *ueCb, + RgrUeRecfg *ueReCfg, + RgSchErrInfo *errInfo )); +#ifdef LTE_ADV +PUBLIC S16 rgSCHSCellCfgUeCfg ARGS(( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgrUeRecfg *ueRecfg, +RgSchErrInfo *err +)); + +PUBLIC S16 rgSCHSCellCfgUePucchReCfg ARGS(( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgrUeRecfg *ueRecfg, +RgSchErrInfo *err +)); +PUBLIC S16 rgSCHCfgVldtRgrUeSCellRecfg ARGS(( +RgrUeRecfg *ueRecfg, +RgSchCellCb *cell, +RgSchUeCb *ue, +RgSchErrInfo *errInfo +)); +PRIVATE S16 rgSCHSCellCfgUeCfgRollBack ARGS(( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgrUeRecfg *ueRecfg +)); +#endif + +/* ccpu00117452 - MOD - Changed macro name from + RGR_RRM_DLPWR_CNTRL to RGR_CQI_REPT */ +#if ((defined (RGR_CQI_REPT)) && (defined (RGR_V2))) +PRIVATE S16 rgSCHCfgUeCqiReptReCfg ARGS (( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgrUeRecfg *ueRecfg +)); + +PRIVATE S16 rgSCHCfgVldtCqiReptReCfg ARGS (( +RgSchCellCb *cell, +RgrUeRecfg *ueRecfg +)); +#endif +/*LTE_L2_MEAS_PHASE2*/ +#ifdef LTE_L2_MEAS +PRIVATE S16 rgSchAddToL2Meas ARGS ((RgSchCellCb *cellCb,RgSchDlLcCb *dlLc)); +#endif +#ifdef EMTC_ENABLE +PUBLIC S16 rgSCHEmtcCfgVldtDrxOnDurCfg +( +U16 onDurTmr +); +PUBLIC Void rgSCHUtlUpdEmtcY +( +RgSchUeCb *ue +); +EXTERN Void rgSCHEmtcHqPAlloc +( +RgSchCellCb *cell, +RgSchDlHqEnt *hqEnt +); +#endif + +/* local typedefs */ +CONSTANT RgSchSrsTxOffst rgSrsTxOffstTbl[RGSCH_MAX_SRS_SFCFG_IDX+1]= + {{1,{0,0,0,0,0,0,0,0}}, + {1,{0,0,0,0,0,0,0,0}}, + {1,{1,0,0,0,0,0,0,0}}, + {1,{0,0,0,0,0,0,0,0}}, + {1,{1,0,0,0,0,0,0,0}}, + {1,{2,0,0,0,0,0,0,0}}, + {1,{3,0,0,0,0,0,0,0}}, + {2,{0,1,0,0,0,0,0,0}}, + {2,{2,3,0,0,0,0,0,0}}, + {1,{0,0,0,0,0,0,0,0}}, + {1,{1,0,0,0,0,0,0,0}}, + {1,{2,0,0,0,0,0,0,0}}, + {1,{3,0,0,0,0,0,0,0}}, + {7,{0,1,2,3,4,6,8,0}}, + {8,{0,1,2,3,4,5,6,8}}, + {0,{0,0,0,0,0,0,0,0}}}; + +/* local externs */ + +#ifdef TFU_UPGRADE +/* SRSCfg Table: Ref 36.213, Table: 8.2.1 */ +CONSTANT RgSchUePCqiSrsSrCfgIdxTbl +rgSchUeSrsCfgIdxFddTbl[RG_SCH_SRS_ISRS_INDX_MAX_FDD]= +{ + { 0,1, 2, 0 }, + { 2,6, 5, 2 }, + { 7,16, 10, 7 }, + { 17,36, 20, 17}, + { 37,76, 40, 37}, + { 77,156, 80, 77}, + { 157,316,160,157}, + { 317,636,320,317 } +}; + +/* Reference : 36.213 Table 8.2-2 */ +CONSTANT RgSchUePCqiSrsSrCfgIdxTbl +rgSchUeSrsCfgIdxTddTbl[RG_SCH_SRS_ISRS_INDX_MAX_TDD]= +{ + { 10,14, 5, 10 }, + { 15,24, 10, 15 }, + { 25,44, 20, 25 }, + { 45,84, 40, 45 }, + { 85,164, 80, 85 }, + { 165,324,160, 165 }, + { 325,644,320, 325 } + /* RESERVED: Configuration Module should not allow Res values */ +}; + +/*Reference: 36.213 Table:7.2.2-1A */ +CONSTANT RgSchUePCqiSrsSrCfgIdxTbl +rgSchUePCqiCfgIdxFddTbl[RG_SCH_CQIPMI_CFGIDX_MAX_FDD]= +{ + { 0,1, 2, 0 }, + { 2,6, 5, 2 }, + { 7,16, 10,7 }, + {17,36, 20,17}, + {37,76, 40, 37}, + {77,156, 80, 77}, + {157,316,160,157}, + {318,349,32,318}, + {350,413,64, 350}, + {414,541,128,414 } + /* RESERVED: Configuration should not allow Res values */ +}; + +/* Reference: 36.213 Table:7.2.2-1C */ +CONSTANT RgSchUePCqiSrsSrCfgIdxTbl +rgSchUeCqiPmiCfgIdxTddTbl[RG_SCH_CQIPMI_CFGIDX_MAX_TDD]= +{ + { 0,0, 1, 0 }, + { 1,5, 5, 1 }, + { 6,15, 10,6 }, + {16,35, 20,16}, + {36,75, 40,36}, + {76,155, 80,76}, + {156,315,160,156} + /* RESERVED: Configuration should not allow Res values */ +}; + +/* Note: RI table is same for FDD and TDD */ +/*Reference: 36.213 Table:7.2.2-1B */ +CONSTANT RgSchUePCqiSrsSrCfgIdxTbl +rgSchUeRiCfgIdxTbl[RG_SCH_RI_CFGIDX_MAX]= +{ + { 0,160, 1, 0 }, + { 161,321, 2, 161 }, + { 322,482, 4, 322 }, + { 483,643, 8, 483}, + { 644,804, 16,644}, + { 805,965, 32,805 } + /* RESERVED: Configuration should not allow Res values */ +}; + +/*Reference: 36.213 Table:7.2.2-2 */ +CONSTANT RgSchUeBwSubSzBwParts +rgSchUeBwSubSzBwPartsTbl[RG_SCH_BW_SUBSZ_BWPARTS_MAX]= +{ + {6,7, 0, 0}, /*TODO: 6,7, NA, NA */ + {8, 10, 4,1}, + {11, 26, 4,2}, + {27, 63, 6,3}, + {64, 110, 8,4} +}; + + +/* Reference : 36.213 Table 10.1-5 */ +/* Note: SR is same table for TDD and FDD */ +CONSTANT RgSchUePCqiSrsSrCfgIdxTbl rgSchUeSrCfgIdxTbl[RG_SCH_ISR_INDX_MAX]= +{ + { 0,4, 5, 0 }, + { 5,14, 10, 5 }, + { 15,34, 20,15 }, + { 35,74, 40,35}, + { 75,154, 80, 75} + /* RESERVED: Configuration should not allow Res values */ +}; + +/*Reference:36.213: Derived from Table: 7.2.1-5 for Label L. + The Label L is CEIL(log2(BinCoe(N and M)))*/ +CONSTANT U8 RgSCHUeAcqi2022LBitWidth[6][28] ={ +{0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5}, +{0,0,2,3,4,4,5,5,6,6,6,7,7,7,7,7,8,8,8,8,8,8,8,9,9,9,9,9}, +{0,0,0,2,4,5,6,6,7,7,8,8,9,9,9,10,10,10,10,11,11,11,11,11,12,12,12,12}, +{0,0,0,0,3,4,6,7,7,8,9,9,10,10,11,11,12,12,12,13,13,13,14,14,14,14,15,15}, +{0,0,0,0,0,3,5,6,7,8,9,10,11,11,12,13,13,14,14,14,15,15,16,16,16,17,17,17}, +{0,0,0,0,0,0,3,5,7,8,9,10,11,12,13,13,14,15,15,16,16,17,17,18,18,18,19,19} +}; + +#endif + +EXTERN U8 rgSchCmnHarqRtt[]; +#ifdef EMTC_ENABLE +EXTERN S16 rgSCHEmtcCellAlloc ARGS((RgSchCellCb *cel)); +EXTERN Void rgSCHEmtcCellFree ARGS((RgSchCellCb *cel)); +EXTERN Void rgSCHEmtcUeInfoFree ARGS((RgSchCellCb *cell, RgSchUeCb *ue)); +EXTERN U8 rgSchfillPucchSrRepNumCountemtc ARGS((RgSchUeCb *ueCb)); +EXTERN U8 rgSchfillPucchCqiRepNumCountemtc ARGS((RgSchUePCqiCb *cqiCb, RgSchUeCb *ueCb)); +EXTERN S16 rgEmtcvalidateSiCfg ARGS((RgrSiCfgReqInfo *siCfg,RgSchCellCb *cell)); +#endif +/* forward references */ + + +/** + * @brief Validates the SCH EndoeB configuration request from RRM to SCH. + * + * @details + * + * Function : rgSCHCfgVldtRgrSchedEnbCfg + * + ** Processing Steps: + * - Retrieve the cell control block. + * - If successful, + * - Validate the range of configured values recieved in + * configuration request. + * - If validated successfully, + * - Return ROK and pointer to the cell. + * - Else + * - Return RFAILED. + * - Else return RFAILED. + * @param[in] Inst inst + * @param[in] RgrSchedEnbCfg *schedEnbCfg + * @param[out] RgSchCellCb **cell + * @param[out] RgSchErrInfo *errInfo + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 rgSCHCfgVldtRgrSchedEnbCfg +( +Inst inst, +RgrSchedEnbCfg *schedEnbCfg, +RgSchErrInfo *errInfo +) +#else +PUBLIC S16 rgSCHCfgVldtRgrSchedEnbCfg(inst, schedEnbCfg, errInfo) +Inst inst; +RgrSchedEnbCfg *schedEnbCfg; +RgSchErrInfo *errInfo; +#endif +{ + TRC2(rgSCHCfgVldtRgrSchedEnbCfg); + RGSCHDBGPRM(inst, (rgSchPBuf(inst), "VALIDATE RGR SCH ENB CONFIG: \n")); + + errInfo->errCause = RGSCHERR_CFG_INVALID_RGR_ENB_CFG; + + // TODO + if ((rgSCHCfgVldtRgrSchCfg(inst, schedEnbCfg)) != ROK) + { + RGSCHDBGERR(inst, (rgSchPBuf(inst), "Validation for scheduler related " + "config failed\n")); + RETVALUE(RFAILED); + } + + RLOG1(L_INFO, "MIMO_DBG:: SCH:: numAntPorts=%d\n",schedEnbCfg->numTxAntPorts); + + /* Validation for the ENB parameters */ + if ((schedEnbCfg->numTxAntPorts == 0) || (schedEnbCfg->numTxAntPorts > 4)) + { + RGSCHDBGERR(inst, (rgSchPBuf(inst),"Invalid number of transmit antenna" + " ports %d\n", schedEnbCfg->numTxAntPorts)); + RETVALUE(RFAILED); + } + + /* Validate csg access mode */ + if((schedEnbCfg->accsMode < RGR_CELL_ACCS_OPEN) || + (schedEnbCfg->accsMode > RGR_CELL_ACCS_HYBRID)) + { + RGSCHDBGERR(inst, (rgSchPBuf(inst), "Invalid CSG Access mode\n")); + RETVALUE(RFAILED); + } + + errInfo->errCause = RGSCHERR_NONE; + RGSCHDBGINFO(inst, (rgSchPBuf(inst), "RGR SCHED ENB config validation done:"\n)); + + RETVALUE(ROK); +} /* rgSCHCfgVldtRgrSchedEnbCfg */ + +/** + * @brief Validates the cell configuration request from RRM to MAC. + * + * @details + * + * Function : rgSCHCfgVldtRgrCellCfg + * + * Processing Steps: + * - Retrieve the cell control block. + * - If successful, + * - Validate the range of configured values recieved in + * configuration request. + * - If validated successfully, + * - Return ROK and pointer to the cell. + * - Else + * - Return RFAILED. + * - Else return RFAILED. + * @param[in] Inst inst + * @param[in] RgrCellCfg *cellCfg + * @param[out] RgSchCellCb **cell + * @param[out] RgSchErrInfo *errInfo + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 rgSCHCfgVldtRgrCellCfg +( +Inst inst, +RgrCellCfg *cellCfg, +RgSchCellCb *cell, +RgSchErrInfo *errInfo +) +#else +PUBLIC S16 rgSCHCfgVldtRgrCellCfg(inst, cellCfg, cell, errInfo) +Inst inst; +RgrCellCfg *cellCfg; +RgSchCellCb *cell; +RgSchErrInfo *errInfo; +#endif +{ + TRC2(rgSCHCfgVldtRgrCellCfg); + + errInfo->errCause = RGSCHERR_CFG_INVALID_RGR_CELL_CFG; + + /* check if cell exists already */ + if ((U8 *)cell != NULLP) + { + RLOG_ARG0(L_ERROR,DBG_CELLID,cellCfg->cellId,"Cell Id already exists"); + RETVALUE(RFAILED); + } + + if(cellCfg->macInst >= RGSCH_INST_START) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cellCfg->cellId, "Invalid MAC Instance %d ", + cellCfg->macInst); + RETVALUE(RFAILED); + } + + if (cellCfg->macRnti.startRnti < RGSCH_MIN_MAC_RNTI ) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cellCfg->cellId, "Invalid start RNTI %d for cell ", + cellCfg->macRnti.startRnti); + RETVALUE(RFAILED); + } + + if ((rgSCHCfgVldtRgrCellSchCfg(inst, cellCfg)) != ROK) + { + RLOG_ARG0(L_ERROR,DBG_CELLID,cellCfg->cellId, "Validation for scheduler related " + "config failed"); + RETVALUE(RFAILED); + } + + if ((cellCfg->dlHqCfg.maxDlHqTx < RGSCH_MIN_HQ_TX) || + (cellCfg->dlHqCfg.maxMsg4HqTx < RGSCH_MIN_HQ_TX)) + { + RLOG_ARG2(L_ERROR,DBG_CELLID,cellCfg->cellId, "Invalid Downlink HARQ configuration:" + " maxDlHqTx %d maxMsg4HqTx %d", cellCfg->dlHqCfg.maxDlHqTx, + cellCfg->dlHqCfg.maxMsg4HqTx); + RETVALUE(RFAILED); + } + if ((cellCfg->cfiCfg.cfi < RGSCH_MIN_CFI_VAL) || + (cellCfg->cfiCfg.cfi > RGSCH_MAX_CFI_VAL)) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cellCfg->cellId, "Invalid CFI configuration %d", + cellCfg->cfiCfg.cfi); + RETVALUE(RFAILED); + } + if (((cellCfg->puschSubBand.subbandStart) + + ((cellCfg->puschSubBand.numSubbands -1) * cellCfg->puschSubBand.size)) + > (cellCfg->bwCfg.ulTotalBw - 1)) + { + RLOG_ARG4(L_ERROR,DBG_CELLID,cellCfg->cellId, "Invalid PUSCH subband configuration:" + " subBandStart %d numSubBands %d subBandSize %d ulTotBw %d", + cellCfg->puschSubBand.subbandStart, + cellCfg->puschSubBand.numSubbands, cellCfg->puschSubBand.size, + cellCfg->bwCfg.ulTotalBw); + RETVALUE(RFAILED); + } + + if (((cellCfg->bwCfg.dlTotalBw < RGSCH_MIN_DL_BW) || + (cellCfg->bwCfg.dlTotalBw > RGSCH_MAX_DL_BW)) || + ((cellCfg->bwCfg.ulTotalBw < RGSCH_MIN_UL_BW) || + (cellCfg->bwCfg.ulTotalBw > RGSCH_MAX_UL_BW))) + { + RLOG_ARG2(L_ERROR,DBG_CELLID,cellCfg->cellId, "Invalid Bandwidth configuration:" + " ul %d dl %d",cellCfg->bwCfg.ulTotalBw, + cellCfg->bwCfg.dlTotalBw); + RETVALUE(RFAILED); + } + if (cellCfg->phichCfg.ngEnum > RGR_NG_TWO) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cellCfg->cellId, "Invalid PHICH Ng configuration %d", + (U8)cellCfg->phichCfg.ngEnum); + RETVALUE(RFAILED); + } + /* Validation for extended PHICH Duration */ + if ((cellCfg->phichCfg.isDurExtend == TRUE) && + (cellCfg->bwCfg.dlTotalBw <= 10) && (cellCfg->cfiCfg.cfi < 2)) + { + RLOG_ARG2(L_ERROR,DBG_CELLID,cellCfg->cellId, "Invalid cfi value for" + "Extended PHICH duration cfi:%d dlBw:%d", + (U8)cellCfg->cfiCfg.cfi, cellCfg->bwCfg.dlTotalBw); + RETVALUE(RFAILED); + } + if ((cellCfg->phichCfg.isDurExtend == TRUE) && + (cellCfg->bwCfg.dlTotalBw > 10) && (cellCfg->cfiCfg.cfi < 3)) + { + RLOG_ARG2(L_ERROR,DBG_CELLID,cellCfg->cellId, "Invalid cfi value for" + "Extended PHICH duration cfi:%d dlBw:%d", + (U8)cellCfg->cfiCfg.cfi, cellCfg->bwCfg.dlTotalBw); + RETVALUE(RFAILED); + } + RLOG4(L_INFO,"CA_DBG:: PUCCH configuration:" + " N2_RB %d N1_PUCCH %d deltaShift %d cyclicShift %d", + cellCfg->pucchCfg.resourceSize, + cellCfg->pucchCfg.n1PucchAn, + cellCfg->pucchCfg.deltaShift, + cellCfg->pucchCfg.cyclicShift); + + /* ccpu00138567- Removing validation check for resourceSize as 0. + * From the spec, n2RB value 0 is a valid config. */ + if ((cellCfg->pucchCfg.resourceSize >= cellCfg->bwCfg.ulTotalBw/2) || + (cellCfg->pucchCfg.n1PucchAn == 0) || + (cellCfg->pucchCfg.deltaShift < RGSCH_PUCCH_MINVAL_DS) || + (cellCfg->pucchCfg.deltaShift > RGSCH_PUCCH_MAXVAL_DS) || + (cellCfg->pucchCfg.cyclicShift > RGSCH_PUCCH_MAXVAL_CS)) + { + RLOG_ARG4(L_ERROR,DBG_CELLID,cellCfg->cellId, "Invalid PUCCH configuration:" + " N2_RB %d N1_PUCCH %d deltaShift %d cyclicShift %d", + cellCfg->pucchCfg.resourceSize, + cellCfg->pucchCfg.n1PucchAn, + cellCfg->pucchCfg.deltaShift, + cellCfg->pucchCfg.cyclicShift); + RETVALUE(RFAILED); + } + if (cellCfg->srsCfg.isSrsCfgSetup && cellCfg->srsCfg.srsBwEnum > RGR_SRS_BWCFG_7) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cellCfg->cellId, "Invalid SRS configuration: " + " srsBw %d", (U8)cellCfg->srsCfg.srsBwEnum); + RETVALUE(RFAILED); + } + + if ((rgSCHCfgVldtRgrCellRACfg(inst, cellCfg)) != ROK) + { + RLOG_ARG0(L_ERROR,DBG_CELLID,cellCfg->cellId, "Validation for Random access related" + "config failed"); + RETVALUE(RFAILED); + } + + if ((rgSCHCfgVldtRgrCellPwrCfg(inst, cellCfg, errInfo)) != ROK) + { + RLOG_ARG0(L_ERROR,DBG_CELLID,cellCfg->cellId, "Validation for cell power " + "config failed"); + RETVALUE(RFAILED); + } + + /* Validate the common logical channel configuration */ + if( (cellCfg->numCmnLcs < RGR_MIN_CMN_LC_PER_CELL)|| + (cellCfg->numCmnLcs > RGR_MAX_CMN_LC_PER_CELL)) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cellCfg->cellId, "Invalid number(%d) of common logical" + "channels in cell config", cellCfg->numCmnLcs); + RETVALUE(RFAILED); + } + if ((rgSCHCfgVldtRgrCmnLcCfg(inst, cellCfg, errInfo)) != ROK) + { + RLOG_ARG0(L_ERROR,DBG_CELLID,cellCfg->cellId, "Validation for common logical" + "channels failed"); + RETVALUE(RFAILED); + } + + /* Added 0 as a valid value for number of TICKs RRM + * 0 implies no ticks i.e. shutting off the feature.*/ + +#ifdef RGR_SI_SCH + if ((rgSCHCfgVldtRgrCellSiCfg(inst, &(cellCfg->siCfg))) != ROK) + { + RLOG_ARG0(L_ERROR,DBG_CELLID,cellCfg->cellId, "Validation for SI" + "configuration failed"); + RETVALUE(RFAILED); + } +#endif /*RGR_SI_SCH */ + + /*ccpu00116923 - ADD - Srs Present support - Start*/ +#ifdef TFU_UPGRADE +#ifdef LTE_TDD + if(cellCfg->srsCfg.isSrsCfgSetup && cellCfg->srsCfg.srsSubFrameCfg > 13) +#else + if(cellCfg->srsCfg.isSrsCfgSetup && cellCfg->srsCfg.srsSubFrameCfg > 14) +#endif + { + RLOG_ARG0(L_ERROR,DBG_CELLID,cellCfg->cellId, "Invalid" + "Subframe configuration"); + RETVALUE(RFAILED); + } +#endif + /*ccpu00116923 - ADD - Srs Present support - End*/ + + if ((cellCfg->bcchTxPwrOffset > 10000) || + (cellCfg->pcchTxPwrOffset > 10000) || + (cellCfg->rarTxPwrOffset > 10000) || + (cellCfg->phichTxPwrOffset > 10000) + ) + { + RLOG_ARG0(L_ERROR,DBG_CELLID,cellCfg->cellId, + "Invalid txPower offset "); + RETVALUE(RFAILED); + } + +/* LTE_ADV_FLAG_REMOVED_START */ + /* Checking Whether DSFR is enabled without enabling SFR */ + if(((cellCfg->rgrLteAdvCfg.pres & RGR_DSFR) && + (RGR_ENABLE == cellCfg->rgrLteAdvCfg.dsfrCfg.status)) && + (!((cellCfg->rgrLteAdvCfg.pres & RGR_SFR) && + (RGR_ENABLE == cellCfg->rgrLteAdvCfg.sfrCfg.status)))) + { + RLOG_ARG0(L_ERROR,DBG_CELLID,cellCfg->cellId, "DSFR is enbaled" + "Without enabling SFR"); + RETVALUE(RFAILED); + } + + if ((rgSCHCfgVldtRgrCellLteAdvCfg(inst, &(cellCfg->rgrLteAdvCfg), + cellCfg->bwCfg.dlTotalBw)) != ROK) + { + RLOG_ARG0(L_ERROR,DBG_CELLID,cellCfg->cellId, "Validation for LTE Adv" + "configuration failed"); + RETVALUE(RFAILED); + } +#ifdef LTE_ADV + if ((rgSCHCfgVldtRgrCellLteLAACfg(inst, cellCfg)) != ROK) + { + RLOG_ARG0(L_ERROR,DBG_CELLID,cellCfg->cellId, "Validation for LTE LAA" + "configuration failed"); + RETVALUE(RFAILED); + } +#endif +/* LTE_ADV_FLAG_REMOVED_END */ + if (cellCfg->msg4pAVal > RGRUE_DLPWRCNTRL_PA_DB3) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cellCfg->cellId, "Invalid" + "msg4pAVal %u", cellCfg->msg4pAVal); + RETVALUE(RFAILED); + } + + /* Validate RgrCellCsgParamCfg */ + if(rgSchCb[inst].rgrSchedEnbCfg.accsMode == RGR_CELL_ACCS_HYBRID) + { + if((rgSCHCfgVldtRgrCellCsgParamCfg(inst, + &(cellCfg->csgParamCfg)) != ROK)) + { + RGSCHDBGERR(inst, (rgSchPBuf(inst), "Validation failed for \n" + "Access CSG parameter failed\n")); + RETVALUE(RFAILED); + } + } +#ifdef EMTC_ENABLE + if (cellCfg->emtcEnable) + { + if(ROK != rgSCHCfgVldtRgrEmtcCellCfg(cellCfg)) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cellCfg->cellId,"Invalid EMTC cell Configuration %d for cell" ,cellCfg->cellId); + RETVALUE(RFAILED); + } + } +#endif + errInfo->errCause = RGSCHERR_NONE; + RETVALUE(ROK); +} /* rgSCHCfgVldtRgrCellCfg */ + +/** + * @brief Validates the scheduler related configuration request from RRM to MAC. + * + * @details + * + * Function : rgSCHCfgVldtRgrSchCfg + * + * Processing Steps: + * - Validate the scheduler related configuration request from RRC to MAC at CFG: + * validate the value range for the configured values. + * - If validated successfully, + * - Return ROK . + * - Else + * - Return RFAILED. + * + * @param[in] Inst inst + * @param[out] RgSchedCfg *rgSchedCfg + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 rgSCHCfgVldtRgrSchCfg +( +Inst inst, +RgrSchedEnbCfg *rgSchedCfg +) +#else +PUBLIC S16 rgSCHCfgVldtRgrSchCfg(inst, rgSchedCfg) +Inst inst; +RgrSchedCfg *rgSchedCfg; +#endif +{ + TRC2(rgSCHCfgVldtRgrSchCfg); + + RGSCHDBGPRM(inst, (rgSchPBuf(inst), "rgSCHCfgVldtRgrSchCfg:Validating \ + scheduler related Configuration")); + if (rgSchedCfg->ulSchdType > (RGSCH_NUM_SCHEDULERS - 1)) + { + RGSCHDBGERR(inst, (rgSchPBuf(inst), "rgSCHCfgVldtRgrSchCfg:Invalid \ + UL scheduler type %d \n", rgSchedCfg->ulSchdType)); + RETVALUE(RFAILED); + } + if (rgSchedCfg->dlSchdType > (RGSCH_NUM_SCHEDULERS - 1)) + { + RGSCHDBGERR(inst, (rgSchPBuf(inst), "rgSCHCfgVldtRgrSchCfg:Invalid \ + DL scheduler type %d \n", rgSchedCfg->dlSchdType)); + RETVALUE(RFAILED); + } + RETVALUE(ROK); +} +/** + * @brief Validates the scheduler related configuration request from RRM to MAC. + * + * @details + * + * Function : rgSCHCfgVldtRgrCellSchCfg + * + * Processing Steps: + * - Validate the scheduler related configuration request from RRC to MAC at CFG: + * validate the value range for the configured values. + * - If validated successfully, + * - Return ROK and pointer to the cell of UE. + * - Else + * - Return RFAILED. + * + * @param[in] Inst inst + * @param[out] RgSchCellCfg *cellCfg + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 rgSCHCfgVldtRgrCellSchCfg +( +Inst inst, +RgrCellCfg *cellCfg +) +#else +PUBLIC S16 rgSCHCfgVldtRgrCellSchCfg(inst, cellCfg) +Inst inst; +RgrCellCfg *cellCfg; +#endif +{ + TRC2(rgSCHCfgVldtRgrCellSchCfg); + +#if RGSCH_NUM_DLFS_SCHEDULERS + if (cellCfg->dlfsSchdType > RGSCH_NUM_DLFS_SCHEDULERS - 1) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cellCfg->cellId,"Invalid dlfs scheduler type %d for cell", + cellCfg->dlfsSchdType); + RETVALUE(RFAILED); + } +#endif + RETVALUE(ROK); +} +/** + * @brief Validates the RACH related configuration request from RRM to MAC. + * + * @details + * + * Function : rgSCHCfgVldtRgrCellRACfg + * + * Processing Steps: + * - Validate the RA configuration request from RRC to MAC at CFG: + * validate the value range for the configured values. + * - If validated successfully, + * - Return ROK and pointer to the cell of UE. + * - Else + * - Return RFAILED. + * + * @param[in] Inst inst + * @param[out] RgSchCellCfg *cellCfg + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 rgSCHCfgVldtRgrCellRACfg +( +Inst inst, +RgrCellCfg *cellCfg +) +#else +PUBLIC S16 rgSCHCfgVldtRgrCellRACfg(inst, cellCfg) +Inst inst; +RgrCellCfg *cellCfg; +#endif +{ + TRC2(rgSCHCfgVldtRgrCellRACfg); + + +#ifdef LTE_TDD + if ((cellCfg->rachCfg.preambleFormat > RGSCH_MAX_TDD_RA_PREAMBLE_FMT) || +#else + if ((cellCfg->rachCfg.preambleFormat > RGSCH_MAX_RA_PREAMBLE_FMT) || +#endif + (cellCfg->rachCfg.raWinSize < RGSCH_MIN_RA_WINSIZE) || + (cellCfg->rachCfg.raWinSize > RGSCH_MAX_RA_WINSIZE) || + (cellCfg->rachCfg.maxMsg3Tx < RGSCH_MIN_HQ_TX) || + (cellCfg->rachCfg.numRaPreamble < RGSCH_MIN_NUM_RA_PREAMBLE) || + (cellCfg->rachCfg.numRaPreamble > RGSCH_MAX_NUM_RA_PREAMBLE) || + (cellCfg->rachCfg.sizeRaPreambleGrpA > + cellCfg->rachCfg.numRaPreamble) || + (cellCfg->rachCfg.prachResource > + (cellCfg->bwCfg.ulTotalBw - RGSCH_NUM_RA_RB))) + { + RLOG_ARG3(L_ERROR,DBG_CELLID,cellCfg->cellId,"Invalid RACH configuration:" + "preamble Fmt %d raWinSize %d maxMsg3Tx %d", + cellCfg->rachCfg.preambleFormat, cellCfg->rachCfg.raWinSize, + cellCfg->rachCfg.maxMsg3Tx); + RLOG_ARG2(L_ERROR,DBG_CELLID,cellCfg->cellId,"Invalid numRaPreamble %d sizeRaPreambleGrpA %d", + cellCfg->rachCfg.numRaPreamble, + cellCfg->rachCfg.sizeRaPreambleGrpA); + RETVALUE(RFAILED); + } + /* RACHO */ + /* verify that the ded Preambles cfgd for Pdcch Order + * do not collide with that of non-dedicated and validates against + * the configuration index and number of RACH + * ded-preambles. For non-zero ded preamble cfg, + * the config index is expected to be != NA.*/ + if ((cellCfg->macPreambleSet.pres) && + ((cellCfg->macPreambleSet.start < cellCfg->rachCfg.numRaPreamble) || + (cellCfg->macPreambleSet.start >= RGSCH_MAX_NUM_RA_PREAMBLE) || + (cellCfg->macPreambleSet.size < 1) || + (cellCfg->macPreambleSet.size > RGSCH_MAX_NUM_RA_PREAMBLE- + cellCfg->rachCfg.numRaPreamble) || + (cellCfg->rachCfg.raOccasion.sfnEnum == RGR_SFN_NA))) + { + RLOG_ARG2(L_ERROR,DBG_CELLID,cellCfg->cellId,"Invalid RACH Preambleset conf:" + "preambleSet Start %d preambleSet Size %d", + cellCfg->macPreambleSet.start, cellCfg->macPreambleSet.size); + RETVALUE(RFAILED); + } +#ifdef RGR_V1 + if(cellCfg->rachCfg.contResTmr) + { + U8 idx; +#ifdef LTE_TDD + idx = cellCfg->ulDlCfgIdx; +#else + idx = 7; /* FDD */ +#endif + /* maxMsg4TxDelay = (HARQ_RTT * MAX_MSG4_HARQ_RETX) + + 3 TTI (MAX L1+L2 processing delay at the UE) */ + U8 maxMsg4TxDelay = (cellCfg->dlHqCfg.maxMsg4HqTx-1) * + rgSchCmnHarqRtt[idx] + 3; + + + if(maxMsg4TxDelay >= cellCfg->rachCfg.contResTmr) + { + RLOG_ARG2(L_WARNING,DBG_CELLID,cellCfg->cellId , + "Warining !: Contention Resolution timer not greater than the " + "guard timer. Conte Res timer %d Guard timer %d", + cellCfg->rachCfg.contResTmr, + maxMsg4TxDelay ); + /* [ccpu00138532]-DEL- removed return fail here as it is ok if the + max Msg4 Tx delay is more than the contension Resolution timer. + In such case, the CRI CE will be scheduled immediately once + msg3 is received */ + } + } + else + { + /* ccpu00128575 ADD - If contention resolution timer is configured as 0, + Then return fail*/ + RLOG_ARG0(L_ERROR,DBG_CELLID,cellCfg->cellId, + "Contention Resolution timer is configured as '0'"); + RETVALUE(RFAILED); + } +#endif + + RETVALUE(ROK); +} + +/** + * @brief Validates the UE configuration request from RRM to MAC. + * + * @details + * + * Function : rgSCHCfgVldtRgrUeCfg + * + * Processing Steps: + * - Validate the UE configuration request from RRC to MAC at CFG: + * validate the value range for the configured values. + * - If validated successfully, + * - Return ROK and pointer to the cell of UE. + * - Else + * - Return RFAILED. + * + * @param[in] Inst inst + * @param[in] RgrUeCfg *ueCfg + * @param[out] RgSchCellCb **cell + * @param[out] RgSchErrInfo *errInfo + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 rgSCHCfgVldtRgrUeCfg +( +Inst inst, +RgrUeCfg *ueCfg, +RgSchCellCb **cell, +RgSchErrInfo *errInfo +) +#else +PUBLIC S16 rgSCHCfgVldtRgrUeCfg(inst, ueCfg, cell, errInfo) +Inst inst; +RgrUeCfg *ueCfg; +RgSchCellCb **cell; +RgSchErrInfo *errInfo; +#endif +{ + TRC2(rgSCHCfgVldtRgrUeCfg); + + errInfo->errCause = RGSCHERR_CFG_INVALID_RGR_UE_CFG; + + if (((*cell) == NULLP) || + ((*cell)->cellId != ueCfg->cellId)) + { + RLOG_ARG1(L_ERROR,DBG_CRNTI,ueCfg->crnti,"Cell does not exist %d", + ueCfg->cellId); + RETVALUE(RFAILED); + } + /* RACHO: + * Check configured preamble id not colliding with non dedicated or PDCCH + * order preamble sets. When valid preamble id given check that C-RNTI given + * in configuration is not amongst the C-RNTI'smanaged by scheduler */ + if ((rgSCHRamVldtUeCfg(*cell, ueCfg)) != ROK) + { + RLOG_ARG1(L_ERROR,DBG_CRNTI,ueCfg->crnti,"CELLID:%d Preamble Id configuration" + "failed ",ueCfg->cellId); + RETVALUE(RFAILED); + } + /* Check if Ue already configured */ + if (rgSCHDbmGetUeCb(*cell, ueCfg->crnti) != NULLP) + { + RLOG_ARG1(L_ERROR,DBG_CRNTI,ueCfg->crnti,"CELLID:%d UEID already exists", + ueCfg->cellId); + RETVALUE(RFAILED); + } + /* Validate Transmission UE modes */ + if ((ueCfg->txMode.pres == TRUE) && ((ueCfg->txMode.txModeEnum < RGR_UE_TM_1) + || (ueCfg->txMode.txModeEnum > RGR_UE_TM_7))) + { + RLOG_ARG2(L_ERROR,DBG_CRNTI,ueCfg->crnti,"CELLID:%d Invalid transmission mode for" + " UE is %d", ueCfg->cellId,(U8)ueCfg->txMode.txModeEnum); + RETVALUE(RFAILED); + } + + /* Validate UE Category */ + if (ueCfg->ueCatEnum > CM_LTE_UE_CAT_8) + { + RLOG_ARG2(L_ERROR,DBG_CRNTI,ueCfg->crnti,"CELLID:%d Invalid category for UE %d", + ueCfg->cellId,(U8)ueCfg->ueCatEnum); + RETVALUE(RFAILED); + } + + /* Validate UE Access Stratum Release */ + if (ueCfg->accessStratumRls > RGR_REL_10) + { + RGSCHDBGERRNEW(inst, (rgSchPBuf(inst), "Invalid Access Stratum Release %u for UE\n", + ueCfg->accessStratumRls)); + RETVALUE(RFAILED); + } + RGSCHDBGINFONEW(inst, (rgSchPBuf(inst), "Configured Access Stratum Release %u\n", \ + ueCfg->accessStratumRls)); + + if ((*cell)->numTxAntPorts == 1) + { + if ((ueCfg->txMode.pres == TRUE) && + (ueCfg->txMode.txModeEnum > RGR_UE_TM_1)) + { + RLOG_ARG2(L_ERROR,DBG_CRNTI,ueCfg->crnti,"CELLID:%d Invalid transmission mode for" + " UE (%d) for the configured Cell Antenna Ports",ueCfg->cellId, + (U8)ueCfg->txMode.txModeEnum); + RETVALUE(RFAILED); + } + } + + if ((rgSCHCfgVldtUeCqiModeCfg(*cell, &ueCfg->ueDlCqiCfg)) != ROK) + { + RLOG_ARG1(L_ERROR,DBG_CRNTI,ueCfg->crnti, "CELLID:%d Invalid CQI Mode configuration", + ueCfg->cellId); + RETVALUE(RFAILED); + } + + /* Validate Max Uplink HARQ transmission value */ + if (ueCfg->ueUlHqCfg.maxUlHqTx < RGSCH_MIN_HQ_TX) + { + RLOG_ARG2(L_ERROR,DBG_CRNTI,ueCfg->crnti,"CELLID:%d Invalid Uplink HARQ config for " + "UE %d",ueCfg->cellId,ueCfg->ueUlHqCfg.maxUlHqTx); + RETVALUE(RFAILED); + } + + if (rgSCHCfgVldtUePwrCfg(*cell, &ueCfg->ueUlPwrCfg) != ROK) + { + RLOG_ARG1(L_ERROR,DBG_CRNTI,ueCfg->crnti,"CELLID:%d Invalid PUSCH Group power" + " configuration",ueCfg->cellId); + RETVALUE(RFAILED); + } + + if (rgSCHCfgVldtUeMeasGapAckNakRepCfg(*cell, ueCfg) != ROK) + { + RLOG_ARG1(L_ERROR,DBG_CRNTI,ueCfg->crnti,"CELLID:%d Invalid MeasGap/AckNackRep" + " configuration",ueCfg->cellId); + RETVALUE(RFAILED); + } + +#ifdef LTEMAC_SPS + /* Validating SPS RNTI */ + if (((ueCfg->ueSpsCfg.spsRnti >= (*cell)->rntiDb.rntiStart) && + (ueCfg->ueSpsCfg.spsRnti<=((*cell)->rntiDb.rntiStart+(*cell)->rntiDb.maxRntis))) + ||(ueCfg->ueSpsCfg.spsRnti == RGSCH_SI_RNTI) + ||(ueCfg->ueSpsCfg.spsRnti == RGSCH_P_RNTI)) + { + RLOG_ARG1(L_ERROR,DBG_CRNTI,ueCfg->crnti,"CELLID:%d Invalid SPS RNTI " + " in DL SPS Config",ueCfg->cellId); + RETVALUE(RFAILED); + } + + if (ueCfg->ueSpsCfg.dlSpsCfg.isDlSpsEnabled) + { + if (rgSCHCfgVldtUeDlSpsCfg(*cell, &ueCfg->ueSpsCfg.dlSpsCfg) != ROK) + { + RLOG_ARG1(L_ERROR,DBG_CRNTI,ueCfg->crnti,"CELLID:%d Invalid DL SPS configuration" + " for the UE",ueCfg->cellId); + RETVALUE(RFAILED); + } + } +#endif +#ifdef TFU_UPGRADE + /* Validated Periodic CQI/PMI, RI , SRS and SR related UeCfg */ + if ( ROK != rgSCHCfgVldtCqiSrSrsUeCfg(*cell, ueCfg, errInfo)) + { + RLOG_ARG1(L_ERROR,DBG_CRNTI,ueCfg->crnti,"CELLID:%d Invalid Periodic CQI/SR/SRS" + "configuration",ueCfg->cellId); + RETVALUE(RFAILED); + } +#endif + + /* Validate DRX specific parameters */ + if ( ROK != rgSCHCfgVldtDrxUeCfg(*cell, &(ueCfg->ueDrxCfg))) + { + RLOG_ARG1(L_ERROR,DBG_CRNTI,ueCfg->crnti,"CELLID:%d Invalid DRX configuration", + ueCfg->cellId); + RETVALUE(RFAILED); + } + +/* ccpu00117452 - MOD - Changed macro name from + RGR_RRM_DLPWR_CNTRL to RGR_CQI_REPT */ +#ifdef RGR_CQI_REPT + if (ueCfg->ueCqiReptCfg.numColltdCqiRept > RGR_CQIRPTS_MAXN) + { + RLOG_ARG2(L_ERROR,DBG_CRNTI,ueCfg->crnti,"CELLID:%d Invalid numColltdCqiRept," + "MAX supported %d",RGR_CQIRPTS_MAXN,ueCfg->cellId); + RETVALUE(RFAILED); + } +#endif /* End of RGR_CQI_REPT */ + +#ifdef EMTC_ENABLE +/*This is to validate the EMTC related configuration if a UE is an EMTC UE*/ + if(TRUE == ueCfg->emtcUeCfg.pres) + { + if ( ROK != rgSCHCfgVldtEmtcUeCfg(*cell, &(ueCfg->emtcUeCfg))) + { + RLOG_ARG2(L_ERROR,DBG_CRNTI,ueCfg->crnti,"CELLID:%d Invalid EMTC UE configurationfor crnti:%d", + ueCfg->cellId, ueCfg->crnti); + RETVALUE(RFAILED); + } + } +#endif + errInfo->errCause = RGSCHERR_NONE; + RETVALUE(ROK); +} /* rgSCHCfgVldtRgrUeCfg */ + + +/** + * @brief Validates the cell reconfiguration request from RRM to MAC. + * + * @details + * + * Function : rgSCHCfgVldtRgrCellRecfg + * + * Processing Steps: + * - Retrieve the cell control block. + * - If successful, + * - Validate the range of reconfigured values recieved in + * re-configuration request. + * - If validated successfully, + * - Return ROK and pointer to the cell. + * - Else + * - Return RFAILED. + * - Else return RFAILED. + * + * @param[in] Inst inst + * @param[in] RgrCellRecfg *cellRecfg + * @param[out] RgSchCellCb **cell + * @param[out] RgSchErrInfo *errInfo + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 rgSCHCfgVldtRgrCellRecfg +( +Inst inst, +RgrCellRecfg *cellRecfg, +RgSchCellCb **cell, +RgSchErrInfo *errInfo +) +#else +PUBLIC S16 rgSCHCfgVldtRgrCellRecfg(inst, cellRecfg, cell, errInfo) +Inst inst; +RgrCellRecfg *cellRecfg; +RgSchCellCb **cell; +RgSchErrInfo *errInfo; +#endif +{ + TRC2(rgSCHCfgVldtRgrCellRecfg); + + + errInfo->errCause = RGSCHERR_CFG_INVALID_RGR_CELL_RECFG; + + /* Fetch cell and validate cell Id with the cell control block*/ + if (((*cell) == NULLP) || + ((*cell)->cellId != cellRecfg->cellId)) + { + RLOG_ARG0(L_ERROR,DBG_CELLID,cellRecfg->cellId,"Cell control block does not exist"); + RETVALUE(RFAILED); + } + + /* Validate recieved values */ + if ((cellRecfg->recfgTypes & RGR_CELL_DL_HARQ_RECFG) && + ((cellRecfg->dlHqRecfg.maxDlHqTx < RGSCH_MIN_HQ_TX) || + (cellRecfg->dlHqRecfg.maxMsg4HqTx < RGSCH_MIN_HQ_TX))) + { + RLOG_ARG2(L_ERROR,DBG_CELLID,cellRecfg->cellId,"Invalid Downlink HARQ configuration:" + " maxDlHqTx %d maxMsg4HqTx %d", cellRecfg->dlHqRecfg.maxDlHqTx, + cellRecfg->dlHqRecfg.maxMsg4HqTx); + RETVALUE(RFAILED); + } + if ((cellRecfg->recfgTypes & RGR_CELL_CFI_RECFG) && + ((cellRecfg->cfiRecfg.cfi < RGSCH_MIN_CFI_VAL) || + (cellRecfg->cfiRecfg.cfi > RGSCH_MAX_CFI_VAL))) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cellRecfg->cellId,"Invalid CFI configuration %d", + cellRecfg->cfiRecfg.cfi); + RETVALUE(RFAILED); + } + if (cellRecfg->recfgTypes & RGR_CELL_PUCCH_RECFG) + { + /* ccpu00138567- Removing validation check for resourceSize as 0. + * From the spec, n2RB value 0 is a valid config. */ + if ((cellRecfg->pucchRecfg.n1PucchAn == 0) || + (cellRecfg->pucchRecfg.resourceSize >= (*cell)->bwCfg.ulTotalBw/2)|| + ((cellRecfg->pucchRecfg.deltaShift < RGSCH_PUCCH_MINVAL_DS) || + (cellRecfg->pucchRecfg.deltaShift > RGSCH_PUCCH_MAXVAL_DS)) || + (cellRecfg->pucchRecfg.cyclicShift > RGSCH_PUCCH_MAXVAL_CS)) + { + RLOG_ARG4(L_ERROR,DBG_CELLID,cellRecfg->cellId,"Invalid PUCCH configuration: " + "N2_RB %d N1_PUCCH %d deltaShift %d cyclicShift %d", + cellRecfg->pucchRecfg.resourceSize, + cellRecfg->pucchRecfg.n1PucchAn, + cellRecfg->pucchRecfg.deltaShift, + cellRecfg->pucchRecfg.cyclicShift); + RETVALUE(RFAILED); + } + } + if (cellRecfg->recfgTypes & RGR_CELL_SRS_RECFG) + { + if (cellRecfg->srsRecfg.isSrsCfgSetup && cellRecfg->srsRecfg.srsBwEnum > RGR_SRS_BWCFG_7) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cellRecfg->cellId,"Invalid SRS configuration: " + "srsBw %d", (U8)cellRecfg->srsRecfg.srsBwEnum); + RETVALUE(RFAILED); + } + + /*ccpu00116923 - ADD - Srs Present support - Start*/ +#ifdef TFU_UPGRADE +#ifdef LTE_TDD + if(cellRecfg->srsRecfg.isSrsCfgSetup && cellRecfg->srsRecfg.srsSubFrameCfg > 13) +#else + if(cellRecfg->srsRecfg.isSrsCfgSetup && cellRecfg->srsRecfg.srsSubFrameCfg > 14) +#endif + { + RLOG_ARG0(L_ERROR,DBG_CELLID,cellRecfg->cellId,"Invalid Subframe configuration "); + RETVALUE(RFAILED); + } +#endif + /*ccpu00116923 - ADD - Srs Present support - End*/ + } + if (cellRecfg->recfgTypes & RGR_CELL_RACH_RECFG) + { + if ((cellRecfg->rachRecfg.preambleFormat > RGSCH_MAX_RA_PREAMBLE_FMT) || + ((cellRecfg->rachRecfg.raWinSize < RGSCH_MIN_RA_WINSIZE) || + (cellRecfg->rachRecfg.raWinSize > RGSCH_MAX_RA_WINSIZE)) || + (cellRecfg->rachRecfg.maxMsg3Tx < RGSCH_MIN_HQ_TX) || + ((cellRecfg->rachRecfg.numRaPreamble < RGSCH_MIN_NUM_RA_PREAMBLE) + || (cellRecfg->rachRecfg.numRaPreamble > RGSCH_MAX_NUM_RA_PREAMBLE)) + || (cellRecfg->rachRecfg.sizeRaPreambleGrpA > + cellRecfg->rachRecfg.numRaPreamble) || + (cellRecfg->rachRecfg.prachResource > + (*cell)->bwCfg.ulTotalBw - RGSCH_NUM_RA_RB)) + { + RLOG_ARG3(L_ERROR,DBG_CELLID,cellRecfg->cellId,"Invalid RACH configuration:" + " preamble Fmt %d raWinSize %d maxMsg3Tx %d", + cellRecfg->rachRecfg.preambleFormat, + cellRecfg->rachRecfg.raWinSize, + cellRecfg->rachRecfg.maxMsg3Tx); + RLOG_ARG2(L_ERROR,DBG_CELLID,cellRecfg->cellId,"Invalid RACH configuration:" + "numRaPreamble %d sizeRaPreambleGrpA %d", + cellRecfg->rachRecfg.numRaPreamble, + cellRecfg->rachRecfg.sizeRaPreambleGrpA); + RETVALUE(RFAILED); + } + } + +#ifdef RGR_SI_SCH + if (cellRecfg->recfgTypes & RGR_CELL_SI_RECFG) + { + if ((rgSCHCfgVldtRgrCellSiCfg(inst, &(cellRecfg->siReCfg))) != ROK) + { + RLOG_ARG0(L_ERROR,DBG_CELLID,cellRecfg->cellId,"Validation for SI" + "Re-configuration failed"); + RETVALUE(RFAILED); + } + } +#endif /*RGR_SI_SCH */ + +/* LTE_ADV_FLAG_REMOVED_START */ + if (cellRecfg->recfgTypes & RGR_CELL_LTEA_FEATURE_RECFG) + { + /* Checkin whether DSFR is enbaled without enabling SFR. + * So we need to check if SFR is enabled along with DSFR + * in the same reconfiguration or it is already enabled earlier*/ + if((cellRecfg->rgrLteAdvCfg.pres & RGR_DSFR) && + (RGR_ENABLE == cellRecfg->rgrLteAdvCfg.dsfrCfg.status)) + { + if(!(((cellRecfg->rgrLteAdvCfg.pres & RGR_SFR) && + (RGR_ENABLE == cellRecfg->rgrLteAdvCfg.sfrCfg.status)) || + ((*cell)->lteAdvCb.sfrCfg.status == RGR_ENABLE))) + { + RLOG_ARG0(L_ERROR,DBG_CELLID,cellRecfg->cellId,"DSFR is enbaled" + "Without enabling SFR"); + RETVALUE(RFAILED); + } + } + if ((rgSCHCfgVldtRgrCellLteAdvCfg(inst, &(cellRecfg->rgrLteAdvCfg), + (*cell)->bwCfg.dlTotalBw)) != ROK) + { + RLOG_ARG0(L_ERROR,DBG_CELLID,cellRecfg->cellId,"Validation for Lte Adv" + "Re-configuration failed"); + RETVALUE(RFAILED); + } + } +/* LTE_ADV_FLAG_REMOVED_END */ + + /* Validating minimum resource for non-CSG users */ + if (cellRecfg->recfgTypes & RGR_CELL_CSG_PARAM_RECFG) + { + if (cellRecfg->csgParamCfg.minDlResNonCsg > 100) + { + RLOG_ARG0(L_ERROR,DBG_CELLID,cellRecfg->cellId,"Invalid Configuration " + "of minimum DL resources for NON-CSG"); + RETVALUE(RFAILED); + } + if (cellRecfg->csgParamCfg.minUlResNonCsg > 100) + { + RLOG_ARG0(L_ERROR,DBG_CELLID,cellRecfg->cellId,"Invalid Configuration " + "of minimum UL resources for NON-CSG"); + RETVALUE(RFAILED); + } + } + errInfo->errCause = RGSCHERR_NONE; + RETVALUE(ROK); +} /* rgSCHCfgVldtRgrCellRecfg */ + +#ifdef LTE_ADV +/** + * @brief Ue SCell configuration for scheduler. It is invoked during first time + * Scell configuration. It is not for reconfiguration + * + * @details + * + * Function : rgSCHSCellCfgUeCfg + * + * This functions updates UE specific scheduler + * information upon UE SCell first time Scell configuration + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ue + * @param[int] RgrUeRecfg *ueRecfg + * @param[out] RgSchErrInfo *err + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 rgSCHSCellCfgUeCfg +( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgrUeRecfg *ueRecfg, +RgSchErrInfo *err +) +#else +PUBLIC S16 rgSCHSCellCfgUeCfg(cell, ue, ueRecfg, err) +RgSchCellCb *cell; +RgSchUeCb *ue; +RgrUeRecfg *ueRecfg; +RgSchErrInfo *err; +#endif +{ + U8 idx; + Inst inst = cell->instIdx; + RgSchCellCb *secCellCb = NULLP; + U8 sCellidx = 0; + RgSchUeCellInfo *sCellInfo = NULLP; + RgrUeSecCellCfg *sCellInfoCfg = NULLP; +#ifdef TFU_UPGRADE + RgrUeAprdDlCqiCfg *aCqiCfg; + RgrUePrdDlCqiCfg *pCqiCfg; +#endif + + TRC2(rgSCHSCellCfgUeCfg); + + RLOG0(L_INFO, "SCELL recfg received from APP \n"); + + RGSCHDBGINFONEW(inst, (rgSchPBuf(inst), + "--------------------------------------------------------------------\n" + "UE SCell ReConfiguration at SCH: rnti (%u) cell(%u)\n" + "--------------------------------------------------------------------\n", + ue->ueId, cell->cellId)); + + + for(idx = 0; idx < ueRecfg->ueSCellCfgInfo.numSCells; idx++) + { + /* Allocate the Ue control block */ + if (((rgSCHUtlAllocSBuf(inst, (Data **)&sCellInfo, + sizeof(RgSchUeCellInfo))) != ROK)) + { + RGSCHDBGERRNEW(inst, (rgSchPBuf(inst), "[%d]SCellIdx :Memomy allocation " + "Failed while Adding SCell Information\n", idx)); + RETVALUE(RFAILED); + } + + + sCellInfoCfg = &ueRecfg->ueSCellCfgInfo.ueSCellDedCfg[idx]; + + + sCellInfo->sCellIdx = sCellInfoCfg->sCellIdx; + sCellInfo->sCellId = sCellInfoCfg->sCellId; + + if(PRSNT_NODEF == sCellInfoCfg->sCellDeActTmr.pres) + { + /* Configure implicit release */ + ue->sCellDeactTmrVal.val = sCellInfoCfg->sCellDeActTmr.val; + ue->isScellExplicitDeAct = FALSE; + ue->sCellDeactTmrVal.pres = PRSNT_NODEF; + } + else if (rgSchCb[cell->instIdx].genCfg.isSCellActDeactAlgoEnable == TRUE) + { + /* Configure explicit release */ + ue->sCellDeactTmrVal.val = RGSCH_SCELL_DEACT_TMR_INFINITY_VAL; + ue->isScellExplicitDeAct = TRUE; + ue->sCellDeactTmrVal.pres = PRSNT_NODEF; + } + else + { + ue->sCellDeactTmrVal.val = 0; + ue->isScellExplicitDeAct = FALSE; + ue->sCellDeactTmrVal.pres = NOTPRSNT; + } + + sCellInfo->sCellState = RG_SCH_SCELL_INACTIVE; + + sCellInfo->ue = ue; + ue->cellInfo[(sCellInfoCfg->sCellIdx)] = sCellInfo; + sCellidx = ((sCellInfo->sCellId - + rgSchCb[cell->instIdx].genCfg.startCellId)&(CM_LTE_MAX_CELLS-1)); + ue->cellIdToCellIdxMap[sCellidx] = sCellInfo->sCellIdx; + + /* For for time one Scell got added, setting allocCmnUlPdcch flag to TRUE, So that + we will allocate PDCCH from common search space and the csiRequest field in DCI0 will + be one bit (spec 36.213 sec 7.2.1)*/ +#ifdef LTE_ADV + if ( ue->numSCells == 0) + { + ue->allocCmnUlPdcch = TRUE; + } +#endif + ue->numSCells++; +#ifdef CA_DBG + printf("\n SCell added for ue %d numScells %d\n",ue->ueId,ue->numSCells); +#endif + /* retrieve teh sec cell Cb */ + if((secCellCb = (RgSchCellCb *)rgSchUtlGetCellCb(inst, sCellInfo->sCellId)) == NULLP) + { + RGSCHDBGERRNEW(inst, (rgSchPBuf(inst), "SCell doesnt exists")); + rgSCHSCellFreeBuf (inst,ue,ueRecfg,idx); + RETVALUE(RFAILED); + } + + if(TRUE == sCellInfoCfg->txMode.pres) + { + sCellInfo->txMode = sCellInfoCfg->txMode; + } + else + { + RGSCHDBGERRNEW(inst, (rgSchPBuf(inst), "[%d]SCellIdx Tx mode not present ",idx)); + sCellInfoCfg->txMode.pres = TRUE; + sCellInfoCfg->txMode.txModeEnum = RGR_UE_TM_1; + + sCellInfo->txMode = sCellInfoCfg->txMode; + } + cmInitTimers (&sCellInfo->actDelayTmr, 1); + cmInitTimers (&sCellInfo->deactTmr, 1); + + ue->f1bCsAVal += rgSCHUtlGetMaxTbSupp(sCellInfo->txMode.txModeEnum); + +#ifdef TFU_UPGRADE + if(TRUE == sCellInfoCfg->ueSCellDlCqiCfg.aprdCqiCfg.pres) + { + sCellInfo->acqiCb.aCqiCfg.aprdModeEnum = + sCellInfoCfg->ueSCellDlCqiCfg.aprdCqiCfg.aprdModeEnum; + } + + if(TRUE == sCellInfoCfg->uePdschDedCfg.uepACfg.pAPrsnt) + { + sCellInfo->pA.pres = TRUE; + sCellInfo->pA.val = sCellInfoCfg->uePdschDedCfg.uepACfg.pA; + } + else + { + sCellInfo->pA.pres = FALSE; + } + + aCqiCfg = &sCellInfoCfg->ueSCellDlCqiCfg.aprdCqiCfg; + RGSCHDBGPRM(cell->instIdx, (rgSchPBuf(cell->instIdx), + "rgSCHCfgACqiUeCfg cellId =%d,Config Presence =%d for \ + Sec Cell Id = %d\n", + cellCb->cellId, aCqiCfg->pres,sCellInfo->sCellId)); + + /* if aperiodic cqi is present then only call the below function as it is + * not mandatory*/ + if(aCqiCfg->pres) + { + if( ROK != rgSCHCfgACqiUeCfg(secCellCb,ue, &sCellInfo->acqiCb, + sCellInfo->txMode.txModeEnum, aCqiCfg, ue->ueCatEnum)) + { + RGSCHDBGERRNEW(inst, (rgSchPBuf(inst), "[%d]SCellIdx ACQI Cfg" + "failed..n\n", idx)); + rgSCHSCellFreeBuf (inst,ue,ueRecfg,idx); + RETVALUE(RFAILED); + } + } + /* Configuring PCQI */ + /* Scell needs to be added to the + * pcqi list only after activation */ + pCqiCfg = &sCellInfoCfg->ueSCellDlCqiCfg.prdCqiCfg; + + if(ROK != rgSCHSCellPCqiCfg(cell,secCellCb,ue,pCqiCfg, + ue->ueCatEnum,sCellInfoCfg->sCellIdx)) + { + RGSCHDBGERRNEW(inst, (rgSchPBuf(inst), "[%d]SCellIdx PCQI Cfg failed..n\n", idx)); + rgSCHSCellFreeBuf (inst,ue,ueRecfg,idx); + RETVALUE(RFAILED); + } +#endif + + /* Configuring ACQI */ + + /* Stroing the secCell for easy access */ + sCellInfo->cell = secCellCb; + + +#ifdef LTE_ADV + if (ROK != rgSCHLaaInitDlRbAllocCb(secCellCb, + &sCellInfo->dlAllocCb)) + { + RETVALUE(RFAILED); + } +#endif + /* Initialize Harq entity */ + + sCellInfo->hqEnt = rgSCHDhmHqEntInit(secCellCb); + if (sCellInfo->hqEnt == NULLP) + { + RGSCHDBGERRNEW(inst, (rgSchPBuf(inst), "[%d]UEID:Hq Entity Initialization " + "failed in config\n", ue->ueId)); + rgSCHSCellFreeBuf (inst,ue,ueRecfg,idx); + RETVALUE(RFAILED); + } +#ifdef EMTC_ENABLE + rgSCHEmtcHqPAlloc(secCellCb, sCellInfo->hqEnt); +#endif + rgSCHCmnDlInitHqEnt(secCellCb, sCellInfo->hqEnt); + + sCellInfo->hqEnt->ue = ue; + /* Init SCell Specific Sched Spfc UE DL CB */ + if ((secCellCb->sc.apis->rgSCHRgrSCellUeCfg(secCellCb, ue, sCellInfoCfg, err)) != ROK) + { + RGSCHDBGERRNEW(inst, (rgSchPBuf(inst), "Spec Sched DL UE CFG FAILED\n")); + rgSCHSCellFreeBuf (inst,ue,ueRecfg,idx); + RETVALUE(RFAILED); + } + +#ifdef LTE_TDD + if((rgSCHUtlAllocUeANFdbkInfo(ue,sCellInfoCfg->sCellIdx)) != ROK) + { + RGSCHDBGERRNEW(inst, (rgSchPBuf(inst), "[%d]UEID:Memomy allocation " + "Failed while UE related Ack Nack Information\n", + ue->ueId)); + rgSCHSCellFreeBuf (inst,ue,ueRecfg,idx); + RETVALUE(RFAILED); + } +#endif /* LTE_TDD */ + +#ifdef LTE_ADV + sCellInfo->sCellLnk.node = (PTR)sCellInfo; + cmLListAdd2Tail(&secCellCb->sCellUeLst, &sCellInfo->sCellLnk); +#endif + + /* Inserting UECB into SCELL DBM */ + rgSCHDbmInsUeCb(secCellCb, ue); + } + +#ifndef MAC_5GTF_UPDATE + ue->ul.useExtBSRSizes = ueRecfg->ueSCellCfgInfo.useExtBSRSizes; +#else + ue->ul.useExtBSRSizes = TRUE; +#endif + + for (idx = 0; idx < RGSCH_ULCTRL_RECP_DIST; idx++) + { + ue->ul.ctrlOnServCellIdx[idx] = 0xFF; + } + /* Trigger SCell addition to primary MAC */ + RETVALUE(ROK); + +} /* rgSCHSCellCfgUeCfg */ +/*f1b_Sprint */ +/** + * @brief UE SCell PUCCH reconfiguration for scheduler + * + * @details + * + * Function : rgSCHSCellCfgUePucchReCfg + * + * This functions updates UE specific scheduler + * information upon UE SCell PUCCH reconfiguration + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ue + * @param[int] RgrUeRecfg *ueRecfg + * @param[out] RgSchErrInfo *err + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 rgSCHSCellCfgUePucchReCfg +( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgrUeRecfg *ueRecfg, +RgSchErrInfo *err +) +#else +PUBLIC S16 rgSCHSCellCfgUePucchReCfg(cell, ue, ueRecfg, err) +RgSchCellCb *cell; +RgSchUeCb *ue; +RgrUeRecfg *ueRecfg; +RgSchErrInfo *err; +#endif +{ + Inst inst = cell->instIdx; + RgrUeSCellAckPucchCfg *sCellPucchRecfg = NULLP; + U8 idx; + + TRC2(rgSCHSCellCfgUePucchReCfg); + RGSCHDBGINFONEW(inst, (rgSchPBuf(inst), + "--------------------------------------------------------------------\n" + "UE SCell PUCCH ReConfiguration at SCH: rnti (%u) cell(%u)\n" + "--------------------------------------------------------------------\n", + ue->ueId, cell->cellId)); + + + sCellPucchRecfg = &ueRecfg->sCellAckN1ResCfg; + /* Copy the UCI format type suported/configured for UE */ + ue->uciFrmtTyp = sCellPucchRecfg->pucchFormatType; + + if (ue->uciFrmtTyp == RG_SCH_UCI_FORMAT1B_CS) + { + ue->n1PucchF1bResCb.cw1N1ResCount = sCellPucchRecfg->u.format1Bcs.sCellAckN1ResTb1Count; + ue->n1PucchF1bResCb.cw2N1ResCount = sCellPucchRecfg->u.format1Bcs.sCellAckN1ResTb2Count; + + for(idx = 0; idx < sCellPucchRecfg->u.format1Bcs.sCellAckN1ResTb1Count; idx++) + { + ue->n1PucchF1bResCb.cw1N1Res[idx].n1PucchIdx = sCellPucchRecfg->u.format1Bcs.sCellAckN1ResTb1[idx]; + } + + for(idx = 0; idx < sCellPucchRecfg->u.format1Bcs.sCellAckN1ResTb2Count; idx++) + { + ue->n1PucchF1bResCb.cw2N1Res[idx].n1PucchIdx = sCellPucchRecfg->u.format1Bcs.sCellAckN1ResTb2[idx]; + } + } +#ifdef LTE_ADV + else if (ue->uciFrmtTyp == RG_SCH_UCI_FORMAT3) + { + ue->n3PucchResCb.antP0N3ResCount = sCellPucchRecfg->u.format3.sCellAckN3ResAntP0Count; + ue->n3PucchResCb.antP1N3ResCount = sCellPucchRecfg->u.format3.sCellAckN3ResAntP1Count; + for (idx = 0;idx < ue->n3PucchResCb.antP0N3ResCount; idx++ ) + { + ue->n3PucchResCb.antP0N3Res[idx].n3PucchIdx + = sCellPucchRecfg->u.format3.sCellAckN3ResAntP0[idx]; + ue->n3PucchResCb.antP0N3Res[idx].n3Lnk.node = NULLP; + ue->n3PucchResCb.antP0N3Res[idx].sCellIdx = RGSCH_INVALID_CELL_IDX; + } + for (idx = 0;idx < ue->n3PucchResCb.antP1N3ResCount; idx++ ) + { + ue->n3PucchResCb.antP1N3Res[idx].n3PucchIdx + = sCellPucchRecfg->u.format3.sCellAckN3ResAntP1[idx]; + ue->n3PucchResCb.antP1N3Res[idx].n3Lnk.node = NULLP; + ue->n3PucchResCb.antP1N3Res[idx].sCellIdx = RGSCH_INVALID_CELL_IDX; + } + ue->simulAckNackCQIFormat3 = ueRecfg->simulAckNackCQIFormat3; + } +#endif + else + { + RLOG1(L_ERROR,"Wrong PUCCH Format:%d configured for CA",ue->uciFrmtTyp); + } + + RETVALUE(ROK); + +} /* rgSCHSCellCfgUePucchReCfg */ +/** + * @brief Validates the UE SCell Reconfiguration request from APP to SCH. + * + * @details + * + * Function : rgSCHCfgVldtRgrUeSCellRecfg + * + * Processing Steps: + * - Validate Number of SCells + * - If validated successfully, + * - Process Number of SCells + * - Else + * - Return RFAILED. + * - Validate SCellIdx value, + * - If validated successfully, + * - Process Number of RgrUeSecCellCfg + * - Else + * - Return RFAILED. + * + * @param[in] RgrUeRecfg *ueRecfg + * @param[out] RgSchCellCb *cell + * @param[out] RgSchUeCb *ue + * @param[out] RgSchErrInfo *errInfo + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 rgSCHCfgVldtRgrUeSCellRecfg +( +RgrUeRecfg *ueRecfg, +RgSchCellCb *cell, +RgSchUeCb *ue, +RgSchErrInfo *errInfo +) +#else +PUBLIC S16 rgSCHCfgVldtRgrUeSCellRecfg(inst, ueRecfg, cell, ue, errInfo) +RgrUeRecfg *ueRecfg; +RgSchCellCb *cell; +RgSchUeCb *ue; +RgSchErrInfo *errInfo; +#endif +{ + RgrUeSecCellCfg *ueSCellDedCfg = NULLP; + RgSchCellCb *sCell = NULLP; + Inst inst = cell->instIdx; + + TRC2(rgSCHCfgVldtRgrUeSCellRecfg); + + RGSCHDBGPRM(inst, (rgSchPBuf(inst), "VALIDATE RGR UE SCELL RECONFIG: cellId %d " + "oldUeId %d cell %p \n", ueRecfg->cellId, ueRecfg->oldCrnti)); + errInfo->errCause = RGSCHERR_CFG_INVALID_RGR_UE_SCELL_RECFG; + + if((ueRecfg->ueSCellCfgInfo.numSCells > RGR_MAX_SCELL_PER_UE) || + (ueRecfg->ueSCellCfgInfo.numSCells < 1)) + { + RGSCHDBGERRNEW(inst, (rgSchPBuf(inst), "Invalid number of SCELL " + " in SCELL Recfg\n")); + RETVALUE(RFAILED); + } + + for(U8 idx = 0; idx < ueRecfg->ueSCellCfgInfo.numSCells; idx++) + { + ueSCellDedCfg = &ueRecfg->ueSCellCfgInfo.ueSCellDedCfg[idx]; + if(ROK != rgSchUtlVldtCellId(inst, ueSCellDedCfg->sCellId)) + { + RGSCHDBGERRNEW(inst, (rgSchPBuf(inst), "SCellId is out of range")); + RETVALUE(RFAILED); + } + /* Validate existence of sec cell */ + sCell = rgSchUtlGetCellCb(inst, ueSCellDedCfg->sCellId); + if(NULLP == sCell ) + { + RGSCHDBGERRNEW(inst, (rgSchPBuf(inst), "SCell doesnt exists")); + RETVALUE(RFAILED); + } + + /* validate the range of serv cell index */ + if((ueSCellDedCfg->sCellIdx < 1) || + (ueSCellDedCfg->sCellIdx > RGR_MAX_SCELL_PER_UE)) + { + RGSCHDBGERRNEW(inst, (rgSchPBuf(inst),"Invalid Serv Cell Idx %d\n", + ueSCellDedCfg->sCellIdx)); + RETVALUE(RFAILED); + } + + /* Is this sec cell alredy confiured */ + if(NULLP != ue->cellInfo[ueSCellDedCfg->sCellIdx]) + { + RGSCHDBGERRNEW(inst, (rgSchPBuf(inst),"Secll with id %d already added\n", + ueSCellDedCfg->sCellIdx)); + RETVALUE(RFAILED); + } + + /* Validate CQI config params */ + if((rgSCHCfgVldtUeCqiModeCfg(sCell, &ueSCellDedCfg->ueSCellDlCqiCfg)) != ROK) + { + RGSCHDBGERRNEW(inst, (rgSchPBuf(inst), "Invalid CQI Mode " + " configuration for Ue %d\n",ue->ueId)); + RETVALUE(RFAILED); + } +#ifdef TFU_UPGRADE + /* 1. Validate UE Aperiodic CQI related parameters */ + if( ROK != rgSCHCfgVldtRgrUeACqiCfg (sCell, ue->ueId, + &ueSCellDedCfg->ueSCellDlCqiCfg.aprdCqiCfg, ueSCellDedCfg->txMode, + errInfo )) + { + RGSCHDBGERR(sCell->instIdx, (rgSchPBuf(sCell->instIdx), + "rgSCHCfgVldtCqiSrSrsUeCfg: Invalid Aperiodic CQI configuration\n")); + RETVALUE(RFAILED); + } + +#ifdef LTEMAC_HDFDD + if( ROK != rgSCHCfgVldtRgrUePCqiCfg (sCell, ue->ueId, + &ueSCellDedCfg->ueSCellDlCqiCfg.prdCqiCfg, ueRecfg->isHdFddEnbld, + ueSCellDedCfg->txMode, errInfo )) +#else + if( ROK != rgSCHCfgVldtRgrUePCqiCfg (sCell, ue->ueId, + &ueSCellDedCfg->ueSCellDlCqiCfg.prdCqiCfg, + ueSCellDedCfg->txMode, + errInfo )) +#endif + { + RGSCHDBGERR(sCell->instIdx, (rgSchPBuf(sCell->instIdx), + "rgSCHCfgVldtCqiSrSrsUeCfg: Invalid Periodic CQI configuration\n")); + RETVALUE(RFAILED); + } + + if((ueSCellDedCfg->txMode.txModeEnum < RGR_UE_TM_1) || + (ueSCellDedCfg->txMode.txModeEnum > RGR_UE_TM_9)) + { + RGSCHDBGERRNEW(inst, (rgSchPBuf(inst), "SCELL Invalid transmission mode for" + " UE %d\n", (U8)ueSCellDedCfg->txMode.txModeEnum)); + RETVALUE(RFAILED); + } +#endif + } + + errInfo->errCause = RGSCHERR_NONE; + RGSCHDBGINFO(inst, (rgSchPBuf(inst), "RGR Ue SCell Reconfig validation done: " + "cellId %d oldUeId %d\n", ueRecfg->cellId, ue->ueId)); + RETVALUE(ROK); +} /* rgSCHCfgVldtRgrUeSCellRecfg */ + +/** + * @brief Ue SCell configuration roll back due to failure during configuration + * of any scell + * + * @details + * + * Function : rgSCHSCellCfgUeCfgRollBack + * + * This functions roll backs the configuration of successfully added Scell + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ue + * @param[int] RgrUeRecfg *ueRecfg + * @param[out] RgSchErrInfo *err + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PRIVATE S16 rgSCHSCellCfgUeCfgRollBack +( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgrUeRecfg *ueRecfg +) +#else +PRIVATE S16 rgSCHSCellCfgUeCfgRollBack(cell, ue, ueRecfg) +RgSchCellCb *cell; +RgSchUeCb *ue; +RgrUeRecfg *ueRecfg; +#endif +{ + Inst inst = cell->instIdx; + RgrUeSecCellCfg *sCellInfoCfg = NULLP; + RgSchUeCellInfo *sCellInfo = NULLP; + RgSchCmnCell *cellSch = NULLP; + + TRC2(rgSCHSCellCfgUeCfgRollBack); + + RGSCHDBGINFONEW(inst, (rgSchPBuf(inst), + "--------------------------------------------------------------------\n" + "UE SCell config roll back at SCH: rnti (%u) cell(%u)\n" + "--------------------------------------------------------------------\n", + ue->ueId, cell->cellId)); + + /* Free all Added scell in this transaction */ + for(U8 idx = 0; idx < ueRecfg->ueSCellCfgInfo.numSCells; idx++) + { + sCellInfoCfg = &ueRecfg->ueSCellCfgInfo.ueSCellDedCfg[idx]; + sCellInfo = ue->cellInfo[(sCellInfoCfg->sCellIdx)]; + + /* if sCellInfo is not NULLP that means this Scell is added hence + * delte it*/ + if (NULLP != sCellInfo) + { + /* Clear Scheduler specific list for this UE from the + * corresponding CELL */ + cellSch = RG_SCH_CMN_GET_CELL(sCellInfo->cell); + cellSch->apisDl->rgSCHDlUeReset(sCellInfo->cell, sCellInfo->ue); + + /* Delete harq Entity of Scell*/ + rgSCHDhmDelHqEnt(cell, &(sCellInfo->hqEnt)); + + rgSCHUtlFreeSBuf(inst, (Data**)&(sCellInfo), + sizeof(RgSchUeCellInfo)); + + ue->cellInfo[(sCellInfoCfg->sCellIdx)] = NULLP; + ue->numSCells--; +#ifdef LTE_ADV + if (ue->numSCells == 0) + { + ue->allocCmnUlPdcch = TRUE; + /* As there is no SCell left so DCI 0 size at UE specific search space + * will be recalculated as the CSI is reduced to 1 bit */ + rgSCHUtlUpdUeDciSize(cell, ue, FALSE); + } +#endif + } + } + RETVALUE(ROK); +} +#endif /* LTE_ADV */ +/** + * @brief Validates the UE reconfiguration request from RRC to MAC. + * + * @details + * + * Function : rgSCHCfgVldtRgrUeRecfg + * + * Processing Steps: + * - Retrieve the UE control block. + * - If successful, + * - Validate the range of reconfigured values recieved in + * re-configuration request. + * - If validated successfully, + * - Return ROK and pointer to the cell and ue. + * - Else + * - Return RFAILED. + * - Else return RFAILED. + * + * @param[in] Inst inst + * @param[in] RgrUeRecfg *ueRecfg + * @param[out] RgSchCellCb **cell + * @param[out] RgSchUeCb **ue + * @param[out] RgSchErrInfo *errInfo + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 rgSCHCfgVldtRgrUeRecfg +( +Inst inst, +RgrUeRecfg *ueRecfg, +RgSchCellCb **cell, +RgSchUeCb **ue, +RgSchErrInfo *errInfo +) +#else +PUBLIC S16 rgSCHCfgVldtRgrUeRecfg(inst, ueRecfg, cell, ue, errInfo) +Inst inst; +RgrUeRecfg *ueRecfg; +RgSchCellCb **cell; +RgSchUeCb **ue; +RgSchErrInfo *errInfo; +#endif +{ + + TRC2(rgSCHCfgVldtRgrUeRecfg); + + errInfo->errCause = RGSCHERR_CFG_INVALID_RGR_UE_RECFG; + + if (((*cell) == NULLP) || + ((*cell)->cellId != ueRecfg->cellId)) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,ueRecfg->cellId, + "Cell does not exist for OLD CRNTI:%d",ueRecfg->oldCrnti); + RETVALUE(RFAILED); + } + + /* Fetch the Old Ue */ + if ((*ue = rgSCHDbmGetUeCb(*cell, ueRecfg->oldCrnti)) == NULLP) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,ueRecfg->cellId,"OLD CRNTI:%d does not exist", + ueRecfg->oldCrnti); + RETVALUE(RFAILED); + } + +#ifdef LTE_ADV + if(RGR_UE_SCELL_ADD_RECFG & ueRecfg->ueRecfgTypes) + { + S16 ret = rgSCHCfgVldtRgrUeSCellRecfg(ueRecfg,*cell, *ue, errInfo); + if ( ret != ROK) + { + RGSCHDBGERR(inst,(rgSchPBuf(inst), "Ue SCell Recfg Validation FAILED\n")); + RETVALUE(RFAILED); + } + errInfo->errCause = RGSCHERR_NONE; + RETVALUE(ROK); + } +#endif + + if (ueRecfg->oldCrnti != ueRecfg->newCrnti) + { + if (rgSCHDbmGetUeCb(*cell, ueRecfg->newCrnti) != NULLP) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,ueRecfg->cellId,"NEW CRNTI:%d already exists", + ueRecfg->newCrnti); + RETVALUE(RFAILED); + } + } + + if ((ueRecfg->ueRecfgTypes & RGR_UE_CSG_PARAM_RECFG) &&\ + ((*ue)->csgMmbrSta == ueRecfg->csgMmbrSta)) + { + RLOG_ARG2(L_ERROR,DBG_CELLID,ueRecfg->cellId,"UE ID [%d] invalid CSG Membership reconfig :%d ", + ueRecfg->newCrnti, (U8)ueRecfg->csgMmbrSta); + RETVALUE(RFAILED); + } + /* Validate values */ + if ((ueRecfg->ueRecfgTypes & RGR_UE_TXMODE_RECFG) && + (ueRecfg->txMode.pres == TRUE) && + ((ueRecfg->txMode.txModeEnum < RGR_UE_TM_1) || + (ueRecfg->txMode.txModeEnum > RGR_UE_TM_7))) + { + RLOG_ARG2(L_ERROR,DBG_CELLID,ueRecfg->cellId,"Invalid transmission mode %d" + "for NEW CRNTI:%d", (U8)ueRecfg->txMode.txModeEnum,ueRecfg->newCrnti); + RETVALUE(RFAILED); + } +#ifndef TFU_UPGRADE + if ((ueRecfg->ueRecfgTypes & RGR_UE_PRD_DLCQI_RECFG) && + (((ueRecfg->prdDlCqiRecfg.k < 1) || (ueRecfg->prdDlCqiRecfg.k > 4)) || + ((ueRecfg->prdDlCqiRecfg.cqiPmiCfgIdx < 1) || + (ueRecfg->prdDlCqiRecfg.cqiPmiCfgIdx > 1024)))) + { + RLOG_ARG2(L_ERROR,DBG_CELLID,ueRecfg->cellId,"Invalid Periodic CQI INFO" + "OLD CRNTI:%d NEW CRNTI:%d",(U8)ueRecfg->oldCrnti,ueRecfg->newCrnti); + RETVALUE(RFAILED); + } +#endif + if ((ueRecfg->ueRecfgTypes & RGR_UE_ULHARQ_RECFG) && + (ueRecfg->ueUlHqRecfg.maxUlHqTx < RGSCH_MIN_HQ_TX)) + { + RLOG_ARG2(L_ERROR,DBG_CELLID,ueRecfg->cellId,"Invalid Uplink HARQ config %d" + "for NEW CRNTI:%d", ueRecfg->ueUlHqRecfg.maxUlHqTx,ueRecfg->newCrnti); + RETVALUE(RFAILED); + } +#ifndef TFU_UPGRADE + if ((ueRecfg->ueRecfgTypes & RGR_UE_PRD_DLCQI_RECFG) && + (ueRecfg->prdDlCqiRecfg.prdModeEnum > RGR_PRD_CQI_MOD21)) + { + RLOG_ARG2(L_ERROR,DBG_CELLID,ueRecfg->cellId,"Invalid periodic mode config for" + " DL CQI %d NEW CRNTI:%d", (U8)ueRecfg->prdDlCqiRecfg.prdModeEnum,ueRecfg->newCrnti); + RETVALUE(RFAILED); + } +#else + if ((ueRecfg->ueRecfgTypes & RGR_UE_PCQI_RECFG) && + (ueRecfg->cqiCfg.cqiSetup.prdModeEnum > RGR_PRD_CQI_MOD21)) + { + RLOG_ARG2(L_ERROR,DBG_CELLID,ueRecfg->cellId,"Invalid periodic mode config for " + "DL CQI %d for NEW CRNTI:%d",(U8)ueRecfg->cqiCfg.cqiSetup.prdModeEnum,ueRecfg->newCrnti); + RETVALUE(RFAILED); + } +#endif /* TFU_UPGRADE */ + /* Validate UE Category */ + if (ueRecfg->ueCatEnum > CM_LTE_UE_CAT_8) + { + RLOG_ARG2(L_ERROR,DBG_CELLID,ueRecfg->cellId,"Invalid category %d for NEW CRNTI:%d", + (U8)ueRecfg->ueCatEnum,ueRecfg->newCrnti); + RETVALUE(RFAILED); + } + + /* Validate UE Access Stratum Release */ + if ((ueRecfg->ueRecfgTypes & RGR_UE_UE_ACCESS_STRATUM_REL_RECFG) && \ + (ueRecfg->accessStratumRls > RGR_REL_11)) + { + RGSCHDBGERRNEW(inst, (rgSchPBuf(inst), "Invalid Access Stratum Release %u for UE\n", + ueRecfg->accessStratumRls)); + RETVALUE(RFAILED); + } + RGSCHDBGINFONEW(inst, (rgSchPBuf(inst), "Configured Access Stratum Release %u\n", \ + ueRecfg->accessStratumRls)); + + if ((ueRecfg->ueRecfgTypes & RGR_UE_APRD_DLCQI_RECFG) && + ((ueRecfg->aprdDlCqiRecfg.pres == TRUE) && + ((ueRecfg->aprdDlCqiRecfg.aprdModeEnum > RGR_APRD_CQI_MOD31) || + (*cell)->bwCfg.dlTotalBw <= 7))) + { + RLOG_ARG2(L_ERROR,DBG_CELLID,ueRecfg->cellId,"Invalid aperiodic mode config for" + " DL CQI %d for NEW CRNTI:%d", (U8)ueRecfg->aprdDlCqiRecfg.aprdModeEnum,ueRecfg->newCrnti); + RETVALUE(RFAILED); + } + if ((ueRecfg->ueRecfgTypes & RGR_UE_ULPWR_RECFG) && + (rgSCHCfgVldtUePwrCfg(*cell, &ueRecfg->ueUlPwrRecfg) != ROK)) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,ueRecfg->cellId,"Invalid PUSCH Group power" + " Reconfiguration for NEW CRNTI:%d",ueRecfg->newCrnti); + RETVALUE(RFAILED); + } + + + if ((ueRecfg->ueRecfgTypes & RGR_UE_ACKNACK_MEASGAP_RECFG) && + (rgSCHCfgVldtUeMeasGapAckNakRepRecfg(*cell, ueRecfg) != ROK)) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,ueRecfg->cellId,"Invalid MeasGap/AckNackRep" + " Reconfiguration for NEW CRNTI:%d",ueRecfg->newCrnti); + RETVALUE(RFAILED); + } +#ifdef LTEMAC_SPS + if(rgSCHCfgVldtSpsReCfg(*cell, *ue, ueRecfg)!= ROK) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,ueRecfg->cellId,"Invalid SPS" + " Reconfiguration for NEW CRNTI:%d",ueRecfg->newCrnti); + RETVALUE(RFAILED); + } +#endif +#ifdef TFU_UPGRADE + /* Validated Periodic CQI/PMI, RI , SRS and SR related UeCfg */ + if ( ROK != rgSCHCfgVldtCqiSrSrsUeReCfg(*cell, *ue, ueRecfg, errInfo)) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,ueRecfg->cellId,"Invalid ACQI, PCQI/SR/SRS " + "Re-configuration for NEW CRNTI:%d",ueRecfg->newCrnti); + RETVALUE(RFAILED); + } +#endif + if ((ueRecfg->ueRecfgTypes & RGR_UE_DRX_RECFG) && + (rgSCHCfgVldtDrxUeCfg(*cell, &(ueRecfg->ueDrxRecfg)) != ROK)) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,ueRecfg->cellId,"Invalid drxParams" + " Reconfiguration for NEW CRNTI:%d",ueRecfg->newCrnti); + RETVALUE(RFAILED); + } + +/* ccpu00117452 - MOD - Changed macro name from + RGR_RRM_DLPWR_CNTRL to RGR_CQI_REPT */ +#ifdef RGR_CQI_REPT + /* Validate DL Power Control Config parameters */ + if(rgSCHCfgVldtCqiReptReCfg(*cell, ueRecfg)!= ROK) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,ueRecfg->cellId,"Invalid DL Power Control" + " Reconfiguration for NEW CRNTI:%d",ueRecfg->newCrnti); + RETVALUE(RFAILED); + } +#endif /* End of RGR_CQI_REPT */ + errInfo->errCause = RGSCHERR_NONE; + RETVALUE(ROK); +} /* rgSCHCfgVldtRgrUeRecfg */ + + +/** + * @brief Validates the logical channel reconfiguration request from + * RRC to MAC. + * + * @details + * + * Function : rgSCHCfgVldtRgrLchRecfg + * + * Processing Steps: + * - Retrieve the uplink and downlink logical channel control block. + * - If successful, + * - Validate the range of reconfigured values recieved in + * re-configuration request. + * - If validated successfully, + * - Return ROK and pointer to the cell, UE and logical channel. + * - Else + * - Return RFAILED. + * - Else return RFAILED. + * + * @param[in] RgrLchRecfg *lcRecfg + * @param[out] RgSchCellCb **cell + * @param[out] RgSchUeCb **ue + * @param[out] RgSchUlLcCb **ulLc + * @param[out] RgSchDlLcCb **dlLc + * @param[out] RgSchErrInfo *errInfo + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 rgSCHCfgVldtRgrLchRecfg +( +Inst inst, +RgrLchRecfg *lcRecfg, +RgSchCellCb **cell, +RgSchUeCb **ue, +RgSchDlLcCb **dlLc, +RgSchErrInfo *errInfo +) +#else +PUBLIC S16 rgSCHCfgVldtRgrLchRecfg(inst, lcRecfg, cell, ue, dlLc, errInfo) +Inst inst; +RgrLchRecfg *lcRecfg; +RgSchCellCb **cell; +RgSchUeCb **ue; +RgSchDlLcCb **dlLc; +RgSchErrInfo *errInfo; +#endif +{ + TRC2(rgSCHCfgVldtRgrLchRecfg); + + errInfo->errCause = RGSCHERR_CFG_INVALID_RGR_LC_RECFG; + + if (((*cell) == NULLP) || + ((*cell)->cellId != lcRecfg->cellId)) + { + RLOG_ARG2(L_ERROR,DBG_CELLID,lcRecfg->cellId,"Cell does not exist " + "for CRNTI:%d LCID:%d",lcRecfg->crnti,lcRecfg->lcId); + RETVALUE(RFAILED); + } + + /* Fetch the Ue for dedicated channels */ + if ((*ue = rgSCHDbmGetUeCb(*cell, lcRecfg->crnti)) == NULLP) + { + RLOG_ARG2(L_ERROR,DBG_CELLID,lcRecfg->cellId,"UEID does not exist" + "dedicated logical channel for CRNTI:%d LCID:%d",lcRecfg->crnti,lcRecfg->lcId); + RETVALUE(RFAILED); + } + + if ((*dlLc = rgSCHDbmGetDlDedLcCb((*ue), lcRecfg->lcId)) == NULLP) + { + RLOG_ARG2(L_ERROR,DBG_CELLID,lcRecfg->cellId,"Dedicated DL LC does not " + "exist for CRNTI:%d LCID:%d",lcRecfg->crnti,lcRecfg->lcId); + RETVALUE(RFAILED); + } + + errInfo->errCause = RGSCHERR_NONE; + RETVALUE(ROK); +} /* rgSCHCfgVldtRgrLchRecfg */ + +/** + * @brief Validates the UE Reset request from RRM to MAC. + * + * @details + * + * Function : rgSCHCfgVldtRgrUeReset + * + * Processing Steps: + * - Retrieve the CELL control block + * - If cell does not exist return RFAILED + * - Retrieve UE Control block + * - If UE does not exist return RFAILED + * - Return ROK + * + * @param[in] Inst inst + * @param[in] RgrRst *reset + * @param[out] RgSchCellCb **cell + * @param[out] RgSchUeCb **ue + * @param[out] RgErrInfo *errInfo + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 rgSCHCfgVldtRgrUeReset +( +Inst inst, +RgrRst *reset, +RgSchCellCb *cell, +RgSchUeCb **ue, +RgSchErrInfo *errInfo +) +#else +PUBLIC S16 rgSCHCfgVldtRgrUeReset(inst, reset, cell, ue, errInfo) +Inst inst; +RgrRst *reset; +RgSchCellCb *cell; +RgSchUeCb **ue; +RgSchErrInfo *errInfo; +#endif +{ + TRC2(rgSCHCfgVldtRgrUeReset); + + + errInfo->errCause = RGSCHERR_CFG_INVALID_RGR_UE_RESET; + + if ((cell == NULLP) || (cell->cellId != reset->cellId)) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,reset->cellId,"CELL does not exist for CRNTI:%d", + reset->crnti); + RETVALUE(RFAILED); + } + /* Fetch the Ue */ + if ((*ue = rgSCHDbmGetUeCb(&(*cell), reset->crnti)) == NULLP) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,reset->cellId,"UE does not exist for CRNTI:%d", + reset->crnti); + RETVALUE(RFAILED); + } + + errInfo->errCause = RGSCHERR_NONE; + + RETVALUE(ROK); +} /* rgSCHCfgVldtRgrUeReset */ + + +/** + * @brief Validates the logical channel reconfiguration request from + * RRC to MAC. + * + * @details + * + * Function : rgSCHCfgVldtRgrLcgRecfg + * + * Processing Steps: + * - Retrieve the uplink and downlink logical channel control block. + * - If successful, + * - Validate the range of reconfigured values recieved in + * re-configuration request. + * - If validated successfully, + * - Return ROK and pointer to the cell, UE and logical channel. + * - Else + * - Return RFAILED. + * - Else return RFAILED. + * + * @param[in] RgrLchRecfg *lcRecfg + * @param[out] RgSchCellCb **cell + * @param[out] RgSchUeCb **ue + * @param[out] RgSchErrInfo *errInfo + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 rgSCHCfgVldtRgrLcgRecfg +( +Inst inst, +RgrLcgRecfg *lcgRecfg, +RgSchCellCb *cell, +RgSchUeCb **ue, +RgSchErrInfo *errInfo +) +#else +PUBLIC S16 rgSCHCfgVldtRgrLcgRecfg(inst, lcgRecfg, cell, ue, errInfo) +Inst inst; +RgrLcgRecfg *lcgRecfg; +RgSchCellCb *cell; +RgSchUeCb **ue; +RgSchErrInfo *errInfo; +#endif +{ + TRC2(rgSCHCfgVldtRgrLcgRecfg); + + errInfo->errCause = RGSCHERR_CFG_INVALID_RGR_LCG_RECFG; + + if (((cell) == NULLP) || + ((cell)->cellId != lcgRecfg->cellId)) + { + RLOG_ARG2(L_ERROR,DBG_CELLID,lcgRecfg->cellId,"Cell does not exist for" + "CRNTI:%d LCGID:%d",lcgRecfg->crnti,lcgRecfg->ulRecfg.lcgId); + RETVALUE(RFAILED); + } + + /* Fetch the Ue for dedicated channels */ + if ((*ue = rgSCHDbmGetUeCb(&(*cell), lcgRecfg->crnti)) == NULLP) + { + RLOG_ARG2(L_ERROR,DBG_CELLID,lcgRecfg->cellId,"UE does not exist for " + "dedicated logical channel group CRNTI:%d LCGID:%d", + lcgRecfg->crnti,lcgRecfg->ulRecfg.lcgId); + RETVALUE(RFAILED); + } + if (lcgRecfg->ulRecfg.lcgId > (RGSCH_MAX_LCG_PER_UE - 1)) + { + RLOG_ARG2(L_ERROR,DBG_CELLID,lcgRecfg->cellId,"Invalid lcgId for uplink logical" + "channel CRNTI:%d LCGID:%d", + lcgRecfg->crnti,lcgRecfg->ulRecfg.lcgId); + RETVALUE(RFAILED); + } + + if ((lcgRecfg->ulRecfg.gbr != 0) && (lcgRecfg->ulRecfg.mbr < lcgRecfg->ulRecfg.gbr)) + { + RGSCHDBGINFO(inst, (rgSchPBuf(inst), "Dedicated Logical Group %d validation failed" + " for ue %d for cell %d\n", lcgCfg->ulInfo.lcgId, lcgCfg->crnti, lcgCfg->cellId)); + RETVALUE(RFAILED); + } + errInfo->errCause = RGSCHERR_NONE; + RETVALUE(ROK); +} /* rgSCHCfgVldtRgrLcgRecfg */ + +/** + * + * @details + * + * Function : rgSCHDynCfiCfg + * + * @param[in] RgSchCellCb *cell + * RgrCellCfg *cellCfg + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PRIVATE S16 rgSCHDynCfiCfg +( +RgSchCellCb *cell, +RgrCellCfg *cellCfg +) +#else +PRIVATE S16 rgSCHDynCfiCfg(cell, cellCfg) +RgSchCellCb *cell; +RgrCellCfg *cellCfg; +#endif +{ + U8 cfi; +#ifdef LTE_TDD + U8 ulDlCfgIdx = cellCfg->ulDlCfgIdx; + U8 mphIdx; + U8 maxMPhich; + U16 numDlSf; +#endif + + TRC2(rgSCHDynCfiCfg); + + cell->dynCfiCb.isDynCfiEnb = cellCfg->isDynCfiEnb; + + /* Initializing Failure Sample Period */ + cell->dynCfiCb.failSamplePrd = (RGSCH_CFI_TTI_MON_INTRVL * + RGSCH_CFI_STEP_UP_TTI_PRCNTG)/100; + /* Initializing Number of Failure Samples */ + cell->dynCfiCb.numFailSamples = (RGSCH_CFI_TTI_MON_INTRVL/ + cell->dynCfiCb.failSamplePrd); + cell->dynCfiCb.maxCfi = RGSCH_MAX_CFI_VAL; + /* Allocating memory for CCE failure average array based on + * monitoring interval and CCE failure sample period */ + if((rgSCHUtlAllocSBuf(cell->instIdx, (Data**)&(cell->dynCfiCb.cceFailSamples), + (cell->dynCfiCb.numFailSamples * sizeof(U16)))) != ROK) + { + RLOG_ARG0(L_ERROR,DBG_CELLID,cellCfg->cellId,"Memory allocation FAILED for cell"); + RETVALUE(RFAILED); + } + + /* Setting the Invalid value 0xFF to pdcchSfIdx, it will be assigned + * a valid value during CFI swithing is done */ + cell->dynCfiCb.pdcchSfIdx = 0xFF; + +#ifdef LTE_TDD + /* In case of config index 0, the mphich index can be upto 2 + * in other config index cases, it will always be set as 1*/ + if(ulDlCfgIdx == 0) + { + maxMPhich = RG_SCH_MAX_MPHICH; + } + else + { + maxMPhich = RG_SCH_MAX_MPHICH -1; + } + /* Calculate the number of CCEs in the cell */ + for(cfi = 1; cfi < RG_SCH_CMN_MAX_CFI; cfi++) + { + for(mphIdx = 0; mphIdx < maxMPhich; mphIdx++) + { + cell->dynCfiCb.cfi2NCceTbl[mphIdx][cfi] = + rgSCHUtlCalcNCce(cell->bwCfg.dlTotalBw, + cell->phichCfg.ngEnum, cfi, mphIdx, + cell->numTxAntPorts, + cell->isCpDlExtend); + } + } +#else + /* Calculate the number of CCEs in the cell */ + for(cfi = 1; cfi < RG_SCH_CMN_MAX_CFI; cfi++) + { + /* CFI Index starts from 1 so that there can be a direct mapping from + actual CFI value to cfi Index. mPhich index will always be set + as 0 for FDD */ + cell->dynCfiCb.cfi2NCceTbl[0][cfi] = + rgSCHUtlCalcNCce(cell->bwCfg.dlTotalBw, cell->phichCfg.ngEnum, + cfi, cell->numTxAntPorts, cell->isCpDlExtend); + } + + /* Calculate the number of CCEs in the cell */ + if(cell->dynCfiCb.isDynCfiEnb == TRUE) + { + /* In case if Dynamic CFI feature is enabled, default CFI + * value 1 is used */ + cell->nCce = cell->dynCfiCb.cfi2NCceTbl[0][1]; + } + else + { + cell->nCce = cell->dynCfiCb.cfi2NCceTbl[0][cellCfg->cfiCfg.cfi]; + } +#endif + +#ifdef LTE_TDD + numDlSf = rgSchTddNumDlSubfrmTbl[ulDlCfgIdx][9] * + (RGSCH_CFI_TTI_MON_INTRVL/10); + cell->dynCfiCb.cfiStepUpTtiCnt = + (RGSCH_CFI_STEP_UP_TTI_PRCNTG * numDlSf)/100; + cell->dynCfiCb.cfiStepDownTtiCnt = + (RGSCH_CFI_STEP_DOWN_TTI_PERCNTG * numDlSf)/100; +#else + cell->dynCfiCb.cfiStepUpTtiCnt = (RGSCH_CFI_STEP_UP_TTI_PRCNTG * + RGSCH_CFI_TTI_MON_INTRVL)/100; + cell->dynCfiCb.cfiStepDownTtiCnt = (RGSCH_CFI_STEP_DOWN_TTI_PERCNTG * + RGSCH_CFI_TTI_MON_INTRVL)/100; +#endif + + RETVALUE(ROK); +} + +/** + * @brief Handler for the SCHED Enb configuration request from RRM to MAC. + * + * @details + * + * Function : rgSCHCfgRgrSchedEnbCfg + * + * Processing Steps: + * - Invoke SCH with SCHEDULER control block to update + * scheduler specific information. + * - Update rgSch control block with the values recieved in the + * configuration. + * - If successful, return ROK else RFAILED. + * + * @param[in] RgSchCb *instCb + * @param[in] SpId spId + * @param[in] RgSchSchedEnbCfg *schedEnbCfg + * @param[out] RgSchErrInfo *errInfo + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 rgSCHCfgRgrSchedEnbCfg +( +Inst inst, +SpId spId, +RgrSchedEnbCfg *schedEnbCfg, +RgSchErrInfo *errInfo +) +#else +PUBLIC S16 rgSCHCfgRgrSchedEnbCfg(inst, spId, schedEnbCfg, errInfo) +Inst inst, +SpId spId; +RgrSchedEnbCfg *schedEnbCfg; +RgSchErrInfo *errInfo; +#endif +{ + TRC2(rgSCHCfgRgrSchedEnbCfg); + + RGSCHDBGPRM(inst, (rgSchPBuf(inst), "APPLYING RGR SCH ENB CONFIG: \n")); + errInfo->errCause = RGSCHERR_CFG_INVALID_RGR_ENB_CFG; + + rgSchCb[inst].rgrSchedEnbCfg = *schedEnbCfg; + RGSCHDBGPRM(inst, (rgSchPBuf(inst),"\ndlSchdType %d ulSchdType %d dlTptCoeffi %d" + "dlFairCoeffi %d ulTptCoeffi %d ulFairCoeffi %d\n", + schedEnbCfg->dlSchdType, schedEnbCfg->ulSchdType, schedEnbCfg->dlSchInfo.dlPfs.tptCoeffi, + schedEnbCfg->dlSchInfo.dlPfs.fairCoeffi, schedEnbCfg->ulSchInfo.ulPfs.tptCoeffi, + schedEnbCfg->ulSchInfo.ulPfs.fairCoeffi)); + +#ifdef RG_5GTF + rgSchCb[inst].rgSchDynTdd.isDynTddEnbld = schedEnbCfg->isDynTddEnbld; +#endif + if(RGR_SCH_TYPE_PFS == schedEnbCfg->dlSchdType) + { + rgSCHEnbPfsDlCfg(inst, errInfo); + } + + errInfo->errCause = RGSCHERR_NONE; + RGSCHDBGINFO(inst, (rgSchPBuf(inst), "RGR SCH ENBconfig done: \n")); + RETVALUE(ROK); +} /* rgSCHCfgRgrSchedEnbCfg */ + +#ifdef RG_5GTF +/** + * @brief Handler for the cell configuration of 5gtf. + * + * @details + * + * Function : rgSCH5gtfCellCfg + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchCellCfg *cellCfg + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 rgSCH5gtfCellCfg +( +RgSchCellCb *cell, +RgrCellCfg *cellCfg +) +#else +PUBLIC S16 rgSCH5gtfCellCfg(cell, cellCfg) +RgSchCellCb *cell; +RgrCellCfg *cellCfg; +#endif +{ + U8 idx; + + TRC2(rgSCHCfgRgrCellCfg); + + for(idx = 0; idx < MAX_5GTF_GROUP; idx++) + { + cell->cell5gtfCb.ueGrp5gConf[idx].beamBitMask = 0; + } + + for(idx = 0 ; idx < MAX_5GTF_SUBFRAME_INFO ; ++idx) + { + cell->cell5gtfCb.dynConfig[idx] = cellCfg->Cell5gtfCfg.dynConfig[idx]; + } + cell->cell5gtfCb.numUes = cellCfg->Cell5gtfCfg.numUes; + cell->cell5gtfCb.uePerGrpPerTti = cellCfg->Cell5gtfCfg.uePerGrp; + cell->cell5gtfCb.ueGrpPerTti = cellCfg->Cell5gtfCfg.ueGrpPerTti; + cell->cell5gtfCb.numCCs = cellCfg->Cell5gtfCfg.numOfCC; + cell->cell5gtfCb.bwPerCC = cellCfg->Cell5gtfCfg.bwPerCC; + printf("\ncell cfg at schd,numUes:%u,uepergrp:%u,uegrppertti:%u,numCC:%u,bwPerc:%u cfi %u\n", + cell->cell5gtfCb.numUes,cell->cell5gtfCb.uePerGrpPerTti,cell->cell5gtfCb.ueGrpPerTti, + cell->cell5gtfCb.numCCs,cell->cell5gtfCb.bwPerCC, cell->cell5gtfCb.cfi); + RETVALUE(ROK); +} +#endif + +#ifdef XEON_LMT_ITBS +EXTERN U16 gWrMaxDlItbs; +EXTERN U16 gWrMaxUlItbs; +#endif +/** + * @brief Handler for the cell configuration request from RRM to MAC. + * + * @details + * + * Function : rgSCHCfgRgrCellCfg + * + * Processing Steps: + * - Invoke SCH with cell control block to update + * scheduler specific information. + * - Update cell control block with the values recieved in the + * configuration. + * - Add to the active list of cells if cell becomes ACTIVE. + * - If successful, return ROK else RFAILED. + * + * @param[in] RgSchCb *instCb + * @param[in] SpId spId + * @param[in] RgSchCellCfg *cellCfg + * @param[out] RgSchErrInfo *errInfo + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 rgSCHCfgRgrCellCfg +( +RgSchCb *instCb, +SpId spId, +RgrCellCfg *cellCfg, +RgSchErrInfo *errInfo +) +#else +PUBLIC S16 rgSCHCfgRgrCellCfg(instCb, spId, cellCfg, errInfo) +RgSchCb *instCb; +SpId spId; +RgrCellCfg *cellCfg; +RgSchErrInfo *errInfo; +#endif +{ + S16 ret; + U8 idx; + Pst pst; + RgInfCellReg cellRegReq; + RgSchCellCb *cell = NULLP; + Inst inst = instCb->rgSchInit.inst; + U32 Idx1 = (U8)((cellCfg->cellId - instCb->genCfg.startCellId)&(CM_LTE_MAX_CELLS-1)); + + TRC2(rgSCHCfgRgrCellCfg); + + errInfo->errCause = RGSCHERR_CFG_RGR_CELL_CFG; + + cmMemset((U8*)&pst, (U8)0, sizeof(Pst)); + + /* Allocate the scheduler's cell control block */ + if((ret = rgSCHUtlAllocSBuf(inst, (Data**)&cell, sizeof(RgSchCellCb))) + != ROK) + { + RLOG_ARG0(L_ERROR,DBG_CELLID,cellCfg->cellId,"Memory allocation FAILED for cell"); + RETVALUE(RFAILED); + } +#ifdef EMTC_ENABLE + if(cellCfg->emtcEnable) + { + if((ret = rgSCHEmtcCellAlloc(cell)) + != ROK) + { + RLOG_ARG0(L_ERROR,DBG_CELLID,cellCfg->cellId,"Memory allocation FAILED for emtc cell"); + RETVALUE(RFAILED); + } + } +#endif + if ((U8 *)cell == NULLP) + { + RLOG_ARG0(L_ERROR,DBG_CELLID,cellCfg->cellId,"Memory allocation FAILED for cell"); + RETVALUE(RFAILED); + } + /* Initialize the lists of the cell */ + ret = rgSCHDbmInitCell(cell); + if (ret != ROK) + { + RLOG_ARG0(L_ERROR,DBG_CELLID,cellCfg->cellId,"DBM initialization FAILED for cell"); + rgSCHCfgFreeCellCb(cell); + RETVALUE(RFAILED); + } +/* LTE_ADV_FLAG_REMOVED_START */ + if(cellCfg->rgrLteAdvCfg.pres & RGR_ABS) + { + cell->lteAdvCb.absCfg = + cellCfg->rgrLteAdvCfg.absCfg; + cmMemset((U8*)cell->lteAdvCb.absLoadInfo, 0, sizeof(U32)*RGR_ABS_PATTERN_LEN); + cell->lteAdvCb.absLoadTtiCnt = 0; + } + + if(cellCfg->rgrLteAdvCfg.pres & RGR_SFR) + { + cell->lteAdvCb.sfrCfg = + cellCfg->rgrLteAdvCfg.sfrCfg; + } + if(cellCfg->rgrLteAdvCfg.pres & RGR_DSFR) + { + cell->lteAdvCb.dsfrCfg = + cellCfg->rgrLteAdvCfg.dsfrCfg; + } +/* LTE_ADV_FLAG_REMOVED_END */ + +#ifdef EMTC_ENABLE + cell->emtcEnable = cellCfg->emtcEnable; +#endif + /* Initialize the cell */ + cell->cellId = cellCfg->cellId; + cell->instIdx = inst; + cell->macInst = cellCfg->macInst; + cell->isCpUlExtend = cellCfg->isCpUlExtend; + cell->isCpDlExtend = cellCfg->isCpDlExtend; + + cell->numTxAntPorts = rgSchCb[inst].rgrSchedEnbCfg.numTxAntPorts; + if(cell->numTxAntPorts == 1) + { + cell->numCellRSPerSf = RGSCH_NUM_CELL_RS_ONE_ANT_PORT; + } + else if(cell->numTxAntPorts == 2) + { + cell->numCellRSPerSf = RGSCH_NUM_CELL_RS_TWO_ANT_PORT; + } + else + { + cell->numCellRSPerSf = RGSCH_NUM_CELL_RS_FOUR_ANT_PORT; + } + cell->bwCfg = cellCfg->bwCfg; + cell->pbchRbStart = ((((cell->bwCfg.dlTotalBw * 12)/2) - 36)/12); /* Ref section 6.6 in 36.211 */ + cell->pbchRbEnd = cell->pbchRbStart + 5; + cell->pucchCfg = cellCfg->pucchCfg; + cell->rachCfg = cellCfg->rachCfg; + cell->siCfg = cellCfg->siCfg; + cell->t300TmrVal = cellCfg->t300TmrVal; +#ifdef RGR_SI_SCH + /*Initialize the SI CB in Cell CB */ + cmMemset((U8 *)&cell->siCb, 0, sizeof(RgSchSiCb)); +#endif + /*Fix: Added Guard Pool for RNTI which will contain RNTIs + *for UEs deleted from Scheduler but not yet from MAC*/ + cmLListInit(&cell->rntiDb.rntiGuardPool); + + /* Initialize the inWindow to sync with scheduler time when ticks starts */ +#ifdef LTEMAC_HDFDD + cell->siCb.inWindow = (cellCfg->siCfg.siWinSize - + (RG_SCH_CMN_DL_DELTA + RG_SCH_CMN_HARQ_INTERVAL)); +#else + cell->siCb.inWindow = (cellCfg->siCfg.siWinSize - + (RG_SCH_CMN_DL_DELTA)); +#endif + + if(cell->siCb.inWindow < 0) + { + cell->siCb.inWindow = 0; + } + cell->macPreambleSet = cellCfg->macPreambleSet; + cell->phichCfg = cellCfg->phichCfg; + + /* Initialize UL and DL CCCH logical channels */ + cell->ulCcchId = RGSCH_INVALID_LC_ID; + cell->dlCcchId = RGSCH_INVALID_LC_ID; + + /* Update SRS configuration */ + cell->srsCfg.isSrsCfgPres = cellCfg->srsCfg.isSrsCfgSetup; + if(cellCfg->srsCfg.isSrsCfgSetup) + { + cell->srsCfg.srsCfgPrdEnum = cellCfg->srsCfg.srsCfgPrdEnum; + cell->srsCfg.srsBwEnum = cellCfg->srsCfg.srsBwEnum; + cell->srsCfg.srsTxOffst = + rgSrsTxOffstTbl[cellCfg->srsCfg.srsSubFrameCfg]; + /*ccpu00116923 - ADD - Srs Present support */ +#ifdef TFU_UPGRADE + cell->srsCfg.srsSubFrameCfg = cellCfg->srsCfg.srsSubFrameCfg; +#endif + } + + /* Configure all the common logical channels for the cell */ + for(idx = 0; idx < cellCfg->numCmnLcs; idx++) + { + /* This never returns failure and hence not checked for */ + rgSCHCfgRgrCmnLcCfg(cell, &(cellCfg->cmnLcCfg[idx]), errInfo); + } + + /* Invoke the MeasGap and ACK NACK Rep handler for cell cfg */ + + /* Dynamic CFI cell configuration */ + ret = rgSCHDynCfiCfg(cell, cellCfg); + if(ret != ROK) + { + RLOG_ARG0(L_ERROR,DBG_CELLID,cellCfg->cellId,"Rgr cell Config failed at " + "Scheduler for cell"); + rgSCHCfgFreeCellCb(cell); + RETVALUE(RFAILED); + } + /* Updating Auto TM Mode enable/diable flag */ + cell->isAutoCfgModeEnb = cellCfg->isAutoCfgModeEnb; + { + if(cell->isAutoCfgModeEnb) + { + RLOG0(L_INFO,"Auto Mode Cfg enabled durint cell cfg\n"); + } + } + /* CPU OvrLoad State Initialization */ +#ifdef XEON_LMT_ITBS + cell->thresholds.maxDlItbs = gWrMaxDlItbs; + cell->thresholds.maxUlItbs = gWrMaxUlItbs; + RLOG2(L_INFO,"LIMIT DL and UL ITBS %d:%d \n",gWrMaxDlItbs,gWrMaxUlItbs); +#else + cell->thresholds.maxDlItbs = RG_SCH_DL_MAX_ITBS; + cell->thresholds.maxUlItbs = RG_SCH_UL_MAX_ITBS; +#endif + cell->measurements.dlTpt = 0; + cell->measurements.ulTpt = 0; + cell->measurements.dlBytesCnt = 0; + cell->measurements.ulBytesCnt = 0; + cell->cpuOvrLdCntrl.cpuOvrLdIns = 0; /* 0 - No command */ + cell->cpuOvrLdCntrl.dlNxtIndxDecNumUeTti = 0; + cell->cpuOvrLdCntrl.ulNxtIndxDecNumUeTti = 0; + for ( idx = 0; idx < 10; idx++ ) + { + cell->cpuOvrLdCntrl.maxUeNewTxPerTti[idx] = cellCfg->maxDlUeNewTxPerTti; + cell->cpuOvrLdCntrl.maxUeNewRxPerTti[idx] = cellCfg->maxUlUeNewTxPerTti; + } + + /* Invoke scheduler to update scheduler specific information */ + ret = rgSCHUtlRgrCellCfg(cell, cellCfg, errInfo); + if (ret != ROK) + { + RLOG_ARG0(L_ERROR,DBG_CELLID,cellCfg->cellId,"Rgr cell Config failed at " + "Scheduler for cell "); + rgSCHCfgFreeCellCb(cell); + RETVALUE(RFAILED); + } + + /* Invoke DHM to update DHM specific information */ + rgSCHDhmRgrCellCfg(cell, cellCfg, errInfo); + + + /* Initialize RNTI DB */ + ret = rgSCHDbmRntiDbInit(cell, cellCfg->macRnti.startRnti, + cellCfg->macRnti.size); + if (ret != ROK) + { + RLOG_ARG0(L_ERROR,DBG_CELLID,cellCfg->cellId,"Rgr Cell Config failed at" + " RNTI DB init for cell"); + rgSCHCfgFreeCellCb(cell); + RETVALUE(RFAILED); + } + + /* Update the cell with recieved configuration */ + cell->dlHqCfg = cellCfg->dlHqCfg; + + RLOG1(L_INFO,"Config DL HQTX = %d\n",cell->dlHqCfg.maxDlHqTx); + + cell->crntSfIdx = 0; + /* Allocate the subframe allocation information */ + if((ret = rgSCHUtlGetSfAlloc(cell)) != ROK) + { + RLOG_ARG0(L_ERROR,DBG_CELLID,cellCfg->cellId,"Memory allocation FAILED for " + "cell"); + rgSCHCfgFreeCellCb(cell); + RETVALUE(RFAILED); + } + /* Update RACH Related information + * XXX: Below function yet to be written in RAM + * To store the preambles given in the configuration for PDCCH order in the + * scheduler cell control block. Initialize the PRACH Mask Index allocated + * for these preambles to invalid values */ + + cell->crntHqIdx = 0; + /* Allocate the subframe allocation information */ + if((ret = rgSCHUtlGetRlsHqAlloc(cell)) != ROK) + { + RLOG_ARG0(L_ERROR,DBG_CELLID,cellCfg->cellId,"Memory allocation FAILED for" + "cell"); + rgSCHCfgFreeCellCb(cell); + RETVALUE(RFAILED); + } + + /* Associate a pair of upper and lower sapCbs with this cell */ + instCb->rgrSap[spId].cell = cell; + instCb->tfuSap[spId].cell = cell; + instCb->rgmSap[spId].cell = cell; + cell->tfuSap = &(instCb->tfuSap[spId]); + + /* CaDev Start */ + instCb->cells[Idx1] = cell; + /* CaDev End */ + + /* rg001.201: Added for sending TTI tick to RRM */ +#if (defined(RGR_RRM_TICK) || defined(RGR_CQI_REPT)) + /* Associate the RGR SAP as well utilized while sending TTI + * Ticks to RGR User. */ + cell->rgrSap = &(instCb->rgrSap[spId]); +#endif + cell->rgmSap = &(instCb->rgmSap[spId]); +#ifdef RGR_RRM_TICK + /* Store the periodicity configured */ + cell->rrmTtiIndPrd = cellCfg->rrmTtiIndPrd; +#endif + +#ifdef LTE_L2_MEAS + cmLListInit(&cell->l2mList); +#endif + + if (rgSCHDrxCellCfg(cell,cellCfg) != ROK) + { + RLOG_ARG0(L_ERROR,DBG_CELLID,cellCfg->cellId,"Drx Memory allocation FAILED for" + " cell"); + rgSCHCfgFreeCellCb(cell); + RETVALUE(RFAILED); + } + cell->overLoadBackOffEnab = FALSE;/* Disabling RachOverload by default */ + /* Updating CSG Parameters */ + cell->minDlResNonCsg = cellCfg->csgParamCfg.minDlResNonCsg; + cell->minUlResNonCsg = cellCfg->csgParamCfg.minUlResNonCsg; + + /* Register the cell with MAC */ + rgSCHUtlGetPstToLyr(&pst, instCb, cell->macInst); + cellRegReq.cellId = cell->cellId; + cellRegReq.cellSapId = spId; +#ifdef LTE_TDD + cellRegReq.maxDlHqProcPerUe = rgSchTddDlNumHarqProcTbl[cellCfg->ulDlCfgIdx]; +#else + cellRegReq.maxDlHqProcPerUe = RGSCH_MAX_DL_HQ_PROC; +#endif + RgSchMacCellReg(&pst, &cellRegReq); + +#ifdef TENB_STATS + cell->tenbStats = TSL2AllocCellStatsBlk(cell->cellId); + cell->tenbStats->cellId = cell->cellId; +#endif + + rgSCHUtlCalcDciSizes(cell); + +#ifdef LTE_ADV + /* Initilalization of the list of UE for which this cell is secondary cell*/ + cmLListInit(&cell->sCellUeLst); +#endif + + +#ifdef LTE_ADV + ret = rgSCHLaaSCellCbInit(cell, cellCfg); + if (ret != ROK) + { + RLOG_ARG0(L_ERROR,DBG_CELLID,cellCfg->cellId,"Rgr Cell Config failed at" + " Initializing the LAA Cell Control Cb"); + rgSCHCfgFreeCellCb(cell); + RETVALUE(RFAILED); + } + cell->isPucchFormat3Sptd = cellCfg->isPucchFormat3Sptd; + RLOG_ARG0(L_INFO,DBG_CELLID,cellCfg->cellId,"Format 3 is Enabled"); + printf ("\n Format 3 is Enabled for CELL:%d",cell->cellId); +#endif + + +#ifdef EMTC_ENABLE + + if(cell->emtcEnable) + { + if (rgSCHCfgEmtcCellCfg(cell,&(cellCfg->emtcCellCfg)) != ROK) + { + RLOG_ARG0(L_ERROR,DBG_CELLID,cellCfg->cellId,"EMTC Config Failed" + " cell"); + RETVALUE(RFAILED); + } + } +#endif + +#ifdef RG_5GTF + ret = rgSCH5gtfCellCfg(cell, cellCfg); + if (ret != ROK) + { + RLOG_ARG0(L_ERROR, DBG_CELLID,cellCfg->cellId,"5GTF Rgr Cell Config failed"); + rgSCHCfgFreeCellCb(cell); + RETVALUE(RFAILED); + } +#endif + errInfo->errCause = RGSCHERR_NONE; + RETVALUE(ROK); +} /* rgSCHCfgRgrCellCfg */ + +/** + * @brief Handler for the UE configuration request from RRC to MAC. + * + * @details + * + * Function : rgSCHCfgRgrUeCfg + * + * Processing Steps: + * - Allocate and create UE control block. + * - Update UE control block with the values recieved in the + * configuration. + * - Invoke RAM, SCH, UHM and DHM with created UE control block, to + * update random access, scheduler, uplink harq and downlink harq + * specific information respectively. + * - If successful, add the control block to hash list of UEs for the cell + * else Rollback and FAIL. + * + * @param[in] RgSchCellCb *cell + * @param[in] RgrUeCfg *ueCfg + * @param[out] RgSchErrInfo *errInfo + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 rgSCHCfgRgrUeCfg +( +RgSchCellCb *cell, +RgrUeCfg *ueCfg, +RgSchErrInfo *errInfo +) +#else +PUBLIC S16 rgSCHCfgRgrUeCfg(cell, ueCfg, errInfo) +RgSchCellCb *cell; +RgrUeCfg *ueCfg; +RgSchErrInfo *errInfo; +#endif +{ + S16 ret; + RgSchRaCb *raCb=NULLP; + RgSchUeCb *ue = NULLP; + Inst inst = cell->instIdx; + U32 lcgCnt; + RgSchDlHqEnt *hqEnt = NULLP; +#ifdef LTE_TDD + U8 ulDlCfgIdx = cell->ulDlCfgIdx; + U8 maxSubframes ; + U8 maxDlSubframes; +#endif + U32 idx = 0; +#ifdef TFU_UPGRADE + RgSchUePCqiCb *cqiCb = NULLP; +#endif + TRC2(rgSCHCfgRgrUeCfg); + + do { + errInfo->errCause = RGSCHERR_CFG_RGR_UE_CFG; + /* RACHO : Check for raCb only if preamble Id not provded */ +#ifndef PRE_DEF_UE_CTX + if (ueCfg->dedPreambleId.pres == NOTPRSNT) + { + if ((raCb = rgSCHDbmGetRaCb(cell, ueCfg->crnti)) == NULLP) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,ueCfg->cellId,"No RaCb exists for" + "CRNTI:%d ",ueCfg->crnti); + break; + } + } +#endif + + /* Allocate the Ue control block */ + if (((rgSCHUtlAllocSBuf(inst, (Data **)&ue, sizeof(RgSchUeCb))) != ROK) || + ((U8 *)ue == NULLP)) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,ueCfg->cellId, "Memory allocation" + " FAILED for CRNTI:%d", ueCfg->crnti); + break; + } + + /* Inititialize Ue control block */ + ue->ueId = ueCfg->crnti; + ue->cell = cell; + /*ccpu00117778- Initialize Transmission Indices upon UE CB creation */ +#ifdef LA + ue->lastRprdAckNackTime.sfn = cell->crntTime.sfn; + ue->lastRprdAckNackTime.subframe = cell->crntTime.subframe; + ue->ueIdle = FALSE; +#endif + + /* Allocate the Ue control block */ + if (((rgSCHUtlAllocSBuf(inst, (Data **)&(ue->cellInfo[RGSCH_PCELL_INDEX]), + sizeof(RgSchUeCellInfo))) != ROK)) + { +#ifndef ALIGN_64BIT + RGSCHDBGERRNEW(inst, (rgSchPBuf(inst), "[%lu]SCellIdx :Memomy allocation " + "Failed while Adding SCell Information\n", idx)); +#else + RGSCHDBGERRNEW(inst, (rgSchPBuf(inst), "[%u]SCellIdx :Memomy allocation " + "Failed while Adding SCell Information\n", idx)); +#endif + RETVALUE(RFAILED); + } + + ue->cellIdToCellIdxMap[RG_SCH_CELLINDEX(cell)] = RGSCH_PCELL_INDEX; + ue->cellInfo[RGSCH_PCELL_INDEX]->cell = cell; + ue->cellInfo[RGSCH_PCELL_INDEX]->ue = ue; +#ifdef LTE_ADV + ue->cellInfo[RGSCH_PCELL_INDEX]->sCellState = RG_SCH_SCELL_ACTIVE; + ue->cellInfo[RGSCH_PCELL_INDEX]->sCellIdx = RGSCH_PCELL_INDEX; + ue->cellInfo[RGSCH_PCELL_INDEX]->sCellId = cell->cellId; + + if (ROK != rgSCHLaaInitDlRbAllocCb(cell, + &ue->cellInfo[RGSCH_PCELL_INDEX]->dlAllocCb)) + { + RETVALUE(RFAILED); + } +#endif +#ifdef TFU_UPGRADE + cqiCb = RG_SCH_GET_UE_CELL_CQI_CB(ue,cell); + cqiCb->nCqiTrIdx = RG_SCH_INVALID_IDX; + cqiCb->nRiTrIdx = RG_SCH_INVALID_IDX; + ue->srsCb.nSrsTrIdx = RG_SCH_INVALID_IDX; + ue->srCb.nSrTrIdx = RG_SCH_INVALID_IDX; +#endif + /* LTE_ADV_FLAG_REMOVED_START */ + /* While doing UE configuration for SFR at SCH, by default + * CC UE power is configured as LOW */ + ue->lteAdvUeCb.isCCUePHigh = FALSE; + /* LTE_ADV_FLAG_REMOVED_END */ + + /* Initialize the lists of the UE */ + if((rgSCHDbmInitUe(ue)) != ROK) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,ueCfg->cellId,"DBM initialization " + "failed for CRNTI:%d", ueCfg->crnti); + break; + } +#ifdef EMTC_ENABLE + if(raCb != NULLP) + { + if(TRUE == raCb->isEmtcRaCb) + { + ue->isEmtcUe = TRUE; + if (rgSCHUtlUpdUeEmtcInfo(cell, ueCfg, ue) != ROK) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,ueCfg->cellId,"EMTC UE Cfg" + "failed for CRNTI:%d", ueCfg->crnti); + break; + } + } + } +#endif + + /* Initialize scheduler related information for UE */ + if(rgSCHUtlRgrUeCfg(cell, ue, ueCfg, errInfo) != ROK) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,ueCfg->cellId,"Scheduler handling " + "failed in config for CRNTI:%d", ueCfg->crnti); + break; + } + + ret = rgSCHUhmHqEntInit(cell, ue); + if (ret != ROK) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,ueCfg->cellId,"UHM HARQ Ent Init " + "Failed for CRNTI:%d", ueCfg->crnti); + break; + } + + /* Initialize RAM related information for UE + * RACHO: if preamble Id is present in ueCfg then raCb will be NULL + * so rgSCHRamRgrUeCfg should take care of creating raCb */ + if ((ueCfg->dedPreambleId.pres == NOTPRSNT) && (NULLP != raCb) ) + { + if((rgSCHRamRgrUeCfg(cell, ue, raCb, errInfo)) != ROK) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,ueCfg->cellId,"Random access " + "handling config failed for CRNTI:%d", ueCfg->crnti); + break; + } + } + else /* if HO Ue */ + { + RG_SCH_CMN_GET_UE_HQE(ue, cell) = rgSCHDhmHqEntInit(cell); + hqEnt = RG_SCH_CMN_GET_UE_HQE(ue, cell); + if (hqEnt == NULLP) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,ueCfg->cellId,"Hq Entity Initialization " + "failed in config for CRNTI:%d", ueCfg->crnti); + break; + } +#ifdef EMTC_ENABLE + rgSCHEmtcHqPAlloc(cell, hqEnt); +#endif + hqEnt->ue = ue; + /* Fix : syed Assign hqEnt to UE only if msg4 is done */ + + rgSCHCmnDlInitHqEnt(cell, hqEnt); + + /* For Hand-In UE Request Aper CQI report + * immediately */ + if (ueCfg->ueDlCqiCfg.aprdCqiCfg.pres) + { + /* Set APCQI for Pcell only*/ + ue->dl.reqForCqi = RG_SCH_APCQI_SERVING_CC; + } + } + /* CA dev Start */ +#ifdef LTE_TDD + maxDlSubframes = rgSchTddNumDlSubfrmTbl[ulDlCfgIdx][RGSCH_NUM_SUB_FRAMES-1]; + maxSubframes = 2 * maxDlSubframes; + ue->dl.numHqDlSfInfo = maxSubframes; + rgSCHUtlAllocSBuf(cell->instIdx, + (Data **)&ue->dl.dlSfHqInfo, sizeof(RgSchDlHqInfo) * (ue->dl.numHqDlSfInfo)); + +#else + ue->dl.numHqDlSfInfo = RGSCH_NUM_DL_SUBFRAMES; +#endif +#ifndef RG_5GTF + for (idx =0;idx < ue->dl.numHqDlSfInfo; idx++) + { + cmLListInit(&ue->dl.dlSfHqInfo[idx].hqPLst); + ue->dl.dlSfHqInfo[idx].dlSfUeLnk.node = NULLP; + + } +#else + { + U8 cellIdx=0; + for (cellIdx = 0;cellIdx < MAX_5GTF_CELL ; cellIdx++) + { + for (idx =0;idx < ue->dl.numHqDlSfInfo; idx++) + { + cmLListInit(&ue->dl.dlSfHqInfo[cellIdx][idx].hqPLst); + ue->dl.dlSfHqInfo[cellIdx][idx].dlSfUeLnk.node = NULLP; + } + } + } +#endif +#ifdef LTE_ADV + rgSCHLaaInitDlHqInfo(cell, ue); +#endif + /* CA dev End */ + + /* Initialize lcgIds to Invalid */ + for (lcgCnt = 0; lcgCnt < RGSCH_MAX_LCG_PER_UE; lcgCnt++) + { + ue->ul.lcgArr[lcgCnt].lcgId = RGSCH_INVALID_LCG_ID; + } + if(raCb != NULLP) + { + rgSCHCfgRgrUePhrMsg3(cell,raCb,ue,errInfo); + /* Moved this code out of rgSCHCfgRgrUePhrMsg3() + * as it was not the appropriate place to + * do this. */ + if (raCb->raState == RGSCH_RA_MSG4_DONE) + { + RLOG_ARG1(L_DEBUG,DBG_CELLID,cell->cellId, + "RNTI:%d RaCb deleted as Msg4 transmission is done", + raCb->tmpCrnti); + rgSCHRamDelRaCb(cell, raCb, FALSE); + } + } + /* Initialize uplink HARQ related information for UE */ + rgSCHUhmRgrUeCfg(cell, ue, ueCfg); + cmInitTimers(&ue->bsrTmr, 1); +#ifdef RGR_V1 + /* Added periodic BSR timer */ + cmInitTimers(&ue->bsrTmr, 1); + + /* Fix - Added proper configuration from U-ARM */ + if(ueCfg->ueBsrTmrCfg.isPrdBsrTmrPres == TRUE) + { + ue->ul.bsrTmrCfg.isPrdBsrTmrPres = TRUE; + ue->ul.bsrTmrCfg.prdBsrTmr = ueCfg->ueBsrTmrCfg.prdBsrTmr; + ue->ul.bsrTmrCfg.retxBsrTmr = ueCfg->ueBsrTmrCfg.retxBsrTmr; + } + +#endif + /* Initialize downlink HARQ related information for UE */ + rgSCHDhmRgrUeCfg(cell, ue, ueCfg, errInfo); + + /* Initialize MeasureGap and Acknack Rep Information for UE */ + if((rgSCHMeasGapANRepUeCfg(cell, ue, ueCfg)) != ROK) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,ueCfg->cellId,"Measurement Gap and" + " AckNack Rep failed in Config for CRNTI:%d", ueCfg->crnti); + break; + } + + +#ifdef LTE_TDD + if((rgSCHUtlAllocUeANFdbkInfo(ue,RGSCH_PCELL_INDEX)) != ROK) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,ueCfg->cellId,"Memomy allocation " + "Failed while UE related Ack Nack Information for CRNTI:%d", + ueCfg->crnti); + break; + } + ue->dl.ackNackMode = ueCfg->ackNackModeEnum; +#endif /* LTE_TDD */ + + /* Insert Ue */ + rgSCHDbmInsUeCb(cell, ue); + +#ifdef TFU_UPGRADE + /* Int ialize APeriodic CQI/PMI/RI Information for UE */ + + RGSCHDBGPRM(cell->instIdx,(rgSchPBuf(cell->instIdx), + "\n rgSCHCfgRgrUeCfg : CellID=%d UeId =%d AcqiCfg Pres =%d", + cell->cellId, ue->ueId, ueCfg->ueDlCqiCfg.aprdCqiCfg.pres)); + + /*Store Trigger Set Bit String to UE */ + + ret = rgSCHCfgACqiUeCfg(cell,ue, (RG_SCH_CMN_GET_ACQICB(ue,cell)),ue->mimoInfo.txMode, + &ueCfg->ueDlCqiCfg.aprdCqiCfg, ue->ueCatEnum); + + ue->cqiRiWritIdx = 0; + ue->cqiRiReadIdx = 0; + /* Initialize Periodic CQI/PMI, RI Information for UE */ + ret = rgSCHCfgPCqiUeCfg(cell, ue, &ueCfg->ueDlCqiCfg.prdCqiCfg, + ue->ueCatEnum); + + /* Initialize UL SRS Information for UE */ + ret = rgSCHCfgSrsUeCfg(cell, ue, &ueCfg->srsCfg); + + /* Initialize SR Information for UE */ + ret = rgSCHCfgSrUeCfg(cell, ue, &ueCfg->srCfg); +#endif + +#ifdef LTEMAC_HDFDD + if (rgSCHHdFddUeCfg(cell, ue, ueCfg->isHdFddEnbld) != ROK) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,ueCfg->cellId, + "Could not do HD-FDD config for CRNTI:%d",ueCfg->crnti); + break; + } + +#endif /* LTEMAC_HDFDD */ + /* ccpu00117452 - MOD - Changed macro name from + RGR_RRM_DLPWR_CNTRL to RGR_CQI_REPT */ +#ifdef RGR_CQI_REPT + ue->cqiReptCfgInfo.numColltdCqiRept = + ueCfg->ueCqiReptCfg.numColltdCqiRept; +#endif /* End of RGR_CQI_REPT */ +#ifdef TFU_UPGRADE + RG_SCH_CMN_GET_PA(ue,cell).pres = FALSE; + if (RG_SCH_UE_CFG_ISPAPRSNT(ueCfg->uePdschDedCfg.uepACfg)) + { + RG_SCH_CMN_GET_PA(ue,cell).pres = TRUE; + RG_SCH_CMN_GET_PA(ue,cell).val = ueCfg->uePdschDedCfg.uepACfg.pA; + } +#endif + ue->isDrxEnabled = ueCfg->ueDrxCfg.isDrxEnabled; + + if ( ue->isDrxEnabled ) + { + if((rgSCHDrxUeCfg(cell,ue,ueCfg)) != ROK ) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,ueCfg->cellId,"DRX configuration failed", + ueCfg->crnti); + break; + } + } + + /* LTE_ADV_FLAG_REMOVED_START */ + if ((cell->lteAdvCb.sfrCfg.status == RGR_ENABLE) || \ + (cell->lteAdvCb.absCfg.status == RGR_ENABLE)) + { + ue->lteAdvUeCb.rgrLteAdvUeCfg = ueCfg->ueLteAdvCfg; + } + /* LTE_ADV_FLAG_REMOVED_END */ + +#ifdef TENB_STATS + ue->tenbStats = TSL2AllocUeStatsBlk(ue->ueId); + ue->tenbStats->stats.rnti = ue->ueId; +#endif +#ifdef LTE_ADV + /*Update A Value for PCell TBs*/ + ue->f1bCsAVal = rgSCHUtlGetMaxTbSupp(ue->mimoInfo.txMode); + RLOG_ARG1(L_ERROR,DBG_CELLID, ueCfg->cellId, + "\n UeCfg A value is %d\n",ue->f1bCsAVal); +#endif + errInfo->errCause = RGSCHERR_NONE; + + ue->accessStratumRls = ueCfg->accessStratumRls; + if (ue->numSCells > 0) + { + /* 2 bit CSI */ + rgSCHUtlUpdUeDciSize(cell, ue, TRUE); + } + else + { + /* 1 bit CSI Access Stratum Release Change */ + rgSCHUtlUpdUeDciSize(cell, ue, FALSE); + } + + RETVALUE(ROK); + }while(0); + + if (ue) + { + rgSCHCfgFreeUeCb(cell, ue); + } + RETVALUE(RFAILED); +} /* rgSCHCfgRgrUeCfg */ + +/** + * @brief Handler for PHR for MSG3. + * + * @details + * + * Function : rgSCHCfgRgrUePhrMsg3 + * + * Processing Steps: + * Handle PHR related config for MSG3 + * + * @param[in] RgSchCellCb *cell + * @param[in] RgrUeCb *ueCb + * @param[in] RgSchRaCb *raCb + * @param[out] RgSchErrInfo *errInfo + **/ +#ifdef ANSI +PRIVATE Void rgSCHCfgRgrUePhrMsg3 +( +RgSchCellCb *cell, +RgSchRaCb *raCb, +RgSchUeCb *ue, +RgSchErrInfo *errInfo +) +#else +PRIVATE Void rgSCHCfgRgrUePhrMsg3(cell, raCb, ue, errInfo) +RgSchCellCb *cell; +RgSchRaCb *raCb; +RgSchUeCb *ue; +RgSchErrInfo *errInfo; +#endif +{ + + TRC2(rgSCHCfgRgrUePhrMsg3); + + /* Record msg3 allocation in the UE */ + rgSCHUtlRecMsg3Alloc(cell, ue, raCb); + + /* If raCb received PHR, update scheduler */ + if(raCb->phr.pres == TRUE) + { + ue->macCeRptTime = raCb->msg3AllocTime; + rgSCHUtlUpdPhr(cell, ue, raCb->phr.val, errInfo); + } + + RETVOID; +} + +/** + * + * @details + * + * Function : rgSCHDynCfiReCfg + * + * @param[in] RgSchCellCb *cell + * Bool isDynCfiEnb + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC Void rgSCHDynCfiReCfg +( +RgSchCellCb *cell, +Bool isDynCfiEnb +) +#else +PUBLIC Void rgSCHDynCfiReCfg(cell, isDynCfiEnb) +RgSchCellCb *cell; +Bool isDynCfiEnb; +#endif +{ + U8 idx; + RgSchCmnDlCell *cellSchDl = RG_SCH_CMN_GET_DL_CELL(cell); + + TRC2(rgSCHDynCfiReCfg); + + if(isDynCfiEnb) + { + cell->dynCfiCb.ttiCnt = 0; + cellSchDl->newCfi = cellSchDl->currCfi; + } + else + { + /* Resetting the parameters*/ + cell->dynCfiCb.cceFailCnt = 0; + cell->dynCfiCb.cceFailSum = 0; + cell->dynCfiCb.prevCceFailIdx = 0; + + for(idx = 0; idx < cell->dynCfiCb.numFailSamples; idx++) + { + cell->dynCfiCb.cceFailSamples[idx] = 0; + } + + cell->dynCfiCb.cceUsed = 0; + cell->dynCfiCb.lowCceCnt = 0; + cell->dynCfiCb.ttiCnt = 0; + } +} +/** + * @brief Handler for the cell reconfiguration request from RRM to MAC. + * + * @details + * + * Function : rgSCHCfgRgrCellRecfg + * + * Processing Steps: + * - Invoke SCH with cell control block to update + * scheduler specific information. + * - Update cell control block with the values recieved in the + * configuration. + * - If successful, return ROK else RFAILED. + * + * @param[in] RgSchCellCb *cell + * @param[in] RgrCellRecfg *cellRecfg + * @param[out] RgSchErrInfo *errInfo + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 rgSCHCfgRgrCellRecfg +( +RgSchCellCb *cell, +RgrCellRecfg *cellRecfg, +RgSchErrInfo *errInfo +) +#else +PUBLIC S16 rgSCHCfgRgrCellRecfg(cell, cellRecfg, errInfo) +RgSchCellCb *cell; +RgrCellRecfg *cellRecfg; +RgSchErrInfo *errInfo; +#endif +{ + S16 ret; + Inst inst = cell->instIdx; +/* LTE_ADV_FLAG_REMOVED_START */ + U8 i = 0; + U16 len; /* dsfr_pal_fixes ** 21-March-2013 ** SKS */ +/* LTE_ADV_FLAG_REMOVED_END */ + + TRC2(rgSCHCfgRgrCellRecfg); + + + errInfo->errCause = RGSCHERR_CFG_RGR_CELL_RECFG; + + /* Invoke scheduler to update scheduler specific information */ + ret = rgSCHUtlRgrCellRecfg(cell, cellRecfg, errInfo); + if (ret != ROK) + { + RLOG_ARG0(L_ERROR,DBG_CELLID,cellRecfg->cellId, "RGR Cell re-configuration failed " + "at Scheduler "); + RETVALUE(RFAILED); + } + + /* Invoke DHM to update DHM specific information */ + rgSCHDhmRgrCellRecfg(cell, cellRecfg, errInfo); + + /* PUCCH Reconfiguration */ + if (cellRecfg->recfgTypes & RGR_CELL_PUCCH_RECFG) + { + cell->pucchCfg = cellRecfg->pucchRecfg; + } + + /* SRS Reconfiguration */ + if (cellRecfg->recfgTypes & RGR_CELL_SRS_RECFG) + { + cell->srsCfg.isSrsCfgPres = cellRecfg->srsRecfg.isSrsCfgSetup; + if(cellRecfg->srsRecfg.isSrsCfgSetup) + { + cell->srsCfg.srsCfgPrdEnum = cellRecfg->srsRecfg.srsCfgPrdEnum; + cell->srsCfg.srsBwEnum = cellRecfg->srsRecfg.srsBwEnum; + cell->srsCfg.srsTxOffst = + rgSrsTxOffstTbl[cellRecfg->srsRecfg.srsSubFrameCfg]; + /*ccpu00116923 - ADD - Srs Present support */ +#ifdef TFU_UPGRADE + cell->srsCfg.srsSubFrameCfg = cellRecfg->srsRecfg.srsSubFrameCfg; +#endif + } + } + + /* RACH Reconfiguration */ + if (cellRecfg->recfgTypes & RGR_CELL_RACH_RECFG) + { + cell->rachCfg = cellRecfg->rachRecfg; + } + + /* ccpu00132256:MOD: Moved this assignment from Validation to here.*/ + if (cellRecfg->recfgTypes & RGR_CELL_TMRS_RECFG) + { + cell->t300TmrVal = cellRecfg->t300TmrVal; + } +#ifdef RGR_SI_SCH + /* SI Reconfiguration */ + if (cellRecfg->recfgTypes & RGR_CELL_SI_RECFG) + { + /*Set the specified SI configuration. */ + cell->siCb.newSiCfg = cellRecfg->siReCfg; + /* Set the Bit mask for SI re-configuration */ + cell->siCb.siBitMask |= RGSCH_SI_SICFG_UPD; +#ifdef EMTC_ENABLE + if(cell->emtcEnable) + { + rgSchEmtcUpdSiCfg(cell, cellRecfg); + } +#endif + } +#endif /*RGR_SI_SCH */ + + /* Overload RACH Control changes */ + if (cellRecfg->recfgTypes & RGR_CELL_CNTRL_CMD_RECFG) + { + if (cellRecfg->cntrlCmdCfg.cmdType == RGR_CNTRL_CMD_RACH_OVRLD) + { + cell->overLoadBackOffEnab = cellRecfg->cntrlCmdCfg.cmdDesc.rachOvrLd.backOffEnb; + cell->overLoadBackOffval = cellRecfg->cntrlCmdCfg.cmdDesc.rachOvrLd.backOffVal; + } + else if (cellRecfg->cntrlCmdCfg.cmdType == RGR_CNTRL_CMD_CPU_OVRLD) + { + if( ROK != rgSCHUtlResetCpuOvrLdState(cell, cellRecfg->cntrlCmdCfg.cmdDesc.\ + cpuOvrLd.instruction)) + { + RLOG_ARG1(L_ERROR,DBG_CELLID, cellRecfg->cellId, + "Invalid CPU OvrLd Ins %d for cell", + cellRecfg->cntrlCmdCfg.cmdDesc.cpuOvrLd.instruction); + RETVALUE(RFAILED); + } + } + } + +/* LTE_ADV_FLAG_REMOVED_START */ + if (cellRecfg->recfgTypes & RGR_CELL_LTEA_FEATURE_RECFG) + { + if(cellRecfg->rgrLteAdvCfg.pres & RGR_ABS) + { + cell->lteAdvCb.absCfg = + cellRecfg->rgrLteAdvCfg.absCfg; + } + if(cellRecfg->rgrLteAdvCfg.pres & RGR_SFR) + { + cmMemcpy((U8 *)&cell->lteAdvCb.sfrCfg, (U8 *)&cellRecfg->rgrLteAdvCfg.sfrCfg, + sizeof(RgrSfrConfig)); + /* dsfr_pal_fixes ** 21-March-2013 ** SKS */ + if (cellRecfg->rgrLteAdvCfg.sfrCfg.status == RGR_ENABLE) + { + for(i = 0; i < RGSCH_NUM_DL_SUBFRAMES; i++) + { + /*initialise the pools of CC and CE*/ + if(rgSchSFRTotalPoolInit(cell, cell->subFrms[i])) + { + RETVALUE(RFAILED); + } + } + } + else + { + for(i = 0; i < RGSCH_NUM_DL_SUBFRAMES; i++) + { + /*initialise the pools of CC and CE*/ + rgSchSFRTotalPoolFree(&cell->subFrms[i]->sfrTotalPoolInfo, cell); + } + + if (cell->lteAdvCb.dsfrCfg.status == RGR_ENABLE) + { + /* releasing rntp info val from each subframe */ + for(i = 0; i < RGSCH_NUM_DL_SUBFRAMES; i++) + { + rgSchDSFRRntpInfoFree(&cell->subFrms[i]->rntpInfo, cell, cell->bwCfg.dlTotalBw); + } + + /* releasing RNTP Aggregation Info from CellCb*/ + rgSchDSFRRntpInfoFree(&cell->rntpAggrInfo, cell, cell->bwCfg.dlTotalBw); + + cell->lteAdvCb.dsfrCfg.status = RGR_DISABLE; + } + } + } + /* dsfr_pal_fixes ** 21-March-2013 ** SKS ** Start */ + if(cellRecfg->rgrLteAdvCfg.pres & RGR_DSFR) + { + cell->lteAdvCb.dsfrCfg = + cellRecfg->rgrLteAdvCfg.dsfrCfg; + if (cell->lteAdvCb.dsfrCfg.status == RGR_ENABLE) + { + for(i = 0; i < RGSCH_NUM_DL_SUBFRAMES; i++) + { + /*initialise the pools of CC and CE*/ + if(rgSchDSFRRntpInfoInit(&cell->subFrms[i]->rntpInfo,cell,cell->bwCfg.dlTotalBw)) + { + RETVALUE(RFAILED); + } + } + /*Calculating the length of RNTP array based on Dl Bandwidth */ + len = (U16)((cell->bwCfg.dlTotalBw % 8 == 0) ? (cell->bwCfg.dlTotalBw/8) : (cell->bwCfg.dlTotalBw/8 + 1)); /* KW fix for LTE_ADV */ + if(cell->rntpAggrInfo.pres == NOTPRSNT) + { + if((rgSCHUtlAllocSBuf(inst, (Data**)&(cell->rntpAggrInfo.val), + (len * sizeof(U8)))) != ROK) + { + RLOG_ARG0(L_ERROR,DBG_CELLID,cellRecfg->cellId, + "Memory allocation FAILED for RNTP Alloc"); + RETVALUE(RFAILED); + } + cell->rntpAggrInfo.pres = PRSNT_NODEF; + cell->rntpAggrInfo.len = len; + } + } + /* in case if DSFR is disabled, need to free RNTP pattern val*/ + else + { + /* releasing rntp info val from each subframe */ + for(i = 0; i < RGSCH_NUM_DL_SUBFRAMES; i++) + { + rgSchDSFRRntpInfoFree(&cell->subFrms[i]->rntpInfo, cell, cell->bwCfg.dlTotalBw); + } + + /* releasing RNTP Aggregation Info from CellCb*/ + rgSchDSFRRntpInfoFree(&cell->rntpAggrInfo, cell, cell->bwCfg.dlTotalBw); + } + } + /* dsfr_pal_fixes ** 21-March-2013 ** SKS ** End */ + } +/* LTE_ADV_FLAG_REMOVED_END */ + + /* Dynamic CFI cell Reconfiguration */ + if(cellRecfg->recfgTypes & RGR_CELL_DYN_CFI_RECFG) + { + if(cell->dynCfiCb.isDynCfiEnb != cellRecfg->isDynCfiEnb) + { + if(cell->dynCfiCb.switchOvrInProgress) + { + cell->dynCfiCb.dynCfiRecfgPend = TRUE; + } + else + { + cell->dynCfiCb.isDynCfiEnb = cellRecfg->isDynCfiEnb; + rgSCHDynCfiReCfg(cell, cellRecfg->isDynCfiEnb); + } + } + else + { + /* To hanlde the case where reconfiguration comes for disabling + * and then enabling before switchover period expires */ + cell->dynCfiCb.dynCfiRecfgPend = FALSE; + } + } + /* Dynamic config of AUTO chnage flag */ + if(cellRecfg->recfgTypes & RGR_CELL_AUTO_CFG_MODE_RECFG) + { + if(cell->isAutoCfgModeEnb != cellRecfg->isAutoCfgModeEnb) + { + cell->isAutoCfgModeEnb = cellRecfg->isAutoCfgModeEnb; + } + } + { + if(cell->isAutoCfgModeEnb) + { + RLOG0(L_INFO,"Auto Mode Cfg enabled durint cell recfg\n"); + } + } + + if (cellRecfg->recfgTypes & RGR_CELL_CSG_PARAM_RECFG) + { + cell->minDlResNonCsg = cellRecfg->csgParamCfg.minDlResNonCsg; + cell->minUlResNonCsg = cellRecfg->csgParamCfg.minUlResNonCsg; + } + + errInfo->errCause = RGSCHERR_NONE; + RETVALUE(ROK); +} /* rgSCHCfgRgrCellRecfg */ + +/** + * @brief Handler for the UE reconfiguration request from RRC to MAC. + * + * @details + * + * Function : rgSCHCfgRgrUeRecfgRntiChg + * + * Processing Steps: + * - If rnti changes, + * - Invoke RAM for UE reconfiguration. + * - Delete old UE from the list. + * - Update the new rnti and re-insert the UE in the list. + * - If successful, return ROK else RFAILED. + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ue + * @param[in] RgrUeRecfg *ueRecfg + * @param[out] RgSchErrInfo *errInfo + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PRIVATE S16 rgSCHCfgRgrUeRecfgRntiChg +( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgrUeRecfg *ueRecfg, +RgSchErrInfo *errInfo +) +#else +PRIVATE S16 rgSCHCfgRgrUeRecfgRntiChg(cell, ue, ueRecfg, errInfo) +RgSchCellCb *cell; +RgSchUeCb *ue; +RgrUeRecfg *ueRecfg; +RgSchErrInfo *errInfo; +#endif +{ +#ifdef LTE_ADV + U8 sCellIdx; +#endif + S16 ret; + RgSchRaCb *raCb; + RgSchRaCb *oldRaCb; + RgSchDlHqEnt **hqEnt = &(RG_SCH_CMN_GET_UE_HQE(ue, cell)); + U8 idx; + + TRC2(rgSCHCfgRgrUeRecfgRntiChg); + + /* Handle CRNTI change in reconfiguration */ + if (ueRecfg->oldCrnti != ueRecfg->newCrnti) + { + RgSchRntiLnk *oldRntiLnk=NULLP; + CmLteRnti oldRnti = 0; + if ((raCb = rgSCHDbmGetRaCb(cell, ueRecfg->newCrnti)) == NULLP) + { + RLOG_ARG2(L_ERROR,DBG_CELLID,ueRecfg->cellId,"UEID:No RaCb exists while" + "Reconfig for OLD CRNTI:%d NEW CRNTI:%d",ueRecfg->oldCrnti,ueRecfg->newCrnti); + RETVALUE(RFAILED); + } + + /* rntiLnk does not exist for a HandIn UE. Hence this check. */ + if(ue->rntiLnk) + { + oldRntiLnk = ue->rntiLnk; + } + else + { + /* Fix : syed HO UE does not have a valid ue->rntiLnk */ + oldRnti = ue->ueId; + } + + RLOG2(L_INFO,"UE ID CHNG OLD %d new %d",ueRecfg->oldCrnti, ueRecfg->newCrnti); + + /* Fix : syed Deleting Old DL HqEnt. It would be assigned after + * reest RACH(msg4) is completed. */ + rgSCHDhmDelHqEnt(cell, hqEnt); + + /* Initialize RAM related information for UE */ + ret = rgSCHRamRgrUeCfg(cell, ue, raCb, errInfo); + if (ret != ROK) + { + RLOG_ARG2(L_ERROR,DBG_CELLID,ueRecfg->cellId,"RAM Handling for UE Reconfig failed" + "for OLD CRNTI:%d NEW CRNTI:%d",ueRecfg->oldCrnti,ueRecfg->newCrnti); + RETVALUE(RFAILED); + } + /* Delete Ue from the ue list */ + rgSCHDbmDelUeCb(cell, ue); + +#ifdef LTE_ADV + if (ue->numSCells) + { + for ( sCellIdx = 1; sCellIdx < CM_LTE_MAX_CELLS; sCellIdx++) + { + if(ue->cellInfo[sCellIdx] != NULLP) + { + rgSCHDbmDelUeCb(ue->cellInfo[sCellIdx]->cell, ue); + } + } + } +#endif + + /* Inititialize Ue control block */ + ue->ueId = ueRecfg->newCrnti; + RLOG_ARG2(L_DEBUG,DBG_CELLID,cell->cellId, + "Changing RNTI from %d to %d", + ueRecfg->oldCrnti, + ueRecfg->newCrnti); +#ifdef EMTC_ENABLE + if(ue->isEmtcUe) + { + rgSCHUtlUpdEmtcY(ue); + } +#endif + + /* Fix ccpu00122631: PCell_Reest: Updating new Rnti in all the cells + * dlAllocCb + */ + for(idx = 0; idx < CM_LTE_MAX_CELLS; idx++) + { + if(ue->cellInfo[idx]) + { + ue->cellInfo[idx]->dlAllocCb.rnti = ueRecfg->newCrnti; + } + } + + rgSCHUtlRecMsg3Alloc(cell, ue, raCb); + + /* If raCb received PHR, update scheduler */ + if(raCb->phr.pres == TRUE) + { + ue->macCeRptTime = raCb->msg3AllocTime; + rgSCHUtlUpdPhr(cell, ue, raCb->phr.val, errInfo); + } + +#ifdef RGR_V2 /* Acc Fix */ + if(TRUE == ue->isDrxEnabled) + { + ueRecfg->ueDrxRecfg.isDrxEnabled = TRUE; + ret = rgSCHDrxUeReCfg(cell,ue,ueRecfg); + + if ( ret != ROK ) + { + RLOG_ARG2(L_ERROR,DBG_CELLID,ueRecfg->cellId,"UE DRX re-est failed" + "for OLD CRNTI:%d NEW CRNTI:%d",ueRecfg->oldCrnti,ueRecfg->newCrnti); + RETVALUE(RFAILED); + } + } +#endif /* Acc Fix */ + + /* Re-insert updated Ue */ + rgSCHDbmInsUeCb(cell, ue); + +#ifdef LTE_ADV + if (ue->numSCells) + { + for ( sCellIdx = 1; sCellIdx < CM_LTE_MAX_CELLS; sCellIdx++) + { + if(ue->cellInfo[sCellIdx] != NULLP) + { + rgSCHDbmInsUeCb(ue->cellInfo[sCellIdx]->cell, ue); + } + } + } +#endif + + +#ifdef TENB_STATS + ue->tenbStats->stats.rnti = ue->ueId; +#endif + + /* Fix : syed If MSG4 is done, since corresponding ueCb + * is ready, the raCb should be cleared immediately. + * Otherwise it would remain in the cell until timed out + * and till then the hq Feedbacks will be assumed to be + * for msg4 */ + if (raCb->raState == RGSCH_RA_MSG4_DONE) + { + RLOG_ARG1(L_DEBUG,DBG_CELLID,ueRecfg->cellId, + "RNTI:%d with RaCb deleted as Msg4 transmission is done", + raCb->tmpCrnti); + rgSCHRamDelRaCb(cell, raCb, FALSE); + } + /* Fix : syed moving the UL CQI initialization to UERESET */ + + /* Release Older rnti */ + if(oldRntiLnk) + { + /* This is the rare case in which back to back reestablishment is + * happening and previous re-est was not done completely (MSG4 was + * not done) for an UE, and again re-est is triggered for the same + * UE. We are deleting the old RA CB for the previous re-est which + * still exist due to MSG4 not transmitted successfully */ + if ((oldRaCb = rgSCHDbmGetRaCb(cell, oldRntiLnk->rnti)) != NULLP) + { + rgSCHRamDelRaCb(cell, oldRaCb, FALSE); + } + + rgSCHUtlRlsRnti(cell, oldRntiLnk, TRUE, ueRecfg->newCrnti); + } + else + { + /* Fix : syed HO UE does not have a valid ue->rntiLnk */ + /* Just indicate to MAC, no need to release at SCH */ + RLOG_ARG2(L_DEBUG,DBG_CELLID,cell->cellId, + "HO OldRnti:%d RLS and NewRnti:%d CHNG IND TO MAC", + oldRnti, ueRecfg->newCrnti); + rgSCHUtlIndRntiRls2Mac(cell, oldRnti, TRUE, ueRecfg->newCrnti); + } + } + RETVALUE(ROK); +} +/** + * @brief Handler for the UE reconfiguration request from RRC to MAC. + * + * @details + * + * Function : rgSCHCfgRgrUeRecfg + * + * Processing Steps: + * - If rnti changes, + * - Invoke RAM for UE reconfiguration. + * - Delete old UE from the list. + * - Update the new rnti and re-insert the UE in the list. + * - Update the UE control block with the reconfigured values. + * - Invoke SCH, UHM and DHM with updated UE control block to + * update scheduler, uplink HARQ and downlink HARQ specific + * parameters. + * - If successful, return ROK else RFAILED. + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ue + * @param[in] RgrUeRecfg *ueRecfg + * @param[out] RgSchErrInfo *errInfo + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 rgSCHCfgRgrUeRecfg +( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgrUeRecfg *ueRecfg, +RgSchErrInfo *errInfo +) +#else +PUBLIC S16 rgSCHCfgRgrUeRecfg(cell, ue, ueRecfg, errInfo) +RgSchCellCb *cell; +RgSchUeCb *ue; +RgrUeRecfg *ueRecfg; +RgSchErrInfo *errInfo; +#endif +{ + S16 ret; +#ifdef LTE_ADV + Bool dciChange = TRUE; +#endif + + TRC2(rgSCHCfgRgrUeRecfg); + + errInfo->errCause = RGSCHERR_CFG_RGR_UE_RECFG; + +#ifdef LTE_ADV + if (ue->numSCells > 0) + { + dciChange = FALSE; + } + if ((ueRecfg->ueRecfgTypes & RGR_UE_UE_ACCESS_STRATUM_REL_RECFG) && \ + (ue->accessStratumRls != ueRecfg->accessStratumRls)) + { + ue->accessStratumRls = ueRecfg->accessStratumRls; + dciChange = TRUE; + } + + /* if SCELL_RECFG is present , no other + * type will be present. Process Scell addition + * and return + * */ + if (ueRecfg->ueRecfgTypes & RGR_UE_SCELL_ADD_RECFG) + { + ret = rgSCHSCellCfgUeCfg(cell, ue, ueRecfg, errInfo); + if( ret != ROK) + { + errInfo->errCause = RGSCHERR_CFG_INVALID_RGR_UE_SCELL_RECFG; + /*FH: SCell config failed for a scell index hence revert all successful + * Scell config and send negative confirmation to APP*/ + rgSCHSCellCfgUeCfgRollBack(cell, ue, ueRecfg); + RETVALUE(RFAILED); + } + } + if (dciChange == TRUE) + { + if (ue->numSCells > 0) + { + /* 2 bit CSI */ + rgSCHUtlUpdUeDciSize(cell, ue, TRUE); + } + else + { + /* 1 bit CSI Access Stratum Release Change */ + rgSCHUtlUpdUeDciSize(cell, ue, FALSE); + } + } + if (ueRecfg->ueRecfgTypes & RGR_UE_SCELL_PUCCH_RECFG) + { + ret = rgSCHSCellCfgUePucchReCfg(cell, ue, ueRecfg, errInfo); + if( ret != ROK) + { + errInfo->errCause = RGSCHERR_CFG_INVALID_RGR_UE_SCELL_PUCCH_RECFG; + RETVALUE(RFAILED); + } + } +#else + if ((ueRecfg->ueRecfgTypes & RGR_UE_UE_ACCESS_STRATUM_REL_RECFG) && \ + (ue->accessStratumRls != ueRecfg->accessStratumRls)) + { + ue->accessStratumRls = ueRecfg->accessStratumRls; + rgSCHUtlUpdUeDciSize(cell, ue, FALSE); + } +#endif /* LTE_ADV */ + + if (ueRecfg->ueRecfgTypes) + { + /* Update scheduler related information for UE */ + ret = rgSCHUtlRgrUeRecfg(cell, ue, ueRecfg, errInfo); + if (ret != ROK) + { + RLOG_ARG2(L_ERROR,DBG_CELLID,ueRecfg->cellId, + "Scheduler handling while reconfig failed" + "for OLD CRNTI:%d NEW CRNTI:%d",ueRecfg->oldCrnti,ueRecfg->newCrnti); + RETVALUE(RFAILED); + } + + /* Update uplink HARQ related information for UE */ + rgSCHUhmRgrUeRecfg(cell, ue, ueRecfg); + + /* Update TA related information for UE */ + if (ueRecfg->ueRecfgTypes & RGR_UE_TATMR_RECFG) + { + rgSCHCfgUeTaRecfg(cell, ue, ueRecfg, errInfo); + } + + /*Update Measurement Gap and AckNack Details */ + /* After merging from 2.2 */ + if (ueRecfg->ueRecfgTypes & RGR_UE_ACKNACK_MEASGAP_RECFG) + { + ret = rgSCHMeasGapANRepUeRecfg(cell, ue, ueRecfg); + if (ret != ROK) + { + RLOG_ARG2(L_ERROR,DBG_CELLID,ueRecfg->cellId,"Measurement Gap and" + "AckNack Rep Recfg failed for OLD CRNTI:%d NEW CRNTI:%d", + ueRecfg->oldCrnti,ueRecfg->newCrnti); + RETVALUE(RFAILED); + } + } + if (ueRecfg->ueRecfgTypes & RGR_UE_BSRTMR_RECFG) + { + cmInitTimers(&ue->bsrTmr, 1); + ue->ul.bsrTmrCfg = ueRecfg->ueBsrTmrRecfg; + if ((ue->ul.bsrTmrCfg.isPrdBsrTmrPres) && + (ue->ul.bsrTmrCfg.prdBsrTmr == 0xFFFF)) + { + ue->ul.bsrTmrCfg.isPrdBsrTmrPres = FALSE; + } + } + } + + if (RFAILED == rgSCHCfgRgrUeRecfgRntiChg (cell, ue, ueRecfg, errInfo)) + { + RLOG_ARG2(L_ERROR,DBG_CELLID,ueRecfg->cellId,"RNTI change " + "failed for OLD CRNTI:%d NEW CRNTI:%d", + ueRecfg->oldCrnti,ueRecfg->newCrnti); + RETVALUE(RFAILED); + } + +#ifdef TFU_UPGRADE + /* Re-Initialize Aperiodic CQI Information for UE*/ + if ( ueRecfg->ueRecfgTypes & RGR_UE_APRD_DLCQI_RECFG ) + { + ret = rgSCHCfgAcqiUeReCfg(cell, ue, &ueRecfg->aprdDlCqiRecfg, + ue->ueCatEnum); + } + /* Re-Initialize Periodic CQI/PMI, RI Information for UE */ + if ( ueRecfg->ueRecfgTypes & RGR_UE_PCQI_RECFG) + { + ret = rgSCHCfgPCqiUeReCfg(cell, ue, &ueRecfg->cqiCfg, + ue->ueCatEnum); + } + /* Re-Initialize UL SRS Information for UE */ + if ( ueRecfg->ueRecfgTypes & RGR_UE_SRS_RECFG) + { + ret = rgSCHCfgSrsUeReCfg(cell, ue, &ueRecfg->srsCfg); + } + /* Re-Initialize SR Information for UE */ + if ( ueRecfg->ueRecfgTypes & RGR_UE_SR_RECFG) + { + ret = rgSCHCfgSrUeReCfg(cell, ue, &ueRecfg->srCfg); + } +#endif + +#ifdef LTEMAC_HDFDD + if(ueRecfg->isHdFddEnbld) + { + ret = rgSCHHdFddUeCfg(cell, ue, ueRecfg->isHdFddEnbld); + if (ret != ROK) + { + errInfo->errCause = RGSCHERR_HDFDD_SPSCFGRD; + RETVALUE(ret); + } + } +#endif /* LTEMAC_HDFDD */ +#ifdef RGR_V2 + if ( ueRecfg->ueRecfgTypes & RGR_UE_DRX_RECFG) + { + ret = rgSCHDrxUeReCfg(cell,ue,ueRecfg); + + if ( ret != ROK ) + { + RLOG_ARG2(L_ERROR,DBG_CELLID,ueRecfg->cellId,"UE DRX reconfig failed" + "failed for OLD CRNTI:%d NEW CRNTI:%d", + ueRecfg->oldCrnti,ueRecfg->newCrnti); + RETVALUE(RFAILED); + } + } +#endif +/* ccpu00117452 - MOD - Changed macro name from + RGR_RRM_DLPWR_CNTRL to RGR_CQI_REPT */ +#ifdef RGR_CQI_REPT + /* CQI Reporting (N) Re-configuration */ + if(ueRecfg->ueRecfgTypes & RGR_UE_CQIREPT_RECFG) + { + ret = rgSCHCfgUeCqiReptReCfg(cell, ue, ueRecfg); + if(ret != OK) + { + errInfo->errCause = RGSCHERR_CQIREPT; + RETVALUE(ret); + } + } +#endif /* End of RGR_CQI_REPT */ +#ifdef TFU_UPGRADE + /* pA Re-configuration */ + if((ueRecfg->ueRecfgTypes & RGR_UE_PA_RECFG) && + RG_SCH_UE_CFG_ISPAPRSNT(ueRecfg->uePdschDedCfg.uepACfg)) + { + RG_SCH_CMN_GET_PA(ue,cell).pres = TRUE; + RG_SCH_CMN_GET_PA(ue,cell).val = ueRecfg->uePdschDedCfg.uepACfg.pA; + } +#endif + +/* LTE_ADV_FLAG_REMOVED_START */ + if(ueRecfg->ueRecfgTypes & RGR_UE_LTEA_RECFG) + { + if(ueRecfg->ueLteAdvCfg.pres & RGR_ABS) + { + ue->lteAdvUeCb.rgrLteAdvUeCfg.isAbsUe = ueRecfg->ueLteAdvCfg.isAbsUe; + } + + if(ueRecfg->ueLteAdvCfg.pres & RGR_SFR) + { + ue->lteAdvUeCb.rgrLteAdvUeCfg.isUeCellEdge = ueRecfg->ueLteAdvCfg.isUeCellEdge; + } + } +/* LTE_ADV_FLAG_REMOVED_END */ +#ifdef EMTC_ENABLE + if(ueRecfg->ueRecfgTypes & RGR_UE_EMTC_DPLXMODE_RECFG) + { + rgSCHEmtcHdFddUeCfg (cell, ue, + ueRecfg->emtcUeRecfg.isHdFddEnbld); + } + if(ueRecfg->ueRecfgTypes & RGR_UE_EMTC_PO_TRIGGER) + { + rgSCHEmtcPOTrigger(cell, ue); + } +#endif + errInfo->errCause = RGSCHERR_NONE; + + RETVALUE(ROK); +} /* rgSCHCfgRgrUeRecfg */ + + +/** + * @brief Handler for the logical channel reconfiguration request from + * RRC to MAC. + * + * @details + * + * Function : rgSCHCfgRgrLchRecfg + * + * Processing Steps: + * - Invoke scheduler to update scheduler specific information. + * - Update the dedicated logical channel Cb with the reconfigured + * values. + * - If successful, return ROK else RFAILED. + * + * @param[in] RgUlCellCb *cell + * @param[in] RgUlUeCb *ue + * @param[in] RgSchUlLcCb *ulLc + * @param[in] RgSchDlLcCb *dlLc + * @param[in] RgrLchRecfg *lcRecfg + * @param[out] RgSchErrInfo *errInfo + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 rgSCHCfgRgrLchRecfg +( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgSchDlLcCb *dlLc, +RgrLchRecfg *lcRecfg, +RgSchErrInfo *errInfo +) +#else +PUBLIC S16 rgSCHCfgRgrLchRecfg(cell, ue, dlLc, lcRecfg, errInfo) +RgSchCellCb *cell; +RgSchUeCb *ue; +RgSchDlLcCb *dlLc; +RgrLchRecfg *lcRecfg; +RgSchErrInfo *errInfo; +#endif +{ + S16 ret = ROK; + + TRC2(rgSCHCfgRgrLchRecfg); + + errInfo->errCause = RGSCHERR_CFG_RGR_LC_RECFG; + /* Invoke Scheduler to update the new configuration */ + ret = rgSCHUtlRgrLcRecfg(cell, ue, dlLc, lcRecfg, errInfo); + if (ret != ROK) + { + RLOG_ARG2(L_ERROR,DBG_CELLID,lcRecfg->cellId,"Scheduler handling for LC Recfg" + " failed for CRNTI:%d LCID:%d",lcRecfg->crnti,lcRecfg->lcId); + RETVALUE(RFAILED); + } + + errInfo->errCause = RGSCHERR_NONE; + RETVALUE(ROK); +} /* rgSCHCfgRgrLchRecfg */ +/** + * @brief Handler for the logical channel reconfiguration request from + * RRC to MAC. + * + * @details + * + * Function : rgSCHCfgRgrLcgRecfg + * + * Processing Steps: + * - Invoke scheduler to update scheduler specific information. + * - Update the dedicated logical channel Cb with the re-configured + * values. + * - If successful, return ROK else RFAILED. + * + * @param[in] RgUlCellCb *cell + * @param[in] RgUlUeCb *ue + * @param[in] RgrLcgRecfg *lcgRecfg + * @param[out] RgSchErrInfo *errInfo + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 rgSCHCfgRgrLcgRecfg +( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgrLcgRecfg *lcgRecfg, +RgSchErrInfo *errInfo +) +#else +PUBLIC S16 rgSCHCfgRgrLcgRecfg(cell, ue, lcgRecfg, errInfo) +RgSchCellCb *cell; +RgSchUeCb *ue; +RgrLcgRecfg *lcgRecfg; +RgSchErrInfo *errInfo; +#endif +{ + S16 ret = ROK; + + TRC2(rgSCHCfgRgrLcgRecfg); + + errInfo->errCause = RGSCHERR_CFG_RGR_LCG_RECFG; + + /*Added for handling LCG ReConfig if the LCG was deleted */ + ue->ul.lcgArr[lcgRecfg->ulRecfg.lcgId].lcgId = lcgRecfg->ulRecfg.lcgId; + + /* Invoke Scheduler to update the new configuration */ + ret = rgSCHUtlRgrLcgRecfg(cell, ue, lcgRecfg, errInfo); + if (ret != ROK) + { + RLOG_ARG2(L_ERROR,DBG_CELLID,lcgRecfg->cellId,"Scheduler handling for LCG Recfg" + " failed for CRNTI:%d LCGID:%d",lcgRecfg->crnti,lcgRecfg->ulRecfg.lcgId); + RETVALUE(RFAILED); + } + + errInfo->errCause = RGSCHERR_NONE; + RETVALUE(ROK); +} /* rgSCHCfgRgrLcgRecfg */ + +/** + * @brief Handler for the UE Reset request from RRM to MAC. + * + * @details + * + * Function : rgSCHCfgRgrUeReset + * + * Processing Steps: + * - Call Measument Gap Module and Ack/Nack Module for resetting UE. + * - Call Common Schduler UE rest API which inturn will call scheduler + * specific UE Reset APis to reset UE. + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ue + * @param[in] RgrRst *reset + * @param[out] RgSchErrInfo *errInfo + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 rgSCHCfgRgrUeReset +( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgrRst *reset, +RgSchErrInfo *errInfo +) +#else +PUBLIC S16 rgSCHCfgRgrUeReset(cell, ue, reset, errInfo) +RgSchCellCb *cell; +RgSchUeCb *ue; +RgrRst *reset; +RgSchErrInfo *errInfo; +#endif +{ + U32 idx; + RgSchRaCb *raCb; + + TRC2(rgSCHCfgRgrUeReset); + + + errInfo->errCause = RGSCHERR_CFG_RGR_UE_RESET; + + /* Setting BO of Each Logical Channel of the UE to 0 */ + for (idx = 0; idx < RGSCH_MAX_LC_PER_UE; idx++) + { + if(ue->dl.lcCb[idx] != NULLP) + ue->dl.lcCb[idx]->bo = 0; + } + + /* Reset the totalBo */ + ue->totalBo = 0; + /* Call DRX module to stop all DRX timers */ + /* ccpu00129899 */ + if(ue->drxCb != NULLP) + { + (Void)rgSCHDrxUeDel(cell,ue); + } + + /* ccpu00140894- Stop TXMode transiition timer if it is running*/ + if (ue->txModeTransTmr.tmrEvnt != TMR_NONE) + { + rgSCHTmrStopTmr(cell, RG_SCH_TMR_TXMODE_TRNSTN, ue); + ue->txModeTransCmplt =TRUE; + } + + /* ccpu00133470- Meas Gap should be released during RRC re-establishment */ + rgSCHMeasGapANRepUeDel(cell, ue, FALSE); + + /* Call Common scheduler which in turn will call specific scheduler for UE + * Reset*/ + rgSCHUtlUeReset(cell, ue); +#ifdef LTE_ADV + /*PCell which is at idx 0 is always active. Adding a line after the loop + *setting RGSCH_PCELL_INDEX to SCELL ACTIVE*/ + ue->cellInfo[RGSCH_PCELL_INDEX]->sCellState = RG_SCH_SCELL_ACTIVE; +#endif + + /* In case of back to back reestablishments, when this UE's + * previous ReEst is still in progress and has got RESET + * as part of new ReEst */ + if((raCb = rgSCHDbmGetRaCb(cell, ue->ueId)) != NULLP) + { + rgSCHRamDelRaCb(cell, raCb, FALSE); + } + /* Fix : syed set UE inactive in DL until UE is reinitialization completed */ + ue->dl.dlInactvMask |= RG_HQENT_INACTIVE; + ue->ul.ulInactvMask |= RG_HQENT_INACTIVE; + /* [ccpu00127141] Resetting TA related parameters */ + ue->dl.taCb.ta = RGSCH_NO_TA_RQD; + ue->dl.taCb.state = RGSCH_TA_IDLE; + + /*[ccpu00121813]-ADD-Initializing outstanding TA value */ + ue->dl.taCb.outStndngTa = FALSE; + ue->dl.taCb.outStndngTaval = RGSCH_NO_TA_RQD; + + if (ue->dl.taCb.cfgTaTmr) + { + rgSCHTmrStartTmr (cell, ue, RG_SCH_TMR_TA, ue->dl.taCb.cfgTaTmr); + } + +#ifdef DL_LA + /* Resetting the Tx mode change factor on UE reset */ + ue->mimoInfo.txModUpChgFactor = 0; + ue->mimoInfo.txModDownChgFactor = 0; +#endif + + errInfo->errCause = RGSCHERR_NONE; + RETVALUE(ROK); +} /* rgSCHCfgRgrUeReset */ + +/** + * @brief Handler for the cell delete request from RRM to MAC. + * + * @details + * + * Function : rgSCHCfgRgrCellDel + * + * Processing Steps: + * - Fetch the cell control block. + * - Remove the cell control block from the hash list of cells. + * - Free the cell control block. + * - If successful, return ROK else return RFAILED. + * + * @param[in] RgSchCellCb *cell + * @param[in] RgrDel *cellDelInfo + * @param[out] RgSchErrInfo *errInfo + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 rgSCHCfgRgrCellDel +( +RgSchCellCb *cell, +RgrDel *cellDelInfo, +RgSchErrInfo *errInfo +) +#else +PUBLIC S16 rgSCHCfgRgrCellDel(cell, cellDelInfo, errInfo) +RgSchCellCb *cell; +RgrDel *cellDelInfo; +RgSchErrInfo *errInfo; +#endif +{ + TRC2(rgSCHCfgRgrCellDel); + + + errInfo->errCause = RGSCHERR_CFG_RGR_CELL_DEL; + + if (cell->cellId != cellDelInfo->u.cellDel.cellId) + { + RLOG_ARG0(L_ERROR,DBG_CELLID,cellDelInfo->u.cellDel.cellId, + "Cell does not exist"); + RETVALUE(RFAILED); + } + + /* Free the active cell */ + rgSCHCfgFreeCellCb(cell); + + errInfo->errCause = RGSCHERR_NONE; + RETVALUE(ROK); +} /* rgSCHCfgRgrCellDel */ + + +/** + * @brief Handler for the UE delete request from RRM to MAC. + * + * @details + * + * Function : rgSCHCfgRgrUeDel + * + * Processing Steps: + * - Fetch the UE control block. + * - Remove the UE control block from the hash list of UEs for the cell. + * - Free the UE control block. + * - If successful, return ROK else return RFAILED. + * + * @param[in] RgSchCellCb *cell + * @param[in] RgrDel *ueDelInfo + * @param[out] RgSchErrInfo *errInfo + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 rgSCHCfgRgrUeDel +( +RgSchCellCb *cell, +RgrDel *ueDelInfo, +RgSchErrInfo *errInfo +) +#else +PUBLIC S16 rgSCHCfgRgrUeDel(cell, ueDelInfo, errInfo) +RgSchCellCb *cell; +RgrDel *ueDelInfo; +RgSchErrInfo *errInfo; +#endif +{ + RgSchUeCb *ue; + RgSchRaCb *raCb; +#ifdef LTE_ADV + Inst inst = cell->instIdx; + RgSchCellCb *secCellCb = NULLP; +#endif + + TRC2(rgSCHCfgRgrUeDel); + errInfo->errCause = RGSCHERR_CFG_RGR_UE_DEL; + + if (cell->cellId != ueDelInfo->u.ueDel.cellId) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,ueDelInfo->u.ueDel.cellId, + "Cell does not exist CRNTI:%d", + ueDelInfo->u.ueDel.crnti); + RETVALUE(RFAILED); + } + if ((ue = rgSCHDbmGetUeCb(cell, ueDelInfo->u.ueDel.crnti)) == NULLP) + { + if((raCb = rgSCHDbmGetRaCb(cell, ueDelInfo->u.ueDel.crnti)) == NULLP) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,ueDelInfo->u.ueDel.cellId, + "RaCb does not exist for CRNTI:%d",ueDelInfo->u.ueDel.crnti); + RETVALUE(RFAILED); + } + else + { + /* This happens in case of Msg4 rejection */ + raCb->toDel = TRUE; + RETVALUE(ROK); + } + } + else + { +#ifdef LTE_ADV + if(ueDelInfo->u.ueScellRel.ueDelTypes & RGR_UE_SCELL_DEL_RECFG) + { + for(U8 idx = 0; idx < ueDelInfo->u.ueScellRel.ueSCellRelCfgInfo.numSCells; idx++) + { + if(NULLP != (secCellCb = (RgSchCellCb *)rgSchUtlGetCellCb(inst, \ + ueDelInfo->u.ueScellRel.ueSCellRelCfgInfo.ueSCellRelDedCfg[idx].sCellId))) + { + rgSCHUtlSndUeSCellDel2Mac(secCellCb, ue->ueId); + rgSCHSCellDelUeSCell(cell,ue,ueDelInfo->u.ueScellRel.ueSCellRelCfgInfo.ueSCellRelDedCfg[idx].sCellIdx); + ue->numSCells--; + if ( ue->numSCells == 0) + { + ue->allocCmnUlPdcch = TRUE; + } + } + } + if (ue->numSCells == 0) + { + /* As there is no SCell left so DCI 0 size at UE specific search space + * will be recalculated as the CSI is reduced to 1 bit */ + rgSCHUtlUpdUeDciSize(cell, ue, FALSE); + } + } + else +#endif + { + /* Delete Ue from the UE list of CELL*/ + rgSCHDbmDelUeCb(cell, ue); + +#ifdef LTE_L2_MEAS + rgSCHDbmDelL2MUe(cell, ue); +#endif + + /* Call MeasGap and AckNakRep processing module */ + rgSCHMeasGapANRepUeDel(cell, ue, TRUE); + + /* ccpu00140894- Stop TXMode transiition timer if it is running*/ + if (ue->txModeTransTmr.tmrEvnt != TMR_NONE) + { + rgSCHTmrStopTmr(cell, RG_SCH_TMR_TXMODE_TRNSTN, ue); + } + + /* Call DRX module to remove UEs from various + * lists it maintain + */ + /* ccpu00129899 */ + if(ue->drxCb != NULLP) + { + (Void)rgSCHDrxUeDel(cell,ue); + /* Free Ue */ + } + /*Fix: If RA CB exists, delete it*/ + if((raCb = rgSCHDbmGetRaCb(cell, ueDelInfo->u.ueDel.crnti)) != NULLP) + { + /* Fix : syed RNTI was getting released twice, once by racb del + * and subsequently by ueDel. Let it get released by ueDel alone */ + rgSCHRamDelRaCb(cell, raCb, FALSE); + } +#ifdef EMTC_ENABLE + if(ue->isEmtcUe) + { + rgSCHEmtcUeDel(cell, ue); + } +#endif + + rgSCHCfgFreeUeCb(cell, ue); + + errInfo->errCause = RGSCHERR_NONE; + + } + RETVALUE(ROK); + } +} /* rgSCHCfgRgrUeDel */ + + +/** + * @brief Handler for the logical channel delete request from + * RRM to MAC. + * + * @details + * + * Function : rgSCHCfgRgrLcDel + * + * Processing Steps: + * - Fetch the logical channel control block. + * - Free the logical channel control block. + * - If successful, return ROK else return RFAILED. + * + * @param[in] RgrDel *lcDelInfo + * @param[out] RgSchErrInfo *errInfo + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 rgSCHCfgRgrLcDel +( +RgSchCellCb *cell, +RgrDel *lcDelInfo, +RgSchErrInfo *errInfo +) +#else +PUBLIC S16 rgSCHCfgRgrLcDel(cell, lcDelInfo, errInfo) +RgSchCellCb *cell; +RgrDel *lcDelInfo; +RgSchErrInfo *errInfo; +#endif +{ + RgSchUeCb *ue; + RgSchDlLcCb *dlLc; +#ifdef LTE_L2_MEAS + U8 lcId; + U8 idx; + RgSchUlLcCb *ulLc; +#endif + + TRC2(rgSCHCfgRgrLcDel); + + errInfo->errCause = RGSCHERR_CFG_RGR_LC_DEL; + + /* Fetch the Active cell */ + if (cell->cellId != lcDelInfo->u.lchDel.cellId) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId, "Cell does not exist %d", + lcDelInfo->u.lchDel.cellId); + RETVALUE(RFAILED); + } + + /* Fetch the Ue */ + if ((ue = rgSCHDbmGetUeCb(cell, lcDelInfo->u.lchDel.crnti)) == NULLP) + { + RLOG_ARG2(L_ERROR,DBG_CELLID,lcDelInfo->u.lchDel.cellId, + "UE does not exist for CRNTI:%d LCID:%d", + lcDelInfo->u.lchDel.crnti,lcDelInfo->u.lchDel.lcId); + RETVALUE(RFAILED); + } + if (lcDelInfo->u.lchDel.lcgId > 3) + { + RLOG_ARG3(L_ERROR,DBG_CELLID,lcDelInfo->u.lchDel.cellId, + "[%d]UEID:For LC %d, LCGid %d is invalid", + lcDelInfo->u.lchDel.crnti,lcDelInfo->u.lchDel.lcId, + lcDelInfo->u.lchDel.lcgId); + RETVALUE(RFAILED); + } + if ((dlLc = rgSCHDbmGetDlDedLcCb(ue, lcDelInfo->u.lchDel.lcId)) + == NULLP) + { + RLOG_ARG2(L_ERROR,DBG_CELLID,lcDelInfo->u.lchDel.cellId, + "LC does not exist for CRNTI:%d LCID:%d", + lcDelInfo->u.lchDel.crnti, lcDelInfo->u.lchDel.lcId); + RETVALUE(RFAILED); + } + rgSCHUtlRgrLcDel(cell, ue, lcDelInfo->u.lchDel.lcId,lcDelInfo->u.lchDel.lcgId); + + /* Reduce any pending bo from this LC(if any) + * from the UE's total BO */ + if(dlLc->bo) + { + if(ue->totalBo >= dlLc->bo) + { + ue->totalBo -= dlLc->bo; + } + else + { + ue->totalBo = 0; /* this scenario should not occur */ + } + } + rgSCHDbmDelDlDedLcCb(ue, dlLc); + rgSCHCfgFreeDlDedLcCb(cell, ue, dlLc); + +#ifdef LTE_L2_MEAS + lcId = lcDelInfo->u.lchDel.lcId; + if (TRUE == ue->ul.lcCb[lcId -1].isValid) + { + ulLc = &(ue->ul.lcCb[lcId -1]); + ue->ul.lcCb[lcId -1].isValid = FALSE; + + if((ulLc->qciCb->ulUeCount) && + (ue->ulActiveLCs & (1 << (ulLc->qciCb->qci -1)))) + { + ulLc->qciCb->ulUeCount--; + ue->ulActiveLCs &= ~(1 << (ulLc->qciCb->qci -1)); + } + /* Shifting LCs in LCG Array because of LC deletion */ + for (idx = ulLc->lcgArrIdx +1; idx < ulLc->lcg->numLch; + idx++) + { + ulLc->lcg->lcArray[idx -1] = + ulLc->lcg->lcArray[idx]; + ulLc->lcg->lcArray[idx -1]->lcgArrIdx = idx -1; + } + ulLc->lcg->numLch--; + ulLc->lcg->lcArray[idx -1] = NULLP; + } +#endif /* LTE_L2_MEAS */ + + + errInfo->errCause = RGSCHERR_NONE; + RETVALUE(ROK); +} /* rgSCHCfgRgrLcDel */ + + + +/** + * @brief Handler for the logical channel delete request from + * RRM to MAC. + * + * @details + * + * Function : rgSCHCfgRgrLcgDel + * + * Processing Steps: + * - Fetch the logical channel control block. + * - Free the logical channel control block. + * - If successful, return ROK else return RFAILED. + * + * @param[in] RgrDel *lcDelInfo + * @param[out] RgSchErrInfo *errInfo + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 rgSCHCfgRgrLcgDel +( +RgSchCellCb *cell, +RgrDel *lcDelInfo, +RgSchErrInfo *errInfo +) +#else +PUBLIC S16 rgSCHCfgRgrLcgDel(cell, lcDelInfo, errInfo) +RgSchCellCb *cell; +RgrDel *lcDelInfo; +RgSchErrInfo *errInfo; +#endif +{ + RgSchUeCb *ue = NULLP; +#ifdef LTE_L2_MEAS + U8 lcCount = 0; +#endif + U8 lcgId = 0; + + TRC2(rgSCHCfgRgrLcgDel); + + + lcgId = lcDelInfo->u.lcgDel.lcgId; + + errInfo->errCause = RGSCHERR_CFG_RGR_LCG_DEL; + + /* Fetch the Active cell */ + if (cell->cellId != lcDelInfo->u.lcgDel.cellId) + { + RLOG_ARG2(L_ERROR,DBG_CELLID,lcDelInfo->u.lchDel.cellId, + "CELL does not exist for CRNTI:%d LCGID:%d", + lcDelInfo->u.lchDel.crnti,lcDelInfo->u.lchDel.lcId); + RETVALUE(RFAILED); + } + + /* Fetch the Ue */ + if ((ue = rgSCHDbmGetUeCb(cell, lcDelInfo->u.lcgDel.crnti)) == NULLP) + { + RLOG_ARG2(L_ERROR,DBG_CELLID,lcDelInfo->u.lchDel.cellId, + "UE does not exist for CRNTI:%d LCGID:%d", + lcDelInfo->u.lchDel.crnti,lcDelInfo->u.lchDel.lcId); + RETVALUE(RFAILED); + } + + /* set lcgId in UEs lcg cntrl blk to invalid */ + rgSCHUtlRgrLcgDel(cell, ue, lcgId); + ue->ul.lcgArr[lcgId].lcgId = RGSCH_INVALID_LCG_ID; + +#ifdef LTE_L2_MEAS + /* Since LCs are being deleted, if any of them are contributing + to Active UE count for a QCI, decrease the count */ + for (lcCount =0; (lcCount < RGSCH_MAX_LC_PER_UE) && + (lcCount < ue->ul.lcgArr[lcgId].numLch) ; lcCount++) + { + if (ue->ul.lcgArr[lcgId].lcArray[lcCount]) + { + if((ue->ul.lcgArr[lcgId]. + lcArray[lcCount]->qciCb->ulUeCount) && + (ue->ulActiveLCs & + (1 << ((ue->ul.lcgArr[lcgId]. + lcArray[lcCount])->qciCb->qci -1)))) + { + /* L2_COUNTERS */ + ue->ul.lcgArr[lcgId]. + lcArray[lcCount]->qciCb->ulUeCount--; + ue->ulActiveLCs &= ~(1 << + (ue->ul.lcgArr[lcgId]. + lcArray[lcCount]->qciCb->qci -1)); + } + } + } +#endif + + errInfo->errCause = RGSCHERR_NONE; + RETVALUE(ROK); +} /* rgSCHCfgRgrLcgDel */ + + + +/*********************************************************** + * + * Func : rgSCHCfgVldtRgrLcCfg + * + * + * Desc : Validates dedicated logical channel configuration recieved from RRM. + * + * Ret : S16 + * ROK - Success + * RFAILED - Failed + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PUBLIC S16 rgSCHCfgVldtRgrLcCfg +( +Inst inst, +RgrLchCfg *lcCfg, +RgSchCellCb **cell, +RgSchUeCb **ue, +RgSchErrInfo *errInfo +) +#else +PUBLIC S16 rgSCHCfgVldtRgrLcCfg(inst, lcCfg, cell, ue, errInfo) +Inst inst; +RgrLchCfg *lcCfg; +RgSchCellCb **cell; +RgSchUeCb **ue; +RgSchErrInfo *errInfo; +#endif +{ + TRC2(rgSCHCfgVldtRgrLcCfg); + + + errInfo->errCause = RGSCHERR_CFG_INVALID_RGR_DED_LC_CFG; + + if (((*cell) == NULLP) || + ((*cell)->cellId != lcCfg->cellId)) + { + RLOG_ARG2(L_ERROR,DBG_CELLID,lcCfg->cellId,"Cell does not existi for " + "CRNTI:%d LCID:%d",lcCfg->crnti, lcCfg->lcId); + RETVALUE(RFAILED); + } + + /* Fetch the Ue */ + if ((*ue = rgSCHDbmGetUeCb(*cell, lcCfg->crnti)) == NULLP) + { + RLOG_ARG2(L_ERROR,DBG_CELLID,lcCfg->cellId,"UE does not exist for dedicated" + " logical channel CRNTI:%d LCID:%d", lcCfg->crnti, lcCfg->lcId); + RETVALUE(RFAILED); + } + + /* Validate logical channel Id */ + if ((lcCfg->lcId < RGSCH_DEDLC_MIN_LCID) + ||(lcCfg->lcId > RGSCH_DEDLC_MAX_LCID)) + { + RLOG_ARG2(L_ERROR,DBG_CELLID,lcCfg->cellId,"Invalid logical channel Id:%d" + "for CRNTI:%d",lcCfg->lcId,lcCfg->crnti); + RETVALUE(RFAILED); + } + + if (lcCfg->lcType != CM_LTE_LCH_DTCH && lcCfg->lcType != CM_LTE_LCH_DCCH) + { + RLOG_ARG3(L_ERROR,DBG_CELLID,lcCfg->cellId,"Invalid logical channel Type %d" + "CRNTI:%d LCID:%d",lcCfg->lcType,lcCfg->crnti, lcCfg->lcId); + RETVALUE(RFAILED); + } + + RETVALUE(ROK); +} /* rgSCHCfgVldtRgrLcCfg */ + +/*********************************************************** + * + * Func : rgSCHCfgVldtRgrLcgCfg + * + * + * Desc : Validates dedicated logical channel group configuration recieved from RRM. + * + * Ret : S16 + * ROK - Success + * RFAILED - Failed + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PUBLIC S16 rgSCHCfgVldtRgrLcgCfg +( +Inst inst, +RgrLcgCfg *lcgCfg, +RgSchCellCb **cell, +RgSchUeCb **ue, +RgSchErrInfo *errInfo +) +#else +PUBLIC S16 rgSCHCfgVldtRgrLcgCfg(inst, lcgCfg, cell, ue, errInfo) +Inst inst; +RgrLcgCfg *lcgCfg; +RgSchCellCb **cell; +RgSchUeCb **ue; +RgSchErrInfo *errInfo; +#endif +{ + TRC2(rgSCHCfgVldtRgrLcgCfg); + + + errInfo->errCause = RGSCHERR_CFG_INVALID_RGR_DED_LCG_CFG; + + if (((*cell) == NULLP) || + ((*cell)->cellId != lcgCfg->cellId)) + { + RLOG_ARG2(L_ERROR,DBG_CELLID,lcgCfg->cellId,"Cell does not exist for" + "CRNTI:%d LCGID:%d",lcgCfg->crnti,lcgCfg->ulInfo.lcgId); + RETVALUE(RFAILED); + } + + /* Fetch the Ue */ + if ((*ue = rgSCHDbmGetUeCb(*cell, lcgCfg->crnti)) == NULLP) + { + RLOG_ARG2(L_ERROR,DBG_CELLID,lcgCfg->cellId,"UE does not exist for " + "dedicated logical channel CRNTI:%d LCGID:%d", lcgCfg->crnti, lcgCfg->ulInfo.lcgId); + RETVALUE(RFAILED); + } + + if ((lcgCfg->ulInfo.gbr != 0) && (lcgCfg->ulInfo.mbr < lcgCfg->ulInfo.gbr)) + { + RETVALUE(RFAILED); + } + + RETVALUE(ROK); +} /* rgSCHCfgVldtRgrLcgCfg */ + + +/*********************************************************** + * + * Func : rgSCHCfgVldtRgrCellPwrCfg + * + * Desc : Validates cell power configuration. + * + * Ret : S16 + * ROK - Success + * RFAILED - Failed + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PRIVATE S16 rgSCHCfgVldtRgrCellPwrCfg +( +Inst inst, +RgrCellCfg *cellCfg, +RgSchErrInfo *errInfo +) +#else +PRIVATE S16 rgSCHCfgVldtRgrCellPwrCfg(inst, cellCfg, errInfo) +Inst inst; +RgrCellCfg *cellCfg; +RgSchErrInfo *errInfo; +#endif +{ + UNUSED(inst); + UNUSED(cellCfg); + UNUSED(errInfo); + + TRC2(rgSCHCfgVldtRgrCellPwrCfg); + + /* This function does nothing now, placeholder for + * subsequent power config validations that may be needed */ + + + RETVALUE(ROK); +} /* rgSCHCfgVldtRgrCellPwrCfg */ + + +/*********************************************************** + * + * Func : rgSCHCfgVldtRgrCmnLcCfg + * + * + * Desc : Validates common logical channel configuration recieved from RRM. + * + * @param[in] Inst inst + * @param[in] RgrCellCfg *cellCfg + * @param[out] RgSchErrInfo *errInfo + * Ret : S16 + * ROK - Success + * RFAILED - Failed + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PRIVATE S16 rgSCHCfgVldtRgrCmnLcCfg +( +Inst inst, +RgrCellCfg *cellCfg, +RgSchErrInfo *errInfo +) +#else +PRIVATE S16 rgSCHCfgVldtRgrCmnLcCfg(inst, cellCfg, errInfo) +Inst inst; +RgrCellCfg *cellCfg; +RgSchErrInfo *errInfo; +#endif +{ + U8 idx; + RgrCmnLchCfg *lcCfg; + U8 dirVld = FALSE; + U8 bitMask = 0x00; + U8 cnt=0; + + TRC2(rgSCHCfgVldtRgrCmnLcCfg); + + errInfo->errCause = RGSCHERR_CFG_INVALID_RGR_CMN_LC_CFG; + + for (idx = 0; idx < cellCfg->numCmnLcs; idx++) + { + lcCfg = &(cellCfg->cmnLcCfg[idx]); + /* Validate downlink info */ + if (lcCfg->dir & RGR_DIR_TX) + { + if (lcCfg->lcType == CM_LTE_LCH_BCCH) + { + if (lcCfg->dlTrchType == CM_LTE_TRCH_DL_SCH) + { + if(cnt == 0) + { + bitMask |= RGSCH_BCCH_DLSCH_CFG1; + cnt++; + } + else + { + + if(( + (cellCfg->siCfg.siWinSize == 1) || + (cellCfg->siCfg.siWinSize == 2) || + (cellCfg->siCfg.siWinSize == 5) || + (cellCfg->siCfg.siWinSize == 10) || + (cellCfg->siCfg.siWinSize == 15) || + (cellCfg->siCfg.siWinSize == 20) || + (cellCfg->siCfg.siWinSize == 40)) && + (cellCfg->siCfg.retxCnt>0) + ) + { + bitMask |= RGSCH_BCCH_DLSCH_CFG2; + } + else + { + RLOG_ARG0(L_ERROR,DBG_CELLID,cellCfg->cellId, + "Invalid si config for cell"); + RETVALUE(RFAILED); + } + } + } + else if (lcCfg->dlTrchType == CM_LTE_TRCH_BCH) + { + bitMask |= RGSCH_BCCH_BCH_CFG; + } + else + { + RLOG_ARG1(L_ERROR,DBG_CELLID, cellCfg->cellId, + "Invalid transport channel %d for cell", lcCfg->dlTrchType); + RETVALUE(RFAILED); + } + } + else if (lcCfg->lcType == CM_LTE_LCH_PCCH) + { + bitMask |= RGSCH_PCCH_CFG; + } + else if (lcCfg->lcType == CM_LTE_LCH_CCCH) + { + bitMask |= RGSCH_DL_CCCH_CFG; + } + dirVld = TRUE; + } + + /* Validate uplink info */ + if (lcCfg->dir & RGR_DIR_RX) + { + /* Uplink CCCH */ + if (lcCfg->lcType != CM_LTE_LCH_CCCH) + { + RLOG_ARG1(L_ERROR,DBG_CELLID, cellCfg->cellId,"Invalid UL common lcType %d " + "for cell", lcCfg->lcType); + RETVALUE(RFAILED); + } + else + { + bitMask |= RGSCH_UL_CCCH_CFG; + } + dirVld = TRUE; + } + + /* Invalid direction */ + if (!dirVld) + { + RLOG_ARG1(L_ERROR,DBG_CELLID, cellCfg->cellId,"Invalid Direction %d", + lcCfg->dir); + RETVALUE(RFAILED); + } + } + if (bitMask != RGSCH_CELL_ACTIVE_CFG) + { + RLOG_ARG0(L_ERROR,DBG_CELLID, cellCfg->cellId, + "Invalid Common channel config for cell"); + RETVALUE(RFAILED); + } + + RETVALUE(ROK); +} /* rgSCHCfgVldtRgrCmnLcCfg */ + + +/*********************************************************** + * + * Func : rgSCHCfgVldtUeCqiModeCfg + * + * + * Desc : Validates UE CQI modes Configuration recieved from RRC. + * + * Ret : S16 + * ROK - Success + * RFAILED - Failed + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PRIVATE S16 rgSCHCfgVldtUeCqiModeCfg +( +RgSchCellCb *cell, +RgrUeDlCqiCfg *ueDlCqiCfg +) +#else +PRIVATE S16 rgSCHCfgVldtUeCqiModeCfg(cell, ueDlCqiCfg) +RgSchCellCb *cell; +RgrUeDlCqiCfg *ueDlCqiCfg; +#endif +{ + + TRC2(rgSCHCfgVldtUeCqiModeCfg) + +#ifndef TFU_UPGRADE + if((ueDlCqiCfg->prdCqiCfg.cqiPmiCfgIdx < 1) || + (ueDlCqiCfg->prdCqiCfg.cqiPmiCfgIdx > 1024)) + { + RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId, + "Invalid Periodic CQI Info"); + RETVALUE(RFAILED); + } +#endif + /* Validate UE Aperiodic CQI mode */ + if ((ueDlCqiCfg->aprdCqiCfg.pres == TRUE) && + ((ueDlCqiCfg->aprdCqiCfg.aprdModeEnum > RGR_APRD_CQI_MOD31) || + (cell->bwCfg.dlTotalBw <= 7))) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId, + "Invalid Aperiodic mode config for DL CQI", + ueDlCqiCfg->aprdCqiCfg.aprdModeEnum); + RETVALUE(RFAILED); + } +#ifndef TFU_UPGRADE + /* Validate UE Periodic CQI mode */ + if (ueDlCqiCfg->prdCqiCfg.prdModeEnum > RGR_PRD_CQI_MOD21) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId, + "Invalid periodic mode config for DL CQI", + ueDlCqiCfg->prdCqiCfg.prdModeEnum); + RETVALUE(RFAILED); + } + /* Validate K value in periodic CQI Config */ + if(((ueDlCqiCfg->prdCqiCfg.prdModeEnum == RGR_PRD_CQI_MOD20) || + (ueDlCqiCfg->prdCqiCfg.prdModeEnum == RGR_PRD_CQI_MOD21)) && + ((ueDlCqiCfg->prdCqiCfg.k < 1)|| + (ueDlCqiCfg->prdCqiCfg.k > 4))) + { + RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId, + "Invalid K for Subband CQI reporting"); + RETVALUE(RFAILED); + } +#else + if ((ueDlCqiCfg->prdCqiCfg.type == 1) && + (ueDlCqiCfg->prdCqiCfg.cqiSetup.prdModeEnum > RGR_PRD_CQI_MOD21)) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId, + "Invalid periodic mode config for DL CQI", + ueDlCqiCfg->prdCqiCfg.cqiSetup.prdModeEnum); + RETVALUE(RFAILED); + } + +#endif + + RETVALUE(ROK); + +} +/*********************************************************** + * + * Func : rgSCHCfgVldtUeMeasGapAckNakRepCfg + * + * + * Desc : Validates UE Measurement Gap and Ack Nack Repetition Configuration recieved from RRC. + * + * Ret : S16 + * ROK - Success + * RFAILED - Failed + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PRIVATE S16 rgSCHCfgVldtUeMeasGapAckNakRepCfg +( +RgSchCellCb *cell, +RgrUeCfg *ueCfg +) +#else +PRIVATE S16 rgSCHCfgVldtUeMeasGapAckNakRepCfg(cell, ueCfg) +RgSchCellCb *cell; +RgrUeCfg *ueCfg; +#endif +{ + + TRC2(rgSCHCfgVldtUeMeasGapAckNakRepCfg) + +#ifdef LTE_TDD + if ((ueCfg->ackNackModeEnum == RGR_TDD_ACKNACK_MODE_MULT) && + (ueCfg->ueAckNackCfg.isAckNackEnabled == TRUE)) + { + RLOG_ARG2(L_ERROR,DBG_CELLID,ueCfg->cellId,"TDD ACK NACK Multiplexing Mode" + "is not allowed when Ack/Nack is Enabled: %d CRNTI:%d", + ueCfg->ueAckNackCfg.ackNackRepFactor,ueCfg->crnti); + RETVALUE(RFAILED); + } +#endif /* LTE_TDD */ + /* Validate AckNackRep Factor */ + if((ueCfg->ueAckNackCfg.isAckNackEnabled == FALSE) && + (!ueCfg->ueMesGapCfg.isMesGapEnabled)) + { + RETVALUE(ROK); + } + + if(ueCfg->ueAckNackCfg.isAckNackEnabled) + { + if ( (ueCfg->ueAckNackCfg.ackNackRepFactor < RGR_ACKNACK_REPFACT_N2) + || (ueCfg->ueAckNackCfg.ackNackRepFactor > RGR_ACKNACK_REPFACT_N6)) + { + RLOG_ARG2(L_ERROR,DBG_CELLID,ueCfg->cellId, "Invalid ACK NACK REP Factor:%d CRNTI:%d", + ueCfg->ueAckNackCfg.ackNackRepFactor,ueCfg->crnti); + RETVALUE(RFAILED); + } + } + if(ueCfg->ueMesGapCfg.isMesGapEnabled) + { + switch(ueCfg->ueMesGapCfg.gapPrd) + { + case RG_MEAS_GAPPRD_40: + if(ueCfg->ueMesGapCfg.gapOffst >= RG_MEAS_GAPPRD_40) + { + RLOG_ARG2(L_ERROR,DBG_CELLID,ueCfg->cellId,"Invalid GAP Offset:%d CRNTI:%d", + ueCfg->ueMesGapCfg.gapOffst,ueCfg->crnti); + RETVALUE(RFAILED); + } + break; + case RG_MEAS_GAPPRD_80: + if(ueCfg->ueMesGapCfg.gapOffst >= RG_MEAS_GAPPRD_80) + { + RLOG_ARG2(L_ERROR,DBG_CELLID,ueCfg->cellId,"Invalid GAP Offset:%d CRNTI:%d", + ueCfg->ueMesGapCfg.gapOffst,ueCfg->crnti); + RETVALUE(RFAILED); + } + break; + default: + { + RLOG_ARG2(L_ERROR,DBG_CELLID,ueCfg->cellId,"Invalid GAP Periodicity Settings:%d" + "CRNTI:%d", ueCfg->ueMesGapCfg.gapPrd,ueCfg->crnti); + RETVALUE(RFAILED); + } + } + } + + RETVALUE(ROK); +} /* rgSCHCfgVldtUeMeasGapAckNakRepCfg*/ + + +/*********************************************************** + * + * Func : rgSCHCfgVldtUeMeasGapAckNakRepRecfg + * + * + * Desc : Validates UE Measurement Gap and Ack Nack Repetition Configuration recieved from RRC. + * + * Ret : S16 + * ROK - Success + * RFAILED - Failed + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PRIVATE S16 rgSCHCfgVldtUeMeasGapAckNakRepRecfg +( +RgSchCellCb *cell, +RgrUeRecfg *ueRecfg +) +#else +PRIVATE S16 rgSCHCfgVldtUeMeasGapAckNakRepRecfg(cell, ueRecfg) +RgSchCellCb *cell; +RgrUeRecfg *ueRecfg; +#endif +{ + + TRC2(rgSCHCfgVldtUeMeasGapAckNakRepRecfg) + if((ueRecfg->ueAckNackRecfg.isAckNackEnabled == FALSE) && + (!ueRecfg->ueMeasGapRecfg.isMesGapEnabled)) + { + RETVALUE(ROK); + } + + if(ueRecfg->ueAckNackRecfg.isAckNackEnabled ) + { + /* Validate AckNackRep Factor */ + if ( (ueRecfg->ueAckNackRecfg.ackNackRepFactor < RGR_ACKNACK_REPFACT_N2) + || (ueRecfg->ueAckNackRecfg.ackNackRepFactor > RGR_ACKNACK_REPFACT_N6)) + { + RLOG_ARG2(L_ERROR,DBG_CELLID,ueRecfg->cellId,"Invalid ACK NACK REP Factor:%d" + "NEW CRNTI:%d",ueRecfg->ueAckNackRecfg.ackNackRepFactor,ueRecfg->newCrnti); + RETVALUE(RFAILED); + } + } + if(ueRecfg->ueMeasGapRecfg.isMesGapEnabled) + { + switch(ueRecfg->ueMeasGapRecfg.gapPrd) + { + case RG_MEAS_GAPPRD_40: + if(ueRecfg->ueMeasGapRecfg.gapOffst >= RG_MEAS_GAPPRD_40) + { + RLOG_ARG2(L_ERROR,DBG_CELLID,ueRecfg->cellId,"Invalid GAP Offset:%d" + "NEW CRNTI:%d",ueRecfg->ueMeasGapRecfg.gapOffst,ueRecfg->newCrnti); + RETVALUE(RFAILED); + } + break; + case RG_MEAS_GAPPRD_80: + if(ueRecfg->ueMeasGapRecfg.gapOffst >= RG_MEAS_GAPPRD_80) + { + RLOG_ARG2(L_ERROR,DBG_CELLID,ueRecfg->cellId,"Invalid GAP Offset:%d" + "NEW CRNTI:%d",ueRecfg->ueMeasGapRecfg.gapOffst,ueRecfg->newCrnti); + RETVALUE(RFAILED); + } + break; + default: + { + RLOG_ARG2(L_ERROR,DBG_CELLID,ueRecfg->cellId,"Invalid GAP Periodicity Settings:%d" + "NEW CRNTI:%d",ueRecfg->ueMeasGapRecfg.gapPrd,ueRecfg->newCrnti); + RETVALUE(RFAILED); + } + } + } + + RETVALUE(ROK); +} /* rgSCHCfgVldtUeMeasGapAckNakRepRecfg*/ + +#ifdef LTEMAC_SPS +/*********************************************************** + * + * Func : rgSCHCfgVldtUeDlSpsCfg + * + * + * Desc : Validates UE's DL SPS configuration recieved from RRC. + * + * Ret : S16 + * ROK - Success + * RFAILED - Failed + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PRIVATE S16 rgSCHCfgVldtUeDlSpsCfg +( +RgSchCellCb *cell, +RgrUeSpsDlCfg *dlSpsCfg +) +#else +PRIVATE S16 rgSCHCfgVldtUeDlSpsCfg(cell, dlSpsCfg) +RgSchCellCb *cell; +RgrUeSpsDlCfg *dlSpsCfg; +#endif +{ + + U8 idx = 0; + + TRC2(rgSCHCfgVldtUeDlSpsCfg); + + /* peridicity validation done in SPS module */ + if ((dlSpsCfg->numPucchVal > RG_SCH_MAX_NUM_N1PUCCH_PER_UE) || + (dlSpsCfg->numPucchVal == 0)) + { + RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,"Invalid number of n1Pucch values" + " in DL SPS Config"); + RETVALUE(RFAILED); + } + + for (idx = 0; idx < dlSpsCfg->numPucchVal; ++idx) + { + if (dlSpsCfg->n1PucchVal[idx] > RG_SCH_MAX_N1PUCCH_VAL) + { +#ifdef ALIGN_64BIT + RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,"Invalid N1Pucch value" + " in DL SPS Config %u", dlSpsCfg->n1PucchVal[idx]); +#else + RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,"Invalid N1Pucch value" + " in DL SPS Config %lu", dlSpsCfg->n1PucchVal[idx]); +#endif + RETVALUE(RFAILED); + } + } + /* SPS_TODO: check will change for TDD */ + if ((dlSpsCfg->numSpsHqProc == 0) || + (dlSpsCfg->numSpsHqProc > RGSCH_MAX_DL_HQ_PROC)) + { + RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,"Invalid number of SPS HARQ procs" + " in DL SPS Config"); + RETVALUE(RFAILED); + } + + RETVALUE(ROK); +} /* rgSCHCfgVldtDlSpsCfg */ +#endif /* LTEMAC_SPS */ + +/*********************************************************** + * + * Func : rgSCHCfgVldtUePwrCfg + * + * + * Desc : Validates UE Group power configuration recieved from RRC. + * + * Ret : S16 + * ROK - Success + * RFAILED - Failed + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PRIVATE S16 rgSCHCfgVldtUePwrCfg +( +RgSchCellCb *cell, +RgrUeUlPwrCfg *pwrCfg +) +#else +PRIVATE S16 rgSCHCfgVldtUePwrCfg(cell, pwrCfg) +RgSchCellCb *cell; +RgrUeUlPwrCfg *pwrCfg; +#endif +{ + + TRC2(rgSCHCfgVldtUePwrCfg); + + /* Group power control works only in accumulated mode */ + if (!pwrCfg->isAccumulated) + { + /* Fix */ + if (pwrCfg->uePuschPwr.pres) + { + RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,"Accumulation configutation" + " not in sync with group power configuration"); + RETVALUE(RFAILED); + } + } + + if (rgSCHCfgVldtUeGrpPwrCfg(cell, &pwrCfg->uePuschPwr) != ROK) + { + RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,"Invalid PUSCH Group power" + " configuration"); + RETVALUE(RFAILED); + } + if (rgSCHCfgVldtUeGrpPwrCfg(cell, &pwrCfg->uePucchPwr) != ROK) + { + RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,"Invalid PUSCH Group power" + " configuration"); + RETVALUE(RFAILED); + } + + RETVALUE(ROK); +} /* rgSCHCfgVldtUePwrCfg */ + +/*********************************************************** + * + * Func : rgSCHCfgVldtUeGrpPwrCfg + * + * + * Desc : Validates UE Group power configuration recieved from RRC. + * + * Ret : S16 + * ROK - Success + * RFAILED - Failed + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PRIVATE S16 rgSCHCfgVldtUeGrpPwrCfg +( +RgSchCellCb *cell, +RgrUeGrpPwrCfg *grpPwrCfg +) +#else +PRIVATE S16 rgSCHCfgVldtUeGrpPwrCfg(cell, grpPwrCfg) +RgSchCellCb *cell; +RgrUeGrpPwrCfg *grpPwrCfg; +#endif +{ + + TRC2(rgSCHCfgVldtUeGrpPwrCfg); + + if ((grpPwrCfg->pres) && + (((grpPwrCfg->tpcRnti > cell->rntiDb.rntiStart) && + ((grpPwrCfg->tpcRnti < + (cell->rntiDb.rntiStart + cell->rntiDb.maxRntis)))))) + { + RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,"Invalid Uplink Group power " + "configuration"); + RETVALUE(RFAILED); + } + + RETVALUE(ROK); +} /* rgSCHCfgVldtUeGrpPwrCfg */ + +#ifdef LTEMAC_SPS +/*********************************************************** + * + * Func : rgSCHCfgVldtSpsReCfg + * + * + * Desc : Validates UE SPS and other SPS dependent + * configuration recieved from RRC. + * + * Ret : S16 + * ROK - Success + * RFAILED - Failed + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PRIVATE S16 rgSCHCfgVldtSpsReCfg +( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgrUeRecfg *ueRecfg +) +#else +PRIVATE S16 rgSCHCfgVldtSpsReCfg(cell, ue, ueRecfg) +RgSchCellCb *cell; +RgSchUeCb *ue; +RgrUeRecfg *ueRecfg; +#endif +{ + + TRC2(rgSCHCfgVldtSpsReCfg); + if ((ueRecfg->ueRecfgTypes & RGR_UE_DLSPS_RECFG) && + (ueRecfg->ueSpsRecfg.dlSpsCfg.isDlSpsEnabled)) + { + /* Validating SPS RNTI */ + if (((ueRecfg->ueSpsRecfg.spsRnti >= cell->rntiDb.rntiStart) && + (ueRecfg->ueSpsRecfg.spsRnti<= + (cell->rntiDb.rntiStart+cell->rntiDb.maxRntis)))|| + (ueRecfg->ueSpsRecfg.spsRnti == RGSCH_SI_RNTI) || + (ueRecfg->ueSpsRecfg.spsRnti == RGSCH_P_RNTI)) + { + RLOG_ARG2(L_ERROR,DBG_CELLID,ueRecfg->cellId,"Invalid SPS RNTI " + " in DL SPS Recfg OLD CRNTI:%d NEW CCRNTI:%d", + ueRecfg->oldCrnti,ueRecfg->newCrnti); + RETVALUE(RFAILED); + } + if (rgSCHCfgVldtUeDlSpsCfg(cell, &ueRecfg->ueSpsRecfg.dlSpsCfg) != ROK) + { + RLOG_ARG2(L_ERROR,DBG_CELLID,ueRecfg->cellId,"Invalid DL SPS configuration" + " for the OLD CRNTI:%d NEW CRNTI:%d", + ueRecfg->oldCrnti,ueRecfg->newCrnti); + RETVALUE(RFAILED); + } + } + +#if RG_SPS_UNUSED + if(ueRecfg->ueSpsRecfg.dlSpsCfg.isDlSpsEnabled) + { + if (ueRecfg->ueRecfgTypes & RGR_UE_DRX_RECFG) + { + /* ccpu00117035 - MOD - changed instIdx to inst */ + /* ccpu00117035 - MOD - changed ueID to oldCrnti*/ + RLOG_ARG2(L_ERROR,DBG_CELLID,ueRecfg->cellId, + " DRX reconfig not supported DL SPS enabled for OLD CRNTI:%d NEW CRNTI:%d", + ueRecfg->oldCrnti,ueRecfg->newCrnti); + RETVALUE(RFAILED); + } + } +#endif +/* ccpu00117627 - ADD - SPS recfg validation against HDFDD */ +#ifdef LTEMAC_HDFDD + if(ueRecfg->ueSpsRecfg.dlSpsCfg.isDlSpsEnabled) + { + if(ue->hdFddEnbld == TRUE) + { + RLOG_ARG2(L_ERROR,DBG_CELLID,ueRecfg->cellId, + "DL SPS is not supported for HDFDD enabled for OLD CRNTI:%d NEW CRNTI:%d", + ueRecfg->oldCrnti,ueRecfg->newCrnti); + RETVALUE(RFAILED); + } + } + if(ueRecfg->ueSpsRecfg.ulSpsCfg.isUlSpsEnabled) + { + if(ue->hdFddEnbld == TRUE) + { + RLOG_ARG2(L_ERROR,DBG_CELLID,ueRecfg->cellId, + "UL SPS is not supported for HDFDD enabled for OLD CRNTI:%d NEW CRNTI:%d", + ueRecfg->oldCrnti,ueRecfg->newCrnti); + RETVALUE(RFAILED); + } + } +#endif + + RETVALUE(ROK); +} /*rgSCHCfgVldtSpsReCfg*/ +#endif + +#if ((defined (RGR_CQI_REPT)) && (defined (RGR_V2))) +/*********************************************************** + * + * Func : rgSCHCfgVldtCqiReptReCfg + * + * + * Desc : Validates UE CQI report for DL Power control + * configuration recieved from RRC. + * + * Ret : S16 + * ROK - Success + * RFAILED - Failed + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PRIVATE S16 rgSCHCfgVldtCqiReptReCfg +( +RgSchCellCb *cell, +RgrUeRecfg *ueRecfg +) +#else +PRIVATE S16 rgSCHCfgVldtCqiReptReCfg(cell, ueRecfg) +RgSchCellCb *cell; +RgrUeRecfg *ueRecfg; +#endif +{ + + TRC2(rgSCHCfgVldtCqiReptReCfg); + /* Validate DL Power Control Config parameters */ + if (ueRecfg->ueCqiReptCfg.numColltdCqiRept > RGR_CQIRPTS_MAXN) + { + RLOG_ARG3(L_ERROR,DBG_CELLID,ueRecfg->cellId,"Invalide numColltdCqiRept," + "MAX supported %d for OLD CRNTI:%d NEW CRNTI:%d",RGR_CQIRPTS_MAXN, + ueRecfg->oldCrnti,ueRecfg->newCrnti); + RETVALUE(RFAILED); + } + + RETVALUE(ROK); +} /*rgSCHCfgVldtCqiReptReCfg*/ +#endif + +/*********************************************************** + * + * Func : rgSCHCfgRgrLcChfg + * + * + * Desc : Handles dedicated logical channel configuration + * recieved from RRC. + * + * Ret : S16 + * ROK - Success + * RFAILED - Failed + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PUBLIC S16 rgSCHCfgRgrLchCfg +( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgrLchCfg *lcCfg, +RgSchErrInfo *errInfo +) +#else +PUBLIC S16 rgSCHCfgRgrLchCfg(cell, ue, lcCfg, errInfo) +RgSchCellCb *cell; +RgSchUeCb *ue; +RgrLchCfg *lcCfg; +RgSchErrInfo *errInfo; +#endif +{ + S16 ret; + RgSchDlLcCb *dlLc = NULLP; + Inst inst = cell->instIdx; +#ifdef LTE_L2_MEAS + RgSchUlLcCb *ulLc; +#endif + + TRC2(rgSCHCfgRgrLchCfg); + + errInfo->errCause = RGSCHERR_CFG_RGR_DED_LC_CFG; + + /* Allocate the downlink logical channel control block */ + if((ret = rgSCHUtlAllocSBuf(inst, (Data**)&dlLc, + sizeof(RgSchDlLcCb))) != ROK) + { + RLOG_ARG2(L_ERROR,DBG_CELLID,lcCfg->cellId,"Memory allocation FAILED for " + "Downlink LCId:%d CRNTI:%d", lcCfg->lcId,lcCfg->crnti); + RETVALUE(RFAILED); + } + if ((U8 *)dlLc == NULLP) + { + RLOG_ARG2(L_ERROR,DBG_CELLID,lcCfg->cellId,"Memory allocation FAILED for " + "Downlink LCID:%d CRNTI:%d", lcCfg->lcId,lcCfg->crnti); + RETVALUE(RFAILED); + } + dlLc->lcId = lcCfg->lcId; +#ifdef LTE_ADV + rgSCHLaaLcCfg(cell, dlLc, lcCfg); +#endif + + rgSCHDbmInsDlDedLcCb(ue, dlLc); + + ret = rgSCHUtlRgrLcCfg(cell, ue, dlLc, lcCfg, errInfo); + + if (ret != ROK) + { + /* ROLLBACK */ + if (dlLc) + { + rgSCHDbmDelDlDedLcCb(ue, dlLc); + rgSCHCfgFreeDlDedLcCb(cell, ue, dlLc); + } + + RLOG_ARG3(L_ERROR,DBG_CELLID,cell->cellId,"Dedicated logical channel " + "configuration failed at SCH:UEID:%d LCID:%d CRNTI:%d", + ue->ueId, lcCfg->lcId,lcCfg->crnti); + RETVALUE(RFAILED); + } +#ifdef LTE_L2_MEAS + RGSCH_ARRAY_BOUND_CHECK(inst, ue->ul.lcCb, (lcCfg->lcId -1)); + if ( !lcCfg->lcId || + (TRUE == ue->ul.lcCb[lcCfg->lcId -1].isValid)) + { + /* ROLLBACK */ + if (dlLc) + { + rgSCHDbmDelDlDedLcCb(ue, dlLc); + rgSCHCfgFreeDlDedLcCb(cell, ue, dlLc); + } + + RLOG_ARG3(L_ERROR,DBG_CELLID,cell->cellId,"Dedicated logical channel " + "configuration failed at SCH: UL LC CB already existing" + " UEID:%d LCID:%d CRNTI:%d", + ue->ueId, lcCfg->lcId,lcCfg->crnti); + RETVALUE(RFAILED); + } + + /* Create UL LC context to maintain LCG to LC mapping and + LC and QCI mapping, this is for L2 Counters :UL ACTIVE UE + PER QCI */ + ue->ul.lcCb[lcCfg->lcId -1].isValid = TRUE; + ulLc = &(ue->ul.lcCb[lcCfg->lcId -1]); + + ulLc->lcId = lcCfg->lcId; + ulLc->qciCb = &(cell->qciArray[lcCfg->dlInfo.dlQos.qci]); + ulLc->qciCb->qci = lcCfg->dlInfo.dlQos.qci; + ue->ul.lcgArr[lcCfg->lcgId].lcArray[ue->ul.lcgArr[lcCfg->lcgId].numLch] = ulLc; + ulLc->lcg = &ue->ul.lcgArr[lcCfg->lcgId]; + ulLc->lcgArrIdx = ue->ul.lcgArr[lcCfg->lcgId].numLch; + ue->ul.lcgArr[lcCfg->lcgId].numLch++; + + dlLc->qciCb = &(cell->qciArray[lcCfg->dlInfo.dlQos.qci]); + dlLc->qciCb->qci = lcCfg->dlInfo.dlQos.qci; + if(lcCfg->lcType == CM_LTE_LCH_DTCH) + { + rgSchAddToL2Meas(cell,dlLc); /*LTE_L2_MEAS_PHASE2*/ + } +#endif /* LTE_L2_MEAS */ + + RETVALUE(ROK); +} /* rgSCHCfgRgrLchCfg */ + +/*********************************************************** + * + * Func : rgSCHCfgRgrLcgCfg + * + * + * Desc : Handles dedicated logical channel group configuration + * recieved from RRM. + * + * Ret : S16 + * ROK - Success + * RFAILED - Failed + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PUBLIC S16 rgSCHCfgRgrLcgCfg +( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgrLcgCfg *lcgCfg, +RgSchErrInfo *errInfo +) +#else +PUBLIC S16 rgSCHCfgRgrLcgCfg(cell, ue, lcgCfg, errInfo) +RgSchCellCb *cell; +RgSchUeCb *ue; +RgrLcgCfg *lcgCfg; +RgSchErrInfo *errInfo; +#endif +{ + S16 ret = ROK; + +#ifdef RG_UNUSED +//#ifdef LTE_L2_MEAS + U32 idx; + RgSchUlLcCb *ulLc; +#endif + TRC2(rgSCHCfgRgrLcgCfg); + + errInfo->errCause = RGSCHERR_CFG_RGR_DED_LCG_CFG; + + ue->ul.lcgArr[lcgCfg->ulInfo.lcgId].lcgId = lcgCfg->ulInfo.lcgId; + + ret = rgSCHUtlRgrLcgCfg(cell, ue, lcgCfg, errInfo); + if (ret != ROK) + { + RLOG_ARG3(L_ERROR,DBG_CELLID,cell->cellId,"Dedicated logical channel " + "configuration failed at SCH: UEID:%d LCGID:%d CRNTI:%d", + ue->ueId, lcgCfg->ulInfo.lcgId,lcgCfg->crnti); + /* Roll back lcgCfg */ + ue->ul.lcgArr[lcgCfg->ulInfo.lcgId].lcgId = RGSCH_INVALID_LCG_ID; + rgSCHUtlRgrLcgDel(cell, ue, lcgCfg->ulInfo.lcgId); + RETVALUE(RFAILED); + } +#ifdef RG_UNUSED +//#ifdef LTE_L2_MEAS + /* Copy all info of UL LCH in cfg to ulLcgCb */ + for (idx = 0; idx < lcgCfg->ulInfo.numLch; idx++) + { + /* Allocate the uplink logical channel control block */ + if((ret = rgSCHUtlAllocSBuf(cell->instIdx, (Data**)&ulLc, + sizeof(RgSchUlLcCb))) != ROK) + { + RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId, "Memory allocation FAILED for "); + RETVALUE(RFAILED); + } + if ((U8 *)ulLc == NULLP) + { + RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId, "Memory allocation FAILED for "); + RETVALUE(RFAILED); + } + /* Create UL LC context to maintain LCG to LC mapping and + LC and QCI mapping, this is for L2 Counters :UL ACTIVE UE + PER QCI */ + ulLc->lcId = lcgCfg->ulInfo.lchUlCfg[idx].lcId; + ulLc->qciCb = &(cell->qciArray[lcgCfg->ulInfo.lchUlCfg[idx].qci]); + ulLc->qciCb->qci = lcgCfg->ulInfo.lchUlCfg[idx].qci; + ue->ul.lcgArr[lcgCfg->ulInfo.lcgId].lcArray[idx] = ulLc; + /* L2_COUNTERS */ + ue->ul.lcCb[ulLc->lcId -1] = ulLc; + ulLc->lcg = &ue->ul.lcgArr[lcgCfg->ulInfo.lcgId]; + ulLc->lcgArrIdx = idx; + } + ue->ul.lcgArr[lcgCfg->ulInfo.lcgId].numLch = lcgCfg->ulInfo.numLch; +#endif /* LTE_L2_MEAS */ + + RETVALUE(ROK); +} /* rgSCHCfgRgrLcgCfg */ + + + +/*********************************************************** + * + * Func : rgSCHCfgRgrCmnLcCfg + * + * + * Desc : Handles dedicated logical channel configuration + * recieved from RRC. + * + * Ret : S16 + * ROK - Success + * RFAILED - Failed + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PRIVATE S16 rgSCHCfgRgrCmnLcCfg +( +RgSchCellCb *cell, +RgrCmnLchCfg *lcCfg, +RgSchErrInfo *errInfo +) +#else +PRIVATE S16 rgSCHCfgRgrCmnLcCfg(cell, lcCfg, errInfo) +RgSchCellCb *cell; +RgrCmnLchCfg *lcCfg; +RgSchErrInfo *errInfo; +#endif +{ + RgSchClcDlLcCb cmnLcCb; + TRC2(rgSCHCfgRgrCmnLcCfg); + + errInfo->errCause = RGSCHERR_CFG_RGR_CMN_LC_CFG; + + cmMemset((U8 *)&cmnLcCb, 0, sizeof(cmnLcCb)); + + /* Handle configuration for CCCH/BCCH/PCCH */ + if (lcCfg->lcType == CM_LTE_LCH_CCCH) + { + /* UL and DL CCCH configuration */ + if (lcCfg->dir & RGR_DIR_TX) + { + cell->dlCcchId = lcCfg->lcId; + } + + if (lcCfg->dir & RGR_DIR_RX) + { + cell->ulCcchId = lcCfg->lcId; + } + } + else + { + cmnLcCb.lcId = lcCfg->lcId; + rgSCHDbmInitCmnLcBoLst(&cmnLcCb); + if (lcCfg->lcType == CM_LTE_LCH_BCCH) + { + /* BCCH on BCH and DLSCH configuration */ + if (lcCfg->dlTrchType == CM_LTE_TRCH_DL_SCH) + { + rgSCHDbmInsBcchOnDlsch(cell, &cmnLcCb); + } + else + { + rgSCHDbmInsBcchOnBch(cell, &cmnLcCb); + } + } + else /* PCCH configuration */ + { + rgSCHDbmInsPcch(cell, &cmnLcCb); + } + } + + RETVALUE(ROK); +} /* rgSCHCfgRgrCmnLcCfg */ + + + +/*********************************************************** + * + * Func : rgSCHCfgFreeDlDedLcCb + * + * + * Desc : + * - Processing Steps: + * - Frees downlink dedicated logical channel control block. + * + * Ret : Void + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PRIVATE Void rgSCHCfgFreeDlDedLcCb +( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgSchDlLcCb *dlLc +) +#else +PRIVATE Void rgSCHCfgFreeDlDedLcCb(cell, ue, dlLc) +RgSchCellCb *cell; +RgSchUeCb *ue; +RgSchDlLcCb *dlLc; +#endif +{ + Inst inst = cell->instIdx; + TRC2(rgSCHCfgFreeDlDedLcCb); + + rgSCHUtlFreeDlLc(cell, ue, dlLc); + + /* De-allocate the Cb */ + /* ccpu00117052 - MOD - Passing double pointer + for proper NULLP assignment*/ + rgSCHUtlFreeSBuf(inst, (Data **)&dlLc, sizeof(*dlLc)); + + + /* Stack Crash problem for TRACE5 changes. Added the return below */ + RETVOID; + +} /* rgSCHCfgFreeDlDedLcCb */ + + +/*********************************************************** + * + * Func : rgSCHCfgFreeDlCmnLcCb + * + * + * Desc : + * - Processing Steps: + * - Frees downlink common logical channel control block. + * + * Ret : Void + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PRIVATE Void rgSCHCfgFreeDlCmnLcCb +( +RgSchClcDlLcCb *cmnDlLc +) +#else +PRIVATE Void rgSCHCfgFreeDlCmnLcCb(cmnDlLc) +RgSchClcDlLcCb *cmnDlLc; +#endif +{ + TRC2(rgSCHCfgFreeDlCmnLcCb); + + cmMemset((U8*)cmnDlLc, 0, sizeof(*cmnDlLc)); + cmnDlLc->lcId = RGSCH_INVALID_LC_ID; + RETVOID; +} /* rgSCHCfgFreeDlCmnLcCb */ + + +/*********************************************************** + * + * Func : rgSCHCfgFreeCellCb + * + * + * Desc : + * - Processing Steps: + * - Frees scheduler cell control block. + * + * Ret : Void + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PUBLIC Void rgSCHCfgFreeCellCb +( +RgSchCellCb *cell +) +#else +PUBLIC Void rgSCHCfgFreeCellCb(cell) +RgSchCellCb *cell; +#endif +{ + Inst inst = cell->instIdx; + CmLList *node; + Buffer *pdu; + RgSchWarningSiInfo *warningSi; + RgSchWarningSiPdu *warningSiPdu; + U8 idx; + + TRC2(rgSCHCfgFreeCellCb); + /* ccpu00132385- SI Warning PDUs which are not processed need to be deleted */ + /* Search for used index in WarningSi */ + for(idx = 0; idx < RGR_MAX_NUM_WARNING_SI; idx++) + { + if(cell->siCb.warningSi[idx].siId == 0) + continue; + cell->siCb.siCtx.siId = cell->siCb.warningSi[idx].siId; + warningSi = (RgSchWarningSiInfo *) cell->siCb. + siArray[cell->siCb.siCtx.siId-1].si; + if(warningSi != NULLP) + { + /* ccpu00136659: CMAS ETWS design change */ + while (CM_LLIST_FIRST_NODE(&warningSi->warningSiMsg.segLstCp, node)) + { + warningSiPdu = (RgSchWarningSiPdu *)node->node; + pdu = warningSiPdu->pdu; + /* ccpu00136659: CMAS ETWS design change */ + cmLListDelFrm(&warningSi->warningSiMsg.segLstCp, node); + RGSCH_FREE_MSG(pdu); + } + cell->siCb.siArray[cell->siCb.siCtx.siId-1].si = NULLP; + } + } + /* Free lists of the cell */ + rgSCHCfgFreeUeLst(cell); +#ifdef LTEMAC_SPS + rgSCHCfgFreeSpsUeLst(cell); +#endif /* LTEMAC_SPS */ +#ifdef EMTC_ENABLE + if ( TRUE == cell->emtcEnable ) + { + rgSCHEmtcCellDel(cell); + } +#endif + rgSCHRamFreeCell(cell); + + rgSCHDbmRntiDbDeInit(cell); + /* Deallocate the subframe allocation information */ + rgSCHUtlPutSfAlloc(cell); + rgSCHUtlFreeCell(cell); + + rgSCHCfgFreeRgrCfgLst(cell); + rgSCHCfgFreeCmnLcLst(cell); + + rgSCHUtlPutRlsHqAlloc(cell); + +#ifdef LTE_TDD + rgSCHDbmDeInitUeTfuPendLst(cell); +#endif /* LTE_TDD */ + +#ifdef RGR_SI_SCH + rgSCHUtlPutSiInfo(cell); +#endif/*RGR_SI_SCH*/ + + (Void)rgSCHDrxCellDel(cell); + + rgSCHUtlFreeSBuf(inst, (Data**)&(cell->dynCfiCb.cceFailSamples), + (cell->dynCfiCb.numFailSamples * sizeof(U16))); + +#ifdef TENB_STATS + TSL2DeallocCellStatsBlk(cell->cellId); +#endif + +#ifdef LTE_ADV + /* LAA_SCELL: Trigger the De-Init function for the LAA Module */ + rgSCHLaaSCellCbDeInit(cell); +#endif + +#ifdef EMTC_ENABLE + if(cell->emtcEnable) + { + rgSCHEmtcCellFree(cell); + } +#endif + /* De-allocate the Cell */ + /* ccpu00117052 - MOD - Passing double pointer + for proper NULLP assignment*/ + rgSCHUtlFreeSBuf(inst, (Data **)&cell, sizeof(*cell)); + + + + /* Stack Crash problem for TRACE5 changes. Added the return below */ + RETVOID; + +} /* rgSCHCfgFreeCellCb */ + + +/*********************************************************** + * + * Func : rgSCHCfgFreeUeCb + * + * + * Desc : + * - Processing Steps: + * - Frees UE control block. + * + * Ret : Void + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PRIVATE Void rgSCHCfgFreeUeCb +( +RgSchCellCb *cell, +RgSchUeCb *ue +) +#else +PRIVATE Void rgSCHCfgFreeUeCb(cell, ue) +RgSchCellCb *cell; +RgSchUeCb *ue; +#endif +{ + RgSchCmnUlUe *ueUl = RG_SCH_CMN_GET_UL_UE(ue, cell); + RgUeUlHqCb *ulHqEnt; + RgSchDlLcCb *dlLc; + Inst inst = cell->instIdx; + U8 lcCnt; + U8 lcgId; + TRC2(rgSCHCfgFreeUeCb); + + /* Free all logical channel info per UE */ + while((dlLc = rgSCHDbmGetNextDlDedLcCb(ue, NULLP)) != NULLP) + { + rgSCHDbmDelDlDedLcCb(ue, dlLc); + rgSCHCfgFreeDlDedLcCb(cell, ue, dlLc); + } + for (lcCnt =0; lcCntul.lcCb[lcCnt].isValid == TRUE) + { + lcgId = ue->ul.lcCb[lcCnt].lcg->lcgId; + if (lcgId <=3) + { + rgSCHUtlRgrLcDel(cell, ue, ue->ul.lcCb[lcCnt].lcId,lcgId); + ue->ul.lcCb[lcCnt].isValid = FALSE; + } + } + } + + ulHqEnt = &(ueUl->hqEnt); + /* Free Scheduler specific information per UE */ + rgSCHUtlFreeUe(cell, ue); + + /* Free Uplink HARQ specific information per UE */ + rgSCHUhmFreeUe(cell, ulHqEnt); + + if ( ue->drxCb != NULLP) + { + /* free drxCb */ + /* ccpu00117052 - MOD - Passing double pointer + for proper NULLP assignment*/ + rgSCHUtlFreeSBuf(cell->instIdx, + (Data**)(&(ue->drxCb)), + sizeof(RgSchDrxUeCb)); + } + + ue->drxCb = (RgSchDrxUeCb *)NULLP; + /* Free Downlink HARQ specific information per UE */ + rgSCHDhmFreeUe(ue); + /* Release the RNTI */ + if (ue->rntiLnk) + { + rgSCHUtlRlsRnti(cell, ue->rntiLnk, FALSE, 0); + } + else + { + /* Fix : syed HO UE does not have a valid ue->rntiLnk */ + /* Just indicate to MAC, no need to release at SCH */ + rgSCHUtlIndRntiRls2Mac(cell, ue->ueId, FALSE, 0); + } +/* rg009.201. Added changes of TFU_UPGRADE */ +#ifdef TFU_UPGRADE + rgSCHCfgPCqiSrsSrUeDel(cell,ue); +#endif +#ifdef LTEMAC_HDFDD + rgSCHHdFddUeDel(cell, ue); +#endif +#ifdef TENB_STATS + if (ue->tenbStats) + { + TSL2DeallocUeStatsBlk(ue->ueId, ue->tenbStats); + } +#endif + + /* CA TODO Some handling needed while SCell Delete*/ +#ifdef LTE_ADV + /* Delete the UE from the PCell secCellActCeLst*/ + rgSCHSCellRmvFrmActLst(cell, ue); + rgSCHSCellDelUe(cell,ue); +#endif + +#ifdef LTE_ADV + rgSCHLaaDeInitDlRbAllocCb(cell, &ue->cellInfo[RGSCH_PCELL_INDEX]->dlAllocCb); +#endif + + rgSCHUtlFreeSBuf(inst, (Data **)&ue->cellInfo[0], sizeof(RgSchUeCellInfo)); + /* De-allocate the Ue */ + /* ccpu00117052 - MOD - Passing double pointer + for proper NULLP assignment*/ +#ifdef EMTC_ENABLE + if(ue->isEmtcUe) + { + rgSCHEmtcUeInfoFree(cell, ue); + } +#endif + rgSCHUtlFreeSBuf(inst, (Data **)&ue, sizeof(*ue)); + + /* Stack Crash problem for TRACE5 changes. Added the return below */ + RETVOID; + +} /* rgSCHCfgFreeUeCb */ + +/*********************************************************** + * + * Func : rgSCHCfgFreeRgrCfgLst + * + * + * Desc : + * - Processing Steps: + * - Frees configuration lists in cell control block. + * + * Ret : Void + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PRIVATE Void rgSCHCfgFreeRgrCfgLst +( +RgSchCellCb *cell +) +#else +PRIVATE Void rgSCHCfgFreeRgrCfgLst(cell) +RgSchCellCb *cell; +#endif +{ + RgSchCfgElem *rgCfgElem; + Inst inst = cell->instIdx; + + TRC2(rgSCHCfgFreeRgrCfgLst); + + /* Free CURRENT RGR cfg list */ + while ((rgCfgElem = rgSCHDbmGetNextCrntRgrCfgElem(cell, NULLP)) != NULLP) + { + rgSCHDbmDelCrntRgrCfgElem(cell, rgCfgElem); + /* ccpu00117052 - MOD - Passing double pointer + for proper NULLP assignment*/ + rgSCHUtlFreeSBuf(inst, (Data **)&rgCfgElem, sizeof(*rgCfgElem)); + } + + /* Free PENDING RGR cfg list */ + while ((rgCfgElem = rgSCHDbmGetNextPndngRgrCfgElem(cell, NULLP)) != NULLP) + { + rgSCHDbmDelPndngRgrCfgElem(cell, rgCfgElem); + /* ccpu00117052 - MOD - Passing double pointer + for proper NULLP assignment*/ + rgSCHUtlFreeSBuf(inst, (Data **)&rgCfgElem, sizeof(*rgCfgElem)); + } + + + /* Stack Crash problem for TRACE5 changes. Added the return below */ + RETVOID; + +} /* rgSCHCfgFreeRgrCfgLst */ + + +/*********************************************************** + * + * Func : rgSCHCfgFreeCmnLcLst + * + * + * Desc : + * - Processing Steps: + * - Frees common logical channels in cell control block. + * + * Ret : Void + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PRIVATE Void rgSCHCfgFreeCmnLcLst +( +RgSchCellCb *cell +) +#else +PRIVATE Void rgSCHCfgFreeCmnLcLst(cell) +RgSchCellCb *cell; +#endif +{ + RgSchClcDlLcCb *dlCmnLc; + + TRC2(rgSCHCfgFreeCmnLcLst); + + if ((dlCmnLc = rgSCHDbmGetBcchOnBch(cell)) != NULLP) + { + rgSCHCfgFreeDlCmnLcCb(dlCmnLc); + } + if ((dlCmnLc = rgSCHDbmGetFirstBcchOnDlsch(cell)) != NULLP) + { + rgSCHCfgFreeDlCmnLcCb(dlCmnLc); + } + if ((dlCmnLc = rgSCHDbmGetSecondBcchOnDlsch(cell)) != NULLP) + { + rgSCHCfgFreeDlCmnLcCb(dlCmnLc); + } + if ((dlCmnLc = rgSCHDbmGetPcch(cell)) != NULLP) + { + rgSCHCfgFreeDlCmnLcCb(dlCmnLc); + } + + + /* Stack Crash problem for TRACE5 changes. Added the return below */ + RETVOID; + +} /* rgSCHCfgFreeCmnLcLst */ + + +/*********************************************************** + * + * Func : rgSCHCfgFreeUeLst + * + * + * Desc : + * - Processing Steps: + * - Frees UE list in cell control block. + * + * Ret : Void + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PRIVATE Void rgSCHCfgFreeUeLst +( +RgSchCellCb *cell +) +#else +PRIVATE Void rgSCHCfgFreeUeLst(cell) +RgSchCellCb *cell; +#endif +{ + RgSchUeCb *ue; +#ifdef LTE_ADV + RgSchUeCellInfo *sCellInfo; + CmLList *node; +#endif + TRC2(rgSCHCfgFreeUeLst); + + /* Free Ues in the list */ + while ((ue = rgSCHDbmGetNextUeCb(cell, NULLP)) != NULLP) + { + rgSCHDbmDelUeCb(cell, ue); + +#ifdef LTE_ADV + if(ue->cell != cell) + { + continue; + } +#endif + + /* Call MeasGap and AckNakRep processing module */ + rgSCHMeasGapANRepUeDel(cell, ue, TRUE); + + rgSCHCfgFreeUeCb(cell, ue); + } + + /* De-initialize the Ue list */ + rgSCHDbmDeInitUeCbLst(cell); + + +#ifdef LTE_ADV + node = cell->sCellUeLst.first; + while(node) + { + sCellInfo = (RgSchUeCellInfo *)node->node; + node = node->next; + rgSCHSCellDelUeSCell(sCellInfo->ue->cell, sCellInfo->ue, sCellInfo->sCellIdx); + } +#endif + + /* Stack Crash problem for TRACE5 changes. Added the return below */ + RETVOID; + +} /* rgSCHCfgFreeUeLst */ + +#ifdef LTEMAC_SPS +/*********************************************************** + * + * Func : rgSCHCfgFreeSpsUeLst + * + * + * Desc : + * - Processing Steps: + * - Frees Sps UE list in cell control block. + * + * Ret : Void + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PRIVATE Void rgSCHCfgFreeSpsUeLst +( +RgSchCellCb *cell +) +#else +PRIVATE Void rgSCHCfgFreeSpsUeLst(cell) +RgSchCellCb *cell; +#endif +{ + RgSchUeCb *ue; + + TRC2(rgSCHCfgFreeSpsUeLst); + + /* Free Ues in the list */ + while ((ue = rgSCHDbmGetNextSpsUeCb(cell, NULLP))) + { + rgSCHDbmDelSpsUeCb(cell, ue); + } + + /* De-initialize the Ue list */ + rgSCHDbmDeInitSpsUeCbLst(cell); + +} /* rgSCHCfgFreeSpsUeLst */ + +#endif /* LTEMAC_SPS */ + +#ifdef RGR_SI_SCH +/*********************************************************** + * + * Func : rgSCHCfgVldtRgrCellSiCfg + * + * Desc : Validates SI Configuration for SI + * + * Ret : S16 + * ROK - Success + * RFAILED - Failed + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PRIVATE S16 rgSCHCfgVldtRgrCellSiCfg +( +Inst inst, +RgrSiCfg *siCfg +) +#else +PRIVATE S16 rgSCHCfgVldtRgrCellSiCfg(inst, siCfg) +Inst inst; +RgrSiCfg *siCfg; +#endif +{ + U8 idx; /* idx for iteration */ + + UNUSED(inst); + + TRC2(rgSCHCfgVldtRgrCellSiCfg); + + +#ifndef LTE_TDD + /* Check that retxCnt value should be <= value of siWinSize. + This validation is only applicable for FDD mode. */ + if(siCfg->retxCnt > siCfg->siWinSize) + { + RLOG0(L_ERROR,"retxCnt is greater than siWinSize, validation failed"); + RETVALUE(RFAILED); + } +#endif + + /* Validate that a valid value for numSi has been specified */ + if(siCfg->numSi > RGR_MAX_NUM_SI) + { + RLOG0(L_ERROR,"Validation for numSi in SI CFG failed"); + RETVALUE(RFAILED); + } + + /* MinPeriodicity will have the least configured periodicity + * Hence initializing with Max periodicity */ + siCfg->minPeriodicity = RGR_SI_PERD_512; + + /*Validate the value of periodicity specified for SIs */ + for(idx = 0;idx < siCfg->numSi;idx++) + { + siCfg->minPeriodicity = RGSCH_MIN(siCfg->minPeriodicity, + siCfg->siPeriodicity[idx]); + /* Set the siPeriodicity as a multiple of 80 subframes */ + switch(siCfg->siPeriodicity[idx]) + { + case RGR_SI_PERD_8: + case RGR_SI_PERD_16: + case RGR_SI_PERD_32: + case RGR_SI_PERD_64: + case RGR_SI_PERD_128: + case RGR_SI_PERD_256: + case RGR_SI_PERD_512: + continue; + + default: + RLOG0(L_ERROR,"Validation for SI Periodicity in SI-CFG failed"); + RETVALUE(RFAILED); + } + } + + RETVALUE(ROK); +} /* rgSCHCfgVldtRgrCellSiCfg */ + +/* LTE_ADV_FLAG_REMOVED_START */ +/*********************************************************** + * + * Func : rgSCHCfgVldtRgrCellLtrAdvCfg + * + * Desc : Validates Lte Adv Configuration + * + * Ret : S16 + * ROK - Success + * RFAILED - Failed + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PRIVATE S16 rgSCHCfgVldtRgrCellLteAdvCfg +( + Inst inst, + RgrLteAdvancedCellConfig *lteAdvCfg, + U8 dlTotalBw + ) +#else +PRIVATE S16 rgSCHCfgVldtRgrCellLteAdvCfg(inst, lteAdvCfg, dlTotalBw) + Inst inst; + RgrLteAdvancedCellConfig *lteAdvCfg; + U8 dlTotalBw; +#endif +{ + U8 temp[RGR_ABS_PATTERN_LEN]; + U32 idx; + UNUSED(inst); + + TRC2(rgSCHCfgVldtRgrCellLteAdvCfg); + + + if((lteAdvCfg->pres & RGR_SFR) && (RGR_ENABLE == lteAdvCfg->sfrCfg.status)) + { + if(lteAdvCfg->sfrCfg.cellEdgeRbRange.startRb > lteAdvCfg->sfrCfg.cellEdgeRbRange.endRb) + { + RLOG0(L_ERROR,"Invalid configuration of cell edge bandwidth for SFR feature"); + RETVALUE(RFAILED); + } + + if(lteAdvCfg->sfrCfg.cellEdgeRbRange.endRb >= dlTotalBw) + { + RLOG0(L_ERROR,"Invalid configuration of cell edge end RB for SFR feature"); + RETVALUE(RFAILED); + } + +#ifdef TFU_UPGRADE + if(lteAdvCfg->sfrCfg.pwrThreshold.pLow >= lteAdvCfg->sfrCfg.pwrThreshold.pHigh) + { + RLOG0(L_ERROR,"Invalid configuration of power threshold for SFR feature"); + RETVALUE(RFAILED); + } +#endif + } + + if((lteAdvCfg->pres & RGR_ABS) && (RGR_ENABLE == lteAdvCfg->absCfg.status)) + { + if((RGR_ABS_MUTE != lteAdvCfg->absCfg.absPatternType) && + (RGR_ABS_TRANSMIT != lteAdvCfg->absCfg.absPatternType)) + { + RLOG0(L_ERROR,"Invalid configuration of ABS pattern type"); + RETVALUE(RFAILED); + } + + cmMemcpy(temp, (U8 *) lteAdvCfg->absCfg.absPattern,RGR_ABS_PATTERN_LEN); + + /* Added validation for ABS pattern len */ + for(idx = 0; idx < RGR_ABS_PATTERN_LEN; idx++) + { + if((temp[idx] != 1) && (temp[idx] != 0)) + { + RLOG0(L_ERROR,"Invalid configuration of ABS pattern type"); + RETVALUE(RFAILED); + } + } + } + + RETVALUE(ROK); +} +/* LTE_ADV_FLAG_REMOVED_END */ + + +/*********************************************************** + * + * Func : rgSCHCfgVldtRgrCellCsgParamCfg + * + * Desc : Validates CSG Parameter Configuration + * + * Ret : S16 + * ROK - Success + * RFAILED - Failed + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PRIVATE S16 rgSCHCfgVldtRgrCellCsgParamCfg +( +Inst inst, +RgrCellCsgParamCfg *csgParam +) +#else +PRIVATE S16 rgSCHCfgVldtRgrCellCsgParamCfg(inst, csgParam) +Inst inst; +RgrCellCsgParamCfg *csgParam; +#endif +{ + + TRC2(rgSCHCfgVldtRgrCellCsgParamCfg); + + RGSCHDBGPRM(inst, (rgSchPBuf(inst), "Validating CSG Parameters \n")); + + if(csgParam->minDlResNonCsg > 100) + { + RLOG0(L_ERROR,"Invalid Configuration of minimum DL resources " + "for NON-CSG"); + RETVALUE(RFAILED); + } + if(csgParam->minUlResNonCsg > 100) + { + RLOG0(L_ERROR,"Invalid Configuration of minimum UL resources " + "for NON-CSG"); + RETVALUE(RFAILED); + } + RETVALUE(ROK); +} + +/** + * @brief Validates the SI configuration request from RRM to MAC. + * + * @details + * + * Function : rgSCHCfgVldtRgrSiCfg + * + * Processing Steps: + * - Validate the range of configured values recieved in + * configuration request. + * - If validated successfully, + * - Return ROK + * - Else + * - Return RFAILED. + * - Else return RFAILED. + * @param[in] Inst inst + * @param[in] RgrCellCfg *siCfg + * @param[out] RgSchCellCb *cell + * @param[out] RgSchErrInfo *errInfo + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 rgSCHCfgVldtRgrSiCfg +( +Inst inst, +RgrSiCfgReqInfo *siCfg, +RgSchCellCb *cell, +RgSchErrInfo *errInfo +) +#else +PUBLIC S16 rgSCHCfgVldtRgrSiCfg(inst, siCfg, cell, errInfo) +Inst inst; +RgrSiCfgReqInfo *siCfg; +RgSchCellCb *cell; +RgSchErrInfo *errInfo; +#endif +{ + MsgLen msgLen = 0; + U8 numSi; + + TRC2(rgSCHCfgVldtRgrSiCfg); + + + errInfo->errCause = RGSCHERR_CFG_INVALID_RGR_SI_CFG; + + /*Validate the cfgType parameter */ + switch(siCfg->cfgType) + { + /*ccpu00140789*/ + case RGR_SI_STOP: + numSi = (cell->siCb.siBitMask & RGSCH_SI_SICFG_UPD) ? + cell->siCb.newSiCfg.numSi : cell->siCfg.numSi; + if((siCfg->siId < RGSCH_SI_SIID_LOWER_LMT) || + (siCfg->siId > numSi)) + { + RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId, "Invalid SI Id value" + " specified"); + RETVALUE(RFAILED); + } + errInfo->errCause = RGSCHERR_NONE; + RETVALUE(ROK); + break; + case RGR_SI_CFG_TYPE_MIB: /* SI CFG Type MIB */ + case RGR_SI_CFG_TYPE_SIB1: /* SI CFG TYPE SIB1 */ + case RGR_SI_CFG_TYPE_SIB1_PWS: /* SI CFG TYPE SIB1_PWS */ + case RGR_SI_CFG_TYPE_SIB8_CDMA: /* SI CFG TYPE SIB 8 CDMA */ +#ifdef EMTC_ENABLE + case RGR_SI_CFG_EMTC_TYPE_SIB1_BR: + case RGR_SI_CFG_EMTC_TYPE_SIB1_BR_PER: +#endif + break; + + case RGR_SI_CFG_TYPE_SI: /* SI CFG TYPE SI */ + /*Check that value of SI should be less than equal + to configured numSi parameter value */ + /* Added siId validation for lower limit */ + numSi = (cell->siCb.siBitMask & RGSCH_SI_SICFG_UPD) ? + cell->siCb.newSiCfg.numSi : cell->siCfg.numSi; + if((siCfg->siId < RGSCH_SI_SIID_LOWER_LMT) || + (siCfg->siId > numSi)) + { + RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId, "Invalid SI Id value" + " specified"); + RETVALUE(RFAILED); + } + + if(siCfg->siId > ((cell->siCfg.minPeriodicity * 10)/cell->siCfg.siWinSize)) + { + RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId, "SiId can not be scheduled "); + RETVALUE(RFAILED); + } + break; + +#ifdef EMTC_ENABLE + case RGR_SI_CFG_EMTC_TYPE_SI: + case RGR_SI_CFG_EMTC_TYPE_SI_PER: + if(ROK != rgEmtcvalidateSiCfg(siCfg,cell)) + { + RETVALUE(RFAILED); + } + break; +#endif + default: + RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId, "Invalid cfgType " + "parameter value"); + RETVALUE(RFAILED); + } + + /*Validate the specified pdu */ + if(NULLP == siCfg->pdu) + { + RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId, "Invalid NULLP pdu " + "specified"); + RETVALUE(RFAILED); + } + + /*Check if PDU is of 0 length*/ + SFndLenMsg(siCfg->pdu, &msgLen); + if(0 == msgLen) + { + RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId, "Invalid pdu " + "specified"); + RETVALUE(RFAILED); + } + + errInfo->errCause = RGSCHERR_NONE; + + + RETVALUE(ROK); +} /* rgSCHCfgVldtRgrSiCfg */ +#endif /*RGR_SI_SCH*/ + +/* LTE_ADV_FLAG_REMOVED_START */ +/** + * @brief Validates the RNTP INF request from RRM to MAC. + * + * @details + * + * Function : rgSCHCfgVldtRgrLoadInf + * + * Processing Steps: + * - Validate the range of configured values recieved in + * LOAD INF request. + * - If validated successfully, + * - Return ROK + * - Else + * - Return RFAILED. + * - Else return RFAILED. + * @param[in] Inst inst + * @param[in] RgrLoadInfReqInfo *loadInfReq + * @param[out] RgSchCellCb *cell + * @param[out] RgSchErrInfo *errInfo + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 rgSCHCfgVldtRgrLoadInf +( + Inst inst, + RgrLoadInfReqInfo *loadInfReq, + RgSchCellCb *cell, + RgSchErrInfo *errInfo + ) +#else +PUBLIC S16 rgSCHCfgVldtRgrLoadInf(inst, loadInfReq, cell, errInfo) + Inst inst; + RgrLoadInfReqInfo *loadInfReq; + RgSchCellCb *cell; + RgSchErrInfo *errInfo; +#endif +{ + + TRC2(rgSCHCfgVldtRgrLoadInf); + + + errInfo->errCause = RGSCHERR_CFG_INVALID_RGR_LOAD_INF; + + /* Validate if the CC startRb which we have received from DSFR lies in CE sub-band of the receiving eNB */ + if((loadInfReq->rgrCcPHighStartRb >= cell->lteAdvCb.sfrCfg.cellEdgeRbRange.startRb) && + (loadInfReq->rgrCcPHighStartRb <= cell->lteAdvCb.sfrCfg.cellEdgeRbRange.endRb)) + { + RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,"Invalid rgrCcPHighStartRb received specified"); + RETVALUE(RFAILED); + } + + /* Validate if the CC endRb which we have received from DSFR lies in CE sub-band of the receiving eNB */ + if((loadInfReq->rgrCcPHighEndRb >= cell->lteAdvCb.sfrCfg.cellEdgeRbRange.startRb) && + (loadInfReq->rgrCcPHighEndRb <= cell->lteAdvCb.sfrCfg.cellEdgeRbRange.endRb)) + { + RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId, "Invalid rgrCcPHighEndRb received specified"); + RETVALUE(RFAILED); + } + + errInfo->errCause = RGSCHERR_NONE; + + + RETVALUE(ROK); +} /* rgSCHCfgVldtRgrLoadInf */ +/* LTE_ADV_FLAG_REMOVED_END */ + +#ifdef TFU_UPGRADE + +/******************************************************************** + * UE ACQI, PCQI, RI, SRS and SR Re/Configuration Validation Functions * + * * + *********************************************************************/ + + /* + * @brief Validates the Tx Mode and PUSCH Mode configuration. + * + * @details + * + * Function : rgSCHCfgVldtRgrTxmodePuschMode + * + * Processing Steps: + * - Validate whether the configured PUSCH Mode and the + * Configured Tx Mode are in the right combination + * - If validated successfully, + * - Return ROK. + * - Else + * - Return RFAILED. + * + * @param[in] RgSchCellCb *cellCb + * @param[in] RgrTxMode txMde + * @param[in] RgrAprdCqiMode puschMode + * @param[out] RgSchErrInfo *errInfo + * @return S16 + * -# ROK + * -# RFAILED + */ +#ifdef ANSI +PUBLIC S16 rgSCHCfgVldtRgrTxmodePuschMode +( + RgSchCellCb *cellCb, + RgrTxMode txMde, + RgrAprdCqiMode puschMode, + RgSchErrInfo *errInfo + ) +#else +PUBLIC S16 rgSCHCfgVldtRgrTxmodePuschMode(cellCb, txMde, puschMode,errInfo) + RgSchCellCb *cellCb; + RgrTxMode txMde; + RgrAprdCqiMode puschMode; + RgSchErrInfo *errInfo; +#endif +{ + TRC2(rgSCHCfgVldtRgrTxmodePuschMode); + + + if (txMde == RGR_UE_TM_1 || txMde == RGR_UE_TM_2 || + txMde == RGR_UE_TM_3 || txMde == RGR_UE_TM_7) + { + if (puschMode == RGR_APRD_CQI_MOD12 || + puschMode == RGR_APRD_CQI_MOD22 || + puschMode == RGR_APRD_CQI_MOD31) + { + RETVALUE(RFAILED); + } + } + + if (txMde == RGR_UE_TM_4 || txMde == RGR_UE_TM_6) + { + if (puschMode == RGR_APRD_CQI_MOD20 || + puschMode == RGR_APRD_CQI_MOD30) + { + RETVALUE(RFAILED); + } + } + + if (txMde == RGR_UE_TM_5 ) + { + if (puschMode != RGR_APRD_CQI_MOD31) + { + RETVALUE(RFAILED); + } + } +#ifdef LTE_ADV + /* TOODO:: Tm8 and TM9 validation has to + * be changed as mentioned inthe commented + * code below*/ + /* TM8 and TM9 supports all modes + * Mode 1-2, 2-2, 3-1 if pmi/ri reporting enabled + * 2-0,3-0 of pmi/ri reporitng isdisabled * + * if pmi/ri is enabled + * Mode 1-2, 2-2, 3-1 if with pmi/ri and csi-rs ports > 1 + * 2-0,3-0 of pmi/ri reporitng isdisabled and csi-rs ports == 1*/ + +#endif + RETVALUE(ROK); +}/*rgSCHCfgVldtRgrTxmodePuschMode ends*/ + + /* + * @brief Validates the UE ACQI configuration request from RRM to MAC. + * + * @details + * + * Function : rgSCHCfgVldtRgrUeACqiCfg + * + * Processing Steps: + * - Validate the UE configuration request from RRC to MAC at CFG: + * validate the ACQI Configuration + * - If validated successfully, + * - Return ROK. + * - Else + * - Return RFAILED. + * + * @param[in] RgSchCellCb *cellCb, + * @param[in] CmLteRnti crnti, + * @param[in] RgrUeAprdDlCqiCfg *acqiCfg, + * @param[in] RgrUeTxModeCfg txMode, + * @param[out] RgSchErrInfo *errInfo + + * @return S16 + * -# ROK + * -# RFAILED + */ +#ifdef ANSI +PUBLIC S16 rgSCHCfgVldtRgrUeACqiCfg +( + RgSchCellCb *cellCb, + CmLteRnti crnti, + RgrUeAprdDlCqiCfg *acqiCfg, + RgrUeTxModeCfg txMode, + RgSchErrInfo *errInfo + ) +#else +PUBLIC S16 rgSCHCfgVldtRgrUeACqiCfg(cellCb, crnti, acqiCfg,txMode, errInfo) + RgSchCellCb *cellCb; + CmLteRnti crnti; + RgrUeAprdDlCqiCfg *acqiCfg; + RgrUeTxModeCfg txMode; + RgSchErrInfo *errInfo; +#endif +{ + RgrTxMode txMde; + RgrAprdCqiMode puschMode; + TRC2(rgSCHCfgVldtRgrUeACqiCfg); + + + if(acqiCfg->pres) + { + if(txMode.pres == TRUE) + { + txMde = txMode.txModeEnum; + puschMode = acqiCfg->aprdModeEnum; + if ( ROK != rgSCHCfgVldtRgrTxmodePuschMode(cellCb, txMde, + puschMode, errInfo)) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cellCb->cellId, + "Invalid Aperiodic CQI configuration CRNTI:%d",crnti); + RETVALUE(RFAILED); + } + } + } + RETVALUE(ROK); +} + + /* + * @brief Validates the Tx Mode and PUCCH Mode configuration. + * + * @details + * + * Function : rgSCHCfgVldtRgrTxmodePucchMode + * + * Processing Steps: + * - Validate whether the configured PUCCH Mode and the + * Configured Tx Mode are in the right combination + * - If validated successfully, + * - Return ROK. + * - Else + * - Return RFAILED. + * + * @param[in] RgSchCellCb *cellCb + * @param[in] RgrTxMode txMde + * @param[in] RgrPrdCqiMode pucchMode + * @param[out] RgSchErrInfo *errInfo + * @return S16 + * -# ROK + * -# RFAILED + */ +#ifdef ANSI +PUBLIC S16 rgSCHCfgVldtRgrTxmodePucchMode +( + RgSchCellCb *cellCb, + RgrTxMode txMde, + RgrPrdCqiMode pucchMode, + RgSchErrInfo *errInfo + ) +#else +PUBLIC S16 rgSCHCfgVldtRgrTxmodePucchMode(cellCb, txMde, pucchMode,errInfo) + RgSchCellCb *cellCb; + RgrTxMode txMde; + RgrPrdCqiMode pucchMode; + RgSchErrInfo *errInfo; +#endif +{ + TRC2(rgSCHCfgVldtRgrTxmodePucchMode); + + + if (pucchMode == RGR_PRD_CQI_MOD10 || pucchMode == RGR_PRD_CQI_MOD20 ) + { + if (txMde ==RGR_UE_TM_4 || txMde ==RGR_UE_TM_5 || txMde ==RGR_UE_TM_6) + { + RETVALUE(RFAILED); + } + } + else if (pucchMode == RGR_PRD_CQI_MOD11 || pucchMode == RGR_PRD_CQI_MOD21) + { + if (txMde ==RGR_UE_TM_1 || txMde ==RGR_UE_TM_2 || txMde ==RGR_UE_TM_3 \ + || txMde ==RGR_UE_TM_7) + { + RETVALUE(RFAILED); + } + } + /* TODO:: Tm8 and TM9 validation needs to be added */ + RETVALUE(ROK); +} + +/* + * @brief Validates the UE Periodic CQI, PMI, RI, re/configuration request from RRM to MAC. + * + * @details + * + * Function : rgSCHCfgVldtRgrUePCqiCfg + * + * Processing Steps: + * - Validate the UE configuration request from RRC to MAC at CFG: + * validate the value range for Periodic CQI, PMI, RI values. + * - If validated successfully, + * - Return ROK. + * - Else + * - Return RFAILED. + * + * @param[in] RgSchCellCb *cellCb, + * @param[in] CmLteRnti crnti, + * @param[in] RgrUePrdDlCqiCfg *cqiCfg, + * @param[in] RgrUeTxModeCfg txMode, + * @param[out] RgSchErrInfo *errInfo + * @return S16 + * -# ROK + * -# RFAILED + */ +#ifdef LTEMAC_HDFDD +#ifdef ANSI +PUBLIC S16 rgSCHCfgVldtRgrUePCqiCfg +( + RgSchCellCb *cellCb, + CmLteRnti crnti, + RgrUePrdDlCqiCfg *cqiCfg, + Bool hdFdd, + RgrUeTxModeCfg txMode, + RgSchErrInfo *errInfo + ) +#else +PUBLIC S16 rgSCHCfgVldtRgrUePCqiCfg(cellCb, crnti, cqiCfg, hdFdd, + txMode, errInfo) + RgSchCellCb *cellCb; + CmLteRnti crnti; + RgrUePrdDlCqiCfg *cqiCfg; + Bool hdFdd; + RgrUeTxModeCfg txMode; + RgSchErrInfo *errInfo; +#endif +#else +#ifdef ANSI +PUBLIC S16 rgSCHCfgVldtRgrUePCqiCfg + ( + RgSchCellCb *cellCb, + CmLteRnti crnti, + RgrUePrdDlCqiCfg *cqiCfg, + RgrUeTxModeCfg txMode, + RgSchErrInfo *errInfo + ) +#else +PUBLIC S16 rgSCHCfgVldtRgrUePCqiCfg(cellCb, crnti, cqiCfg, txMode, errInfo) + RgSchCellCb *cellCb; + CmLteRnti crnti; + RgrUePrdDlCqiCfg *cqiCfg; + RgrUeTxModeCfg txMode; + RgSchErrInfo *errInfo; +#endif +#endif +{ + RgrTxMode txMde; + RgrPrdCqiMode pucchMode; + + TRC2(rgSCHCfgVldtRgrUePCqiCfg); + + txMde = RGR_UE_TM_1; + pucchMode = RGR_PRD_CQI_MOD20; + if ( RGR_SCH_PCQI_SETUP == cqiCfg->type ) + { + /*1. Validate for Tx Mode and PUCCH Mode combination*/ + if(txMode.pres == TRUE) + { + txMde = txMode.txModeEnum; + pucchMode = cqiCfg->cqiSetup.prdModeEnum; + if ( ROK != rgSCHCfgVldtRgrTxmodePucchMode(cellCb, txMde, + pucchMode, errInfo)) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cellCb->cellId, + "Invalid Tx Mode-PUCCH Mode combination CRNTI:%d",crnti); + RETVALUE(RFAILED); + } + } + + /*2. Validate for PCQI Reporting Type and PUCCH Mode combination*/ + if((cqiCfg->cqiSetup.cqiRepType==1) && + ((pucchMode == RGR_PRD_CQI_MOD20) || + (pucchMode == RGR_PRD_CQI_MOD21))) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cellCb->cellId, + "Invalid Reporting Type-PUCCH Mode combination CRNTI:%d",crnti); + RETVALUE(RFAILED); + } + + if((cqiCfg->cqiSetup.cqiRepType==2) && + ((pucchMode == RGR_PRD_CQI_MOD10) || + (pucchMode == RGR_PRD_CQI_MOD11))) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cellCb->cellId, + "Invalid Reporting Type-PUCCH Mode combination CRNTI:%d",crnti); + RETVALUE(RFAILED); + } + + /*3. Validate CQI/PMI and RI Configuration related parameter values */ + /*TODO- To be compared with configured n2Pucch Index*/ + if (cqiCfg->cqiSetup.cqiPResIdx > RG_SCH_PUCCH_RES_MAX_SUPP ) + { + RLOG_ARG3(L_ERROR,DBG_CELLID,cellCb->cellId, + "Not Supported or Invalid CQI-PUCCH resourceIndex=%d Cfg Val=%d CRNTI:%d", + RG_SCH_PUCCH_RES_MAX_SUPP, cqiCfg->type,crnti); + RETVALUE(RFAILED); + } + +#ifdef LTEMAC_HDFDD + if(hdFdd) + { + if((cqiCfg->cqiSetup.cqiPCfgIdx > RG_SCH_ICQI_MAX_SUPP)|| + (cqiCfg->cqiSetup.cqiPCfgIdx < 7) || + (cqiCfg->cqiSetup.cqiPCfgIdx == 317)) + { + RLOG_ARG4(L_ERROR,DBG_CELLID,cellCb->cellId, + "Not Supported or Invalid Cfg CQI Min Index Sup =%d" + "Max Index Sup=%d Cfg Val=%d CRNTI:%d", RG_SCH_ICQI_MIN_SUPP, + RG_SCH_ICQI_MAX_SUPP, cqiCfg->type,crnti); + RETVALUE(RFAILED); + } + } + else + { + if((cqiCfg->cqiSetup.cqiPCfgIdx > RG_SCH_ICQI_MAX_SUPP)|| + (cqiCfg->cqiSetup.cqiPCfgIdx == 317)) + { + RLOG_ARG4(L_ERROR,DBG_CELLID,cellCb->cellId, + "Not Supported or Invalid Cfg CQI Min Index Sup =%d " + "Max Index Sup=%d Cfg Val=%d CRNTI:%d", RG_SCH_ICQI_MIN_SUPP, + RG_SCH_ICQI_MAX_SUPP, cqiCfg->type,crnti); + RETVALUE(RFAILED); + } + } +#else + if((cqiCfg->cqiSetup.cqiPCfgIdx > RG_SCH_ICQI_MAX_SUPP)|| + (cqiCfg->cqiSetup.cqiPCfgIdx == 317)) + { + RLOG_ARG4(L_ERROR,DBG_CELLID,cellCb->cellId, + "Not Supported or Invalid Cfg CQI Min Index Sup =%d" + "Max Index Sup=%d Cfg Val=%d CRNTI;%d", RG_SCH_ICQI_MIN_SUPP, + RG_SCH_ICQI_MAX_SUPP, cqiCfg->type,crnti); + RETVALUE(RFAILED); + } +#endif + + if((cqiCfg->cqiSetup.cqiRepType < RGR_UE_PCQI_WB_REP) || + (cqiCfg->cqiSetup.cqiRepType > RGR_UE_PCQI_SB_REP)) + { + RLOG_ARG2(L_ERROR,DBG_CELLID,cellCb->cellId, + "Invalid Cfg CQI Report" + "ModeCfg Val=%d CRNTI:%d", cqiCfg->type,crnti); + RETVALUE(RFAILED); + } + + if((cqiCfg->cqiSetup.cqiRepType == RGR_UE_PCQI_SB_REP) && + ((cqiCfg->cqiSetup.k < RG_SCH_CQI_K_MIN) || + (cqiCfg->cqiSetup.k > RG_SCH_CQI_K_MAX))) + { + RLOG_ARG2(L_ERROR,DBG_CELLID,cellCb->cellId, + "Invalid CQI Cfg K Cfg Val=%d CRNTI:%d", cqiCfg->type,crnti); + RETVALUE(RFAILED); + } + + if((cqiCfg->cqiSetup.cqiRepType == RGR_UE_PCQI_SB_REP) && + (cellCb->bwCfg.dlTotalBw <= 7)) + { + RLOG_ARG2(L_ERROR,DBG_CELLID,cellCb->cellId, + "Invalid Periodic CQI mode Cfg for dlTotalBw (%d) for CRNTI:%d", + cellCb->bwCfg.dlTotalBw, crnti); + RETVALUE(RFAILED); + } + +#ifndef LTE_TDD + if (cqiCfg->cqiSetup.cqiPCfgIdx == RG_SCH_ICQI_RESV_FDD ) + { + RLOG_ARG2(L_ERROR,DBG_CELLID,cellCb->cellId, + "Reserved value Cfg =%d CRNTI:%d", + cqiCfg->cqiSetup.cqiPResIdx,crnti); + RETVALUE(RFAILED); + } +#endif + + /* 4. Check RI Configuration values */ + if(cqiCfg->cqiSetup.riEna == TRUE) + { + if(txMode.pres == TRUE) + { + if((txMde != RGR_UE_TM_3) + && (txMde != RGR_UE_TM_4) + && (txMde != RGR_UE_TM_8) +#ifdef LTE_ADV + && (txMde != RGR_UE_TM_9) +#endif + ) + { + RLOG_ARG2(L_ERROR,DBG_CELLID,cellCb->cellId, + "Invalid Transmission Mode =%d CRNTI:%d", + txMde,crnti); + RETVALUE(RFAILED); + } + } + + if(cqiCfg->cqiSetup.riCfgIdx > RG_SCH_IRI_MAX_SUPP) + { + RLOG_ARG2(L_ERROR,DBG_CELLID,cellCb->cellId, + "Invalid Index RI value Cfg =%d CRNTI:%d", + cqiCfg->cqiSetup.riCfgIdx,crnti); + RETVALUE(RFAILED); + } + } + } + + + RETVALUE(ROK); +} + +/* + * @brief Validates the UE SRS Re/Configuation request from RRM to MAC. + * + * @details + * + * Function : rgSCHCfgVldtRgrUeUlSrsCfg + * + * Processing Steps: + * - Validate the UE configuration request from RRC to MAC at CFG: + * validate the value range for SRS values. + * - If validated successfully, + * - Return ROK. + * - Else + * - Return RFAILED. + * + * @param[in] RgSchCellCb *cellCb, + * @param[in] CmLteRnti crnti, + * @param[in] RgrUeUlSrsCfg *srsCfg, + * @param[out] RgSchErrInfo *errInfo + * @return S16 + * -# ROK + * -# RFAILED + */ +#ifdef LTEMAC_HDFDD +#ifdef ANSI +PUBLIC S16 rgSCHCfgVldtRgrUeUlSrsCfg +( + RgSchCellCb *cellCb, + CmLteRnti crnti, + RgrUeUlSrsCfg *srsCfg, + Bool hdFdd, + RgSchErrInfo *errInfo + ) +#else +PUBLIC S16 rgSCHCfgVldtRgrUeUlSrsCfg(cellCb, crnti, srsCfg, hdFdd, errInfo) + RgSchCellCb *cellCb; + CmLteRnti crnti; + RgrUeUlSrsCfg *srsCfg; + Bool hdFdd; + RgSchErrInfo *errInfo; +#endif +#else +#ifdef ANSI +PUBLIC S16 rgSCHCfgVldtRgrUeUlSrsCfg +( + RgSchCellCb *cellCb, + CmLteRnti crnti, + RgrUeUlSrsCfg *srsCfg, + RgSchErrInfo *errInfo + ) +#else +PUBLIC S16 rgSCHCfgVldtRgrUeUlSrsCfg(cellCb, crnti, srsCfg, errInfo) + RgSchCellCb *cellCb; + CmLteRnti crnti; + RgrUeUlSrsCfg *srsCfg; + RgSchErrInfo *errInfo; +#endif +#endif +{ + U16 srsPeri=0; + U16 srsOffset=0; + U8 srsSubframe=0; + + TRC2(rgSCHCfgVldtRgrUeUlSrsCfg); + + + if ( RGR_SCH_SRS_SETUP == srsCfg->type ) + { + + /*ccpu00130768 - ADD - if cell specific SRS is not configured*/ + if(cellCb->srsCfg.isSrsCfgPres == FALSE) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cellCb->cellId, + "Cell specific SRS is not configured CRNTI:%d",crnti); + RETVALUE(RFAILED); + } + + /* 1. Validate SRS Configuration related parameter values */ + /* 1.1 iSRS should be 0-636; Ref: 36.213. Table 8.2-1 */ +#ifdef LTEMAC_HDFDD + if(hdFdd) + { + if ( (srsCfg->srsSetup.srsCfgIdx < 7) || + (srsCfg->srsSetup.srsCfgIdx > RG_SCH_ISRS_MAX_SUPP) ) + { + RLOG_ARG4(L_ERROR,DBG_CELLID,cellCb->cellId, + "Not Supported or Invalid Cfg " + "SRS Min Index Sup =%d Max Index Sup=%d Cfg Val=%d CRNTI:%d", + RG_SCH_ISRS_MIN_SUPP, RG_SCH_ISRS_MAX_SUPP, + srsCfg->srsSetup.srsCfgIdx,crnti); + RETVALUE(RFAILED); + } + } + else + { + if ( srsCfg->srsSetup.srsCfgIdx > RG_SCH_ISRS_MAX_SUPP ) + { + RLOG_ARG4(L_ERROR,DBG_CELLID,cellCb->cellId, + "Not Supported or Invalid Cfg" + "SRS Min Index Sup =%d Max Index Sup=%d Cfg Val=%d CRNTI:%d", + RG_SCH_ISRS_MIN_SUPP, RG_SCH_ISRS_MAX_SUPP, + srsCfg->srsSetup.srsCfgIdx,crnti); + RETVALUE(RFAILED); + } + + } +#else + if ( srsCfg->srsSetup.srsCfgIdx > RG_SCH_ISRS_MAX_SUPP ) + { + RLOG_ARG4(L_ERROR,DBG_CELLID,cellCb->cellId, + "Not Supported or Invalid Cfg" + "SRS Min Index Sup =%d Max Index Sup=%d Cfg Val=%d CRNTI:%d", + RG_SCH_ISRS_MIN_SUPP, RG_SCH_ISRS_MAX_SUPP, + srsCfg->srsSetup.srsCfgIdx,crnti); + RETVALUE(RFAILED); + } +#endif +#ifdef LTE_TDD + /* Compute SRS Offset and Periodicity */ + rgSCHUtlGetCfgPerOff( RG_SCH_TDD_SRS_TBL, + srsCfg->srsSetup.srsCfgIdx, + &srsPeri, &srsOffset); +#else + rgSCHUtlGetCfgPerOff( RG_SCH_FDD_SRS_TBL, + srsCfg->srsSetup.srsCfgIdx, + &srsPeri, &srsOffset); +#endif + srsSubframe = srsOffset%RGSCH_NUM_SUB_FRAMES; +#ifdef LTE_TDD + if(rgSchTddCellSpSrsSubfrmTbl[cellCb->srsCfg.srsSubFrameCfg][srsSubframe] == FALSE) { +#else + if(rgSchFddCellSpSrsSubfrmTbl[cellCb->srsCfg.srsSubFrameCfg][srsSubframe] == FALSE) { +#endif + RLOG_ARG2(L_ERROR,DBG_CELLID,cellCb->cellId, + "UE specific SRS is not occuring in Cell specific SRS subframe" + "srs Cfg Idx =%d CRNTI:%d", + srsCfg->srsSetup.srsCfgIdx,crnti); + RETVALUE(RFAILED); + } + + + if ( srsCfg->srsSetup.fDomPosi > RG_SCH_SRS_FREQDOM_POS_MAX ) + { + RLOG_ARG4(L_ERROR,DBG_CELLID,cellCb->cellId, + "Not Supported or Invalid Cfg" + "SRS Min Freq Domain Position =%d" + "Max Freq Domain Position =%d Cfg Val=%d CRNTI:%d", + RG_SCH_SRS_FREQDOM_POS_MIN, RG_SCH_SRS_FREQDOM_POS_MAX, + srsCfg->srsSetup.srsCfgIdx,crnti); + RETVALUE(RFAILED); + } + + if ( srsCfg->srsSetup.txComb > RG_SCH_SRS_TXCOMB_MAX ) + { + RLOG_ARG4(L_ERROR,DBG_CELLID,cellCb->cellId, + "Not Supported or Invalid Cfg" + "SRS Min TX Comb =%d Max TX Comb =%d Cfg Val=%d CRNTI:%d", + RG_SCH_SRS_TXCOMB_MIN, RG_SCH_SRS_TXCOMB_MAX, + srsCfg->srsSetup.srsCfgIdx,crnti); + RETVALUE(RFAILED); + } + } + RETVALUE(ROK); +} + +/* + * @brief Validates the UE SR Re/configuration request from RRM to MAC. + * + * @details + * + * Function : rgSCHCfgVldtRgrUeSrCfg + * + * Processing Steps: + * - Validate the UE re/configuration request from RRC to MAC at CFG: + * validate the value range for SR values. + * - If validated successfully, + * - Return ROK. + * - Else + * - Return RFAILED. + * + * @param[in] RgSchCellCb *cellCb, + * @param[in] CmLteRnti crnti, + * @param[in] RgrUeSrCfg *srCfg, + * @param[out] RgSchErrInfo *errInfo + * @return S16 + * -# ROK + * -# RFAILED + */ +#ifdef LTEMAC_HDFDD +#ifdef ANSI +PUBLIC S16 rgSCHCfgVldtRgrUeSrCfg +( + RgSchCellCb *cellCb, + CmLteRnti crnti, + RgrUeSrCfg *srCfg, + Bool hdFdd, + RgSchErrInfo *errInfo + ) +#else +PUBLIC S16 rgSCHCfgVldtRgrUeSrCfg(cellCb, crnti, srCfg, hdFdd, errInfo) + RgSchCellCb *cellCb; + CmLteRnti crnti; + RgrUeSrCfg *srCfg; + Bool hdFdd; + RgSchErrInfo *errInfo; +#endif +#else +#ifdef ANSI +PUBLIC S16 rgSCHCfgVldtRgrUeSrCfg +( + RgSchCellCb *cellCb, + CmLteRnti crnti, + RgrUeSrCfg *srCfg, + RgSchErrInfo *errInfo + ) +#else +PUBLIC S16 rgSCHCfgVldtRgrUeSrCfg(cellCb, crnti, srCfg, errInfo) + RgSchCellCb *cellCb; + CmLteRnti crnti; + RgrUeSrCfg *srCfg; + RgSchErrInfo *errInfo; +#endif +#endif +{ + + TRC2(rgSCHCfgVldtRgrUeSrCfg); + + + + if ( RGR_SCH_SR_SETUP == srCfg->type ) + { + /* 1. Validate SR Configuration related parameter values */ +#ifdef LTEMAC_HDFDD + if(hdFdd) + { + if (( srCfg->srSetup.srResIdx > RG_SCH_SR_RES_IDX ) || + ( srCfg->srSetup.srCfgIdx < 5 ) || + ( srCfg->srSetup.srCfgIdx > RG_SCH_ISR_MAX_SUPP )) + { + RLOG_ARG4(L_ERROR,DBG_CELLID,cellCb->cellId, + "Invalid SR Index Cfg =%d" + "Max Supp=%d,Min Supp=%d CRNTI:%d", srCfg->srSetup.srCfgIdx, + RG_SCH_ISR_MAX_SUPP, RG_SCH_ISR_MIN_SUPP,crnti); + + RETVALUE(RFAILED); + } + } + else + { + if (( srCfg->srSetup.srResIdx > RG_SCH_SR_RES_IDX ) || + ( srCfg->srSetup.srCfgIdx > RG_SCH_ISR_MAX_SUPP )) + { + RLOG_ARG4(L_ERROR,DBG_CELLID,cellCb->cellId, + "Invalid SR Index Cfg =%d" + "Max Supp=%d,Min Supp=%d CRNTI:%d", srCfg->srSetup.srCfgIdx, + RG_SCH_ISR_MAX_SUPP, RG_SCH_ISR_MIN_SUPP,crnti); + + RETVALUE(RFAILED); + } + } +#else + if (( srCfg->srSetup.srResIdx > RG_SCH_SR_RES_IDX ) || + ( srCfg->srSetup.srCfgIdx > RG_SCH_ISR_MAX_SUPP )) + { + RLOG_ARG4(L_ERROR,DBG_CELLID,cellCb->cellId, + "Invalid SR Index Cfg =%d" + "Max Supp=%d,Min Supp=%d CRNTI:%d", srCfg->srSetup.srCfgIdx, + RG_SCH_ISR_MAX_SUPP, RG_SCH_ISR_MIN_SUPP,crnti); + + RETVALUE(RFAILED); + } +#endif + } + RETVALUE(ROK); +} + + +/* + * @brief Validates the UE Aperiodic & Periodic CQI, PMI, RI, SRS and SR Configuration + * request from RRM to MAC. + * + * @details + * + * Function :rgSCHCfgVldtCqiSrSrsUeCfg + * + * Processing Steps: + * - Validate the UE configuration request from RRC to MAC at CFG: + * validate the value range for Aperiodic & Periodic CQI, PMI, RI , SRS and SR values. + * - If validated successfully, + * - Return ROK. + * - Else + * - Return RFAILED. + * + * @param[in] RgSchCellCb *cellCb + * @param[in] RgrUeCfg *ueCfg + * @param[out] RgSchErrInfo *errInfo + * @return S16 + * -# ROK + * -# RFAILED + */ +#ifdef ANSI +PRIVATE S16 rgSCHCfgVldtCqiSrSrsUeCfg +( + RgSchCellCb *cellCb, + RgrUeCfg *ueCfg, + RgSchErrInfo *errInfo + ) +#else +PRIVATE S16 rgSCHCfgVldtCqiSrSrsUeCfg(cellCb, ueCfg, errInfo) + RgSchCellCb *cellCb; + RgrUeCfg *ueCfg; + RgSchErrInfo *errInfo; +#endif +{ + + TRC2(rgSCHCfgVldtCqiSrSrsUeCfg); + + + /* 1. Validate UE Aperiodic CQI related parameters */ + if ( ROK != rgSCHCfgVldtRgrUeACqiCfg (cellCb, ueCfg->crnti, + &ueCfg->ueDlCqiCfg.aprdCqiCfg, ueCfg->txMode, errInfo )) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cellCb->cellId, + "Invalid Aperiodic CQI configuration CRNTI:%d",ueCfg->crnti); + RETVALUE(RFAILED); + } + + /* 1. Validate UE Periodic CQI/PMI, SRS and SR related parameters */ +#ifdef LTEMAC_HDFDD + if ( ROK != rgSCHCfgVldtRgrUePCqiCfg (cellCb, ueCfg->crnti, + &ueCfg->ueDlCqiCfg.prdCqiCfg, ueCfg->isHdFddEnbld, + ueCfg->txMode, errInfo )) +#else + if ( ROK != rgSCHCfgVldtRgrUePCqiCfg (cellCb, ueCfg->crnti, + &ueCfg->ueDlCqiCfg.prdCqiCfg, ueCfg->txMode, errInfo )) +#endif + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cellCb->cellId, + "Invalid Periodic CQI configuration CRNTI:%d",ueCfg->crnti); + RETVALUE(RFAILED); + } + + /* 2. Validate SRS Configuration related parameter values */ +#ifdef LTEMAC_HDFDD + if ( ROK != rgSCHCfgVldtRgrUeUlSrsCfg(cellCb, ueCfg->crnti, &ueCfg->srsCfg, + ueCfg->isHdFddEnbld, errInfo )) +#else + if ( ROK != rgSCHCfgVldtRgrUeUlSrsCfg(cellCb, ueCfg->crnti, + &ueCfg->srsCfg, errInfo )) +#endif + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cellCb->cellId, + "Invalid SRS configuration CRNTI:%d",ueCfg->crnti); + RETVALUE(RFAILED); + } + + /* 3. Validate SR Configuration related parameter values */ +#ifdef LTEMAC_HDFDD + if ( ROK != rgSCHCfgVldtRgrUeSrCfg (cellCb, ueCfg->crnti, &ueCfg->srCfg, + ueCfg->isHdFddEnbld, errInfo)) +#else + if ( ROK != rgSCHCfgVldtRgrUeSrCfg (cellCb, ueCfg->crnti, + &ueCfg->srCfg, errInfo)) +#endif + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cellCb->cellId, + "Invalid SR configuration CRNTI:%d",ueCfg->crnti); + RETVALUE(RFAILED); + } + + RETVALUE(ROK); + +} + + + +/***************************************************************** + * UE PCQI, RI, SRS and SR Re Configuration Validation Functions * + * * + ******************************************************************/ +/* + * @brief Validates the UE Periodic CQI, PMI, RI, SRS and SR + * Re-configuration request from RRM to MAC. + * + * @details + * + * Function : rgSCHCfgVldtCqiSrSrsUeReCfg + * + * Processing Steps: + * - Validate the UE Re configuration request from RRC to MAC at CFG: + * validate the value range for Periodic CQI, PMI, RI, SRS and SR values. + * - If validated successfully, + * - Return ROK. + * - Else + * - Return RFAILED. + * + * @param[in] RgSchCellCb *cellCb + * @param[in] RgSchUeCb *ueCb + * @param[in] RgrUeCfg *ueCfg + * @param[out] RgSchErrInfo *errInfo + * @return S16 + * -# ROK + * -# RFAILED + */ +#ifdef ANSI +PRIVATE S16 rgSCHCfgVldtCqiSrSrsUeReCfg +( + RgSchCellCb *cellCb, + RgSchUeCb *ueCb, + RgrUeRecfg *ueReCfg, + RgSchErrInfo *errInfo + ) +#else +PRIVATE S16 rgSCHCfgVldtCqiSrSrsUeReCfg(cellCb, ueCb, ueReCfg, errInfo) + RgSchCellCb *cellCb; + RgSchUeCb *ueCb; + RgrUeRecfg *ueReCfg; + RgSchErrInfo *errInfo; +#endif +{ + RgrUeTxModeCfg txMode; + TRC3(rgSCHCfgVldtCqiSrSrsUeReCfg); + + txMode.pres = TRUE; + txMode.tmTrnstnState = RGR_TXMODE_RECFG_CMPLT; + if ((ueReCfg->ueRecfgTypes & RGR_UE_TXMODE_RECFG) && + (ueReCfg->txMode.pres == TRUE)) + { + txMode.txModeEnum = ueReCfg->txMode.txModeEnum; + } + else + { + txMode.txModeEnum = ueCb->mimoInfo.txMode; + } + + /* 1. Validate UE CQI/PMI, SRS and SR related parameters */ + + if ( ueReCfg->ueRecfgTypes & RGR_UE_APRD_DLCQI_RECFG ) + { + if ( ROK != rgSCHCfgVldtRgrUeACqiCfg (cellCb, ueReCfg->oldCrnti, + &ueReCfg->aprdDlCqiRecfg, txMode, errInfo )) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cellCb->cellId, + "Invalid Aperiodic CQI configuration OLD CRNTI:%d",ueReCfg->oldCrnti); + RETVALUE(RFAILED); + } + } + + + /* 2. Validate UE CQI/PMI, SRS and SR related parameters */ + + if ( ueReCfg->ueRecfgTypes & RGR_UE_PCQI_RECFG ) + { +#ifdef LTEMAC_HDFDD + if ( ROK != rgSCHCfgVldtRgrUePCqiCfg (cellCb, ueReCfg->oldCrnti, + &ueReCfg->cqiCfg, ueReCfg->isHdFddEnbld, txMode, errInfo )) +#else + if ( ROK != rgSCHCfgVldtRgrUePCqiCfg (cellCb, ueReCfg->oldCrnti, + &ueReCfg->cqiCfg, txMode, errInfo )) +#endif + + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cellCb->cellId, + "Invalid Periodic CQI configuration OLD CRNTI:%d",ueReCfg->oldCrnti); + RETVALUE(RFAILED); + } + } + + if(ueReCfg->ueRecfgTypes & RGR_UE_SRS_RECFG ) + { +#ifdef LTEMAC_HDFDD + if ( ROK != rgSCHCfgVldtRgrUeUlSrsCfg(cellCb, ueReCfg->oldCrnti, + &ueReCfg->srsCfg, ueReCfg->isHdFddEnbld, errInfo )) +#else + if ( ROK != rgSCHCfgVldtRgrUeUlSrsCfg(cellCb, ueReCfg->oldCrnti, + &ueReCfg->srsCfg, errInfo )) +#endif + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cellCb->cellId, + "Invalid SRS configuration OLD CRNTI:%d",ueReCfg->oldCrnti); + RETVALUE(RFAILED); + } + + } + + if ( ueReCfg->ueRecfgTypes & RGR_UE_SR_RECFG ) + { +#ifdef LTEMAC_HDFDD + if ( ROK != rgSCHCfgVldtRgrUeSrCfg (cellCb, ueReCfg->oldCrnti, + &ueReCfg->srCfg, ueReCfg->isHdFddEnbld, errInfo)) +#else + if ( ROK != rgSCHCfgVldtRgrUeSrCfg (cellCb, ueReCfg->oldCrnti, + &ueReCfg->srCfg, errInfo)) +#endif + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cellCb->cellId, + "Invalid SR configuration OLD CRNTI:%d",ueReCfg->oldCrnti); + RETVALUE(RFAILED); + } + } + + RETVALUE(ROK); +} + + +/***************************************************************** + * UE ACQI, PCQI, RI, SRS SR Configuration Functions * + * * + ******************************************************************/ + /** + * @brief Handles Aperiodic CQI , PMI, RI configuration for a UE. + * + * @details + * + * Function : rgSCHCfgACqiUeCfg + * + * Invoking Module Processing: + * - This shall be invoked by SCH_GOM at UE configuration. It + * shall do the validations for the spec-defined values. + * + * Processing Steps: + * + * - Return ROK + * + * @param[in] RgSchCellCb *cell + * @param[in] RgrTxMode txMode + * @param[in] RgrUeAprdDlCqiCfg *aCqiCfg + * @param[in] CmLteUeCategory ueCat + * @return S16 + * -# ROK + * + **/ +#ifdef ANSI +PUBLIC S16 rgSCHCfgACqiUeCfg +( +RgSchCellCb *cellCb, +RgSchUeCb *ue, +RgSchUeACqiCb *acqiCb, +RgrTxMode ueTxMode, +RgrUeAprdDlCqiCfg *aCqiCfg, +CmLteUeCategory ueCat +) +#else +PUBLIC S16 rgSCHCfgACqiUeCfg(cellCb,ue,acqiCb ueTxMode, aCqiCfg, ueCat) +RgSchCellCb *cellCb; +RgSchUeCb *ue; +RgSchUeACqiCb *acqiCb; +RgrTxMode ueTxMode; +RgrUeAprdDlCqiCfg *aCqiCfg; +CmLteUeCategory ueCat; +#endif +{ + U8 M; /*Num of Subbands -- Applicable only for Mode 2-0 and 2-2*/ + U8 k; /*SubBand Size (RB) -- + Holds different values depending on Mode*/ + U8 cqiPmiSzR1; /*CQIPMI Size for Rank =1*/ + U8 cqiPmiSzRn1; /*CQIPMI Size for Rank > 1*/ + + TRC3(rgSCHCfgACqiUeCfg); + + cqiPmiSzR1 = 0; + cqiPmiSzRn1 = 0; + + acqiCb->aCqiCfg.pres = aCqiCfg->pres; + acqiCb->aCqiCfg.aprdModeEnum = aCqiCfg->aprdModeEnum; + + if(aCqiCfg->pres) + { +#ifdef LTE_ADV + /*Store Trigger Set Bit String to UE */ + RgSchUeCellInfo *pCellInfo = RG_SCH_CMN_GET_PCELL_INFO(ue); + pCellInfo->acqiCb.aCqiCfg.triggerSet1 = aCqiCfg->triggerSet1; + pCellInfo->acqiCb.aCqiCfg.triggerSet2 = aCqiCfg->triggerSet2; +#endif + + + switch(aCqiCfg->aprdModeEnum) + { + case RGR_APRD_CQI_MOD12: + case RGR_APRD_CQI_MOD30: + case RGR_APRD_CQI_MOD31: + RG_SCH_GET_CQI_K_VAL(cellCb->bwCfg.dlTotalBw, k); + acqiCb->N = RGSCH_CEIL(cellCb->bwCfg.dlTotalBw, k); + acqiCb->k = k; + break; + + case RGR_APRD_CQI_MOD20: + case RGR_APRD_CQI_MOD22: + RG_SCH_GET_SBCQI_M_K_VAL(cellCb->bwCfg.dlTotalBw, M, k); + acqiCb->N = RGSCH_CEIL(cellCb->bwCfg.dlTotalBw, k); + acqiCb->k = k; + acqiCb->M = M; + acqiCb->L = RgSCHUeAcqi2022LBitWidth[M-1][acqiCb->N-1]; + break; + + default: + break; + } + if((ueTxMode == RGR_UE_TM_3) || + (ueTxMode == RGR_UE_TM_4)) + { + if(cellCb->numTxAntPorts ==2) + { + acqiCb->riNumBits = 1; + } + else if(cellCb->numTxAntPorts ==4) + { + if(ueCat == CM_LTE_UE_CAT_8) + { + acqiCb->riNumBits = 3; + } + else if(ueCat >= CM_LTE_UE_CAT_5) + { + acqiCb->riNumBits = 2; + } + else + { + acqiCb->riNumBits = 1; + } + } + } + rgSCHCfgUtlFetchAcqiBitSz(acqiCb, cellCb->numTxAntPorts, + &cqiPmiSzR1, &cqiPmiSzRn1); + acqiCb->cqiPmiSzR1 = cqiPmiSzR1; + acqiCb->cqiPmiSzRn1 = cqiPmiSzRn1; + } + acqiCb->cqiReqField = TRUE; +#ifdef LTE_ADV + rgSchCmnSetCqiReqField(RG_SCH_CMN_GET_SCELL_INFO(ue, cellCb),ue,&acqiCb->cqiReqField); +#endif + + RETVALUE(ROK); +} + +/** + * @brief Handles Periodic CQI , PMI, RI configuration for a UE. + * + * @details + * + * Function : rgSCHCfgPCqiUeCfg + * + * Invoking Module Processing: + * - This shall be invoked by SCH_GOM at UE configuration. It shall do the + * validations for the spec-defined values. + * + * Processing Steps: + * - For UE-specific Periodic CQI related configuration, + * - If Periodic CQI/PMI is configured, + * - Update UE with the configured values. + - Compute and Update next occurance of CQI/PMI or RI Tranmission instance. + - Update the CQI offset and CQI perodicity information + - Add Ue to cell's list + * + * + * - For UE-specific Periodic RI related configuration, + * - If Periodic RI is configured, + * - Update UE with the configured values. + - Compute and Update next occurance of RI Tranmission instance. + - Update the RI offset and RI perodicity information + * + * + * - Return ROK + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ue + * @param[in] RgrUePrdDlCqiCfg *cqiCfg + * @param[in] CmLteUeCategory ueCat + * @return S16 + * -# ROK + * + **/ +#ifdef ANSI +PUBLIC S16 rgSCHCfgPCqiUeCfg +( + RgSchCellCb *cellCb, + RgSchUeCb *ueCb, + RgrUePrdDlCqiCfg *cqiCfg, + CmLteUeCategory ueCat + ) +#else +PUBLIC S16 rgSCHCfgPCqiUeCfg(cellCb, ueCb, cqiCfg, ueCat) + RgSchCellCb *cellCb; + RgSchUeCb *ueCb; + RgrUePrdDlCqiCfg *cqiCfg; + CmLteUeCategory ueCat; +#endif +{ + CmLteTimingInfo timingInfo; + U16 crntTime; + U16 cqiTrInstTime; + U8 j; /*Bandwidth Parts*/ + U8 temp; + U8 loop; + RgSchUePCqiCb *cqiCb = NULLP; + TRC3(rgSCHCfgPCqiUeCfg); + + crntTime = (cellCb->crntTime.sfn * RGSCH_NUM_SUB_FRAMES_5G)+ + (cellCb->crntTime.subframe); + cqiCb = RG_SCH_GET_UE_CELL_CQI_CB(ueCb,cellCb); + cqiCb->servCellInfo = ueCb->cellInfo[0]; + /* Periodic CQI is setup */ + if (cqiCfg->type == RGR_SCH_PCQI_SETUP) + { + for(loop = 0; loop < MAX_CQI_RI_RPT_BUFF;loop++) + { + ueCb->rawCqiBitW[loop].type = TFU_RECP_REQ_INVLD; /* setting invalid type*/ + } + /* 1. Copy the Received CQI Cfg parameters to ueCb */ + cmMemcpy((U8 *)&cqiCb->cqiCfg, (U8 *)cqiCfg, + sizeof(RgrUePrdDlCqiCfg)); + + /* 2. Compute Periodic CQI Periodicity and subframe offset */ +#ifndef LTE_TDD + rgSCHUtlGetCfgPerOff(RG_SCH_FDD_PCQI_TBL, cqiCfg->cqiSetup.cqiPCfgIdx, + &cqiCb->cqiPeri, &cqiCb->cqiOffset); +#else + rgSCHUtlGetCfgPerOff( RG_SCH_TDD_PCQI_TBL, + cqiCfg->cqiSetup.cqiPCfgIdx, + &cqiCb->cqiPeri, &cqiCb->cqiOffset); +#endif + RLOG_ARG3(L_DEBUG,DBG_CELLID,cellCb->cellId, + "rgSCHCfgPCqiUeCfg(): UEID:%d CQI Peri=%d, CQI Offset=%d", + ueCb->ueId, + cqiCb->cqiPeri, + cqiCb->cqiOffset); + + + cqiTrInstTime = ((cqiCb->cqiPeri+crntTime) - cqiCb->cqiOffset) + %cqiCb->cqiPeri; + cqiCb->nCqiTrIdx = (crntTime + + (cqiCb->cqiPeri - cqiTrInstTime)); + /* Introduced timing delta for reception req + * in FDD*/ + if(cqiCb->nCqiTrIdx <= (crntTime + TFU_RECPREQ_DLDELTA)) + { + cqiCb->nCqiTrIdx = cqiCb->nCqiTrIdx + cqiCb->cqiPeri; + } + + /* To handle the SFN wrap around case */ + cqiCb->nCqiTrIdx = cqiCb->nCqiTrIdx % (RGSCH_MAX_SFN * RGSCH_NUM_SUB_FRAMES_5G); + + timingInfo.sfn = cqiCb->nCqiTrIdx/RGSCH_NUM_SUB_FRAMES_5G; + timingInfo.subframe = cqiCb->nCqiTrIdx % RGSCH_NUM_SUB_FRAMES_5G; + + cqiCb->nCqiTrIdx = cqiCb->nCqiTrIdx + %RG_SCH_PCQI_SRS_SR_TRINS_SIZE; + +#ifdef EMTC_ENABLE + /*CQI Repetition configuration*/ + if(ueCb->isEmtcUe) + { + rgSchfillPucchCqiRepNumCountemtc(cqiCb, ueCb); + } +#endif + + if(RGR_UE_PCQI_SB_REP == cqiCfg->cqiSetup.cqiRepType) + { + U8 k; /*SubBand Size (RB) */ + RG_SCH_GET_CQI_J_VAL(cellCb->bwCfg.dlTotalBw, j); + RG_SCH_GET_CQI_K_VAL(cellCb->bwCfg.dlTotalBw, k); + cqiCb->J = j; /*Number of Bandwidth Parts*/ + /*h: reporting instances required for a complete CQI/PMI report */ + /*j:Number of bandwidth parts; k: Subband Size*/ + cqiCb->h = (cqiCb->cqiCfg.cqiSetup.k *j )+1; + /* ccpu00140905- L-size is coming as 3 for 100Rbs where it should be 2*/ + temp = RGSCH_CEIL(cellCb->bwCfg.dlTotalBw, (j*k)); + cqiCb->label = (temp & (temp-1)) ? + (1+ rgSCHUtlLog32bitNbase2(temp)) : rgSCHUtlLog32bitNbase2(temp); + + rgSCHTomUtlPcqiSbCalcBpIdx(timingInfo,ueCb, cqiCb); + } +#ifdef LTE_ADV + else + { + cqiCb->prioLvl = RG_SCH_CQI_PRIO_LVL_1; + } +#endif + + /* Place the UE in cellCb->tIUeLstCp */ + cqiCb->cqiLstEnt.node=(PTR) cqiCb; +#ifdef LTE_ADV + cqiCb->isCqiIgnoByCollsn = FALSE; + cqiCb->isRiIgnoByCollsn = FALSE; +#endif + + + cmLListAdd2Tail(&cellCb->pCqiSrsSrLst[cqiCb->nCqiTrIdx].cqiLst, + &cqiCb->cqiLstEnt); + + + /* 4. Rank Indicator Cfg handler */ + rgSCHCfgRiUeCfg(cellCb, ueCb, cqiCfg, ueCat); + } + else + { + cqiCb->cqiCfg.type = RGR_SCH_PCQI_REL; + if(cqiCb->nCqiTrIdx != RG_SCH_INVALID_IDX) + { + cmLListDelFrm(&cellCb->pCqiSrsSrLst[cqiCb->nCqiTrIdx].cqiLst,\ + &cqiCb->cqiLstEnt); + } + if(cqiCb->nRiTrIdx != RG_SCH_INVALID_IDX) + { + cmLListDelFrm(&cellCb->pCqiSrsSrLst[cqiCb->nRiTrIdx].riLst, \ + &cqiCb->riLstEnt); + RG_SCH_RECORD(&cqiCb->histElem,RGSCH_ACTION_DEL, + &cellCb->pCqiSrsSrLst[cqiCb->nRiTrIdx].riLst); + } + cqiCb->nCqiTrIdx = RG_SCH_INVALID_IDX; + cqiCb->nRiTrIdx = RG_SCH_INVALID_IDX; + cqiCb->riDist = RG_SCH_INVALID_IDX; + } + ueCb->nPCqiCb = cqiCb; + ueCb->nPRiCb = cqiCb; + RETVALUE(ROK); +} + +/** + * @brief Handles Periodic RI configuration for a UE. + * + * @details + * + * Function : rgSCHCfgRiUeCfg + * + * Invoking Module Processing: + * - This shall be invoked by SCH_GOM at UE configuration. It shall do the + * validations for the spec-defined values. + * + * Processing Steps: + * - For UE-specific Periodic RI related configuration, + * - If Periodic RI is configured, + * - Update UE with the configured values. + - Compute and Update next occurance of RI Tranmission instance. + - Update the RI offset and RI perodicity information + * + * - Return ROK + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ue + * @param[in] RgrUePrdDlCqiCfg *cqiCfg + * @param[in] CmLteUeCategory ueCat + * @return S16 + * -# ROK + * + **/ +#ifdef ANSI +PUBLIC S16 rgSCHCfgRiUeCfg +( + RgSchCellCb *cellCb, + RgSchUeCb *ueCb, + RgrUePrdDlCqiCfg *cqiCfg, + CmLteUeCategory ueCat + ) +#else +PUBLIC S16 rgSCHCfgRiUeCfg(cellCb, ueCb, cqiCfg, ueCat) + RgSchCellCb *cellCb; + RgSchUeCb *ueCb; + RgrUePrdDlCqiCfg *cqiCfg; + CmLteUeCategory ueCat; +#endif +{ + U16 crntTime; + U16 riTrInsTime; + U8 j; /*Bandwidth parts. Valid for Modes 2-0, 2-1*/ + U16 periodicity; + U16 tempIdx; + RgSchUePCqiCb *cqiCb = NULLP; + + TRC3(rgSCHCfgRiUeCfg); + + + + crntTime = (cellCb->crntTime.sfn * RGSCH_NUM_SUB_FRAMES_5G) + +(cellCb->crntTime.subframe); + cqiCb = RG_SCH_GET_UE_CELL_CQI_CB(ueCb,cellCb); + /* 1. Rank Indicator is enabled */ + if(cqiCfg->cqiSetup.riEna) + { + + rgSCHUtlGetCfgPerOff(RG_SCH_RI_TBL, + cqiCfg->cqiSetup.riCfgIdx, + &cqiCb->riPeri, &cqiCb->riOffset); + + RLOG_ARG3(L_DEBUG,DBG_CELLID,cellCb->cellId, + "rgSCHCfgRiUeCfg(): RI Peri=%d, RI Offset=%d UEID:%d", + cqiCb->riPeri, cqiCb->riOffset,ueCb->ueId); + + cqiCb->perRiVal = 1; + cqiCb->invalidateCqi = FALSE; + + if(RGR_UE_PCQI_WB_REP == cqiCfg->cqiSetup.cqiRepType) + { + /* + 1. wideband RI reporting is configured + (Mode 1-0 or 1-1) + (10*sfn+floor(subframe)-Noffsetcqi-NoffsetRI )Mod(NCqiperiod + *MriPeriod)=0 + */ + periodicity = cqiCb->cqiPeri * cqiCb->riPeri; + } + else + { + /* + * Where Widesband and Subband RI reporting is configured + * (Mode 2-0 or 2-1 ) + * (10*sfn+floor(subframe)-Noffsetcqi-NoffsetRI ) + * Mod(H. NCqiperiod *MriPeriod )=0 + * where H= J * K +1; J=Number of bandwidth parts(BW/subsize). + * K is RGR interf input + */ + + RG_SCH_GET_CQI_J_VAL(cellCb->bwCfg.dlTotalBw, j); + cqiCb->h = (cqiCb->cqiCfg.cqiSetup.k *j )+1; + periodicity = cqiCb->h * cqiCb->cqiPeri * + cqiCb->riPeri; + } + + /* In case of SFN wraparound, the SB CQI reporting cycle breaks + * and RI->WB CQI->SBCQI.. should resume. RI is repositioned + * accordingly. WBCQI handling is naturally accomplished */ + if (periodicity >= RGSCH_MAX_SUBFRM_5G) + { + periodicity = cqiCb->cqiOffset - cqiCb->riOffset + + RGSCH_MAX_SUBFRM_5G - (crntTime); + tempIdx = crntTime + periodicity; + printf("CHECK_SID - periodicity %d tempIdx %d\n", periodicity, tempIdx); + } + else + { + if ((crntTime + TFU_RECPREQ_DLDELTA + periodicity) > + (RGSCH_MAX_SUBFRM_5G - 1)) + { + riTrInsTime = (periodicity - cqiCb->cqiOffset + cqiCb->riOffset) % periodicity; + tempIdx = RGSCH_MAX_SUBFRM_5G + (periodicity - riTrInsTime); + } + else + { + riTrInsTime = ((periodicity +crntTime )- \ + cqiCb->cqiOffset + cqiCb->riOffset)\ + % periodicity; + tempIdx = (crntTime + (periodicity -riTrInsTime)); + } + } + if (tempIdx <= (crntTime + TFU_RECPREQ_DLDELTA)) + { + tempIdx = tempIdx + periodicity; + } + cqiCb->nRiTrIdx = tempIdx + % RG_SCH_PCQI_SRS_SR_TRINS_SIZE; + if(periodicity >= RG_SCH_PCQI_SRS_SR_TRINS_SIZE) + { + cqiCb->riDist = rgSCHUtlFindDist((U16)(crntTime + TFU_RECPREQ_DLDELTA), + (U16) tempIdx); + } + else + { + cqiCb->riDist =0; + } + if(ueCb->mimoInfo.txMode == RGR_UE_TM_3 + || ueCb->mimoInfo.txMode == RGR_UE_TM_4) + { + if (cellCb->numTxAntPorts ==2) + { + cqiCb->riNumBits = 1; + } + else if(cellCb->numTxAntPorts ==4) + { + if(ueCat == CM_LTE_UE_CAT_8) + { + cqiCb->riNumBits = 3; + } + else if(ueCat >= CM_LTE_UE_CAT_5) + { + cqiCb->riNumBits = 2; + } + else + { + cqiCb->riNumBits = 1; + } + } + } + /* Place the UE in cellCb->tIUeLstCp */ + cqiCb->riLstEnt.node=(PTR) cqiCb; + + cmLListAdd2Tail(&cellCb->pCqiSrsSrLst[cqiCb->nRiTrIdx].riLst, + &cqiCb->riLstEnt); + RG_SCH_RECORD(&cqiCb->histElem,RGSCH_ACTION_ADD, + &cellCb->pCqiSrsSrLst[cqiCb->nRiTrIdx].riLst); + + + } + else + { + cqiCb->nRiTrIdx = RG_SCH_INVALID_IDX; + cqiCb->riDist = RG_SCH_INVALID_IDX; + } + + RETVALUE(ROK); + +} + +/* @brief Handles SRS configuration for a UE. + * + * @details + * + * Function : rgSCHCfgSrsUeCfg + * + * Invoking Module Processing: + * - This shall be invoked by SCH_GOM at UE configuration. It shall do the + * validations for the spec-defined values. + * + * Processing Steps: + * - For UE-specific SRS related configuration, + * - If SRS is configured, + * - Update UE with the configured values. + - Compute and Update next occurance of SRS Tranmission instance. + - Update the SRS offset and SRS perodicity information + - Add Ue to cell's srs list + * - else + * - next occurance transmission instance of SRS = RG_SCH_INVALID_IDX + * + * - Return ROK + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ue + * @param[in] RgrUeUlSrsCfg *srsCfg + * + * @return S16 + * -# ROK + * -# RFAILED + */ +#ifdef ANSI +PUBLIC S16 rgSCHCfgSrsUeCfg +( + RgSchCellCb *cellCb, + RgSchUeCb *ueCb, + RgrUeUlSrsCfg *srsCfg + ) +#else +PUBLIC S16 rgSCHCfgSrsUeCfg(cellCb, ueCb, srsCfg) + RgSchCellCb *cellCb; + RgSchUeCb *ueCb; + RgrUeUlSrsCfg *srsCfg; +#endif +{ + U16 srsTrInsTime; + U16 crntTime; + U16 tempIdx; + + TRC3(rgSCHCfgSrsUeCfg); + + + crntTime = (cellCb->crntTime.sfn * RGSCH_NUM_SUB_FRAMES_5G) + +(cellCb->crntTime.subframe); + + if(RGR_SCH_SRS_SETUP == srsCfg->type) + { + /* 1. Copy the Received Cfg parameters to local cb */ + cmMemcpy((U8 *)&ueCb->srsCb.srsCfg, (U8 *)srsCfg, sizeof(RgrUeUlSrsCfg)); + +#ifndef LTE_TDD + /* 2. Compute SRS Offset and Periodicity */ + rgSCHUtlGetCfgPerOff( RG_SCH_FDD_SRS_TBL, + srsCfg->srsSetup.srsCfgIdx, + &ueCb->srsCb.peri, &ueCb->srsCb.offset); +#else + rgSCHUtlGetCfgPerOff( RG_SCH_TDD_SRS_TBL, + srsCfg->srsSetup.srsCfgIdx, + &ueCb->srsCb.peri, &ueCb->srsCb.offset); +#endif + + RLOG_ARG3(L_DEBUG,DBG_CELLID,cellCb->cellId, + "rgSCHCfgSrsUeCfg(): SRS Peri=%d, SRS Offset=%d UEID:%d", + ueCb->srsCb.peri,ueCb->srsCb.offset,ueCb->ueId); + + /* 3. Compute next Tranmission index for SRS */ + /* Referenence: 36.213 Section:8.2 + i. SRS transmission instances for TDD with period > 2 and for FDD are + ((10*sfn +Ksrs-suframeoffset))/mod(periodicity)) + FDD: Ksrs is 0...9 + TDD: Ksrs Table 8.2-3: + ii.The SRS transmission instances for TDD (periodicity == 2) + (Ksrs-Toffset)mod(5)==0. Note: This is not supported now + */ + + srsTrInsTime = ((ueCb->srsCb.peri+crntTime) - ueCb->srsCb.offset) + %ueCb->srsCb.peri; + tempIdx = (crntTime + (ueCb->srsCb.peri - srsTrInsTime)); +#ifdef LTE_TDD + if (tempIdx <= (crntTime + TFU_DELTA)) +#else + if (tempIdx <= (crntTime + TFU_RECPREQ_DLDELTA)) +#endif + { + tempIdx = tempIdx + ueCb->srsCb.peri; + } + ueCb->srsCb.nSrsTrIdx =(U16) (tempIdx + % RG_SCH_PCQI_SRS_SR_TRINS_SIZE); + if(ueCb->srsCb.peri >= RG_SCH_PCQI_SRS_SR_TRINS_SIZE) + { +#ifdef LTE_TDD + ueCb->srsCb.srsDist = rgSCHUtlFindDist((U8)(crntTime+TFU_DELTA), + (U16)tempIdx); +#else + ueCb->srsCb.srsDist = rgSCHUtlFindDist((U8)(crntTime + TFU_RECPREQ_DLDELTA), + (U16)tempIdx); +#endif + } + else + { + ueCb->srsCb.srsDist = 0; + } + + /*UE Tx Antenna Selection - START*/ + if(ueCb->ul.ulTxAntSel.pres == TRUE ) + { + /*for both partial and full sounding bandwidth, + and when frequency hopping is disabled */ + ueCb->srsCb.selectedAnt = (crntTime/ueCb->srsCb.peri)%2; + } + else + { + /* TS 36.213 specifies that if Tx Antenna Selection is + disabled/not supported then its Port 0*/ + ueCb->srsCb.selectedAnt=0; + } + ueCb->validTxAnt = ueCb->srsCb.selectedAnt; + /*UE Tx Antenna Selection - ENDS*/ + + ueCb->srsCb.srsLstEnt.node=(PTR)ueCb; + cmLListAdd2Tail(&cellCb->pCqiSrsSrLst[ueCb->srsCb.nSrsTrIdx].srsLst, + &ueCb->srsCb.srsLstEnt); + + + } + else + { + /* SRS Release / Not configured */ + ueCb->srsCb.srsCfg.type = RGR_SCH_SRS_REL; + if(ueCb->srsCb.nSrsTrIdx != RG_SCH_INVALID_IDX) + { + cmLListDelFrm(&cellCb->pCqiSrsSrLst[ueCb->srsCb.nSrsTrIdx].srsLst, + &ueCb->srsCb.srsLstEnt); + } + ueCb->srsCb.nSrsTrIdx = RG_SCH_INVALID_IDX; + ueCb->srsCb.srsLstEnt.node =(PTR) NULLP; + } + + RETVALUE(ROK); +} + + +/* * @brief Handles SR configuration for a UE. + * + * @details + * + * Function : rgSCHCfgSrUeCfg + * + * Invoking Module Processing: + * - This shall be invoked by SCH_GOM at UE configuration. It shall do the + * validations for the spec-defined values. + * + * - If SR is configured, + * - Update UE with the configured values. + - Compute and Update next occurance of SR Tranmission instance. + - Update the SR offset and SR perodicity information + - Add Ue to cell->tIUeLstCp[n] + * - else + * - next occurance transmission instance of SR = RG_INVALID_SR_ID + * + * + * - Return ROK + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ue + * @param[in] RgrUeSrCfg *srCfg + * + * @return S16 + * -# ROK + * -# RFAILED + */ +#ifdef ANSI +PUBLIC S16 rgSCHCfgSrUeCfg +( + RgSchCellCb *cellCb, + RgSchUeCb *ueCb, + RgrUeSrCfg *srCfg + ) +#else +PUBLIC S16 rgSCHCfgSrUeCfg(cellCb, ueCb, srCfg) + RgSchCellCb *cellCb; + RgSchUeCb *ueCb; + RgrUeSrCfg *srCfg; +#endif +{ + U16 srTrInsTime; + U16 crntTime; + + TRC3(rgSCHCfgSrUeCfg); + + + crntTime = (cellCb->crntTime.sfn * RGSCH_NUM_SUB_FRAMES_5G) + +(cellCb->crntTime.subframe); + if(srCfg->type == RGR_SCH_SR_SETUP) + { + /* 1. Copy the Received Cfg parameters to local cb */ + cmMemcpy((U8 *)&ueCb->srCb.srCfg, (U8 *)srCfg, sizeof(RgrUeSrCfg)); + + + /* 2. Compute SR periodicity and offset */ + rgSCHUtlGetCfgPerOff( RG_SCH_SR_TBL, + srCfg->srSetup.srCfgIdx, + &ueCb->srCb.peri, &ueCb->srCb.offset); + + RLOG_ARG4(L_DEBUG,DBG_CELLID,cellCb->cellId , + "SR Config: idx(%u), period (%u) offset (%u) UEID:%d", + srCfg->srSetup.srCfgIdx, + ueCb->srCb.peri, + ueCb->srCb.offset, + ueCb->ueId); +#ifdef EMTC_ENABLE + if(ueCb->isEmtcUe) + { + rgSchfillPucchSrRepNumCountemtc(ueCb); + } +#endif + /* 3. Compute Next Transmission Instance */ + + srTrInsTime = ((ueCb->srCb.peri+crntTime) - ueCb->srCb.offset) + %ueCb->srCb.peri; + ueCb->srCb.nSrTrIdx = (crntTime + (ueCb->srCb.peri- srTrInsTime)); +#ifdef LTE_TDD + if (ueCb->srCb.nSrTrIdx <= (crntTime + TFU_DELTA)) +#else + if (ueCb->srCb.nSrTrIdx <= (crntTime + TFU_RECPREQ_DLDELTA)) +#endif + { + ueCb->srCb.nSrTrIdx = ueCb->srCb.nSrTrIdx + ueCb->srCb.peri; + } + ueCb->srCb.nSrTrIdx = ueCb->srCb.nSrTrIdx + % RG_SCH_PCQI_SRS_SR_TRINS_SIZE; + ueCb->srCb.srLstEnt.node= (PTR) ueCb; + + /* 4. Place UE in Cell SR Tranmisison Instance List */ + cmLListAdd2Tail(&cellCb->pCqiSrsSrLst[ueCb->srCb.nSrTrIdx].srLst, + &ueCb->srCb.srLstEnt); + } + else + { + ueCb->srCb.srCfg.type = RGR_SCH_SR_REL; + + if(ueCb->srCb.nSrTrIdx != RG_SCH_INVALID_IDX) + { + cmLListDelFrm(&cellCb->pCqiSrsSrLst[ueCb->srCb.nSrTrIdx].srLst, + &ueCb->srCb.srLstEnt); + } + ueCb->srCb.nSrTrIdx = RG_SCH_INVALID_IDX; + ueCb->srCb.srLstEnt.node = (PTR)NULLP; + } + + RETVALUE(ROK); +} + + +/***************************************************************** + * UE PCQI, RI, SRS and SR Re Configuration Functions * + * * + ******************************************************************/ + + +/* * @brief Handles Periodic CQI, PMI, RI Re-configuration for a UE. + * + * @details + * + * Function : rgSCHCfgPCqiUeReCfg + * + * Invoking Module Processing: + * - This shall be invoked by SCH_GOM at UE Re configuration. It shall do the + * validations for the spec-defined values. + * + * Processing Steps: + * - For UE-specific Periodic CQI related configuration, + * - If Periodic CQI/PMI is re configured(first time enabled), + * - Update UE with the configured values. + * - Compute and Update next occurance of CQI/PMI or RI Tranmission + * instance. + * - Update the CQI offset and CQI perodicity information + * - Add Ue to cell's list + * - If Periodic CQI/PMI is re configured(modify), + * - Update UE with the configured values. + * - Del Ue from cell->tIUeLstCp list + * - Compute and Update next occurance of CQI/PMI or RI Tranmission + * instance. + * - Update the CQI offset and CQI perodicity information + * - Add Ue to cell's list + * - If Periodic CQI/PMI is re configured(disabled), + * - Update UE with the configured values. + * - Del Ue from cell's list + * - Update next occurance of CQI/PMI or RI Tranmission instance. + * - next occurance of CQI/PMI = RG_INVALID_CQIPMI_ID + * + * - For UE-specific Periodic RI related configuration, + * - If Periodic RI is configured(first time enabled), + * - Update UE with the configured values. + * - Compute and Update next occurance of RI Tranmission instance. + * - Update the RI offset and RI perodicity information + * - If Periodic RI is configured(modify), + * - Update UE with the configured values. + * - Compute and Update next occurance of RI Tranmission instance. + * - Update the RI offset and RI perodicity information + * - else + * - next occurance of RI = RG_INVALID_CQIPMI_ID + * + * - Return ROK + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ue + * @param[in] RgrUeCfg *ueCfg + * + * @return S16 + * -# ROK + * + */ +#ifdef ANSI +PUBLIC S16 rgSCHCfgPCqiUeReCfg +( + RgSchCellCb *cellCb, + RgSchUeCb *ueCb, + RgrUePrdDlCqiCfg *cqiCfg, + CmLteUeCategory ueCat + ) +#else +PUBLIC S16 rgSCHCfgPCqiUeReCfg(cellCb, ueCb, cqiCfg, ueCat) + RgSchCellCb *cellCb; + RgSchUeCb *ueCb; + RgrUePrdDlCqiCfg *cqiCfg; + CmLteUeCategory ueCat; +#endif +{ + + RgSchUePCqiCb *cqiCb = NULLP; + TRC3(rgSCHCfgPCqiUeReCfg); + + cqiCb = RG_SCH_GET_UE_CELL_CQI_CB(ueCb,cellCb); + /* Fix: ccpu00124008 Fix for incorrect check causing missed CQI reception instance */ + if((cqiCfg->type == RGR_SCH_PCQI_SETUP) && + (cqiCb->cqiCfg.type != RGR_SCH_PCQI_SETUP)) + { + /* 1. cqi is in Release (Disable) state, Recfg is allowing Setup (Enable) + */ + rgSCHCfgPCqiUeCfg(cellCb, ueCb, cqiCfg, ueCat); + + } + else if((cqiCfg->type == RGR_SCH_PCQI_SETUP) && + (cqiCb->cqiCfg.type == RGR_SCH_PCQI_SETUP )) + { + + /* + 2. Present is SETUP(Enable) state, Recfg is modifying SETUP(Enable) + + 2.1 Delete UE from the cqiList + 2.2 Set next occurance Transmission instace to "INVALID" + 2.3 Compute Next occurance Transmission instace + 2.4 Placed ue in Transmission instance list. + */ + if(cqiCb->nCqiTrIdx != RG_SCH_INVALID_IDX ) + cmLListDelFrm(&cellCb->pCqiSrsSrLst[cqiCb->nCqiTrIdx].cqiLst, + &cqiCb->cqiLstEnt); + + if(cqiCb->nRiTrIdx != RG_SCH_INVALID_IDX ) + { + cmLListDelFrm(&cellCb->pCqiSrsSrLst[cqiCb->nRiTrIdx].riLst, + &cqiCb->riLstEnt); + RG_SCH_RECORD(&cqiCb->histElem,RGSCH_ACTION_DEL, + &cellCb->pCqiSrsSrLst[cqiCb->nRiTrIdx].riLst); + } + + + cqiCb->cqiLstEnt.next = NULLP; + cqiCb->cqiLstEnt.prev = NULLP; + cqiCb->nCqiTrIdx = RG_SCH_INVALID_IDX; + cqiCb->nRiTrIdx = RG_SCH_INVALID_IDX; + cqiCb->riDist = RG_SCH_INVALID_IDX; + + rgSCHCfgPCqiUeCfg(cellCb, ueCb, cqiCfg, ueCat); + } + else + { + /* Present is SETUP(Enable) state, Recfg is Release(Disable) */ + rgSCHCfgPCqiUeCfg(cellCb, ueCb, cqiCfg, ueCat); + } + + /* ccpu00140578:: */ + cqiCb->riRecpPrcsd = FALSE; + RETVALUE(ROK); +} + + +/* * @brief Handles SRS Re-configuration for a UE. + * + * @details + * + * Function : rgSCHCfgSrsUeReCfg + * + * Invoking Module Processing: + * - This shall be invoked by SCH_GOM at UE Re configuration. It shall do the + * validations for the spec-defined values. + * + * Processing Steps: + * - For UE-specific SRS related re configuration, + * - If SRS is configured modified(First time Enabled), + * - Update UE with the configured values. + * - Compute and Update next occurance of SRS Tranmission instance. + * - Update the SRS offset and SRS perodicity information + * - Add Ue to cell's list + * - If SRS is configured modified(Changed offset or index ), + * - Delete UE from cell->tIUeLstCp[n] if present + * - Update UE with the configured values. + * - Compute and Update next occurance of SRS Tranmission instance. + * - Update the SRS offset and SRS perodicity information + * - Add Ue to cell's list + * - If SRS is configured modified(disabled), + * - Delete UE from cell->tIUeLstCp[n] if present + * - Update next occurance of SRS Tranmission instance to "INVALID". + * - Update the SRS offset and SRS perodicity information "INVALID" + * - else + * - ROK + * + * - Return ROK + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ue + * @param[in] RgrUeUlSrsCfg *srsCfg + * + * @return S16 + * -# ROK + * -# RFAILED + */ +#ifdef ANSI +PUBLIC S16 rgSCHCfgSrsUeReCfg +( + RgSchCellCb *cellCb, + RgSchUeCb *ueCb, + RgrUeUlSrsCfg *srsCfg + ) +#else +PUBLIC S16 rgSCHCfgSrsUeReCfg(cellCb, ueCb, srsCfg) + RgSchCellCb *cellCb; + RgSchUeCb *ueCb; + RgrUeUlSrsCfg *srsCfg; +#endif +{ + + TRC3(rgSCHCfgSrsUeReCfg); + + + + if(( RGR_SCH_SRS_SETUP == srsCfg->type) || + ( RGR_SCH_SRS_SETUP != ueCb->srsCb.srsCfg.type )) + { + /* 1. Present is Release(Disable) state, Recfg is allowing + * SETUP(Enable) */ + rgSCHCfgSrsUeCfg(cellCb, ueCb, srsCfg); + } + else if (( RGR_SCH_SRS_SETUP == srsCfg->type ) && + ( RGR_SCH_SRS_SETUP == ueCb->srsCb.srsCfg.type)) + { + + /* 2. Present is SETUP(Eanble) state, Recfg is modifying SETUP(Enable) + + 2.1 Delete UE from the cqiList + 2.2 Set next occurance Transmission instance to "INVALID" + 2.3 Compute Next occurance Transmission instance + 2.4 Placed ue in Transmission instance list. + */ + if (ueCb->srsCb.nSrsTrIdx != RG_SCH_INVALID_IDX) + { + cmLListDelFrm(&cellCb->pCqiSrsSrLst[ueCb->srsCb.nSrsTrIdx].srsLst, + &ueCb->srsCb.srsLstEnt); + ueCb->srsCb.nSrsTrIdx = RG_SCH_INVALID_IDX; + } + + rgSCHCfgSrsUeCfg(cellCb, ueCb, srsCfg); + } + else + { + /* 3. Present is SETUP(Enable) state, Recfg is Release(Disable)*/ + rgSCHCfgSrsUeCfg(cellCb, ueCb, srsCfg); + } + /* ccpu00140578:: */ + ueCb->srsCb.srsRecpPrcsd = FALSE; + + RETVALUE(ROK); +} + +/* @brief Handles SR Re-configuration for a UE. + * + * @details + * + * Function : rgSCHCfgSrUeReCfg + * + * Invoking Module Processing: + * - This shall be invoked by SCH_GOM at UE Re configuration. + * It shall do the validations for the spec-defined values. + * + * Processing Steps: + * - For UE-specific SR related re configuration, + * - If SR is configured modified(First time Enabled), + * - Update UE with the configured values. + * - Compute and Update next occurance of SR Tranmission instance. + * - Update the SR offset and SR perodicity information + * - Add Ue to cell->tIUeLstCp[n] + * - If SR is configured modified(Changed offset or index ), + * - Delete UE from cell->tIUeLstCp[n] if present + * - Update UE with the configured values. + * - Compute and Update next occurance of SR Tranmission instance. + * - Update the SR offset and SR perodicity information + * - Add Ue to cell->tIUeLstCp[n] + * - If SR is configured modified(disabled), + * - Delete UE from cell->tIUeLstCp[n] if present + * - Update next occurance of SR Tranmission instance to "INVALID". + * - Update the SR offset and SR perodicity information "INVALID" + * - else + * - ROK + * + * + * + * - Return ROK + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ue + * @param[in] RgrUeCfg *ueCfg + * + * @return S16 + * -# ROK + * -# RFAILED + */ +#ifdef ANSI +PUBLIC S16 rgSCHCfgSrUeReCfg +( + RgSchCellCb *cellCb, + RgSchUeCb *ueCb, + RgrUeSrCfg *srCfg + ) +#else +PUBLIC S16 rgSCHCfgSrUeReCfg(cellCb, ueCb, srCfg) + RgSchCellCb *cellCb; + RgSchUeCb *ueCb; + RgrUeSrCfg *srCfg; +#endif +{ + TRC3(rgSCHCfgSrUeReCfg); + + + /* Fix : syed Incorrect check for SR RECFG */ + if((srCfg->type == RGR_SCH_SR_SETUP) && + (ueCb->srCb.srCfg.type != RGR_SCH_SR_SETUP)) + { + /* + 1. Present is Release(Disable) state, Recfg is allowing SETUP(Enable) + */ + rgSCHCfgSrUeCfg(cellCb, ueCb, srCfg); + } + else if((srCfg->type == RGR_SCH_SR_SETUP) && + (ueCb->srCb.srCfg.type == RGR_SCH_SR_SETUP)) + { + + /* 2. Present is SETUP(Eanble) state, Recfg is modifying SETUP(Enable) + + 2.1 Delete UE from the cqiList + 2.2 Compute Next occurance Transmission instace + */ + if(ueCb->srCb.nSrTrIdx != RG_SCH_INVALID_IDX ) + { + cmLListDelFrm(&cellCb->pCqiSrsSrLst[ueCb->srCb.nSrTrIdx].srLst, + &ueCb->srCb.srLstEnt); + ueCb->srCb.nSrTrIdx = RG_SCH_INVALID_IDX; + } + rgSCHCfgSrUeCfg(cellCb, ueCb, srCfg); + + } + else + { + /* 3. Present is SETUP(Enable) state, Recfg is Release(Disable) */ + rgSCHCfgSrUeCfg(cellCb, ueCb, srCfg); + } + + RETVALUE(ROK); +} + +/* @brief Handles ACQI Re-configuration for a UE. + * + * @details + * + * Function : rgSCHCfgAcqiUeReCfg + * + * Invoking Module Processing: + * - This shall be invoked by SCH_GOM at UE Re configuration. + * It shall do the validations for the spec-defined values. + * + * Processing Steps: + * - For UE-specific ACQI related re configuration, + * - Check if the ACQI Mode has been changed from the + * existing Configuration. + * - If the configuration has been changed, + * - Call Aperiodic Config function to change the config + * - else + * - ROK + * + * + * - Return ROK + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ue + * @param[in] RgrUeAprdDlCqiCfg *acqiCfg + * + * @return S16 + * -# ROK + * -# RFAILED + */ +#ifdef ANSI +PUBLIC S16 rgSCHCfgAcqiUeReCfg +( + RgSchCellCb *cellCb, + RgSchUeCb *ueCb, + RgrUeAprdDlCqiCfg *acqiCfg, + CmLteUeCategory ueCat + ) +#else +PUBLIC S16 rgSCHCfgAcqiUeReCfg(cellCb, ueCb, acqiCfg, ueCat) + RgSchCellCb *cellCb; + RgSchUeCb *ueCb; + RgrUeAprdDlCqiCfg *acqiCfg; + CmLteUeCategory ueCat; +#endif +{ + TRC3(rgSCHCfgAcqiUeReCfg); + + RETVALUE(rgSCHCfgACqiUeCfg(cellCb,ueCb,(RG_SCH_CMN_GET_ACQICB(ueCb,cellCb)) + ,ueCb->mimoInfo.txMode, acqiCfg, ueCat)); + +} + +/***************************************************************** + * UE PCQI, RI, SRS and SR Configuration Delete * + * * + *****************************************************************/ + +/* @brief Free Periodic CQI/PMI/RI, SRS and SR transmission instance + * related data structures of this UE from CellCb + * + * @details + * + * Function : rgSCHCfgPCqiSrsSrUeDel + * + * Invoking Module Processing: + * - This shall be invoked by SCH_GOM at Ue deletion. + * + * Processing Steps: + * - For SRS Transmission Instance + * - if (srsTxInst!= RG_INVALID) + * - Remove from the cellCb->tIUeLstCp[srsTxInst*3+2] + * - else + * - Nothing to do + * - For SR Transmission Instance + * - if (srTxInst!= RG_INVALID) + * - Remove from the cellCb->tIUeLstCp[srTxInst*3+1] + * - else + * - Nothing to do + * - For Periodic CQI/PMI RI Transmission Instance + * - if (pCqiTxInst!= RG_INVALID) + * - Remove from the cellCb->tIUeLstCp[srTxInst*3+0] + * - else + * - Nothing to do + * - Return ROK + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ue + * + * @return S16 + * -# ROK + */ +#ifdef ANSI +PUBLIC S16 rgSCHCfgPCqiSrsSrUeDel +( + RgSchCellCb *cellCb, + RgSchUeCb *ueCb + ) +#else +PUBLIC S16 rgSCHCfgPCqiSrsSrUeDel(cellCb, ueCb) + RgSchCellCb *cellCb; + RgSchUeCb *ueCb; +#endif +{ +#ifdef LTE_ADV + U32 cellIdx; + U32 sCellCnt = 0; +#endif + RgSchUePCqiCb *cqiRiCb = NULLP; + TRC3(rgSCHCfgPCqiSrsSrUeDel); + + cqiRiCb = RG_SCH_GET_UE_CELL_CQI_CB(ueCb,cellCb); + + + + /* Delete SRS Transmission Instance */ + if (ueCb->srsCb.nSrsTrIdx != RG_SCH_INVALID_IDX) + { + cmLListDelFrm(&cellCb->pCqiSrsSrLst[ueCb->srsCb.nSrsTrIdx].srsLst, + &ueCb->srsCb.srsLstEnt); + ueCb->srsCb.nSrsTrIdx = RG_SCH_INVALID_IDX; + } + + /* Delete SR Transmission Instance */ + if (ueCb->srCb.nSrTrIdx != RG_SCH_INVALID_IDX) + { + cmLListDelFrm(&cellCb->pCqiSrsSrLst[ueCb->srCb.nSrTrIdx].srLst, + &ueCb->srCb.srLstEnt); + ueCb->srCb.nSrTrIdx = RG_SCH_INVALID_IDX; + } + + /* Delete Periodic CQI/PMI Transmission Instance */ + if (cqiRiCb->nCqiTrIdx != RG_SCH_INVALID_IDX) + { + cmLListDelFrm(&cellCb->pCqiSrsSrLst[cqiRiCb->nCqiTrIdx].cqiLst, + &cqiRiCb->cqiLstEnt); + cqiRiCb->nCqiTrIdx = RG_SCH_INVALID_IDX; + + /* Delete Periodic RI Transmission Instance */ + + if (cqiRiCb->nRiTrIdx != RG_SCH_INVALID_IDX) + { + cmLListDelFrm(&cellCb->pCqiSrsSrLst[cqiRiCb->nRiTrIdx].riLst, + &cqiRiCb->riLstEnt); + RG_SCH_RECORD(&cqiRiCb->histElem,RGSCH_ACTION_DEL, + &cellCb->pCqiSrsSrLst[cqiRiCb->nRiTrIdx].riLst); + cqiRiCb->nRiTrIdx = RG_SCH_INVALID_IDX; + } + } + +#ifdef LTE_ADV + for (cellIdx =1; cellIdx <= RG_SCH_MAX_SCELL; cellIdx++) + { + /* If a serving cell is configured */ + if(ueCb->cellInfo[cellIdx] != NULLP) + { + /* If the serving cell is in ACTIVE state and + If it is not the same serving cell as cqiRiCb for which + collision is being checked */ + cqiRiCb = &ueCb->cellInfo[cellIdx]->cqiCb; + /* Delete Periodic CQI/PMI Transmission Instance */ + if (cqiRiCb->nCqiTrIdx != RG_SCH_INVALID_IDX) + { + cmLListDelFrm(&cellCb->pCqiSrsSrLst[cqiRiCb->nCqiTrIdx].cqiLst, + &cqiRiCb->cqiLstEnt); + cqiRiCb->nCqiTrIdx = RG_SCH_INVALID_IDX; + + /* Delete Periodic RI Transmission Instance */ + + if (cqiRiCb->nRiTrIdx != RG_SCH_INVALID_IDX) + { + cmLListDelFrm(&cellCb->pCqiSrsSrLst[cqiRiCb->nRiTrIdx].riLst, + &cqiRiCb->riLstEnt); + RG_SCH_RECORD(&cqiRiCb->histElem,RGSCH_ACTION_DEL, + &cellCb->pCqiSrsSrLst[cqiRiCb->nRiTrIdx].riLst); + cqiRiCb->nRiTrIdx = RG_SCH_INVALID_IDX; + } + } + sCellCnt++; + /* If all of the num of configured scells are checked then break */ + if (sCellCnt == ueCb->numSCells) + { + break; + } + } + } +#endif + + RETVALUE(ROK); +} + + +/* @brief Search the cfgIdx in given table and retrive periodicity & offset + * @details + * + * Function : rgSCHUtlGetCfgPerOff + * + * Invoking Module Processing: + * - This shall be invoked by Cfg Module + * + * Processing Steps: + * binary search for given entry in table + * find the periodicty, offset for a given config index from the table + * - Return ROK + * @param[in] RgSchPerTbl tbl + * @param[in] U16 cfgIdx + * @param[out] U16 *peri + * @param[out] U16 *offset + * + * @return S16 + * -# ROK + * + */ +#ifdef ANSI +PUBLIC S16 rgSCHUtlGetCfgPerOff +( + RgSchPerTbl tbl, + U16 cfgIdx, + U16 *peri, + U16 *offset + ) +#else +PUBLIC S16 rgSCHUtlGetCfgPerOff ( tbl, cfgIdx, peri, offset) + RgSchPerTbl tbl; + U16 cfgIdx; + U16 *peri; + U16 *offset; +#endif +{ + U8 mid; + U8 min = 0; + U8 max = 0; + CONSTANT RgSchUePCqiSrsSrCfgIdxTbl* table; + TRC3(rgSCHUtlGetCfgPerOff); + + /* Added the function instead of the MACRO to get the + * periodicity table */ + table = rgSCHCfgUtlGetPcqiSrsSrRiTbl ( tbl,&min,&max ); + do{ + mid = (min+max)/2; + if (( cfgIdx >= table[mid].min) && + ( cfgIdx <= table[mid].max)) + { + *peri = table[mid].peri; + *offset = cfgIdx - table[mid].offset; + break; + } + + if ( cfgIdx > table[mid].min) + { + min = mid+1; + } + else + { + max = mid-1; + } + + }while( min <= max ); + + RETVALUE(ROK); +} + + +/*********************************************************** + * + * Func : rgSCHCfgUtlFetchAcqiBitSz + * + * + * Desc : Fetch the CQI/PMI bits for a UE based on the mode and store them + * for decoding. + * + * Ret : Void + * ROK - RETVOID + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PRIVATE Void rgSCHCfgUtlFetchAcqiBitSz +( + RgSchUeACqiCb *acqiCb, + U8 numTxAnt, + U8* cqiPmiSzR1, + U8* cqiPmiSzRn1 + ) +#else +PRIVATE Void rgSCHCfgUtlFetchAcqiBitSz(acqiCb, numTxAnt, cqiPmiSzR1, cqiPmiSzRn1) + RgSchUeACqiCb *acqiCb; + U8 numTxAnt; + U8* cqiPmiSzR1; + U8* cqiPmiSzRn1; +#endif +{ + + U32 confRepMode; + + + TRC3(rgSCHCfgUtlFetchAcqiBitSz); + + confRepMode = acqiCb->aCqiCfg.aprdModeEnum; + switch(confRepMode) + { + case RGR_APRD_CQI_MOD12: + { + if(numTxAnt == 2) + { + *cqiPmiSzR1 = 4 + 2*acqiCb->N; + *cqiPmiSzRn1 = 8+ acqiCb->N; + } + else if(numTxAnt == 4) + { + *cqiPmiSzR1 = 4 + 4*acqiCb->N; + *cqiPmiSzRn1 = 8 + 4*acqiCb->N; + } + } + break; + + case RGR_APRD_CQI_MOD20: + { + *cqiPmiSzR1 = 6 + acqiCb->L; + *cqiPmiSzRn1 = 6 + acqiCb->L; + } + break; + + case RGR_APRD_CQI_MOD22: + { + if(numTxAnt == 2) + { + *cqiPmiSzR1 = 10 + acqiCb->L; + *cqiPmiSzRn1 = 14 + acqiCb->L; + } + else if(numTxAnt == 4) + { + *cqiPmiSzR1 = 14 + acqiCb->L; + *cqiPmiSzRn1 = 20 + acqiCb->L; + } + } + break; + + case RGR_APRD_CQI_MOD30: + { + *cqiPmiSzR1 = 4 + 2*acqiCb->N; + *cqiPmiSzRn1 = 4 + 2*acqiCb->N; + } + break; + + case RGR_APRD_CQI_MOD31: + { + if(numTxAnt == 2) + { + *cqiPmiSzR1 = 6 + 2*acqiCb->N; + *cqiPmiSzRn1 = 9 + 4*acqiCb->N; + } + else if(numTxAnt == 4) + { + *cqiPmiSzR1 = 8 + 2*acqiCb->N; + *cqiPmiSzRn1 = 12 + 4*acqiCb->N; + } + } + break; + default: + break; + } + RETVOID; +} +/* Added the function rgSCHCfgUtlGetPcqiCrsSrRiTbl to be used + * instead of the MACRO RG_SCH_GET_PERIODICITY_TBL */ +/*********************************************************** + * + * Func : rgSCHCfgUtlGetPcqiCrsSrRiTbl + * + * + * Desc : Get the Srs Cqi Crs Ri Table + * + * Ret : Void + * ROK - RETVOID + * + * Notes: + * + * File : + * + **********************************************************/ + +#ifdef ANSI +PRIVATE CONSTANT RgSchUePCqiSrsSrCfgIdxTbl * rgSCHCfgUtlGetPcqiSrsSrRiTbl +( + RgSchPerTbl tblType, + U8* min, + U8* max +) +#else +PRIVATE CONSTANT RgSchUePCqiSrsSrCfgIdxTbl * rgSCHCfgUtlGetPcqiSrsSrRiTbl(tblType, min, max) + RgSchPerTbl tblType; + U8* min; + U8* max; +#endif +{ + CONSTANT RgSchUePCqiSrsSrCfgIdxTbl * table; + TRC3(rgSCHCfgUtlGetPcqiCrsSrRiTbl); + + switch (tblType) + { + + case RG_SCH_FDD_PCQI_TBL: + { + table = rgSchUePCqiCfgIdxFddTbl; + * min = 0; + * max=RG_SCH_CQIPMI_CFGIDX_MAX_FDD; + break; + } + case RG_SCH_TDD_PCQI_TBL: + { + table = rgSchUeCqiPmiCfgIdxTddTbl; + * min = 0; + * max=RG_SCH_CQIPMI_CFGIDX_MAX_TDD; + break; + } + case RG_SCH_RI_TBL: + { + table = rgSchUeRiCfgIdxTbl; + * min = 0; + * max=RG_SCH_RI_CFGIDX_MAX; + break; + } + case RG_SCH_FDD_SRS_TBL: + { + table = rgSchUeSrsCfgIdxFddTbl; + * min = 0; + * max=RG_SCH_SRS_ISRS_INDX_MAX_FDD; + break; + } + case RG_SCH_TDD_SRS_TBL: + { + table = rgSchUeSrsCfgIdxTddTbl; + * min = 0; + * max=RG_SCH_SRS_ISRS_INDX_MAX_TDD; + break; + } + case RG_SCH_SR_TBL: + { + table = rgSchUeSrCfgIdxTbl; + * min = 0; + * max=RG_SCH_ISR_INDX_MAX; + break; + } + default: + { + table = (CONSTANT RgSchUePCqiSrsSrCfgIdxTbl *) 0; + * min = 0; + * max = 0; + break; + } + + } + RETVALUE ( table ); +} +/* #endif */ +#endif /* TFU_UPGRADE */ + +/*********************************************************** + * + * Func : rgSCHCfgVldtDrxUeCfg + * + * + * Desc : Validates UE DRX Timers Configuration recieved from RRC. + * + * Ret : S16 + * ROK - Success + * RFAILED - Failed + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PRIVATE S16 rgSCHCfgVldtDrxUeCfg +( +RgSchCellCb *cell, +RgrUeDrxCfg *ueDrxCfg +) +#else +PRIVATE S16 rgSCHCfgVldtDrxUeCfg(cell, ueDrxCfg) +RgSchCellCb *cell; +RgrUeDrxCfg *ueDrxCfg; +#endif +{ + TRC2(rgSCHCfgVldtDrxUeCfg) + + + if (ueDrxCfg->isDrxEnabled == FALSE) + { + RETVALUE(ROK); + } + +#ifdef LTEMAC_R9 + if ( ueDrxCfg->cqiMask.pres ) + { + if ( ueDrxCfg->cqiMask.val != RGR_DRX_SETUP ) + { +#ifdef ALIGN_64BIT + RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,"Invalid cqiMask configuration (%d)", + ueDrxCfg->cqiMask.val); +#else + RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,"Invalid cqiMask configuration(%ld)", + ueDrxCfg->cqiMask.val); +#endif + RETVALUE(RFAILED); + } + } +#endif /*LTEMAC_R9*/ +#ifdef EMTC_ENABLE + if(ueDrxCfg->isEmtcUe) + { + if(ueDrxCfg->drxOnDurTmrR13Pres) + { + if ( rgSCHEmtcCfgVldtDrxOnDurCfg(ueDrxCfg->drxOnDurTmr) != ROK ) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,"Invalid onDurTimer configuration(%d)", + ueDrxCfg->drxOnDurTmr); + RETVALUE(RFAILED); + } + } + else + { + if (rgSCHCfgVldtDrxOnDurCfg(ueDrxCfg->drxOnDurTmr) != ROK ) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,"Invalid onDurTimer configuration(%d) for EMTC", + ueDrxCfg->drxOnDurTmr); + RETVALUE(RFAILED); + } + + } + } + else +#endif + { + if ( rgSCHCfgVldtDrxOnDurCfg(ueDrxCfg->drxOnDurTmr) != ROK ) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,"Invalid onDurTimer configuration(%d) for EMTC", + ueDrxCfg->drxOnDurTmr); + RETVALUE(RFAILED); + } + } + + if ( rgSCHCfgVldtDrxInActvCfg(ueDrxCfg->drxInactvTmr) != ROK ) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,"Invalid Inactivity configuration(%d)", + ueDrxCfg->drxInactvTmr); + RETVALUE(RFAILED); + } +#ifdef EMTC_ENABLE + if(ueDrxCfg->isEmtcUe) + { + if(ueDrxCfg->drxRetxTmrR13Pres) + { + if ( rgSCHEmtcCfgVldtDrxReTxCfg(ueDrxCfg->drxRetxTmr) != ROK ) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,"Invalid DrxReTX configuration(%d) for EMTC", + ueDrxCfg->drxRetxTmr); + RETVALUE(RFAILED); + } + } + else + { + if (rgSCHCfgVldtDrxReTxCfg(ueDrxCfg->drxRetxTmr) != ROK ) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,"Invalid DrxReTX configuration(%d)", + ueDrxCfg->drxRetxTmr); + RETVALUE(RFAILED); + } + + } + } + else +#endif + { + if ( rgSCHCfgVldtDrxReTxCfg(ueDrxCfg->drxRetxTmr) != ROK ) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,"Invalid DrxReTX configuration(%d)", + ueDrxCfg->drxRetxTmr); + RETVALUE(RFAILED); + } + } +#ifdef EMTC_ENABLE + if(ueDrxCfg->isEmtcUe) + { + if ( rgSCHEmtcCfgVldtDrxUlReTxCfg(ueDrxCfg->emtcDrxUlRetxTmr) != ROK ) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,"Invalid DrxReTX configuration(%d) for EMTC", + ueDrxCfg->drxRetxTmr); + RETVALUE(RFAILED); + } + + } +#endif + + if ( rgSCHCfgVldtDrxLngCycCfg(ueDrxCfg->drxLongCycleOffst) != ROK ) + { + RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,"Invalid LongCycle configuration"); + RETVALUE(RFAILED); + } + + if ( ueDrxCfg->drxLongCycleOffst.longDrxCycle < ueDrxCfg->drxOnDurTmr ) + { + RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,"Invalid combination of Long DRX Cycle " + " and onDuration timer values"); + RETVALUE(RFAILED); + } + +#ifdef LTE_TDD + if( rgSCHCfgVldtTddDrxCycCfg(cell, ueDrxCfg->drxLongCycleOffst.longDrxCycle, + ueDrxCfg->drxOnDurTmr, ueDrxCfg->drxLongCycleOffst.drxStartOffst) != ROK) + { + RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,"Invalid combination of Long DRX Cycle " + " and onDuration timer values"); + RETVALUE(RFAILED); + } +#endif + + if( TRUE == ueDrxCfg->drxShortDrx.pres ) + { + if ( ueDrxCfg->drxShortDrx.shortDrxCycle < ueDrxCfg->drxOnDurTmr ) + { + RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,"Invalid combination of short DRX " + "Cycle and onDuration timer values"); + RETVALUE(RFAILED); + } + + if ( (ueDrxCfg->drxLongCycleOffst.longDrxCycle % + ueDrxCfg->drxShortDrx.shortDrxCycle) != 0) + { + RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId," Long DRX cycle is not multiple of " + "short DRX cycle"); + RETVALUE(RFAILED); + } + + if ( rgSCHCfgVldtDrxShrtCycCfg(ueDrxCfg->drxShortDrx) != ROK ) + { + RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,"Invalid Short Cycle configuration"); + RETVALUE(RFAILED); + } + +#ifdef LTE_TDD + if( rgSCHCfgVldtTddDrxCycCfg(cell, ueDrxCfg->drxShortDrx.shortDrxCycle, + ueDrxCfg->drxOnDurTmr, + ueDrxCfg->drxLongCycleOffst.drxStartOffst % + ueDrxCfg->drxShortDrx.shortDrxCycle) != ROK) + { + RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,"Invalid combination of Long DRX Cycle " + " and onDuration timer values"); + RETVALUE(RFAILED); + } +#endif + } + + RETVALUE(ROK); +}/*rgSCHCfgVldtDrxUeCfg*/ + +/*********************************************************** + * + * Func : rgSCHCfgVldtDrxOnDurCfg + * + * + * Desc : Validates UE DRX On Duration configuration + * recieved from RRC. + * + * Ret : S16 + * ROK - Success + * RFAILED - Failed + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PRIVATE S16 rgSCHCfgVldtDrxOnDurCfg +( +U8 onDurTmr +) +#else +PRIVATE S16 rgSCHCfgVldtDrxOnDurCfg(onDurTmr) +U8 onDurTmr; +#endif +{ + TRC2(rgSCHCfgVldtDrxOnDurCfg) + + switch ( onDurTmr ) + { + case RGR_DRX_PRD_1PSF: + case RGR_DRX_PRD_2PSF: + case RGR_DRX_PRD_3PSF: + case RGR_DRX_PRD_4PSF: + case RGR_DRX_PRD_5PSF: + case RGR_DRX_PRD_6PSF: + case RGR_DRX_PRD_8PSF: + case RGR_DRX_PRD_10PSF: + case RGR_DRX_PRD_20PSF: + case RGR_DRX_PRD_30PSF: + case RGR_DRX_PRD_40PSF: + case RGR_DRX_PRD_50PSF: + case RGR_DRX_PRD_60PSF: + case RGR_DRX_PRD_80PSF: + case RGR_DRX_PRD_100PSF: + case RGR_DRX_PRD_200PSF: + break; + + default: + { + RETVALUE(RFAILED); + } + }/*switch(onDurTmr)*/ + + RETVALUE(ROK); +}/*rgSCHCfgVldtOnDurCfg*/ + +/*********************************************************** + * + * Func : rgSCHCfgVldtDrxInActvCfg + * + * + * Desc : Validates UE DRX InActivity configuration + * recieved from RRC. + * + * Ret : S16 + * ROK - Success + * RFAILED - Failed + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PRIVATE S16 rgSCHCfgVldtDrxInActvCfg +( +U16 inActvTmr +) +#else +PRIVATE S16 rgSCHCfgVldtDrxInActvCfg(inActvTmr) +U16 inActvTmr; +#endif +{ + TRC2(rgSCHCfgVldtDrxInActvCfg) + + switch ( inActvTmr ) + { + case RGR_DRX_PRD_1PSF: + case RGR_DRX_PRD_2PSF: + case RGR_DRX_PRD_3PSF: + case RGR_DRX_PRD_4PSF: + case RGR_DRX_PRD_5PSF: + case RGR_DRX_PRD_6PSF: + case RGR_DRX_PRD_8PSF: + case RGR_DRX_PRD_10PSF: + case RGR_DRX_PRD_20PSF: + case RGR_DRX_PRD_30PSF: + case RGR_DRX_PRD_40PSF: + case RGR_DRX_PRD_50PSF: + case RGR_DRX_PRD_60PSF: + case RGR_DRX_PRD_80PSF: + case RGR_DRX_PRD_100PSF: + case RGR_DRX_PRD_200PSF: + case RGR_DRX_PRD_300PSF: + case RGR_DRX_PRD_500PSF: + case RGR_DRX_PRD_750PSF: + case RGR_DRX_PRD_1280PSF: + case RGR_DRX_PRD_1920PSF: + case RGR_DRX_PRD_2560PSF: + break; + + default: + { + RETVALUE(RFAILED); + } + }/*switch(InactvTmr)*/ + + RETVALUE(ROK); +}/*rgSCHCfgVldtDrxInActvCfg*/ + +/*********************************************************** + * + * Func : rgSCHCfgVldtDrxReTxCfg + * + * + * Desc : Validates DRX ReTx timer configuration + * recieved from RRC. + * + * Ret : S16 + * ROK - Success + * RFAILED - Failed + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PRIVATE S16 rgSCHCfgVldtDrxReTxCfg +( +U8 reTxTmr +) +#else +PRIVATE S16 rgSCHCfgVldtDrxReTxCfg(reTxTmr) +U8 reTxTmr; +#endif +{ + TRC2(rgSCHCfgVldtDrxReTxCfg) + + switch ( reTxTmr ) + { + case RGR_DRX_PRD_1PSF: + case RGR_DRX_PRD_2PSF: + case RGR_DRX_PRD_4PSF: + case RGR_DRX_PRD_6PSF: + case RGR_DRX_PRD_8PSF: + case RGR_DRX_PRD_16PSF: + case RGR_DRX_PRD_24PSF: + case RGR_DRX_PRD_33PSF: + break; + + default: + { + RETVALUE(RFAILED); + } + }/*switch(drxRetxTmr)*/ + + RETVALUE(ROK); +}/*rgSCHCfgVldtDrxReTxCfg*/ + +/*********************************************************** + * + * Func : rgSCHCfgVldtDrxShrtCycCfg + * + * + * Desc : Validates DRX Short Cycle timer configuration + * recieved from RRC. + * + * Ret : S16 + * ROK - Success + * + * RFAILED - Failed + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PRIVATE S16 rgSCHCfgVldtDrxLngCycCfg +( +RgrDrxLongCycleOffst lngCycleOffst +) +#else +PRIVATE S16 rgSCHCfgVldtDrxLngCycCfg(lngCycleOffst) +RgrDrxLongCycleOffst lngCycleOffst; +#endif +{ + TRC2(rgSCHCfgVldtDrxLngCycCfg) + + if ( rgSCHCfgVldtDrxLngCyclTmrs(lngCycleOffst.longDrxCycle) != ROK ) + { + RETVALUE(RFAILED); + } + + if ( lngCycleOffst.drxStartOffst >= lngCycleOffst.longDrxCycle ) + { + RETVALUE(RFAILED); + } + + RETVALUE(ROK); +}/*rgSCHCfgVldtDrxLngCycCfg*/ + +/*********************************************************** + * + * Func : rgSCHCfgVldtDrxLngCyclTmrs + * + * + * Desc : Validates DRX Long Cycle timer values + * recieved from RRC. + * + * Ret : S16 + * ROK - Success + * + * RFAILED - Failed + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PRIVATE S16 rgSCHCfgVldtDrxLngCyclTmrs +( +U16 val +) +#else +PRIVATE S16 rgSCHCfgVldtDrxLngCyclTmrs(val) +U16 val; +#endif +{ + TRC2(rgSCHCfgVldtDrxLngCyclTmrs) + + switch ( val ) + { + case RGR_DRX_PRD_10SF: + case RGR_DRX_PRD_20SF: + case RGR_DRX_PRD_32SF: + case RGR_DRX_PRD_40SF: + case RGR_DRX_PRD_64SF: + case RGR_DRX_PRD_80SF: + case RGR_DRX_PRD_128SF: + case RGR_DRX_PRD_160SF: + case RGR_DRX_PRD_256SF: + case RGR_DRX_PRD_320SF: + case RGR_DRX_PRD_512SF: + case RGR_DRX_PRD_640SF: + case RGR_DRX_PRD_1024SF: + case RGR_DRX_PRD_1280SF: + case RGR_DRX_PRD_2048SF: + case RGR_DRX_PRD_2560SF: + break; + + default: + { + RETVALUE(RFAILED); + } + }/*switch(longDrxCycle)*/ + + RETVALUE(ROK); +}/*rgSCHCfgVldtDrxLngCyclTmrs*/ + +/*********************************************************** + * + * Func : rgSCHCfgVldtDrxShrtCycCfg + * + * + * Desc : Validates DRX Short Cycle timer configuration + * recieved from RRC. + * + * Ret : S16 + * ROK - Success + * + * RFAILED - Failed + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PRIVATE S16 rgSCHCfgVldtDrxShrtCycCfg +( +RgrDrxShortDrx shrtCycCfg +) +#else +PRIVATE S16 rgSCHCfgVldtDrxShrtCycCfg(shrtCycCfg) +RgrDrxShortDrx shrtCycCfg; +#endif +{ + TRC2(rgSCHCfgVldtDrxShrtCycCfg) + + switch(shrtCycCfg.shortDrxCycle) + { + case RGR_DRX_PRD_2SF: + case RGR_DRX_PRD_5SF: + case RGR_DRX_PRD_8SF: + case RGR_DRX_PRD_10SF: + case RGR_DRX_PRD_16SF: + case RGR_DRX_PRD_20SF: + case RGR_DRX_PRD_32SF: + case RGR_DRX_PRD_40SF: + case RGR_DRX_PRD_64SF: + case RGR_DRX_PRD_80SF: + case RGR_DRX_PRD_128SF: + case RGR_DRX_PRD_160SF: + case RGR_DRX_PRD_256SF: + case RGR_DRX_PRD_320SF: + case RGR_DRX_PRD_640SF: + break; + + default: + { + RETVALUE(RFAILED); + } + + }/*switch(shortDrxCycle)*/ + + if ( (shrtCycCfg.drxShortCycleTmr < RGR_DRX_SHRTCYCLE_MIN) || + (shrtCycCfg.drxShortCycleTmr > RGR_DRX_SHRTCYCLE_MAX) + ) + { + RETVALUE(RFAILED); + } + + RETVALUE(ROK); +} + +/** + * @brief Handler for TA related UE Reconfiguration. + * + * @details + * + * Function : rgSCHCfgUeTaRecfg + * + * This function shall fetch the TA timer related information into the + * respective ueCb from the UE configuration as provided by the + * upper layers. + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ueCb + * @param[in] RgrUeCfg *ueCfg + * @param[out] RgSchErrInfo *errInfo + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PRIVATE Void rgSCHCfgUeTaRecfg +( +RgSchCellCb *cell, +RgSchUeCb *ueCb, +RgrUeRecfg *ueCfg, +RgSchErrInfo *err +) +#else +PRIVATE Void rgSCHCfgUeTaRecfg(cell, ueCb, ueCfg, err) +RgSchCellCb *cell; +RgSchUeCb *ueCb; +RgrUeRecfg *ueCfg; +RgSchErrInfo *err; +#endif +{ + TRC2(rgSCHCfgUeTaRecfg) + + UNUSED(err); + + /* Update the TA related information */ + + if (ueCfg->ueTaTmrRecfg.pres) + { + /* Configuring taTmr with 30 deficit, to enable eNodeB sending + * TA command before the expiry of TA at UE. Also considering for + * possible retx for this TA command */ + /* [ccpu00121813]-ADD-Added chk if tatmr val > 30 */ + if(ueCfg->ueTaTmrRecfg.taTmr > 30) + { + ueCb->dl.taCb.cfgTaTmr = ueCfg->ueTaTmrRecfg.taTmr - 30; + } + /* If TA Timer is running. Stop it and then start it*/ + if (ueCb->taTmr.tmrEvnt != TMR_NONE) + { + rgSCHTmrStopTmr(cell, ueCb->taTmr.tmrEvnt, ueCb); + rgSCHTmrStartTmr(cell, ueCb, RG_SCH_TMR_TA, ueCb->dl.taCb.cfgTaTmr); + } + else + { + rgSCHTmrStartTmr(cell, ueCb, RG_SCH_TMR_TA, ueCb->dl.taCb.cfgTaTmr); + } + } + RETVOID; +} /* rgSCHCfgUeTaRecfg */ + +/* ccpu00117452 - MOD - Changed macro name from + RGR_RRM_DLPWR_CNTRL to RGR_CQI_REPT */ +#if ((defined (RGR_CQI_REPT)) && (defined (RGR_V2))) +/*********************************************************** + * + * Func : rgSCHCfgUeCqiReptReCfg + * + * + * Desc : Reconfiguration of PUSH N CQI Reporting + * + * Ret : RFAILED in case of failure + * ROK if success + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PRIVATE S16 rgSCHCfgUeCqiReptReCfg +( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgrUeRecfg *ueRecfg +) +#else +PRIVATE S16 rgSCHCfgUeCqiReptReCfg(cell, ue, ueRecfg) +RgSchCellCb *cell; +RgSchUeCb *ue; +RgrUeRecfg *ueRecfg; +#endif +{ + S16 retVal; + TRC3(rgSCHCfgUeCqiReptReCfg) + + /* Check has it been disabled */ + if(ueRecfg->ueCqiReptCfg.numColltdCqiRept) + { + /* Check if we need to send CQI reports collagted so far and send if so */ + if(ue->schCqiInfo.cqiCount >= + ueRecfg->ueCqiReptCfg.numColltdCqiRept) + { + RgrStaIndInfo *staInfo; + /* if yes, Send StaInd to RRM */ + retVal = rgSCHUtlAllocSBuf (cell->instIdx,(Data**)&staInfo, + sizeof(RgrStaIndInfo)); + if(retVal != ROK) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId, + "Could not allocate memory for sending StaInd OLD CRNTI:%d",ueRecfg->oldCrnti); + RETVALUE(retVal); + } + + /* Fill StaInd for sending collated N CQI rpeort */ + rgSCHUtlFillSndStaInd(cell, ue, staInfo, + ueRecfg->ueCqiReptCfg.numColltdCqiRept); + } + } + else + { + ue->schCqiInfo.cqiCount = 0; + } + + ue->cqiReptCfgInfo.numColltdCqiRept = + ueRecfg->ueCqiReptCfg.numColltdCqiRept; + RETVALUE(ROK); +} /* End of rgSCHCfgUeCqiReptReCfg */ +#endif /* End of RGR_CQI_REPT */ +/*This function Added Ue in ongoing L2 Meas*/ +/*LTE_L2_MEAS_PHASE2*/ +#ifdef LTE_L2_MEAS +PRIVATE S16 rgSchAddToL2Meas(RgSchCellCb *cellCb,RgSchDlLcCb *dlLc) +{ + CmLList *lnk; + U16 idx; + RgSchL2MeasCb *measCb = NULLP; + lnk = cellCb->l2mList.first; + + while(lnk != NULLP) + { + /* Get the MeasCb : RgSchL2MeasCb */ + measCb = (RgSchL2MeasCb *)lnk->node; + if (measCb->measReq.measType & LRG_L2MEAS_AVG_PRB_PER_QCI_DL) + { + for(idx = 0;idx < measCb->measReq.avgPrbQciDl.numQci;idx++) + { + if(measCb->measReq.avgPrbQciDl.qci[idx] == dlLc->qciCb->qci) + { + break; /*exit from for loop*/ + } + } + if(idx == measCb->measReq.avgPrbQciDl.numQci) + { + measCb->measReq.avgPrbQciDl.qci[measCb->measReq.avgPrbQciDl.numQci++] = dlLc->qciCb->qci; + } + } + lnk = lnk->next; + }/*End of while loop*/ + + RETVALUE(ROK); +} +#endif +#ifdef LTE_ADV +/** + * @brief UE SCell Buffer Free + * + * @details + * + * Function : rgSCHSCellFreeBuf + * + * This functions will free allocated memory + * for UE secondart cellCB + * + * + * @param[in] Inst inst + * @param[in] RgSchUeCb *ue + * @param[int] RgrUeRecfg *ueRecfg + * @param[out] U8 idx + * @return VOID + **/ +#ifdef ANSI +PUBLIC Void rgSCHSCellFreeBuf +( +Inst inst, +RgSchUeCb *ue, +RgrUeRecfg *ueRecfg, +U8 idx +) +#else +PUBLIC Void rgSCHSCellFreeBuf(inst ,ue, ueRecfg, idx) +Inst inst; +RgSchUeCb *ue; +RgrUeRecfg *ueRecfg; +U8 idx; +#endif +{ + RgSchUeCellInfo *sCellInfo = NULLP; + RgrUeSecCellCfg *sCellInfoRecfg = NULLP; + + TRC2(rgSCHSCellFreeBuf); + + for(U8 i = 0; i <= idx; i++) + { + sCellInfoRecfg = &ueRecfg->ueSCellCfgInfo.ueSCellDedCfg[i]; + sCellInfo = ue->cellInfo[(sCellInfoRecfg->sCellIdx)]; + + if (NULLP != sCellInfo) + { + rgSCHUtlFreeSBuf(inst, (Data**)&(sCellInfo), + sizeof(RgSchUeCellInfo)); + ue->cellInfo[(sCellInfoRecfg->sCellIdx)] = NULLP; + + } + } + RETVOID; +} +#endif +/********************************************************************** + + End of file +**********************************************************************/ diff --git a/src/5gnrmac/rg_sch_clist.x b/src/5gnrmac/rg_sch_clist.x new file mode 100755 index 000000000..dfcb11f2e --- /dev/null +++ b/src/5gnrmac/rg_sch_clist.x @@ -0,0 +1,81 @@ +/******************************************************************************* +################################################################################ +# Copyright (c) [2017-2019] [Radisys] # +# # +# 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. # +################################################################################ +*******************************************************************************/ + +/********************************************************************20** + + Name: common - linked list functions + + Type: C include file + + Desc: Structures, variables and typedefs required by the + linked list management routines. + + File: rg_sch_clist.x + +*********************************************************************21*/ + +#ifndef __RGSCHRRCLIST__ +#define __RGSCHRRCLIST__ + +#ifdef __cplusplus +extern "C" { +#endif + + +typedef struct rgSchRrCList RgSchRrCList; +typedef struct rgSchRrCListCp RgSchRrCListCp; + +/* doubly linked list */ +struct rgSchRrCList +{ + RgSchRrCList *next; /* next */ + RgSchRrCList *prev; /* previous */ + PTR node; /* node */ +}; + +struct rgSchRrCListCp +{ + RgSchRrCList *first; /* first entry in list */ + RgSchRrCList *crnt; /* entry last accessed */ + U32 count; /* number of entries */ +}; + +EXTERN Void rgSCHRrCListInit ARGS ((RgSchRrCListCp *lList)); +EXTERN Void rgSCHRrCListAdd2Tail ARGS ((RgSchRrCListCp *lList, \ + RgSchRrCList *node)); +/* Renamed functions to start with rgSCH */ +EXTERN RgSchRrCList *rgSCHRrCListDelFrm ARGS ((RgSchRrCListCp *lList, \ + RgSchRrCList *node)); +EXTERN Void rgSCHRrCListInsrtAtCrnt ARGS ((RgSchRrCListCp *lList, \ + RgSchRrCList *node)); +/* LTE_ADV_FLAG_REMOVED_START */ +EXTERN Void rgSCHRrCListAdd2Crnt ARGS ((RgSchRrCListCp *lList, \ + RgSchRrCList *node)); +/* LTE_ADV_FLAG_REMOVED_END */ + + +#ifdef __cplusplus +} +#endif + +#endif /* __RRCLIST__ */ + +/********************************************************************** + + End of file +**********************************************************************/ diff --git a/src/5gnrmac/rg_sch_cmn.c b/src/5gnrmac/rg_sch_cmn.c new file mode 100755 index 000000000..3c1b490bc --- /dev/null +++ b/src/5gnrmac/rg_sch_cmn.c @@ -0,0 +1,32150 @@ +/******************************************************************************* +################################################################################ +# Copyright (c) [2017-2019] [Radisys] # +# # +# 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. # +################################################################################ +*******************************************************************************/ + +/************************************************************************ + + Name: LTE-MAC layer + + Type: C source file + + Desc: C source code for Entry point fucntions + + File: rg_sch_cmn.c + +**********************************************************************/ + +/** @file rg_sch_cmn.c +@brief This file implements the schedulers main access to MAC layer code. +*/ + +static const char* RLOG_MODULE_NAME="MAC"; +static int RLOG_FILE_ID=187; +static int RLOG_MODULE_ID=4096; + +/* header include files -- defines (.h) */ +#include "envopt.h" /* environment options */ +#include "envdep.h" /* environment dependent */ +#include "envind.h" /* environment independent */ +#include "gen.h" /* general layer */ +#include "ssi.h" /* system service interface */ +#include "cm_hash.h" /* common hash list */ +#include "cm_llist.h" /* common linked list library */ +#include "cm_err.h" /* common error */ +#include "cm_lte.h" /* common LTE */ +#include "cm5.h" +#include "lrg.h" +#include "rgr.h" +#include "tfu.h" +#include "rgm.h" +#include "rg_env.h" +#include "rg_sch_err.h" +#include "rg_sch_inf.h" +#include "rg_sch.h" +#include "rg_sch_cmn.h" +#include "rl_interface.h" +#include "rl_common.h" + +/* header/extern include files (.x) */ +#include "gen.x" /* general layer typedefs */ +#include "ssi.x" /* system services typedefs */ +#include "cm5.x" /* common timers */ +#include "cm_hash.x" /* common hash list */ +#include "cm_lib.x" /* common library */ +#include "cm_llist.x" /* common linked list */ +#include "cm_mblk.x" /* memory management */ +#include "cm_tkns.x" /* common tokens */ +#include "cm_lte.x" /* common tokens */ +#include "tfu.x" /* TFU types */ +#include "lrg.x" /* layer management typedefs for MAC */ +#include "rgr.x" /* layer management typedefs for MAC */ +#include "rgm.x" /* layer management typedefs for MAC */ +#include "rg_sch_inf.x" /* typedefs for Scheduler */ +#include "rg_sch.x" /* typedefs for Scheduler */ +#include "rg_sch_cmn.x" /* typedefs for Scheduler */ +#ifdef MAC_SCH_STATS +#include "lrg.x" /* Stats Structures */ +#endif /* MAC_SCH_STATS */ +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#ifdef EMTC_ENABLE +EXTERN U32 emtcStatsUlTomSrInd; +EXTERN U32 emtcStatsUlBsrTmrTxp; +#endif + +#define RG_ITBS_DIFF(_x, _y) ((_x) > (_y) ? (_x) - (_y) : (_y) - (_x)) +EXTERN Void rgSCHSc1UlInit ARGS((RgUlSchdApis *apis)); +#ifdef RG_PHASE2_SCHED +EXTERN Void rgSCHRrUlInit ARGS((RgUlSchdApis *apis)); +#ifdef EMTC_ENABLE +EXTERN Void rgSCHEmtcHqInfoFree ARGS((RgSchCellCb *cell, RgSchDlHqProcCb *hqP)); +EXTERN Void rgSCHEmtcRrUlInit ARGS((RgUlSchdApis *apis)); +EXTERN Void rgSCHEmtcCmnDlInit ARGS((Void)); +EXTERN Void rgSCHEmtcCmnUlInit ARGS((Void)); +EXTERN Void rgSCHEmtcCmnUeNbReset ARGS((RgSchUeCb *ueCb)); +EXTERN RgSchCmnCqiToTbs *rgSchEmtcCmnCqiToTbs[RGSCH_MAX_NUM_LYR_PERCW][RG_SCH_CMN_MAX_CP][RG_SCH_CMN_MAX_CFI]; +#endif +EXTERN Void rgSCHMaxciUlInit ARGS((RgUlSchdApis *apis)); +EXTERN Void rgSCHPfsUlInit ARGS((RgUlSchdApis *apis)); +#endif +EXTERN Void rgSCHSc1DlInit ARGS((RgDlSchdApis *apis)); +#ifdef RG_PHASE2_SCHED +EXTERN Void rgSCHRrDlInit ARGS((RgDlSchdApis *apis)); +#ifdef EMTC_ENABLE +EXTERN Void rgSCHEmtcRrDlInit ARGS((RgDlEmtcSchdApis *apis)); +#endif +EXTERN Void rgSCHMaxciDlInit ARGS((RgDlSchdApis *apis)); +EXTERN Void rgSCHPfsDlInit ARGS((RgDlSchdApis *apis)); +#ifdef TFU_UPGRADE +EXTERN Void rgSCHDlfsInit ARGS((RgDlfsSchdApis *apis)); +#endif +#endif +#ifdef EMTC_ENABLE +EXTERN Void rgSCHCmnGetCqiEmtcDciFrmt2AggrLvl ARGS((RgSchCellCb *cell)); +EXTERN Void rgSCHCmnGetEmtcDciFrmtSizes ARGS((RgSchCellCb *cell)); +EXTERN Void rgSCHEmtcRrUlProcRmvFrmRetx ARGS((RgSchCellCb *cell, RgSchUlHqProcCb *proc)); +EXTERN S16 rgSCHCmnPrecompEmtcMsg3Vars +ARGS(( +RgSchCmnUlCell *cellUl, +U8 ccchCqi, +U16 msgSzA, +U8 sbSize, +Bool isEcp +)); +PUBLIC Void rgSCHEmtcCmnUeCcchSduDel +( +RgSchCellCb *cell, +RgSchUeCb *ueCb +); +EXTERN Void rgSCHEmtcRmvFrmTaLst +( +RgSchCmnDlCell *cellDl, +RgSchUeCb *ue +); +EXTERN Void rgSCHEmtcInitTaLst +( +RgSchCmnDlCell *cellDl +); +EXTERN Void rgSCHEmtcAddToTaLst +( +RgSchCmnDlCell *cellDl, +RgSchUeCb *ue +); + +#endif + +#ifdef RGR_SI_SCH +PRIVATE Void rgSCHDlSiSched ARGS((RgSchCellCb *cell, + RgSchCmnDlRbAllocInfo *allocInfo, + RgInfSfAlloc *subfrmAlloc)); +PRIVATE Void rgSCHChkNUpdSiCfg ARGS((RgSchCellCb *cell)); +PRIVATE Void rgSCHSelectSi ARGS((RgSchCellCb *cell)); +#endif /*RGR_SI_SCH*/ +/* LTE_ADV_FLAG_REMOVED_START */ +#ifndef LTE_TDD +PRIVATE S16 rgSCHCmnNonDlfsUpdDSFRTyp2Alloc +( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgSchDlSf *dlSf, +U8 rbStrt, +U8 numRb +); +PRIVATE S16 rgSCHCmnBuildRntpInfo ( +RgSchCellCb *cell, +U8 *rntpPtr, +U8 startRb, +U8 nmbRb, +U16 bw +); +#endif + +PUBLIC Void rgSCHCmnDlSpsSch +( + RgSchCellCb *cell +); +/* LTE_ADV_FLAG_REMOVED_END */ + +PRIVATE Void rgSCHCmnNonDlfsBcchPcchRbAlloc ARGS(( +RgSchCellCb *cell, +RgSchCmnDlRbAllocInfo *allocInfo +)); +PRIVATE Void rgSCHBcchPcchDlRbAlloc ARGS(( +RgSchCellCb *cell, +RgSchCmnDlRbAllocInfo *allocInfo +)); +PRIVATE Void rgSCHCmnDlBcchPcchAlloc ARGS(( +RgSchCellCb *cell +)); +#ifdef RGR_CQI_REPT +PRIVATE Void rgSCHCmnDlCqiOnPucchInd ARGS (( + RgSchCellCb *cell, + RgSchUeCb *ue, + TfuDlCqiPucch *pucchCqi, + RgrUeCqiRept *ueCqiRept, + Bool *isCqiAvail, + Bool *is2ndCwCqiAvail + )); +PRIVATE Void rgSCHCmnDlCqiOnPuschInd ARGS (( + RgSchCellCb *cell, + RgSchUeCb *ue, + TfuDlCqiPusch *puschCqi, + RgrUeCqiRept *ueCqiRept, + Bool *isCqiAvail, + Bool *is2ndCwCqiAvail + )); +#else +PRIVATE Void rgSCHCmnDlCqiOnPucchInd ARGS (( + RgSchCellCb *cell, + RgSchUeCb *ue, + TfuDlCqiPucch *pucchCqi + )); +PRIVATE Void rgSCHCmnDlCqiOnPuschInd ARGS (( + RgSchCellCb *cell, + RgSchUeCb *ue, + TfuDlCqiPusch *puschCqi + )); +#endif +/* ccpu00117452 - MOD - Changed macro name from + RGR_RRM_DLPWR_CNTRL to RGR_CQI_REPT */ +#ifdef RGR_CQI_REPT +PRIVATE S16 rgSCHCmnUeDlPwrCtColltCqiRept ARGS(( + RgSchCellCb *cell, + RgSchUeCb *ue, + RgrUeCqiRept *ueCqiRept)); +#endif /* End of RGR_CQI_REPT */ +/* Fix: syed align multiple UEs to refresh at same time */ +PRIVATE Void rgSCHCmnGetRefreshPer ARGS(( + RgSchCellCb *cell, + RgSchUeCb *ue, + U32 *waitPer)); +PRIVATE S16 rgSCHCmnApplyUeRefresh ARGS(( +RgSchCellCb *cell, +RgSchUeCb *ue)); +#ifdef DL_LA +PUBLIC Void rgSCHCmnDlSetUeAllocLmtLa ARGS +(( +RgSchCellCb *cell, +RgSchUeCb *ue +)); +PRIVATE Void rgSCHCheckAndSetTxScheme ARGS +(( +RgSchCellCb *cell, +RgSchUeCb *ue +)); +#endif + +#ifdef LTE_TDD +PRIVATE U32 rgSCHCmnCalcDwPtsTbSz ARGS +(( +RgSchCellCb *cell, +U32 bo, +U8 *rb, +U8 *iTbs, +U8 lyr, +U8 cfi +)); + +PRIVATE Void rgSCHCmnCalcDwPtsTbSz2Cw ARGS +(( +RgSchCellCb *cell, +U32 bo, +U8 *rb, +U8 maxRb, +U8 *iTbs1, +U8 *iTbs2, +U8 lyr1, +U8 lyr2, +U32 *tb1Sz, +U32 *tb2Sz, +U8 cfi +)); + +#endif +PRIVATE Void rgSCHCmnNonDlfsType0Alloc +( +RgSchCellCb *cell, +RgSchDlSf *dlSf, +RgSchDlRbAlloc *allocInfo, +RgSchUeCb *ue +); +PRIVATE Void rgSCHCmnInitRbAlloc ARGS +(( +RgSchCellCb *cell +)); +#ifdef __cplusplus +} +#endif /* __cplusplus */ + + +/* local defines */ +PUBLIC RgSchdApis rgSchCmnApis; +PRIVATE RgUlSchdApis rgSchUlSchdTbl[RGSCH_NUM_SCHEDULERS]; +PRIVATE RgDlSchdApis rgSchDlSchdTbl[RGSCH_NUM_SCHEDULERS]; +#ifdef EMTC_ENABLE +PRIVATE RgUlSchdApis rgSchEmtcUlSchdTbl[RGSCH_NUM_EMTC_SCHEDULERS]; +PRIVATE RgDlEmtcSchdApis rgSchEmtcDlSchdTbl[RGSCH_NUM_EMTC_SCHEDULERS]; +#endif +#ifdef RG_PHASE2_SCHED +PRIVATE RgDlfsSchdApis rgSchDlfsSchdTbl[RGSCH_NUM_DLFS_SCHEDULERS]; +#endif +PRIVATE RgUlSchdInits rgSchUlSchdInits = RGSCH_ULSCHED_INITS; +PRIVATE RgDlSchdInits rgSchDlSchdInits = RGSCH_DLSCHED_INITS; +#ifdef EMTC_ENABLE +PRIVATE RgEmtcUlSchdInits rgSchEmtcUlSchdInits = RGSCH_EMTC_ULSCHED_INITS; +PRIVATE RgEmtcDlSchdInits rgSchEmtcDlSchdInits = RGSCH_EMTC_DLSCHED_INITS; +#endif +#if (defined (RG_PHASE2_SCHED) && defined (TFU_UPGRADE)) +PRIVATE RgDlfsSchdInits rgSchDlfsSchdInits = RGSCH_DLFSSCHED_INITS; +#endif + +typedef Void (*RgSchCmnDlAllocRbFunc) ARGS((RgSchCellCb *cell, RgSchDlSf *subFrm, +RgSchUeCb *ue, U32 bo, U32 *effBo, RgSchDlHqProcCb *proc, +RgSchCmnDlRbAllocInfo *cellWdAllocInfo)); +typedef U8 (*RgSchCmnDlGetPrecInfFunc) ARGS((RgSchCellCb *cell, RgSchUeCb *ue, + U8 numLyrs, Bool bothCwEnbld)); + +PRIVATE Void rgSCHCmnFillHqPPdcchDciFrmt1 ARGS(( +RgSchCellCb *cell, +RgSchDlRbAlloc *rbAllocInfo, +RgSchDlHqProcCb *hqP, +RgSchPdcch *pdcch, +U8 tpc +)); +PRIVATE Void rgSCHCmnFillHqPPdcchDciFrmt1A ARGS(( +RgSchCellCb *cell, +RgSchDlRbAlloc *rbAllocInfo, +RgSchDlHqProcCb *hqP, +RgSchPdcch *pdcch, +U8 tpc +)); +PRIVATE Void rgSCHCmnFillHqPPdcchDciFrmt1B ARGS(( +RgSchCellCb *cell, +RgSchDlRbAlloc *rbAllocInfo, +RgSchDlHqProcCb *hqP, +RgSchPdcch *pdcch, +U8 tpc +)); +PRIVATE Void rgSCHCmnFillHqPPdcchDciFrmt2 ARGS(( +RgSchCellCb *cell, +RgSchDlRbAlloc *rbAllocInfo, +RgSchDlHqProcCb *hqP, +RgSchPdcch *pdcch, +U8 tpc +)); +PRIVATE Void rgSCHCmnFillHqPPdcchDciFrmt2A ARGS(( +RgSchCellCb *cell, +RgSchDlRbAlloc *rbAllocInfo, +RgSchDlHqProcCb *hqP, +RgSchPdcch *pdcch, +U8 tpc +)); +PRIVATE Void rgSCHCmnDlAllocTxRbTM1 ARGS(( +RgSchCellCb *cell, +RgSchDlSf *subFrm, +RgSchUeCb *ue, +U32 bo, +U32 *effBo, +RgSchDlHqProcCb *proc, +RgSchCmnDlRbAllocInfo *cellWdAllocInfo +)); +PRIVATE Void rgSCHCmnDlAllocTxRbTM2 ARGS(( +RgSchCellCb *cell, +RgSchDlSf *subFrm, +RgSchUeCb *ue, +U32 bo, +U32 *effBo, +RgSchDlHqProcCb *proc, +RgSchCmnDlRbAllocInfo *cellWdAllocInfo +)); +PRIVATE Void rgSCHCmnDlAllocTxRbTM3 ARGS(( +RgSchCellCb *cell, +RgSchDlSf *subFrm, +RgSchUeCb *ue, +U32 bo, +U32 *effBo, +RgSchDlHqProcCb *proc, +RgSchCmnDlRbAllocInfo *cellWdAllocInfo +)); +PRIVATE Void rgSCHCmnDlAllocTxRbTM4 ARGS(( +RgSchCellCb *cell, +RgSchDlSf *subFrm, +RgSchUeCb *ue, +U32 bo, +U32 *effBo, +RgSchDlHqProcCb *proc, +RgSchCmnDlRbAllocInfo *cellWdAllocInfo +)); +#ifdef RG_UNUSED +PRIVATE Void rgSCHCmnDlAllocTxRbTM5 ARGS(( +RgSchCellCb *cell, +RgSchDlSf *subFrm, +RgSchUeCb *ue, +U32 bo, +U32 *effBo, +RgSchDlHqProcCb *proc, +RgSchCmnDlRbAllocInfo *cellWdAllocInfo +)); +#endif +PRIVATE Void rgSCHCmnDlAllocTxRbTM6 ARGS(( +RgSchCellCb *cell, +RgSchDlSf *subFrm, +RgSchUeCb *ue, +U32 bo, +U32 *effBo, +RgSchDlHqProcCb *proc, +RgSchCmnDlRbAllocInfo *cellWdAllocInfo +)); +PRIVATE Void rgSCHCmnDlAllocTxRbTM7 ARGS(( +RgSchCellCb *cell, +RgSchDlSf *subFrm, +RgSchUeCb *ue, +U32 bo, +U32 *effBo, +RgSchDlHqProcCb *proc, +RgSchCmnDlRbAllocInfo *cellWdAllocInfo +)); +PRIVATE Void rgSCHCmnDlAllocRetxRbTM1 ARGS(( +RgSchCellCb *cell, +RgSchDlSf *subFrm, +RgSchUeCb *ue, +U32 bo, +U32 *effBo, +RgSchDlHqProcCb *proc, +RgSchCmnDlRbAllocInfo *cellWdAllocInfo +)); +PRIVATE Void rgSCHCmnDlAllocRetxRbTM2 ARGS(( +RgSchCellCb *cell, +RgSchDlSf *subFrm, +RgSchUeCb *ue, +U32 bo, +U32 *effBo, +RgSchDlHqProcCb *proc, +RgSchCmnDlRbAllocInfo *cellWdAllocInfo +)); +PRIVATE Void rgSCHCmnDlAllocRetxRbTM3 ARGS(( +RgSchCellCb *cell, +RgSchDlSf *subFrm, +RgSchUeCb *ue, +U32 bo, +U32 *effBo, +RgSchDlHqProcCb *proc, +RgSchCmnDlRbAllocInfo *cellWdAllocInfo +)); +PRIVATE Void rgSCHCmnDlAllocRetxRbTM4 ARGS(( +RgSchCellCb *cell, +RgSchDlSf *subFrm, +RgSchUeCb *ue, +U32 bo, +U32 *effBo, +RgSchDlHqProcCb *proc, +RgSchCmnDlRbAllocInfo *cellWdAllocInfo +)); +#ifdef RG_UNUSED +PRIVATE Void rgSCHCmnDlAllocRetxRbTM5 ARGS(( +RgSchCellCb *cell, +RgSchDlSf *subFrm, +RgSchUeCb *ue, +U32 bo, +U32 *effBo, +RgSchDlHqProcCb *proc, +RgSchCmnDlRbAllocInfo *cellWdAllocInfo +)); +#endif +PRIVATE Void rgSCHCmnDlAllocRetxRbTM6 ARGS(( +RgSchCellCb *cell, +RgSchDlSf *subFrm, +RgSchUeCb *ue, +U32 bo, +U32 *effBo, +RgSchDlHqProcCb *proc, +RgSchCmnDlRbAllocInfo *cellWdAllocInfo +)); +PRIVATE Void rgSCHCmnDlAllocRetxRbTM7 ARGS(( +RgSchCellCb *cell, +RgSchDlSf *subFrm, +RgSchUeCb *ue, +U32 bo, +U32 *effBo, +RgSchDlHqProcCb *proc, +RgSchCmnDlRbAllocInfo *cellWdAllocInfo +)); + +#ifdef LTE_ADV +PRIVATE U8 rgSchGetN1ResCount ARGS (( + RgSchUeCb *ue, + U16 servCellId +)); +PUBLIC Bool rgSchCmnChkDataOnlyOnPcell +( + RgSchUeCb *ue, + RgSchDlSf *dlSf +); +#endif /*LTE_ADV */ +PUBLIC U8 rgSCHCmnCalcPcqiBitSz +( + RgSchUeCb *ueCb, + U8 numTxAnt +); + +#ifndef LTE_ADV +/* Functions specific to each transmission mode for DL Tx RB Allocation*/ +RgSchCmnDlAllocRbFunc dlAllocTxRbFunc[7] = {rgSCHCmnDlAllocTxRbTM1, +rgSCHCmnDlAllocTxRbTM2, rgSCHCmnDlAllocTxRbTM3, rgSCHCmnDlAllocTxRbTM4, +NULLP, rgSCHCmnDlAllocTxRbTM6, rgSCHCmnDlAllocTxRbTM7}; + +/* Functions specific to each transmission mode for DL Retx RB Allocation*/ +RgSchCmnDlAllocRbFunc dlAllocRetxRbFunc[7] = {rgSCHCmnDlAllocRetxRbTM1, +rgSCHCmnDlAllocRetxRbTM2, rgSCHCmnDlAllocRetxRbTM3, rgSCHCmnDlAllocRetxRbTM4, +NULLP, rgSCHCmnDlAllocRetxRbTM6, rgSCHCmnDlAllocRetxRbTM7}; +#else +/* Functions specific to each transmission mode for DL Tx RB Allocation*/ +RgSchCmnDlAllocRbFunc dlAllocTxRbFunc[9] = {rgSCHCmnDlAllocTxRbTM1, +rgSCHCmnDlAllocTxRbTM2, rgSCHCmnDlAllocTxRbTM3, rgSCHCmnDlAllocTxRbTM4, +NULLP, rgSCHCmnDlAllocTxRbTM6, rgSCHCmnDlAllocTxRbTM7, NULLP, NULLP}; + +/* Functions specific to each transmission mode for DL Retx RB Allocation*/ +RgSchCmnDlAllocRbFunc dlAllocRetxRbFunc[9] = {rgSCHCmnDlAllocRetxRbTM1, +rgSCHCmnDlAllocRetxRbTM2, rgSCHCmnDlAllocRetxRbTM3, rgSCHCmnDlAllocRetxRbTM4, +NULLP, rgSCHCmnDlAllocRetxRbTM6, rgSCHCmnDlAllocRetxRbTM7, NULLP, NULLP}; + +#endif + + +PRIVATE U8 rgSCHCmnDlTM3PrecInf2 ARGS(( +RgSchCellCb *cell, +RgSchUeCb *ue, +U8 numTxLyrs, +Bool bothCwEnbld +)); +PRIVATE U8 rgSCHCmnDlTM3PrecInf4 ARGS(( +RgSchCellCb *cell, +RgSchUeCb *ue, +U8 numTxLyrs, +Bool bothCwEnbld +)); +PRIVATE U8 rgSCHCmnDlTM4PrecInf2 ARGS(( +RgSchCellCb *cell, +RgSchUeCb *ue, +U8 numTxLyrs, +Bool bothCwEnbld +)); +PRIVATE U8 rgSCHCmnDlTM4PrecInf4 ARGS(( +RgSchCellCb *cell, +RgSchUeCb *ue, +U8 numTxLyrs, +Bool bothCwEnbld +)); +/* Functions specific to each transmission mode for DL RB Allocation*/ +RgSchCmnDlGetPrecInfFunc getPrecInfoFunc[2][2] = { +{rgSCHCmnDlTM3PrecInf2, rgSCHCmnDlTM3PrecInf4}, +{rgSCHCmnDlTM4PrecInf2, rgSCHCmnDlTM4PrecInf4} +}; + +PRIVATE S16 rgSCHCmnDlAlloc1CwRetxRb ARGS(( +RgSchCellCb *cell, +RgSchDlSf *subFrm, +RgSchUeCb *ue, +RgSchDlHqTbCb *tbInfo, +U8 noLyr, +U8 *numRb, +U32 *effBo +)); +PRIVATE S16 rgSCHCmnDlAlloc2CwRetxRb ARGS(( +RgSchCellCb *cell, +RgSchDlSf *subFrm, +RgSchUeCb *ue, +RgSchDlHqProcCb *proc, +U8 *numRb, +Bool *swpFlg, +U32 *effBo +)); +PRIVATE Void rgSCHCmnDlTM3TxTx ARGS(( +RgSchCellCb *cell, +RgSchDlSf *subFrm, +RgSchUeCb *ue, +U32 bo, +U32 *effBo, +RgSchDlHqProcCb *proc, +RgSchCmnDlRbAllocInfo *cellWdAllocInfo +)); +PRIVATE Void rgSCHCmnDlTM3TxRetx ARGS(( +RgSchCellCb *cell, +RgSchDlSf *subFrm, +RgSchUeCb *ue, +U32 bo, +U32 *effBo, +RgSchDlHqProcCb *proc, +RgSchCmnDlRbAllocInfo *cellWdAllocInfo +)); +PRIVATE Void rgSCHCmnDlTM3RetxRetx ARGS(( +RgSchCellCb *cell, +RgSchDlSf *subFrm, +RgSchUeCb *ue, +U32 bo, +U32 *effBo, +RgSchDlHqProcCb *proc, +RgSchCmnDlRbAllocInfo *cellWdAllocInfo +)); + +PRIVATE Void rgSCHCmnNonDlfsUpdTyp2Alloc ARGS(( +RgSchCellCb *cell, +RgSchDlSf *dlSf, +U8 rbStrt, +U8 numRb +)); +/* LTE_ADV_FLAG_REMOVED_START */ +#ifndef LTE_TDD +PRIVATE Void rgSCHCmnNonDlfsSFRCmnChannelUpdTyp2Alloc ARGS(( +RgSchCellCb *cell, +RgSchDlSf *dlSf, +U8 rbStrt, +U8 numRb +)); +#endif +/* LTE_ADV_FLAG_REMOVED_END */ +PRIVATE Void rgSCHCmnDlRbInfoAddUeTx ARGS(( +RgSchCellCb *cell, +RgSchCmnDlRbAllocInfo *allocInfo, +RgSchUeCb *ue, +RgSchDlHqProcCb *proc +)); +PRIVATE Void rgSCHCmnDlRbInfoAddUeRetx ARGS(( +RgSchCellCb *cell, +RgSchCmnDlRbAllocInfo *allocInfo, +RgSchUeCb *ue, +RgSchDlHqProcCb *hqP +)); +PRIVATE Void rgSCHCmnDlAdd2NonSchdRetxLst ARGS(( +RgSchCmnDlRbAllocInfo *allocInfo, +RgSchUeCb *ue, +RgSchDlHqProcCb *proc +)); +PRIVATE S16 rgSCHCmnDlAlloc2CwTxRetxRb ARGS(( +RgSchCellCb *cell, +RgSchDlSf *subFrm, +RgSchUeCb *ue, +RgSchDlHqTbCb *reTxTb, +RgSchDlHqTbCb *txTb, +U8 *numRb, +U32 *effBo +)); +PRIVATE S16 rgSCHCmnDlAlloc2CwTxRb ARGS(( +RgSchCellCb *cell, +RgSchDlSf *subFrm, +RgSchUeCb *ue, +RgSchDlHqProcCb *proc, +U32 bo, +U8 *numRb, +U32 *effBo +)); +PRIVATE S16 rgSCHCmnDlAlloc1CwTxRb ARGS(( +RgSchCellCb *cell, +RgSchDlSf *subFrm, +RgSchUeCb *ue, +RgSchDlHqTbCb *tbInfo, +U32 bo, +U8 *numRb, +U32 *effBo +)); +#ifndef LTEMAC_SPS +PRIVATE Void rgSCHCmnFillHqPTb ARGS(( +RgSchCellCb *cell, +RgSchDlRbAlloc *rbAllocInfo, +U8 tbAllocIdx, +RgSchPdcch *pdcch +)); +#endif +#ifdef LTEMAC_SPS +PRIVATE Void rgSCHCmnDlGetBestFitHole ARGS(( +U32 *allocMask, +U8 numMaskRbs, +U32 *crntAllocMask, +U8 rbsReq, +U8 *allocStart, +U8 *allocNumRbs, +Bool isPartialAlloc +)); +#ifdef RGSCH_SPS_UNUSED +PRIVATE U32 rgSCHCmnGetRaType1Mask ARGS(( +U8 rbIdx, +U8 rbgSize, +U8 *type1Subset +)); +#endif +PRIVATE U32 rgSCHCmnGetRaType0Mask ARGS(( +U8 rbIdx, +U8 rbgSize +)); +PRIVATE U32 rgSCHCmnGetRaType2Mask ARGS(( +U8 rbIdx, +U8 *maskIdx +)); +#endif + +PUBLIC Bool rgSCHCmnRetxAllocAvoid ARGS(( +RgSchDlSf *subFrm, +RgSchCellCb *cell, +RgSchDlHqProcCb *proc +)); + +PUBLIC U16 rgSCHCmnGetSiSetId ARGS(( +U16 sfn, +U8 sf, +U16 minPeriodicity +)); + +#ifdef TFU_UPGRADE +PRIVATE S16 rgSCHCmnUlMdfyGrntForCqi ARGS(( +RgSchCellCb *cell, +RgSchUeCb *ue, +U32 maxRb, +U32 *numSb, +U8 *iTbs, +U32 hqSz, +U32 stepDownItbs, +U32 effTgt +)); +#endif + +#ifdef RG_5GTF +//TODO_SID: Currenly table is only for 100 Prbs. Need to modify wrt VRBG table 8.1.5.2.1-1 V5G_213 +U32 rgSch5gtfTbSzTbl[MAX_5GTF_MCS] = + {1864, 5256, 8776, 13176, 17576, 21976, 26376, 31656, 35176, 39576, 43976, 47496, 52776, 59376, 66392}; +U32 g5gtfTtiCnt = 0; +U32 gUl5gtfSrRecv = 0; +U32 gUl5gtfBsrRecv = 0; +U32 gUl5gtfUeSchPick = 0; +U32 gUl5gtfPdcchSchd = 0; +U32 gUl5gtfAllocAllocated = 0; +U32 gUl5gtfUeRbAllocDone = 0; +U32 gUl5gtfUeRmvFnlzZeroBo = 0; +U32 gUl5gtfUeFnlzReAdd = 0; +U32 gUl5gtfPdcchSend = 0; +U32 gUl5gtfRbAllocFail = 0; +U32 ul5gtfsidUlMarkUl = 0; +U32 ul5gtfsidDlSchdPass = 0; +U32 ul5gtfsidDlAlreadyMarkUl = 0; +U32 ul5gtfTotSchdCnt = 0; +#endif + +/* CQI Offset Index to Beta CQI Offset value mapping, + * stored as parts per 1000. Reserved is set to 0. + * Refer 36.213 sec 8.6.3 Tbl 8.6.3-3 */ +PUBLIC U32 rgSchCmnBetaCqiOffstTbl[16] = {0, 0, 1125, + 1250, 1375, 1625, 1750, 2000, 2250, 2500, 2875, + 3125, 3500, 4000, 5000, 6250}; +PUBLIC U32 rgSchCmnBetaHqOffstTbl[16] = {2000, 2500, 3125, + 4000, 5000, 6250, 8000,10000, 12625, 15875, 20000, + 31000, 50000,80000,126000,0}; +PUBLIC U32 rgSchCmnBetaRiOffstTbl[16] = {1250, 1625, 2000, + 2500, 3125, 4000, 5000, 6250, 8000, 10000,12625, + 15875,20000,0,0,0}; +PUBLIC S8 rgSchCmnDlCqiDiffOfst[8] = {0, 1, 2, 3, -4, -3, -2, -1}; + +/* Include CRS REs while calculating Efficiency */ +CONSTANT PRIVATE U8 rgSchCmnAntIdx[5] = {0,0,1,0,2}; +CONSTANT PRIVATE U8 rgSchCmnNumResForCrs[5] = {0,6,12,0,16}; +U32 cfiSwitchCnt ; +U32 cfiIncr ; +U32 cfiDecr ; + + +#ifdef TFU_UPGRADE +PUBLIC S8 rgSchCmnApUeSelDiffCqi[4] = {1, 2, 3, 4}; +PUBLIC S8 rgSchCmnApEnbConfDiffCqi[4] = {0, 1, 2, -1}; +#endif + +typedef struct rgSchCmnDlUeDciFrmtOptns +{ + TfuDciFormat spfcDciFrmt; /* TM(Transmission Mode) specific DCI format. + * Search space : UE Specific by C-RNTI only. */ + U8 spfcDciRAType; /* Resource Alloctn(RA) type for spfcDciFrmt */ + TfuDciFormat prfrdDciFrmt; /* Preferred DCI format among the available + * options for TD (Transmit Diversity) */ + U8 prfrdDciRAType; /* Resource Alloctn(RA) type for prfrdDciFrmt */ +}RgSchCmnDlUeDciFrmtOptns; +#ifndef LTE_ADV + +/* DCI Format options for each Transmission Mode */ +RgSchCmnDlUeDciFrmtOptns rgSchCmnDciFrmtOptns[7] = { + {TFU_DCI_FORMAT_1, RG_SCH_CMN_RA_TYPE0, TFU_DCI_FORMAT_1A, RG_SCH_CMN_RA_TYPE2}, + {TFU_DCI_FORMAT_1, RG_SCH_CMN_RA_TYPE0, TFU_DCI_FORMAT_1A, RG_SCH_CMN_RA_TYPE2}, + {TFU_DCI_FORMAT_2A,RG_SCH_CMN_RA_TYPE0, TFU_DCI_FORMAT_1A, RG_SCH_CMN_RA_TYPE2}, + {TFU_DCI_FORMAT_2, RG_SCH_CMN_RA_TYPE0, TFU_DCI_FORMAT_1A, RG_SCH_CMN_RA_TYPE2}, + {TFU_DCI_FORMAT_1D,RG_SCH_CMN_RA_TYPE2, TFU_DCI_FORMAT_1A, RG_SCH_CMN_RA_TYPE2}, + {TFU_DCI_FORMAT_1B,RG_SCH_CMN_RA_TYPE2, TFU_DCI_FORMAT_1A, RG_SCH_CMN_RA_TYPE2}, + {TFU_DCI_FORMAT_1, RG_SCH_CMN_RA_TYPE0, TFU_DCI_FORMAT_1A, RG_SCH_CMN_RA_TYPE2} +}; + +#else +/* DCI Format options for each Transmission Mode */ +RgSchCmnDlUeDciFrmtOptns rgSchCmnDciFrmtOptns[9] = { + {TFU_DCI_FORMAT_1, RG_SCH_CMN_RA_TYPE0, TFU_DCI_FORMAT_1A, RG_SCH_CMN_RA_TYPE2}, + {TFU_DCI_FORMAT_1, RG_SCH_CMN_RA_TYPE0, TFU_DCI_FORMAT_1A, RG_SCH_CMN_RA_TYPE2}, + {TFU_DCI_FORMAT_2A,RG_SCH_CMN_RA_TYPE0, TFU_DCI_FORMAT_1A, RG_SCH_CMN_RA_TYPE2}, + {TFU_DCI_FORMAT_2, RG_SCH_CMN_RA_TYPE0, TFU_DCI_FORMAT_1A, RG_SCH_CMN_RA_TYPE2}, + {TFU_DCI_FORMAT_1D,RG_SCH_CMN_RA_TYPE2, TFU_DCI_FORMAT_1A, RG_SCH_CMN_RA_TYPE2}, + {TFU_DCI_FORMAT_1B,RG_SCH_CMN_RA_TYPE2, TFU_DCI_FORMAT_1A, RG_SCH_CMN_RA_TYPE2}, + {TFU_DCI_FORMAT_1, RG_SCH_CMN_RA_TYPE0, TFU_DCI_FORMAT_1A, RG_SCH_CMN_RA_TYPE2} +}; +#endif + + +typedef struct rgSchCmnDlImcsTbl +{ + U8 modOdr; /* Modulation Order */ + U8 iTbs; /* ITBS */ +}RgSchCmnDlImcsTbl[29]; + +CONSTANT struct rgSchCmnMult235Info +{ + U8 match; /* Closest number satisfying 2^a.3^b.5^c, with a bias + * towards the smaller number */ + U8 prvMatch; /* Closest number not greater than array index + * satisfying 2^a.3^b.5^c */ +} rgSchCmnMult235Tbl[110+1] = { + {0, 0}, /* dummy */ + {1, 1}, {2, 2}, {3, 3}, {4, 4}, {5, 5}, {6, 6}, {6, 6}, {8, 8}, + {9, 9}, {10, 10}, {10, 10}, {12, 12}, {12, 12}, {15, 12}, {15, 15}, + {16, 16}, {16, 16}, {18, 18}, {18, 18}, {20, 20}, {20, 20}, {20, 20}, + {24, 20}, {24, 24}, {25, 25}, {25, 25}, {27, 27}, {27, 27}, {30, 27}, + {30, 30}, {30, 30}, {32, 32}, {32, 32}, {32, 32}, {36, 32}, {36, 36}, + {36, 36}, {36, 36}, {40, 36}, {40, 40}, {40, 40}, {40, 40}, {45, 40}, + {45, 40}, {45, 45}, {45, 45}, {48, 45}, {48, 48}, {48, 48}, {50, 50}, + {50, 50}, {50, 50}, {54, 50}, {54, 54}, {54, 54}, {54, 54}, {54, 54}, + {60, 54}, {60, 54}, {60, 60}, {60, 60}, {60, 60}, {64, 60}, {64, 64}, + {64, 64}, {64, 64}, {64, 64}, {64, 64}, {72, 64}, {72, 64}, {72, 64}, + {72, 72}, {72, 72}, {75, 72}, {75, 75}, {75, 75}, {75, 75}, {80, 75}, + {80, 75}, {80, 80}, {81, 81}, {81, 81}, {81, 81}, {81, 81}, {81, 81}, + {90, 81}, {90, 81}, {90, 81}, {90, 81}, {90, 90}, {90, 90}, {90, 90}, + {90, 90}, {96, 90}, {96, 90}, {96, 96}, {96, 96}, {96, 96}, {100, 96}, + {100, 100}, {100, 100}, {100, 100}, {100, 100}, {100, 100}, {108, 100}, + {108, 100}, {108, 100}, {108, 108}, {108, 108}, {108, 108} +}; + +/* R8 Upgrade */ +/* BI table from 36.321 Table 7.2.1 */ +CONSTANT PRIVATE S16 rgSchCmnBiTbl[RG_SCH_CMN_NUM_BI_VAL] = { + 0, 10, 20, 30,40,60,80,120,160,240,320,480,960}; +PUBLIC RgSchCmnUlCqiInfo rgSchCmnUlCqiTbl[RG_SCH_CMN_UL_NUM_CQI] = { + { 0, 0 }, + {RGSCH_CMN_QM_CQI_1,RGSCH_CMN_UL_EFF_CQI_1 }, + {RGSCH_CMN_QM_CQI_2,RGSCH_CMN_UL_EFF_CQI_2 }, + {RGSCH_CMN_QM_CQI_3,RGSCH_CMN_UL_EFF_CQI_3 }, + {RGSCH_CMN_QM_CQI_4,RGSCH_CMN_UL_EFF_CQI_4 }, + {RGSCH_CMN_QM_CQI_5,RGSCH_CMN_UL_EFF_CQI_5 }, + {RGSCH_CMN_QM_CQI_6,RGSCH_CMN_UL_EFF_CQI_6 }, + {RGSCH_CMN_QM_CQI_7,RGSCH_CMN_UL_EFF_CQI_7 }, + {RGSCH_CMN_QM_CQI_8,RGSCH_CMN_UL_EFF_CQI_8 }, + {RGSCH_CMN_QM_CQI_9,RGSCH_CMN_UL_EFF_CQI_9 }, + {RGSCH_CMN_QM_CQI_10,RGSCH_CMN_UL_EFF_CQI_10 }, + {RGSCH_CMN_QM_CQI_11,RGSCH_CMN_UL_EFF_CQI_11 }, + {RGSCH_CMN_QM_CQI_12,RGSCH_CMN_UL_EFF_CQI_12 }, + {RGSCH_CMN_QM_CQI_13,RGSCH_CMN_UL_EFF_CQI_13 }, + {RGSCH_CMN_QM_CQI_14,RGSCH_CMN_UL_EFF_CQI_14 }, + {RGSCH_CMN_QM_CQI_15,RGSCH_CMN_UL_EFF_CQI_15 }, +}; + +#ifdef RG_UNUSED +/* This table maps a (delta_offset * 2 + 2) to a (beta * 8) + * where beta is 10^-(delta_offset/10) rounded off to nearest 1/8 + */ +PRIVATE U16 rgSchCmnUlBeta8Tbl[29] = { + 6, RG_SCH_CMN_UL_INVALID_BETA8, 8, 9, 10, 11, 13, 14, 16, 18, 20, 23, + 25, 28, 32, RG_SCH_CMN_UL_INVALID_BETA8, 40, RG_SCH_CMN_UL_INVALID_BETA8, + 50, RG_SCH_CMN_UL_INVALID_BETA8, 64, RG_SCH_CMN_UL_INVALID_BETA8, 80, + RG_SCH_CMN_UL_INVALID_BETA8, 101, RG_SCH_CMN_UL_INVALID_BETA8, 127, + RG_SCH_CMN_UL_INVALID_BETA8, 160 +}; +#endif + +/* QCI to SVC priority mapping. Index specifies the Qci*/ +PRIVATE U8 rgSchCmnDlQciPrio[RG_SCH_CMN_MAX_QCI] = RG_SCH_CMN_QCI_TO_PRIO; + +/* The configuration is efficiency measured per 1024 REs. */ +/* The first element stands for when CQI is not known */ +/* This table is used to translate CQI to its corrospoding */ +/* allocation parameters. These are currently from 36.213 */ +/* Just this talbe needs to be edited for modifying the */ +/* the resource allocation behaviour */ + +/* ADD CQI to MCS mapping correction + * single dimensional array is replaced by 2 dimensions for different CFI*/ +PRIVATE U16 rgSchCmnCqiPdschEff[4][16] = {RG_SCH_CMN_CQI_TO_PDSCH_EFF_CFI0 ,RG_SCH_CMN_CQI_TO_PDSCH_EFF_CFI1, + RG_SCH_CMN_CQI_TO_PDSCH_EFF_CFI2,RG_SCH_CMN_CQI_TO_PDSCH_EFF_CFI3}; + +PRIVATE U16 rgSchCmn2LyrCqiPdschEff[4][16] = {RG_SCH_CMN_2LYR_CQI_TO_PDSCH_EFF_CFI0 ,RG_SCH_CMN_2LYR_CQI_TO_PDSCH_EFF_CFI1, + RG_SCH_CMN_2LYR_CQI_TO_PDSCH_EFF_CFI2, RG_SCH_CMN_2LYR_CQI_TO_PDSCH_EFF_CFI3}; + +/* This configuration determines the transalation of a UEs CQI to its */ +/* PDCCH coding efficiency. This may be edited based on the installation */ +PRIVATE U8 rgSchCmnDlRvTbl[4] = {0, 2, 3, 1}; /* RVIdx sequence is corrected*/ + +/* Indexed by [DciFrmt]. + * Considering the following definition in determining the dciFrmt index. + * typedef enum +{ + TFU_DCI_FORMAT_0, + TFU_DCI_FORMAT_1, + TFU_DCI_FORMAT_1A, + TFU_DCI_FORMAT_1B, + TFU_DCI_FORMAT_1C, + TFU_DCI_FORMAT_1D, + TFU_DCI_FORMAT_2, + TFU_DCI_FORMAT_2A, + TFU_DCI_FORMAT_3, + TFU_DCI_FORMAT_3A +} TfuDciFormat; +*/ +PRIVATE U16 rgSchCmnDciFrmtSizes[10]; + + +PRIVATE U16 rgSchCmnCqiPdcchEff[16] = RG_SCH_CMN_CQI_TO_PDCCH_EFF; + +#ifdef LTE_TDD + +PUBLIC RgSchTddUlDlSubfrmTbl rgSchTddUlDlSubfrmTbl = { + {RG_SCH_TDD_DL_SUBFRAME, RG_SCH_TDD_SPL_SUBFRAME, RG_SCH_TDD_UL_SUBFRAME, RG_SCH_TDD_UL_SUBFRAME, RG_SCH_TDD_UL_SUBFRAME, RG_SCH_TDD_DL_SUBFRAME, RG_SCH_TDD_SPL_SUBFRAME, RG_SCH_TDD_UL_SUBFRAME, RG_SCH_TDD_UL_SUBFRAME, RG_SCH_TDD_UL_SUBFRAME}, + {RG_SCH_TDD_DL_SUBFRAME, RG_SCH_TDD_SPL_SUBFRAME, RG_SCH_TDD_UL_SUBFRAME, RG_SCH_TDD_UL_SUBFRAME, RG_SCH_TDD_DL_SUBFRAME, RG_SCH_TDD_DL_SUBFRAME, RG_SCH_TDD_SPL_SUBFRAME, RG_SCH_TDD_UL_SUBFRAME, RG_SCH_TDD_UL_SUBFRAME, RG_SCH_TDD_DL_SUBFRAME}, + {RG_SCH_TDD_DL_SUBFRAME, RG_SCH_TDD_SPL_SUBFRAME, RG_SCH_TDD_UL_SUBFRAME, RG_SCH_TDD_DL_SUBFRAME, RG_SCH_TDD_DL_SUBFRAME, RG_SCH_TDD_DL_SUBFRAME, RG_SCH_TDD_SPL_SUBFRAME, RG_SCH_TDD_UL_SUBFRAME, RG_SCH_TDD_DL_SUBFRAME, RG_SCH_TDD_DL_SUBFRAME}, + {RG_SCH_TDD_DL_SUBFRAME, RG_SCH_TDD_SPL_SUBFRAME, RG_SCH_TDD_UL_SUBFRAME, RG_SCH_TDD_UL_SUBFRAME, RG_SCH_TDD_UL_SUBFRAME, RG_SCH_TDD_DL_SUBFRAME, RG_SCH_TDD_DL_SUBFRAME, RG_SCH_TDD_DL_SUBFRAME, RG_SCH_TDD_DL_SUBFRAME, RG_SCH_TDD_DL_SUBFRAME}, + {RG_SCH_TDD_DL_SUBFRAME, RG_SCH_TDD_SPL_SUBFRAME, RG_SCH_TDD_UL_SUBFRAME, RG_SCH_TDD_UL_SUBFRAME, RG_SCH_TDD_DL_SUBFRAME, RG_SCH_TDD_DL_SUBFRAME, RG_SCH_TDD_DL_SUBFRAME, RG_SCH_TDD_DL_SUBFRAME, RG_SCH_TDD_DL_SUBFRAME, RG_SCH_TDD_DL_SUBFRAME}, + {RG_SCH_TDD_DL_SUBFRAME, RG_SCH_TDD_SPL_SUBFRAME, RG_SCH_TDD_UL_SUBFRAME, RG_SCH_TDD_DL_SUBFRAME, RG_SCH_TDD_DL_SUBFRAME, RG_SCH_TDD_DL_SUBFRAME, RG_SCH_TDD_DL_SUBFRAME, RG_SCH_TDD_DL_SUBFRAME, RG_SCH_TDD_DL_SUBFRAME, RG_SCH_TDD_DL_SUBFRAME}, + {RG_SCH_TDD_DL_SUBFRAME, RG_SCH_TDD_SPL_SUBFRAME, RG_SCH_TDD_UL_SUBFRAME, RG_SCH_TDD_UL_SUBFRAME, RG_SCH_TDD_UL_SUBFRAME, RG_SCH_TDD_DL_SUBFRAME, RG_SCH_TDD_SPL_SUBFRAME, RG_SCH_TDD_UL_SUBFRAME, RG_SCH_TDD_UL_SUBFRAME, RG_SCH_TDD_DL_SUBFRAME} +}; + +/* SPS_INTG_FIX */ +#ifdef LTEMAC_SPS +PUBLIC U8 rgSchTddSpsDlMaxRetxTbl[RGSCH_MAX_TDD_UL_DL_CFG] = { + /* 0 */ 6, + /* 1 */ 7, + /* 2 */ 8, + /* 3 */ 11, + /* 4 */ 12, + /* 5 */ 13, + /* 6 */ 7}; + +#endif + + +/* Special Subframes in OFDM symbols */ +/* ccpu00134197-MOD-Correct the number of symbols */ +PUBLIC RgSchTddSplSubfrmInfoTbl rgSchTddSplSubfrmInfoTbl = { + {3, 1, 1, 3, 1, 1}, + {9, 1, 1, 8, 1, 1}, + {10, 1, 1, 9, 1, 1}, + {11, 1, 1, 10, 1, 1}, + {12, 1, 1, 3, 2, 2}, + {3, 2, 2, 8, 2, 2}, + {9, 2, 2, 9, 2, 2}, + {10, 2, 2, 0, 0, 0}, + {11, 2, 2, 0, 0, 0} +}; + +/* PHICH 'm' value Table */ +PUBLIC RgSchTddPhichMValTbl rgSchTddPhichMValTbl = { + {2, 1, 0, 0, 0, 2, 1, 0, 0, 0}, + {0, 1, 0, 0, 1, 0, 1, 0, 0, 1}, + {0, 0, 0, 1, 0, 0, 0, 0, 1, 0}, + {1, 0, 0, 0, 0, 0, 0, 0, 1, 1}, + {0, 0, 0, 0, 0, 0, 0, 0, 1, 1}, + {0, 0, 0, 0, 0, 0, 0, 0, 1, 0}, + {1, 1, 0, 0, 0, 1, 1, 0, 0, 1} +}; + +/* PHICH 'K' value Table */ +PUBLIC RgSchTddKPhichTbl rgSchTddKPhichTbl = { + {0, 0, 4, 7, 6, 0, 0, 4, 7, 6}, + {0, 0, 4, 6, 0, 0, 0, 4, 6, 0}, + {0, 0, 6, 0, 0, 0, 0, 6, 0, 0}, + {0, 0, 6, 6, 6, 0, 0, 0, 0, 0}, + {0, 0, 6, 6, 0, 0, 0, 0, 0, 0}, + {0, 0, 6, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 4, 6, 6, 0, 0, 4, 7, 0} +}; + +/* Uplink association index 'K' value Table */ +PUBLIC RgSchTddUlAscIdxKDashTbl rgSchTddUlAscIdxKDashTbl = { + {0, 0, 6, 4, 0, 0, 0, 6, 4, 0}, + {0, 0, 4, 0, 0, 0, 0, 4, 0, 0}, + {0, 0, 4, 4, 4, 0, 0, 0, 0, 0}, + {0, 0, 4, 4, 0, 0, 0, 0, 0, 0}, + {0, 0, 4, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 7, 7, 5, 0, 0, 7, 7, 0} +}; + + +/* PUSCH 'K' value Table */ +PUBLIC RgSchTddPuschTxKTbl rgSchTddPuschTxKTbl = { + {4, 6, 0, 0, 0, 4, 6, 0, 0, 0}, + {0, 6, 0, 0, 4, 0, 6, 0, 0, 4}, + {0, 0, 0, 4, 0, 0, 0, 0, 4, 0}, + {4, 0, 0, 0, 0, 0, 0, 0, 4, 4}, + {0, 0, 0, 0, 0, 0, 0, 0, 4, 4}, + {0, 0, 0, 0, 0, 0, 0, 0, 4, 0}, + {7, 7, 0, 0, 0, 7, 7, 0, 0, 5} +}; + +/* PDSCH to PUCCH Table for DL Harq Feed back. Based on the + Downlink association set index 'K' table */ +PUBLIC U8 rgSchTddPucchTxTbl[7][10] = { + {4, 6, 0, 0, 0, 4, 6, 0, 0, 0}, + {7, 6, 0, 0, 4, 7, 6, 0, 0, 4}, + {7, 6, 0, 4, 8, 7, 6, 0, 4, 8}, + {4, 11, 0, 0, 0, 7, 6, 6, 5, 5}, + {12, 11, 0, 0, 8, 7, 7, 6, 5, 4}, + {12, 11, 0, 9, 8, 7, 6, 5, 4, 13}, + {7, 7, 0, 0, 0, 7, 7, 0, 0, 5} +}; + +/* Table to fetch the next DL sf idx for applying the + new CFI. The next Dl sf Idx at which the new CFI + is applied is always the starting Sf of the next ACK/NACK + Fdbk bundle. + + Ex: In Cfg-2, sf4 and sf9 are the only subframes at which + a new ACK/NACK bundle of DL subframes can start + + D S U D D D S U D D D S U D D D S U D D + 4 9 + + dlSf Array for Cfg-2: + sfNum: 0 1 3 4 5 6 8 9 0 1 3 4 5 6 8 9 + sfIdx: 0 1 2 3 4 5 6 7 8 9 10 11 12 12 14 15 + + If CFI changes at sf0, nearest DL SF bundle >= 4 TTI is sf4 + So at sf4 the new CFI can be applied. To arrive at sf4 from + sf0, the sfIdx has to be increased by 3 */ + +PUBLIC U8 rgSchTddPdcchSfIncTbl[7][10] = { + /* A/N Bundl: 0,1,5,6*/ {2, 1, 0, 0, 0, 2, 1, 0, 0, 0}, + /* A/N Bundl: 0,4,5,9*/ {2, 2, 0, 0, 3, 2, 2, 0, 0, 3}, + /* A/N Bundl: 4,9*/ {3, 6, 0, 5, 4, 3, 6, 0, 5, 4}, + /* A/N Bundl: 1,7,9*/ {4, 3, 0, 0, 0, 4, 5, 4, 6, 5}, + /* A/N Bundl: 0,6*/ {4, 3, 0, 0, 6, 5, 4, 7, 6, 5}, + /* A/N Bundl: 9*/ {8, 7, 0, 6, 5, 4, 12, 11, 10, 9}, + /* A/N Bundl: 0,1,5,6,9*/ {2, 1, 0, 0, 0, 2, 2, 0, 0, 3} +}; + + +/* combine compilation fixes */ +#ifdef LTEMAC_SPS +/* subframe offset values to be used when twoIntervalsConfig is enabled in UL + * SPS for a UE */ +PUBLIC RgSchTddSfOffTbl rgSchTddSfOffTbl = { + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 1, -1, 0, 0, 0, 1, -1, 0}, + {0, 0, 5, 0, 0, 0, 0, -5, 0, 0}, + {0, 0, 1, 1, -2, 0, 0, 0, 0, 0}, + {0, 0, 1, -1, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0} +}; + + +/* Table to determine when uplink SPS configured grants should + * explicitly be reserved in a subframe. When enries are same + * as that of Msg3SubfrmTbl, indicates competition with msg3. + * As of now, this is same as Msg3SubfrmTbl (leaving out uldlcfg 2), + * except that all 255s are now zeros. */ +PUBLIC RgSchTddSpsUlRsrvTbl rgSchTddSpsUlRsrvTbl = { + {0, 0, 0, 6, 8, 0, 0, 0, 6, 8}, + {0, 0, 6, 9, 0, 0, 0, 6, 9, 0}, + {0, 0, 10, 0, 0, 0, 0, 10, 0, 0}, + {0, 0, 0, 0, 8, 0, 7, 7, 14, 0}, + {0, 0, 0, 9, 0, 0, 7, 15, 0, 0}, + {0, 0, 10, 0, 0, 0, 16, 0, 0, 0}, + {0, 0, 0, 0, 8, 0, 0, 0, 9, 0} +}; + +/* Inverse DL Assoc Set index Table */ +PUBLIC RgSchTddInvDlAscSetIdxTbl rgSchTddInvDlAscSetIdxTbl = { + {4, 6, 0, 0, 0, 4, 6, 0, 0, 0}, + {7, 6, 0, 0, 4, 7, 6, 0, 0, 4}, + {7, 6, 0, 4, 8, 7, 6, 0, 4, 8}, + {4, 11, 0, 0, 0, 7, 6, 6, 5, 5}, + {12, 11, 0, 0, 8, 7, 7, 6, 5, 4}, + {12, 11, 0, 9, 8, 7, 6, 5, 4, 13}, + {7, 7, 0, 0, 0, 7, 7, 0, 0, 5} +}; + +#endif /* (LTEMAC_SPS ) */ + +/* Number of Uplink subframes Table */ +PRIVATE U8 rgSchTddNumUlSf[] = {6, 4, 2, 3, 2, 1, 5}; + +/* Downlink HARQ processes Table */ +PUBLIC RgSchTddUlNumHarqProcTbl rgSchTddUlNumHarqProcTbl = { 7, 4, 2, 3, 2, 1, 6}; + +/* Uplink HARQ processes Table */ +PUBLIC RgSchTddDlNumHarqProcTbl rgSchTddDlNumHarqProcTbl = { 4, 7, 10, 9, 12, 15, 6}; + +/* Downlink association index set 'K' value Table */ +PUBLIC RgSchTddDlAscSetIdxKTbl rgSchTddDlAscSetIdxKTbl = { + { {0, {0}}, {0, {0}}, {1, {6}}, {0, {0}}, {1, {4}}, {0, {0}}, {0, {0}}, {1, {6}}, {0, {0}}, {1, {4}} }, + + { {0, {0}}, {0, {0}}, {2, {7, 6}}, {1, {4}}, {0, {0}}, {0, {0}}, {0, {0}}, {2, {7, 6}}, {1, {4}}, {0, {0}} }, + + { {0, {0}}, {0, {0}}, {4, {8, 7, 4, 6}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {4, {8, 7, 4, 6}}, {0, {0}}, {0, {0}} }, + + { {0, {0}}, {0, {0}}, {3, {7, 6, 11}}, {2, {6, 5}}, {2, {5, 4}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}} }, + + { {0, {0}}, {0, {0}}, {4, {12, 8, 7, 11}}, {4, {6, 5, 4, 7}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}} }, + + { {0, {0}}, {0, {0}}, {9, {13, 12, 9, 8, 7, 5, 4, 11, 6}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}} }, + + { {0, {0}}, {0, {0}}, {1, {7}}, {1, {7}}, {1, {5}}, {0, {0}}, {0, {0}}, {1, {7}}, {1, {7}}, {0, {0}} } +}; + + /* ccpu132282-ADD-the table rgSchTddDlAscSetIdxKTbl is rearranged in + * decreasing order of Km, this is used to calculate the NCE used for + * calculating N1Pucch Resource for Harq*/ +PUBLIC RgSchTddDlAscSetIdxKTbl rgSchTddDlHqPucchResCalTbl = { + { {0, {0}}, {0, {0}}, {1, {6}}, {0, {0}}, {1, {4}}, {0, {0}}, {0, {0}}, {1, {6}}, {0, {0}}, {1, {4}} }, + + { {0, {0}}, {0, {0}}, {2, {7, 6}}, {1, {4}}, {0, {0}}, {0, {0}}, {0, {0}}, {2, {7, 6}}, {1, {4}}, {0, {0}} }, + + { {0, {0}}, {0, {0}}, {4, {8, 7, 6, 4}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {4, {8, 7, 6, 4}}, {0, {0}}, {0, {0}} }, + + { {0, {0}}, {0, {0}}, {3, {11, 7, 6}}, {2, {6, 5}}, {2, {5, 4}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}} }, + + { {0, {0}}, {0, {0}}, {4, {12, 11, 8, 7}}, {4, {7, 6, 5, 4}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}} }, + + { {0, {0}}, {0, {0}}, {9, {13, 12, 11, 9, 8, 7, 6, 5, 4}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}} }, + + { {0, {0}}, {0, {0}}, {1, {7}}, {1, {7}}, {1, {5}}, {0, {0}}, {0, {0}}, {1, {7}}, {1, {7}}, {0, {0}} } +}; + +/* Minimum number of Ack/Nack feeback information to be + stored for each UL-DL configuration */ +PUBLIC RgSchTddANFdbkMapTbl rgSchTddANFdbkMapTbl = {4, 4, 2, 3, 2, 1, 5}; + +/* Uplink switch points and number of UL subframes Table */ +PUBLIC RgSchTddMaxUlSubfrmTbl rgSchTddMaxUlSubfrmTbl = { + {2,3,3}, {2,2,2}, {2,1,1}, {1,3,0}, {1,2,0}, {1,1,0}, {2,3,2} +}; + +/* Uplink switch points and number of DL subframes Table */ +PUBLIC RgSchTddMaxDlSubfrmTbl rgSchTddMaxDlSubfrmTbl = { + {2,2,2}, {2,3,3}, {2,4,4}, {1,7,0}, {1,8,0}, {1,9,0}, {2,2,3} +}; + +/* Number of UL subframes present before a particular subframe */ +PUBLIC RgSchTddNumUlSubfrmTbl rgSchTddNumUlSubfrmTbl = { + {0, 0, 1, 2, 3, 3, 3, 4, 5, 6}, + {0, 0, 1, 2, 2, 2, 2, 3, 4, 4}, + {0, 0, 1, 1, 1, 1, 1, 2, 2, 2}, + {0, 0, 1, 2, 3, 3, 3, 3, 3, 3}, + {0, 0, 1, 2, 2, 2, 2, 2, 2, 2}, + {0, 0, 1, 1, 1, 1, 1, 1, 1, 1}, + {0, 0, 1, 2, 3, 3, 3, 4, 5, 5} +}; + +/* Number of DL subframes present till a particular subframe */ +PUBLIC RgSchTddNumDlSubfrmTbl rgSchTddNumDlSubfrmTbl = { + {1, 2, 2, 2, 2, 3, 4, 4, 4, 4}, + {1, 2, 2, 2, 3, 4, 5, 5, 5, 6}, + {1, 2, 2, 3, 4, 5, 6, 6, 7, 8}, + {1, 2, 2, 2, 2, 3, 4, 5, 6, 7}, + {1, 2, 2, 2, 3, 4, 5, 6, 7, 8}, + {1, 2, 2, 3, 4, 5, 6, 7, 8, 9}, + {1, 2, 2, 2, 2, 3, 4, 4, 4, 5} +}; + + +/* Nearest possible UL subframe Index from UL subframe + * DL Index < UL Index */ +PUBLIC RgSchTddLowDlSubfrmIdxTbl rgSchTddLowDlSubfrmIdxTbl = { + {0, 1, 1, 1, 1, 5, 6, 6, 6, 6}, + {0, 1, 1, 1, 4, 5, 6, 6, 6, 9}, + {0, 1, 1, 3, 4, 5, 6, 6, 8, 9}, + {0, 1, 1, 1, 1, 5, 6, 7, 8, 9}, + {0, 1, 1, 1, 4, 5, 6, 7, 8, 9}, + {0, 1, 1, 3, 4, 5, 6, 7, 8, 9}, + {0, 1, 1, 1, 1, 5, 6, 6, 6, 9} +}; + +/* Nearest possible DL subframe Index from UL subframe + * DL Index > UL Index + * 10 represents Next SFN low DL Idx */ +PUBLIC RgSchTddHighDlSubfrmIdxTbl rgSchTddHighDlSubfrmIdxTbl = { + {0, 1, 5, 5, 5, 5, 6, 10, 10, 10}, + {0, 1, 4, 4, 4, 5, 6, 9, 9, 9}, + {0, 1, 3, 3, 4, 5, 6, 8, 8, 9}, + {0, 1, 5, 5, 5, 5, 6, 7, 8, 9}, + {0, 1, 4, 4, 4, 5, 6, 7, 8, 9}, + {0, 1, 3, 3, 4, 5, 6, 7, 8, 9}, + {0, 1, 5, 5, 5, 5, 6, 9, 9, 9} +}; + +/* RACH Message3 related information */ +PUBLIC RgSchTddMsg3SubfrmTbl rgSchTddMsg3SubfrmTbl = { + {7, 6, 255, 255, 255, 7, 6, 255, 255, 255}, + {7, 6, 255, 255, 8, 7, 6, 255, 255, 8}, + {7, 6, 255, 9, 8, 7, 6, 255, 9, 8}, + {12, 11, 255, 255, 255, 7, 6, 6, 6, 13}, + {12, 11, 255, 255, 8, 7, 6, 6, 14, 13}, + {12, 11, 255, 9, 8, 7, 6, 15, 14, 13}, + {7, 6, 255, 255, 255, 7, 6, 255, 255, 8} +}; + +/* ccpu00132341-DEL Removed rgSchTddRlsDlSubfrmTbl and used Kset table for + * releasing DL HARQs */ + +/* DwPTS Scheduling Changes Start */ +/* Provides the number of Cell Reference Signals in DwPTS + * region per RB */ +PRIVATE U8 rgSchCmnDwptsCrs[2][3] = {/* [Spl Sf cfg][Ant Port] */ + {4, 8, 16}, /* Spl Sf cfg 1,2,3,6,7,8 */ + {6, 12, 20}, /* Spl Sf cfg 4 */ +}; + +PRIVATE S8 rgSchCmnSplSfDeltaItbs[9] = RG_SCH_DWPTS_ITBS_ADJ; +/* DwPTS Scheduling Changes End */ +#endif + + +PRIVATE U32 rgSchCmnBsrTbl[64] = { + 0, 10, 12, 14, 17, 19, 22, 26, + 31, 36, 42, 49, 57, 67, 78, 91, + 107, 125, 146, 171, 200, 234, 274, 321, + 376, 440, 515, 603, 706, 826, 967, 1132, + 1326, 1552, 1817, 2127, 2490, 2915, 3413, 3995, + 4677, 5476, 6411, 7505, 8787, 10287, 12043, 14099, + 16507, 19325, 22624, 26487, 31009, 36304, 42502, 49759, + 58255, 68201, 79846, 93479, 109439, 128125, 150000, 220000 +}; + +PRIVATE U32 rgSchCmnExtBsrTbl[64] = { + 0, 10, 13, 16, 19, 23, 29, 35, + 43, 53, 65, 80, 98, 120, 147, 181, + 223, 274, 337, 414, 509, 625, 769, 945, + 1162, 1429, 1757, 2161, 2657, 3267, 4017, 4940, + 6074, 7469, 9185, 11294, 13888, 17077, 20999, 25822, + 31752, 39045, 48012, 59039, 72598, 89272, 109774, 134986, + 165989, 204111, 250990, 308634, 379519, 466683, 573866, 705666, + 867737, 1067031, 1312097, 1613447, 1984009, 2439678, 3000000, 3100000 +}; + + +PRIVATE U8 rgSchCmnUlRvIdxToIMcsTbl[4] = {32, 30, 31, 29}; + +PUBLIC U8 rgSchCmnUlCqiToTbsTbl[RG_SCH_CMN_MAX_CP][RG_SCH_CMN_UL_NUM_CQI]; + +PUBLIC RgSchTbSzTbl rgTbSzTbl = { + { + {16, 32, 56, 88, 120, 152, 176, 208, 224, 256, 288, 328, 344, 376, 392, 424, 456, 488, 504, 536, 568, 600, 616, 648, 680, 712, 744, 776, 776, 808, 840, 872, 904, 936, 968, 1000, 1032, 1032, 1064, 1096, 1128, 1160, 1192, 1224, 1256, 1256, 1288, 1320, 1352, 1384, 1416, 1416, 1480, 1480, 1544, 1544, 1608, 1608, 1608, 1672, 1672, 1736, 1736, 1800, 1800, 1800, 1864, 1864, 1928, 1928, 1992, 1992, 2024, 2088, 2088, 2088, 2152, 2152, 2216, 2216, 2280, 2280, 2280, 2344, 2344, 2408, 2408, 2472, 2472, 2536, 2536, 2536, 2600, 2600, 2664, 2664, 2728, 2728, 2728, 2792, 2792, 2856, 2856, 2856, 2984, 2984, 2984, 2984, 2984, 3112}, + {24, 56, 88, 144, 176, 208, 224, 256, 328, 344, 376, 424, 456, 488, 520, 568, 600, 632, 680, 712, 744, 776, 808, 872, 904, 936, 968, 1000, 1032, 1064, 1128, 1160, 1192, 1224, 1256, 1288, 1352, 1384, 1416, 1416, 1480, 1544, 1544, 1608, 1608, 1672, 1736, 1736, 1800, 1800, 1864, 1864, 1928, 1992, 1992, 2024, 2088, 2088, 2152, 2152, 2216, 2280, 2280, 2344, 2344, 2408, 2472, 2472, 2536, 2536, 2600, 2600, 2664, 2728, 2728, 2792, 2792, 2856, 2856, 2856, 2984, 2984, 2984, 3112, 3112, 3112, 3240, 3240, 3240, 3240, 3368, 3368, 3368, 3496, 3496, 3496, 3496, 3624, 3624, 3624, 3752, 3752, 3752, 3752, 3880, 3880, 3880, 4008, 4008, 4008}, + {32, 72, 144, 176, 208, 256, 296, 328, 376, 424, 472, 520, 568, 616, 648, 696, 744, 776, 840, 872, 936, 968, 1000, 1064, 1096, 1160, 1192, 1256, 1288, 1320, 1384, 1416, 1480, 1544, 1544, 1608, 1672, 1672, 1736, 1800, 1800, 1864, 1928, 1992, 2024, 2088, 2088, 2152, 2216, 2216, 2280, 2344, 2344, 2408, 2472, 2536, 2536, 2600, 2664, 2664, 2728, 2792, 2856, 2856, 2856, 2984, 2984, 3112, 3112, 3112, 3240, 3240, 3240, 3368, 3368, 3368, 3496, 3496, 3496, 3624, 3624, 3624, 3752, 3752, 3880, 3880, 3880, 4008, 4008, 4008, 4136, 4136, 4136, 4264, 4264, 4264, 4392, 4392, 4392, 4584, 4584, 4584, 4584, 4584, 4776, 4776, 4776, 4776, 4968, 4968}, + {40, 104, 176, 208, 256, 328, 392, 440, 504, 568, 616, 680, 744, 808, 872, 904, 968, 1032, 1096, 1160, 1224, 1256, 1320, 1384, 1416, 1480, 1544, 1608, 1672, 1736, 1800, 1864, 1928, 1992, 2024, 2088, 2152, 2216, 2280, 2344, 2408, 2472, 2536, 2536, 2600, 2664, 2728, 2792, 2856, 2856, 2984, 2984, 3112, 3112, 3240, 3240, 3368, 3368, 3496, 3496, 3624, 3624, 3624, 3752, 3752, 3880, 3880, 4008, 4008, 4136, 4136, 4264, 4264, 4392, 4392, 4392, 4584, 4584, 4584, 4776, 4776, 4776, 4776, 4968, 4968, 4968, 5160, 5160, 5160, 5352, 5352, 5352, 5352, 5544, 5544, 5544, 5736, 5736, 5736, 5736, 5992, 5992, 5992, 5992, 6200, 6200, 6200, 6200, 6456, 6456}, + {56, 120, 208, 256, 328, 408, 488, 552, 632, 696, 776, 840, 904, 1000, 1064, 1128, 1192, 1288, 1352, 1416, 1480, 1544, 1608, 1736, 1800, 1864, 1928, 1992, 2088, 2152, 2216, 2280, 2344, 2408, 2472, 2600, 2664, 2728, 2792, 2856, 2984, 2984, 3112, 3112, 3240, 3240, 3368, 3496, 3496, 3624, 3624, 3752, 3752, 3880, 4008, 4008, 4136, 4136, 4264, 4264, 4392, 4392, 4584, 4584, 4584, 4776, 4776, 4968, 4968, 4968, 5160, 5160, 5160, 5352, 5352, 5544, 5544, 5544, 5736, 5736, 5736, 5992, 5992, 5992, 5992, 6200, 6200, 6200, 6456, 6456, 6456, 6456, 6712, 6712, 6712, 6968, 6968, 6968, 6968, 7224, 7224, 7224, 7480, 7480, 7480, 7480, 7736, 7736, 7736, 7992}, + {72, 144, 224, 328, 424, 504, 600, 680, 776, 872, 968, 1032, 1128, 1224, 1320, 1384, 1480, 1544, 1672, 1736, 1864, 1928, 2024, 2088, 2216, 2280, 2344, 2472, 2536, 2664, 2728, 2792, 2856, 2984, 3112, 3112, 3240, 3368, 3496, 3496, 3624, 3752, 3752, 3880, 4008, 4008, 4136, 4264, 4392, 4392, 4584, 4584, 4776, 4776, 4776, 4968, 4968, 5160, 5160, 5352, 5352, 5544, 5544, 5736, 5736, 5736, 5992, 5992, 5992, 6200, 6200, 6200, 6456, 6456, 6712, 6712, 6712, 6968, 6968, 6968, 7224, 7224, 7224, 7480, 7480, 7480, 7736, 7736, 7736, 7992, 7992, 7992, 8248, 8248, 8248, 8504, 8504, 8760, 8760, 8760, 8760, 9144, 9144, 9144, 9144, 9528, 9528, 9528, 9528, 9528}, + {328, 176, 256, 392, 504, 600, 712, 808, 936, 1032, 1128, 1224, 1352, 1480, 1544, 1672, 1736, 1864, 1992, 2088, 2216, 2280, 2408, 2472, 2600, 2728, 2792, 2984, 2984, 3112, 3240, 3368, 3496, 3496, 3624, 3752, 3880, 4008, 4136, 4136, 4264, 4392, 4584, 4584, 4776, 4776, 4968, 4968, 5160, 5160, 5352, 5352, 5544, 5736, 5736, 5992, 5992, 5992, 6200, 6200, 6456, 6456, 6456, 6712, 6712, 6968, 6968, 6968, 7224, 7224, 7480, 7480, 7736, 7736, 7736, 7992, 7992, 8248, 8248, 8248, 8504, 8504, 8760, 8760, 8760, 9144, 9144, 9144, 9144, 9528, 9528, 9528, 9528, 9912, 9912, 9912, 10296, 10296, 10296, 10296, 10680, 10680, 10680, 10680, 11064, 11064, 11064, 11448, 11448, 11448}, + {104, 224, 328, 472, 584, 712, 840, 968, 1096, 1224, 1320, 1480, 1608, 1672, 1800, 1928, 2088, 2216, 2344, 2472, 2536, 2664, 2792, 2984, 3112, 3240, 3368, 3368, 3496, 3624, 3752, 3880, 4008, 4136, 4264, 4392, 4584, 4584, 4776, 4968, 4968, 5160, 5352, 5352, 5544, 5736, 5736, 5992, 5992, 6200, 6200, 6456, 6456, 6712, 6712, 6712, 6968, 6968, 7224, 7224, 7480, 7480, 7736, 7736, 7992, 7992, 8248, 8248, 8504, 8504, 8760, 8760, 8760, 9144, 9144, 9144, 9528, 9528, 9528, 9912, 9912, 9912, 10296, 10296, 10296, 10680, 10680, 10680, 11064, 11064, 11064, 11448, 11448, 11448, 11448, 11832, 11832, 11832, 12216, 12216, 12216, 12576, 12576, 12576, 12960, 12960, 12960, 12960, 13536, 13536}, + {120, 256, 392, 536, 680, 808, 968, 1096, 1256, 1384, 1544, 1672, 1800, 1928, 2088, 2216, 2344, 2536, 2664, 2792, 2984, 3112, 3240, 3368, 3496, 3624, 3752, 3880, 4008, 4264, 4392, 4584, 4584, 4776, 4968, 4968, 5160, 5352, 5544, 5544, 5736, 5992, 5992, 6200, 6200, 6456, 6456, 6712, 6968, 6968, 7224, 7224, 7480, 7480, 7736, 7736, 7992, 7992, 8248, 8504, 8504, 8760, 8760, 9144, 9144, 9144, 9528, 9528, 9528, 9912, 9912, 9912, 10296, 10296, 10680, 10680, 10680, 11064, 11064, 11064, 11448, 11448, 11448, 11832, 11832, 12216, 12216, 12216, 12576, 12576, 12576, 12960, 12960, 12960, 13536, 13536, 13536, 13536, 14112, 14112, 14112, 14112, 14688, 14688, 14688, 14688, 15264, 15264, 15264, 15264}, + {136, 296, 456, 616, 776, 936, 1096, 1256, 1416, 1544, 1736, 1864, 2024, 2216, 2344, 2536, 2664, 2856, 2984, 3112, 3368, 3496, 3624, 3752, 4008, 4136, 4264, 4392, 4584, 4776, 4968, 5160, 5160, 5352, 5544, 5736, 5736, 5992, 6200, 6200, 6456, 6712, 6712, 6968, 6968, 7224, 7480, 7480, 7736, 7992, 7992, 8248, 8248, 8504, 8760, 8760, 9144, 9144, 9144, 9528, 9528, 9912, 9912, 10296, 10296, 10296, 10680, 10680, 11064, 11064, 11064, 11448, 11448, 11832, 11832, 11832, 12216, 12216, 12576, 12576, 12960, 12960, 12960, 13536, 13536, 13536, 13536, 14112, 14112, 14112, 14112, 14688, 14688, 14688, 15264, 15264, 15264, 15264, 15840, 15840, 15840, 16416, 16416, 16416, 16416, 16992, 16992, 16992, 16992, 17568}, + {144, 328, 504, 680, 872, 1032, 1224, 1384, 1544, 1736, 1928, 2088, 2280, 2472, 2664, 2792, 2984, 3112, 3368, 3496, 3752, 3880, 4008, 4264, 4392, 4584, 4776, 4968, 5160, 5352, 5544, 5736, 5736, 5992, 6200, 6200, 6456, 6712, 6712, 6968, 7224, 7480, 7480, 7736, 7992, 7992, 8248, 8504, 8504, 8760, 9144, 9144, 9144, 9528, 9528, 9912, 9912, 10296, 10296, 10680, 10680, 11064, 11064, 11448, 11448, 11448, 11832, 11832, 12216, 12216, 12576, 12576, 12960, 12960, 12960, 13536, 13536, 13536, 14112, 14112, 14112, 14688, 14688, 14688, 14688, 15264, 15264, 15264, 15840, 15840, 15840, 16416, 16416, 16416, 16992, 16992, 16992, 16992, 17568, 17568, 17568, 18336, 18336, 18336, 18336, 18336, 19080, 19080, 19080, 19080}, + {176, 376, 584, 776, 1000, 1192, 1384, 1608, 1800, 2024, 2216, 2408, 2600, 2792, 2984, 3240, 3496, 3624, 3880, 4008, 4264, 4392, 4584, 4776, 4968, 5352, 5544, 5736, 5992, 5992, 6200, 6456, 6712, 6968, 6968, 7224, 7480, 7736, 7736, 7992, 8248, 8504, 8760, 8760, 9144, 9144, 9528, 9528, 9912, 9912, 10296, 10680, 10680, 11064, 11064, 11448, 11448, 11832, 11832, 12216, 12216, 12576, 12576, 12960, 12960, 13536, 13536, 13536, 14112, 14112, 14112, 14688, 14688, 14688, 15264, 15264, 15840, 15840, 15840, 16416, 16416, 16416, 16992, 16992, 16992, 17568, 17568, 17568, 18336, 18336, 18336, 18336, 19080, 19080, 19080, 19080, 19848, 19848, 19848, 19848, 20616, 20616, 20616, 21384, 21384, 21384, 21384, 22152, 22152, 22152}, + {208, 440, 680, 904, 1128, 1352, 1608, 1800, 2024, 2280, 2472, 2728, 2984, 3240, 3368, 3624, 3880, 4136, 4392, 4584, 4776, 4968, 5352, 5544, 5736, 5992, 6200, 6456, 6712, 6712, 6968, 7224, 7480, 7736, 7992, 8248, 8504, 8760, 8760, 9144, 9528, 9528, 9912, 9912, 10296, 10680, 10680, 11064, 11064, 11448, 11832, 11832, 12216, 12216, 12576, 12576, 12960, 12960, 13536, 13536, 14112, 14112, 14112, 14688, 14688, 15264, 15264, 15264, 15840, 15840, 16416, 16416, 16416, 16992, 16992, 17568, 17568, 17568, 18336, 18336, 18336, 19080, 19080, 19080, 19080, 19848, 19848, 19848, 20616, 20616, 20616, 21384, 21384, 21384, 21384, 22152, 22152, 22152, 22920, 22920, 22920, 23688, 23688, 23688, 23688, 24496, 24496, 24496, 24496, 25456}, + {224, 488, 744, 1000, 1256, 1544, 1800, 2024, 2280, 2536, 2856, 3112, 3368, 3624, 3880, 4136, 4392, 4584, 4968, 5160, 5352, 5736, 5992, 6200, 6456, 6712, 6968, 7224, 7480, 7736, 7992, 8248, 8504, 8760, 9144, 9144, 9528, 9912, 9912, 10296, 10680, 10680, 11064, 11448, 11448, 11832, 12216, 12216, 12576, 12960, 12960, 13536, 13536, 14112, 14112, 14688, 14688, 14688, 15264, 15264, 15840, 15840, 16416, 16416, 16992, 16992, 16992, 17568, 17568, 18336, 18336, 18336, 19080, 19080, 19080, 19848, 19848, 19848, 20616, 20616, 20616, 21384, 21384, 21384, 22152, 22152, 22152, 22920, 22920, 22920, 23688, 23688, 23688, 24496, 24496, 24496, 25456, 25456, 25456, 25456, 26416, 26416, 26416, 26416, 27376, 27376, 27376, 27376, 28336, 28336}, + {256, 552, 840, 1128, 1416, 1736, 1992, 2280, 2600, 2856, 3112, 3496, 3752, 4008, 4264, 4584, 4968, 5160, 5544, 5736, 5992, 6200, 6456, 6968, 7224, 7480, 7736, 7992, 8248, 8504, 8760, 9144, 9528, 9912, 9912, 10296, 10680, 11064, 11064, 11448, 11832, 12216, 12216, 12576, 12960, 12960, 13536, 13536, 14112, 14112, 14688, 14688, 15264, 15264, 15840, 15840, 16416, 16416, 16992, 16992, 17568, 17568, 18336, 18336, 18336, 19080, 19080, 19848, 19848, 19848, 20616, 20616, 20616, 21384, 21384, 22152, 22152, 22152, 22920, 22920, 22920, 23688, 23688, 24496, 24496, 24496, 25456, 25456, 25456, 25456, 26416, 26416, 26416, 27376, 27376, 27376, 28336, 28336, 28336, 28336, 29296, 29296, 29296, 29296, 30576, 30576, 30576, 30576, 31704, 31704}, + {280, 600, 904, 1224, 1544, 1800, 2152, 2472, 2728, 3112, 3368, 3624, 4008, 4264, 4584, 4968, 5160, 5544, 5736, 6200, 6456, 6712, 6968, 7224, 7736, 7992, 8248, 8504, 8760, 9144, 9528, 9912, 10296, 10296, 10680, 11064, 11448, 11832, 11832, 12216, 12576, 12960, 12960, 13536, 13536, 14112, 14688, 14688, 15264, 15264, 15840, 15840, 16416, 16416, 16992, 16992, 17568, 17568, 18336, 18336, 18336, 19080, 19080, 19848, 19848, 20616, 20616, 20616, 21384, 21384, 22152, 22152, 22152, 22920, 22920, 23688, 23688, 23688, 24496, 24496, 24496, 25456, 25456, 25456, 26416, 26416, 26416, 27376, 27376, 27376, 28336, 28336, 28336, 29296, 29296, 29296, 29296, 30576, 30576, 30576, 30576, 31704, 31704, 31704, 31704, 32856, 32856, 32856, 34008, 34008}, + {328, 632, 968, 1288, 1608, 1928, 2280, 2600, 2984, 3240, 3624, 3880, 4264, 4584, 4968, 5160, 5544, 5992, 6200, 6456, 6712, 7224, 7480, 7736, 7992, 8504, 8760, 9144, 9528, 9912, 9912, 10296, 10680, 11064, 11448, 11832, 12216, 12216, 12576, 12960, 13536, 13536, 14112, 14112, 14688, 14688, 15264, 15840, 15840, 16416, 16416, 16992, 16992, 17568, 17568, 18336, 18336, 19080, 19080, 19848, 19848, 19848, 20616, 20616, 21384, 21384, 22152, 22152, 22152, 22920, 22920, 23688, 23688, 24496, 24496, 24496, 25456, 25456, 25456, 26416, 26416, 26416, 27376, 27376, 27376, 28336, 28336, 28336, 29296, 29296, 29296, 30576, 30576, 30576, 30576, 31704, 31704, 31704, 31704, 32856, 32856, 32856, 34008, 34008, 34008, 34008, 35160, 35160, 35160, 35160}, + {336, 696, 1064, 1416, 1800, 2152, 2536, 2856, 3240, 3624, 4008, 4392, 4776, 5160, 5352, 5736, 6200, 6456, 6712, 7224, 7480, 7992, 8248, 8760, 9144, 9528, 9912, 10296, 10296, 10680, 11064, 11448, 11832, 12216, 12576, 12960, 13536, 13536, 14112, 14688, 14688, 15264, 15264, 15840, 16416, 16416, 16992, 17568, 17568, 18336, 18336, 19080, 19080, 19848, 19848, 20616, 20616, 20616, 21384, 21384, 22152, 22152, 22920, 22920, 23688, 23688, 24496, 24496, 24496, 25456, 25456, 26416, 26416, 26416, 27376, 27376, 27376, 28336, 28336, 29296, 29296, 29296, 30576, 30576, 30576, 30576, 31704, 31704, 31704, 32856, 32856, 32856, 34008, 34008, 34008, 35160, 35160, 35160, 35160, 36696, 36696, 36696, 36696, 37888, 37888, 37888, 39232, 39232, 39232, 39232}, + {376, 776, 1160, 1544, 1992, 2344, 2792, 3112, 3624, 4008, 4392, 4776, 5160, 5544, 5992, 6200, 6712, 7224, 7480, 7992, 8248, 8760, 9144, 9528, 9912, 10296, 10680, 11064, 11448, 11832, 12216, 12576, 12960, 13536, 14112, 14112, 14688, 15264, 15264, 15840, 16416, 16416, 16992, 17568, 17568, 18336, 18336, 19080, 19080, 19848, 19848, 20616, 21384, 21384, 22152, 22152, 22920, 22920, 23688, 23688, 24496, 24496, 24496, 25456, 25456, 26416, 26416, 27376, 27376, 27376, 28336, 28336, 29296, 29296, 29296, 30576, 30576, 30576, 31704, 31704, 31704, 32856, 32856, 32856, 34008, 34008, 34008, 35160, 35160, 35160, 36696, 36696, 36696, 37888, 37888, 37888, 37888, 39232, 39232, 39232, 40576, 40576, 40576, 40576, 42368, 42368, 42368, 42368, 43816, 43816}, + {408, 840, 1288, 1736, 2152, 2600, 2984, 3496, 3880, 4264, 4776, 5160, 5544, 5992, 6456, 6968, 7224, 7736, 8248, 8504, 9144, 9528, 9912, 10296, 10680, 11064, 11448, 12216, 12576, 12960, 13536, 13536, 14112, 14688, 15264, 15264, 15840, 16416, 16992, 16992, 17568, 18336, 18336, 19080, 19080, 19848, 20616, 20616, 21384, 21384, 22152, 22152, 22920, 22920, 23688, 24496, 24496, 25456, 25456, 25456, 26416, 26416, 27376, 27376, 28336, 28336, 29296, 29296, 29296, 30576, 30576, 30576, 31704, 31704, 32856, 32856, 32856, 34008, 34008, 34008, 35160, 35160, 35160, 36696, 36696, 36696, 37888, 37888, 37888, 39232, 39232, 39232, 40576, 40576, 40576, 40576, 42368, 42368, 42368, 43816, 43816, 43816, 43816, 45352, 45352, 45352, 46888, 46888, 46888, 46888}, + {440, 904, 1384, 1864, 2344, 2792, 3240, 3752, 4136, 4584, 5160, 5544, 5992, 6456, 6968, 7480, 7992, 8248, 8760, 9144, 9912, 10296, 10680, 11064, 11448, 12216, 12576, 12960, 13536, 14112, 14688, 14688, 15264, 15840, 16416, 16992, 16992, 17568, 18336, 18336, 19080, 19848, 19848, 20616, 20616, 21384, 22152, 22152, 22920, 22920, 23688, 24496, 24496, 25456, 25456, 26416, 26416, 27376, 27376, 28336, 28336, 29296, 29296, 29296, 30576, 30576, 31704, 31704, 31704, 32856, 32856, 34008, 34008, 34008, 35160, 35160, 35160, 36696, 36696, 36696, 37888, 37888, 39232, 39232, 39232, 40576, 40576, 40576, 42368, 42368, 42368, 42368, 43816, 43816, 43816, 45352, 45352, 45352, 46888, 46888, 46888, 46888, 48936, 48936, 48936, 48936, 48936, 51024, 51024, 51024}, + {488, 1000, 1480, 1992, 2472, 2984, 3496, 4008, 4584, 4968, 5544, 5992, 6456, 6968, 7480, 7992, 8504, 9144, 9528, 9912, 10680, 11064, 11448, 12216, 12576, 12960, 13536, 14112, 14688, 15264, 15840, 15840, 16416, 16992, 17568, 18336, 18336, 19080, 19848, 19848, 20616, 21384, 21384, 22152, 22920, 22920, 23688, 24496, 24496, 25456, 25456, 26416, 26416, 27376, 27376, 28336, 28336, 29296, 29296, 30576, 30576, 31704, 31704, 31704, 32856, 32856, 34008, 34008, 35160, 35160, 35160, 36696, 36696, 36696, 37888, 37888, 39232, 39232, 39232, 40576, 40576, 40576, 42368, 42368, 42368, 43816, 43816, 43816, 45352, 45352, 45352, 46888, 46888, 46888, 46888, 48936, 48936, 48936, 48936, 51024, 51024, 51024, 51024, 52752, 52752, 52752, 52752, 55056, 55056, 55056}, + {520, 1064, 1608, 2152, 2664, 3240, 3752, 4264, 4776, 5352, 5992, 6456, 6968, 7480, 7992, 8504, 9144, 9528, 10296, 10680, 11448, 11832, 12576, 12960, 13536, 14112, 14688, 15264, 15840, 16416, 16992, 16992, 17568, 18336, 19080, 19080, 19848, 20616, 21384, 21384, 22152, 22920, 22920, 23688, 24496, 24496, 25456, 25456, 26416, 27376, 27376, 28336, 28336, 29296, 29296, 30576, 30576, 31704, 31704, 32856, 32856, 34008, 34008, 34008, 35160, 35160, 36696, 36696, 36696, 37888, 37888, 39232, 39232, 40576, 40576, 40576, 42368, 42368, 42368, 43816, 43816, 43816, 45352, 45352, 45352, 46888, 46888, 46888, 48936, 48936, 48936, 48936, 51024, 51024, 51024, 51024, 52752, 52752, 52752, 55056, 55056, 55056, 55056, 57336, 57336, 57336, 57336, 59256, 59256, 59256}, + {552, 1128, 1736, 2280, 2856, 3496, 4008, 4584, 5160, 5736, 6200, 6968, 7480, 7992, 8504, 9144, 9912, 10296, 11064, 11448, 12216, 12576, 12960, 13536, 14112, 14688, 15264, 15840, 16416, 16992, 17568, 18336, 19080, 19848, 19848, 20616, 21384, 22152, 22152, 22920, 23688, 24496, 24496, 25456, 25456, 26416, 27376, 27376, 28336, 28336, 29296, 29296, 30576, 30576, 31704, 31704, 32856, 32856, 34008, 34008, 35160, 35160, 36696, 36696, 37888, 37888, 37888, 39232, 39232, 40576, 40576, 40576, 42368, 42368, 43816, 43816, 43816, 45352, 45352, 45352, 46888, 46888, 46888, 48936, 48936, 48936, 51024, 51024, 51024, 51024, 52752, 52752, 52752, 55056, 55056, 55056, 55056, 57336, 57336, 57336, 57336, 59256, 59256, 59256, 59256, 61664, 61664, 61664, 61664, 63776}, + {584, 1192, 1800, 2408, 2984, 3624, 4264, 4968, 5544, 5992, 6712, 7224, 7992, 8504, 9144, 9912, 10296, 11064, 11448, 12216, 12960, 13536, 14112, 14688, 15264, 15840, 16416, 16992, 17568, 18336, 19080, 19848, 19848, 20616, 21384, 22152, 22920, 22920, 23688, 24496, 25456, 25456, 26416, 26416, 27376, 28336, 28336, 29296, 29296, 30576, 31704, 31704, 32856, 32856, 34008, 34008, 35160, 35160, 36696, 36696, 36696, 37888, 37888, 39232, 39232, 40576, 40576, 42368, 42368, 42368, 43816, 43816, 45352, 45352, 45352, 46888, 46888, 46888, 48936, 48936, 48936, 51024, 51024, 51024, 52752, 52752, 52752, 52752, 55056, 55056, 55056, 57336, 57336, 57336, 57336, 59256, 59256, 59256, 61664, 61664, 61664, 61664, 63776, 63776, 63776, 63776, 66592, 66592, 66592, 66592}, + {616, 1256, 1864, 2536, 3112, 3752, 4392, 5160, 5736, 6200, 6968, 7480, 8248, 8760, 9528, 10296, 10680, 11448, 12216, 12576, 13536, 14112, 14688, 15264, 15840, 16416, 16992, 17568, 18336, 19080, 19848, 20616, 20616, 21384, 22152, 22920, 23688, 24496, 24496, 25456, 26416, 26416, 27376, 28336, 28336, 29296, 29296, 30576, 31704, 31704, 32856, 32856, 34008, 34008, 35160, 35160, 36696, 36696, 37888, 37888, 39232, 39232, 40576, 40576, 40576, 42368, 42368, 43816, 43816, 43816, 45352, 45352, 46888, 46888, 46888, 48936, 48936, 48936, 51024, 51024, 51024, 52752, 52752, 52752, 55056, 55056, 55056, 55056, 57336, 57336, 57336, 59256, 59256, 59256, 61664, 61664, 61664, 61664, 63776, 63776, 63776, 63776, 66592, 66592, 66592, 66592, 68808, 68808, 68808, 71112}, + {712, 1480, 2216, 2984, 3752, 4392, 5160, 5992, 6712, 7480, 8248, 8760, 9528, 10296, 11064, 11832, 12576, 13536, 14112, 14688, 15264, 16416, 16992, 17568, 18336, 19080, 19848, 20616, 21384, 22152, 22920, 23688, 24496, 25456, 25456, 26416, 27376, 28336, 29296, 29296, 30576, 30576, 31704, 32856, 32856, 34008, 35160, 35160, 36696, 36696, 37888, 37888, 39232, 40576, 40576, 40576, 42368, 42368, 43816, 43816, 45352, 45352, 46888, 46888, 48936, 48936, 48936, 51024, 51024, 52752, 52752, 52752, 55056, 55056, 55056, 55056, 57336, 57336, 57336, 59256, 59256, 59256, 61664, 61664, 61664, 63776, 63776, 63776, 66592, 66592, 66592, 68808, 68808, 68808, 71112, 71112, 71112, 73712, 73712, 75376, 75376, 75376, 75376, 75376, 75376, 75376, 75376, 75376, 75376, 75376} + }, + { + {32, 88, 152, 208, 256, 328, 376, 424, 488, 536, 600, 648, 712, 776, 808, 872, 936, 1000, 1032, 1096, 1160, 1224, 1256, 1320, 1384, 1416, 1480, 1544, 1608, 1672, 1736, 1800, 1800, 1864, 1928, 1992, 2088, 2088, 2152, 2216, 2280, 2344, 2408, 2472, 2536, 2536, 2600, 2664, 2728, 2792, 2856, 2856, 2984, 2984, 3112, 3112, 3240, 3240, 3240, 3368, 3368, 3496, 3496, 3624, 3624, 3624, 3752, 3752, 3880, 3880, 4008, 4008, 4008, 4136, 4136, 4136, 4264, 4264, 4392, 4392, 4584, 4584, 4584, 4776, 4776, 4776, 4776, 4968, 4968, 5160, 5160, 5160, 5160, 5160, 5352, 5352, 5544, 5544, 5544, 5544, 5544, 5736, 5736, 5736, 5992, 5992, 5992, 5992, 5992, 6200}, + {56, 144, 208, 256, 344, 424, 488, 568, 632, 712, 776, 872, 936, 1000, 1064, 1160, 1224, 1288, 1384, 1416, 1544, 1608, 1672, 1736, 1800, 1864, 1992, 2024, 2088, 2152, 2280, 2344, 2408, 2472, 2536, 2600, 2728, 2792, 2856, 2856, 2984, 3112, 3112, 3240, 3240, 3368, 3496, 3496, 3624, 3624, 3752, 3752, 3880, 4008, 4008, 4008, 4136, 4136, 4264, 4264, 4392, 4584, 4584, 4776, 4776, 4776, 4968, 4968, 5160, 5160, 5160, 5160, 5352, 5544, 5544, 5544, 5544, 5736, 5736, 5736, 5992, 5992, 5992, 6200, 6200, 6200, 6456, 6456, 6456, 6456, 6712, 6712, 6712, 6968, 6968, 6968, 6968, 7224, 7224, 7224, 7480, 7480, 7480, 7480, 7736, 7736, 7736, 7992, 7992, 7992}, + {72, 176, 256, 328, 424, 520, 616, 696, 776, 872, 968, 1064, 1160, 1256, 1320, 1416, 1544, 1608, 1672, 1800, 1864, 1992, 2088, 2152, 2216, 2344, 2408, 2536, 2600, 2664, 2792, 2856, 2984, 3112, 3112, 3240, 3368, 3368, 3496, 3624, 3624, 3752, 3880, 4008, 4008, 4136, 4264, 4264, 4392, 4584, 4584, 4584, 4776, 4776, 4968, 5160, 5160, 5160, 5352, 5352, 5544, 5544, 5736, 5736, 5736, 5992, 5992, 6200, 6200, 6200, 6456, 6456, 6456, 6712, 6712, 6712, 6968, 6968, 6968, 7224, 7224, 7224, 7480, 7480, 7736, 7736, 7736, 7992, 7992, 7992, 8248, 8248, 8248, 8504, 8504, 8504, 8760, 8760, 8760, 9144, 9144, 9144, 9144, 9144, 9528, 9528, 9528, 9528, 9912, 9912}, + {104, 208, 328, 440, 568, 680, 808, 904, 1032, 1160, 1256, 1384, 1480, 1608, 1736, 1864, 1992, 2088, 2216, 2344, 2472, 2536, 2664, 2792, 2856, 2984, 3112, 3240, 3368, 3496, 3624, 3752, 3880, 4008, 4136, 4264, 4392, 4392, 4584, 4776, 4776, 4968, 4968, 5160, 5352, 5352, 5544, 5544, 5736, 5736, 5992, 5992, 6200, 6200, 6456, 6456, 6712, 6712, 6968, 6968, 7224, 7224, 7224, 7480, 7480, 7736, 7736, 7992, 7992, 8248, 8248, 8504, 8504, 8760, 8760, 8760, 9144, 9144, 9144, 9528, 9528, 9528, 9528, 9912, 9912, 9912, 10296, 10296, 10296, 10680, 10680, 10680, 10680, 11064, 11064, 11064, 11448, 11448, 11448, 11448, 11832, 11832, 11832, 11832, 12576, 12576, 12576, 12576, 12960, 12960}, + {120, 256, 408, 552, 696, 840, 1000, 1128, 1288, 1416, 1544, 1736, 1864, 1992, 2152, 2280, 2408, 2600, 2728, 2856, 2984, 3112, 3240, 3496, 3624, 3752, 3880, 4008, 4136, 4264, 4392, 4584, 4776, 4968, 4968, 5160, 5352, 5544, 5544, 5736, 5992, 5992, 6200, 6200, 6456, 6456, 6712, 6968, 6968, 7224, 7224, 7480, 7480, 7736, 7992, 7992, 8248, 8248, 8504, 8504, 8760, 8760, 9144, 9144, 9144, 9528, 9528, 9912, 9912, 9912, 10296, 10296, 10296, 10680, 10680, 11064, 11064, 11064, 11448, 11448, 11448, 11832, 11832, 11832, 11832, 12576, 12576, 12576, 12960, 12960, 12960, 12960, 13536, 13536, 13536, 14112, 14112, 14112, 14112, 14688, 14688, 14688, 14688, 14688, 14688, 14688, 15264, 15264, 15264, 15840}, + {144, 328, 504, 680, 872, 1032, 1224, 1384, 1544, 1736, 1928, 2088, 2280, 2472, 2664, 2792, 2984, 3112, 3368, 3496, 3752, 3880, 4008, 4264, 4392, 4584, 4776, 4968, 5160, 5352, 5544, 5736, 5736, 5992, 6200, 6200, 6456, 6712, 6968, 6968, 7224, 7480, 7480, 7736, 7992, 7992, 8248, 8504, 8760, 8760, 9144, 9144, 9528, 9528, 9528, 9912, 9912, 10296, 10296, 10680, 10680, 11064, 11064, 11448, 11448, 11448, 11832, 11832, 11832, 12576, 12576, 12576, 12960, 12960, 13536, 13536, 13536, 14112, 14112, 14112, 14688, 14688, 14688, 14688, 14688, 14688, 15264, 15264, 15264, 15840, 15840, 15840, 16416, 16416, 16416, 16992, 16992, 17568, 17568, 17568, 17568, 18336, 18336, 18336, 18336, 19080, 19080, 19080, 19080, 19080}, + {176, 392, 600, 808, 1032, 1224, 1480, 1672, 1864, 2088, 2280, 2472, 2728, 2984, 3112, 3368, 3496, 3752, 4008, 4136, 4392, 4584, 4776, 4968, 5160, 5352, 5736, 5992, 5992, 6200, 6456, 6712, 6968, 6968, 7224, 7480, 7736, 7992, 8248, 8248, 8504, 8760, 9144, 9144, 9528, 9528, 9912, 9912, 10296, 10296, 10680, 10680, 11064, 11448, 11448, 11832, 11832, 11832, 12576, 12576, 12960, 12960, 12960, 13536, 13536, 14112, 14112, 14112, 14688, 14688, 14688, 14688, 15264, 15264, 15264, 15840, 15840, 16416, 16416, 16416, 16992, 16992, 17568, 17568, 17568, 18336, 18336, 18336, 18336, 19080, 19080, 19080, 19080, 19848, 19848, 19848, 20616, 20616, 20616, 20616, 21384, 21384, 21384, 21384, 24264, 24264, 24264, 22920, 22920, 22920}, + {224, 472, 712, 968, 1224, 1480, 1672, 1928, 2216, 2472, 2664, 2984, 3240, 3368, 3624, 3880, 4136, 4392, 4584, 4968, 5160, 5352, 5736, 5992, 6200, 6456, 6712, 6712, 6968, 7224, 7480, 7736, 7992, 8248, 8504, 8760, 9144, 9144, 9528, 9912, 9912, 10296, 10680, 10680, 11064, 11448, 11448, 11832, 11832, 12216, 12576, 12576, 12960, 12960, 13536, 13536, 14112, 14112, 14688, 14688, 14688, 14688, 15264, 15264, 15840, 15840, 16416, 16416, 16992, 16992, 17568, 17568, 17568, 18336, 18336, 18336, 19080, 19080, 19080, 19848, 19848, 19848, 20616, 20616, 20616, 21384, 21384, 21384, 24264, 24264, 24264, 22920, 22920, 22920, 22920, 23688, 23688, 23688, 24496, 24496, 24496, 25456, 25456, 25456, 25456, 25456, 25456, 25456, 27376, 27376}, + {256, 536, 808, 1096, 1384, 1672, 1928, 2216, 2536, 2792, 3112, 3368, 3624, 3880, 4264, 4584, 4776, 4968, 5352, 5544, 5992, 6200, 6456, 6712, 6968, 7224, 7480, 7736, 7992, 8504, 8760, 9144, 9144, 9528, 9912, 9912, 10296, 10680, 11064, 11064, 11448, 11832, 12216, 12216, 12576, 12960, 12960, 13536, 13536, 14112, 14112, 14688, 14688, 15264, 15264, 15264, 15840, 15840, 16416, 16992, 16992, 17568, 17568, 18336, 18336, 18336, 19080, 19080, 19080, 19848, 19848, 19848, 20616, 20616, 21384, 21384, 21384, 24264, 24264, 24264, 22920, 22920, 22920, 23688, 23688, 24496, 24496, 24496, 25456, 25456, 25456, 25456, 25456, 25456, 27376, 27376, 27376, 27376, 28336, 28336, 28336, 28336, 29296, 29296, 29296, 29296, 30576, 30576, 30576, 30576}, + {296, 616, 936, 1256, 1544, 1864, 2216, 2536, 2856, 3112, 3496, 3752, 4136, 4392, 4776, 5160, 5352, 5736, 5992, 6200, 6712, 6968, 7224, 7480, 7992, 8248, 8504, 8760, 9144, 9528, 9912, 10296, 10296, 10680, 11064, 11448, 11832, 11832, 12216, 12576, 12960, 13536, 13536, 14112, 14112, 14688, 14688, 15264, 15264, 15840, 16416, 16416, 16992, 16992, 17568, 17568, 18336, 18336, 18336, 19080, 19080, 19848, 19848, 20616, 20616, 20616, 21384, 21384, 24264, 24264, 24264, 22920, 22920, 23688, 23688, 23688, 24496, 24496, 25456, 25456, 25456, 25456, 25456, 27376, 27376, 27376, 27376, 28336, 28336, 28336, 28336, 29296, 29296, 29296, 30576, 30576, 30576, 30576, 31704, 31704, 31704, 32856, 32856, 32856, 32856, 34008, 34008, 34008, 34008, 35160}, + {328, 680, 1032, 1384, 1736, 2088, 2472, 2792, 3112, 3496, 3880, 4264, 4584, 4968, 5352, 5736, 5992, 6200, 6712, 6968, 7480, 7736, 7992, 8504, 8760, 9144, 9528, 9912, 10296, 10680, 11064, 11448, 11448, 11832, 12216, 12576, 12960, 13536, 13536, 14112, 14688, 14688, 15264, 15264, 15840, 16416, 16416, 16992, 16992, 17568, 18336, 18336, 18336, 19080, 19080, 19848, 19848, 20616, 20616, 21384, 21384, 24264, 24264, 22920, 22920, 22920, 23688, 23688, 24496, 24496, 25456, 25456, 25456, 25456, 25456, 27376, 27376, 27376, 28336, 28336, 28336, 29296, 29296, 29296, 29296, 30576, 30576, 30576, 31704, 31704, 31704, 32856, 32856, 32856, 34008, 34008, 34008, 34008, 35160, 35160, 35160, 36696, 36696, 36696, 36696, 36696, 37888, 37888, 37888, 37888}, + {376, 776, 1192, 1608, 2024, 2408, 2792, 3240, 3624, 4008, 4392, 4776, 5352, 5736, 5992, 6456, 6968, 7224, 7736, 7992, 8504, 8760, 9144, 9528, 9912, 10680, 11064, 11448, 11832, 12216, 12576, 12960, 13536, 13536, 14112, 14688, 14688, 15264, 15840, 16416, 16416, 16992, 17568, 17568, 18336, 18336, 19080, 19080, 19848, 19848, 20616, 21384, 21384, 22152, 22152, 22920, 22920, 23688, 23688, 24496, 24496, 25456, 25456, 25456, 25456, 27376, 27376, 27376, 28336, 28336, 28336, 29296, 29296, 29296, 30576, 30576, 31704, 31704, 31704, 32856, 32856, 32856, 34008, 34008, 34008, 35160, 35160, 35160, 36696, 36696, 36696, 36696, 37888, 37888, 37888, 37888, 39232, 39232, 39232, 39232, 40576, 40576, 40576, 42368, 42368, 42368, 42368, 43816, 43816, 43816}, + {440, 904, 1352, 1800, 2280, 2728, 3240, 3624, 4136, 4584, 4968, 5544, 5992, 6456, 6712, 7224, 7736, 8248, 8760, 9144, 9528, 9912, 10680, 11064, 11448, 11832, 12216, 12576, 12960, 13536, 14112, 14688, 15264, 15264, 15840, 16416, 16992, 17568, 17568, 18336, 19080, 19080, 19848, 19848, 20616, 21384, 21384, 22152, 22152, 22920, 23688, 23688, 24496, 24496, 25456, 25456, 25456, 25456, 27376, 27376, 28336, 28336, 28336, 29296, 29296, 30576, 30576, 30576, 31704, 31704, 32856, 32856, 32856, 34008, 34008, 35160, 35160, 35160, 36696, 36696, 36696, 37888, 37888, 37888, 37888, 39232, 39232, 39232, 40576, 40576, 40576, 42368, 42368, 42368, 42368, 43816, 43816, 43816, 45352, 45352, 45352, 46888, 46888, 46888, 46888, 48936, 48936, 48936, 48936, 51024}, + {488, 1000, 1544, 2024, 2536, 3112, 3624, 4136, 4584, 5160, 5736, 6200, 6712, 7224, 7736, 8248, 8760, 9144, 9912, 10296, 10680, 11448, 11832, 12216, 12960, 13536, 14112, 14688, 14688, 15264, 15840, 16416, 16992, 17568, 18336, 18336, 19080, 19848, 19848, 20616, 21384, 21384, 22152, 22920, 22920, 23688, 24496, 24496, 25456, 25456, 26416, 26416, 27376, 27376, 28336, 29296, 29296, 29296, 30576, 30576, 31704, 31704, 32856, 32856, 34008, 34008, 34008, 35160, 35160, 36696, 36696, 36696, 37888, 37888, 37888, 39232, 39232, 39232, 40576, 40576, 40576, 42368, 42368, 42368, 43816, 43816, 43816, 45352, 45352, 45352, 46888, 46888, 46888, 48936, 48936, 48936, 51024, 51024, 51024, 51024, 52752, 52752, 52752, 52752, 55056, 55056, 55056, 55056, 57336, 57336}, + {552, 1128, 1736, 2280, 2856, 3496, 4008, 4584, 5160, 5736, 6200, 6968, 7480, 7992, 8504, 9144, 9912, 10296, 11064, 11448, 12216, 12576, 12960, 13536, 14112, 14688, 15264, 15840, 16416, 16992, 17568, 18336, 19080, 19848, 19848, 20616, 21384, 22152, 22152, 22920, 23688, 24496, 24496, 25456, 25456, 26416, 27376, 27376, 28336, 28336, 29296, 29296, 30576, 30576, 31704, 31704, 32856, 32856, 34008, 34008, 35160, 35160, 36696, 36696, 36696, 37888, 37888, 39232, 39232, 39232, 40576, 40576, 40576, 42368, 42368, 43816, 43816, 43816, 45352, 45352, 45352, 46888, 46888, 48936, 48936, 48936, 51024, 51024, 51024, 51024, 52752, 52752, 52752, 55056, 55056, 55056, 57336, 57336, 57336, 57336, 59256, 59256, 59256, 59256, 61664, 61664, 61664, 61664, 63776, 63776}, + {600, 1224, 1800, 2472, 3112, 3624, 4264, 4968, 5544, 6200, 6712, 7224, 7992, 8504, 9144, 9912, 10296, 11064, 11832, 12216, 12960, 13536, 14112, 14688, 15264, 15840, 16416, 16992, 17568, 18336, 19080, 19848, 20616, 20616, 21384, 22152, 22920, 23688, 23688, 24496, 25456, 25456, 26416, 27376, 27376, 28336, 29296, 29296, 30576, 30576, 31704, 31704, 32856, 32856, 34008, 34008, 35160, 35160, 36696, 36696, 36696, 37888, 37888, 39232, 39232, 40576, 40576, 40576, 42368, 42368, 43816, 43816, 43816, 45352, 45352, 46888, 46888, 46888, 48936, 48936, 48936, 51024, 51024, 51024, 52752, 52752, 52752, 55056, 55056, 55056, 57336, 57336, 57336, 59256, 59256, 59256, 59256, 61664, 61664, 61664, 61664, 63776, 63776, 63776, 63776, 66592, 66592, 66592, 68808, 68808}, + {632, 1288, 1928, 2600, 3240, 3880, 4584, 5160, 5992, 6456, 7224, 7736, 8504, 9144, 9912, 10296, 11064, 11832, 12216, 12960, 13536, 14112, 14688, 15840, 16416, 16992, 17568, 18336, 19080, 19848, 19848, 20616, 21384, 22152, 22920, 23688, 24496, 24496, 25456, 26416, 26416, 27376, 28336, 28336, 29296, 30576, 30576, 31704, 31704, 32856, 32856, 34008, 34008, 35160, 35160, 36696, 36696, 37888, 37888, 39232, 39232, 39232, 40576, 40576, 42368, 42368, 43816, 43816, 43816, 45352, 45352, 46888, 46888, 48936, 48936, 48936, 51024, 51024, 51024, 52752, 52752, 52752, 55056, 55056, 55056, 57336, 57336, 57336, 59256, 59256, 59256, 61664, 61664, 61664, 61664, 63776, 63776, 63776, 63776, 66592, 66592, 66592, 68808, 68808, 68808, 68808, 71112, 71112, 71112, 71112}, + {696, 1416, 2152, 2856, 3624, 4392, 5160, 5736, 6456, 7224, 7992, 8760, 9528, 10296, 10680, 11448, 12216, 12960, 13536, 14688, 15264, 15840, 16416, 17568, 18336, 19080, 19848, 20616, 20616, 21384, 22152, 22920, 23688, 24496, 25456, 26416, 26416, 27376, 28336, 29296, 29296, 30576, 30576, 31704, 32856, 32856, 34008, 35160, 35160, 36696, 36696, 37888, 37888, 39232, 39232, 40576, 40576, 40576, 42368, 42368, 43816, 43816, 45352, 45352, 46888, 46888, 48936, 48936, 48936, 51024, 51024, 52752, 52752, 52752, 55056, 55056, 55056, 57336, 57336, 59256, 59256, 59256, 61664, 61664, 61664, 61664, 63776, 63776, 63776, 66592, 66592, 66592, 68808, 68808, 68808, 71112, 71112, 71112, 71112, 73712, 73712, 73712, 73712, 76208, 76208, 76208, 78704, 78704, 78704, 78704}, + {776, 1544, 2344, 3112, 4008, 4776, 5544, 6200, 7224, 7992, 8760, 9528, 10296, 11064, 11832, 12576, 13536, 14112, 15264, 15840, 16416, 17568, 18336, 19080, 19848, 20616, 21384, 22152, 22920, 23688, 24496, 25456, 26416, 27376, 27376, 28336, 29296, 30576, 30576, 31704, 32856, 32856, 34008, 35160, 35160, 36696, 37888, 37888, 39232, 39232, 40576, 40576, 42368, 42368, 43816, 43816, 45352, 45352, 46888, 46888, 48936, 48936, 48936, 51024, 51024, 52752, 52752, 55056, 55056, 55056, 57336, 57336, 59256, 59256, 59256, 61664, 61664, 61664, 63776, 63776, 63776, 66592, 66592, 66592, 68808, 68808, 68808, 71112, 71112, 71112, 73712, 73712, 73712, 76208, 76208, 76208, 76208, 78704, 78704, 78704, 81176, 81176, 81176, 81176, 84760, 84760, 84760, 84760, 87936, 87936}, + {840, 1736, 2600, 3496, 4264, 5160, 5992, 6968, 7736, 8504, 9528, 10296, 11064, 12216, 12960, 13536, 14688, 15264, 16416, 16992, 18336, 19080, 19848, 20616, 21384, 22152, 22920, 24496, 25456, 25456, 26416, 27376, 28336, 29296, 30576, 30576, 31704, 32856, 34008, 34008, 35160, 36696, 36696, 37888, 39232, 39232, 40576, 40576, 42368, 43816, 43816, 45352, 45352, 46888, 46888, 48936, 48936, 51024, 51024, 51024, 52752, 52752, 55056, 55056, 57336, 57336, 59256, 59256, 59256, 61664, 61664, 61664, 63776, 63776, 66592, 66592, 66592, 68808, 68808, 68808, 71112, 71112, 71112, 73712, 73712, 73712, 76208, 76208, 76208, 78704, 78704, 78704, 81176, 81176, 81176, 81176, 84760, 84760, 84760, 87936, 87936, 87936, 87936, 90816, 90816, 90816, 93800, 93800, 93800, 93800}, + {904, 1864, 2792, 3752, 4584, 5544, 6456, 7480, 8248, 9144, 10296, 11064, 12216, 12960, 14112, 14688, 15840, 16992, 17568, 18336, 19848, 20616, 21384, 22152, 22920, 24496, 25456, 26416, 27376, 28336, 29296, 29296, 30576, 31704, 32856, 34008, 34008, 35160, 36696, 36696, 37888, 39232, 40576, 40576, 42368, 42368, 43816, 45352, 45352, 46888, 46888, 48936, 48936, 51024, 51024, 52752, 52752, 55056, 55056, 57336, 57336, 59256, 59256, 59256, 61664, 61664, 63776, 63776, 63776, 66592, 66592, 68808, 68808, 68808, 71112, 71112, 71112, 73712, 73712, 73712, 76208, 76208, 78704, 78704, 78704, 81176, 81176, 81176, 84760, 84760, 84760, 84760, 87936, 87936, 87936, 90816, 90816, 90816, 93800, 93800, 93800, 93800, 97896, 97896, 97896, 97896, 97896, 101840, 101840, 101840}, + {1000, 1992, 2984, 4008, 4968, 5992, 6968, 7992, 9144, 9912, 11064, 12216, 12960, 14112, 15264, 15840, 16992, 18336, 19080, 19848, 21384, 22152, 22920, 24496, 25456, 26416, 27376, 28336, 29296, 30576, 31704, 31704, 32856, 34008, 35160, 36696, 36696, 37888, 39232, 40576, 40576, 42368, 43816, 43816, 45352, 46888, 46888, 48936, 48936, 51024, 51024, 52752, 52752, 55056, 55056, 57336, 57336, 59256, 59256, 61664, 61664, 63776, 63776, 63776, 66592, 66592, 68808, 68808, 71112, 71112, 71112, 73712, 73712, 73712, 76208, 76208, 78704, 78704, 78704, 81176, 81176, 81176, 84760, 84760, 84760, 87936, 87936, 87936, 90816, 90816, 90816, 93800, 93800, 93800, 93800, 97896, 97896, 97896, 97896, 101840, 101840, 101840, 101840, 105528, 105528, 105528, 105528, 110136, 110136, 110136}, + {1064, 2152, 3240, 4264, 5352, 6456, 7480, 8504, 9528, 10680, 11832, 12960, 14112, 15264, 16416, 16992, 18336, 19080, 20616, 21384, 22920, 23688, 24496, 25456, 27376, 28336, 29296, 30576, 31704, 32856, 34008, 34008, 35160, 36696, 37888, 39232, 40576, 40576, 42368, 43816, 43816, 45352, 46888, 46888, 48936, 48936, 51024, 51024, 52752, 55056, 55056, 57336, 57336, 59256, 59256, 61664, 61664, 63776, 63776, 66592, 66592, 68808, 68808, 68808, 71112, 71112, 73712, 73712, 73712, 76208, 76208, 78704, 78704, 81176, 81176, 81176, 84760, 84760, 84760, 87936, 87936, 87936, 90816, 90816, 90816, 93800, 93800, 93800, 97896, 97896, 97896, 97896, 101840, 101840, 101840, 101840, 105528, 105528, 105528, 110136, 110136, 110136, 110136, 115040, 115040, 115040, 115040, 119816, 119816, 119816}, + {1128, 2280, 3496, 4584, 5736, 6968, 7992, 9144, 10296, 11448, 12576, 13536, 14688, 15840, 16992, 18336, 19848, 20616, 22152, 22920, 24496, 25456, 26416, 27376, 28336, 29296, 30576, 31704, 32856, 34008, 35160, 36696, 37888, 39232, 40576, 40576, 42368, 43816, 45352, 45352, 46888, 48936, 48936, 51024, 51024, 52752, 55056, 55056, 57336, 57336, 59256, 59256, 61664, 61664, 63776, 63776, 66592, 66592, 68808, 68808, 71112, 71112, 73712, 73712, 76208, 76208, 76208, 78704, 78704, 81176, 81176, 81176, 84760, 84760, 87936, 87936, 87936, 90816, 90816, 90816, 93800, 93800, 93800, 97896, 97896, 97896, 101840,101840,101840,101840,105528, 105528, 105528, 110136, 110136, 110136, 110136, 115040, 115040, 115040, 115040, 119816, 119816, 119816, 119816, 124464, 124464, 124464, 124464, 128496}, + {1192, 2408, 3624, 4968, 5992, 7224, 8504, 9912, 11064, 12216, 13536, 14688, 15840, 16992, 18336, 19848, 20616, 22152, 22920, 24496, 25456, 26416, 28336, 29296, 30576, 31704, 32856, 34008, 35160, 36696, 37888, 39232, 40576, 42368, 42368, 43816, 45352, 46888, 46888, 48936, 51024, 51024, 52752, 52752, 55056, 57336, 57336, 59256, 59256, 61664, 61664, 63776, 63776, 66592, 66592, 68808, 71112, 71112, 73712, 73712, 73712, 76208, 76208, 78704, 78704, 81176, 81176, 84760, 84760, 84760, 87936, 87936, 90816, 90816, 90816, 93800, 93800, 93800, 97896, 97896, 97896, 101840, 101840, 101840, 105528, 105528, 105528, 105528, 110136, 110136, 110136, 115040, 115040, 115040, 115040, 119816, 119816, 119816, 124464, 124464, 124464, 124464, 128496, 128496, 128496, 128496, 133208, 133208, 133208, 133208}, + {1256, 2536, 3752, 5160, 6200, 7480, 8760, 10296, 11448, 12576, 14112, 15264, 16416, 17568, 19080, 20616, 21384, 22920, 24496, 25456, 26416, 28336, 29296, 30576, 31704, 32856, 34008, 35160, 36696, 37888, 39232, 40576, 42368, 43816, 43816, 45352, 46888, 48936, 48936, 51024, 52752, 52752, 55056, 55056, 57336, 59256, 59256, 61664, 61664, 63776, 63776, 66592, 66592, 68808, 71112, 71112, 73712, 73712, 76208, 76208, 78704, 78704, 81176, 81176, 81176, 84760, 84760, 87936, 87936, 87936, 90816, 90816, 93800, 93800, 93800, 97896, 97896, 97896, 101840, 101840, 101840, 105528, 105528, 105528, 110136, 110136, 110136, 110136, 115040,115040, 115040, 119816, 119816, 119816, 124464, 124464, 124464, 124464, 128496, 128496, 128496, 128496, 133208, 133208, 133208, 133208, 137792, 137792, 137792, 142248}, + {1480, 2984, 4392, 5992, 7480, 8760, 10296, 11832, 13536, 14688, 16416, 17568, 19080, 20616, 22152, 23688, 25456, 26416, 28336, 29296, 30576, 32856, 34008, 35160, 36696, 37888, 40576, 40576, 42368, 43816, 45352, 46888, 48936, 51024, 52752, 52752, 55056, 55056, 57336, 59256, 59256, 61664, 63776, 63776, 66592, 68808, 68808, 71112, 73712, 75376, 75376, 75376, 75376, 75376, 75376, 81176, 84760, 84760, 87936, 87936, 90816, 90816, 93800, 93800, 97896, 97896, 97896, 101840, 101840, 105528, 105528, 105528, 110136, 110136, 110136, 110136, 115040, 115040, 115040, 119816, 119816, 119816, 124464, 124464, 124464, 128496, 128496, 128496, 133208, 133208, 133208, 137792, 137792, 137792, 142248, 142248, 142248, 146856, 146856,149776, 149776, 149776, 149776, 149776, 149776, 149776, 149776, 149776, 149776, 149776} + } +}; +RgSchUlIMcsTbl rgUlIMcsTbl = { + {2, 0}, {2, 1}, {2, 2}, {2, 3}, {2, 4}, {2, 5}, + {2, 6}, {2, 7}, {2, 8}, {2, 9}, {2, 10}, + {4, 10}, {4, 11}, {4, 12}, {4, 13}, {4, 14}, + {4, 15}, {4, 16}, {4, 17}, {4, 18}, {4, 19}, + {6, 19}, {6, 20}, {6, 21}, {6, 22}, {6, 23}, + {6, 24}, {6, 25}, {6, 26} +}; +RgSchUeCatTbl rgUeCatTbl = { + /*Column1:Maximum number of bits of an UL-SCH + transport block transmitted within a TTI + - maxUlBits + Column2:Maximum number of bits of a DLSCH + transport block received within a TTI + - maxDlBits + Column3:Total number of soft channel bits + - maxSftChBits + Column4:Support for 64QAM in UL + - ul64qamSup + Column5:Maximum number of DL-SCH transport + block bits received within a TTI + - maxDlTbBits + Column6:Maximum number of supported layers for + spatial multiplexing in DL + - maxTxLyrs*/ + {5160, {10296,0}, 250368, FALSE, 10296, 1}, + {25456, {51024,0}, 1237248, FALSE, 51024, 2}, + {51024, {75376,0}, 1237248, FALSE, 102048, 2}, + {51024, {75376,0}, 1827072, FALSE, 150752, 2}, + {75376, {149776,0}, 3667200, TRUE, 299552, 4}, + {51024, {75376,149776}, 3654144, FALSE, 301504, 4}, + {51024, {75376,149776}, 3654144, FALSE, 301504, 4}, + {149776,{299856,0}, 35982720,TRUE, 2998560, 8} +}; + +/* [ccpu00138532]-ADD-The below table stores the min HARQ RTT time + in Downlink for TDD and FDD. Indices 0 to 6 map to tdd UL DL config 0-6. + Index 7 map to FDD */ +U8 rgSchCmnHarqRtt[8] = {4,7,10,9,12,15,6,8}; +/* Number of CFI Switchover Index is equals to 7 TDD Indexes + 1 FDD index */ +U8 rgSchCfiSwitchOvrWinLen[] = {7, 4, 2, 3, 2, 1, 6, 8}; + +/* EffTbl is calculated for single layer and two layers. + * CqiToTbs is calculated for single layer and two layers */ +RgSchCmnTbSzEff rgSchCmnNorCfi1Eff[RGSCH_MAX_NUM_LYR_PERCW], rgSchCmnNorCfi2Eff[RGSCH_MAX_NUM_LYR_PERCW]; +RgSchCmnTbSzEff rgSchCmnNorCfi3Eff[RGSCH_MAX_NUM_LYR_PERCW], rgSchCmnNorCfi4Eff[RGSCH_MAX_NUM_LYR_PERCW]; +/* New variable to store UL effiency values for normal and extended CP*/ +RgSchCmnTbSzEff rgSchCmnNorUlEff[1],rgSchCmnExtUlEff[1]; +RgSchCmnCqiToTbs rgSchCmnNorCfi1CqiToTbs[RGSCH_MAX_NUM_LYR_PERCW], rgSchCmnNorCfi2CqiToTbs[RGSCH_MAX_NUM_LYR_PERCW]; +RgSchCmnCqiToTbs rgSchCmnNorCfi3CqiToTbs[RGSCH_MAX_NUM_LYR_PERCW], rgSchCmnNorCfi4CqiToTbs[RGSCH_MAX_NUM_LYR_PERCW]; +RgSchCmnCqiToTbs *rgSchCmnCqiToTbs[RGSCH_MAX_NUM_LYR_PERCW][RG_SCH_CMN_MAX_CP][RG_SCH_CMN_MAX_CFI]; +RgSchCmnTbSzEff rgSchCmnExtCfi1Eff[RGSCH_MAX_NUM_LYR_PERCW], rgSchCmnExtCfi2Eff[RGSCH_MAX_NUM_LYR_PERCW]; +RgSchCmnTbSzEff rgSchCmnExtCfi3Eff[RGSCH_MAX_NUM_LYR_PERCW], rgSchCmnExtCfi4Eff[RGSCH_MAX_NUM_LYR_PERCW]; +RgSchCmnCqiToTbs rgSchCmnExtCfi1CqiToTbs[RGSCH_MAX_NUM_LYR_PERCW], rgSchCmnExtCfi2CqiToTbs[RGSCH_MAX_NUM_LYR_PERCW]; +RgSchCmnCqiToTbs rgSchCmnExtCfi3CqiToTbs[RGSCH_MAX_NUM_LYR_PERCW], rgSchCmnExtCfi4CqiToTbs[RGSCH_MAX_NUM_LYR_PERCW]; +/* Include CRS REs while calculating Efficiency */ +RgSchCmnTbSzEff *rgSchCmnEffTbl[RGSCH_MAX_NUM_LYR_PERCW][RG_SCH_CMN_MAX_CP][RG_SCH_CMN_MAX_ANT_CONF][RG_SCH_CMN_MAX_CFI]; +RgSchCmnTbSzEff *rgSchCmnUlEffTbl[RG_SCH_CMN_MAX_CP]; +#ifdef LTE_TDD +RgSchRaPrmblToRaFrmTbl rgRaPrmblToRaFrmTbl = {1, 2, 2, 3, 1}; +#else +/* Added matrix 'rgRaPrmblToRaFrmTbl'for computation of RA sub-frames from RA preamble */ +RgSchRaPrmblToRaFrmTbl rgRaPrmblToRaFrmTbl = {1, 2, 2, 3}; +#endif + +EXTERN RgUlSchdInits rgSchUlSchdInits; +EXTERN RgDlSchdInits rgSchDlSchdInits; +EXTERN RgDlfsSchdInits rgSchDlfsSchdInits; +#ifdef EMTC_ENABLE +EXTERN RgEmtcUlSchdInits rgSchEmtcUlSchdInits; +EXTERN RgEmtcDlSchdInits rgSchEmtcDlSchdInits; +#endif + +/* RACHO : start */ +PRIVATE S16 rgSCHCmnUeIdleExdThrsld ARGS(( +RgSchCellCb *cell, +RgSchUeCb *ue +)); +PUBLIC RgSchUeCb* rgSCHCmnGetHoUe ARGS(( +RgSchCellCb *cell, +U16 rapId +)); +PRIVATE Void rgSCHCmnDelDedPreamble ARGS(( +RgSchCellCb *cell, +U8 preambleId +)); +PUBLIC RgSchUeCb* rgSCHCmnGetPoUe ARGS(( +RgSchCellCb *cell, +U16 rapId, +CmLteTimingInfo timingInfo +)); +PRIVATE Void rgSCHCmnDelRachInfo ARGS(( +RgSchCellCb *cell, +RgSchUeCb *ue +)); +PRIVATE S16 rgSCHCmnUlRbAllocForPoHoUe ARGS(( +RgSchCellCb *cell, +RgSchUlSf *sf, +RgSchUeCb *ue, +U8 maxRb +)); +PRIVATE Void rgSCHCmnHdlHoPo ARGS(( +RgSchCellCb *cell, +CmLListCp *raRspLst, +RgSchRaReqInfo *raReq +)); +PRIVATE Void rgSCHCmnAllocPoHoGrnt ARGS(( +RgSchCellCb *cell, +CmLListCp *raRspLst, +RgSchUeCb *ue, +RgSchRaReqInfo *raReq +)); +PRIVATE Void rgSCHCmnFillPdcchOdr2Sf ARGS(( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgSchPdcch *pdcc, +U8 rapId, +U8 prachMskIdx +)); +PRIVATE Void rgSCHCmnDlAdd2PdcchOdrQ ARGS(( +RgSchCellCb *cell, +RgSchUeCb *ue +)); +PRIVATE Void rgSCHCmnDlRmvFrmPdcchOdrQ ARGS(( +RgSchCellCb *cell, +RgSchUeCb *ue +)); +PRIVATE Void rgSCHCmnUpdNxtPrchMskIdx ARGS(( +RgSchCellCb *cell +)); +PRIVATE Void rgSCHCmnUpdRachParam ARGS(( +RgSchCellCb *cell +)); +PRIVATE S16 rgSCHCmnAllocPOParam ARGS(( +RgSchCellCb *cell, +RgSchDlSf *dlSf, +RgSchUeCb *ue, +RgSchPdcch **pdcch, +U8 *rapId, +U8 *prachMskIdx +)); +PRIVATE Void rgSCHCmnGenPdcchOrder ARGS(( +RgSchCellCb *cell, +RgSchDlSf *dlSf +)); +PRIVATE Void rgSCHCmnCfgRachDedPrm ARGS(( +RgSchCellCb *cell +)); +/* RACHO : end */ + +PRIVATE Void rgSCHCmnHdlUlInactUes ARGS(( +RgSchCellCb *cell +)); +PRIVATE Void rgSCHCmnHdlDlInactUes ARGS(( +RgSchCellCb *cell +)); +PRIVATE Void rgSCHCmnUlInit ARGS((Void +)); +PRIVATE Void rgSCHCmnDlInit ARGS((Void +)); +PRIVATE Void rgSCHCmnInitDlRbAllocInfo ARGS(( +RgSchCmnDlRbAllocInfo *allocInfo +)); +PRIVATE Void rgSCHCmnUpdUlCompEffBsr ARGS(( +RgSchUeCb *ue +)); +#if RG_UNUSED +PRIVATE Void rgSCHCmnUlSetAllUnSched ARGS(( +RgSchCmnUlRbAllocInfo *allocInfo +)); +PRIVATE Void rgSCHCmnUlUpdSf ARGS(( + RgSchCellCb *cell, + RgSchCmnUlRbAllocInfo *allocInfo, + RgSchUlSf *sf + )); +PRIVATE Void rgSCHCmnUlHndlAllocRetx ARGS(( + RgSchCellCb *cell, + RgSchCmnUlRbAllocInfo *allocInfo, + RgSchUlSf *sf, + RgSchUlAlloc *alloc + )); +#endif +PRIVATE Void rgSCHCmnGrpPwrCntrlPucch ARGS(( +RgSchCellCb *cell, +RgSchDlSf *dlSf +)); +PRIVATE Void rgSCHCmnGrpPwrCntrlPusch ARGS(( +RgSchCellCb *cell, +RgSchUlSf *ulSf +)); +PRIVATE Void rgSCHCmnDelUeFrmRefreshQ ARGS(( +RgSchCellCb *cell, +RgSchUeCb *ue +)); +PRIVATE S16 rgSCHCmnTmrExpiry ARGS(( +PTR cb, /* Pointer to timer control block */ +S16 tmrEvnt /* Timer Event */ +)); +PRIVATE S16 rgSCHCmnTmrProc ARGS(( +RgSchCellCb *cell +)); +PRIVATE Void rgSCHCmnAddUeToRefreshQ ARGS(( +RgSchCellCb *cell, +RgSchUeCb *ue, +U32 wait +)); +PRIVATE Void rgSCHCmnDlCcchRetx ARGS(( +RgSchCellCb *cell, +RgSchCmnDlRbAllocInfo *allocInfo +)); +PRIVATE Void rgSCHCmnUpdUeMimoInfo ARGS(( +RgrUeCfg *ueCfg, +RgSchCmnDlUe *ueDl, +RgSchCellCb *cell, +RgSchCmnCell *cellSchd +)); +PRIVATE Void rgSCHCmnUpdUeUlCqiInfo ARGS(( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgSchCmnUlUe *ueUl, +RgSchCmnUe *ueSchCmn, +RgSchCmnCell *cellSchd, +Bool isEcp +)); +#ifdef RGR_V1 +PRIVATE Void rgSCHCmnDlCcchSduRetx ARGS(( +RgSchCellCb *cell, +RgSchCmnDlRbAllocInfo *allocInfo +)); +PRIVATE Void rgSCHCmnDlCcchSduTx ARGS(( +RgSchCellCb *cell, +RgSchCmnDlRbAllocInfo *allocInfo +)); +PRIVATE S16 rgSCHCmnCcchSduAlloc ARGS(( +RgSchCellCb *cell, +RgSchUeCb *ueCb, +RgSchCmnDlRbAllocInfo *allocInfo +)); +PRIVATE S16 rgSCHCmnCcchSduDedAlloc ARGS(( +RgSchCellCb *cell, +RgSchUeCb *ueCb +)); +PRIVATE S16 rgSCHCmnNonDlfsCcchSduRbAlloc ARGS(( +RgSchCellCb *cell, +RgSchUeCb *ueCb, +RgSchDlSf *dlSf +)); +#endif +PRIVATE Void rgSCHCmnInitVars ARGS(( + RgSchCellCb *cell + )); + +/*ccpu00117180 - DEL - Moved rgSCHCmnUpdVars to .x as its access is now PUBLIC */ +PRIVATE Void rgSCHCmnUlRbAllocForLst ARGS(( + RgSchCellCb *cell, + RgSchUlSf *sf, + U32 count, + CmLListCp *reqLst, + CmLListCp *schdLst, + CmLListCp *nonSchdLst, + Bool isNewTx + )); +PRIVATE S16 rgSCHCmnUlRbAllocForUe ARGS(( + RgSchCellCb *cell, + RgSchUlSf *sf, + RgSchUeCb *ue, + U8 maxRb, + RgSchUlHole *hole + )); +PRIVATE Void rgSCHCmnMsg3GrntReq ARGS(( + RgSchCellCb *cell, + CmLteRnti rnti, + Bool preamGrpA, + RgSchUlHqProcCb *hqProc, + RgSchUlAlloc **ulAllocRef, + U8 *hqProcIdRef + )); +PRIVATE Void rgSCHCmnUlNonadapRetx ARGS(( + RgSchCmnUlCell *cellUl, + RgSchUlAlloc *alloc, + U8 idx + )); + +PRIVATE Void rgSCHCmnDlCcchRarAlloc ARGS(( +RgSchCellCb *cell +)); +PRIVATE Void rgSCHCmnDlCcchTx ARGS(( +RgSchCellCb *cell, +RgSchCmnDlRbAllocInfo *allocInfo +)); +PRIVATE Void rgSCHCmnDlBcchPcch ARGS(( +RgSchCellCb *cell, +RgSchCmnDlRbAllocInfo *allocInfo, +RgInfSfAlloc *subfrmAlloc +)); +PUBLIC Bool rgSCHCmnChkInWin ARGS(( +CmLteTimingInfo frm, +CmLteTimingInfo start, +CmLteTimingInfo end +)); +PUBLIC Bool rgSCHCmnChkPastWin ARGS(( +CmLteTimingInfo frm, +CmLteTimingInfo end +)); +PRIVATE Void rgSCHCmnClcAlloc ARGS(( +RgSchCellCb *cell, +RgSchDlSf *sf, +RgSchClcDlLcCb *lch, +U16 rnti, +RgSchCmnDlRbAllocInfo *allocInfo +)); +#ifndef LTEMAC_SPS +PRIVATE Void rgSCHCmnClcRbAlloc ARGS(( +RgSchCellCb *cell, +U32 bo, +U8 cqi, +U8 *rb, +U32 *tbs, +U8 *mcs, +RgSchDlSf *sf +)); +#endif + +PRIVATE S16 rgSCHCmnMsg4Alloc ARGS(( +RgSchCellCb *cell, +RgSchRaCb *raCb, +RgSchCmnDlRbAllocInfo *allocInfo +)); +PRIVATE S16 rgSCHCmnMsg4DedAlloc ARGS(( +RgSchCellCb *cell, +RgSchRaCb *raCb +)); +PRIVATE Void rgSCHCmnDlRaRsp ARGS(( +RgSchCellCb *cell, +RgSchCmnDlRbAllocInfo *allocInfo +)); +PRIVATE S16 rgSCHCmnRaRspAlloc ARGS(( +RgSchCellCb *cell, +RgSchDlSf *subFrm, +U16 rntiIdx, +U16 rarnti, +U8 noRaRnti, +RgSchCmnDlRbAllocInfo *allocInfo +)); +PRIVATE Void rgSCHCmnUlUeDelAllocs ARGS(( +RgSchCellCb *cell, +RgSchUeCb *ue +)); +PRIVATE Void rgSCHCmnDlSetUeAllocLmt ARGS(( +RgSchCellCb *cell, +RgSchCmnDlUe *ueDl, +Bool isEmtcUe +)); +PRIVATE S16 rgSCHCmnDlRgrCellCfg ARGS(( +RgSchCellCb *cell, +RgrCellCfg *cfg, +RgSchErrInfo *err +)); +PRIVATE Void rgSCHCmnUlAdapRetx ARGS(( +RgSchUlAlloc *alloc, +RgSchUlHqProcCb *proc +)); +PRIVATE Void rgSCHCmnUlUpdAllocRetx ARGS(( +RgSchCellCb *cell, +RgSchUlAlloc *alloc +)); +PRIVATE Void rgSCHCmnUlSfReTxAllocs ARGS(( +RgSchCellCb *cell, +RgSchUlSf *sf +)); +/* Fix: syed Adaptive Msg3 Retx crash. */ +PRIVATE Void rgSCHCmnUlSfRlsRetxProcs ARGS(( +RgSchCellCb *cell, +RgSchUlSf *sf +)); + +#ifdef TFU_UPGRADE +PRIVATE Void rgSCHCmnDlHdlTxModeRecfg ARGS +(( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgrUeRecfg *ueRecfg, +U8 numTxPorts +)); +#else +PRIVATE Void rgSCHCmnDlHdlTxModeRecfg ARGS +(( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgrUeRecfg *ueRecfg +)); +#endif + + +/* + * DL RB allocation specific functions + */ + +PRIVATE Void rgSCHCmnDlRbAlloc ARGS(( +RgSchCellCb *cell, +RgSchCmnDlRbAllocInfo *allocInfo +)); +PRIVATE Void rgSCHCmnNonDlfsRbAlloc ARGS(( +RgSchCellCb *cell, +RgSchCmnDlRbAllocInfo *allocInfo +)); +PRIVATE S16 rgSCHCmnNonDlfsCmnRbAlloc ARGS(( +RgSchCellCb *cell, +RgSchDlRbAlloc *cmnAllocInfo)); + +#ifndef LTE_TDD +PRIVATE Void rgSCHCmnNonDlfsPbchRbAllocAdj ARGS(( +RgSchCellCb *cell, +RgSchDlRbAlloc *cmnAllocInfo, +U8 pbchSsRsSym, +Bool isBcchPcch +)); +/* Added function to adjust TBSize*/ +PRIVATE Void rgSCHCmnNonDlfsPbchTbSizeAdj ARGS(( +RgSchDlRbAlloc *allocInfo, +U8 numOvrlapgPbchRb, +U8 pbchSsRsSym, +U8 idx, +U32 bytesReq +)); + +/* Added function to find num of overlapping PBCH rb*/ +PRIVATE Void rgSCHCmnFindNumPbchOvrlapRbs ARGS(( +RgSchCellCb *cell, +RgSchDlSf *dlSf, +RgSchDlRbAlloc *allocInfo, +U8 *numOvrlapgPbchRb +)); + +PRIVATE U8 rgSCHCmnFindNumAddtlRbsAvl ARGS(( +RgSchCellCb *cell, +RgSchDlSf *dlSf, +RgSchDlRbAlloc *allocInfo +)); +#ifdef DEBUGP +PRIVATE Void rgSCHCmnFindCodeRate ARGS(( +RgSchCellCb *cell, +RgSchDlSf *dlSf, +RgSchDlRbAlloc *allocInfo, +U8 idx +)); +#endif +#endif +PRIVATE Void rgSCHCmnNonDlfsMsg4Alloc ARGS(( +RgSchCellCb *cell, +RgSchCmnMsg4RbAlloc *msg4AllocInfo, +U8 isRetx +)); +PRIVATE S16 rgSCHCmnNonDlfsMsg4RbAlloc ARGS(( +RgSchCellCb *cell, +RgSchRaCb *raCb, +RgSchDlSf *dlSf +)); + +PRIVATE S16 rgSCHCmnNonDlfsUeRbAlloc ARGS(( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgSchDlSf *dlSf, +U8 *isDlBwAvail +)); +#ifndef LTEMAC_SPS +PRIVATE U32 rgSCHCmnCalcRiv ARGS(( U8 bw, + U8 rbStart, + U8 numRb)); +#endif + +#ifdef LTE_TDD +PRIVATE Void rgSCHCmnUpdHqAndDai ARGS(( +RgSchDlHqProcCb *hqP, +RgSchDlSf *subFrm, +RgSchDlHqTbCb *tbCb, +U8 tbAllocIdx +)); +PRIVATE S16 rgSCHCmnUlCalcAvailBw ARGS(( +RgSchCellCb *cell, +RgrCellCfg *cellCfg, +U8 cfi, +U8 *rbStartRef, +U8 *bwAvailRef +)); +PRIVATE S16 rgSCHCmnDlKdashUlAscInit ARGS(( +RgSchCellCb *cell +)); +PRIVATE S16 rgSCHCmnDlANFdbkInit ARGS(( +RgSchCellCb *cell +)); +PRIVATE S16 rgSCHCmnDlNpValInit ARGS(( +RgSchCellCb *cell +)); +PRIVATE S16 rgSCHCmnDlCreateRachPrmLst ARGS(( +RgSchCellCb *cell +)); +PRIVATE S16 rgSCHCmnDlCpyRachInfo ARGS(( +RgSchCellCb *cell, +RgSchTddRachRspLst rachRspLst[][RGSCH_NUM_SUB_FRAMES], +U8 raArrSz +)); +PRIVATE S16 rgSCHCmnDlRachInfoInit ARGS(( +RgSchCellCb *cell +)); +PRIVATE S16 rgSCHCmnDlPhichOffsetInit ARGS(( +RgSchCellCb *cell +)); +#endif +#ifdef TFU_UPGRADE +PRIVATE Void rgSCHCmnFindUlCqiUlTxAnt ARGS +(( + RgSchCellCb *cell, + RgSchUeCb *ue, + U8 wideCqi + )); + PRIVATE RgSchCmnRank rgSCHCmnComputeRank ARGS +(( + RgrTxMode txMode, + U32 *pmiBitMap, + U8 numTxPorts + )); + + PRIVATE RgSchCmnRank rgSCHCmnComp2TxMode3 ARGS +(( + U32 *pmiBitMap + )); + + PRIVATE RgSchCmnRank rgSCHCmnComp4TxMode3 ARGS +(( + U32 *pmiBitMap + )); + + PRIVATE RgSchCmnRank rgSCHCmnComp2TxMode4 ARGS +(( + U32 *pmiBitMap + )); + + PRIVATE RgSchCmnRank rgSCHCmnComp4TxMode4 ARGS +(( + U32 *pmiBitMap + )); + + PRIVATE U8 rgSCHCmnCalcWcqiFrmSnr ARGS +(( + RgSchCellCb *cell, + TfuSrsRpt *srsRpt + )); +#endif + +/* comcodsepa : start */ + +/** + * @brief This function computes efficiency and stores in a table. + * + * @details + * + * Function: rgSCHCmnCompEff + * Purpose: this function computes the efficiency as number of + * bytes per 1024 symbols. The CFI table is also filled + * with the same information such that comparison is valid + * + * Invoked by: Scheduler + * + * @param[in] U8 noPdcchSym + * @param[in] U8 cpType + * @param[in] U8 txAntIdx + * @param[in] RgSchCmnTbSzEff* effTbl + * @return Void + * + **/ +#ifdef ANSI +PRIVATE Void rgSCHCmnCompEff +( +U8 noPdcchSym, +U8 cpType, +U8 txAntIdx, +RgSchCmnTbSzEff *effTbl +) +#else +PRIVATE Void rgSCHCmnCompEff(noPdcchSym, cpType, txAntIdx, effTbl) +U8 noPdcchSym; +U8 cpType; +U8 txAntIdx; +RgSchCmnTbSzEff *effTbl; +#endif +{ + U8 noResPerRb; + U8 noSymPerRb; + U8 resOfCrs; /* Effective REs occupied by CRS */ + U8 i, j; + + TRC2(rgSCHCmnCompEff); + + switch (cpType) + { + case RG_SCH_CMN_NOR_CP: + noSymPerRb = 14; + break; + case RG_SCH_CMN_EXT_CP: + noSymPerRb = 12; + break; + default: + /* Generate a log error. This case should never be executed */ + RETVOID; + } + + /* Depending on the Tx Antenna Index, deduct the + * Resource elements for the CRS */ + switch (txAntIdx) + { + case 0: + resOfCrs = RG_SCH_CMN_EFF_CRS_ONE_ANT_PORT; + break; + case 1: + resOfCrs = RG_SCH_CMN_EFF_CRS_TWO_ANT_PORT; + break; + case 2: + resOfCrs = RG_SCH_CMN_EFF_CRS_FOUR_ANT_PORT; + break; + default: + /* Generate a log error. This case should never be executed */ + RETVOID; + } + noResPerRb = ((noSymPerRb - noPdcchSym) * RB_SCH_CMN_NUM_SCS_PER_RB) - resOfCrs; + for (i = 0; i < RG_SCH_CMN_NUM_TBS; i++) + { + (*effTbl)[i] = 0; + for (j = 0; j < RG_SCH_CMN_NUM_RBS; j++) + { + /* This line computes the coding efficiency per 1024 REs */ + (*effTbl)[i] += (rgTbSzTbl[0][i][j] * 1024) / (noResPerRb * (j+1)); + } + (*effTbl)[i] /= RG_SCH_CMN_NUM_RBS; + } + RETVOID; +} +/** + * @brief This function computes efficiency and stores in a table. + * + * @details + * + * Function: rgSCHCmnCompUlEff + * Purpose: this function computes the efficiency as number of + * bytes per 1024 symbols. The CFI table is also filled + * with the same information such that comparison is valid + * + * Invoked by: Scheduler + * + * @param[in] U8 noUlRsSym + * @param[in] U8 cpType + * @param[in] U8 txAntIdx + * @param[in] RgSchCmnTbSzEff* effTbl + * @return Void + * + **/ +#ifdef ANSI +PRIVATE Void rgSCHCmnCompUlEff +( +U8 noUlRsSym, +U8 cpType, +RgSchCmnTbSzEff *effTbl +) +#else +PRIVATE Void rgSCHCmnCompUlEff(noUlRsSym, cpType, effTbl) +U8 noUlRsSym; +U8 cpType; +RgSchCmnTbSzEff *effTbl; +#endif +{ + U8 noResPerRb; + U8 noSymPerRb; + U8 i, j; + + TRC2(rgSCHCmnCompUlEff); + + switch (cpType) + { + case RG_SCH_CMN_NOR_CP: + noSymPerRb = 14; + break; + case RG_SCH_CMN_EXT_CP: + noSymPerRb = 12; + break; + default: + /* Generate a log error. This case should never be executed */ + RETVOID; + } + + noResPerRb = ((noSymPerRb - noUlRsSym) * RB_SCH_CMN_NUM_SCS_PER_RB); + for (i = 0; i < RG_SCH_CMN_NUM_TBS; i++) + { + (*effTbl)[i] = 0; + for (j = 0; j < RG_SCH_CMN_NUM_RBS; j++) + { + /* This line computes the coding efficiency per 1024 REs */ + (*effTbl)[i] += (rgTbSzTbl[0][i][j] * 1024) / (noResPerRb * (j+1)); + } + (*effTbl)[i] /= RG_SCH_CMN_NUM_RBS; + } + RETVOID; +} + +/** + * @brief This function computes efficiency for 2 layers and stores in a table. + * + * @details + * + * Function: rgSCHCmn2LyrCompEff + * Purpose: this function computes the efficiency as number of + * bytes per 1024 symbols. The CFI table is also filled + * with the same information such that comparison is valid + * + * Invoked by: Scheduler + * + * @param[in] U8 noPdcchSym + * @param[in] U8 cpType + * @param[in] U8 txAntIdx + * @param[in] RgSchCmnTbSzEff* effTbl2Lyr + * @return Void + * + **/ +#ifdef ANSI +PRIVATE Void rgSCHCmn2LyrCompEff +( +U8 noPdcchSym, +U8 cpType, +U8 txAntIdx, +RgSchCmnTbSzEff *effTbl2Lyr +) +#else +PRIVATE Void rgSCHCmn2LyrCompEff(noPdcchSym, cpType, txAntIdx, effTbl2Lyr) +U8 noPdcchSym; +U8 cpType; +U8 txAntIdx; +RgSchCmnTbSzEff *effTbl2Lyr; +#endif +{ + U8 noResPerRb; + U8 noSymPerRb; + U8 resOfCrs; /* Effective REs occupied by CRS */ + U8 i, j; + + TRC2(rgSCHCmn2LyrCompEff); + + switch (cpType) + { + case RG_SCH_CMN_NOR_CP: + noSymPerRb = 14; + break; + case RG_SCH_CMN_EXT_CP: + noSymPerRb = 12; + break; + default: + /* Generate a log error. This case should never be executed */ + RETVOID; + } + + /* Depending on the Tx Antenna Index, deduct the + * Resource elements for the CRS */ + switch (txAntIdx) + { + case 0: + resOfCrs = RG_SCH_CMN_EFF_CRS_ONE_ANT_PORT; + break; + case 1: + resOfCrs = RG_SCH_CMN_EFF_CRS_TWO_ANT_PORT; + break; + case 2: + resOfCrs = RG_SCH_CMN_EFF_CRS_FOUR_ANT_PORT; + break; + default: + /* Generate a log error. This case should never be executed */ + RETVOID; + } + + noResPerRb = ((noSymPerRb - noPdcchSym) * RB_SCH_CMN_NUM_SCS_PER_RB) - resOfCrs; + for (i = 0; i < RG_SCH_CMN_NUM_TBS; i++) + { + (*effTbl2Lyr)[i] = 0; + for (j = 0; j < RG_SCH_CMN_NUM_RBS; j++) + { + /* This line computes the coding efficiency per 1024 REs */ + (*effTbl2Lyr)[i] += (rgTbSzTbl[1][i][j] * 1024) / (noResPerRb * (j+1)); + } + (*effTbl2Lyr)[i] /= RG_SCH_CMN_NUM_RBS; + } + RETVOID; +} + + +/** + * @brief This function initializes the rgSchCmnDciFrmtSizes table. + * + * @details + * + * Function: rgSCHCmnGetDciFrmtSizes + * Purpose: This function determines the sizes of all + * the available DCI Formats. The order of + * bits addition for each format is inaccordance + * with the specs. + * Invoked by: rgSCHCmnRgrCellCfg + * + * @return Void + * + **/ +#ifdef ANSI +PRIVATE Void rgSCHCmnGetDciFrmtSizes +( +RgSchCellCb *cell +) +#else +PRIVATE Void rgSCHCmnGetDciFrmtSizes(cell) +RgSchCellCb *cell; +#endif +{ + + TRC2(rgSCHCmnGetDciFrmtSizes); + + /* DCI Format 0 size determination */ + rgSchCmnDciFrmtSizes[0] = 1 + + 1 + + rgSCHUtlLog32bitNbase2((cell->bwCfg.ulTotalBw * \ + (cell->bwCfg.ulTotalBw + 1))/2) + + 5 + + 1 + + 2 + + 3 + +#ifdef LTE_TDD + 2 + + 2 + +#endif + 1; + /* DCI Format 1 size determination */ + rgSchCmnDciFrmtSizes[1] = 1 + + RGSCH_CEIL(cell->bwCfg.dlTotalBw, cell->rbgSize) + + 5 + +#ifndef LTE_TDD + 3 + +#else + 4 + 2 + /* HqProc Id and DAI */ +#endif + 1 + + 2 + + 2; + + /* DCI Format 1A size determination */ + rgSchCmnDciFrmtSizes[2] = 1 + /* Flag for format0/format1a differentiation */ + 1 + /* Localized/distributed VRB assignment flag */ + 5 + /* For mcs */ +#ifndef LTE_TDD + 3 + /* Harq process Id */ +#else + 4 + /* Harq process Id */ + 2 + /* UL Index or DAI */ +#endif + 1 + /* New Data Indicator */ + 2 + /* For RV */ + 2 + /* For tpc */ + 1 + rgSCHUtlLog32bitNbase2((cell->bwCfg.dlTotalBw * \ + (cell->bwCfg.dlTotalBw + 1))/2); + /* Resource block assignment ceil[log2(bw(bw+1)/2)] : \ + Since VRB is local */ + + /* DCI Format 1B size determination */ + rgSchCmnDciFrmtSizes[3] = 1 + + rgSCHUtlLog32bitNbase2((cell->bwCfg.dlTotalBw * \ + (cell->bwCfg.dlTotalBw + 1))/2) + + 5 + + 3 + +#ifdef LTE_TDD + 1 + /* HqP */ + 2 + /* Dai */ +#endif + 1 + + 2 + + 2 + + ((cell->numTxAntPorts == 4)? 4:2) + + 1; + + /* DCI Format 1C size determination */ + /* Approximation: NDLVrbGap1 ~= Nprb for DL */ + rgSchCmnDciFrmtSizes[4] = (cell->bwCfg.dlTotalBw < 50)? 0:1 + + (cell->bwCfg.dlTotalBw < 50)? + (rgSCHUtlLog32bitNbase2((cell->bwCfg.dlTotalBw/2 * \ + (cell->bwCfg.dlTotalBw/2 + 1))/2)) : + (rgSCHUtlLog32bitNbase2((cell->bwCfg.dlTotalBw/4 * \ + (cell->bwCfg.dlTotalBw/4 + 1))/2)) + + 5; + + /* DCI Format 1D size determination */ + rgSchCmnDciFrmtSizes[5] = 1 + + rgSCHUtlLog32bitNbase2((cell->bwCfg.dlTotalBw * \ + (cell->bwCfg.dlTotalBw + 1))/2) + + 5 + + 3 + +#ifdef LTE_TDD + 1 + 2 + +#endif + 1 + + 2 + + 2 + + ((cell->numTxAntPorts == 4)? 4:2) + + 1; + + /* DCI Format 2 size determination */ + rgSchCmnDciFrmtSizes[6] = ((cell->bwCfg.dlTotalBw < 10)?0:1) + + RGSCH_CEIL(cell->bwCfg.dlTotalBw, cell->rbgSize) + + 2 + +#ifdef LTE_TDD + 2 + 1 + +#endif + 3 + + 1 + + (5 + 1 + 2)*2 + + ((cell->numTxAntPorts == 4)? 6:3); + + /* DCI Format 2A size determination */ + rgSchCmnDciFrmtSizes[7] = ((cell->bwCfg.dlTotalBw < 10)?0:1) + + RGSCH_CEIL(cell->bwCfg.dlTotalBw, cell->rbgSize) + + 2 + +#ifdef LTE_TDD + 2 + 1 + +#endif + 3 + + 1 + + (5 + 1 + 2)*2 + + ((cell->numTxAntPorts == 4)? 2:0); + + /* DCI Format 3 size determination */ + rgSchCmnDciFrmtSizes[8] = rgSchCmnDciFrmtSizes[0]; + + /* DCI Format 3A size determination */ + rgSchCmnDciFrmtSizes[9] = rgSchCmnDciFrmtSizes[0]; + + RETVOID; +} + + +/** + * @brief This function initializes the cmnCell->dciAggrLvl table. + * + * @details + * + * Function: rgSCHCmnGetCqiDciFrmt2AggrLvl + * Purpose: This function determines the Aggregation level + * for each CQI level against each DCI format. + * Invoked by: rgSCHCmnRgrCellCfg + * + * @return Void + * + **/ +#ifdef ANSI +PRIVATE Void rgSCHCmnGetCqiDciFrmt2AggrLvl +( +RgSchCellCb *cell +) +#else +PRIVATE Void rgSCHCmnGetCqiDciFrmt2AggrLvl(cell) +RgSchCellCb *cell; +#endif +{ + RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell); + U8 i; + U8 j; + + TRC2(rgSCHCmnGetCqiDciFrmt2AggrLvl); + + for (i = 0; i < RG_SCH_CMN_MAX_CQI; i++) + { + for (j = 0; j < 10; j++) + { + U32 pdcchBits; /* Actual number of phy bits needed for a given DCI Format + * for a given CQI Level */ + pdcchBits = (rgSchCmnDciFrmtSizes[j] * 1024)/rgSchCmnCqiPdcchEff[i]; + /* V5G_211 : 6.6 */ + if (pdcchBits < 192) + { + cellSch->dciAggrLvl[i][j] = CM_LTE_AGGR_LVL2; + continue; + } + if (pdcchBits < 384) + { + cellSch->dciAggrLvl[i][j] = CM_LTE_AGGR_LVL4; + continue; + } + if (pdcchBits < 768) + { + cellSch->dciAggrLvl[i][j] = CM_LTE_AGGR_LVL8; + continue; + } + cellSch->dciAggrLvl[i][j] = CM_LTE_AGGR_LVL16; + } + } + RETVOID; +} + +/** + * @brief This function initializes all the data for the scheduler. + * + * @details + * + * Function: rgSCHCmnDlInit + * Purpose: This function initializes the following information: + * 1. Efficiency table + * 2. CQI to table index - It is one row for upto 3 RBs + * and another row for greater than 3 RBs + * currently extended prefix is compiled out. + * Invoked by: MAC intialization code..may be ActvInit + * + * @return Void + * + **/ +#ifdef ANSI +PRIVATE Void rgSCHCmnDlInit +( +) +#else +PRIVATE Void rgSCHCmnDlInit() +#endif +{ + U8 i; + S16 j; + S16 k; + U8 idx; + RgSchCmnTbSzEff *effTbl; + RgSchCmnCqiToTbs *tbsTbl; + + TRC2(rgSCHCmnDlInit); + + /* 0 corresponds to Single layer case, 1 corresponds to 2 layers case*/ + /* Init Efficiency table for normal cyclic prefix */ + /*Initialize Efficiency table for Layer Index 0 */ + /*Initialize Efficiency table for Tx Antenna Port Index 0 */ + /*Initialize Efficiency table for each of the CFI indices. The + * 4th Dimension of the rgSCHCmnEffTbl table refers to the CFI Index*/ + rgSchCmnEffTbl[0][RG_SCH_CMN_NOR_CP][0][0] = &rgSchCmnNorCfi1Eff[0]; + rgSchCmnEffTbl[0][RG_SCH_CMN_NOR_CP][0][1] = &rgSchCmnNorCfi2Eff[0]; + rgSchCmnEffTbl[0][RG_SCH_CMN_NOR_CP][0][2] = &rgSchCmnNorCfi3Eff[0]; + rgSchCmnEffTbl[0][RG_SCH_CMN_NOR_CP][0][3] = &rgSchCmnNorCfi4Eff[0]; + /*Initialize Efficency table for Tx Antenna Port Index 1 */ + rgSchCmnEffTbl[0][RG_SCH_CMN_NOR_CP][1][0] = &rgSchCmnNorCfi1Eff[0]; + rgSchCmnEffTbl[0][RG_SCH_CMN_NOR_CP][1][1] = &rgSchCmnNorCfi2Eff[0]; + rgSchCmnEffTbl[0][RG_SCH_CMN_NOR_CP][1][2] = &rgSchCmnNorCfi3Eff[0]; + rgSchCmnEffTbl[0][RG_SCH_CMN_NOR_CP][1][3] = &rgSchCmnNorCfi4Eff[0]; + /*Initialize Efficency table for Tx Antenna Port Index 2 */ + rgSchCmnEffTbl[0][RG_SCH_CMN_NOR_CP][2][0] = &rgSchCmnNorCfi1Eff[0]; + rgSchCmnEffTbl[0][RG_SCH_CMN_NOR_CP][2][1] = &rgSchCmnNorCfi2Eff[0]; + rgSchCmnEffTbl[0][RG_SCH_CMN_NOR_CP][2][2] = &rgSchCmnNorCfi3Eff[0]; + rgSchCmnEffTbl[0][RG_SCH_CMN_NOR_CP][2][3] = &rgSchCmnNorCfi4Eff[0]; + + /*Initialize CQI to TBS table for Layer Index 0 for Normal CP */ + rgSchCmnCqiToTbs[0][RG_SCH_CMN_NOR_CP][0] = &rgSchCmnNorCfi1CqiToTbs[0]; + rgSchCmnCqiToTbs[0][RG_SCH_CMN_NOR_CP][1] = &rgSchCmnNorCfi2CqiToTbs[0]; + rgSchCmnCqiToTbs[0][RG_SCH_CMN_NOR_CP][2] = &rgSchCmnNorCfi3CqiToTbs[0]; + rgSchCmnCqiToTbs[0][RG_SCH_CMN_NOR_CP][3] = &rgSchCmnNorCfi4CqiToTbs[0]; + + /*Intialize Efficency table for Layer Index 1 */ + /*Initialize Efficiency table for Tx Antenna Port Index 0 */ + /*Initialize Efficiency table for each of the CFI indices. The + * 4th Dimension of the rgSCHCmnEffTbl table refers to the CFI Index*/ + rgSchCmnEffTbl[1][RG_SCH_CMN_NOR_CP][0][0] = &rgSchCmnNorCfi1Eff[1]; + rgSchCmnEffTbl[1][RG_SCH_CMN_NOR_CP][0][1] = &rgSchCmnNorCfi2Eff[1]; + rgSchCmnEffTbl[1][RG_SCH_CMN_NOR_CP][0][2] = &rgSchCmnNorCfi3Eff[1]; + rgSchCmnEffTbl[1][RG_SCH_CMN_NOR_CP][0][3] = &rgSchCmnNorCfi4Eff[1]; + /*Initialize Efficiency table for Tx Antenna Port Index 1 */ + rgSchCmnEffTbl[1][RG_SCH_CMN_NOR_CP][1][0] = &rgSchCmnNorCfi1Eff[1]; + rgSchCmnEffTbl[1][RG_SCH_CMN_NOR_CP][1][1] = &rgSchCmnNorCfi2Eff[1]; + rgSchCmnEffTbl[1][RG_SCH_CMN_NOR_CP][1][2] = &rgSchCmnNorCfi3Eff[1]; + rgSchCmnEffTbl[1][RG_SCH_CMN_NOR_CP][1][3] = &rgSchCmnNorCfi4Eff[1]; + /*Initialize Efficiency table for Tx Antenna Port Index 2 */ + rgSchCmnEffTbl[1][RG_SCH_CMN_NOR_CP][2][0] = &rgSchCmnNorCfi1Eff[1]; + rgSchCmnEffTbl[1][RG_SCH_CMN_NOR_CP][2][1] = &rgSchCmnNorCfi2Eff[1]; + rgSchCmnEffTbl[1][RG_SCH_CMN_NOR_CP][2][2] = &rgSchCmnNorCfi3Eff[1]; + rgSchCmnEffTbl[1][RG_SCH_CMN_NOR_CP][2][3] = &rgSchCmnNorCfi4Eff[1]; + + /*Initialize CQI to TBS table for Layer Index 1 for Normal CP */ + rgSchCmnCqiToTbs[1][RG_SCH_CMN_NOR_CP][0] = &rgSchCmnNorCfi1CqiToTbs[1]; + rgSchCmnCqiToTbs[1][RG_SCH_CMN_NOR_CP][1] = &rgSchCmnNorCfi2CqiToTbs[1]; + rgSchCmnCqiToTbs[1][RG_SCH_CMN_NOR_CP][2] = &rgSchCmnNorCfi3CqiToTbs[1]; + rgSchCmnCqiToTbs[1][RG_SCH_CMN_NOR_CP][3] = &rgSchCmnNorCfi4CqiToTbs[1]; + + for (idx = 0; idx < RG_SCH_CMN_MAX_ANT_CONF; idx++) + { + for (i = 0; i < RG_SCH_CMN_MAX_CFI; i++) + { + /* EfficiencyTbl calculation incase of 2 layers for normal CP */ + rgSCHCmnCompEff((U8)(i + 1), RG_SCH_CMN_NOR_CP, idx,\ + rgSchCmnEffTbl[0][RG_SCH_CMN_NOR_CP][idx][i]); + rgSCHCmn2LyrCompEff((U8)(i + 1), RG_SCH_CMN_NOR_CP, idx, \ + rgSchCmnEffTbl[1][RG_SCH_CMN_NOR_CP][idx][i]); + } + } + + for (idx = 0; idx < RG_SCH_CMN_MAX_ANT_CONF; idx++) + { + for (i = 0; i < RG_SCH_CMN_MAX_CFI; i++) + { + effTbl = rgSchCmnEffTbl[0][RG_SCH_CMN_NOR_CP][idx][i]; + tbsTbl = rgSchCmnCqiToTbs[0][RG_SCH_CMN_NOR_CP][i]; + for (j = RG_SCH_CMN_NUM_TBS - 1, k = RG_SCH_CMN_MAX_CQI - 1; + (j >= 0) && (k > 0); --j) + { + /* ADD CQI to MCS mapping correction + * single dimensional array is replaced by 2 dimensions for different CFI*/ + if ((*effTbl)[j] <= rgSchCmnCqiPdschEff[i][k]) + { + (*tbsTbl)[k--] = (U8)j; + } + } + for (; k > 0; --k) + { + (*tbsTbl)[k] = 0; + } + /* effTbl,tbsTbl calculation incase of 2 layers for normal CP */ + effTbl = rgSchCmnEffTbl[1][RG_SCH_CMN_NOR_CP][idx][i]; + tbsTbl = rgSchCmnCqiToTbs[1][RG_SCH_CMN_NOR_CP][i]; + for (j = RG_SCH_CMN_NUM_TBS - 1, k = RG_SCH_CMN_MAX_CQI - 1; + (j >= 0) && (k > 0); --j) + { + /* ADD CQI to MCS mapping correction + * single dimensional array is replaced by 2 dimensions for different CFI*/ + if ((*effTbl)[j] <= rgSchCmn2LyrCqiPdschEff[i][k]) + { + (*tbsTbl)[k--] = (U8)j; + } + } + for (; k > 0; --k) + { + (*tbsTbl)[k] = 0; + } + } + } + + /* Efficiency Table for Extended CP */ + /*Initialize Efficiency table for Layer Index 0 */ + /*Initialize Efficiency table for Tx Antenna Port Index 0 */ + /*Initialize Efficiency table for each of the CFI indices. The + * 4th Dimension of the rgSCHCmnEffTbl table refers to the CFI Index*/ + rgSchCmnEffTbl[0][RG_SCH_CMN_EXT_CP][0][0] = &rgSchCmnExtCfi1Eff[0]; + rgSchCmnEffTbl[0][RG_SCH_CMN_EXT_CP][0][1] = &rgSchCmnExtCfi2Eff[0]; + rgSchCmnEffTbl[0][RG_SCH_CMN_EXT_CP][0][2] = &rgSchCmnExtCfi3Eff[0]; + rgSchCmnEffTbl[0][RG_SCH_CMN_EXT_CP][0][3] = &rgSchCmnExtCfi4Eff[0]; + /*Initialize Efficency table for Tx Antenna Port Index 1 */ + rgSchCmnEffTbl[0][RG_SCH_CMN_EXT_CP][1][0] = &rgSchCmnExtCfi1Eff[0]; + rgSchCmnEffTbl[0][RG_SCH_CMN_EXT_CP][1][1] = &rgSchCmnExtCfi2Eff[0]; + rgSchCmnEffTbl[0][RG_SCH_CMN_EXT_CP][1][2] = &rgSchCmnExtCfi3Eff[0]; + rgSchCmnEffTbl[0][RG_SCH_CMN_EXT_CP][1][3] = &rgSchCmnExtCfi4Eff[0]; + /*Initialize Efficency table for Tx Antenna Port Index 2 */ + rgSchCmnEffTbl[0][RG_SCH_CMN_EXT_CP][2][0] = &rgSchCmnExtCfi1Eff[0]; + rgSchCmnEffTbl[0][RG_SCH_CMN_EXT_CP][2][1] = &rgSchCmnExtCfi2Eff[0]; + rgSchCmnEffTbl[0][RG_SCH_CMN_EXT_CP][2][2] = &rgSchCmnExtCfi3Eff[0]; + rgSchCmnEffTbl[0][RG_SCH_CMN_EXT_CP][2][3] = &rgSchCmnExtCfi4Eff[0]; + + /*Initialize CQI to TBS table for Layer Index 0 for Extended CP */ + rgSchCmnCqiToTbs[0][RG_SCH_CMN_EXT_CP][0] = &rgSchCmnExtCfi1CqiToTbs[0]; + rgSchCmnCqiToTbs[0][RG_SCH_CMN_EXT_CP][1] = &rgSchCmnExtCfi2CqiToTbs[0]; + rgSchCmnCqiToTbs[0][RG_SCH_CMN_EXT_CP][2] = &rgSchCmnExtCfi3CqiToTbs[0]; + rgSchCmnCqiToTbs[0][RG_SCH_CMN_EXT_CP][3] = &rgSchCmnExtCfi4CqiToTbs[0]; + + /*Initialize Efficiency table for Layer Index 1 */ + /*Initialize Efficiency table for each of the CFI indices. The + * 4th Dimension of the rgSCHCmnEffTbl table refers to the CFI Index*/ + /*Initialize Efficency table for Tx Antenna Port Index 0 */ + rgSchCmnEffTbl[1][RG_SCH_CMN_EXT_CP][0][0] = &rgSchCmnExtCfi1Eff[1]; + rgSchCmnEffTbl[1][RG_SCH_CMN_EXT_CP][0][1] = &rgSchCmnExtCfi2Eff[1]; + rgSchCmnEffTbl[1][RG_SCH_CMN_EXT_CP][0][2] = &rgSchCmnExtCfi3Eff[1]; + rgSchCmnEffTbl[1][RG_SCH_CMN_EXT_CP][0][3] = &rgSchCmnExtCfi4Eff[1]; + /*Initialize Efficency table for Tx Antenna Port Index 1 */ + rgSchCmnEffTbl[1][RG_SCH_CMN_EXT_CP][1][0] = &rgSchCmnExtCfi1Eff[1]; + rgSchCmnEffTbl[1][RG_SCH_CMN_EXT_CP][1][1] = &rgSchCmnExtCfi2Eff[1]; + rgSchCmnEffTbl[1][RG_SCH_CMN_EXT_CP][1][2] = &rgSchCmnExtCfi3Eff[1]; + rgSchCmnEffTbl[1][RG_SCH_CMN_EXT_CP][1][3] = &rgSchCmnExtCfi4Eff[1]; + /*Initialize Efficency table for Tx Antenna Port Index 2 */ + rgSchCmnEffTbl[1][RG_SCH_CMN_EXT_CP][2][0] = &rgSchCmnExtCfi1Eff[1]; + rgSchCmnEffTbl[1][RG_SCH_CMN_EXT_CP][2][1] = &rgSchCmnExtCfi2Eff[1]; + rgSchCmnEffTbl[1][RG_SCH_CMN_EXT_CP][2][2] = &rgSchCmnExtCfi3Eff[1]; + rgSchCmnEffTbl[1][RG_SCH_CMN_EXT_CP][2][3] = &rgSchCmnExtCfi4Eff[1]; + + /*Initialize CQI to TBS table for Layer Index 1 for Extended CP */ + rgSchCmnCqiToTbs[1][RG_SCH_CMN_EXT_CP][0] = &rgSchCmnExtCfi1CqiToTbs[1]; + rgSchCmnCqiToTbs[1][RG_SCH_CMN_EXT_CP][1] = &rgSchCmnExtCfi2CqiToTbs[1]; + rgSchCmnCqiToTbs[1][RG_SCH_CMN_EXT_CP][2] = &rgSchCmnExtCfi3CqiToTbs[1]; + rgSchCmnCqiToTbs[1][RG_SCH_CMN_EXT_CP][3] = &rgSchCmnExtCfi4CqiToTbs[1]; + /* Activate this code when extended cp is supported */ + for (idx = 0; idx < RG_SCH_CMN_MAX_ANT_CONF; idx++) + { + for (i = 0; i < RG_SCH_CMN_MAX_CFI; i++) + { + /* EfficiencyTbl calculation incase of 2 layers for extendedl CP */ + rgSCHCmnCompEff( (U8)(i + 1 ), (U8)RG_SCH_CMN_EXT_CP, idx,\ + rgSchCmnEffTbl[0][RG_SCH_CMN_EXT_CP][idx][i]); + rgSCHCmn2LyrCompEff((U8)(i + 1), (U8) RG_SCH_CMN_EXT_CP,idx, \ + rgSchCmnEffTbl[1][RG_SCH_CMN_EXT_CP][idx][i]); + } + } + + for (idx = 0; idx < RG_SCH_CMN_MAX_ANT_CONF; idx++) + { + for (i = 0; i < RG_SCH_CMN_MAX_CFI; i++) + { + effTbl = rgSchCmnEffTbl[0][RG_SCH_CMN_EXT_CP][idx][i]; + tbsTbl = rgSchCmnCqiToTbs[0][RG_SCH_CMN_EXT_CP][i]; + for (j = RG_SCH_CMN_NUM_TBS - 1, k = RG_SCH_CMN_MAX_CQI - 1; + (j >= 0) && (k > 0); --j) + { + /* ADD CQI to MCS mapping correction + * single dimensional array is replaced by 2 dimensions for different CFI*/ + if ((*effTbl)[j] <= rgSchCmnCqiPdschEff[i][k]) + { + (*tbsTbl)[k--] = (U8)j; + } + } + for (; k > 0; --k) + { + (*tbsTbl)[k] = 0; + } + /* effTbl,tbsTbl calculation incase of 2 layers for extended CP */ + effTbl = rgSchCmnEffTbl[1][RG_SCH_CMN_EXT_CP][idx][i]; + tbsTbl = rgSchCmnCqiToTbs[1][RG_SCH_CMN_EXT_CP][i]; + for (j = RG_SCH_CMN_NUM_TBS - 1, k = RG_SCH_CMN_MAX_CQI - 1; + (j >= 0) && (k > 0); --j) + { + /* ADD CQI to MCS mapping correction + * single dimensional array is replaced by 2 dimensions for different CFI*/ + if ((*effTbl)[j] <= rgSchCmn2LyrCqiPdschEff[i][k]) + { + (*tbsTbl)[k--] = (U8)j; + } + } + for (; k > 0; --k) + { + (*tbsTbl)[k] = 0; + } + } + } + RETVOID; +} + +/** + * @brief This function initializes all the data for the scheduler. + * + * @details + * + * Function: rgSCHCmnUlInit + * Purpose: This function initializes the following information: + * 1. Efficiency table + * 2. CQI to table index - It is one row for upto 3 RBs + * and another row for greater than 3 RBs + * currently extended prefix is compiled out. + * Invoked by: MAC intialization code..may be ActvInit + * + * @return Void + * + **/ +#ifdef ANSI +PRIVATE Void rgSCHCmnUlInit +( +) +#else +PRIVATE Void rgSCHCmnUlInit() +#endif +{ + U8 *mapTbl = &rgSchCmnUlCqiToTbsTbl[RG_SCH_CMN_NOR_CP][0]; + RgSchCmnTbSzEff *effTbl = &rgSchCmnNorUlEff[0]; + CONSTANT RgSchCmnUlCqiInfo *cqiTbl = &rgSchCmnUlCqiTbl[0]; + S16 i; + S16 j; + TRC2(rgSCHCmnUlInit); + + /* Initaializing new variable added for UL eff */ + rgSchCmnUlEffTbl[RG_SCH_CMN_NOR_CP] = &rgSchCmnNorUlEff[0]; + /* Reason behind using 3 as the number of symbols to rule out for + * efficiency table computation would be that we are using 2 symbols for + * DMRS(1 in each slot) and 1 symbol for SRS*/ + rgSCHCmnCompUlEff(RGSCH_UL_SYM_DMRS_SRS,RG_SCH_CMN_NOR_CP,rgSchCmnUlEffTbl[RG_SCH_CMN_NOR_CP]); + + for (i = RGSCH_NUM_ITBS - 1, j = RG_SCH_CMN_UL_NUM_CQI - 1; + i >= 0 && j > 0; --i) + { + if ((*effTbl)[i] <= cqiTbl[j].eff) + { + mapTbl[j--] = (U8)i; + } + } + for (; j > 0; --j) + { + mapTbl[j] = 0; + } + effTbl = &rgSchCmnExtUlEff[0]; + mapTbl = &rgSchCmnUlCqiToTbsTbl[RG_SCH_CMN_EXT_CP][0]; + + /* Initaializing new variable added for UL eff */ + rgSchCmnUlEffTbl[RG_SCH_CMN_EXT_CP] = &rgSchCmnExtUlEff[0]; + /* Reason behind using 3 as the number of symbols to rule out for + * efficiency table computation would be that we are using 2 symbols for + * DMRS(1 in each slot) and 1 symbol for SRS*/ + rgSCHCmnCompUlEff(3,RG_SCH_CMN_EXT_CP,rgSchCmnUlEffTbl[RG_SCH_CMN_EXT_CP]); + + for (i = RGSCH_NUM_ITBS - 1, j = RG_SCH_CMN_UL_NUM_CQI - 1; + i >= 0 && j > 0; --i) + { + if ((*effTbl)[i] <= cqiTbl[j].eff) + { + mapTbl[j--] = (U8)i; + } + } + for (; j > 0; --j) + { + mapTbl[j] = 0; + } + rgSCHPwrInit(); + RETVOID; +} + + +/** + * @brief This function initializes all the data for the scheduler. + * + * @details + * + * Function: rgSCHCmnInit + * Purpose: This function initializes the following information: + * 1. Efficiency table + * 2. CQI to table index - It is one row for upto 3 RBs + * and another row for greater than 3 RBs + * currently extended prefix is compiled out. + * Invoked by: MAC intialization code..may be ActvInit + * + * @return Void + * + **/ +#ifdef ANSI +PUBLIC Void rgSCHCmnInit +( +) +#else +PUBLIC Void rgSCHCmnInit() +#endif +{ + U8 idx; + TRC2(rgSCHCmnInit); + + rgSCHCmnDlInit(); + rgSCHCmnUlInit(); +#ifdef EMTC_ENABLE + rgSCHEmtcCmnDlInit(); + rgSCHEmtcCmnUlInit(); +#endif +#ifdef LTEMAC_SPS + rgSCHCmnSpsInit(); +#endif + + /* Init the function pointers */ + rgSchCmnApis.rgSCHRgrUeCfg = rgSCHCmnRgrUeCfg; + rgSchCmnApis.rgSCHRgrUeRecfg = rgSCHCmnRgrUeRecfg; + rgSchCmnApis.rgSCHFreeUe = rgSCHCmnUeDel; + rgSchCmnApis.rgSCHRgrCellCfg = rgSCHCmnRgrCellCfg; + rgSchCmnApis.rgSCHRgrCellRecfg = rgSCHCmnRgrCellRecfg; + rgSchCmnApis.rgSCHFreeCell = rgSCHCmnCellDel; + rgSchCmnApis.rgSCHRgrLchCfg = rgSCHCmnRgrLchCfg; + rgSchCmnApis.rgSCHRgrLcgCfg = rgSCHCmnRgrLcgCfg; + rgSchCmnApis.rgSCHRgrLchRecfg = rgSCHCmnRgrLchRecfg; + rgSchCmnApis.rgSCHRgrLcgRecfg = rgSCHCmnRgrLcgRecfg; + rgSchCmnApis.rgSCHFreeDlLc = rgSCHCmnFreeDlLc; + rgSchCmnApis.rgSCHFreeLcg = rgSCHCmnLcgDel; + rgSchCmnApis.rgSCHRgrLchDel = rgSCHCmnRgrLchDel; + rgSchCmnApis.rgSCHActvtUlUe = rgSCHCmnActvtUlUe; + rgSchCmnApis.rgSCHActvtDlUe = rgSCHCmnActvtDlUe; + rgSchCmnApis.rgSCHHdlUlTransInd = rgSCHCmnHdlUlTransInd; + rgSchCmnApis.rgSCHDlDedBoUpd = rgSCHCmnDlDedBoUpd; + rgSchCmnApis.rgSCHUlRecMsg3Alloc = rgSCHCmnUlRecMsg3Alloc; + rgSchCmnApis.rgSCHUlCqiInd = rgSCHCmnUlCqiInd; + rgSchCmnApis.rgSCHPucchDeltaPwrInd = rgSCHPwrPucchDeltaInd; + rgSchCmnApis.rgSCHUlHqProcForUe = rgSCHCmnUlHqProcForUe; +#ifdef RG_UNUSED + rgSchCmnApis.rgSCHUpdUlHqProc = rgSCHCmnUpdUlHqProc; +#endif + rgSchCmnApis.rgSCHUpdBsrShort = rgSCHCmnUpdBsrShort; + rgSchCmnApis.rgSCHUpdBsrTrunc = rgSCHCmnUpdBsrTrunc; + rgSchCmnApis.rgSCHUpdBsrLong = rgSCHCmnUpdBsrLong; + rgSchCmnApis.rgSCHUpdPhr = rgSCHCmnUpdPhr; + rgSchCmnApis.rgSCHUpdExtPhr = rgSCHCmnUpdExtPhr; + rgSchCmnApis.rgSCHContResUlGrant = rgSCHCmnContResUlGrant; + rgSchCmnApis.rgSCHSrRcvd = rgSCHCmnSrRcvd; + rgSchCmnApis.rgSCHFirstRcptnReq = rgSCHCmnFirstRcptnReq; + rgSchCmnApis.rgSCHNextRcptnReq = rgSCHCmnNextRcptnReq; + rgSchCmnApis.rgSCHFirstHqFdbkAlloc = rgSCHCmnFirstHqFdbkAlloc; + rgSchCmnApis.rgSCHNextHqFdbkAlloc = rgSCHCmnNextHqFdbkAlloc; + rgSchCmnApis.rgSCHDlProcAddToRetx = rgSCHCmnDlProcAddToRetx; + rgSchCmnApis.rgSCHDlCqiInd = rgSCHCmnDlCqiInd; +#ifdef EMTC_ENABLE + rgSchCmnApis.rgSCHUlProcAddToRetx = rgSCHCmnEmtcUlProcAddToRetx; +#endif +#ifdef TFU_UPGRADE + rgSchCmnApis.rgSCHSrsInd = rgSCHCmnSrsInd; +#endif + rgSchCmnApis.rgSCHDlTARpt = rgSCHCmnDlTARpt; + rgSchCmnApis.rgSCHDlRlsSubFrm = rgSCHCmnDlRlsSubFrm; + rgSchCmnApis.rgSCHUeReset = rgSCHCmnUeReset; +#ifdef LTEMAC_SPS + rgSchCmnApis.rgSCHHdlCrntiCE = rgSCHCmnHdlCrntiCE; + rgSchCmnApis.rgSCHDlProcAck = rgSCHCmnDlProcAck; + rgSchCmnApis.rgSCHDlRelPdcchFbk = rgSCHCmnDlRelPdcchFbk; + rgSchCmnApis.rgSCHUlSpsRelInd = rgSCHCmnUlSpsRelInd; + rgSchCmnApis.rgSCHUlSpsActInd = rgSCHCmnUlSpsActInd; + rgSchCmnApis.rgSCHUlCrcFailInd = rgSCHCmnUlCrcFailInd; + rgSchCmnApis.rgSCHUlCrcInd = rgSCHCmnUlCrcInd; +#endif + rgSchCmnApis.rgSCHDrxStrtInActvTmrInUl = rgSCHCmnDrxStrtInActvTmrInUl; + rgSchCmnApis.rgSCHUpdUeDataIndLcg = rgSCHCmnUpdUeDataIndLcg; + + for (idx = 0; idx < RGSCH_NUM_SCHEDULERS; ++idx) + { + rgSchUlSchdInits[idx](&rgSchUlSchdTbl[idx]); + rgSchDlSchdInits[idx](&rgSchDlSchdTbl[idx]); + } +#ifdef EMTC_ENABLE + for (idx = 0; idx < RGSCH_NUM_EMTC_SCHEDULERS; ++idx) + { + rgSchEmtcUlSchdInits[idx](&rgSchEmtcUlSchdTbl[idx]); + rgSchEmtcDlSchdInits[idx](&rgSchEmtcDlSchdTbl[idx]); + } +#endif +#if (defined (RG_PHASE2_SCHED) && defined(TFU_UPGRADE)) + for (idx = 0; idx < RGSCH_NUM_DLFS_SCHEDULERS; ++idx) + { + rgSchDlfsSchdInits[idx](&rgSchDlfsSchdTbl[idx]); + } +#endif +#ifdef LTE_ADV + rgSchCmnApis.rgSCHRgrSCellUeCfg = rgSCHCmnRgrSCellUeCfg; + rgSchCmnApis.rgSCHRgrSCellUeDel = rgSCHCmnRgrSCellUeDel; +#endif + RETVOID; +} + + +/** + * @brief This function is a wrapper to call scheduler specific API. + * + * @details + * + * Function: rgSCHCmnDlRlsSubFrm + * Purpose: Releases scheduler Information from DL SubFrm. + * + * Invoked by: DHM + * + * @param[in] RgSchCellCb *cell + * @param[out] CmLteTimingInfo frm + * @return Void + * + **/ +#ifdef ANSI +PUBLIC Void rgSCHCmnDlRlsSubFrm +( +RgSchCellCb *cell, +CmLteTimingInfo frm +) +#else +PUBLIC Void rgSCHCmnDlRlsSubFrm(cell, frm) +RgSchCellCb *cell; +CmLteTimingInfo frm; +#endif +{ + RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell); + RgSchDlSf *sf; + + TRC2(rgSCHCmnDlRlsSubFrm); + + /* Get the pointer to the subframe */ + sf = rgSCHUtlSubFrmGet(cell, frm); + + rgSCHUtlSubFrmPut(cell, sf); + if (sf->dlfsSf) + { + /* Re-initialize DLFS specific information for the sub-frame */ + cellSch->apisDlfs->rgSCHDlfsReinitSf(cell, sf); + } + RETVOID; +} + + + +/** + * @brief This function is the starting function for DL allocation. + * + * @details + * + * Function: rgSCHCmnDlCmnChAlloc + * Purpose: Scheduling for downlink. It performs allocation in the order + * of priority wich BCCH/PCH first, CCCH, Random Access and TA. + * + * Invoked by: Scheduler + * + * @param[in] RgSchCellCb* cell + * @param[out] RgSchCmnDlRbAllocInfo* allocInfo + * @return Void + * + **/ +#ifdef ANSI +PRIVATE Void rgSCHCmnDlCcchRarAlloc +( +RgSchCellCb *cell +) +#else +PRIVATE Void rgSCHCmnDlCcchRarAlloc(cell) +RgSchCellCb *cell; +#endif +{ + RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell); + + TRC2(rgSCHCmnDlCcchRarAlloc); + + rgSCHCmnDlCcchRetx(cell, &cellSch->allocInfo); + /* LTE_ADV_FLAG_REMOVED_START */ + if(RG_SCH_ABS_ENABLED_ABS_SF == cell->lteAdvCb.absDlSfInfo) + { + if(cell->lteAdvCb.absCfg.absPatternType & RGR_ABS_MUTE) + { + /*eNodeB need to blank the subframe */ + } + else + { + rgSCHCmnDlCcchTx(cell, &cellSch->allocInfo); + } + } + else + { + rgSCHCmnDlCcchTx(cell, &cellSch->allocInfo); + } + /* LTE_ADV_FLAG_REMOVED_END */ + +#ifdef RGR_V1 + + /*Added these function calls for processing CCCH SDU arriving + * after guard timer expiry.Functions differ from above two functions + * in using ueCb instead of raCb.*/ + rgSCHCmnDlCcchSduRetx(cell, &cellSch->allocInfo); + /* LTE_ADV_FLAG_REMOVED_START */ + if(RG_SCH_ABS_ENABLED_ABS_SF == cell->lteAdvCb.absDlSfInfo) + { + if(cell->lteAdvCb.absCfg.absPatternType & RGR_ABS_MUTE) + { + /*eNodeB need to blank the subframe */ + } + else + { + rgSCHCmnDlCcchSduTx(cell, &cellSch->allocInfo); + } + } + else + { + rgSCHCmnDlCcchSduTx(cell, &cellSch->allocInfo); + } + /* LTE_ADV_FLAG_REMOVED_END */ +#endif + +#ifdef LTE_TDD + if(cellSch->ul.msg3SchdIdx != RGSCH_INVALID_INFO) + { + /* Do not schedule msg3 if there is a CFI change ongoing */ + if (cellSch->dl.currCfi == cellSch->dl.newCfi) + { + rgSCHCmnDlRaRsp(cell, &cellSch->allocInfo); + } + } +#else + /* LTE_ADV_FLAG_REMOVED_START */ + if(RG_SCH_ABS_ENABLED_ABS_SF == cell->lteAdvCb.absDlSfInfo) + { + if(cell->lteAdvCb.absCfg.absPatternType & RGR_ABS_MUTE) + { + /*eNodeB need to blank the subframe */ + } + else + { + /* Do not schedule msg3 if there is a CFI change ongoing */ + if (cellSch->dl.currCfi == cellSch->dl.newCfi) + { + rgSCHCmnDlRaRsp(cell, &cellSch->allocInfo); + } + } + } + else + { + /* Do not schedule msg3 if there is a CFI change ongoing */ + if (cellSch->dl.currCfi == cellSch->dl.newCfi) + { + rgSCHCmnDlRaRsp(cell, &cellSch->allocInfo); + } + } + /* LTE_ADV_FLAG_REMOVED_END */ +#endif + + RETVOID; +} + +#ifdef RGR_V1 +/** + * @brief Scheduling for CCCH SDU. + * + * @details + * + * Function: rgSCHCmnCcchSduAlloc + * Purpose: Scheduling for CCCH SDU + * + * Invoked by: Scheduler + * + * @param[in] RgSchCellCb* cell + * @param[in] RgSchUeCb* ueCb + * @param[out] RgSchCmnDlRbAllocInfo *allocInfo + * @return S16 + * + **/ +#ifdef ANSI +PRIVATE S16 rgSCHCmnCcchSduAlloc +( +RgSchCellCb *cell, +RgSchUeCb *ueCb, +RgSchCmnDlRbAllocInfo *allocInfo +) +#else +PRIVATE S16 rgSCHCmnCcchSduAlloc(cell, ueCb, allocInfo) +RgSchCellCb *cell; +RgSchUeCb *ueCb; +RgSchCmnDlRbAllocInfo *allocInfo; +#endif +{ + RgSchDlRbAlloc *rbAllocInfo; + RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell); + RgSchCmnDlUe *ueDl = RG_SCH_CMN_GET_DL_UE(ueCb,cell); + + TRC2(rgSCHCmnCcchSduAlloc); + + /* Return if subframe BW exhausted */ + if (allocInfo->ccchSduAlloc.ccchSduDlSf->bw <= + allocInfo->ccchSduAlloc.ccchSduDlSf->bwAssigned) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId, + "bw<=bwAssigned for UEID:%d",ueCb->ueId); + RETVALUE(RFAILED); + } + + if (rgSCHDhmGetCcchSduHqProc(ueCb, cellSch->dl.time, &(ueDl->proc)) != ROK) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId, + "rgSCHDhmGetCcchSduHqProc failed UEID:%d",ueCb->ueId); + RETVALUE(RFAILED); + } + + rbAllocInfo = RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ueCb, cell); + rbAllocInfo->dlSf = allocInfo->ccchSduAlloc.ccchSduDlSf; + + if (rgSCHCmnCcchSduDedAlloc(cell, ueCb) != ROK) + { + /* Fix : syed Minor failure handling, release hqP if Unsuccessful */ + rgSCHDhmRlsHqpTb(ueDl->proc, 0, FALSE); + RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId, + "rgSCHCmnCcchSduDedAlloc failed UEID:%d",ueCb->ueId); + RETVALUE(RFAILED); + } + cmLListAdd2Tail(&allocInfo->ccchSduAlloc.ccchSduTxLst, &ueDl->proc->reqLnk); + ueDl->proc->reqLnk.node = (PTR)ueDl->proc; + allocInfo->ccchSduAlloc.ccchSduDlSf->schdCcchUe++; + + RETVALUE(ROK); +} +/** + * @brief This function scheduler for downlink CCCH messages. + * + * @details + * + * Function: rgSCHCmnDlCcchSduTx + * Purpose: Scheduling for downlink CCCH + * + * Invoked by: Scheduler + * + * @param[in] RgSchCellCb *cell + * @param[out] RgSchCmnDlRbAllocInfo *allocInfo + * @return Void + * + **/ +#ifdef ANSI +PRIVATE Void rgSCHCmnDlCcchSduTx +( +RgSchCellCb *cell, +RgSchCmnDlRbAllocInfo *allocInfo +) +#else +PRIVATE Void rgSCHCmnDlCcchSduTx(cell, allocInfo) +RgSchCellCb *cell; +RgSchCmnDlRbAllocInfo *allocInfo; +#endif +{ + CmLList *node; + RgSchUeCb *ueCb; + RgSchCmnDlUe *ueCmnDl; + RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell); + + RgSchDlSf *dlSf = allocInfo->ccchSduAlloc.ccchSduDlSf; + + TRC2(rgSCHCmnDlCcchSduTx); + + node = cell->ccchSduUeLst.first; + while(node) + { + if(cellSch->dl.maxCcchPerDlSf && + dlSf->schdCcchUe == cellSch->dl.maxCcchPerDlSf) + { + break; + } + else + { + ueCb = (RgSchUeCb *)(node->node); + ueCmnDl = RG_SCH_CMN_GET_DL_UE(ueCb,cell); + node = node->next; + /* Fix : syed postpone scheduling for this + * until msg4 is done */ + /* Fix : syed RLC can erroneously send CCCH SDU BO + * twice. Hence an extra guard to avoid if already + * scheduled for RETX */ + if ((!(ueCb->dl.dlInactvMask & RG_HQENT_INACTIVE)) && + (!ueCmnDl->proc)) + { + if ((rgSCHCmnCcchSduAlloc(cell, ueCb, allocInfo)) != ROK) + { + break; + } + } + else + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,"ERROR!! THIS SHOULD " + "NEVER HAPPEN for UEID:%d", ueCb->ueId); + continue; + } + } + } + RETVOID; +} +#endif + +/** + * @brief This function scheduler for downlink CCCH messages. + * + * @details + * + * Function: rgSCHCmnDlCcchTx + * Purpose: Scheduling for downlink CCCH + * + * Invoked by: Scheduler + * + * @param[in] RgSchCellCb *cell + * @param[out] RgSchCmnDlRbAllocInfo *allocInfo + * @return Void + * + **/ +#ifdef ANSI +PRIVATE Void rgSCHCmnDlCcchTx +( +RgSchCellCb *cell, +RgSchCmnDlRbAllocInfo *allocInfo +) +#else +PRIVATE Void rgSCHCmnDlCcchTx(cell, allocInfo) +RgSchCellCb *cell; +RgSchCmnDlRbAllocInfo *allocInfo; +#endif +{ + CmLList *node; + RgSchRaCb *raCb; + RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell); + RgSchDlSf *dlSf = allocInfo->msg4Alloc.msg4DlSf; + + TRC2(rgSCHCmnDlCcchTx); + + node = cell->raInfo.toBeSchdLst.first; + while(node) + { + if(cellSch->dl.maxCcchPerDlSf && + dlSf->schdCcchUe == cellSch->dl.maxCcchPerDlSf) + { + break; + } + else + { + + raCb = (RgSchRaCb *)(node->node); + node = node->next; + /* Address allocation for this UE for MSG 4 */ + /* Allocation for Msg4 */ + if ((rgSCHCmnMsg4Alloc(cell, raCb, allocInfo)) != ROK) + { + break; + } + } + } + RETVOID; +} + +#ifdef RGR_V1 +/** + * @brief This function scheduler for downlink CCCH messages. + * + * @details + * + * Function: rgSCHCmnDlCcchSduRetx + * Purpose: Scheduling for downlink CCCH + * + * Invoked by: Scheduler + * + * @param[in] RgSchCellCb *cell + * @param[out] RgSchCmnDlRbAllocInfo *allocInfo + * @return Void + * + **/ +#ifdef ANSI +PRIVATE Void rgSCHCmnDlCcchSduRetx +( +RgSchCellCb *cell, +RgSchCmnDlRbAllocInfo *allocInfo +) +#else +PRIVATE Void rgSCHCmnDlCcchSduRetx(cell, allocInfo) +RgSchCellCb *cell; +RgSchCmnDlRbAllocInfo *allocInfo; +#endif +{ + RgSchDlRbAlloc *rbAllocInfo; + CmLList *node; + RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell); + RgSchUeCb *ueCb; + RgSchDlHqProcCb *hqP; + U8 retxBw = 0; + RgSchCmnDlUe *ueDl; + RgSchDlSf *dlSf = allocInfo->ccchSduAlloc.ccchSduDlSf; + + TRC2(rgSCHCmnDlCcchSduRetx); + + node = cellSch->dl.ccchSduRetxLst.first; + while(node) + { + if(cellSch->dl.maxCcchPerDlSf && + dlSf->schdCcchUe == cellSch->dl.maxCcchPerDlSf) + { + break; + } + else + { + + hqP = (RgSchDlHqProcCb *)(node->node); + node = node->next; + + /* DwPts Scheduling Changes Start */ +#ifdef LTE_TDD + if (rgSCHCmnRetxAvoidTdd(allocInfo->ccchSduAlloc.ccchSduDlSf, + cell, hqP) == TRUE) + { + continue; + } +#endif + /* DwPts Scheduling Changes End */ + + if (hqP->tbInfo[0].dlGrnt.numRb > (dlSf->bw - dlSf->bwAssigned)) + { + break; + } + ueCb = (RgSchUeCb*)(hqP->hqE->ue); + ueDl = RG_SCH_CMN_GET_DL_UE(ueCb,cell); + + rbAllocInfo = RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ueCb, cell); + /* Fill RB Alloc Info */ + rbAllocInfo->dlSf = dlSf; + rbAllocInfo->tbInfo[0].bytesReq = hqP->tbInfo[0].ccchSchdInfo.totBytes; + rbAllocInfo->rbsReq = hqP->tbInfo[0].dlGrnt.numRb; + /* Fix : syed iMcs setting did not correspond to RETX */ + RG_SCH_CMN_GET_MCS_FOR_RETX((&hqP->tbInfo[0]), + rbAllocInfo->tbInfo[0].imcs); + rbAllocInfo->rnti = ueCb->ueId; + rbAllocInfo->tbInfo[0].noLyr = hqP->tbInfo[0].numLyrs; + /* Fix : syed Copying info in entirety without depending on stale TX information */ + rbAllocInfo->tbInfo[0].tbCb = &hqP->tbInfo[0]; + rbAllocInfo->tbInfo[0].schdlngForTb = TRUE; + /* Fix : syed Assigning proc to scratchpad */ + ueDl->proc = hqP; + + retxBw += rbAllocInfo->rbsReq; + + cmLListAdd2Tail(&allocInfo->ccchSduAlloc.ccchSduRetxLst, \ + &hqP->reqLnk); + hqP->reqLnk.node = (PTR)hqP; + dlSf->schdCcchUe++; + } + } + dlSf->bwAssigned += retxBw; + RETVOID; +} +#endif + +/** + * @brief This function scheduler for downlink CCCH messages. + * + * @details + * + * Function: rgSCHCmnDlCcchRetx + * Purpose: Scheduling for downlink CCCH + * + * Invoked by: Scheduler + * + * @param[in] RgSchCellCb *cell + * @param[out] RgSchCmnDlRbAllocInfo *allocInfo + * @return Void + * + **/ +#ifdef ANSI +PRIVATE Void rgSCHCmnDlCcchRetx +( +RgSchCellCb *cell, +RgSchCmnDlRbAllocInfo *allocInfo +) +#else +PRIVATE Void rgSCHCmnDlCcchRetx(cell, allocInfo) +RgSchCellCb *cell; +RgSchCmnDlRbAllocInfo *allocInfo; +#endif +{ + CmLList *node; + RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell); + RgSchRaCb *raCb; + RgSchDlHqProcCb *hqP; + U8 retxBw = 0; + RgSchDlSf *dlSf = allocInfo->msg4Alloc.msg4DlSf; + + TRC2(rgSCHCmnDlCcchRetx); + + node = cellSch->dl.msg4RetxLst.first; + while(node) + { + if(cellSch->dl.maxCcchPerDlSf && + dlSf->schdCcchUe == cellSch->dl.maxCcchPerDlSf) + { + break; + } + else + { + hqP = (RgSchDlHqProcCb *)(node->node); + + node = node->next; + + /* DwPts Scheduling Changes Start */ +#ifdef LTE_TDD + if (rgSCHCmnRetxAvoidTdd(allocInfo->msg4Alloc.msg4DlSf, + cell, hqP) == TRUE) + { + continue; + } +#endif + /* DwPts Scheduling Changes End */ + + if (hqP->tbInfo[0].dlGrnt.numRb > (dlSf->bw - dlSf->bwAssigned)) + { + break; + } + raCb = (RgSchRaCb*)(hqP->hqE->raCb); + /* Fill RB Alloc Info */ + raCb->rbAllocInfo.dlSf = dlSf; + raCb->rbAllocInfo.tbInfo[0].bytesReq = hqP->tbInfo[0].ccchSchdInfo.totBytes; + raCb->rbAllocInfo.rbsReq = hqP->tbInfo[0].dlGrnt.numRb; + /* Fix : syed iMcs setting did not correspond to RETX */ + RG_SCH_CMN_GET_MCS_FOR_RETX((&hqP->tbInfo[0]), + raCb->rbAllocInfo.tbInfo[0].imcs); + raCb->rbAllocInfo.rnti = raCb->tmpCrnti; + raCb->rbAllocInfo.tbInfo[0].noLyr = hqP->tbInfo[0].numLyrs; + /* Fix; syed Copying info in entirety without depending on stale TX information */ + raCb->rbAllocInfo.tbInfo[0].tbCb = &hqP->tbInfo[0]; + raCb->rbAllocInfo.tbInfo[0].schdlngForTb = TRUE; + + retxBw += raCb->rbAllocInfo.rbsReq; + + cmLListAdd2Tail(&allocInfo->msg4Alloc.msg4RetxLst, \ + &hqP->reqLnk); + hqP->reqLnk.node = (PTR)hqP; + dlSf->schdCcchUe++; + } + } + dlSf->bwAssigned += retxBw; + RETVOID; +} + + +/** + * @brief This function implements scheduler DL allocation for + * for broadcast (on PDSCH) and paging. + * + * @details + * + * Function: rgSCHCmnDlBcchPcch + * Purpose: This function implements scheduler for DL allocation + * for broadcast (on PDSCH) and paging. + * + * Invoked by: Scheduler + * + * @param[in] RgSchCellCb* cell + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PRIVATE Void rgSCHCmnDlBcchPcch +( +RgSchCellCb *cell, +RgSchCmnDlRbAllocInfo *allocInfo, +RgInfSfAlloc *subfrmAlloc +) +#else +PRIVATE Void rgSCHCmnDlBcchPcch(cell, allocInfo, subfrmAlloc) +RgSchCellCb *cell; +RgSchCmnDlRbAllocInfo *allocInfo; +RgInfSfAlloc *subfrmAlloc; +#endif +{ + CmLteTimingInfo frm; + RgSchDlSf *sf; + RgSchClcDlLcCb *pcch; + RgSchClcBoRpt *bo; +#ifndef RGR_SI_SCH + Bool valid; + RgSchClcDlLcCb *bcch, *bch; +#endif/*RGR_SI_SCH*/ + + + TRC2(rgSCHCmnDlBcchPcch); + + frm = cell->crntTime; +#ifdef LTEMAC_HDFDD + /* For HDFDD we need scheduling information at least RG_SCH_CMN_DL_DELTA + + RG_SCH_CMN_HARQ_INTERVAL (7) subframes ahead */ + RGSCH_INCR_SUB_FRAME(frm, RG_SCH_CMN_DL_DELTA + RG_SCH_CMN_HARQ_INTERVAL); +#else + RGSCH_INCR_SUB_FRAME(frm, RG_SCH_CMN_DL_DELTA); +#endif + + /* Compute the subframe for which allocation is being made */ + /* essentially, we need pointer to the dl frame for this subframe */ + sf = rgSCHUtlSubFrmGet(cell, frm); + + +#ifndef RGR_SI_SCH + bch = rgSCHDbmGetBcchOnBch(cell); +#if (ERRCLASS & ERRCLS_DEBUG) + if (bch == NULLP) + { + RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,"BCCH on BCH is not configured"); + RETVOID; + } +#endif + if (bch->boLst.first != NULLP) + { + bo = (RgSchClcBoRpt *)(bch->boLst.first->node); + if (RGSCH_TIMEINFO_SAME(frm, bo->timeToTx)) + { + sf->bch.tbSize = bo->bo; + cmLListDelFrm(&bch->boLst, bch->boLst.first); + /* ccpu00117052 - MOD - Passing double pointer + for proper NULLP assignment*/ + rgSCHUtlFreeSBuf(cell->instIdx, (Data **)&bo, sizeof(*bo)); + rgSCHUtlFillRgInfCmnLcInfo(sf, subfrmAlloc, bch->lcId,TRUE); + } + } + else + { + if ((frm.sfn % 4 == 0) && (frm.subframe == 0)) + { + } + } + + allocInfo->bcchAlloc.schdFirst = FALSE; + bcch = rgSCHDbmGetFirstBcchOnDlsch(cell); +#if (ERRCLASS & ERRCLS_DEBUG) + if (bcch == NULLP) + { + RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,"BCCH on DLSCH is not configured"); + RETVOID; + } +#endif + if (bcch->boLst.first != NULLP) + { + bo = (RgSchClcBoRpt *)(bcch->boLst.first->node); + + if (RGSCH_TIMEINFO_SAME(frm, bo->timeToTx)) + { + allocInfo->bcchAlloc.schdFirst = TRUE; + /* Time to perform allocation for this BCCH transmission */ + rgSCHCmnClcAlloc(cell, sf, bcch, RGSCH_SI_RNTI, allocInfo); + } + } + + if(!allocInfo->bcchAlloc.schdFirst) + { + CmLList *lnk; + bcch = rgSCHDbmGetSecondBcchOnDlsch(cell); +#if (ERRCLASS & ERRCLS_DEBUG) + if (bcch == NULLP) + { + RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,"BCCH on DLSCH is not configured"); + RETVOID; + } +#endif + lnk = bcch->boLst.first; + while (lnk != NULLP) + { + bo = (RgSchClcBoRpt *)(lnk->node); + lnk = lnk->next; + valid = rgSCHCmnChkInWin(frm, bo->timeToTx, bo->maxTimeToTx); + + if(valid) + { + bo->i = RGSCH_CALC_SF_DIFF(frm, bo->timeToTx); + /* Time to perform allocation for this BCCH transmission */ + rgSCHCmnClcAlloc(cell, sf, bcch, RGSCH_SI_RNTI, allocInfo); + break; + } + else + { + valid = rgSCHCmnChkPastWin(frm, bo->maxTimeToTx); + if(valid) + { + cmLListDelFrm(&bcch->boLst, &bo->boLstEnt); + /* ccpu00117052 - MOD - Passing double pointer + for proper NULLP assignment*/ + rgSCHUtlFreeSBuf(cell->instIdx, (Data **)&bo, + sizeof(RgSchClcBoRpt)); + } + } + } + } +#else + rgSCHDlSiSched(cell, allocInfo, subfrmAlloc); +#endif/*RGR_SI_SCH*/ + + pcch = rgSCHDbmGetPcch(cell); +#ifdef ERRCLS_KW + if (pcch == NULLP) + { + RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,"PCCH on DLSCH is not configured"); + RETVOID; + } +#endif + if (pcch->boLst.first != NULLP) + { + bo = (RgSchClcBoRpt *)(pcch->boLst.first->node); + + if (RGSCH_TIMEINFO_SAME(frm, bo->timeToTx)) + { + /* Time to perform allocation for this PCCH transmission */ + rgSCHCmnClcAlloc(cell, sf, pcch, RGSCH_P_RNTI, allocInfo); + } + } + RETVOID; +} + +/* +* +* Fun: rgSCHCmnChkInWin +* +* Desc: This function checks if frm occurs in window +* +* Ret: TRUE - if in window +* FALSE - otherwise +* +* Notes: None +* +* File: rg_sch_cmn.c +* +*/ +#ifdef ANSI +PUBLIC Bool rgSCHCmnChkInWin +( +CmLteTimingInfo frm, +CmLteTimingInfo start, +CmLteTimingInfo end +) +#else +PUBLIC Bool rgSCHCmnChkInWin(frm, start, end) +CmLteTimingInfo frm; +CmLteTimingInfo start; +CmLteTimingInfo end; +#endif +{ + Bool inWin = FALSE; + + TRC2(rgSCHCmnChkInWin); + + if (end.sfn > start.sfn) + { + if (frm.sfn > start.sfn + || (frm.sfn == start.sfn && frm.subframe >= start.subframe)) + { + if (frm.sfn < end.sfn +#ifdef EMTC_ENABLE + || (frm.sfn == end.sfn && frm.subframe <= end.subframe)) +#else + || (frm.sfn == end.sfn && frm.subframe <= start.subframe)) +#endif + { + inWin = TRUE; + } + } + } + /* Testing for wrap around, sfn wraparound check should be enough */ + else if (end.sfn < start.sfn) + { + if (frm.sfn > start.sfn + || (frm.sfn == start.sfn && frm.subframe >= start.subframe)) + { + inWin = TRUE; + } + else + { + if (frm.sfn < end.sfn + || (frm.sfn == end.sfn && frm.subframe <= end.subframe)) + { + inWin = TRUE; + } + } + } + else /* start.sfn == end.sfn */ + { + if (frm.sfn == start.sfn + && (frm.subframe >= start.subframe + && frm.subframe <= end.subframe)) + { + inWin = TRUE; + } + } + + RETVALUE(inWin); +} /* end of rgSCHCmnChkInWin*/ + +/* +* +* Fun: rgSCHCmnChkPastWin +* +* Desc: This function checks if frm has gone past window edge +* +* Ret: TRUE - if past window edge +* FALSE - otherwise +* +* Notes: None +* +* File: rg_sch_cmn.c +* +*/ +#ifdef ANSI +PUBLIC Bool rgSCHCmnChkPastWin +( +CmLteTimingInfo frm, +CmLteTimingInfo end +) +#else +PUBLIC Bool rgSCHCmnChkPastWin(frm, end) +CmLteTimingInfo frm; +CmLteTimingInfo end; +#endif +{ + CmLteTimingInfo refFrm = end; + Bool pastWin; + + TRC2(rgSCHCmnChkPastWin); + + RGSCH_INCR_FRAME(refFrm.sfn); + RGSCH_INCR_SUB_FRAME(end, 1); + pastWin = rgSCHCmnChkInWin(frm, end, refFrm); + + RETVALUE(pastWin); +} /* end of rgSCHCmnChkPastWin*/ + +/** + * @brief This function implements allocation of the resources for common + * channels BCCH, PCCH. + * + * @details + * + * Function: rgSCHCmnClcAlloc + * Purpose: This function implements selection of number of RBs based + * the allowed grant for the service. It is also responsible + * for selection of MCS for the transmission. + * + * Invoked by: Scheduler + * + * @param[in] RgSchCellCb *cell, + * @param[in] RgSchDlSf *sf, + * @param[in] RgSchClcDlLcCb *lch, + * @param[in] U16 rnti, + * @param[out] RgSchCmnDlRbAllocInfo *allocInfo + * @return Void + * + **/ +#ifdef ANSI +PRIVATE Void rgSCHCmnClcAlloc +( +RgSchCellCb *cell, +RgSchDlSf *sf, +RgSchClcDlLcCb *lch, +U16 rnti, +RgSchCmnDlRbAllocInfo *allocInfo +) +#else +PRIVATE Void rgSCHCmnClcAlloc(cell, sf, lch, rnti, allocInfo) +RgSchCellCb *cell; +RgSchDlSf *sf; +RgSchClcDlLcCb *lch; +U16 rnti; +RgSchCmnDlRbAllocInfo *allocInfo; +#endif +{ + RgSchCmnDlCell *cellDl = RG_SCH_CMN_GET_DL_CELL(cell); + RgSchClcBoRpt *bo; + U32 rb=0; + U8 mcs; + U32 tbs; +#ifdef LTE_TDD + U8 lostRe; + U8 cfi = cellDl->currCfi; +#endif + + TRC2(rgSCHCmnClcAlloc); + + bo = (RgSchClcBoRpt *)(lch->boLst.first->node); + + mcs = bo->mcs; + tbs = bo->bo; + /* rgSCHCmnClcRbAllocForFxdTb(cell, bo->bo, cellDl->ccchCqi, &rb);*/ + if(cellDl->bitsPerRb==0) + { + while ((rgTbSzTbl[0][0][rb]) < (tbs*8)) + { + rb++; + } + rb = rb+1; + } + else + { + rb = RGSCH_CEIL((tbs*8), cellDl->bitsPerRb); + } + /* DwPTS Scheduling Changes Start */ +#ifdef LTE_TDD + if(sf->sfType == RG_SCH_SPL_SF_DATA) + { + RGSCH_GET_SPS_SF_CFI(cell->bwCfg.dlTotalBw, cfi); + + /* Calculate the less RE's because of DwPTS */ + lostRe = rb * (cellDl->noResPerRb[cfi] - cellDl->numReDwPts[cfi]); + + /* Increase number of RBs in Spl SF to compensate for lost REs */ + rb += RGSCH_CEIL(lostRe, cellDl->numReDwPts[cfi]); + } +#endif + /* DwPTS Scheduling Changes End */ + /*ccpu00115595- end*/ + /* additional check to see if required RBs + * exceeds the available */ + if (rb > sf->bw - sf->bwAssigned) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,"BW allocation " + "failed for CRNTI:%d",rnti); + RETVOID; + } + + /* Update the subframe Allocated BW field */ + sf->bwAssigned = sf->bwAssigned + rb; + /* Fill in the BCCH/PCCH transmission info to the RBAllocInfo struct */ + if (rnti == RGSCH_SI_RNTI) + { + allocInfo->bcchAlloc.rnti = rnti; + allocInfo->bcchAlloc.dlSf = sf; + allocInfo->bcchAlloc.tbInfo[0].bytesReq = tbs; + allocInfo->bcchAlloc.rbsReq = rb; + allocInfo->bcchAlloc.tbInfo[0].imcs = mcs; + allocInfo->bcchAlloc.tbInfo[0].noLyr = 1; + /* Nprb indication at PHY for common Ch */ + allocInfo->bcchAlloc.nPrb = bo->nPrb; + } + else + { + allocInfo->pcchAlloc.rnti = rnti; + allocInfo->pcchAlloc.dlSf = sf; + allocInfo->pcchAlloc.tbInfo[0].bytesReq = tbs; + allocInfo->pcchAlloc.rbsReq = rb; + allocInfo->pcchAlloc.tbInfo[0].imcs = mcs; + allocInfo->pcchAlloc.tbInfo[0].noLyr = 1; + allocInfo->pcchAlloc.nPrb = bo->nPrb; + } + RETVOID; +} + + +/** + * @brief This function implements PDCCH allocation for common channels. + * + * @details + * + * Function: rgSCHCmnCmnPdcchAlloc + * Purpose: This function implements allocation of PDCCH for a UE. + * 1. This uses index 0 of PDCCH table for efficiency. + * 2. Uses he candidate PDCCH count for the aggr level. + * 3. Look for availability for each candidate and choose + * the first one available. + * + * Invoked by: Scheduler + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchDlSf *sf + * @return RgSchPdcch * + * -# NULLP when unsuccessful + * + **/ +#ifdef ANSI +PUBLIC RgSchPdcch *rgSCHCmnCmnPdcchAlloc +( +RgSchCellCb *cell, +RgSchDlSf *subFrm +) +#else +PUBLIC RgSchPdcch *rgSCHCmnCmnPdcchAlloc(cell, subFrm) +RgSchCellCb *cell; +RgSchDlSf *subFrm; +#endif +{ + U8 i; + CmLteAggrLvl aggrLvl; + RgSchPdcchInfo *pdcchInfo; + RgSchPdcch *pdcch; + RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell); + U8 numCce; /*store num CCEs based on + aggregation level */ + TRC2(rgSCHCmnCmnPdcchAlloc); + + aggrLvl = cellSch->dl.cmnChAggrLvl; + + pdcchInfo = &(subFrm->pdcchInfo); + + /* Updating the no. of nCce in pdcchInfo, in case if CFI + * was changed */ +#ifdef LTE_TDD + if(subFrm->nCce != pdcchInfo->nCce) + { + rgSCHUtlPdcchInit(cell, subFrm, subFrm->nCce); + } +#else + if(cell->nCce != pdcchInfo->nCce) + { + rgSCHUtlPdcchInit(cell, subFrm, cell->nCce); + } +#endif + + switch (aggrLvl) + { + case CM_LTE_AGGR_LVL4: + numCce = 4; + break; + case CM_LTE_AGGR_LVL8: + numCce = 8; + break; + case CM_LTE_AGGR_LVL16: + numCce = 16; + break; + default: + RETVALUE(NULLP); + } + + if (rgSCHUtlPdcchAvail(cell, pdcchInfo, aggrLvl, &pdcch) == TRUE) + { +#ifdef LTEMAC_SPS + pdcch->isSpsRnti = FALSE; +#endif + /* Increment the CCE used counter in the current subframe */ + subFrm->cceCnt += numCce; + pdcch->pdcchSearchSpace = RG_SCH_CMN_SEARCH_SPACE; + + RETVALUE(pdcch); + } + + /* PDCCH Allocation Failed, Mark cceFailure flag as TRUE */ + subFrm->isCceFailure = TRUE; + + RLOG_ARG1(L_DEBUG,DBG_CELLID,cell->cellId, + "PDCCH ERR: NO PDDCH AVAIL IN COMMON SEARCH SPACE aggr:%u", + aggrLvl); + RETVALUE(NULLP); +} + + +/** + * @brief This function implements bandwidth allocation for common channels. + * + * @details + * + * Function: rgSCHCmnClcRbAlloc + * Purpose: This function implements bandwith allocation logic + * for common control channels. + * + * Invoked by: Scheduler + * + * @param[in] RgSchCellCb* cell + * @param[in] U32 bo + * @param[in] U8 cqi + * @param[in] U8 *rb + * @param[in] U32 *tbs + * @param[in] U8 *mcs + * @param[in] RgSchDlSf *sf + * @return Void + * + **/ +#ifdef LTEMAC_SPS +#ifdef ANSI +PUBLIC Void rgSCHCmnClcRbAlloc +( +RgSchCellCb *cell, +U32 bo, +U8 cqi, +U8 *rb, +U32 *tbs, +U8 *mcs, +U8 *iTbs, +Bool isSpsBo, +RgSchDlSf *sf +) +#else +PUBLIC Void rgSCHCmnClcRbAlloc(cell, bo, cqi, rb, tbs, mcs, iTbs, isSpsBo) +RgSchCellCb *cell; +U32 bo; +U8 cqi; +U8 *rb; +U32 *tbs; +U8 *mcs; +U8 *iTbs; +Bool isSpsBo; +RgSchDlSf *sf; +#endif +#else +#ifdef ANSI +PRIVATE Void rgSCHCmnClcRbAlloc +( +RgSchCellCb *cell, +U32 bo, +U8 cqi, +U8 *rb, +U32 *tbs, +U8 *mcs, +RgSchDlSf *sf +) +#else +PRIVATE Void rgSCHCmnClcRbAlloc(cell, bo, cqi, rb, tbs, mcs, sf) +RgSchCellCb *cell; +U32 bo; +U8 cqi; +U8 *rb; +U32 *tbs; +U8 *mcs; +RgSchDlSf *sf; +#endif +#endif /* LTEMAC_SPS */ +{ + U8 iTbsVal; + RgSchCmnTbSzEff *effTbl; + U32 eff; + U32 noRes; + RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell); + U8 cfi = cellSch->dl.currCfi; + U32 tmpRb=0; + TRC2(rgSCHCmnClcRbAlloc); + + /* first get the CQI to MCS table and determine the number of RBs */ + effTbl = (RgSchCmnTbSzEff *)(cellSch->dl.cqiToEffTbl[0][cfi]); + iTbsVal = (*(RgSchCmnCqiToTbs *)(cellSch->dl.cqiToTbsTbl[0][cfi]))[cqi]; + RG_SCH_CMN_DL_TBS_TO_MCS(iTbsVal, *mcs); + + /* Efficiency is number of bits per 1024 REs */ + eff = (*effTbl)[iTbsVal]; + + /* Get the number of REs needed for this bo */ + noRes = ((bo * 8 * 1024) / eff ); + + /* Get the number of RBs needed for this transmission */ + /* Number of RBs = No of REs / No of REs per RB */ + tmpRb = RGSCH_CEIL(noRes, cellSch->dl.noResPerRb[cfi]); + /* KWORK_FIX: added check to see if rb has crossed maxRb*/ + RGSCH_ARRAY_BOUND_CHECK_WITH_POS_IDX(cell->instIdx, rgTbSzTbl[0][0], (tmpRb-1)); + if (tmpRb > cellSch->dl.maxDlBwPerUe) + { + tmpRb = cellSch->dl.maxDlBwPerUe; + } + while ((rgTbSzTbl[0][iTbsVal][tmpRb-1]/8) < bo && + (tmpRb < cellSch->dl.maxDlBwPerUe)) + { + tmpRb++; + RGSCH_ARRAY_BOUND_CHECK_WITH_POS_IDX(cell->instIdx, rgTbSzTbl[0][0], (tmpRb-1)); + } + *tbs = rgTbSzTbl[0][iTbsVal][tmpRb-1]/8; + *rb = (U8)tmpRb; + RG_SCH_CMN_DL_TBS_TO_MCS(iTbsVal, *mcs); + + RETVOID; +} + + + +/** + * @brief Scheduling for MSG4. + * + * @details + * + * Function: rgSCHCmnMsg4Alloc + * Purpose: Scheduling for MSG4 + * + * Invoked by: Scheduler + * + * @param[in] RgSchCellCb* cell + * @param[in] RgSchRaCb* raCb + * @param[out] RgSchCmnDlRbAllocInfo *allocInfo + * @return S16 + * + **/ +#ifdef ANSI +PRIVATE S16 rgSCHCmnMsg4Alloc +( +RgSchCellCb *cell, +RgSchRaCb *raCb, +RgSchCmnDlRbAllocInfo *allocInfo +) +#else +PRIVATE S16 rgSCHCmnMsg4Alloc(cell, raCb, allocInfo) +RgSchCellCb *cell; +RgSchRaCb *raCb; +RgSchCmnDlRbAllocInfo *allocInfo; +#endif +{ + RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell); + + TRC2(rgSCHCmnMsg4Alloc); + + /* SR_RACH_STATS : MSG4 TO BE TXED */ + rgNumMsg4ToBeTx++; + /* Return if subframe BW exhausted */ + if (allocInfo->msg4Alloc.msg4DlSf->bw <= + allocInfo->msg4Alloc.msg4DlSf->bwAssigned) + { + RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId , + "bw<=bwAssigned"); + RETVALUE(RFAILED); + } + + if (rgSCHDhmGetMsg4HqProc(raCb, cellSch->dl.time) != ROK) + { + RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId, + "rgSCHDhmGetMsg4HqProc failed"); + RETVALUE(RFAILED); + } + + raCb->rbAllocInfo.dlSf = allocInfo->msg4Alloc.msg4DlSf; + + if (rgSCHCmnMsg4DedAlloc(cell, raCb) != ROK) + { + /* Fix : syed Minor failure handling, release hqP if Unsuccessful */ + rgSCHDhmRlsHqpTb(raCb->dlHqE->msg4Proc, 0, FALSE); + RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId, + "rgSCHCmnMsg4DedAlloc failed."); + RETVALUE(RFAILED); + } + cmLListAdd2Tail(&allocInfo->msg4Alloc.msg4TxLst, &raCb->dlHqE->msg4Proc->reqLnk); + raCb->dlHqE->msg4Proc->reqLnk.node = (PTR)raCb->dlHqE->msg4Proc; + allocInfo->msg4Alloc.msg4DlSf->schdCcchUe++; + + RETVALUE(ROK); +} + + +/** + * @brief This function implements PDCCH allocation for an UE. + * + * @details + * + * Function: PdcchAlloc + * Purpose: This function implements allocation of PDCCH for an UE. + * 1. Get the aggregation level for the CQI of the UE. + * 2. Get the candidate PDCCH count for the aggr level. + * 3. Look for availability for each candidate and choose + * the first one available. + * + * Invoked by: Scheduler + * + * @param[in] cell + * @param[in] subFrm + * @param[in] cqi + * @param[in] dciFrmt + * @return RgSchPdcch * + * -# NULLP when unsuccessful + * + **/ +#ifdef ANSI +PUBLIC RgSchPdcch *rgSCHCmnPdcchAlloc +( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgSchDlSf *subFrm, +U8 cqi, +TfuDciFormat dciFrmt, +Bool isDtx +) +#else +PUBLIC RgSchPdcch *rgSCHCmnPdcchAlloc(cell, subFrm, cqi, dciFrmt, isDtx) +RgSchCellCb *cell; +RgSchUeCb *ue; +RgSchDlSf *subFrm; +U8 cqi; +TfuDciFormat dciFrmt; +Bool isDtx; +#endif +{ + CmLteAggrLvl aggrLvl; + RgSchPdcchInfo *pdcchInfo; + RgSchPdcch *pdcch; + U8 numxREGs; + + TRC2(rgSCHCmnPdcchAlloc); + + /* 3.1 consider the selected DCI format size in determining the + * aggregation level */ + //TODO_SID Need to update. Currently using 4 aggregation level + aggrLvl = CM_LTE_AGGR_LVL2;//cellSch->dciAggrLvl[cqi][dciFrmt]; + +#ifdef LTE_ADV + if((dciFrmt == TFU_DCI_FORMAT_1A) && + ((ue) && (ue->allocCmnUlPdcch)) ) + { + pdcch = rgSCHCmnCmnPdcchAlloc(cell, subFrm); + /* Since CRNTI Scrambled */ + if(NULLP != pdcch) + { + pdcch->dciNumOfBits = ue->dciSize.cmnSize[dciFrmt]; + // prc_trace_format_string(PRC_TRACE_GROUP_PS, PRC_TRACE_INFO_LOW,"Forcing alloc in CMN search spc size %d fmt %d \n", + // pdcch->dciNumOfBits, dciFrmt); + } + RETVALUE(pdcch); + } +#endif + + /* Incrementing aggrLvl by 1 if it not AGGR_LVL8(MAX SIZE) + * inorder to increse the redudancy bits for better decoding of UE */ + if (isDtx) + { + if (aggrLvl != CM_LTE_AGGR_LVL16) + { + switch(aggrLvl) + { + case CM_LTE_AGGR_LVL2: + aggrLvl = CM_LTE_AGGR_LVL4; + break; + case CM_LTE_AGGR_LVL4: + aggrLvl = CM_LTE_AGGR_LVL8; + break; + case CM_LTE_AGGR_LVL8: + aggrLvl = CM_LTE_AGGR_LVL16; + break; + default: + break; + } + /* aggrLvl += 1; */ + } + } + + pdcchInfo = &subFrm->pdcchInfo; + + /* Updating the no. of nCce in pdcchInfo, in case if CFI + * was changed */ +#ifdef LTE_TDD + if(subFrm->nCce != pdcchInfo->nCce) + { + rgSCHUtlPdcchInit(cell, subFrm, subFrm->nCce); + } +#else + if(cell->nCce != pdcchInfo->nCce) + { + rgSCHUtlPdcchInit(cell, subFrm, cell->nCce); + } +#endif + + if (pdcchInfo->nCce < (1 << (aggrLvl - 1))) + { + /* PDCCH Allocation Failed, Mark cceFailure flag as TRUE */ + subFrm->isCceFailure = TRUE; + RLOG_ARG1(L_DEBUG,DBG_CELLID,cell->cellId, + "PDCCH ERR: NO PDDCH AVAIL IN UE SEARCH SPACE :aggr(%u)", + aggrLvl); + + RETVALUE(NULLP); + } + + if (rgSCHUtlPdcchAvail(cell, pdcchInfo, aggrLvl, &pdcch) == TRUE) + { + /* SR_RACH_STATS : Reset isTBMsg4 */ + pdcch->dci.u.format1aInfo.t.pdschInfo.isTBMsg4= FALSE; + pdcch->dci.u.format0Info.isSrGrant = FALSE; +#ifdef LTEMAC_SPS + pdcch->isSpsRnti = FALSE; +#endif + /* Increment the CCE used counter in the current subframe */ + subFrm->cceCnt += aggrLvl; + pdcch->pdcchSearchSpace = RG_SCH_UE_SPECIFIC_SEARCH_SPACE; + if (ue != NULLP) + { +#ifdef LTE_ADV + if (ue->cell != cell) + { + /* Secondary Cell */ + //pdcch->dciNumOfBits = ue->dciSize.noUlCcSize[dciFrmt]; + pdcch->dciNumOfBits = MAX_5GTF_DCIA1B1_SIZE; + } + else +#endif + { + //pdcch->dciNumOfBits = ue->dciSize.dedSize[dciFrmt]; + //TODO_SID Need to update dci size. + pdcch->dciNumOfBits = MAX_5GTF_DCIA1B1_SIZE; + } + } + else + { + /* MSG4 */ + pdcch->dciNumOfBits = cell->dciSize.size[dciFrmt]; + } + RETVALUE(pdcch); + } + + /* PDCCH Allocation Failed, Mark cceFailure flag as TRUE */ + subFrm->isCceFailure = TRUE; + + RLOG_ARG1(L_DEBUG,DBG_CELLID,cell->cellId, + "PDCCH ERR: NO PDDCH AVAIL IN UE SEARCH SPACE :aggr(%u)", + aggrLvl); + RETVALUE(NULLP); +} + +#ifdef RGR_V1 +/** + * @brief This function implements BW allocation for CCCH SDU + * + * @details + * + * Function: rgSCHCmnCcchSduDedAlloc + * Purpose: Downlink bandwidth Allocation for CCCH SDU. + * + * Invoked by: Scheduler + * + * @param[in] RgSchCellCb* cell + * @param[out] RgSchUeCb *ueCb + * @return S16 + * + **/ +#ifdef ANSI +PRIVATE S16 rgSCHCmnCcchSduDedAlloc +( +RgSchCellCb *cell, +RgSchUeCb *ueCb +) +#else +PRIVATE S16 rgSCHCmnCcchSduDedAlloc(cell, ueCb) +RgSchCellCb *cell; +RgSchUeCb *ueCb; +#endif +{ + RgSchDlHqEnt *hqE = NULLP; + U32 effBo; + RgSchDlRbAlloc *rbAllocinfo = NULLP; + RgSchCmnDlCell *cellDl = RG_SCH_CMN_GET_DL_CELL(cell); + U8 iTbs; + U8 numRb; +#ifdef LTE_TDD + U8 cfi = cellDl->currCfi; +#endif + + TRC2(rgSCHCmnCcchSduDedAlloc); + + rbAllocinfo = RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ueCb, cell); + + effBo = ueCb->dlCcchInfo.bo + RGSCH_CCCH_SDU_HDRSIZE; + +#ifndef LTEMAC_SPS + rgSCHCmnClcRbAlloc(cell, effBo, cellDl->ccchCqi, &rbAllocinfo->rbsReq, \ + &rbAllocinfo->tbInfo[0].bytesReq, + &rbAllocinfo->tbInfo[0].imcs, rbAllocinfo->dlSf); +#else /* LTEMAC_SPS */ + rgSCHCmnClcRbAlloc(cell, effBo, cellDl->ccchCqi, &rbAllocinfo->rbsReq, \ + &rbAllocinfo->tbInfo[0].bytesReq,\ + &rbAllocinfo->tbInfo[0].imcs, &iTbs, FALSE, + rbAllocinfo->dlSf); +#endif /* LTEMAC_SPS */ + + iTbs = 0; + /* Cannot exceed the total number of RBs in the cell */ + if ((S16)rbAllocinfo->rbsReq > ((S16)(rbAllocinfo->dlSf->bw - \ + rbAllocinfo->dlSf->bwAssigned))) + { + /* Check if atleast one allocation was possible. + This may be the case where the Bw is very less and + with the configured CCCH CQI, CCCH SDU exceeds the min Bw */ + if (rbAllocinfo->dlSf->bwAssigned == 0) + { + numRb = rbAllocinfo->dlSf->bw; + RG_SCH_CMN_DL_MCS_TO_TBS(rbAllocinfo->tbInfo[0].imcs, iTbs); + while (rgTbSzTbl[0][++iTbs][numRb-1]/8 < effBo) + { + iTbs++; + } + rbAllocinfo->rbsReq = numRb; + rbAllocinfo->tbInfo[0].bytesReq = rgTbSzTbl[0][iTbs][numRb-1]/8; + /* DwPTS Scheduling Changes Start */ +#ifdef LTE_TDD + if(rbAllocinfo->dlSf->sfType == RG_SCH_SPL_SF_DATA) + { + rbAllocinfo->tbInfo[0].bytesReq = + rgSCHCmnCalcDwPtsTbSz(cell, effBo, &numRb, &iTbs, 1,cfi); + } +#endif + /* DwPTS Scheduling Changes End */ + RG_SCH_CMN_DL_TBS_TO_MCS(iTbs, rbAllocinfo->tbInfo[0].imcs); + } + else + { + RETVALUE(RFAILED); + } + } + + /* Update the subframe Allocated BW field */ + rbAllocinfo->dlSf->bwAssigned = rbAllocinfo->dlSf->bwAssigned + \ + rbAllocinfo->rbsReq; + hqE = RG_SCH_CMN_GET_UE_HQE(ueCb, cell); + rbAllocinfo->tbInfo[0].tbCb = &hqE->ccchSduProc->tbInfo[0]; + rbAllocinfo->rnti = ueCb->ueId; + rbAllocinfo->tbInfo[0].noLyr = 1; + + RETVALUE(ROK); +} +#endif + +/** + * @brief This function implements BW allocation for MSG4 + * + * @details + * + * Function: rgSCHCmnMsg4DedAlloc + * Purpose: Downlink bandwidth Allocation for MSG4. + * + * Invoked by: Scheduler + * + * @param[in] RgSchCellCb* cell + * @param[out] RgSchRaCb *raCb + * @return S16 + * + **/ +#ifdef ANSI +PRIVATE S16 rgSCHCmnMsg4DedAlloc +( +RgSchCellCb *cell, +RgSchRaCb *raCb +) +#else +PRIVATE S16 rgSCHCmnMsg4DedAlloc(cell, raCb) +RgSchCellCb *cell; +RgSchRaCb *raCb; +#endif +{ + U32 effBo; + RgSchDlRbAlloc *rbAllocinfo = &raCb->rbAllocInfo; + U8 iTbs; + U8 numRb; +#ifdef LTE_TDD + RgSchCmnDlCell *cellDl = RG_SCH_CMN_GET_DL_CELL(cell); + U8 cfi = cellDl->currCfi; +#endif + + TRC2(rgSCHCmnMsg4DedAlloc); + + effBo = raCb->dlCcchInfo.bo + RGSCH_MSG4_HDRSIZE + RGSCH_CONT_RESID_SIZE; + +#ifndef LTEMAC_SPS + rgSCHCmnClcRbAlloc(cell, effBo, raCb->ccchCqi, &rbAllocinfo->rbsReq, \ + &rbAllocinfo->tbInfo[0].bytesReq,\ + &rbAllocinfo->tbInfo[0].imcs, rbAllocinfo->dlSf); +#else /* LTEMAC_SPS */ + rgSCHCmnClcRbAlloc(cell, effBo, raCb->ccchCqi, &rbAllocinfo->rbsReq, \ + &rbAllocinfo->tbInfo[0].bytesReq,\ + &rbAllocinfo->tbInfo[0].imcs, &iTbs, FALSE, + rbAllocinfo->dlSf); +#endif /* LTEMAC_SPS */ + + iTbs = 0; + /* Cannot exceed the total number of RBs in the cell */ + if ((S16)rbAllocinfo->rbsReq > ((S16)(rbAllocinfo->dlSf->bw - \ + rbAllocinfo->dlSf->bwAssigned))) + { + /* Check if atleast one allocation was possible. + This may be the case where the Bw is very less and + with the configured CCCH CQI, CCCH SDU exceeds the min Bw */ + if (rbAllocinfo->dlSf->bwAssigned == 0) + { + numRb = rbAllocinfo->dlSf->bw; + RG_SCH_CMN_DL_MCS_TO_TBS(rbAllocinfo->tbInfo[0].imcs, iTbs); + while (rgTbSzTbl[0][++iTbs][numRb-1]/8 < effBo) + { + iTbs++; + } + rbAllocinfo->rbsReq = numRb; + rbAllocinfo->tbInfo[0].bytesReq = rgTbSzTbl[0][iTbs][numRb-1]/8; + /* DwPTS Scheduling Changes Start */ +#ifdef LTE_TDD + if(rbAllocinfo->dlSf->sfType == RG_SCH_SPL_SF_DATA) + { + rbAllocinfo->tbInfo[0].bytesReq = + rgSCHCmnCalcDwPtsTbSz(cell, effBo, &numRb, &iTbs, 1, cfi); + } +#endif + /* DwPTS Scheduling Changes End */ + RG_SCH_CMN_DL_TBS_TO_MCS(iTbs, rbAllocinfo->tbInfo[0].imcs); + } + else + { + RETVALUE(RFAILED); + } + } + + /* Update the subframe Allocated BW field */ + rbAllocinfo->dlSf->bwAssigned = rbAllocinfo->dlSf->bwAssigned + \ + rbAllocinfo->rbsReq; + rbAllocinfo->rnti = raCb->tmpCrnti; + rbAllocinfo->tbInfo[0].tbCb = &raCb->dlHqE->msg4Proc->tbInfo[0]; + rbAllocinfo->tbInfo[0].schdlngForTb = TRUE; + rbAllocinfo->tbInfo[0].noLyr = 1; + + RETVALUE(ROK); +} + +#ifdef LTE_TDD +/** + * @brief This function implements scheduling for RA Response. + * + * @details + * + * Function: rgSCHCmnDlRaRsp + * Purpose: Downlink scheduling for RA responses. + * + * Invoked by: Scheduler + * + * @param[in] RgSchCellCb* cell + * @return Void + * + **/ +#ifdef ANSI +PRIVATE Void rgSCHCmnDlRaRsp +( +RgSchCellCb *cell, +RgSchCmnDlRbAllocInfo *allocInfo +) +#else +PRIVATE Void rgSCHCmnDlRaRsp(cell, allocInfo) +RgSchCellCb *cell; +RgSchCmnDlRbAllocInfo *allocInfo; +#endif +{ + CmLteTimingInfo frm; + CmLteTimingInfo schFrm; + RgSchDlSf *subFrm; + U16 rarnti; + U8 i; + U8 noRaRnti=0; + U8 raIdx; + RgSchTddRachRspLst *rachRsp; + U8 ulDlCfgIdx = cell->ulDlCfgIdx; + U8 sfnIdx; + U8 subfrmIdx; + U16 rntiIdx=0; + TRC2(rgSCHCmnDlRaRsp); + + frm = cell->crntTime; + RGSCH_INCR_SUB_FRAME(frm, RG_SCH_CMN_DL_DELTA); + + /* Compute the subframe for which allocation is being made */ + /* essentially, we need pointer to the dl frame for this subframe */ + subFrm = rgSCHUtlSubFrmGet(cell, frm); + + /* Get the RACH Response scheduling related information + * for the subframe with RA index */ + raIdx = rgSchTddNumDlSubfrmTbl[ulDlCfgIdx][frm.subframe]-1; + + rachRsp = &cell->rachRspLst[raIdx]; + + for(sfnIdx = 0; sfnIdx < rachRsp->numRadiofrms; sfnIdx++) + { + /* For all scheduled RACH Responses in SFNs */ + schFrm = frm; + RG_SCH_CMN_DECR_FRAME(schFrm.sfn, rachRsp->rachRsp[sfnIdx].sfnOffset); + /* For all scheduled RACH Responses in subframes */ + for(subfrmIdx = 0; + subfrmIdx < rachRsp->rachRsp[sfnIdx].numSubfrms; subfrmIdx++) + { + schFrm.subframe = rachRsp->rachRsp[sfnIdx].subframe[subfrmIdx]; + /* compute the last RA RNTI used in the previous subframe */ + raIdx = (((schFrm.sfn % cell->raInfo.maxRaSize) * \ + RGSCH_NUM_SUB_FRAMES * RGSCH_MAX_RA_RNTI_PER_SUBFRM) \ + + schFrm.subframe); + + /* For all RA RNTIs within a subframe */ + + for(i=0; (i < RGSCH_MAX_RA_RNTI_PER_SUBFRM) && \ + (noRaRnti < RGSCH_MAX_TDD_RA_RSP_ALLOC); i++) + { + rarnti = (schFrm.subframe + RGSCH_NUM_SUB_FRAMES*i + 1); + rntiIdx = (raIdx + RGSCH_NUM_SUB_FRAMES*i); + + if (cell->raInfo.raReqLst[rntiIdx].first != NULLP) + { + /* compute the next RA RNTI */ + if (rgSCHCmnRaRspAlloc(cell, subFrm, rntiIdx, + rarnti, noRaRnti, allocInfo) != ROK) + { + /* The resources are exhausted */ + break; + } + noRaRnti++; + } + } + noRaRnti=0; + } + } + + RETVOID; +} +#else +/** + * @brief This function implements scheduling for RA Response. + * + * @details + * + * Function: rgSCHCmnDlRaRsp + * Purpose: Downlink scheduling for RA responses. + * + * Invoked by: Scheduler + * + * @param[in] RgSchCellCb* cell + * @param[out] RgSchCmnDlRbAllocInfo *allocInfo + * @return Void + * + **/ +#ifdef ANSI +PRIVATE Void rgSCHCmnDlRaRsp //FDD +( +RgSchCellCb *cell, +RgSchCmnDlRbAllocInfo *allocInfo +) +#else +PRIVATE Void rgSCHCmnDlRaRsp(cell, allocInfo) +RgSchCellCb *cell; +RgSchCmnDlRbAllocInfo *allocInfo; +#endif +{ + CmLteTimingInfo frm; + CmLteTimingInfo winStartFrm; + RgSchDlSf *subFrm; + U8 winStartIdx; + U8 winGap; + U8 rarnti; + U8 raIdx; + RgSchCmnCell *sched; + U8 i,noRaRnti=0; + TRC2(rgSCHCmnDlRaRsp); + + frm = cell->crntTime; + RGSCH_INCR_SUB_FRAME(frm, RG_SCH_CMN_DL_DELTA); + + /* Compute the subframe for which allocation is being made */ + /* essentially, we need pointer to the dl frame for this subframe */ + subFrm = rgSCHUtlSubFrmGet(cell, frm); + sched = RG_SCH_CMN_GET_CELL(cell); + + /* ccpu00132523 - Window Start calculated by considering RAR window size, + * RAR Wait period, Subframes occuppied for respective preamble format*/ + winGap = (sched->dl.numRaSubFrms-1) + (cell->rachCfg.raWinSize-1) + +RGSCH_RARSP_WAIT_PERIOD; + + /* Window starting occassion is retrieved using the gap and tried to + * fit to the size of raReqLst array*/ + RGSCHDECRFRMCRNTTIME(frm, winStartFrm, winGap); + + //5G_TODO TIMING update. Need to check + winStartIdx = (winStartFrm.sfn & 1) * RGSCH_MAX_RA_RNTI+ winStartFrm.subframe; + + for(i = 0; ((i < cell->rachCfg.raWinSize) && (noRaRnti < RG_SCH_CMN_MAX_CMN_PDCCH)); i++) + { + raIdx = (winStartIdx + i) % RGSCH_RAREQ_ARRAY_SIZE; + + if (cell->raInfo.raReqLst[raIdx].first != NULLP) + { + allocInfo->raRspAlloc[noRaRnti].biEstmt = \ + (!i * RGSCH_ONE_BIHDR_SIZE); + rarnti = raIdx % RGSCH_MAX_RA_RNTI+ 1; + if (rgSCHCmnRaRspAlloc(cell, subFrm, raIdx, + rarnti, noRaRnti, allocInfo) != ROK) + { + /* The resources are exhausted */ + break; + } + /* ccpu00132523- If all the RAP ids are not scheduled then need not + * proceed for next RA RNTIs*/ + if(allocInfo->raRspAlloc[noRaRnti].numRapids < cell->raInfo.raReqLst[raIdx].count) + { + break; + } + noRaRnti++; /* Max of RG_SCH_CMN_MAX_CMN_PDCCH RARNTIs + for response allocation */ + } + } + RETVOID; +} +#endif + + +/** + * @brief This function allocates the resources for an RARNTI. + * + * @details + * + * Function: rgSCHCmnRaRspAlloc + * Purpose: Allocate resources to a RARNTI. + * 0. Allocate PDCCH for sending the response. + * 1. Locate the number of RA requests pending for the RARNTI. + * 2. Compute the size of data to be built. + * 3. Using common channel CQI, compute the number of RBs. + * + * Invoked by: Scheduler + * + * @param[in] RgSchCellCb *cell, + * @param[in] RgSchDlSf *subFrm, + * @param[in] U16 rarnti, + * @param[in] U8 noRaRnti + * @param[out] RgSchCmnDlRbAllocInfo *allocInfo + * @return S16 + * + **/ +#ifdef ANSI +PRIVATE S16 rgSCHCmnRaRspAlloc +( +RgSchCellCb *cell, +RgSchDlSf *subFrm, +U16 raIndex, +U16 rarnti, +U8 noRaRnti, +RgSchCmnDlRbAllocInfo *allocInfo +) +#else +PRIVATE S16 rgSCHCmnRaRspAlloc(cell,subFrm,raIndex,rarnti,noRaRnti,allocInfo) +RgSchCellCb *cell; +RgSchDlSf *subFrm; +U16 raIndex; +U16 rarnti; +U8 noRaRnti; +RgSchCmnDlRbAllocInfo *allocInfo; +#endif +{ + RgSchCmnDlCell *cellDl = RG_SCH_CMN_GET_DL_CELL(cell); + RgSchCmnUlCell *cellUl = RG_SCH_CMN_GET_UL_CELL(cell); + U16 noBytes; + U32 rb = 0; + U32 tbs; + /*ccpu00116700,ccpu00116708- Corrected the wrong type for mcs*/ + U8 mcs; + CmLListCp *reqLst; + /* RACH handling related changes */ + Bool isAlloc = FALSE; + static U8 schdNumRapid = 0; + U8 remNumRapid = 0; + U8 nPrb = 0; + S32 allwdTbSz = 0; +#ifdef LTE_TDD + U16 lostRe; + U8 cfi = cellDl->currCfi; +#endif + + TRC2(rgSCHCmnRaRspAlloc); +#ifndef RGR_V1 + UNUSED(cellUl); +#endif + + /* ccpu00132523: Resetting the schdRap Id count in every scheduling subframe*/ + if(noRaRnti == 0) + { + schdNumRapid = 0; + } + + + if (subFrm->bw == subFrm->bwAssigned) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId, + "bw == bwAssigned RARNTI:%d",rarnti); + RETVALUE(RFAILED); + } + + reqLst = &cell->raInfo.raReqLst[raIndex]; + if (reqLst->count == 0) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId, + "reqLst Count=0 RARNTI:%d",rarnti); + RETVALUE(RFAILED); + } + remNumRapid = reqLst->count; + +#ifdef RGR_V1 + /* Limit number of rach rsps to maxMsg3PerUlsf */ + if ( schdNumRapid+remNumRapid > cellUl->maxMsg3PerUlSf ) + { + remNumRapid = cellUl->maxMsg3PerUlSf-schdNumRapid; + } +#endif + + while (remNumRapid) + { + /* Try allocating for as many RAPIDs as possible */ + /* BI sub-header size to the tbSize requirement */ + noBytes = RGSCH_GET_RAR_BYTES(remNumRapid) +\ + allocInfo->raRspAlloc[noRaRnti].biEstmt; + if ((allwdTbSz = rgSCHUtlGetAllwdCchTbSz(noBytes*8, &nPrb, &mcs)) == -1) + { + remNumRapid--; + continue; + } + + /* rgSCHCmnClcRbAllocForFxdTb(cell, allwdTbSz/8, cellDl->ccchCqi, &rb);*/ + if(cellDl->bitsPerRb==0) + { + while ((rgTbSzTbl[0][0][rb]) <(U32) allwdTbSz) + { + rb++; + } + rb = rb+1; + } + else + { + rb = RGSCH_CEIL(allwdTbSz, cellDl->bitsPerRb); + } + /* DwPTS Scheduling Changes Start */ +#ifdef LTE_TDD + if (subFrm->sfType == RG_SCH_SPL_SF_DATA) + { + RGSCH_GET_SPS_SF_CFI(cell->bwCfg.dlTotalBw, cfi); + + /* Calculate the less RE's because of DwPTS */ + lostRe = rb * (cellDl->noResPerRb[cfi] - + cellDl->numReDwPts[cfi]); + + /* Increase number of RBs in Spl SF to compensate for lost REs */ + rb += RGSCH_CEIL(lostRe, cellDl->numReDwPts[cfi]); + } +#endif + /* DwPTS Scheduling Changes End */ + + /*ccpu00115595- end*/ + if (rb > subFrm->bw - subFrm->bwAssigned) + { + remNumRapid--; + continue; + } + /* Allocation succeeded for 'remNumRapid' */ + isAlloc = TRUE; + tbs = allwdTbSz/8; + printf("\n!!!RAR alloc noBytes:%u,allwdTbSz:%u,tbs:%u,rb:%u\n", + noBytes,allwdTbSz,tbs,rb); + break; + } + if (!isAlloc) + { + RLOG_ARG0(L_INFO,DBG_CELLID,cell->cellId,"BW alloc Failed"); + RETVALUE(RFAILED); + } + + subFrm->bwAssigned = subFrm->bwAssigned + rb; + + /* Fill AllocInfo structure */ + allocInfo->raRspAlloc[noRaRnti].rnti = rarnti; + allocInfo->raRspAlloc[noRaRnti].tbInfo[0].bytesReq = tbs; + allocInfo->raRspAlloc[noRaRnti].rbsReq = rb; + allocInfo->raRspAlloc[noRaRnti].dlSf = subFrm; + allocInfo->raRspAlloc[noRaRnti].tbInfo[0].imcs = mcs; + allocInfo->raRspAlloc[noRaRnti].raIndex = raIndex; + /* RACH changes for multiple RAPID handling */ + allocInfo->raRspAlloc[noRaRnti].numRapids = remNumRapid; + allocInfo->raRspAlloc[noRaRnti].nPrb = nPrb; + allocInfo->raRspAlloc[noRaRnti].tbInfo[0].noLyr = 1; + allocInfo->raRspAlloc[noRaRnti].vrbgReq = RGSCH_CEIL(nPrb,MAX_5GTF_VRBG_SIZE); + schdNumRapid += remNumRapid; + RETVALUE(ROK); +} + +/*********************************************************** + * + * Func : rgSCHCmnUlAllocFillRbInfo + * + * Desc : Fills the start RB and the number of RBs for + * uplink allocation. + * + * Ret : void + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PUBLIC Void rgSCHCmnUlAllocFillRbInfo +( +RgSchCellCb *cell, +RgSchUlSf *sf, +RgSchUlAlloc *alloc +) +#else +PUBLIC Void rgSCHCmnUlAllocFillRbInfo(cell, sf, alloc) +RgSchCellCb *cell; +RgSchUlSf *sf; +RgSchUlAlloc *alloc; +#endif +{ + RgSchCmnUlCell *cellUl = RG_SCH_CMN_GET_UL_CELL(cell); + RgSchCmnDlCell *cellDl = RG_SCH_CMN_GET_DL_CELL(cell); + U8 cfi = cellDl->currCfi; + + + TRC2(rgSCHCmnUlAllocFillRbInfo); + alloc->grnt.rbStart = (alloc->sbStart * cellUl->sbSize) + + cell->dynCfiCb.bwInfo[cfi].startRb; + + /* Num RBs = numSbAllocated * sbSize - less RBs in the last SB */ + alloc->grnt.numRb = (alloc->numSb * cellUl->sbSize); + + RETVOID; +} + +/** + * @brief Grant request for Msg3. + * + * @details + * + * Function : rgSCHCmnMsg3GrntReq + * + * This is invoked by downlink scheduler to request allocation + * for msg3. + * Steps: + * - Attempt to allocate msg3 in the current msg3 subframe + * Allocation attempt based on whether preamble is from group A + * and the value of MESSAGE_SIZE_GROUP_A + * - Link allocation with passed RNTI and msg3 HARQ process + * - Set the HARQ process ID (*hqProcIdRef) + * + * @param[in] RgSchCellCb *cell + * @param[in] CmLteRnti rnti + * @param[in] Bool preamGrpA + * @param[in] RgSchUlHqProcCb *hqProc + * @param[out] RgSchUlAlloc **ulAllocRef + * @param[out] U8 *hqProcIdRef + * @return Void + **/ +#ifdef ANSI +PRIVATE Void rgSCHCmnMsg3GrntReq +( +RgSchCellCb *cell, +CmLteRnti rnti, +Bool preamGrpA, +RgSchUlHqProcCb *hqProc, +RgSchUlAlloc **ulAllocRef, +U8 *hqProcIdRef +) +#else +PRIVATE Void rgSCHCmnMsg3GrntReq(cell, rnti, preamGrpA, hqProc, + ulAllocRef, hqProcIdRef) +RgSchCellCb *cell; +CmLteRnti rnti; +Bool preamGrpA; +RgSchUlHqProcCb *hqProc; +RgSchUlAlloc **ulAllocRef; +U8 *hqProcIdRef; +#endif +{ + RgSchCmnUlCell *cellUl = RG_SCH_CMN_GET_UL_CELL(cell); + RgSchUlSf *sf = &cellUl->ulSfArr[cellUl->msg3SchdIdx]; + RgSchUlHole *hole; + RgSchUlAlloc *alloc; + U8 iMcs; + U8 numSb; + + TRC2(rgSCHCmnMsg3GrntReq); + + *ulAllocRef = NULLP; + + /* Fix: ccpu00120610 Use remAllocs from subframe during msg3 allocation */ + if (*sf->allocCountRef >= cellUl->maxAllocPerUlSf) + { + RETVOID; + } + if (preamGrpA == FALSE) + { + numSb = cellUl->ra.prmblBNumSb; + iMcs = cellUl->ra.prmblBIMcs; + } + else + { + numSb = cellUl->ra.prmblANumSb; + iMcs = cellUl->ra.prmblAIMcs; + } + + if ((hole = rgSCHUtlUlHoleFirst(sf)) != NULLP) + { + if(*sf->allocCountRef == 0) + { + RgSchCmnDlCell *cellDl = RG_SCH_CMN_GET_DL_CELL(cell); + /* Reinitialize the hole */ + if (sf->holeDb->count == 1 && (hole->start == 0)) /* Sanity check of holeDb */ + { + hole->num = cell->dynCfiCb.bwInfo[cellDl->currCfi].numSb; + /* Re-Initialize available subbands because of CFI change*/ + hole->num = cell->dynCfiCb.bwInfo[cellDl->currCfi].numSb; + } + else + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId, + "Error! holeDb sanity check failed RNTI:%d",rnti); + } + } + if (numSb <= hole->num) + { + U8 iTbs; + alloc = rgSCHUtlUlAllocGetHole(sf, numSb, hole); + rgSCHCmnUlAllocFillRbInfo(cell, sf, alloc); + alloc->grnt.iMcs = iMcs; + alloc->grnt.iMcsCrnt = iMcs; + iTbs = rgSCHCmnUlGetITbsFrmIMcs(iMcs); + RGSCH_ARRAY_BOUND_CHECK(cell->instIdx, rgTbSzTbl[0], iTbs); + /* To include the length and ModOrder in DataRecp Req.*/ + alloc->grnt.datSz = rgTbSzTbl[0][iTbs][alloc->grnt.numRb-1] / 8; + RG_SCH_UL_MCS_TO_MODODR(iMcs, alloc->grnt.modOdr); + /* RACHO : setting nDmrs to 0 and UlDelaybit to 0*/ + alloc->grnt.nDmrs = 0; + alloc->grnt.hop = 0; + alloc->grnt.delayBit = 0; + alloc->grnt.isRtx = FALSE; + *ulAllocRef = alloc; + *hqProcIdRef = (cellUl->msg3SchdHqProcIdx); + hqProc->procId = *hqProcIdRef; + hqProc->ulSfIdx = (cellUl->msg3SchdIdx); + alloc->rnti = rnti; + alloc->ue = NULLP; + alloc->pdcch = FALSE; + alloc->forMsg3 = TRUE; + alloc->hqProc = hqProc; + rgSCHUhmNewTx(hqProc, (U8)(cell->rachCfg.maxMsg3Tx - 1), alloc); + //RLOG_ARG4(L_DEBUG,DBG_CELLID,cell->cellId, + printf( + "\nRNTI:%d MSG3 ALLOC proc(%p)procId(%d)schdIdx(%d)\n", + alloc->rnti, + ((PTR)alloc->hqProc), + alloc->hqProc->procId, + alloc->hqProc->ulSfIdx); + RLOG_ARG2(L_DEBUG,DBG_CELLID,cell->cellId, + "alloc(%p)maxMsg3Tx(%d)", + ((PTR)alloc), + cell->rachCfg.maxMsg3Tx); + } + } + + RETVOID; +} + + +/** + * @brief This function determines the allocation limits and + * parameters that aid in DL scheduling. + * + * @details + * + * Function: rgSCHCmnDlSetUeAllocLmt + * Purpose: This function determines the Maximum RBs + * a UE is eligible to get based on softbuffer + * limitation and cell->>>maxDlBwPerUe. The Codeword + * specific parameters like iTbs, eff and noLyrs + * are also set in this function. This function + * is called while UE configuration and UeDlCqiInd. + * + * Invoked by: Scheduler + * + * @param[in] RgSchCellCb *cellCb + * @param[in] RgSchCmnDlUe *ueDl + * @return Void + * + **/ +#ifdef ANSI +PRIVATE Void rgSCHCmnDlSetUeAllocLmt +( +RgSchCellCb *cell, +RgSchCmnDlUe *ueDl, +Bool isEmtcUe +) +#else +PRIVATE Void rgSCHCmnDlSetUeAllocLmt(cell, ueDl, isEmtcUe) +RgSchCellCb *cell; +RgSchCmnDlUe *ueDl; +Bool isEmtcUe; +#endif +{ + U8 modOrder; + U32 maxRb; + RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell); + U8 cfi = cellSch->dl.currCfi; + + TRC2(rgSCHCmnDlSetUeAllocLmt); + +#ifdef EMTC_ENABLE + if(TRUE == isEmtcUe) + { + /* ITbs for CW0 for 1 Layer Tx */ + ueDl->mimoInfo.cwInfo[0].iTbs[0] = (*(RgSchEmtcCmnCqiToTbs *)(cellSch->dl.emtcCqiToTbsTbl[0][cfi]))\ + [ueDl->mimoInfo.cwInfo[0].cqi]; + /* ITbs for CW0 for 2 Layer Tx */ + ueDl->mimoInfo.cwInfo[0].iTbs[1] = (*(RgSchEmtcCmnCqiToTbs *)(cellSch->dl.emtcCqiToTbsTbl[1][cfi]))\ + [ueDl->mimoInfo.cwInfo[0].cqi]; + /* Eff for CW0 for 1 Layer Tx */ + ueDl->mimoInfo.cwInfo[0].eff[0] = (*(RgSchCmnTbSzEff *)(cellSch->dl.cqiToEffTbl[0][cfi]))\ + [ueDl->mimoInfo.cwInfo[0].iTbs[0]]; + /* Eff for CW0 for 2 Layer Tx */ + ueDl->mimoInfo.cwInfo[0].eff[1] = (*(RgSchCmnTbSzEff *)(cellSch->dl.cqiToEffTbl[1][cfi]))\ + [ueDl->mimoInfo.cwInfo[0].iTbs[1]]; + + /* ITbs for CW1 for 1 Layer Tx */ + ueDl->mimoInfo.cwInfo[1].iTbs[0] = (*(RgSchEmtcCmnCqiToTbs *)(cellSch->dl.emtcCqiToTbsTbl[0][cfi]))\ + [ueDl->mimoInfo.cwInfo[1].cqi]; + /* ITbs for CW1 for 2 Layer Tx */ + ueDl->mimoInfo.cwInfo[1].iTbs[1] = (*(RgSchEmtcCmnCqiToTbs *)(cellSch->dl.emtcCqiToTbsTbl[1][cfi]))\ + [ueDl->mimoInfo.cwInfo[1].cqi]; + /* Eff for CW1 for 1 Layer Tx */ + ueDl->mimoInfo.cwInfo[1].eff[0] = (*(RgSchCmnTbSzEff *)(cellSch->dl.cqiToEffTbl[0][cfi]))\ + [ueDl->mimoInfo.cwInfo[1].iTbs[0]]; + /* Eff for CW1 for 2 Layer Tx */ + ueDl->mimoInfo.cwInfo[1].eff[1] = (*(RgSchCmnTbSzEff *)(cellSch->dl.cqiToEffTbl[1][cfi]))\ + [ueDl->mimoInfo.cwInfo[1].iTbs[1]]; + } + else +#endif + { + /* ITbs for CW0 for 1 Layer Tx */ + ueDl->mimoInfo.cwInfo[0].iTbs[0] = (*(RgSchCmnCqiToTbs *)(cellSch->dl.cqiToTbsTbl[0][cfi]))\ + [ueDl->mimoInfo.cwInfo[0].cqi]; + /* ITbs for CW0 for 2 Layer Tx */ + ueDl->mimoInfo.cwInfo[0].iTbs[1] = (*(RgSchCmnCqiToTbs *)(cellSch->dl.cqiToTbsTbl[1][cfi]))\ + [ueDl->mimoInfo.cwInfo[0].cqi]; + /* Eff for CW0 for 1 Layer Tx */ + ueDl->mimoInfo.cwInfo[0].eff[0] = (*(RgSchCmnTbSzEff *)(cellSch->dl.cqiToEffTbl[0][cfi]))\ + [ueDl->mimoInfo.cwInfo[0].iTbs[0]]; + /* Eff for CW0 for 2 Layer Tx */ + ueDl->mimoInfo.cwInfo[0].eff[1] = (*(RgSchCmnTbSzEff *)(cellSch->dl.cqiToEffTbl[1][cfi]))\ + [ueDl->mimoInfo.cwInfo[0].iTbs[1]]; + + /* ITbs for CW1 for 1 Layer Tx */ + ueDl->mimoInfo.cwInfo[1].iTbs[0] = (*(RgSchCmnCqiToTbs *)(cellSch->dl.cqiToTbsTbl[0][cfi]))\ + [ueDl->mimoInfo.cwInfo[1].cqi]; + /* ITbs for CW1 for 2 Layer Tx */ + ueDl->mimoInfo.cwInfo[1].iTbs[1] = (*(RgSchCmnCqiToTbs *)(cellSch->dl.cqiToTbsTbl[1][cfi]))\ + [ueDl->mimoInfo.cwInfo[1].cqi]; + /* Eff for CW1 for 1 Layer Tx */ + ueDl->mimoInfo.cwInfo[1].eff[0] = (*(RgSchCmnTbSzEff *)(cellSch->dl.cqiToEffTbl[0][cfi]))\ + [ueDl->mimoInfo.cwInfo[1].iTbs[0]]; + /* Eff for CW1 for 2 Layer Tx */ + ueDl->mimoInfo.cwInfo[1].eff[1] = (*(RgSchCmnTbSzEff *)(cellSch->dl.cqiToEffTbl[1][cfi]))\ + [ueDl->mimoInfo.cwInfo[1].iTbs[1]]; + } + +//#ifdef DL_LA + // ueDl->laCb.cqiBasediTbs = ueDl->mimoInfo.cwInfo[0].iTbs[0] * 100; +//#endif + /* Assigning noLyrs to each CW assuming optimal Spatial multiplexing + * capability */ + (ueDl->mimoInfo.ri/2 == 0)? (ueDl->mimoInfo.cwInfo[0].noLyr = 1) : \ + (ueDl->mimoInfo.cwInfo[0].noLyr = ueDl->mimoInfo.ri/2); + ueDl->mimoInfo.cwInfo[1].noLyr = ueDl->mimoInfo.ri - ueDl->mimoInfo.cwInfo[0].noLyr; + /* rg002.101:ccpu00102106: correcting DL harq softbuffer limitation logic. + * The maxTbSz is the maximum number of PHY bits a harq process can + * hold. Hence we limit our allocation per harq process based on this. + * Earlier implementation we misinterpreted the maxTbSz to be per UE + * per TTI, but in fact it is per Harq per TTI. */ + /* rg002.101:ccpu00102106: cannot exceed the harq Tb Size + * and harq Soft Bits limit.*/ + + /* Considering iTbs corresponding to 2 layer transmission for + * codeword0(approximation) and the maxLayers supported by + * this UE at this point of time. */ + RG_SCH_CMN_TBS_TO_MODODR(ueDl->mimoInfo.cwInfo[0].iTbs[1], modOrder); + + /* Bits/modOrder gives #REs, #REs/noResPerRb gives #RBs */ + /* rg001.301 -MOD- [ccpu00119213] : avoiding wraparound */ + maxRb = ((ueDl->maxSbSz)/(cellSch->dl.noResPerRb[cfi] * modOrder *\ + ueDl->mimoInfo.ri)); + if (cellSch->dl.isDlFreqSel) + { + /* Rounding off to left nearest multiple of RBG size */ + maxRb -= maxRb % cell->rbgSize; + } + ueDl->maxRb = RGSCH_MIN(maxRb, cellSch->dl.maxDlBwPerUe); + if (cellSch->dl.isDlFreqSel) + { + /* Rounding off to right nearest multiple of RBG size */ + if (ueDl->maxRb % cell->rbgSize) + { + ueDl->maxRb += (cell->rbgSize - + (ueDl->maxRb % cell->rbgSize)); + } + } + + /* Set the index of the cwInfo, which is better in terms of + * efficiency. If RI<2, only 1 CW, hence btrCwIdx shall be 0 */ + if (ueDl->mimoInfo.ri < 2) + { + ueDl->mimoInfo.btrCwIdx = 0; + } + else + { + if (ueDl->mimoInfo.cwInfo[0].eff[ueDl->mimoInfo.cwInfo[0].noLyr-1] <\ + ueDl->mimoInfo.cwInfo[1].eff[ueDl->mimoInfo.cwInfo[1].noLyr-1]) + { + ueDl->mimoInfo.btrCwIdx = 1; + } + else + { + ueDl->mimoInfo.btrCwIdx = 0; + } + } + + RETVOID; + } + +#ifdef DL_LA + +/** + * @brief This function updates TX Scheme. + * + * @details + * + * Function: rgSCHCheckAndSetTxScheme + * Purpose: This function determines the Maximum RBs + * a UE is eligible to get based on softbuffer + * limitation and cell->>>maxDlBwPerUe. The Codeword + * specific parameters like iTbs, eff and noLyrs + * are also set in this function. This function + * is called while UE configuration and UeDlCqiInd. + * + * Invoked by: Scheduler + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ue + * @return Void + * + **/ +#ifdef ANSI +PRIVATE Void rgSCHCheckAndSetTxScheme +( +RgSchCellCb *cell, +RgSchUeCb *ue +) +#else +PRIVATE Void rgSCHCheckAndSetTxScheme(cell, ue) +RgSchCellCb *cell; +RgSchUeCb *ue; +#endif +{ + RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell); + RgSchCmnDlUe *ueDl = RG_SCH_CMN_GET_DL_UE(ue ,cell); + U8 cfi = cellSch->dl.currCfi; + U8 maxiTbs; + U8 cqiBasediTbs; + U8 actualiTbs; + + TRC2(rgSCHCheckAndSetTxScheme); + + maxiTbs = (*(RgSchCmnCqiToTbs*)(cellSch->dl.cqiToTbsTbl[0][cfi]))\ + [RG_SCH_CMN_MAX_CQI - 1]; + cqiBasediTbs = (ueDl->laCb[0].cqiBasediTbs)/100; + actualiTbs = ueDl->mimoInfo.cwInfo[0].iTbs[0]; + + if((actualiTbs < RG_SCH_TXSCHEME_CHNG_ITBS_FACTOR) && (cqiBasediTbs > + actualiTbs) && ((cqiBasediTbs - actualiTbs) > RG_SCH_TXSCHEME_CHNG_THRSHD)) + { + RG_SCH_CMN_SET_FORCE_TD(ue,cell, RG_SCH_CMN_TD_TXSCHEME_CHNG); + } + + if(actualiTbs >= maxiTbs) + { + RG_SCH_CMN_UNSET_FORCE_TD(ue,cell, RG_SCH_CMN_TD_TXSCHEME_CHNG); + } + + RETVOID; +} + +/** + * @brief This function determines the allocation limits and + * parameters that aid in DL scheduling. + * + * @details + * + * Function: rgSCHCmnDlSetUeAllocLmtLa + * Purpose: This function determines the Maximum RBs + * a UE is eligible to get based on softbuffer + * limitation and cell->>>maxDlBwPerUe. The Codeword + * specific parameters like iTbs, eff and noLyrs + * are also set in this function. This function + * is called while UE configuration and UeDlCqiInd. + * + * Invoked by: Scheduler + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ue + * @return Void + * + **/ +#ifdef ANSI +PUBLIC Void rgSCHCmnDlSetUeAllocLmtLa +( +RgSchCellCb *cell, +RgSchUeCb *ue +) +#else +PUBLIC Void rgSCHCmnDlSetUeAllocLmtLa(cell, ue) +RgSchCellCb *cell; +RgSchUeCb *ue; +#endif +{ + U8 modOrder; + U32 maxRb; + U8 reportediTbs; + RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell); + RgSchCmnDlUe *ueDl = RG_SCH_CMN_GET_DL_UE(ue,cell); + U8 cfi = cellSch->dl.currCfi; + U8 maxiTbs; + U8 cwIdx = 0; + + TRC2(rgSCHCmnDlSetUeAllocLmtLa); + + maxiTbs = (*(RgSchCmnCqiToTbs *)(cellSch->dl.cqiToTbsTbl[0][cfi]))[RG_SCH_CMN_MAX_CQI - 1]; + if(ueDl->cqiFlag == TRUE) + { + for(cwIdx=0; cwIdx < RG_SCH_CMN_MAX_CW_PER_UE; cwIdx++) + { + S32 iTbsNew; + + /* Calcluating the reported iTbs for code word 0 */ + reportediTbs = ue->ue5gtfCb.mcs; + + iTbsNew = (S32) reportediTbs; + + if(!ueDl->laCb[cwIdx].notFirstCqi) + { + /* This is the first CQI report from UE */ + ueDl->laCb[cwIdx].cqiBasediTbs = (iTbsNew * 100); + ueDl->laCb[cwIdx].notFirstCqi = TRUE; + } + else if ((RG_ITBS_DIFF(reportediTbs, ueDl->mimoInfo.cwInfo[cwIdx].iTbs[0])) > 5) + { + /* Ignore this iTBS report and mark that last iTBS report was */ + /* ignored so that subsequently we reset the LA algorithm */ + ueDl->laCb[cwIdx].lastiTbsIgnored = TRUE; + ueDl->laCb[cwIdx].numLastiTbsIgnored++; + if( ueDl->laCb[cwIdx].numLastiTbsIgnored > 10) + { + /* CQI reported by UE is not catching up. Reset the LA algorithm */ + ueDl->laCb[cwIdx].cqiBasediTbs = (iTbsNew * 100); + ueDl->laCb[cwIdx].deltaiTbs = 0; + ueDl->laCb[cwIdx].lastiTbsIgnored = FALSE; + ueDl->laCb[cwIdx].numLastiTbsIgnored = 0; + } + } + else + { + if (ueDl->laCb[cwIdx].lastiTbsIgnored != TRUE) + { + ueDl->laCb[cwIdx].cqiBasediTbs = ((20 * iTbsNew * 100) + + (80 * ueDl->laCb[cwIdx].cqiBasediTbs))/100; + } + else + { + /* Reset the LA as iTbs in use caught up with the value */ + /* reported by UE. */ + ueDl->laCb[cwIdx].cqiBasediTbs = ((20 * iTbsNew * 100) + + (80 * ueDl->mimoInfo.cwInfo[cwIdx].iTbs[0] * 100))/100; + ueDl->laCb[cwIdx].deltaiTbs = 0; + ueDl->laCb[cwIdx].lastiTbsIgnored = FALSE; + } + } + + iTbsNew = (ueDl->laCb[cwIdx].cqiBasediTbs + ueDl->laCb[cwIdx].deltaiTbs)/100; + + RG_SCH_CHK_ITBS_RANGE(iTbsNew, maxiTbs); + + ueDl->mimoInfo.cwInfo[cwIdx].iTbs[0] = RGSCH_MIN(iTbsNew, cell->thresholds.maxDlItbs); + //ueDl->mimoInfo.cwInfo[cwIdx].iTbs[1] = ueDl->mimoInfo.cwInfo[cwIdx].iTbs[0]; +#ifdef RG_5GTF + ue->ue5gtfCb.mcs = ueDl->mimoInfo.cwInfo[cwIdx].iTbs[0]; + /* + printf("reportediTbs[%d] cqiBasediTbs[%d] deltaiTbs[%d] iTbsNew[%d] mcs[%d] cwIdx[%d]\n", + reportediTbs, ueDl->laCb[cwIdx].cqiBasediTbs, ueDl->laCb[cwIdx].deltaiTbs, + iTbsNew, ue->ue5gtfCb.mcs, cwIdx); + */ +#endif + + if((ue->mimoInfo.txMode != RGR_UE_TM_3) && (ue->mimoInfo.txMode != RGR_UE_TM_4)) + { + break; + } + } + ueDl->cqiFlag = FALSE; + } + + + RETVOID; +} +#endif +/*********************************************************** + * + * Func : rgSCHCmnDlUeResetTemp + * + * Desc : Reset whatever variables where temporarily used + * during UE scheduling. + * + * Ret : Void + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PUBLIC Void rgSCHCmnDlHqPResetTemp +( +RgSchDlHqProcCb *hqP +) +#else +PUBLIC Void rgSCHCmnDlHqPResetTemp(hqP) +RgSchDlHqProcCb *hqP; +#endif +{ + + TRC2(rgSCHCmnDlHqPResetTemp); + + /* Fix: syed having a hqP added to Lists for RB assignment rather than + * a UE, as adding UE was limiting handling some scenarios */ + hqP->reqLnk.node = (PTR)NULLP; + hqP->schdLstLnk.node = (PTR)NULLP; + + RETVOID; +} /* rgSCHCmnDlHqPResetTemp */ + +/*********************************************************** + * + * Func : rgSCHCmnDlUeResetTemp + * + * Desc : Reset whatever variables where temporarily used + * during UE scheduling. + * + * Ret : Void + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PUBLIC Void rgSCHCmnDlUeResetTemp +( +RgSchUeCb *ue, +RgSchDlHqProcCb *hqP +) +#else +PUBLIC Void rgSCHCmnDlUeResetTemp(ue, hqP) +RgSchUeCb *ue; +RgSchDlHqProcCb *hqP; +#endif +{ + RgSchDlRbAlloc *allocInfo; + RgSchCmnDlUe *cmnUe = RG_SCH_CMN_GET_DL_UE(ue,hqP->hqE->cell); +#ifdef LTE_ADV + Void *tmpCb; +#endif + + TRC2(rgSCHCmnDlUeResetTemp); + + /* Fix : syed check for UE's existence was useless. + * Instead we need to check that reset is done only for the + * information of a scheduled harq proc, which is cmnUe->proc. + * Reset should not be done for non-scheduled hqP */ + if((cmnUe->proc == hqP) || (cmnUe->proc == NULLP)) + { + cmnUe->proc = NULLP; + allocInfo = RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ue, hqP->hqE->cell); +#ifdef LTE_ADV + tmpCb = allocInfo->laaCb; +#endif + cmMemset((U8 *)allocInfo, (U8)0, sizeof(RgSchDlRbAlloc)); + allocInfo->rnti = ue->ueId; +#ifdef LTE_ADV + allocInfo->laaCb = tmpCb; +#endif + /* Fix: syed moving this to a common function for both scheduled + * and non-scheduled UEs */ + cmnUe->outStndAlloc = 0; + } + rgSCHCmnDlHqPResetTemp(hqP); + + RETVOID; +} /* rgSCHCmnDlUeResetTemp */ + +/*********************************************************** + * + * Func : rgSCHCmnUlUeResetTemp + * + * Desc : Reset whatever variables where temporarily used + * during UE scheduling. + * + * Ret : Void + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PUBLIC Void rgSCHCmnUlUeResetTemp +( +RgSchCellCb *cell, +RgSchUeCb *ue +) +#else +PUBLIC Void rgSCHCmnUlUeResetTemp(cell, ue) +RgSchCellCb *cell; +RgSchUeCb *ue; +#endif +{ + RgSchCmnUlUe *cmnUlUe = RG_SCH_CMN_GET_UL_UE(ue,cell); + + TRC2(rgSCHCmnUlUeResetTemp); + + cmMemset((U8 *)&cmnUlUe->alloc, (U8)0, sizeof(cmnUlUe->alloc)); + + RETVOID; +} /* rgSCHCmnUlUeResetTemp */ + + + +/** + * @brief This function fills the PDCCH information from dlProc. + * + * @details + * + * Function: rgSCHCmnFillPdcch + * Purpose: This function fills in the PDCCH information + * obtained from the RgSchDlRbAlloc + * during common channel scheduling(P, SI, RA - RNTI's). + * + * Invoked by: Downlink Scheduler + * + * @param[out] RgSchPdcch* pdcch + * @param[in] RgSchDlRbAlloc* rbAllocInfo + * @return Void + * + **/ +#ifdef ANSI +PUBLIC Void rgSCHCmnFillPdcch +( +RgSchCellCb *cell, +RgSchPdcch *pdcch, +RgSchDlRbAlloc *rbAllocInfo +) +#else +PUBLIC Void rgSCHCmnFillPdcch(cell, pdcch, rbAllocInfo) +RgSchCellCb *cell; +RgSchPdcch *pdcch; +RgSchDlRbAlloc *rbAllocInfo; +#endif +{ + + TRC2(rgSCHCmnFillPdcch); + + /* common channel pdcch filling, + * only 1A and Local is supported */ + pdcch->rnti = rbAllocInfo->rnti; + pdcch->dci.dciFormat = rbAllocInfo->dciFormat; + switch(rbAllocInfo->dciFormat) + { +#ifdef RG_5GTF /* ANOOP: ToDo: DCI format B1/B2 filling */ + case TFU_DCI_FORMAT_B1: + { + /* ToDo: Anoop */ + pdcch->dci.u.formatB1Info.formatType = 0; + pdcch->dci.u.formatB1Info.xPDSCHRange = rbAllocInfo->tbInfo[0].cmnGrnt.xPDSCHRange; + pdcch->dci.u.formatB1Info.RBAssign = rbAllocInfo->tbInfo[0].cmnGrnt.rbAssign; + pdcch->dci.u.formatB1Info.u.rbAssignB1Val324.hqProcId = 0; + pdcch->dci.u.formatB1Info.u.rbAssignB1Val324.mcs = rbAllocInfo->tbInfo[0].imcs; + pdcch->dci.u.formatB1Info.u.rbAssignB1Val324.ndi = 0; + //pdcch->dci.u.formatB1Info.u.rbAssignB1Val324.ndi = rbAllocInfo->tbInfo[0].ndi; + pdcch->dci.u.formatB1Info.u.rbAssignB1Val324.RV = rbAllocInfo->tbInfo[0].cmnGrnt.rv; + pdcch->dci.u.formatB1Info.u.rbAssignB1Val324.bmiHqAckNack = 0; + pdcch->dci.u.formatB1Info.CSI_BSI_BRI_Req = 0; + pdcch->dci.u.formatB1Info.CSIRS_BRRS_TxTiming = 0; + pdcch->dci.u.formatB1Info.CSIRS_BRRS_SymbIdx = 0; + pdcch->dci.u.formatB1Info.CSIRS_BRRS_ProcInd = 0; + pdcch->dci.u.formatB1Info.xPUCCH_TxTiming = 0; + //TODO_SID: Need to update + pdcch->dci.u.formatB1Info.freqResIdx_xPUCCH = 0; + pdcch->dci.u.formatB1Info.beamSwitch = 0; + pdcch->dci.u.formatB1Info.SRS_Config = 0; + pdcch->dci.u.formatB1Info.SRS_Symbol = 0; + //TODO_SID: Need to check.Currently setting 0(1 layer, ports(8) w/o OCC). + pdcch->dci.u.formatB1Info.AntPorts_numLayers = 0; + pdcch->dci.u.formatB1Info.SCID = rbAllocInfo->tbInfo[0].cmnGrnt.SCID; + //TODO_SID: Hardcoding TPC command to 1 i.e. No change + pdcch->dci.u.formatB1Info.tpcCmd = 1; //tpc; + pdcch->dci.u.formatB1Info.DL_PCRS = 0; + + break; /* case TFU_DCI_FORMAT_B1: */ + } + + case TFU_DCI_FORMAT_B2: + { + //printf(" RG_5GTF:: Pdcch filling with DCI format B2\n"); + /* ToDo: Anoop */ + break; /* case TFU_DCI_FORMAT_B2: */ + } +#endif + case TFU_DCI_FORMAT_1A: + pdcch->dci.u.format1aInfo.isPdcchOrder = FALSE; + + /*Nprb indication at PHY for common Ch + *setting least significant bit of tpc field to 1 if + nPrb=3 and 0 otherwise. */ + if (rbAllocInfo->nPrb == 3) + { + pdcch->dci.u.format1aInfo.t.pdschInfo.tpcCmd = 1; + } + else + { + pdcch->dci.u.format1aInfo.t.pdschInfo.tpcCmd = 0; + } + pdcch->dci.u.format1aInfo.t.pdschInfo.allocInfo.nGap2.pres = NOTPRSNT; + pdcch->dci.u.format1aInfo.t.pdschInfo.allocInfo.isLocal = TRUE; + pdcch->dci.u.format1aInfo.t.pdschInfo.allocInfo.mcs = \ + rbAllocInfo->tbInfo[0].imcs; + pdcch->dci.u.format1aInfo.t.pdschInfo.allocInfo.ndi = 0; + pdcch->dci.u.format1aInfo.t.pdschInfo.allocInfo.rv = 0; + /* Add RIV CALC */ + pdcch->dci.u.format1aInfo.t.pdschInfo.allocInfo.alloc.type = + TFU_ALLOC_TYPE_RIV; + pdcch->dci.u.format1aInfo.t.pdschInfo.allocInfo.alloc.u.riv = + rgSCHCmnCalcRiv (cell->bwCfg.dlTotalBw, + rbAllocInfo->allocInfo.raType2.rbStart, + rbAllocInfo->allocInfo.raType2.numRb); + +#ifdef LTE_TDD + pdcch->dci.u.format1aInfo.t.pdschInfo.allocInfo.harqProcId.pres = \ + FALSE; +#ifdef TFU_TDD + pdcch->dci.u.format1aInfo.t.pdschInfo.dai.pres = TRUE; + pdcch->dci.u.format1aInfo.t.pdschInfo.dai.val = 1; +#endif +#endif + break; /* case TFU_DCI_FORMAT_1A: */ + case TFU_DCI_FORMAT_1: + pdcch->dci.u.format1Info.tpcCmd = 0; + /* Avoiding this check,as we dont support Type1 RA */ +#ifdef RG_UNUSED + if (rbAllocInfo->raType == RG_SCH_CMN_RA_TYPE0) + { +#endif + pdcch->dci.u.format1Info.allocInfo.isAllocType0 = TRUE; + pdcch->dci.u.format1Info.allocInfo.resAllocMap[0] = + ((rbAllocInfo->allocInfo.raType0.dlAllocBitMask >> 24) + & 0xff); + pdcch->dci.u.format1Info.allocInfo.resAllocMap[1] = + ((rbAllocInfo->allocInfo.raType0.dlAllocBitMask >> 16) + & 0x00ff); + pdcch->dci.u.format1Info.allocInfo.resAllocMap[2] = + ((rbAllocInfo->allocInfo.raType0.dlAllocBitMask >> 8) + & 0x0000ff); + pdcch->dci.u.format1Info.allocInfo.resAllocMap[3] = + ((rbAllocInfo->allocInfo.raType0.dlAllocBitMask & 0x000000ff)); +#ifdef RG_UNUSED + } +#endif + pdcch->dci.u.format1Info.allocInfo.harqProcId = 0; + pdcch->dci.u.format1Info.allocInfo.ndi = 0; + pdcch->dci.u.format1Info.allocInfo.mcs = rbAllocInfo->tbInfo[0].imcs; + pdcch->dci.u.format1Info.allocInfo.rv = 0; +#ifdef TFU_TDD + pdcch->dci.u.format1Info.dai = 1; +#endif + break; + default: + RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,"Allocator's icorrect " + "dciForamt Fill RNTI:%d",rbAllocInfo->rnti); + break; + } + RETVOID; +} + +#ifdef LTE_TDD +/** + * @brief This function finds whether the subframe is special subframe or not. + * + * @details + * + * Function: rgSCHCmnIsSplSubfrm + * Purpose: This function finds the subframe index of the special subframe + * and finds whether the current DL index matches it or not. + * + * Invoked by: Scheduler + * + * @param[in] U8 splfrmCnt + * @param[in] U8 curSubfrmIdx + * @param[in] U8 periodicity + * @param[in] RgSchTddSubfrmInfo *subfrmInfo + * @return Bool + * + **/ +#ifdef ANSI +PRIVATE Bool rgSCHCmnIsSplSubfrm +( +U8 splfrmCnt, +U8 curSubfrmIdx, +U8 periodicity, +RgSchTddSubfrmInfo *subfrmInfo +) +#else +PRIVATE Bool rgSCHCmnIsSplSubfrm(splfrmCnt, curSubfrmIdx, periodicity, subfrmInfo) +U8 splfrmCnt; +U8 curSubfrmIdx; +U8 periodicity; +RgSchTddSubfrmInfo *subfrmInfo; +#endif +{ + U8 dlSfCnt = 0; + U8 splfrmIdx = 0; + + TRC2(rgSCHCmnIsSplSubfrm); + + if(splfrmCnt > 0) + { + if(periodicity == RG_SCH_CMN_5_MS_PRD) + { + if(splfrmCnt%2) + { + dlSfCnt = ((splfrmCnt-1)/2) *\ + (subfrmInfo->numFrmHf1 + subfrmInfo->numFrmHf2); + dlSfCnt = dlSfCnt + subfrmInfo->numFrmHf1; + } + else + { + dlSfCnt = (splfrmCnt/2) * \ + (subfrmInfo->numFrmHf1 + subfrmInfo->numFrmHf2); + } + } + else + { + dlSfCnt = splfrmCnt * subfrmInfo->numFrmHf1; + } + splfrmIdx = RG_SCH_CMN_SPL_SUBFRM_1 +\ + (periodicity*splfrmCnt - dlSfCnt); + } + else + { + splfrmIdx = RG_SCH_CMN_SPL_SUBFRM_1; + } + + if(splfrmIdx == curSubfrmIdx) + { + RETVALUE(TRUE); + } + + RETVALUE(FALSE); +} + +/** + * @brief This function updates DAI or UL index. + * + * @details + * + * Function: rgSCHCmnUpdHqAndDai + * Purpose: Updates the DAI based on UL-DL Configuration + * index and UE. It also updates the HARQ feedback + * time and 'm' index. + * + * Invoked by: TOM + * + * @param[in] RgDlHqProcCb *hqP + * @param[in] RgSchDlSf *subFrm + * @param[in] RgSchDlHqTbCb *tbCb + * @param[in] U8 tbAllocIdx + * @return Void + * + **/ +#ifdef ANSI +PRIVATE Void rgSCHCmnUpdHqAndDai +( +RgSchDlHqProcCb *hqP, +RgSchDlSf *subFrm, +RgSchDlHqTbCb *tbCb, +U8 tbAllocIdx +) +#else +PRIVATE Void rgSCHCmnUpdHqAndDai(hqP, subFrm, tbCb,tbAllocIdx) +RgSchDlHqProcCb *hqP; +RgSchDlSf *subFrm; +RgSchDlHqTbCb *tbCb; +U8 tbAllocIdx; +#endif +{ + RgSchUeCb *ue = hqP->hqE->ue; + + TRC2(rgSCHCmnUpdHqAndDai); + + if(subFrm != NULLP) + { + /* set the time at which UE shall send the feedback + * for this process */ + tbCb->fdbkTime.sfn = (tbCb->timingInfo.sfn + \ + subFrm->dlFdbkInfo.sfnOffset) % RGSCH_MAX_SFN; + tbCb->fdbkTime.subframe = subFrm->dlFdbkInfo.subframe; + tbCb->m = subFrm->dlFdbkInfo.m; + } + else + { + /* set the time at which UE shall send the feedback + * for this process */ + tbCb->fdbkTime.sfn = (tbCb->timingInfo.sfn + \ + hqP->subFrm->dlFdbkInfo.sfnOffset) % RGSCH_MAX_SFN; + tbCb->fdbkTime.subframe = hqP->subFrm->dlFdbkInfo.subframe; + tbCb->m = hqP->subFrm->dlFdbkInfo.m; + } + + /* ccpu00132340-MOD- DAI need to be updated for first TB only*/ + if(ue && !tbAllocIdx) + { + Bool havePdcch = (tbCb->hqP->pdcch ? TRUE : FALSE); + U8 dlDai; + + dlDai = rgSCHCmnUpdDai(ue, &tbCb->fdbkTime, tbCb->m, havePdcch,tbCb->hqP, + &tbCb->dai); + if(havePdcch) + {/* Non SPS occasions */ + tbCb->hqP->pdcch->dlDai = dlDai; + /* hqP->ulDai is used for N1 resource filling + * when SPS occaions present in a bundle */ + tbCb->hqP->ulDai = tbCb->dai; + tbCb->hqP->dlDai = dlDai; + } + } + + /* Updatijng pucchFdbkIdx for both PUCCH or PUSCH + fdbk reception */ + tbCb->pucchFdbkIdx = tbCb->hqP->ulDai; + + RETVOID; +} + + +/** + * @brief This function updates DAI or UL index. + * + * @details + * + * Function: rgSCHCmnUpdDai + * Purpose: Updates the DAI in the ack-nack info, a valid + * ue should be passed + * + * Invoked by: TOM + * + * @param[in] RgDlHqProcCb *hqP + * @param[in] RgSchDlSf *subFrm + * @param[in] RgSchDlHqTbCb *tbCb + * @return U8 dlDai + * + **/ +#ifdef ANSI +PUBLIC U8 rgSCHCmnUpdDai +( +RgSchUeCb *ue, +CmLteTimingInfo *fdbkTime, +U8 m, +Bool havePdcch, +RgSchDlHqProcCb *hqP, +U8 *ulDai +) +#else +PUBLIC U8 rgSCHCmnUpdDai(ue, fdbkTime, m, havePdcch,tbCb,servCellId,hqP,ulDai) +RgSchUeCb *ue; +CmLteTimingInfo *fdbkTime; +U8 m; +Bool havePdcch; +RgSchDlHqProcCb *hqP; +U8 *ulDai; +#endif +{ + RgSchTddANInfo *anInfo; + U8 servCellIdx; + U8 ackNackFdbkArrSize; + + + TRC2(rgSCHCmnUpdDai); + + if(hqP != NULLP) + {/* Non SPS */ +#ifdef LTE_ADV + servCellIdx = rgSchUtlGetServCellIdx(hqP->hqE->cell->instIdx, + hqP->hqE->cell->cellId, + ue); +#else + servCellIdx = RGSCH_PCELL_INDEX; +#endif + ackNackFdbkArrSize = hqP->hqE->cell->ackNackFdbkArrSize; + }else + {/* SPS on primary cell */ + servCellIdx = RGSCH_PCELL_INDEX; + ackNackFdbkArrSize = ue->cell->ackNackFdbkArrSize; + } + + + anInfo = rgSCHUtlGetUeANFdbkInfo(ue, fdbkTime,servCellIdx); + + /* If no ACK/NACK feedback already present, create a new one */ + if(NULLP == anInfo) + { + anInfo = &ue->cellInfo[servCellIdx]->anInfo[ue->cellInfo[servCellIdx]->nextFreeANIdx]; + anInfo->sfn = fdbkTime->sfn; + anInfo->subframe = fdbkTime->subframe; + anInfo->latestMIdx = m; + /* Fixing DAI value - ccpu00109162 */ + /* Handle TDD case as in MIMO definition of the function */ + anInfo->ulDai = 1; + if (havePdcch) + { + anInfo->dlDai = 1; + } + anInfo->isSpsOccasion = FALSE; + /* set the free Index to store Ack/Nack Information*/ + ue->cellInfo[servCellIdx]->nextFreeANIdx = (ue->cellInfo[servCellIdx]->nextFreeANIdx + 1) % + ackNackFdbkArrSize; + + } + else + { + anInfo->latestMIdx = m; + /* Fixing DAI value - ccpu00109162 */ + /* Handle TDD case as in MIMO definition of the function */ + anInfo->ulDai = anInfo->ulDai + 1; + if (havePdcch) + { + anInfo->dlDai = anInfo->dlDai + 1; + } + } +#ifdef LTE_ADV + /* ignoring the Scell check, + * for primary cell this field is unused*/ + if(hqP != NULLP) + {/* SPS*/ + anInfo->n1ResTpcIdx = hqP->tpc; + } + + if(ulDai) + {/* As this not required for release pdcch */ + *ulDai = anInfo->ulDai; + } +#endif + RETVALUE(anInfo->dlDai); + +} +#endif /* ifdef LTE_TDD */ + +PUBLIC U32 rgHqRvRetxCnt[4][2]; +PUBLIC U32 rgUlrate_grant; + +/** + * @brief This function fills the HqP TB with rbAllocInfo. + * + * @details + * + * Function: rgSCHCmnFillHqPTb + * Purpose: This function fills in the HqP TB with rbAllocInfo. + * + * Invoked by: rgSCHCmnFillHqPTb + * + * @param[in] RgSchCellCb* cell + * @param[in] RgSchDlRbAlloc *rbAllocInfo, + * @param[in] U8 tbAllocIdx + * @param[in] RgSchPdcch *pdcch + * @return Void + * + **/ +#ifdef LTEMAC_SPS +#ifdef ANSI +PUBLIC Void rgSCHCmnFillHqPTb +( +RgSchCellCb *cell, +RgSchDlRbAlloc *rbAllocInfo, +U8 tbAllocIdx, +RgSchPdcch *pdcch +) +#else +PUBLIC Void rgSCHCmnFillHqPTb(cell, rbAllocInfo, tbAllocIdx, pdcch) +RgSchCellCb *cell; +RgSchDlRbAlloc *rbAllocInfo; +U8 tbAllocIdx; +RgSchPdcch *pdcch; +#endif +#else +#ifdef ANSI +PRIVATE Void rgSCHCmnFillHqPTb +( +RgSchCellCb *cell, +RgSchDlRbAlloc *rbAllocInfo, +U8 tbAllocIdx, +RgSchPdcch *pdcch +) +#else +PRIVATE Void rgSCHCmnFillHqPTb(cell, rbAllocInfo, tbAllocIdx, pdcch) +RgSchCellCb *cell; +RgSchDlRbAlloc *rbAllocInfo; +U8 tbAllocIdx; +RgSchPdcch *pdcch; +#endif +#endif /* LTEMAC_SPS */ +{ + RgSchCmnDlCell *cmnCellDl = RG_SCH_CMN_GET_DL_CELL(cell); + RgSchDlTbAllocInfo *tbAllocInfo = &rbAllocInfo->tbInfo[tbAllocIdx]; + RgSchDlHqTbCb *tbInfo = tbAllocInfo->tbCb; + RgSchDlHqProcCb *hqP = tbInfo->hqP; + + TRC2(rgSCHCmnFillHqPTb); + + /*ccpu00120365-ADD-if tb is disabled, set mcs=0,rv=1. + * Relevant for DCI format 2 & 2A as per 36.213-7.1.7.2 + */ + if ( tbAllocInfo->isDisabled) + { + + tbInfo->dlGrnt.iMcs = 0; + tbInfo->dlGrnt.rv = 1; + } + /* Fill for TB retransmission */ + else if (tbInfo->txCntr > 0) + { + + tbInfo->timingInfo = cmnCellDl->time; + /* Fix */ + if ((tbInfo->isAckNackDtx == TFU_HQFDB_DTX)) + { + tbInfo->dlGrnt.iMcs = tbAllocInfo->imcs; + rgHqRvRetxCnt[tbInfo->dlGrnt.rv][tbInfo->tbIdx]++; + } + else + { + tbInfo->dlGrnt.rv = rgSchCmnDlRvTbl[++(tbInfo->ccchSchdInfo.rvIdx) & 0x03]; + } + + /* fill the scheduler information of hqProc */ + tbInfo->ccchSchdInfo.totBytes = tbAllocInfo->bytesAlloc; + RGSCH_ARRAY_BOUND_CHECK(cell->instIdx,hqP->tbInfo,tbInfo->tbIdx ); + rgSCHDhmHqTbRetx(hqP->hqE, tbInfo->timingInfo, hqP, tbInfo->tbIdx); + } + /* Fill for TB transmission */ + else + { + /* Fill the HqProc */ + tbInfo->dlGrnt.iMcs = tbAllocInfo->imcs; + tbInfo->tbSz = tbAllocInfo->bytesAlloc; + tbInfo->timingInfo = cmnCellDl->time; + + tbInfo->dlGrnt.rv = rgSchCmnDlRvTbl[0]; + /* fill the scheduler information of hqProc */ + tbInfo->ccchSchdInfo.rvIdx = 0; + tbInfo->ccchSchdInfo.totBytes = tbAllocInfo->bytesAlloc; + /* DwPts Scheduling Changes Start */ + /* DwPts Scheduling Changes End */ + cell->measurements.dlBytesCnt += tbAllocInfo->bytesAlloc; + } + + /*ccpu00120365:-ADD-only add to subFrm list if tb is not disabled */ + if ( tbAllocInfo->isDisabled == FALSE ) + { + /* Set the number of transmitting SM layers for this TB */ + tbInfo->numLyrs = tbAllocInfo->noLyr; + /* Set the TB state as WAITING to indicate TB has been + * considered for transmission */ + tbInfo->state = HQ_TB_WAITING; + hqP->subFrm = rbAllocInfo->dlSf; + tbInfo->hqP->pdcch = pdcch; + //tbInfo->dlGrnt.numRb = rbAllocInfo->rbsAlloc; + rgSCHUtlDlHqPTbAddToTx(hqP->subFrm, hqP, tbInfo->tbIdx); + } + RETVOID; +} + +/** + * @brief This function fills the PDCCH DCI format 2 information from dlProc. + * + * @details + * + * Function: rgSCHCmnFillHqPPdcchDciFrmt2 + * Purpose: This function fills in the PDCCH information + * obtained from the RgSchDlHqProcCb and RgSchDlRbAlloc + * for dedicated service scheduling. It also + * obtains TPC to be filled in from the power module. + * Assign the PDCCH to HQProc. + * + * Invoked by: Downlink Scheduler + * + * @param[in] RgSchCellCb* cell + * @param[in] RgSchDlRbAlloc* rbAllocInfo + * @param[in] RgDlHqProc* hqP + * @param[out] RgSchPdcch *pdcch + * @param[in] U8 tpc + * @return Void + * + **/ +#ifdef ANSI +PRIVATE Void rgSCHCmnFillHqPPdcchDciFrmtB1B2 +( +RgSchCellCb *cell, +RgSchDlRbAlloc *rbAllocInfo, +RgSchDlHqProcCb *hqP, +RgSchPdcch *pdcch, +U8 tpc +) +#else +PRIVATE Void rgSCHCmnFillHqPPdcchDciFrmtB1B2(cell, rbAllocInfo, hqP, pdcch, tpc) +RgSchCellCb *cell; +RgSchDlRbAlloc *rbAllocInfo; +RgSchDlHqProcCb *hqP; +RgSchPdcch *pdcch; +U8 tpc; +#endif +{ + + TRC2(rgSCHCmnFillHqPPdcchDciFrmtB1B2) + + rgSCHCmnFillHqPTb(cell, rbAllocInfo, 0, pdcch); + //Currently hardcoding values here. + //printf("Filling 5GTF UL DCI for rnti %d \n",alloc->rnti); + switch(rbAllocInfo->dciFormat) + { + case TFU_DCI_FORMAT_B1: + { + pdcch->dci.u.formatB1Info.formatType = 0; + pdcch->dci.u.formatB1Info.xPDSCHRange = rbAllocInfo->tbInfo[0].tbCb->dlGrnt.xPDSCHRange; + pdcch->dci.u.formatB1Info.RBAssign = rbAllocInfo->tbInfo[0].tbCb->dlGrnt.rbAssign; + pdcch->dci.u.formatB1Info.u.rbAssignB1Val324.hqProcId = hqP->procId; + pdcch->dci.u.formatB1Info.u.rbAssignB1Val324.mcs = rbAllocInfo->tbInfo[0].imcs; + pdcch->dci.u.formatB1Info.u.rbAssignB1Val324.ndi = rbAllocInfo->tbInfo[0].tbCb->ndi; + pdcch->dci.u.formatB1Info.u.rbAssignB1Val324.RV = rbAllocInfo->tbInfo[0].tbCb->dlGrnt.rv; + pdcch->dci.u.formatB1Info.u.rbAssignB1Val324.bmiHqAckNack = 0; + pdcch->dci.u.formatB1Info.CSI_BSI_BRI_Req = 0; + pdcch->dci.u.formatB1Info.CSIRS_BRRS_TxTiming = 0; + pdcch->dci.u.formatB1Info.CSIRS_BRRS_SymbIdx = 0; + pdcch->dci.u.formatB1Info.CSIRS_BRRS_ProcInd = 0; + pdcch->dci.u.formatB1Info.xPUCCH_TxTiming = 0; + //TODO_SID: Need to update + pdcch->dci.u.formatB1Info.freqResIdx_xPUCCH = 0; + pdcch->dci.u.formatB1Info.beamSwitch = 0; + pdcch->dci.u.formatB1Info.SRS_Config = 0; + pdcch->dci.u.formatB1Info.SRS_Symbol = 0; + //TODO_SID: Need to check.Currently setting 0(1 layer, ports(8) w/o OCC). + pdcch->dci.u.formatB1Info.AntPorts_numLayers = 0; + pdcch->dci.u.formatB1Info.SCID = rbAllocInfo->tbInfo[0].tbCb->dlGrnt.SCID; + //TODO_SID: Hardcoding TPC command to 1 i.e. No change + pdcch->dci.u.formatB1Info.tpcCmd = 1; //tpc; + pdcch->dci.u.formatB1Info.DL_PCRS = 0; + break; + } + case TFU_DCI_FORMAT_B2: + { + pdcch->dci.u.formatB2Info.formatType = 1; + pdcch->dci.u.formatB2Info.xPDSCHRange = rbAllocInfo->tbInfo[0].tbCb->dlGrnt.xPDSCHRange; + pdcch->dci.u.formatB2Info.RBAssign = rbAllocInfo->tbInfo[0].tbCb->dlGrnt.rbAssign; + pdcch->dci.u.formatB2Info.u.rbAssignB1Val324.hqProcId = hqP->procId; + pdcch->dci.u.formatB2Info.u.rbAssignB1Val324.mcs = rbAllocInfo->tbInfo[0].imcs; + pdcch->dci.u.formatB2Info.u.rbAssignB1Val324.ndi = rbAllocInfo->tbInfo[0].tbCb->ndi; + pdcch->dci.u.formatB2Info.u.rbAssignB1Val324.RV = rbAllocInfo->tbInfo[0].tbCb->dlGrnt.rv; + pdcch->dci.u.formatB2Info.u.rbAssignB1Val324.bmiHqAckNack = 0; + pdcch->dci.u.formatB2Info.CSI_BSI_BRI_Req = 0; + pdcch->dci.u.formatB2Info.CSIRS_BRRS_TxTiming = 0; + pdcch->dci.u.formatB2Info.CSIRS_BRRS_SymbIdx = 0; + pdcch->dci.u.formatB2Info.CSIRS_BRRS_ProcInd = 0; + pdcch->dci.u.formatB2Info.xPUCCH_TxTiming = 0; + //TODO_SID: Need to update + pdcch->dci.u.formatB2Info.freqResIdx_xPUCCH = 0; + pdcch->dci.u.formatB2Info.beamSwitch = 0; + pdcch->dci.u.formatB2Info.SRS_Config = 0; + pdcch->dci.u.formatB2Info.SRS_Symbol = 0; + //TODO_SID: Need to check.Currently setting 4(2 layer, ports(8,9) w/o OCC). + pdcch->dci.u.formatB2Info.AntPorts_numLayers = 4; + pdcch->dci.u.formatB2Info.SCID = rbAllocInfo->tbInfo[0].tbCb->dlGrnt.SCID; + //TODO_SID: Hardcoding TPC command to 1 i.e. No change + pdcch->dci.u.formatB2Info.tpcCmd = 1; //tpc; + pdcch->dci.u.formatB2Info.DL_PCRS = 0; + break; + } + default: + RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId," 5GTF_ERROR Allocator's icorrect " + "dciForamt Fill RNTI:%d",rbAllocInfo->rnti); + break; + } + + RETVOID; +} + +extern U32 totPcellSCell; +extern U32 addedForScell; +extern U32 addedForScell1; +extern U32 addedForScell2; +/** + * @brief This function fills the PDCCH information from dlProc. + * + * @details + * + * Function: rgSCHCmnFillHqPPdcch + * Purpose: This function fills in the PDCCH information + * obtained from the RgSchDlHqProcCb and RgSchDlRbAlloc + * for dedicated service scheduling. It also + * obtains TPC to be filled in from the power module. + * Assign the PDCCH to HQProc. + * + * Invoked by: Downlink Scheduler + * + * @param[in] RgSchCellCb* cell + * @param[in] RgSchDlRbAlloc* rbAllocInfo + * @param[in] RgDlHqProc* hqP + * @return Void + * + **/ +#ifdef ANSI +PUBLIC Void rgSCHCmnFillHqPPdcch +( +RgSchCellCb *cell, +RgSchDlRbAlloc *rbAllocInfo, +RgSchDlHqProcCb *hqP +) +#else +PUBLIC Void rgSCHCmnFillHqPPdcch(cell, rbAllocInfo, hqP) +RgSchCellCb *cell; +RgSchDlRbAlloc *rbAllocInfo; +RgSchDlHqProcCb *hqP; +#endif +{ + RgSchCmnDlCell *cmnCell = RG_SCH_CMN_GET_DL_CELL(cell); + RgSchPdcch *pdcch = rbAllocInfo->pdcch; + U8 tpc = 1; + + TRC2(rgSCHCmnFillHqPPdcch); + + if (hqP->hqE->ue) + { +#ifdef LTE_ADV + if(RG_SCH_IS_CELL_SEC(hqP->hqE->ue, cell)) + { + tpc = hqP->tpc; + } + else +#endif + { + tpc = rgSCHPwrPucchTpcForUe(cell, hqP->hqE->ue); + } + /* Fix: syed moving this to a common function for both scheduled + * and non-scheduled UEs */ + + pdcch->ue = hqP->hqE->ue; + if (hqP->hqE->ue->csgMmbrSta == FALSE) + { + cmnCell->ncsgPrbCnt += rbAllocInfo->rbsAlloc; + } + cmnCell->totPrbCnt += rbAllocInfo->rbsAlloc; +#ifdef TENB_STATS + { + hqP->hqE->ue->tenbStats->stats.nonPersistent.sch[RG_SCH_CELLINDEX(hqP->hqE->cell)].dlPrbUsg += + rbAllocInfo->rbsAlloc; + hqP->hqE->ue->tenbStats->stats.nonPersistent.sch[RG_SCH_CELLINDEX(hqP->hqE->cell)].dlSumCw0iTbs += + rbAllocInfo->tbInfo[0].iTbs; + hqP->hqE->ue->tenbStats->stats.nonPersistent.sch[RG_SCH_CELLINDEX(hqP->hqE->cell)].dlNumCw0iTbs ++; + hqP->hqE->ue->tenbStats->stats.nonPersistent.sch[RG_SCH_CELLINDEX(hqP->hqE->cell)].dlTpt += + (rbAllocInfo->tbInfo[0].bytesAlloc << 3); + +#ifdef LTE_ADV + totPcellSCell += (rbAllocInfo->tbInfo[0].bytesAlloc << 3); + if(RG_SCH_IS_CELL_SEC(hqP->hqE->ue, cell)) + { + addedForScell += (rbAllocInfo->tbInfo[0].bytesAlloc << 3); + addedForScell1 += (rbAllocInfo->tbInfo[0].bytesAlloc << 3); +/* + printf (" Hqp %d cell %d addedForScell %lu addedForScell1 %lu sfn:sf %d:%d \n", + hqP->procId, + hqP->hqE->cell->cellId, + addedForScell, + addedForScell1, + cell->crntTime.sfn, + cell->crntTime.subframe); + */ + } +#endif + hqP->hqE->cell->tenbStats->sch.dlPrbUsage[0] += + rbAllocInfo->rbsAlloc; + hqP->hqE->cell->tenbStats->sch.dlSumCw0iTbs += + rbAllocInfo->tbInfo[0].iTbs; + hqP->hqE->cell->tenbStats->sch.dlNumCw0iTbs ++; + hqP->hqE->cell->tenbStats->sch.dlTtlTpt += + (rbAllocInfo->tbInfo[0].bytesAlloc << 3); + if (rbAllocInfo->tbInfo[1].schdlngForTb) + { + hqP->hqE->cell->tenbStats->sch.dlSumCw1iTbs += + rbAllocInfo->tbInfo[1].iTbs; + hqP->hqE->cell->tenbStats->sch.dlNumCw1iTbs ++; + hqP->hqE->ue->tenbStats->stats.nonPersistent.sch[RG_SCH_CELLINDEX(hqP->hqE->cell)].dlSumCw1iTbs += + rbAllocInfo->tbInfo[1].iTbs; + hqP->hqE->ue->tenbStats->stats.nonPersistent.sch[RG_SCH_CELLINDEX(hqP->hqE->cell)].dlNumCw1iTbs ++; + hqP->hqE->ue->tenbStats->stats.nonPersistent.sch[RG_SCH_CELLINDEX(hqP->hqE->cell)].dlTpt += + (rbAllocInfo->tbInfo[1].bytesAlloc << 3); + + +#ifdef LTE_ADV + if(RG_SCH_IS_CELL_SEC(hqP->hqE->ue, cell)) + { + addedForScell += (rbAllocInfo->tbInfo[1].bytesAlloc << 3); + addedForScell2 += (rbAllocInfo->tbInfo[1].bytesAlloc << 3); +/* + printf (" Hqp %d cell %d addedForScell %lu addedForScell2 %lu \n", + hqP->procId, + hqP->hqE->cell->cellId, + addedForScell, + addedForScell2); + */ + } + totPcellSCell += (rbAllocInfo->tbInfo[1].bytesAlloc << 3); +#endif + + + hqP->hqE->cell->tenbStats->sch.dlTtlTpt += + (rbAllocInfo->tbInfo[1].bytesAlloc << 3); + } + /* + printf ("add DL TPT is %lu sfn:sf %d:%d \n", hqP->hqE->ue->tenbStats->stats.nonPersistent.sch[RG_SCH_CELLINDEX(hqP->hqE->cell)].dlTpt , + cell->crntTime.sfn, + cell->crntTime.subframe); + */ + } +#endif + } + + pdcch->rnti = rbAllocInfo->rnti; + pdcch->dci.dciFormat = rbAllocInfo->dciFormat; + /* Update subframe and pdcch info in HqTb control block */ + switch(rbAllocInfo->dciFormat) + { +#ifdef RG_5GTF + case TFU_DCI_FORMAT_B1: + case TFU_DCI_FORMAT_B2: + { + // printf(" RG_5GTF:: Pdcch filling with DCI format B1/B2\n"); + rgSCHCmnFillHqPPdcchDciFrmtB1B2(cell, rbAllocInfo, hqP, \ + pdcch, tpc); + break; + } +#endif + default: + RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId, + "Allocator's incorrect dciForamt Fill for RNTI:%d",rbAllocInfo->rnti); + break; + } + RETVOID; +} + +/** + * @brief This function fills the PDCCH DCI format 1 information from dlProc. + * + * @details + * + * Function: rgSCHCmnFillHqPPdcchDciFrmt1 + * Purpose: This function fills in the PDCCH information + * obtained from the RgSchDlHqProcCb and RgSchDlRbAlloc + * for dedicated service scheduling. It also + * obtains TPC to be filled in from the power module. + * Assign the PDCCH to HQProc. + * + * Invoked by: Downlink Scheduler + * + * @param[in] RgSchCellCb* cell + * @param[in] RgSchDlRbAlloc* rbAllocInfo + * @param[in] RgDlHqProc* hqP + * @param[out] RgSchPdcch *pdcch + * @param[in] U8 tpc + * @return Void + * + **/ +#ifdef ANSI +PRIVATE Void rgSCHCmnFillHqPPdcchDciFrmt1 +( +RgSchCellCb *cell, +RgSchDlRbAlloc *rbAllocInfo, +RgSchDlHqProcCb *hqP, +RgSchPdcch *pdcch, +U8 tpc +) +#else +PRIVATE Void rgSCHCmnFillHqPPdcchDciFrmt1(cell, rbAllocInfo, hqP, pdcch, tpc) +RgSchCellCb *cell; +RgSchDlRbAlloc *rbAllocInfo; +RgSchDlHqProcCb *hqP; +RgSchPdcch *pdcch; +U8 tpc; +#endif +{ + +#ifdef LTE_TDD + RgSchTddANInfo *anInfo; +#endif + +#ifdef LTEMAC_SPS +/* For activation or reactivation, + * Harq ProcId should be 0 */ + RgSchCmnDlHqProc *cmnHqDl = RG_SCH_CMN_GET_DL_HQP(hqP); +#endif + + TRC2(rgSCHCmnFillHqPPdcchDciFrmt1) + + rgSCHCmnFillHqPTb(cell, rbAllocInfo, 0, pdcch); + pdcch->dci.u.format1Info.tpcCmd = tpc; + /* Avoiding this check,as we dont support Type1 RA */ +#ifdef RG_UNUSED + if (rbAllocInfo->raType == RG_SCH_CMN_RA_TYPE0) + { +#endif + pdcch->dci.u.format1Info.allocInfo.isAllocType0 = TRUE; + pdcch->dci.u.format1Info.allocInfo.resAllocMap[0] = + ((rbAllocInfo->allocInfo.raType0.dlAllocBitMask >> 24) + & 0xff); + pdcch->dci.u.format1Info.allocInfo.resAllocMap[1] = + ((rbAllocInfo->allocInfo.raType0.dlAllocBitMask >> 16) + & 0x00ff); + pdcch->dci.u.format1Info.allocInfo.resAllocMap[2] = + ((rbAllocInfo->allocInfo.raType0.dlAllocBitMask >> 8) + & 0x0000ff); + pdcch->dci.u.format1Info.allocInfo.resAllocMap[3] = + ((rbAllocInfo->allocInfo.raType0.dlAllocBitMask & 0x000000ff)); +#ifdef RG_UNUSED + } +#endif +#ifdef LTEMAC_SPS + if ((!(hqP->tbInfo[0].txCntr)) && + (cmnHqDl != (RgSchCmnDlHqProc*)NULLP && + ((cmnHqDl->spsAction & RG_SCH_CMN_SPS_DL_ACTV) || + (cmnHqDl->spsAction & RG_SCH_CMN_SPS_DL_REACTV))) + ) + { + pdcch->dci.u.format1Info.allocInfo.harqProcId = 0; + } + else + { + pdcch->dci.u.format1Info.allocInfo.harqProcId = hqP->procId; + } +#else + pdcch->dci.u.format1Info.allocInfo.harqProcId = hqP->procId; +#endif + + pdcch->dci.u.format1Info.allocInfo.ndi = + rbAllocInfo->tbInfo[0].tbCb->ndi; + pdcch->dci.u.format1Info.allocInfo.mcs = + rbAllocInfo->tbInfo[0].imcs; + pdcch->dci.u.format1Info.allocInfo.rv = + rbAllocInfo->tbInfo[0].tbCb->dlGrnt.rv; +#ifdef LTE_TDD + if(hqP->hqE->ue != NULLP) + { +#ifdef LTE_ADV + U8 servCellIdx = rgSchUtlGetServCellIdx(hqP->hqE->cell->instIdx, + hqP->hqE->cell->cellId, + hqP->hqE->ue); + + anInfo = rgSCHUtlGetUeANFdbkInfo(hqP->hqE->ue, + &(rbAllocInfo->tbInfo[0].tbCb->fdbkTime),servCellIdx); +#else + anInfo = rgSCHUtlGetUeANFdbkInfo(hqP->hqE->ue, + &(rbAllocInfo->tbInfo[0].tbCb->fdbkTime),0); +#endif +#ifdef TFU_TDD + if(anInfo) + { + pdcch->dci.u.format1Info.dai = RG_SCH_GET_DAI_VALUE(anInfo->dlDai); + } + else + { + /* Fixing DAI value - ccpu00109162 */ + pdcch->dci.u.format1Info.dai = RG_SCH_MAX_DAI_IDX; + } +#endif + } + else + { + /* always 0 for RACH */ + pdcch->dci.u.format1Info.allocInfo.harqProcId = 0; +#ifdef TFU_TDD + /* Fixing DAI value - ccpu00109162 */ + pdcch->dci.u.format1Info.dai = 1; +#endif + } +#endif + + + RETVOID; +} +/** + * @brief This function fills the PDCCH DCI format 1A information from dlProc. + * + * @details + * + * Function: rgSCHCmnFillHqPPdcchDciFrmt1A + * Purpose: This function fills in the PDCCH information + * obtained from the RgSchDlHqProcCb and RgSchDlRbAlloc + * for dedicated service scheduling. It also + * obtains TPC to be filled in from the power module. + * Assign the PDCCH to HQProc. + * + * Invoked by: Downlink Scheduler + * + * @param[in] RgSchCellCb* cell + * @param[in] RgSchDlRbAlloc* rbAllocInfo + * @param[in] RgDlHqProc* hqP + * @param[out] RgSchPdcch *pdcch + * @param[in] U8 tpc + * @return Void + * + **/ +#ifdef ANSI +PRIVATE Void rgSCHCmnFillHqPPdcchDciFrmt1A +( +RgSchCellCb *cell, +RgSchDlRbAlloc *rbAllocInfo, +RgSchDlHqProcCb *hqP, +RgSchPdcch *pdcch, +U8 tpc +) +#else +PRIVATE Void rgSCHCmnFillHqPPdcchDciFrmt1A(cell, rbAllocInfo, hqP, pdcch, tpc) +RgSchCellCb *cell; +RgSchDlRbAlloc *rbAllocInfo; +RgSchDlHqProcCb *hqP; +RgSchPdcch *pdcch; +U8 tpc; +#endif +{ + +#ifdef LTE_TDD + RgSchTddANInfo *anInfo; +#endif + +#ifdef LTEMAC_SPS + RgSchCmnDlHqProc *cmnHqDl = RG_SCH_CMN_GET_DL_HQP(hqP); +#endif + + TRC2(rgSCHCmnFillHqPPdcchDciFrmt1A) + + rgSCHCmnFillHqPTb(cell, rbAllocInfo, 0, pdcch); + pdcch->dci.u.format1aInfo.isPdcchOrder = FALSE; + pdcch->dci.u.format1aInfo.t.pdschInfo.tpcCmd = tpc; + pdcch->dci.u.format1aInfo.t.pdschInfo.allocInfo.mcs = \ + rbAllocInfo->tbInfo[0].imcs; + pdcch->dci.u.format1aInfo.t.pdschInfo.allocInfo.harqProcId.pres = TRUE; +#ifdef LTEMAC_SPS + if ((!(hqP->tbInfo[0].txCntr)) && + ( cmnHqDl != (RgSchCmnDlHqProc*)NULLP && + ((cmnHqDl->spsAction & RG_SCH_CMN_SPS_DL_ACTV) || + (cmnHqDl->spsAction & RG_SCH_CMN_SPS_DL_REACTV)) + )) + { + pdcch->dci.u.format1aInfo.t.pdschInfo.allocInfo.harqProcId.val = 0; + } + else + { + pdcch->dci.u.format1aInfo.t.pdschInfo.allocInfo.harqProcId.val + = hqP->procId; + } +#else + pdcch->dci.u.format1aInfo.t.pdschInfo.allocInfo.harqProcId.val = + hqP->procId; +#endif + pdcch->dci.u.format1aInfo.t.pdschInfo.allocInfo.ndi = \ + rbAllocInfo->tbInfo[0].tbCb->ndi; + pdcch->dci.u.format1aInfo.t.pdschInfo.allocInfo.rv = \ + rbAllocInfo->tbInfo[0].tbCb->dlGrnt.rv; + /* As of now, we do not support Distributed allocations */ + pdcch->dci.u.format1aInfo.t.pdschInfo.allocInfo.isLocal = TRUE; + pdcch->dci.u.format1aInfo.t.pdschInfo.allocInfo.nGap2.pres = NOTPRSNT; + pdcch->dci.u.format1aInfo.t.pdschInfo.allocInfo.alloc.type = + TFU_ALLOC_TYPE_RIV; + pdcch->dci.u.format1aInfo.t.pdschInfo.allocInfo.alloc.u.riv = + rgSCHCmnCalcRiv (cell->bwCfg.dlTotalBw, + rbAllocInfo->allocInfo.raType2.rbStart, + rbAllocInfo->allocInfo.raType2.numRb); +#ifdef LTE_TDD + if(hqP->hqE->ue != NULLP) + { +#ifdef LTE_ADV + U8 servCellIdx = rgSchUtlGetServCellIdx(hqP->hqE->cell->instIdx, + hqP->hqE->cell->cellId, + hqP->hqE->ue); + anInfo = rgSCHUtlGetUeANFdbkInfo(hqP->hqE->ue, + &(rbAllocInfo->tbInfo[0].tbCb->fdbkTime),servCellIdx); +#else + anInfo = rgSCHUtlGetUeANFdbkInfo(hqP->hqE->ue, + &(rbAllocInfo->tbInfo[0].tbCb->fdbkTime),0); +#endif +#ifdef TFU_TDD + pdcch->dci.u.format1aInfo.t.pdschInfo.dai.pres = TRUE; + if(anInfo) + { + pdcch->dci.u.format1aInfo.t.pdschInfo.dai.val = + RG_SCH_GET_DAI_VALUE(anInfo->dlDai); + } + else + { + /* Fixing DAI value - ccpu00109162 */ + pdcch->dci.u.format1aInfo.t.pdschInfo.dai.val = RG_SCH_MAX_DAI_IDX; + RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId, + "PDCCH is been scheduled without updating anInfo RNTI:%d", + rbAllocInfo->rnti); + } +#endif + } + else + { + /* always 0 for RACH */ + pdcch->dci.u.format1aInfo.t.pdschInfo.allocInfo.harqProcId.pres + = FALSE; +#ifdef TFU_TDD + pdcch->dci.u.format1aInfo.t.pdschInfo.dai.pres = TRUE; + /* Fixing DAI value - ccpu00109162 */ + pdcch->dci.u.format1aInfo.t.pdschInfo.dai.val = 1; +#endif + } +#endif + + RETVOID; +} +/** + * @brief This function fills the PDCCH DCI format 1B information from dlProc. + * + * @details + * + * Function: rgSCHCmnFillHqPPdcchDciFrmt1B + * Purpose: This function fills in the PDCCH information + * obtained from the RgSchDlHqProcCb and RgSchDlRbAlloc + * for dedicated service scheduling. It also + * obtains TPC to be filled in from the power module. + * Assign the PDCCH to HQProc. + * + * Invoked by: Downlink Scheduler + * + * @param[in] RgSchCellCb* cell + * @param[in] RgSchDlRbAlloc* rbAllocInfo + * @param[in] RgDlHqProc* hqP + * @param[out] RgSchPdcch *pdcch + * @param[in] U8 tpc + * @return Void + * + **/ +#ifdef ANSI +PRIVATE Void rgSCHCmnFillHqPPdcchDciFrmt1B +( +RgSchCellCb *cell, +RgSchDlRbAlloc *rbAllocInfo, +RgSchDlHqProcCb *hqP, +RgSchPdcch *pdcch, +U8 tpc +) +#else +PRIVATE Void rgSCHCmnFillHqPPdcchDciFrmt1B(cell, rbAllocInfo, hqP, pdcch, tpc) +RgSchCellCb *cell; +RgSchDlRbAlloc *rbAllocInfo; +RgSchDlHqProcCb *hqP; +RgSchPdcch *pdcch; +U8 tpc; +#endif +{ + +#ifdef LTE_TDD + RgSchTddANInfo *anInfo; +#endif + +#ifdef LTEMAC_SPS + RgSchCmnDlHqProc *cmnHqDl = RG_SCH_CMN_GET_DL_HQP(hqP); +#endif + + TRC2(rgSCHCmnFillHqPPdcchDciFrmt1B) + + rgSCHCmnFillHqPTb(cell, rbAllocInfo, 0, pdcch); + pdcch->dci.u.format1bInfo.tpcCmd = tpc; + pdcch->dci.u.format1bInfo.allocInfo.mcs = \ + rbAllocInfo->tbInfo[0].imcs; +#ifdef LTEMAC_SPS + if ((!(hqP->tbInfo[0].txCntr)) && + ( cmnHqDl != (RgSchCmnDlHqProc*)NULLP && + ((cmnHqDl->spsAction & RG_SCH_CMN_SPS_DL_ACTV) || + (cmnHqDl->spsAction & RG_SCH_CMN_SPS_DL_REACTV)) + )) + { + pdcch->dci.u.format1bInfo.allocInfo.harqProcId = 0; + } + else + { + pdcch->dci.u.format1bInfo.allocInfo.harqProcId = hqP->procId; + } +#else + pdcch->dci.u.format1bInfo.allocInfo.harqProcId = hqP->procId; +#endif + pdcch->dci.u.format1bInfo.allocInfo.ndi = \ + rbAllocInfo->tbInfo[0].tbCb->ndi; + pdcch->dci.u.format1bInfo.allocInfo.rv = \ + rbAllocInfo->tbInfo[0].tbCb->dlGrnt.rv; + /* As of now, we do not support Distributed allocations */ + pdcch->dci.u.format1bInfo.allocInfo.isLocal = TRUE; + pdcch->dci.u.format1bInfo.allocInfo.nGap2.pres = NOTPRSNT; + pdcch->dci.u.format1bInfo.allocInfo.alloc.type = + TFU_ALLOC_TYPE_RIV; + pdcch->dci.u.format1bInfo.allocInfo.alloc.u.riv = + rgSCHCmnCalcRiv (cell->bwCfg.dlTotalBw, + rbAllocInfo->allocInfo.raType2.rbStart, + rbAllocInfo->allocInfo.raType2.numRb); + /* Fill precoding Info */ + pdcch->dci.u.format1bInfo.allocInfo.pmiCfm = \ + rbAllocInfo->mimoAllocInfo.precIdxInfo >> 4; + pdcch->dci.u.format1bInfo.allocInfo.tPmi = \ + rbAllocInfo->mimoAllocInfo.precIdxInfo & 0x0F; +#ifdef LTE_TDD + if(hqP->hqE->ue != NULLP) + { +#ifdef LTE_ADV + U8 servCellIdx = rgSchUtlGetServCellIdx(hqP->hqE->cell->instIdx, + hqP->hqE->cell->cellId, + hqP->hqE->ue); + anInfo = rgSCHUtlGetUeANFdbkInfo(hqP->hqE->ue, + &(rbAllocInfo->tbInfo[0].tbCb->fdbkTime),servCellIdx); +#else + anInfo = rgSCHUtlGetUeANFdbkInfo(hqP->hqE->ue, + &(rbAllocInfo->tbInfo[0].tbCb->fdbkTime),0); +#endif +#ifdef TFU_TDD + if(anInfo) + { + pdcch->dci.u.format1bInfo.dai = + RG_SCH_GET_DAI_VALUE(anInfo->dlDai); + } + else + { + pdcch->dci.u.format1bInfo.dai = RG_SCH_MAX_DAI_IDX; + RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId, + "PDCCH is been scheduled without updating anInfo RNTI:%d", + rbAllocInfo->rnti); + } +#endif + } +#endif + + RETVOID; + +} +/** + * @brief This function fills the PDCCH DCI format 2 information from dlProc. + * + * @details + * + * Function: rgSCHCmnFillHqPPdcchDciFrmt2 + * Purpose: This function fills in the PDCCH information + * obtained from the RgSchDlHqProcCb and RgSchDlRbAlloc + * for dedicated service scheduling. It also + * obtains TPC to be filled in from the power module. + * Assign the PDCCH to HQProc. + * + * Invoked by: Downlink Scheduler + * + * @param[in] RgSchCellCb* cell + * @param[in] RgSchDlRbAlloc* rbAllocInfo + * @param[in] RgDlHqProc* hqP + * @param[out] RgSchPdcch *pdcch + * @param[in] U8 tpc + * @return Void + * + **/ +#ifdef ANSI +PRIVATE Void rgSCHCmnFillHqPPdcchDciFrmt2 +( +RgSchCellCb *cell, +RgSchDlRbAlloc *rbAllocInfo, +RgSchDlHqProcCb *hqP, +RgSchPdcch *pdcch, +U8 tpc +) +#else +PRIVATE Void rgSCHCmnFillHqPPdcchDciFrmt2(cell, rbAllocInfo, hqP, pdcch, tpc) +RgSchCellCb *cell; +RgSchDlRbAlloc *rbAllocInfo; +RgSchDlHqProcCb *hqP; +RgSchPdcch *pdcch; +U8 tpc; +#endif +{ + +#ifdef LTE_TDD + RgSchTddANInfo *anInfo; +#endif + +#ifdef LTEMAC_SPS +/* ccpu00119023-ADD-For activation or reactivation, + * Harq ProcId should be 0 */ + RgSchCmnDlHqProc *cmnHqDl = RG_SCH_CMN_GET_DL_HQP(hqP); +#endif + + TRC2(rgSCHCmnFillHqPPdcchDciFrmt2) + + rgSCHCmnFillHqPTb(cell, rbAllocInfo, 0, pdcch); + /*ccpu00120365:-ADD-call also if tb is disabled */ + if (rbAllocInfo->tbInfo[1].schdlngForTb || + rbAllocInfo->tbInfo[1].isDisabled) + { + rgSCHCmnFillHqPTb(cell, rbAllocInfo, 1, pdcch); + } + pdcch->dci.u.format2Info.tpcCmd = tpc; + /* Avoiding this check,as we dont support Type1 RA */ +#ifdef RG_UNUSED + if (rbAllocInfo->raType == RG_SCH_CMN_RA_TYPE0) + { +#endif + pdcch->dci.u.format2Info.allocInfo.isAllocType0 = TRUE; + pdcch->dci.u.format2Info.allocInfo.resAllocMap[0] = + ((rbAllocInfo->allocInfo.raType0.dlAllocBitMask >> 24) + & 0xff); + pdcch->dci.u.format2Info.allocInfo.resAllocMap[1] = + ((rbAllocInfo->allocInfo.raType0.dlAllocBitMask >> 16) + & 0x00ff); + pdcch->dci.u.format2Info.allocInfo.resAllocMap[2] = + ((rbAllocInfo->allocInfo.raType0.dlAllocBitMask >> 8) + & 0x0000ff); + pdcch->dci.u.format2Info.allocInfo.resAllocMap[3] = + ((rbAllocInfo->allocInfo.raType0.dlAllocBitMask & 0x000000ff)); +#ifdef RG_UNUSED + } +#endif +#ifdef LTEMAC_SPS + if ((!(hqP->tbInfo[0].txCntr)) && + ( cmnHqDl != (RgSchCmnDlHqProc*)NULLP && + ((cmnHqDl->spsAction & RG_SCH_CMN_SPS_DL_ACTV) || + (cmnHqDl->spsAction & RG_SCH_CMN_SPS_DL_REACTV)) + )) + { + pdcch->dci.u.format2Info.allocInfo.harqProcId = 0; + } + else + { + pdcch->dci.u.format2Info.allocInfo.harqProcId = hqP->procId; + } +#else + pdcch->dci.u.format2Info.allocInfo.harqProcId = hqP->procId; +#endif + /* Initialize the TB info for both the TBs */ + pdcch->dci.u.format2Info.allocInfo.tbInfo[0].mcs = 0; + pdcch->dci.u.format2Info.allocInfo.tbInfo[0].rv = 1; + pdcch->dci.u.format2Info.allocInfo.tbInfo[1].mcs = 0; + pdcch->dci.u.format2Info.allocInfo.tbInfo[1].rv = 1; + /* Fill tbInfo for scheduled TBs */ + pdcch->dci.u.format2Info.allocInfo.tbInfo[rbAllocInfo->tbInfo[0].\ + tbCb->tbIdx].ndi = rbAllocInfo->tbInfo[0].tbCb->ndi; + pdcch->dci.u.format2Info.allocInfo.tbInfo[rbAllocInfo->tbInfo[0].\ + tbCb->tbIdx].mcs = rbAllocInfo->tbInfo[0].imcs; + pdcch->dci.u.format2Info.allocInfo.tbInfo[rbAllocInfo->tbInfo[0].\ + tbCb->tbIdx].rv = rbAllocInfo->tbInfo[0].tbCb->dlGrnt.rv; + /* If we reach this function. It is safely assumed that + * rbAllocInfo->tbInfo[0] always has non default valid values. + * rbAllocInfo->tbInfo[1]'s scheduling is optional */ + if (rbAllocInfo->tbInfo[1].schdlngForTb == TRUE) + { + pdcch->dci.u.format2Info.allocInfo.tbInfo[rbAllocInfo->tbInfo[1].\ + tbCb->tbIdx].ndi = rbAllocInfo->tbInfo[1].tbCb->ndi; + pdcch->dci.u.format2Info.allocInfo.tbInfo[rbAllocInfo->tbInfo[1].\ + tbCb->tbIdx].mcs = rbAllocInfo->tbInfo[1].imcs; + pdcch->dci.u.format2Info.allocInfo.tbInfo[rbAllocInfo->tbInfo[1].\ + tbCb->tbIdx].rv = rbAllocInfo->tbInfo[1].tbCb->dlGrnt.rv; + } + pdcch->dci.u.format2Info.allocInfo.transSwap = + rbAllocInfo->mimoAllocInfo.swpFlg; + pdcch->dci.u.format2Info.allocInfo.precoding = + rbAllocInfo->mimoAllocInfo.precIdxInfo; +#ifdef LTE_TDD + if(hqP->hqE->ue != NULLP) + { + +#ifdef LTE_ADV + U8 servCellIdx = rgSchUtlGetServCellIdx(hqP->hqE->cell->instIdx, + hqP->hqE->cell->cellId, + hqP->hqE->ue); + anInfo = rgSCHUtlGetUeANFdbkInfo(hqP->hqE->ue, + &(rbAllocInfo->tbInfo[0].tbCb->fdbkTime),servCellIdx); +#else + anInfo = rgSCHUtlGetUeANFdbkInfo(hqP->hqE->ue, + &(rbAllocInfo->tbInfo[0].tbCb->fdbkTime),0); +#endif +#ifdef TFU_TDD + if(anInfo) + { + pdcch->dci.u.format2Info.dai = RG_SCH_GET_DAI_VALUE(anInfo->dlDai); + } + else + { + pdcch->dci.u.format2Info.dai = RG_SCH_MAX_DAI_IDX; + RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId, + "PDCCH is been scheduled without updating anInfo RNTI:%d", + rbAllocInfo->rnti); + } +#endif + } +#endif + + RETVOID; +} +/** + * @brief This function fills the PDCCH DCI format 2A information from dlProc. + * + * @details + * + * Function: rgSCHCmnFillHqPPdcchDciFrmt2A + * Purpose: This function fills in the PDCCH information + * obtained from the RgSchDlHqProcCb and RgSchDlRbAlloc + * for dedicated service scheduling. It also + * obtains TPC to be filled in from the power module. + * Assign the PDCCH to HQProc. + * + * Invoked by: Downlink Scheduler + * + * @param[in] RgSchCellCb* cell + * @param[in] RgSchDlRbAlloc* rbAllocInfo + * @param[in] RgDlHqProc* hqP + * @param[out] RgSchPdcch *pdcch + * @param[in] U8 tpc + * @return Void + * + **/ +#ifdef ANSI +PRIVATE Void rgSCHCmnFillHqPPdcchDciFrmt2A +( +RgSchCellCb *cell, +RgSchDlRbAlloc *rbAllocInfo, +RgSchDlHqProcCb *hqP, +RgSchPdcch *pdcch, +U8 tpc +) +#else +PRIVATE Void rgSCHCmnFillHqPPdcchDciFrmt2A(cell, rbAllocInfo, hqP, pdcch, tpc) +RgSchCellCb *cell; +RgSchDlRbAlloc *rbAllocInfo; +RgSchDlHqProcCb *hqP; +RgSchPdcch *pdcch; +U8 tpc; +#endif +{ +#ifdef LTE_TDD + RgSchTddANInfo *anInfo; +#endif + +#ifdef LTEMAC_SPS + RgSchCmnDlHqProc *cmnHqDl = RG_SCH_CMN_GET_DL_HQP(hqP); +#endif + + TRC2(rgSCHCmnFillHqPPdcchDciFrmt2A) + + rgSCHCmnFillHqPTb(cell, rbAllocInfo, 0, pdcch); + /*ccpu00120365:-ADD-call also if tb is disabled */ + if (rbAllocInfo->tbInfo[1].schdlngForTb || + rbAllocInfo->tbInfo[1].isDisabled) + { + + rgSCHCmnFillHqPTb(cell, rbAllocInfo, 1, pdcch); + } + + pdcch->dci.u.format2AInfo.tpcCmd = tpc; + /* Avoiding this check,as we dont support Type1 RA */ +#ifdef RG_UNUSED + if (rbAllocInfo->raType == RG_SCH_CMN_RA_TYPE0) + { +#endif + pdcch->dci.u.format2AInfo.allocInfo.isAllocType0 = TRUE; + pdcch->dci.u.format2AInfo.allocInfo.resAllocMap[0] = + ((rbAllocInfo->allocInfo.raType0.dlAllocBitMask >> 24) + & 0xff); + pdcch->dci.u.format2AInfo.allocInfo.resAllocMap[1] = + ((rbAllocInfo->allocInfo.raType0.dlAllocBitMask >> 16) + & 0x00ff); + pdcch->dci.u.format2AInfo.allocInfo.resAllocMap[2] = + ((rbAllocInfo->allocInfo.raType0.dlAllocBitMask >> 8) + & 0x0000ff); + pdcch->dci.u.format2AInfo.allocInfo.resAllocMap[3] = + ((rbAllocInfo->allocInfo.raType0.dlAllocBitMask & 0x000000ff)); +#ifdef RG_UNUSED + } +#endif +#ifdef LTEMAC_SPS + if ((!(hqP->tbInfo[0].txCntr)) && + ( cmnHqDl != (RgSchCmnDlHqProc*)NULLP && + ((cmnHqDl->spsAction & RG_SCH_CMN_SPS_DL_ACTV) || + (cmnHqDl->spsAction & RG_SCH_CMN_SPS_DL_REACTV)) + )) + { + pdcch->dci.u.format2AInfo.allocInfo.harqProcId = 0; + } + else + { + pdcch->dci.u.format2AInfo.allocInfo.harqProcId = hqP->procId; + } +#else + pdcch->dci.u.format2AInfo.allocInfo.harqProcId = hqP->procId; +#endif + /* Initialize the TB info for both the TBs */ + pdcch->dci.u.format2AInfo.allocInfo.tbInfo[0].mcs = 0; + pdcch->dci.u.format2AInfo.allocInfo.tbInfo[0].rv = 1; + pdcch->dci.u.format2AInfo.allocInfo.tbInfo[1].mcs = 0; + pdcch->dci.u.format2AInfo.allocInfo.tbInfo[1].rv = 1; + /* Fill tbInfo for scheduled TBs */ + pdcch->dci.u.format2AInfo.allocInfo.tbInfo[rbAllocInfo->tbInfo[0].\ + tbCb->tbIdx].ndi = rbAllocInfo->tbInfo[0].tbCb->ndi; + pdcch->dci.u.format2AInfo.allocInfo.tbInfo[rbAllocInfo->tbInfo[0].\ + tbCb->tbIdx].mcs = rbAllocInfo->tbInfo[0].imcs; + pdcch->dci.u.format2AInfo.allocInfo.tbInfo[rbAllocInfo->tbInfo[0].\ + tbCb->tbIdx].rv = rbAllocInfo->tbInfo[0].tbCb->dlGrnt.rv; + /* If we reach this function. It is safely assumed that + * rbAllocInfo->tbInfo[0] always has non default valid values. + * rbAllocInfo->tbInfo[1]'s scheduling is optional */ + + if (rbAllocInfo->tbInfo[1].schdlngForTb == TRUE) + { + pdcch->dci.u.format2AInfo.allocInfo.tbInfo[rbAllocInfo->tbInfo[1].\ + tbCb->tbIdx].ndi = rbAllocInfo->tbInfo[1].tbCb->ndi; + pdcch->dci.u.format2AInfo.allocInfo.tbInfo[rbAllocInfo->tbInfo[1].\ + tbCb->tbIdx].mcs = rbAllocInfo->tbInfo[1].imcs; + pdcch->dci.u.format2AInfo.allocInfo.tbInfo[rbAllocInfo->tbInfo[1].\ + tbCb->tbIdx].rv = rbAllocInfo->tbInfo[1].tbCb->dlGrnt.rv; + + } + pdcch->dci.u.format2AInfo.allocInfo.transSwap = + rbAllocInfo->mimoAllocInfo.swpFlg; + pdcch->dci.u.format2AInfo.allocInfo.precoding = + rbAllocInfo->mimoAllocInfo.precIdxInfo; +#ifdef LTE_TDD + if(hqP->hqE->ue != NULLP) + { +#ifdef LTE_ADV + U8 servCellIdx = rgSchUtlGetServCellIdx(hqP->hqE->cell->instIdx, + hqP->hqE->cell->cellId, + hqP->hqE->ue); + anInfo = rgSCHUtlGetUeANFdbkInfo(hqP->hqE->ue, + &(rbAllocInfo->tbInfo[0].tbCb->fdbkTime),servCellIdx); +#else + anInfo = rgSCHUtlGetUeANFdbkInfo(hqP->hqE->ue, + &(rbAllocInfo->tbInfo[0].tbCb->fdbkTime),0); +#endif +#ifdef TFU_TDD + if(anInfo) + { + pdcch->dci.u.format2AInfo.dai = RG_SCH_GET_DAI_VALUE(anInfo->dlDai); + } + else + { + pdcch->dci.u.format2AInfo.dai = RG_SCH_MAX_DAI_IDX; + RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId, + "PDCCH is been scheduled without updating anInfo RNTI:%d", + rbAllocInfo->rnti); + } +#endif + } +#endif + + + RETVOID; +} + +/** + * @brief init of Sch vars. + * + * @details + * + * Function: rgSCHCmnInitVars + Purpose: Initialization of various UL subframe indices + * + * @param[in] RgSchCellCb *cell + * @return Void + * + **/ +#ifdef ANSI +PRIVATE Void rgSCHCmnInitVars +( +RgSchCellCb *cell +) +#else +PRIVATE Void rgSCHCmnInitVars(cell) +RgSchCellCb *cell; +#endif +{ + RgSchCmnUlCell *cellUl = RG_SCH_CMN_GET_UL_CELL(cell); + + TRC2(rgSCHCmnInitVars); + + cellUl->idx = RGSCH_INVALID_INFO; + cellUl->schdIdx = RGSCH_INVALID_INFO; + cellUl->schdHqProcIdx = RGSCH_INVALID_INFO; + cellUl->msg3SchdIdx = RGSCH_INVALID_INFO; +#ifdef EMTC_ENBLE + cellUl->emtcMsg3SchdIdx = RGSCH_INVALID_INFO; +#endif + cellUl->msg3SchdHqProcIdx = RGSCH_INVALID_INFO; + cellUl->rcpReqIdx = RGSCH_INVALID_INFO; + cellUl->hqFdbkIdx[0] = RGSCH_INVALID_INFO; + cellUl->hqFdbkIdx[1] = RGSCH_INVALID_INFO; + cellUl->reTxIdx[0] = RGSCH_INVALID_INFO; + cellUl->reTxIdx[1] = RGSCH_INVALID_INFO; + /* Stack Crash problem for TRACE5 Changes. Added the return below */ + RETVOID; + +} + +#ifndef LTE_TDD +/** + * @brief Updation of Sch vars per TTI. + * + * @details + * + * Function: rgSCHCmnUpdVars + * Purpose: Updation of Sch vars per TTI. + * + * @param[in] RgSchCellCb *cell + * @return Void + * + **/ +#ifdef ANSI +PUBLIC Void rgSCHCmnUpdVars +( +RgSchCellCb *cell +) +#else +PUBLIC Void rgSCHCmnUpdVars(cell) +RgSchCellCb *cell; +#endif +{ + CmLteTimingInfo timeInfo; + RgSchCmnUlCell *cellUl = RG_SCH_CMN_GET_UL_CELL(cell); + U16 idx; + + TRC2(rgSCHCmnUpdVars); + + idx = (cell->crntTime.sfn * RGSCH_NUM_SUB_FRAMES_5G + cell->crntTime.subframe); + cellUl->idx = ((idx) % (RG_SCH_CMN_UL_NUM_SF)); +#ifdef UL_ADPT_DBG + printf("idx %d cellUl->idx %d RGSCH_NUM_SUB_FRAMES_5G %d time(%d %d) \n",idx,cellUl->idx ,RGSCH_NUM_SUB_FRAMES_5G,cell->crntTime.sfn,cell->crntTime.subframe); +#endif + /* Need to scheduler for after SCHED_DELTA */ + /* UL allocation has been advanced by 1 subframe + * so that we do not wrap around and send feedback + * before the data is even received by the PHY */ + /* Introduced timing delta for UL control */ + idx = (cellUl->idx + TFU_ULCNTRL_DLDELTA + RGSCH_PDCCH_PUSCH_DELTA); + cellUl->schdIdx = ((idx) % (RG_SCH_CMN_UL_NUM_SF)); + + RGSCHCMNADDTOCRNTTIME(cell->crntTime,timeInfo, + TFU_ULCNTRL_DLDELTA + RGSCH_PDCCH_PUSCH_DELTA) + cellUl->schdHqProcIdx = rgSCHCmnGetUlHqProcIdx(&timeInfo, cell); + + /* ccpu00127193 filling schdTime for logging and enhancement purpose*/ + cellUl->schdTime = timeInfo; + + /* msg3 scheduling two subframes after general scheduling */ + idx = (cellUl->idx + RG_SCH_CMN_DL_DELTA + RGSCH_RARSP_MSG3_DELTA); + cellUl->msg3SchdIdx = ((idx) % (RG_SCH_CMN_UL_NUM_SF)); + + RGSCHCMNADDTOCRNTTIME(cell->crntTime,timeInfo, + RG_SCH_CMN_DL_DELTA+ RGSCH_RARSP_MSG3_DELTA) + cellUl->msg3SchdHqProcIdx = rgSCHCmnGetUlHqProcIdx(&timeInfo, cell); + + idx = (cellUl->idx + TFU_RECPREQ_DLDELTA); + + cellUl->rcpReqIdx = ((idx) % (RG_SCH_CMN_UL_NUM_SF)); + + /* Downlink harq feedback is sometime after data reception / harq failure */ + /* Since feedback happens prior to scheduling being called, we add 1 to */ + /* take care of getting the correct subframe for feedback */ + idx = (cellUl->idx - TFU_CRCIND_ULDELTA + RG_SCH_CMN_UL_NUM_SF); +#ifdef UL_ADPT_DBG + printf("Finally setting cellUl->hqFdbkIdx[0] = %d TFU_CRCIND_ULDELTA %d RG_SCH_CMN_UL_NUM_SF %d\n",idx,TFU_CRCIND_ULDELTA,RG_SCH_CMN_UL_NUM_SF); +#endif + cellUl->hqFdbkIdx[0] = (idx % (RG_SCH_CMN_UL_NUM_SF)); + + idx = ((cellUl->schdIdx) % (RG_SCH_CMN_UL_NUM_SF)); + + cellUl->reTxIdx[0] = (U8) idx; +#ifdef UL_ADPT_DBG + printf("cellUl->hqFdbkIdx[0] %d cellUl->reTxIdx[0] %d \n",cellUl->hqFdbkIdx[0], cellUl->reTxIdx[0] ); +#endif + /* RACHO: update cmn sched specific RACH variables, + * mainly the prachMaskIndex */ + rgSCHCmnUpdRachParam(cell); + + RETVOID; +} +#endif + +#ifdef LTE_TDD + +/** + * @brief To get uplink subframe index associated with current PHICH + * transmission. + * + * @details + * + * Function: rgSCHCmnGetPhichUlSfIdx + * Purpose: Gets uplink subframe index associated with current PHICH + * transmission based on SFN and subframe no + * + * @param[in] CmLteTimingInfo *timeInfo + * @param[in] RgSchCellCb *cell + * @return U8 + * + **/ +#ifdef ANSI +PUBLIC U8 rgSCHCmnGetPhichUlSfIdx +( +CmLteTimingInfo *timeInfo, +RgSchCellCb *cell +) +#else +PUBLIC U8 rgSCHCmnGetPhichUlSfIdx(timeInfo, cell) +CmLteTimingInfo *timeInfo; +RgSchCellCb *cell; +#endif +{ + RgSchCmnUlCell *cellUl = RG_SCH_CMN_GET_UL_CELL(cell); + RgSchDlSf *dlsf; + U8 ulDlCfgIdx = cell->ulDlCfgIdx; + U8 idx; + U16 numUlSf; + U16 sfn; + U8 subframe; + + TRC2(rgSCHCmnGetPhichUlSfIdx); + + dlsf = rgSCHUtlSubFrmGet(cell, *timeInfo); + + if(dlsf->phichOffInfo.sfnOffset == RGSCH_INVALID_INFO) + { + RETVALUE(RGSCH_INVALID_INFO); + } + subframe = dlsf->phichOffInfo.subframe; + + sfn = (RGSCH_MAX_SFN + timeInfo->sfn - + dlsf->phichOffInfo.sfnOffset) % RGSCH_MAX_SFN; + + /* ccpu00130980: numUlSf(U16) parameter added to avoid integer + * wrap case such that idx will be proper*/ + numUlSf = rgSchTddNumUlSubfrmTbl[ulDlCfgIdx][RGSCH_NUM_SUB_FRAMES-1]; + numUlSf = ((numUlSf * sfn) + rgSchTddNumUlSubfrmTbl[ulDlCfgIdx][subframe]) - 1; + idx = numUlSf % (cellUl->numUlSubfrms); + + RETVALUE(idx); +} + +/** + * @brief To get uplink subframe index. + * + * @details + * + * + * Function: rgSCHCmnGetUlSfIdx + * Purpose: Gets uplink subframe index based on SFN and subframe number. + * + * @param[in] CmLteTimingInfo *timeInfo + * @param[in] U8 ulDlCfgIdx + * @return U8 + * + **/ +#ifdef ANSI +PUBLIC U8 rgSCHCmnGetUlSfIdx +( +CmLteTimingInfo *timeInfo, +RgSchCellCb *cell +) +#else +PUBLIC U8 rgSCHCmnGetUlSfIdx(timeInfo, cell) +CmLteTimingInfo *timeInfo; +RgSchCellCb *cell; +#endif +{ + RgSchCmnUlCell *cellUl = RG_SCH_CMN_GET_UL_CELL(cell); + U8 ulDlCfgIdx = cell->ulDlCfgIdx; + U8 idx = 0; + U16 numUlSf; + + TRC2(rgSCHCmnGetUlSfIdx); + + /* ccpu00130980: numUlSf(U16) parameter added to avoid integer + * wrap case such that idx will be proper*/ + numUlSf = rgSchTddNumUlSubfrmTbl[ulDlCfgIdx][RGSCH_NUM_SUB_FRAMES-1]; + numUlSf = ((numUlSf * timeInfo->sfn) + \ + rgSchTddNumUlSubfrmTbl[ulDlCfgIdx][timeInfo->subframe]) - 1; + idx = numUlSf % (cellUl->numUlSubfrms); + + RETVALUE(idx); +} + +#endif + +/** + * @brief To get uplink hq index. + * + * @details + * + * + * Function: rgSCHCmnGetUlHqProcIdx + * Purpose: Gets uplink subframe index based on SFN and subframe number. + * + * @param[in] CmLteTimingInfo *timeInfo + * @param[in] U8 ulDlCfgIdx + * @return U8 + * + **/ +#ifdef ANSI +PUBLIC U8 rgSCHCmnGetUlHqProcIdx +( +CmLteTimingInfo *timeInfo, +RgSchCellCb *cell +) +#else +PUBLIC U8 rgSCHCmnGetUlHqProcIdx(timeInfo, cell) +CmLteTimingInfo *timeInfo; +RgSchCellCb *cell; +#endif +{ + U8 procId; + U32 numUlSf; + +#ifndef LTE_TDD + numUlSf = (timeInfo->sfn * RGSCH_NUM_SUB_FRAMES_5G + timeInfo->subframe); + procId = numUlSf % RGSCH_NUM_UL_HQ_PROC; +#else + U8 ulDlCfgIdx = cell->ulDlCfgIdx; + /*ccpu00130639 - MOD - To get correct UL HARQ Proc IDs for all UL/DL Configs*/ + U8 numUlSfInSfn; + S8 sfnCycle = cell->tddHqSfnCycle; + U8 numUlHarq = rgSchTddUlNumHarqProcTbl[ulDlCfgIdx] + + /* TRACE 5 Changes */ + TRC2(rgSCHCmnGetUlHqProcIdx); + + /* Calculate the number of UL SF in one SFN */ + numUlSfInSfn = RGSCH_NUM_SUB_FRAMES - + rgSchTddNumDlSubfrmTbl[ulDlCfgIdx][RGSCH_NUM_SUB_FRAMES-1]; + + /* Check for the SFN wrap around case */ + if(cell->crntTime.sfn == 1023 && timeInfo->sfn == 0) + { + sfnCycle++; + } + else if(cell->crntTime.sfn == 0 && timeInfo->sfn == 1023) + { + /* sfnCycle decremented by 1 */ + sfnCycle = (sfnCycle + numUlHarq-1) % numUlHarq; + } + /* Calculate the total number of UL sf */ + /* -1 is done since uplink sf are counted from 0 */ + numUlSf = numUlSfInSfn * (timeInfo->sfn + (sfnCycle*1024)) + + rgSchTddNumUlSubfrmTbl[ulDlCfgIdx][timeInfo->subframe] - 1; + + procId = numUlSf % numUlHarq; +#endif + RETVALUE(procId); +} + + +/* UL_ALLOC_CHANGES */ +/*********************************************************** + * + * Func : rgSCHCmnUlFreeAlloc + * + * Desc : Free an allocation - invokes UHM and releases + * alloc for the scheduler + * Doest need subframe as argument + * + * Ret : + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PUBLIC Void rgSCHCmnUlFreeAlloc +( +RgSchCellCb *cell, +RgSchUlAlloc *alloc +) +#else +PUBLIC Void rgSCHCmnUlFreeAlloc(cell, alloc) +RgSchCellCb *cell; +RgSchUlAlloc *alloc; +#endif +{ + RgSchUlHqProcCb *hqProc; + TRC2(rgSCHCmnUlFreeAllocation); + + if (alloc->forMsg3) + { + /* Fix : Release RNTI upon MSG3 max TX failure for non-HO UEs */ + if ((alloc->hqProc->remTx == 0) && + (alloc->hqProc->rcvdCrcInd == FALSE) && + (alloc->raCb)) + { + RgSchRaCb *raCb = alloc->raCb; + rgSCHUhmFreeProc(alloc->hqProc, cell); + rgSCHUtlUlAllocRelease(alloc); + rgSCHRamDelRaCb(cell, raCb, TRUE); + RETVOID; + } + } + + hqProc = alloc->hqProc; + rgSCHUtlUlAllocRelease(alloc); + rgSCHUhmFreeProc(hqProc, cell); + RETVOID; +} + + +/*********************************************************** + * + * Func : rgSCHCmnUlFreeAllocation + * + * Desc : Free an allocation - invokes UHM and releases + * alloc for the scheduler + * + * Ret : + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PUBLIC Void rgSCHCmnUlFreeAllocation +( +RgSchCellCb *cell, +RgSchUlSf *sf, +RgSchUlAlloc *alloc +) +#else +PUBLIC Void rgSCHCmnUlFreeAllocation(cell, sf, alloc) +RgSchCellCb *cell; +RgSchUlSf *sf; +RgSchUlAlloc *alloc; +#endif +{ + RgSchUlHqProcCb *hqProc; + + TRC2(rgSCHCmnUlFreeAllocation); + + if (alloc->forMsg3) + { + /* Fix : Release RNTI upon MSG3 max TX failure for non-HO UEs */ + if ((alloc->hqProc->remTx == 0) && + (alloc->hqProc->rcvdCrcInd == FALSE) && + (alloc->raCb)) + { + RgSchRaCb *raCb = alloc->raCb; + rgSCHUhmFreeProc(alloc->hqProc, cell); + rgSCHUtlUlAllocRls(sf, alloc); + rgSCHRamDelRaCb(cell, raCb, TRUE); + RETVOID; + } + } + + hqProc = alloc->hqProc; + rgSCHUhmFreeProc(hqProc, cell); +#ifdef LTE_L2_MEAS + /* re-setting the PRB count while freeing the allocations */ + sf->totPrb = 0; +#endif + rgSCHUtlUlAllocRls(sf, alloc); + + RETVOID; +} + +/** + * @brief This function implements PDCCH allocation for an UE + * in the currently running subframe. + * + * @details + * + * Function: rgSCHCmnPdcchAllocCrntSf + * Purpose: This function determines current DL subframe + * and UE DL CQI to call the actual pdcch allocator + * function. + * Note that this function is called only + * when PDCCH request needs to be made during + * uplink scheduling. + * + * Invoked by: Scheduler + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ue + * @return RgSchPdcch * + * -# NULLP when unsuccessful + **/ +#ifdef ANSI +PUBLIC RgSchPdcch *rgSCHCmnPdcchAllocCrntSf +( +RgSchCellCb *cell, +RgSchUeCb *ue +) +#else +PUBLIC RgSchPdcch *rgSCHCmnPdcchAllocCrntSf(cell, ue) +RgSchCellCb *cell; +RgSchUeCb *ue; +#endif +{ + CmLteTimingInfo frm = cell->crntTime; + RgSchCmnDlUe *ueDl = RG_SCH_CMN_GET_DL_UE(ue,cell); + RgSchDlSf *sf; + RgSchPdcch *pdcch = NULLP; + + TRC2(rgSCHCmnPdcchAllocCrntSf); + RGSCH_INCR_SUB_FRAME(frm, TFU_ULCNTRL_DLDELTA); + sf = rgSCHUtlSubFrmGet(cell, frm); + +#ifdef LTE_ADV + if (ue->allocCmnUlPdcch) + { + pdcch = rgSCHCmnCmnPdcchAlloc(cell, sf); + /* Since CRNTI Scrambled */ + if(NULLP != pdcch) + { + pdcch->dciNumOfBits = ue->dciSize.cmnSize[TFU_DCI_FORMAT_0]; + } + } + else +#endif + { + //pdcch = rgSCHCmnPdcchAlloc(cell, ue, sf, y, ueDl->mimoInfo.cwInfo[0].cqi, TFU_DCI_FORMAT_0, FALSE); + pdcch = rgSCHCmnPdcchAlloc(cell, ue, sf, ueDl->mimoInfo.cwInfo[0].cqi, TFU_DCI_FORMAT_A1, FALSE); + } + RETVALUE(pdcch); +} + +/*********************************************************** + * + * Func : rgSCHCmnUlAllocFillNdmrs + * + * Desc : Determines and fills N_dmrs for a UE uplink + * allocation. + * + * Ret : + * + * Notes: N_dmrs determination is straightforward, so + * it is configured per subband + * + * File : + * + **********************************************************/ +#ifdef ANSI +PUBLIC Void rgSCHCmnUlAllocFillNdmrs +( +RgSchCmnUlCell *cellUl, +RgSchUlAlloc *alloc +) +#else +PUBLIC Void rgSCHCmnUlAllocFillNdmrs(cellUl, alloc) +RgSchCmnUlCell *cellUl; +RgSchUlAlloc *alloc; +#endif +{ + TRC2(rgSCHCmnUlAllocFillNdmrs); + alloc->grnt.nDmrs = cellUl->dmrsArr[alloc->sbStart]; + RETVOID; +} + +/*********************************************************** + * + * Func : rgSCHCmnUlAllocLnkHqProc + * + * Desc : Links a new allocation for an UE with the + * appropriate HARQ process of the UE. + * + * Ret : + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PUBLIC Void rgSCHCmnUlAllocLnkHqProc +( +RgSchUeCb *ue, +RgSchUlAlloc *alloc, +RgSchUlHqProcCb *proc, +Bool isRetx +) +#else +PUBLIC Void rgSCHCmnUlAllocLnkHqProc(ue, alloc, proc, isRetx) +RgSchUeCb *ue; +RgSchUlAlloc *alloc; +RgSchUlHqProcCb *proc; +Bool isRetx; +#endif +{ + TRC2(rgSCHCmnUlAllocLnkHqProc); + + if(TRUE == isRetx) + { + rgSCHCmnUlAdapRetx(alloc, proc); + } + else + { +#ifdef LTE_L2_MEAS /* L2_COUNTERS */ + alloc->ue = ue; +#endif + rgSCHUhmNewTx(proc, (((RgUeUlHqCb*)proc->hqEnt)->maxHqRetx), alloc); + } + RETVOID; +} + +/** + * @brief This function releases a PDCCH in the subframe that is + * currently being allocated for. + * + * @details + * + * Function: rgSCHCmnPdcchRlsCrntSf + * Purpose: This function determines current DL subframe + * which is considered for PDCCH allocation, + * and then calls the actual function that + * releases a PDCCH in a specific subframe. + * Note that this function is called only + * when PDCCH release needs to be made during + * uplink scheduling. + * + * Invoked by: Scheduler + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchPdcch *pdcch + * @return Void + **/ +#ifdef ANSI +PUBLIC Void rgSCHCmnPdcchRlsCrntSf +( +RgSchCellCb *cell, +RgSchPdcch *pdcch +) +#else +PUBLIC Void rgSCHCmnPdcchRlsCrntSf(cell, pdcch) +RgSchCellCb *cell; +RgSchPdcch *pdcch; +#endif +{ + CmLteTimingInfo frm = cell->crntTime; + RgSchDlSf *sf; + + TRC2(rgSCHCmnPdcchRlsCrntSf); + + RGSCH_INCR_SUB_FRAME(frm, TFU_ULCNTRL_DLDELTA); + sf = rgSCHUtlSubFrmGet(cell, frm); + rgSCHUtlPdcchPut(cell, &sf->pdcchInfo, pdcch); + RETVOID; +} +/*********************************************************** + * + * Func : rgSCHCmnUlFillPdcchWithAlloc + * + * Desc : Fills a PDCCH with format 0 information. + * + * Ret : + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PUBLIC Void rgSCHCmnUlFillPdcchWithAlloc +( +RgSchPdcch *pdcch, +RgSchUlAlloc *alloc, +RgSchUeCb *ue +) +#else +PUBLIC Void rgSCHCmnUlFillPdcchWithAlloc(pdcch, alloc, ue) +RgSchPdcch *pdcch; +RgSchUlAlloc *alloc; +RgSchUeCb *ue; +#endif +{ + + TRC2(rgSCHCmnUlFillPdcchWithAlloc); + + pdcch->ue = ue; + pdcch->rnti = alloc->rnti; + //pdcch->dci.dciFormat = TFU_DCI_FORMAT_A2; + pdcch->dci.dciFormat = alloc->grnt.dciFrmt; + + //Currently hardcoding values here. + //printf("Filling 5GTF UL DCI for rnti %d \n",alloc->rnti); + switch(pdcch->dci.dciFormat) + { + case TFU_DCI_FORMAT_A1: + { + pdcch->dci.u.formatA1Info.formatType = 0; + pdcch->dci.u.formatA1Info.xPUSCHRange = alloc->grnt.xPUSCHRange; + pdcch->dci.u.formatA1Info.xPUSCH_TxTiming = 0; + pdcch->dci.u.formatA1Info.RBAssign = alloc->grnt.rbAssign; + pdcch->dci.u.formatA1Info.u.rbAssignA1Val324.hqProcId = alloc->grnt.hqProcId; + pdcch->dci.u.formatA1Info.u.rbAssignA1Val324.mcs = alloc->grnt.iMcsCrnt; + pdcch->dci.u.formatA1Info.u.rbAssignA1Val324.ndi = alloc->hqProc->ndi; + pdcch->dci.u.formatA1Info.CSI_BSI_BRI_Req = 0; + pdcch->dci.u.formatA1Info.CSIRS_BRRS_TxTiming = 0; + pdcch->dci.u.formatA1Info.CSIRS_BRRS_SymbIdx = 0; + pdcch->dci.u.formatA1Info.CSIRS_BRRS_ProcInd = 0; + pdcch->dci.u.formatA1Info.numBSI_Reports = 0; + pdcch->dci.u.formatA1Info.uciOnxPUSCH = alloc->grnt.uciOnxPUSCH; + pdcch->dci.u.formatA1Info.beamSwitch = 0; + pdcch->dci.u.formatA1Info.SRS_Config = 0; + pdcch->dci.u.formatA1Info.SRS_Symbol = 0; + pdcch->dci.u.formatA1Info.REMapIdx_DMRS_PCRS_numLayers = 0; + pdcch->dci.u.formatA1Info.SCID = alloc->grnt.SCID; + pdcch->dci.u.formatA1Info.PMI = alloc->grnt.PMI; + pdcch->dci.u.formatA1Info.UL_PCRS = 0; + pdcch->dci.u.formatA1Info.tpcCmd = alloc->grnt.tpc; + break; + } + case TFU_DCI_FORMAT_A2: + { + pdcch->dci.u.formatA2Info.formatType = 1; + pdcch->dci.u.formatA2Info.xPUSCHRange = alloc->grnt.xPUSCHRange; + pdcch->dci.u.formatA2Info.xPUSCH_TxTiming = 0; + pdcch->dci.u.formatA2Info.RBAssign = alloc->grnt.rbAssign; + pdcch->dci.u.formatA2Info.u.rbAssignA1Val324.hqProcId = alloc->grnt.hqProcId; + pdcch->dci.u.formatA2Info.u.rbAssignA1Val324.mcs = alloc->grnt.iMcsCrnt; + pdcch->dci.u.formatA2Info.u.rbAssignA1Val324.ndi = alloc->hqProc->ndi; + pdcch->dci.u.formatA2Info.CSI_BSI_BRI_Req = 0; + pdcch->dci.u.formatA2Info.CSIRS_BRRS_TxTiming = 0; + pdcch->dci.u.formatA2Info.CSIRS_BRRS_SymbIdx = 0; + pdcch->dci.u.formatA2Info.CSIRS_BRRS_ProcInd = 0; + pdcch->dci.u.formatA2Info.numBSI_Reports = 0; + pdcch->dci.u.formatA2Info.uciOnxPUSCH = alloc->grnt.uciOnxPUSCH; + pdcch->dci.u.formatA2Info.beamSwitch = 0; + pdcch->dci.u.formatA2Info.SRS_Config = 0; + pdcch->dci.u.formatA2Info.SRS_Symbol = 0; + pdcch->dci.u.formatA2Info.REMapIdx_DMRS_PCRS_numLayers = 0; + pdcch->dci.u.formatA2Info.SCID = alloc->grnt.SCID; + pdcch->dci.u.formatA2Info.PMI = alloc->grnt.PMI; + pdcch->dci.u.formatA2Info.UL_PCRS = 0; + pdcch->dci.u.formatA2Info.tpcCmd = alloc->grnt.tpc; + break; + } + default: + RLOG1(L_ERROR," 5GTF_ERROR UL Allocator's icorrect " + "dciForamt Fill RNTI:%d",alloc->rnti); + break; + } + + + RETVOID; +} + +/*********************************************************** + * + * Func : rgSCHCmnUlAllocFillTpc + * + * Desc : Determines and fills TPC for an UE allocation. + * + * Ret : + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PUBLIC Void rgSCHCmnUlAllocFillTpc +( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgSchUlAlloc *alloc +) +#else +PUBLIC Void rgSCHCmnUlAllocFillTpc(cell, ue, alloc) +RgSchCellCb *cell; +RgSchUeCb *ue; +RgSchUlAlloc *alloc; +#endif +{ + TRC2(rgSCHCmnUlAllocFillTpc); + alloc->grnt.tpc = rgSCHPwrPuschTpcForUe(cell, ue); + RETVOID; +} + + +/*********************************************************** + * + * Func : rgSCHCmnAddUeToRefreshQ + * + * Desc : Adds a UE to refresh queue, so that the UE is + * periodically triggered to refresh it's GBR and + * AMBR values. + * + * Ret : + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PRIVATE Void rgSCHCmnAddUeToRefreshQ +( +RgSchCellCb *cell, +RgSchUeCb *ue, +U32 wait +) +#else +PRIVATE Void rgSCHCmnAddUeToRefreshQ(cell, ue, wait) +RgSchCellCb *cell; +RgSchUeCb *ue; +U32 wait; +#endif +{ + RgSchCmnCell *sched = RG_SCH_CMN_GET_CELL(cell); + CmTmrArg arg; + RgSchCmnUeInfo *ueSchd = RG_SCH_CMN_GET_CMN_UE(ue); + + TRC2(rgSCHCmnAddUeToRefreshQ); + UNUSED(cell); + + cmMemset((U8 *)&arg, 0, sizeof(arg)); + arg.tqCp = &sched->tmrTqCp; + arg.tq = sched->tmrTq; + arg.timers = &ueSchd->tmr; + arg.cb = (PTR)ue; + arg.tNum = 0; + arg.max = 1; + arg.evnt = RG_SCH_CMN_EVNT_UE_REFRESH; + arg.wait = wait; + cmPlcCbTq(&arg); + RETVOID; +} + +/** + * @brief Perform UE reset procedure. + * + * @details + * + * Function : rgSCHCmnUlUeReset + * + * This functions performs BSR resetting and + * triggers UL specific scheduler + * to Perform UE reset procedure. + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ue + * @return Void + **/ +#ifdef ANSI +PRIVATE Void rgSCHCmnUlUeReset +( +RgSchCellCb *cell, +RgSchUeCb *ue +) +#else +PRIVATE Void rgSCHCmnUlUeReset(cell, ue) +RgSchCellCb *cell; +RgSchUeCb *ue; +#endif +{ + RgSchCmnCell *cellSchd = RG_SCH_CMN_GET_CELL(cell); + RgSchCmnUlUe *ueUl = RG_SCH_CMN_GET_UL_UE(ue,cell); + U8 lcgCnt=0; + RgSchCmnLcg *lcgCmn; + CmLList *node; + RgSchCmnAllocRecord *allRcd; + TRC2(rgSCHCmnUlUeReset); + + ue->ul.minReqBytes = 0; + ue->ul.totalBsr = 0; + ue->ul.effBsr = 0; + ue->ul.nonGbrLcgBs = 0; + ue->ul.effAmbr = ue->ul.cfgdAmbr; + + node = ueUl->ulAllocLst.first; + while (node) + { + allRcd = (RgSchCmnAllocRecord *)node->node; + allRcd->alloc = 0; + node = node->next; + } + for(lcgCnt = 0; lcgCnt < RGSCH_MAX_LCG_PER_UE; lcgCnt++) + { + lcgCmn = RG_SCH_CMN_GET_UL_LCG(&ue->ul.lcgArr[lcgCnt]); + lcgCmn->bs = 0; + lcgCmn->reportedBs = 0; + lcgCmn->effGbr = lcgCmn->cfgdGbr; + lcgCmn->effDeltaMbr = lcgCmn->deltaMbr; + } + rgSCHCmnUlUeDelAllocs(cell, ue); + + ue->isSrGrant = FALSE; + + cellSchd->apisUl->rgSCHUlUeReset(cell, ue); + + /* Stack Crash problem for TRACE5 changes. Added the return below */ + RETVOID; + +} + +/** + * @brief RESET UL CQI and DL CQI&RI to conservative values + * for a reestablishing UE. + * + * @details + * + * Function : rgSCHCmnResetRiCqi + * + * RESET UL CQI and DL CQI&RI to conservative values + * for a reestablishing UE + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ue + * @return Void + **/ +#ifdef ANSI +PRIVATE Void rgSCHCmnResetRiCqi +( +RgSchCellCb *cell, +RgSchUeCb *ue +) +#else +PRIVATE Void rgSCHCmnResetRiCqi(cell, ue) +RgSchCellCb *cell; +RgSchUeCb *ue; +#endif +{ + RgSchCmnCell *cellSchd = RG_SCH_CMN_GET_CELL(cell); + RgSchCmnUe *ueSchCmn = RG_SCH_CMN_GET_UE(ue,cell); + RgSchCmnDlUe *ueDl = RG_SCH_CMN_GET_DL_UE(ue,cell); + RgSchCmnUlUe *ueUl = RG_SCH_CMN_GET_UL_UE(ue,cell); + + TRC2(rgSCHCmnResetRiCqi); + + rgSCHCmnUpdUeUlCqiInfo(cell, ue, ueUl, ueSchCmn, cellSchd, + cell->isCpUlExtend); + + ueDl->mimoInfo.cwInfo[0].cqi = cellSchd->dl.ccchCqi; + ueDl->mimoInfo.cwInfo[1].cqi = cellSchd->dl.ccchCqi; + ueDl->mimoInfo.ri = 1; + if ((ue->mimoInfo.txMode == RGR_UE_TM_4) || + (ue->mimoInfo.txMode == RGR_UE_TM_6)) + { + RG_SCH_CMN_SET_FORCE_TD(ue, cell, RG_SCH_CMN_TD_NO_PMI); + } + if (ue->mimoInfo.txMode == RGR_UE_TM_3) + { + RG_SCH_CMN_SET_FORCE_TD(ue, cell, RG_SCH_CMN_TD_RI_1); + } +#ifdef EMTC_ENABLE + rgSCHCmnDlSetUeAllocLmt(cell, ueDl, ue->isEmtcUe); +#else + rgSCHCmnDlSetUeAllocLmt(cell, ueDl, FALSE); +#endif + +#ifdef TFU_UPGRADE + /* Request for an early Aper CQI in case of reest */ + RgSchUeACqiCb *acqiCb = RG_SCH_CMN_GET_ACQICB(ue,cell); + if(acqiCb && acqiCb->aCqiCfg.pres) + { + acqiCb->aCqiTrigWt = 0; + } +#endif + + RETVOID; +} + +/** + * @brief Perform UE reset procedure. + * + * @details + * + * Function : rgSCHCmnDlUeReset + * + * This functions performs BO resetting and + * triggers DL specific scheduler + * to Perform UE reset procedure. + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ue + * @return Void + **/ +#ifdef ANSI +PRIVATE Void rgSCHCmnDlUeReset +( +RgSchCellCb *cell, +RgSchUeCb *ue +) +#else +PRIVATE Void rgSCHCmnDlUeReset(cell, ue) +RgSchCellCb *cell; +RgSchUeCb *ue; +#endif +{ + RgSchCmnCell *cellSchd = RG_SCH_CMN_GET_CELL(cell); + RgSchCmnDlCell *cellCmnDl = RG_SCH_CMN_GET_DL_CELL(cell); + RgSchCmnDlUe *ueDl = RG_SCH_CMN_GET_DL_UE(ue,cell); + + TRC2(rgSCHCmnDlUeReset); + + if (ueDl->rachInfo.poLnk.node != NULLP) + { + rgSCHCmnDlRmvFrmPdcchOdrQ(cell, ue); + } + + /* Fix: syed Remove from TA List if this UE is there. + * If TA Timer is running. Stop it */ + if (ue->dlTaLnk.node) + { + cmLListDelFrm(&cellCmnDl->taLst, &ue->dlTaLnk); + ue->dlTaLnk.node = (PTR)NULLP; + } + else if (ue->taTmr.tmrEvnt != TMR_NONE) + { + rgSCHTmrStopTmr(cell, ue->taTmr.tmrEvnt, ue); + } + + cellSchd->apisDl->rgSCHDlUeReset(cell, ue); +#ifdef LTE_ADV + if (ue->numSCells) + { + rgSCHSCellDlUeReset(cell,ue); + } +#endif +} + +/** + * @brief Perform UE reset procedure. + * + * @details + * + * Function : rgSCHCmnUeReset + * + * This functions triggers specific scheduler + * to Perform UE reset procedure. + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ue + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC Void rgSCHCmnUeReset +( +RgSchCellCb *cell, +RgSchUeCb *ue +) +#else +PUBLIC Void rgSCHCmnUeReset(cell, ue) +RgSchCellCb *cell; +RgSchUeCb *ue; +#endif +{ + U8 idx; + Pst pst; + RgInfResetHqEnt hqEntRstInfo; + + TRC2(rgSCHCmnUeReset); + /* RACHO: remove UE from pdcch, handover and rapId assoc Qs */ + rgSCHCmnDelRachInfo(cell, ue); + + rgSCHPwrUeReset(cell, ue); + + rgSCHCmnUlUeReset(cell, ue); + rgSCHCmnDlUeReset(cell, ue); + +#ifdef LTE_ADV + /* Making allocCmnUlPdcch TRUE to allocate DCI0/1A from Common search space. + As because multiple cells are added hence 2 bits CqiReq is there + This flag will be set to FALSE once we will get Scell READY */ + ue->allocCmnUlPdcch = TRUE; +#endif + + /* Fix : syed RESET UL CQI and DL CQI&RI to conservative values + * for a reestablishing UE */ + /*Reset Cqi Config for all the configured cells*/ + for (idx = 0;idx < CM_LTE_MAX_CELLS; idx++) + { + if (ue->cellInfo[idx] != NULLP) + { + rgSCHCmnResetRiCqi(ue->cellInfo[idx]->cell, ue); + } + } + /*After Reset Trigger APCQI for Pcell*/ + RgSchUeCellInfo *pCellInfo = RG_SCH_CMN_GET_PCELL_INFO(ue); + if(pCellInfo->acqiCb.aCqiCfg.pres) + { + ue->dl.reqForCqi = RG_SCH_APCQI_SERVING_CC; + } + +/* sending HqEnt reset to MAC */ + hqEntRstInfo.cellId = cell->cellId; + hqEntRstInfo.crnti = ue->ueId; + + rgSCHUtlGetPstToLyr(&pst, &rgSchCb[cell->instIdx], cell->macInst); + RgSchMacRstHqEnt(&pst,&hqEntRstInfo); + + RETVOID; +} + +/** + * @brief UE out of MeasGap or AckNackReptn. + * + * @details + * + * Function : rgSCHCmnActvtUlUe + * + * This functions triggers specific scheduler + * to start considering it for scheduling. + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ue + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC Void rgSCHCmnActvtUlUe +( +RgSchCellCb *cell, +RgSchUeCb *ue +) +#else +PUBLIC Void rgSCHCmnActvtUlUe(cell, ue) +RgSchCellCb *cell; +RgSchUeCb *ue; +#endif +{ + RgSchCmnCell *cellSchd = RG_SCH_CMN_GET_CELL(cell); + TRC2(rgSCHCmnActvtUlUe); + + /* : take care of this in UL retransmission */ + cellSchd->apisUl->rgSCHUlActvtUe(cell, ue); + RETVOID; +} + +/** + * @brief UE out of MeasGap or AckNackReptn. + * + * @details + * + * Function : rgSCHCmnActvtDlUe + * + * This functions triggers specific scheduler + * to start considering it for scheduling. + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ue + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC Void rgSCHCmnActvtDlUe +( +RgSchCellCb *cell, +RgSchUeCb *ue +) +#else +PUBLIC Void rgSCHCmnActvtDlUe(cell, ue) +RgSchCellCb *cell; +RgSchUeCb *ue; +#endif +{ + RgSchCmnCell *cellSchd = RG_SCH_CMN_GET_CELL(cell); + TRC2(rgSCHCmnActvtDlUe); + + cellSchd->apisDl->rgSCHDlActvtUe(cell, ue); + RETVOID; +} + +/** + * @brief This API is invoked to indicate scheduler of a CRC indication. + * + * @details + * + * Function : rgSCHCmnHdlUlTransInd + * This API is invoked to indicate scheduler of a CRC indication. + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ue + * @param[in] CmLteTimingInfo timingInfo + * + * @return Void + **/ +#ifdef ANSI +PUBLIC Void rgSCHCmnHdlUlTransInd +( +RgSchCellCb *cell, +RgSchUeCb *ue, +CmLteTimingInfo timingInfo +) +#else +PUBLIC Void rgSCHCmnHdlUlTransInd(cell, ue, timingInfo) +RgSchCellCb *cell; +RgSchUeCb *ue; +CmLteTimingInfo timingInfo; +#endif +{ + TRC2(rgSCHCmnHdlUlTransInd); + + /* Update the latest UL dat/sig transmission time */ + RGSCHCPYTIMEINFO(timingInfo, ue->ul.ulTransTime); + if (RG_SCH_CMN_IS_UE_PDCCHODR_INACTV(ue)) + { + /* Some UL Transmission from this UE. + * Activate this UE if it was inactive */ + RG_SCH_CMN_DL_UPDT_INACTV_MASK ( cell, ue, RG_PDCCHODR_INACTIVE); + RG_SCH_CMN_UL_UPDT_INACTV_MASK ( cell, ue, RG_PDCCHODR_INACTIVE); + } + RETVOID; +} + +#ifdef TFU_UPGRADE + +/** + * @brief Compute the minimum Rank based on Codebook subset + * restriction configuration for 4 Tx Ports and Tx Mode 4. + * + * @details + * + * Function : rgSCHCmnComp4TxMode4 + * + * Depending on BitMap set at CBSR during Configuration + * - return the least possible Rank + * + * + * @param[in] U32 *pmiBitMap + * @return RgSchCmnRank + **/ +#ifdef ANSI +PRIVATE RgSchCmnRank rgSCHCmnComp4TxMode4 +( + U32 *pmiBitMap + ) +#else +PRIVATE RgSchCmnRank rgSCHCmnComp4TxMode4(pmiBitMap) + U32 *pmiBitMap; +#endif +{ + U32 bitMap0, bitMap1; + TRC2(rgSCHCmnComp4TxMode4); + bitMap0 = pmiBitMap[0]; + bitMap1 = pmiBitMap[1]; + if((bitMap1) & 0xFFFF) + { + RETVALUE (RG_SCH_CMN_RANK_1); + } + else if((bitMap1>>16) & 0xFFFF) + { + RETVALUE (RG_SCH_CMN_RANK_2); + } + else if((bitMap0) & 0xFFFF) + { + RETVALUE (RG_SCH_CMN_RANK_3); + } + else if((bitMap0>>16) & 0xFFFF) + { + RETVALUE (RG_SCH_CMN_RANK_4); + } + else + { + RETVALUE (RG_SCH_CMN_RANK_1); + } +} + + +/** + * @brief Compute the minimum Rank based on Codebook subset + * restriction configuration for 2 Tx Ports and Tx Mode 4. + * + * @details + * + * Function : rgSCHCmnComp2TxMode4 + * + * Depending on BitMap set at CBSR during Configuration + * - return the least possible Rank + * + * + * @param[in] U32 *pmiBitMap + * @return RgSchCmnRank + **/ +#ifdef ANSI +PRIVATE RgSchCmnRank rgSCHCmnComp2TxMode4 +( + U32 *pmiBitMap + ) +#else +PRIVATE RgSchCmnRank rgSCHCmnComp2TxMode4(pmiBitMap) + U32 *pmiBitMap; +#endif +{ + U32 bitMap0; + TRC2(rgSCHCmnComp2TxMode4); + bitMap0 = pmiBitMap[0]; + if((bitMap0>>26)& 0x0F) + { + RETVALUE (RG_SCH_CMN_RANK_1); + } + else if((bitMap0>>30) & 3) + { + RETVALUE (RG_SCH_CMN_RANK_2); + } + else + { + RETVALUE (RG_SCH_CMN_RANK_1); + } +} + +/** + * @brief Compute the minimum Rank based on Codebook subset + * restriction configuration for 4 Tx Ports and Tx Mode 3. + * + * @details + * + * Function : rgSCHCmnComp4TxMode3 + * + * Depending on BitMap set at CBSR during Configuration + * - return the least possible Rank + * + * + * @param[in] U32 *pmiBitMap + * @return RgSchCmnRank + **/ +#ifdef ANSI +PRIVATE RgSchCmnRank rgSCHCmnComp4TxMode3 +( + U32 *pmiBitMap + ) +#else +PRIVATE RgSchCmnRank rgSCHCmnComp4TxMode3(pmiBitMap) + U32 *pmiBitMap; +#endif +{ + U32 bitMap0; + TRC2(rgSCHCmnComp4TxMode3); + bitMap0 = pmiBitMap[0]; + if((bitMap0>>28)& 1) + { + RETVALUE (RG_SCH_CMN_RANK_1); + } + else if((bitMap0>>29) &1) + { + RETVALUE (RG_SCH_CMN_RANK_2); + } + else if((bitMap0>>30) &1) + { + RETVALUE (RG_SCH_CMN_RANK_3); + } + else if((bitMap0>>31) &1) + { + RETVALUE (RG_SCH_CMN_RANK_4); + } + else + { + RETVALUE (RG_SCH_CMN_RANK_1); + } +} + +/** + * @brief Compute the minimum Rank based on Codebook subset + * restriction configuration for 2 Tx Ports and Tx Mode 3. + * + * @details + * + * Function : rgSCHCmnComp2TxMode3 + * + * Depending on BitMap set at CBSR during Configuration + * - return the least possible Rank + * + * + * @param[in] U32 *pmiBitMap + * @return RgSchCmnRank + **/ +#ifdef ANSI +PRIVATE RgSchCmnRank rgSCHCmnComp2TxMode3 +( + U32 *pmiBitMap + ) +#else +PRIVATE RgSchCmnRank rgSCHCmnComp2TxMode3(pmiBitMap) + U32 *pmiBitMap; +#endif +{ + U32 bitMap0; + TRC2(rgSCHCmnComp2TxMode3); + bitMap0 = pmiBitMap[0]; + if((bitMap0>>30)& 1) + { + RETVALUE (RG_SCH_CMN_RANK_1); + } + else if((bitMap0>>31) &1) + { + RETVALUE (RG_SCH_CMN_RANK_2); + } + else + { + RETVALUE (RG_SCH_CMN_RANK_1); + } +} + +/** + * @brief Compute the minimum Rank based on Codebook subset + * restriction configuration. + * + * @details + * + * Function : rgSCHCmnComputeRank + * + * Depending on Num Tx Ports and Transmission mode + * - return the least possible Rank + * + * + * @param[in] RgrTxMode txMode + * @param[in] U32 *pmiBitMap + * @param[in] U8 numTxPorts + * @return RgSchCmnRank + **/ +#ifdef ANSI +PRIVATE RgSchCmnRank rgSCHCmnComputeRank +( + RgrTxMode txMode, + U32 *pmiBitMap, + U8 numTxPorts + ) +#else +PRIVATE RgSchCmnRank rgSCHCmnComputeRank(txMode, pmiBitMap, numTxPorts) + RgrTxMode txMode; + U32 *pmiBitMap; + U8 numTxPorts; +#endif +{ + TRC2(rgSCHCmnComputeRank); + + if (numTxPorts ==2 && txMode == RGR_UE_TM_3) + { + RETVALUE (rgSCHCmnComp2TxMode3(pmiBitMap)); + } + else if (numTxPorts ==4 && txMode == RGR_UE_TM_3) + { + RETVALUE (rgSCHCmnComp4TxMode3(pmiBitMap)); + } + else if (numTxPorts ==2 && txMode == RGR_UE_TM_4) + { + RETVALUE (rgSCHCmnComp2TxMode4(pmiBitMap)); + } + else if (numTxPorts ==4 && txMode == RGR_UE_TM_4) + { + RETVALUE (rgSCHCmnComp4TxMode4(pmiBitMap)); + } + else + { + RETVALUE (RG_SCH_CMN_RANK_1); + } +} + +#endif + +/** + * @brief Harq Entity Deinitialization for CMN SCH. + * + * @details + * + * Function : rgSCHCmnDlDeInitHqEnt + * + * Harq Entity Deinitialization for CMN SCH + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchDlHqEnt *hqE + * @return VOID + **/ +/*KWORK_FIX:Changed function return type to void */ +#ifdef ANSI +PUBLIC Void rgSCHCmnDlDeInitHqEnt +( +RgSchCellCb *cell, +RgSchDlHqEnt *hqE +) +#else +PUBLIC Void rgSCHCmnDlDeInitHqEnt(cell, hqE) +RgSchCellCb *cell; +RgSchDlHqEnt *hqE; +#endif +{ + RgSchCmnCell *cellSchd = RG_SCH_CMN_GET_CELL(cell); + RgSchDlHqProcCb *hqP; + U8 cnt; + S16 ret; + + TRC2(rgSCHCmnDlDeInitHqEnt); + + ret = cellSchd->apisDl->rgSCHDlUeHqEntDeInit(cell, hqE); + /* Free only If the Harq proc are created*/ + if(RFAILED == ret) + { + } + + for(cnt = 0; cnt < hqE->numHqPrcs; cnt++) + { + hqP = &hqE->procs[cnt]; + if ((RG_SCH_CMN_GET_DL_HQP(hqP))) + { + rgSCHUtlFreeSBuf(cell->instIdx, + (Data**)(&(hqP->sch)), (sizeof(RgSchCmnDlHqProc))); + } + } +#ifdef LTE_ADV + rgSCHLaaDeInitDlHqProcCb (cell, hqE); +#endif + + RETVOID; +} + +/** + * @brief Harq Entity initialization for CMN SCH. + * + * @details + * + * Function : rgSCHCmnDlInitHqEnt + * + * Harq Entity initialization for CMN SCH + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ue + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 rgSCHCmnDlInitHqEnt +( +RgSchCellCb *cell, +RgSchDlHqEnt *hqEnt +) +#else +PUBLIC S16 rgSCHCmnDlInitHqEnt(cell, hqEnt) +RgSchCellCb *cell; +RgSchDlHqEnt *hqEnt; +#endif + +{ + RgSchDlHqProcCb *hqP; + U8 cnt; + + RgSchCmnCell *cellSchd = RG_SCH_CMN_GET_CELL(cell); + TRC2(rgSCHCmnDlInitHqEnt); + + for(cnt = 0; cnt < hqEnt->numHqPrcs; cnt++) + { + hqP = &hqEnt->procs[cnt]; + if (rgSCHUtlAllocSBuf(cell->instIdx, + (Data**)&(hqP->sch), (sizeof(RgSchCmnDlHqProc))) != ROK) + { + RETVALUE(RFAILED); + } + } +#ifdef EMTC_ENABLE + if((cell->emtcEnable) &&(hqEnt->ue->isEmtcUe)) + { + if(ROK != cellSchd->apisEmtcDl->rgSCHDlUeHqEntInit(cell, hqEnt)) + { + RETVALUE(RFAILED); + } + + } + else +#endif + { + if(ROK != cellSchd->apisDl->rgSCHDlUeHqEntInit(cell, hqEnt)) + { + RETVALUE(RFAILED); + } + } + + RETVALUE(ROK); +} /* rgSCHCmnDlInitHqEnt */ + +/** + * @brief This function computes distribution of refresh period + * + * @details + * + * Function: rgSCHCmnGetRefreshDist + * Purpose: This function computes distribution of refresh period + * This is required to align set of UEs refresh + * around the different consecutive subframe. + * + * Invoked by: rgSCHCmnGetRefreshPerDist + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ue + * @return Void + * + **/ +#ifdef ANSI +PRIVATE U8 rgSCHCmnGetRefreshDist +( +RgSchCellCb *cell, +RgSchUeCb *ue +) +#else +PRIVATE U8 rgSCHCmnGetRefreshDist(cell, ue) +RgSchCellCb *cell; +RgSchUeCb *ue; +#endif +{ + U8 refOffst; +#ifdef DEBUGP + Inst inst = cell->instIdx; +#endif + TRC2(rgSCHCmnGetRefreshDist); + + for(refOffst = 0; refOffst < RGSCH_MAX_REFRESH_OFFSET; refOffst++) + { + if(cell->refreshUeCnt[refOffst] < RGSCH_MAX_REFRESH_GRPSZ) + { + cell->refreshUeCnt[refOffst]++; + ue->refreshOffset = refOffst; + /* printf("UE[%d] refresh offset[%d]. Cell refresh ue count[%d].\n", ue->ueId, refOffst, cell->refreshUeCnt[refOffst]); */ + RETVALUE(refOffst); + } + } + + RGSCHDBGERRNEW(inst, (rgSchPBuf(inst), "Allocation of refresh distribution failed\n")); + /* We should not enter here normally, but incase of failure, allocating from last offset*/ + cell->refreshUeCnt[refOffst-1]++; + ue->refreshOffset = refOffst-1; + + RETVALUE(refOffst-1); +} +/** + * @brief This function computes initial Refresh Wait Period. + * + * @details + * + * Function: rgSCHCmnGetRefreshPer + * Purpose: This function computes initial Refresh Wait Period. + * This is required to align multiple UEs refresh + * around the same time. + * + * Invoked by: rgSCHCmnGetRefreshPer + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ue + * @param[in] U32 *waitPer + * @return Void + * + **/ +#ifdef ANSI +PRIVATE Void rgSCHCmnGetRefreshPer +( +RgSchCellCb *cell, +RgSchUeCb *ue, +U32 *waitPer +) +#else +PRIVATE Void rgSCHCmnGetRefreshPer(cell, ue, waitPer) +RgSchCellCb *cell; +RgSchUeCb *ue; +U32 *waitPer; +#endif +{ + U32 refreshPer; + U32 crntSubFrm; + + TRC2(rgSCHCmnGetRefreshPer); + + refreshPer = RG_SCH_CMN_REFRESH_TIME * RG_SCH_CMN_REFRESH_TIMERES; + crntSubFrm = cell->crntTime.sfn * RGSCH_NUM_SUB_FRAMES_5G + cell->crntTime.subframe; + /* Fix: syed align multiple UEs to refresh at same time */ + *waitPer = refreshPer - (crntSubFrm % refreshPer); + *waitPer = RGSCH_CEIL(*waitPer, RG_SCH_CMN_REFRESH_TIMERES); + *waitPer = *waitPer + rgSCHCmnGetRefreshDist(cell, ue); + + RETVOID; +} + + +#ifdef LTE_ADV +/** + * @brief UE initialisation for scheduler. + * + * @details + * + * Function : rgSCHCmnRgrSCellUeCfg + * + * This functions intialises UE specific scheduler + * information for SCELL + * 0. Perform basic validations + * 1. Allocate common sched UE cntrl blk + * 2. Perform DL cfg (allocate Hq Procs Cmn sched cntrl blks) + * 3. Perform UL cfg + * 4. Perform DLFS cfg + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ue + * @param[out] RgSchErrInfo *err + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 rgSCHCmnRgrSCellUeCfg +( +RgSchCellCb *sCell, +RgSchUeCb *ue, +RgrUeSecCellCfg *sCellInfoCfg, +RgSchErrInfo *err +) +#else +PUBLIC S16 rgSCHCmnRgrSCellUeCfg(sCell, ue, sCellInfoCfg, err) +RgSchCellCb *sCell; +RgSchUeCb *ue; +RgrUeSecCellCfg *sCellInfoCfg; +RgSchErrInfo *err; +#endif +{ + U8 i; + S16 ret; + U8 cnt; + RgSchCmnAllocRecord *allRcd; + RgSchDlRbAlloc *allocInfo; + RgSchCmnCell *cellSchd = RG_SCH_CMN_GET_CELL(ue->cell); + RgSchCmnUlUe *ueUl; + RgSchCmnUlUe *ueUlPcell; + RgSchCmnUe *pCellUeSchCmn; + RgSchCmnUe *ueSchCmn; + RgSchCmnDlUe *ueDl; + RgSchCmnDlUe *pCellUeDl; +#ifdef DEBUGP + Inst inst = ue->cell->instIdx; +#endif + U32 idx = (U8)((sCell->cellId - rgSchCb[sCell->instIdx].genCfg.startCellId)&(CM_LTE_MAX_CELLS-1)); + TRC2(rgSCHCmnRgrSCellUeCfg); + + pCellUeSchCmn = RG_SCH_CMN_GET_UE(ue,ue->cell); + pCellUeDl = &pCellUeSchCmn->dl; + + /* 1. Allocate Common sched control block */ + if((rgSCHUtlAllocSBuf(sCell->instIdx, + (Data**)&(((ue->cellInfo[ue->cellIdToCellIdxMap[idx]])->sch)), (sizeof(RgSchCmnUe))) != ROK)) + { + RGSCHDBGERRNEW(inst, (rgSchPBuf(inst), "Memory allocation FAILED\n")); + err->errCause = RGSCHERR_SCH_CFG; + RETVALUE(RFAILED); + } + ueSchCmn = RG_SCH_CMN_GET_UE(ue,sCell); + + /*2. Perform UEs downlink configuration */ + ueDl = &ueSchCmn->dl; + + /*CA TODO*/ + ueDl->mimoInfo = pCellUeDl->mimoInfo; + + if ((ue->mimoInfo.txMode == RGR_UE_TM_4) || + (ue->mimoInfo.txMode == RGR_UE_TM_6)) + { + RG_SCH_CMN_SET_FORCE_TD(ue, sCell, RG_SCH_CMN_TD_NO_PMI); + } + if (ue->mimoInfo.txMode == RGR_UE_TM_3) + { + RG_SCH_CMN_SET_FORCE_TD(ue, sCell, RG_SCH_CMN_TD_RI_1); + } + RGSCH_ARRAY_BOUND_CHECK(sCell->instIdx, rgUeCatTbl, pCellUeSchCmn->cmn.ueCat); + ueDl->maxTbBits = rgUeCatTbl[pCellUeSchCmn->cmn.ueCat].maxDlTbBits; + /*CA dev-Start*/ + U8 ri = 0; + ri = RGSCH_MIN(ri, sCell->numTxAntPorts); + if(((CM_LTE_UE_CAT_6 == pCellUeSchCmn->cmn.ueCat ) + ||(CM_LTE_UE_CAT_7 == pCellUeSchCmn->cmn.ueCat)) + && (4 == ri)) + { + ueDl->maxTbSz = rgUeCatTbl[pCellUeSchCmn->cmn.ueCat].maxDlBits[1]; + } + else + { + ueDl->maxTbSz = rgUeCatTbl[pCellUeSchCmn->cmn.ueCat].maxDlBits[0]; + } + /*CA dev-End*/ + /* Fix : syed Assign hqEnt to UE only if msg4 is done */ +#ifdef LTE_TDD + ueDl->maxSbSz = (rgUeCatTbl[pCellUeSchCmn->cmn.ueCat].maxSftChBits/ + rgSchTddDlNumHarqProcTbl[sCell->ulDlCfgIdx]); +#else + ueDl->maxSbSz = (rgUeCatTbl[pCellUeSchCmn->cmn.ueCat].maxSftChBits/ + RGSCH_NUM_DL_HQ_PROC); +#endif +#ifdef EMTC_ENABLE + rgSCHCmnDlSetUeAllocLmt(sCell, ueDl, ue->isEmtcUe); +#else + rgSCHCmnDlSetUeAllocLmt(sCell, ueDl, FALSE); +#endif + + /* DL ambr */ + /* ambrCfgd config moved to ueCb.dl, as it's not needed for per cell wise*/ + + allocInfo = RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ue, sCell); + allocInfo->rnti = ue->ueId; + + /* Initializing the lastCfi value to current cfi value */ + ueDl->lastCfi = cellSchd->dl.currCfi; + + if ((cellSchd->apisDl->rgSCHRgrSCellDlUeCfg(sCell, ue, err)) != ROK) + { + RGSCHDBGERRNEW(inst, (rgSchPBuf(inst), "Spec Sched DL UE CFG FAILED\n")); + RETVALUE(RFAILED); + } + + /* TODO: enhance for DLFS RB Allocation for SCELLs in future dev */ + + /* DLFS UE Config */ + if (cellSchd->dl.isDlFreqSel) + { + if ((cellSchd->apisDlfs->rgSCHDlfsSCellUeCfg(sCell, ue, sCellInfoCfg, err)) != ROK) + { + RGSCHDBGERRNEW(inst, (rgSchPBuf(inst), "DLFS UE config FAILED\n")); + RETVALUE(RFAILED); + } + } + + /* TODO: Do UL SCELL CFG during UL CA dev */ + { + ueUl = RG_SCH_CMN_GET_UL_UE(ue, sCell); + + /* TODO_ULCA: SRS for SCELL needs to be handled in the below function call */ + rgSCHCmnUpdUeUlCqiInfo(sCell, ue, ueUl, ueSchCmn, cellSchd, + sCell->isCpUlExtend); + + ret = rgSCHUhmHqEntInit(sCell, ue); + if (ret != ROK) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,sCell->cellId,"SCELL UHM HARQ Ent Init " + "Failed for CRNTI:%d", ue->ueId); + RETVALUE(RFAILED); + } + + ueUlPcell = RG_SCH_CMN_GET_UL_UE(ue, ue->cell); + /* Initialize uplink HARQ related information for UE */ + ueUl->hqEnt.maxHqRetx = ueUlPcell->hqEnt.maxHqRetx; + cmLListInit(&ueUl->hqEnt.free); + cmLListInit(&ueUl->hqEnt.inUse); + for(i=0; i < ueUl->hqEnt.numHqPrcs; i++) + { + ueUl->hqEnt.hqProcCb[i].hqEnt = (void*)(&ueUl->hqEnt); + ueUl->hqEnt.hqProcCb[i].procId = i; + ueUl->hqEnt.hqProcCb[i].ulSfIdx = RGSCH_INVALID_INFO; + ueUl->hqEnt.hqProcCb[i].alloc = NULLP; +#ifdef LTEMAC_SPS + /* ccpu00139513- Initializing SPS flags*/ + ueUl->hqEnt.hqProcCb[i].isSpsActvnHqP = FALSE; + ueUl->hqEnt.hqProcCb[i].isSpsOccnHqP = FALSE; +#endif + cmLListAdd2Tail(&ueUl->hqEnt.free, &ueUl->hqEnt.hqProcCb[i].lnk); + ueUl->hqEnt.hqProcCb[i].lnk.node = (PTR)&ueUl->hqEnt.hqProcCb[i]; + } + + /* Allocate UL BSR allocation tracking List */ + cmLListInit(&ueUl->ulAllocLst); + + for (cnt = 0; cnt < RG_SCH_CMN_MAX_ALLOC_TRACK; cnt++) + { + if((rgSCHUtlAllocSBuf(sCell->instIdx, + (Data**)&(allRcd),sizeof(RgSchCmnAllocRecord)) != ROK)) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,sCell->cellId,"SCELL Memory allocation FAILED" + "for CRNTI:%d",ue->ueId); + err->errCause = RGSCHERR_SCH_CFG; + RETVALUE(RFAILED); + } + allRcd->allocTime = sCell->crntTime; + cmLListAdd2Tail(&ueUl->ulAllocLst, &allRcd->lnk); + allRcd->lnk.node = (PTR)allRcd; + } + + /* After initialising UL part, do power related init */ + ret = rgSCHPwrUeSCellCfg(sCell, ue, sCellInfoCfg); + if (ret != ROK) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,sCell->cellId, "Could not do " + "power config for UE CRNTI:%d",ue->ueId); + RETVALUE(RFAILED); + } + +#ifdef EMTC_ENABLE + if(TRUE == ue->isEmtcUe) + { + if ((cellSchd->apisEmtcUl->rgSCHRgrUlUeCfg(sCell, ue, NULL, err)) != ROK) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,sCell->cellId, "Spec Sched UL UE CFG FAILED" + "for CRNTI:%d",ue->ueId); + RETVALUE(RFAILED); + } + } + else +#endif + { + if ((cellSchd->apisUl->rgSCHRgrUlUeCfg(sCell, ue, NULL, err)) != ROK) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,sCell->cellId, "Spec Sched UL UE CFG FAILED" + "for CRNTI:%d",ue->ueId); + RETVALUE(RFAILED); + } + } + + ue->ul.isUlCaEnabled = TRUE; + } + + RETVALUE(ROK); +} /* rgSCHCmnRgrSCellUeCfg */ + + +/** + * @brief UE initialisation for scheduler. + * + * @details + * + * Function : rgSCHCmnRgrSCellUeDel + * + * This functions Delete UE specific scheduler + * information for SCELL + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ue + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 rgSCHCmnRgrSCellUeDel +( +RgSchUeCellInfo *sCellInfo, +RgSchUeCb *ue +) +#else +PUBLIC S16 rgSCHCmnRgrSCellUeDel(sCellInfo, ue) +RgSchUeCellInfo *sCellInfo; +RgSchUeCb *ue; +#endif +{ + RgSchCmnCell *cellSchd = RG_SCH_CMN_GET_CELL(ue->cell); + Inst inst = ue->cell->instIdx; + + TRC2(rgSCHCmnRgrSCellUeDel); + + cellSchd->apisDl->rgSCHRgrSCellDlUeDel(sCellInfo, ue); + + /* UL CA */ + rgSCHCmnUlUeDelAllocs(sCellInfo->cell, ue); + +#ifdef EMTC_ENABLE + if(TRUE == ue->isEmtcUe) + { + cellSchd->apisEmtcUl->rgSCHFreeUlUe(sCellInfo->cell, ue); + } + else +#endif + { + cellSchd->apisUl->rgSCHFreeUlUe(sCellInfo->cell, ue); + } + + /* DLFS UE Config */ + if (cellSchd->dl.isDlFreqSel) + { + if ((cellSchd->apisDlfs->rgSCHDlfsSCellUeDel(sCellInfo->cell, ue)) != ROK) + { + RGSCHDBGERRNEW(inst, (rgSchPBuf(inst), "DLFS Scell del FAILED\n")); + RETVALUE(RFAILED); + } + } + + rgSCHUtlFreeSBuf(sCellInfo->cell->instIdx, + (Data**)(&(sCellInfo->sch)), (sizeof(RgSchCmnUe))); + + + RETVALUE(ROK); +} /* rgSCHCmnRgrSCellUeDel */ + +#endif + +#ifdef RG_5GTF +/** + * @brief Handles 5gtf configuration for a UE + * + * @details + * + * Function : rgSCHCmn5gtfUeCfg + * + * Processing Steps: + * + * - Return ROK + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ue + * @param[in] RgrUeCfg *cfg + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 rgSCHCmn5gtfUeCfg +( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgrUeCfg *cfg +) +#else +PUBLIC S16 rgSCHCmn5gtfUeCfg(cell, ue, cfg) +RgSchCellCb *cell; +RgSchUeCb *ue; +RgrUeCfg *cfg; +#endif +{ + TRC2(rgSCHCmnRgrUeCfg); + + RgSchUeGrp *ue5gtfGrp; + ue->ue5gtfCb.grpId = cfg->ue5gtfCfg.grpId; + ue->ue5gtfCb.BeamId = cfg->ue5gtfCfg.BeamId; + ue->ue5gtfCb.numCC = cfg->ue5gtfCfg.numCC; + ue->ue5gtfCb.mcs = cfg->ue5gtfCfg.mcs; + ue->ue5gtfCb.maxPrb = cfg->ue5gtfCfg.maxPrb; + + ue->ue5gtfCb.cqiRiPer = 100; + /* 5gtf TODO: CQIs to start from (10,0)*/ + ue->ue5gtfCb.nxtCqiRiOccn.sfn = 10; + ue->ue5gtfCb.nxtCqiRiOccn.subframe = 0; + ue->ue5gtfCb.rank = 1; + + printf("\nschd cfg at mac,%u,%u,%u,%u,%u\n",ue->ue5gtfCb.grpId,ue->ue5gtfCb.BeamId,ue->ue5gtfCb.numCC, + ue->ue5gtfCb.mcs,ue->ue5gtfCb.maxPrb); + + ue5gtfGrp = &(cell->cell5gtfCb.ueGrp5gConf[ue->ue5gtfCb.BeamId]); + + /* TODO_5GTF: Currently handling 1 group only. Need to update when multi group + scheduling comes into picture */ + if(ue5gtfGrp->beamBitMask & (1 << ue->ue5gtfCb.BeamId)) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId, + "5GTF_ERROR Invalid beam id CRNTI:%d",cfg->crnti); + RETVALUE(RFAILED); + } + ue5gtfGrp->beamBitMask |= (1 << ue->ue5gtfCb.BeamId); + + RETVALUE(ROK); +} +#endif + +/** + * @brief UE initialisation for scheduler. + * + * @details + * + * Function : rgSCHCmnRgrUeCfg + * + * This functions intialises UE specific scheduler + * information + * 0. Perform basic validations + * 1. Allocate common sched UE cntrl blk + * 2. Perform DL cfg (allocate Hq Procs Cmn sched cntrl blks) + * 3. Perform UL cfg + * 4. Perform DLFS cfg + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ue + * @param[int] RgrUeCfg *ueCfg + * @param[out] RgSchErrInfo *err + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 rgSCHCmnRgrUeCfg +( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgrUeCfg *ueCfg, +RgSchErrInfo *err +) +#else +PUBLIC S16 rgSCHCmnRgrUeCfg(cell, ue, ueCfg, err) +RgSchCellCb *cell; +RgSchUeCb *ue; +RgrUeCfg *ueCfg; +RgSchErrInfo *err; +#endif +{ + RgSchDlRbAlloc *allocInfo; + S16 ret; + RgSchCmnCell *cellSchd = RG_SCH_CMN_GET_CELL(cell); + RgSchCmnUe *ueSchCmn; + RgSchCmnUlUe *ueUl; + RgSchCmnDlUe *ueDl; + U8 cnt; + RgSchCmnAllocRecord *allRcd; + U32 waitPer; + U32 idx = (U8)((cell->cellId - rgSchCb[cell->instIdx].genCfg.startCellId)&(CM_LTE_MAX_CELLS-1)); + RgSchUeCellInfo *pCellInfo = RG_SCH_CMN_GET_PCELL_INFO(ue); + TRC2(rgSCHCmnRgrUeCfg); + + + /* 1. Allocate Common sched control block */ + if((rgSCHUtlAllocSBuf(cell->instIdx, + (Data**)&(((ue->cellInfo[ue->cellIdToCellIdxMap[idx]])->sch)), (sizeof(RgSchCmnUe))) != ROK)) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId, + "Memory allocation FAILED for CRNTI:%d",ueCfg->crnti); + err->errCause = RGSCHERR_SCH_CFG; + RETVALUE(RFAILED); + } + ueSchCmn = RG_SCH_CMN_GET_UE(ue,cell); + ue->dl.ueDlCqiCfg = ueCfg->ueDlCqiCfg; + pCellInfo->acqiCb.aCqiCfg = ueCfg->ueDlCqiCfg.aprdCqiCfg; + if(ueCfg->ueCatEnum > 0 ) + { + /*KWORK_FIX removed NULL chk for ueSchCmn*/ + ueSchCmn->cmn.ueCat = ueCfg->ueCatEnum - 1; + } + else + { + ueSchCmn->cmn.ueCat = 0; /* Assuming enum values correctly set */ + } + cmInitTimers(&ueSchCmn->cmn.tmr, 1); + + /*2. Perform UEs downlink configuration */ + ueDl = &ueSchCmn->dl; + /* RACHO : store the rapId assigned for HandOver UE. + * Append UE to handover list of cmnCell */ + if (ueCfg->dedPreambleId.pres == PRSNT_NODEF) + { + rgSCHCmnDelDedPreamble(cell, ueCfg->dedPreambleId.val); + ueDl->rachInfo.hoRapId = ueCfg->dedPreambleId.val; + cmLListAdd2Tail(&cellSchd->rachCfg.hoUeLst, &ueDl->rachInfo.hoLnk); + ueDl->rachInfo.hoLnk.node = (PTR)ue; + } + + rgSCHCmnUpdUeMimoInfo(ueCfg, ueDl, cell, cellSchd); + + if (ueCfg->txMode.pres == TRUE) + { + if ((ueCfg->txMode.txModeEnum == RGR_UE_TM_4) || + (ueCfg->txMode.txModeEnum == RGR_UE_TM_6)) + { + RG_SCH_CMN_SET_FORCE_TD(ue, cell, RG_SCH_CMN_TD_NO_PMI); + } + if (ueCfg->txMode.txModeEnum == RGR_UE_TM_3) + { + RG_SCH_CMN_SET_FORCE_TD(ue, cell, RG_SCH_CMN_TD_RI_1); + } + } + RGSCH_ARRAY_BOUND_CHECK(cell->instIdx, rgUeCatTbl, ueSchCmn->cmn.ueCat); + ueDl->maxTbBits = rgUeCatTbl[ueSchCmn->cmn.ueCat].maxDlTbBits; + /*CA dev-Start*/ + U8 ri = 0; + ri = RGSCH_MIN(ri, cell->numTxAntPorts); + if(((CM_LTE_UE_CAT_6 == ueSchCmn->cmn.ueCat ) + ||(CM_LTE_UE_CAT_7 == ueSchCmn->cmn.ueCat)) + && (4 == ri)) + { + ueDl->maxTbSz = rgUeCatTbl[ueSchCmn->cmn.ueCat].maxDlBits[1]; + } + else + { + ueDl->maxTbSz = rgUeCatTbl[ueSchCmn->cmn.ueCat].maxDlBits[0]; + } + /*CA dev-End*/ + /* Fix : syed Assign hqEnt to UE only if msg4 is done */ +#ifdef LTE_TDD + ueDl->maxSbSz = (rgUeCatTbl[ueSchCmn->cmn.ueCat].maxSftChBits/ + rgSchTddDlNumHarqProcTbl[cell->ulDlCfgIdx]); +#else + ueDl->maxSbSz = (rgUeCatTbl[ueSchCmn->cmn.ueCat].maxSftChBits/ + RGSCH_NUM_DL_HQ_PROC); +#endif +#ifdef EMTC_ENABLE + rgSCHCmnDlSetUeAllocLmt(cell, ueDl, ue->isEmtcUe); +#else + rgSCHCmnDlSetUeAllocLmt(cell, ueDl, FALSE); +#endif + /* if none of the DL and UL AMBR are configured then fail the configuration + */ + if((ueCfg->ueQosCfg.dlAmbr == 0) && (ueCfg->ueQosCfg.ueBr == 0)) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,"UL Ambr and DL Ambr are" + "configured as 0 for CRNTI:%d",ueCfg->crnti); + err->errCause = RGSCHERR_SCH_CFG; + RETVALUE(RFAILED); + } + /* DL ambr */ + ue->dl.ambrCfgd = (ueCfg->ueQosCfg.dlAmbr * RG_SCH_CMN_REFRESH_TIME)/100; + + allocInfo = RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ue, cell); + allocInfo->rnti = ue->ueId; + + /* Initializing the lastCfi value to current cfi value */ + ueDl->lastCfi = cellSchd->dl.currCfi; +#ifdef EMTC_ENABLE + if(cell->emtcEnable && ue->isEmtcUe) + { + if ((cellSchd->apisEmtcDl->rgSCHRgrDlUeCfg(cell, ue, ueCfg, err)) != ROK) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId, + "Spec Sched DL UE CFG FAILED for CRNTI:%d",ueCfg->crnti); + RETVALUE(RFAILED); + } + + } + else +#endif + { + if ((cellSchd->apisDl->rgSCHRgrDlUeCfg(cell, ue, ueCfg, err)) != ROK) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId, + "Spec Sched DL UE CFG FAILED for CRNTI:%d",ueCfg->crnti); + RETVALUE(RFAILED); + } + } + + + + /* 3. Initialize ul part */ + ueUl = &ueSchCmn->ul; + + rgSCHCmnUpdUeUlCqiInfo(cell, ue, ueUl, ueSchCmn, cellSchd, + cell->isCpUlExtend); + + ue->ul.maxBytesPerUePerTti = rgUeCatTbl[ueSchCmn->cmn.ueCat].maxUlBits * \ + RG_SCH_CMN_MAX_BITS_RATIO / (RG_SCH_CMN_UL_COM_DENOM*8); + + ue->ul.cfgdAmbr = (ueCfg->ueQosCfg.ueBr * RG_SCH_CMN_REFRESH_TIME)/100; + ue->ul.effAmbr = ue->ul.cfgdAmbr; + RGSCHCPYTIMEINFO(cell->crntTime, ue->ul.ulTransTime); + + /* Allocate UL BSR allocation tracking List */ + cmLListInit(&ueUl->ulAllocLst); + + for (cnt = 0; cnt < RG_SCH_CMN_MAX_ALLOC_TRACK; cnt++) + { + if((rgSCHUtlAllocSBuf(cell->instIdx, + (Data**)&(allRcd),sizeof(RgSchCmnAllocRecord)) != ROK)) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,"Memory allocation FAILED" + "for CRNTI:%d",ueCfg->crnti); + err->errCause = RGSCHERR_SCH_CFG; + RETVALUE(RFAILED); + } + allRcd->allocTime = cell->crntTime; + cmLListAdd2Tail(&ueUl->ulAllocLst, &allRcd->lnk); + allRcd->lnk.node = (PTR)allRcd; + } + /* Allocate common sch cntrl blocks for LCGs */ + for (cnt=0; cntinstIdx, + (Data**)&(ue->ul.lcgArr[cnt].sch), (sizeof(RgSchCmnLcg))); + if (ret != ROK) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId, + "SCH struct alloc failed for CRNTI:%d",ueCfg->crnti); + err->errCause = RGSCHERR_SCH_CFG; + RETVALUE(ret); + } + } + /* After initialising UL part, do power related init */ + ret = rgSCHPwrUeCfg(cell, ue, ueCfg); + if (ret != ROK) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId, "Could not do " + "power config for UE CRNTI:%d",ueCfg->crnti); + RETVALUE(RFAILED); + } +#ifdef LTEMAC_SPS + ret = rgSCHCmnSpsUeCfg(cell, ue, ueCfg, err); + if (ret != ROK) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId, "Could not do " + "SPS config for CRNTI:%d",ueCfg->crnti); + RETVALUE(RFAILED); + } +#endif /* LTEMAC_SPS */ + +#ifdef EMTC_ENABLE + if(TRUE == ue->isEmtcUe) + { + if ((cellSchd->apisEmtcUl->rgSCHRgrUlUeCfg(cell, ue, ueCfg, err)) != ROK) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId, "Spec Sched UL UE CFG FAILED" + "for CRNTI:%d",ueCfg->crnti); + RETVALUE(RFAILED); + } + } + else +#endif + { + if ((cellSchd->apisUl->rgSCHRgrUlUeCfg(cell, ue, ueCfg, err)) != ROK) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId, "Spec Sched UL UE CFG FAILED" + "for CRNTI:%d",ueCfg->crnti); + RETVALUE(RFAILED); + } + } + + /* DLFS UE Config */ + if (cellSchd->dl.isDlFreqSel) + { + if ((cellSchd->apisDlfs->rgSCHDlfsUeCfg(cell, ue, ueCfg, err)) != ROK) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId, "DLFS UE config FAILED" + "for CRNTI:%d",ueCfg->crnti); + RETVALUE(RFAILED); + } + } + + /* Fix: syed align multiple UEs to refresh at same time */ + rgSCHCmnGetRefreshPer(cell, ue, &waitPer); + /* Start UE Qos Refresh Timer */ + rgSCHCmnAddUeToRefreshQ(cell, ue, waitPer); +#ifdef RG_5GTF + rgSCHCmn5gtfUeCfg(cell, ue, ueCfg); +#endif + + RETVALUE(ROK); +} /* rgSCHCmnRgrUeCfg */ + +/** + * @brief UE TX mode reconfiguration handler. + * + * @details + * + * Function : rgSCHCmnDlHdlTxModeRecfg + * + * This functions updates UE specific scheduler + * information upon UE reconfiguration. + * + * @param[in] RgSchUeCb *ue + * @param[in] RgrUeRecfg *ueRecfg + * @return Void + **/ +#ifdef TFU_UPGRADE +#ifdef ANSI +PRIVATE Void rgSCHCmnDlHdlTxModeRecfg +( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgrUeRecfg *ueRecfg, +U8 numTxPorts +) +#else +PRIVATE Void rgSCHCmnDlHdlTxModeRecfg(cell, ue, ueRecfg, numTxPorts) +RgSchCellCb *cell; +RgSchUeCb *ue; +RgrUeRecfg *ueRecfg; +U8 numTxPorts; +#endif +#else +#ifdef ANSI +PRIVATE Void rgSCHCmnDlHdlTxModeRecfg +( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgrUeRecfg *ueRecfg +) +#else +PRIVATE Void rgSCHCmnDlHdlTxModeRecfg(cell, ue, ueRecfg) +RgSchCellCb *cell; +RgSchUeCb *ue; +RgrUeRecfg *ueRecfg; +#endif +#endif +{ + RgSchCmnDlUe *ueDl = RG_SCH_CMN_GET_DL_UE(ue,cell); + TRC2(rgSCHCmnDlHdlTxModeRecfg); + + if (ueRecfg->txMode.pres != PRSNT_NODEF) + { + RETVOID; + } + /* ccpu00140894- Starting Timer for TxMode Transition Completion*/ + ue->txModeTransCmplt =FALSE; + rgSCHTmrStartTmr (ue->cell, ue, RG_SCH_TMR_TXMODE_TRNSTN, RG_SCH_TXMODE_TRANS_TIMER); + if (ueRecfg->txMode.tmTrnstnState == RGR_TXMODE_RECFG_CMPLT) + { + RG_SCH_CMN_UNSET_FORCE_TD(ue, cell, + RG_SCH_CMN_TD_TXMODE_RECFG); + /* MS_WORKAROUND for ccpu00123186 MIMO Fix Start: need to set FORCE TD bitmap based on TX mode */ + ueDl->mimoInfo.ri = 1; + if ((ueRecfg->txMode.txModeEnum == RGR_UE_TM_4) || + (ueRecfg->txMode.txModeEnum == RGR_UE_TM_6)) + { + RG_SCH_CMN_SET_FORCE_TD(ue, cell, RG_SCH_CMN_TD_NO_PMI); + } + if (ueRecfg->txMode.txModeEnum == RGR_UE_TM_3) + { + RG_SCH_CMN_SET_FORCE_TD(ue, cell, RG_SCH_CMN_TD_RI_1); + } + /* MIMO Fix End: need to set FORCE TD bitmap based on TX mode */ + RETVOID; + } + if (ueRecfg->txMode.tmTrnstnState == RGR_TXMODE_RECFG_START) + { + /* start afresh forceTD masking */ + RG_SCH_CMN_INIT_FORCE_TD(ue, cell, 0); + RG_SCH_CMN_SET_FORCE_TD(ue, cell, RG_SCH_CMN_TD_TXMODE_RECFG); + /* Intialize MIMO related parameters of UE */ + +#ifdef TFU_UPGRADE + if(ueRecfg->txMode.pres) + { + if((ueRecfg->txMode.txModeEnum ==RGR_UE_TM_3) || + (ueRecfg->txMode.txModeEnum ==RGR_UE_TM_4)) + { + if(ueRecfg->ueCodeBookRstRecfg.pres) + { + ueDl->mimoInfo.ri = + rgSCHCmnComputeRank(ueRecfg->txMode.txModeEnum, + ueRecfg->ueCodeBookRstRecfg.pmiBitMap, numTxPorts); + } + else + { + ueDl->mimoInfo.ri = 1; + } + } + else + { + ueDl->mimoInfo.ri = 1; + } + } + else + { + ueDl->mimoInfo.ri = 1; + } +#else + ueDl->mimoInfo.ri = 1; +#endif /* TFU_UPGRADE */ + if ((ueRecfg->txMode.txModeEnum == RGR_UE_TM_4) || + (ueRecfg->txMode.txModeEnum == RGR_UE_TM_6)) + { + RG_SCH_CMN_SET_FORCE_TD(ue, cell, RG_SCH_CMN_TD_NO_PMI); + } + if (ueRecfg->txMode.txModeEnum == RGR_UE_TM_3) + { + RG_SCH_CMN_SET_FORCE_TD(ue, cell, RG_SCH_CMN_TD_RI_1); + } + RETVOID; + } +} +/*********************************************************** + * + * Func : rgSCHCmnUpdUeMimoInfo + * + * Desc : Updates UL and DL Ue Information + * + * Ret : + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PRIVATE Void rgSCHCmnUpdUeMimoInfo +( +RgrUeCfg *ueCfg, +RgSchCmnDlUe *ueDl, +RgSchCellCb *cell, +RgSchCmnCell *cellSchd +) +#else +PRIVATE Void rgSCHCmnUpdUeMimoInfo(ueCfg, ueDl, cell, cellSchd) +RgrUeCfg *ueCfg; +RgSchCmnDlUe *ueDl; +RgSchCellCb *cell; +RgSchCmnCell *cellSchd; +#endif +{ + TRC2(rgSCHCmnUpdUeMimoInfo) +#ifdef TFU_UPGRADE + if(ueCfg->txMode.pres) + { + if((ueCfg->txMode.txModeEnum ==RGR_UE_TM_3) || + (ueCfg->txMode.txModeEnum ==RGR_UE_TM_4)) + { + if(ueCfg->ueCodeBookRstCfg.pres) + { + ueDl->mimoInfo.ri = + rgSCHCmnComputeRank(ueCfg->txMode.txModeEnum, + ueCfg->ueCodeBookRstCfg.pmiBitMap, cell->numTxAntPorts); + } + else + { + ueDl->mimoInfo.ri = 1; + } + } + else + { + ueDl->mimoInfo.ri = 1; + } + } + else + { + ueDl->mimoInfo.ri = 1; + } + +#else + ueDl->mimoInfo.ri = 1; +#endif /*TFU_UPGRADE */ + ueDl->mimoInfo.cwInfo[0].cqi = cellSchd->dl.ccchCqi; + ueDl->mimoInfo.cwInfo[1].cqi = cellSchd->dl.ccchCqi; + + RETVOID; +} +/*********************************************************** + * + * Func : rgSCHCmnUpdUeUlCqiInfo + * + * Desc : Updates UL and DL Ue Information + * + * Ret : + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PRIVATE Void rgSCHCmnUpdUeUlCqiInfo +( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgSchCmnUlUe *ueUl, +RgSchCmnUe *ueSchCmn, +RgSchCmnCell *cellSchd, +Bool isEcp +) +#else +PRIVATE Void rgSCHCmnUpdUeUlCqiInfo(cell, ue, ueUl, ueSchCmn, cellSchd, isEcp) +RgSchCellCb *cell; +RgSchUeCb *ue; +RgSchCmnUlUe *ueUl; +RgSchCmnUe *ueSchCmn; +RgSchCmnCell *cellSchd; +Bool isEcp; +#endif +{ + + TRC2(rgSCHCmnUpdUeUlCqiInfo) + +#ifdef TFU_UPGRADE + if(ue->srsCb.srsCfg.type == RGR_SCH_SRS_SETUP) + { + if(ue->ul.ulTxAntSel.pres) + { + ueUl->crntUlCqi[ue->srsCb.selectedAnt] = cellSchd->ul.dfltUlCqi; + ueUl->validUlCqi = ueUl->crntUlCqi[ue->srsCb.selectedAnt]; + } + else + { + ueUl->crntUlCqi[0] = cellSchd->ul.dfltUlCqi; + ueUl->validUlCqi = ueUl->crntUlCqi[0]; + } + ue->validTxAnt = ue->srsCb.selectedAnt; + } + else + { + ueUl->validUlCqi = cellSchd->ul.dfltUlCqi; + ue->validTxAnt = 0; + } +#ifdef UL_LA + ueUl->ulLaCb.cqiBasediTbs = rgSchCmnUlCqiToTbsTbl[isEcp] + [ueUl->validUlCqi] * 100; + ueUl->ulLaCb.deltaiTbs = 0; +#endif + +#else + ueUl->crntUlCqi[0] = cellSchd->ul.dfltUlCqi; +#endif /*TFU_UPGRADE */ + RGSCH_ARRAY_BOUND_CHECK(cell->instIdx, rgUeCatTbl, ueSchCmn->cmn.ueCat); + if (rgUeCatTbl[ueSchCmn->cmn.ueCat].ul64qamSup == FALSE) + { + ueUl->maxUlCqi = cellSchd->ul.max16qamCqi; + } + else + { + ueUl->maxUlCqi = RG_SCH_CMN_UL_NUM_CQI - 1; + } + + RETVOID; +} +/*********************************************************** + * + * Func : rgSCHCmnUpdUeCatCfg + * + * Desc : Updates UL and DL Ue Information + * + * Ret : + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PRIVATE Void rgSCHCmnUpdUeCatCfg +( +RgSchUeCb *ue, +RgSchCellCb *cell +) +#else +PRIVATE Void rgSCHCmnUpdUeCatCfg(ue, cell) +RgSchUeCb *ue; +RgSchCellCb *cell; +#endif +{ + RgSchDlHqEnt *hqE = NULLP; + RgSchCmnUlUe *ueUl = RG_SCH_CMN_GET_UL_UE(ue,cell); + RgSchCmnDlUe *ueDl = RG_SCH_CMN_GET_DL_UE(ue,cell); + RgSchCmnUe *ueSchCmn = RG_SCH_CMN_GET_UE(ue,cell); + RgSchCmnCell *cellSchd = RG_SCH_CMN_GET_CELL(cell); + + TRC2(rgSCHCmnUpdUeCatCfg) + + ueDl->maxTbBits = rgUeCatTbl[ueSchCmn->cmn.ueCat].maxDlTbBits; + + hqE = RG_SCH_CMN_GET_UE_HQE(ue, cell); + /*CA dev-Start*/ + U8 ri = 0; + ri = RGSCH_MIN(ri, cell->numTxAntPorts); + if(((CM_LTE_UE_CAT_6 == ueSchCmn->cmn.ueCat ) + ||(CM_LTE_UE_CAT_7 == ueSchCmn->cmn.ueCat)) + && (RG_SCH_MAX_TX_LYRS_4 == ri)) + { + ueDl->maxTbSz = rgUeCatTbl[ueSchCmn->cmn.ueCat].maxDlBits[1]; + } + else + { + ueDl->maxTbSz = rgUeCatTbl[ueSchCmn->cmn.ueCat].maxDlBits[0]; + } + /*CA dev-End*/ + ueDl->maxSbSz = (rgUeCatTbl[ueSchCmn->cmn.ueCat].maxSftChBits/ + hqE->numHqPrcs); + if (rgUeCatTbl[ueSchCmn->cmn.ueCat].ul64qamSup == FALSE) + { + ueUl->maxUlCqi = cellSchd->ul.max16qamCqi; + } + else + { + ueUl->maxUlCqi = RG_SCH_CMN_UL_NUM_CQI - 1; + } + ue->ul.maxBytesPerUePerTti = rgUeCatTbl[ueSchCmn->cmn.ueCat].maxUlBits * \ + RG_SCH_CMN_MAX_BITS_RATIO / (RG_SCH_CMN_UL_COM_DENOM*8); + RETVOID; +} + +/** + * @brief UE reconfiguration for scheduler. + * + * @details + * + * Function : rgSChCmnRgrUeRecfg + * + * This functions updates UE specific scheduler + * information upon UE reconfiguration. + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ue + * @param[int] RgrUeRecfg *ueRecfg + * @param[out] RgSchErrInfo *err + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 rgSCHCmnRgrUeRecfg +( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgrUeRecfg *ueRecfg, +RgSchErrInfo *err +) +#else +PUBLIC S16 rgSCHCmnRgrUeRecfg(cell, ue, ueRecfg, err) +RgSchCellCb *cell; +RgSchUeCb *ue; +RgrUeRecfg *ueRecfg; +RgSchErrInfo *err; +#endif +{ + RgSchCmnCell *cellSchCmn = RG_SCH_CMN_GET_CELL(cell); + U32 waitPer; + + TRC2(rgSCHCmnRgrUeRecfg); + /* Basic validations */ + if (ueRecfg->ueRecfgTypes & RGR_UE_TXMODE_RECFG) + { +#ifdef TFU_UPGRADE + rgSCHCmnDlHdlTxModeRecfg(cell, ue, ueRecfg, cell->numTxAntPorts); +#else + rgSCHCmnDlHdlTxModeRecfg(cell, ue, ueRecfg); +#endif /* TFU_UPGRADE */ + } + if(ueRecfg->ueRecfgTypes & RGR_UE_CSG_PARAM_RECFG) + { + ue->csgMmbrSta = ueRecfg->csgMmbrSta; + } + /* Changes for UE Category reconfiguration feature */ + if(ueRecfg->ueRecfgTypes & RGR_UE_UECAT_RECFG) + { + rgSCHCmnUpdUeCatCfg(ue, cell); + } + if (ueRecfg->ueRecfgTypes & RGR_UE_APRD_DLCQI_RECFG) + { + RgSchUeCellInfo *pCellInfo = RG_SCH_CMN_GET_PCELL_INFO(ue); + pCellInfo->acqiCb.aCqiCfg = ueRecfg->aprdDlCqiRecfg; + } +#ifndef TFU_UPGRADE + if (ueRecfg->ueRecfgTypes & RGR_UE_PRD_DLCQI_RECFG) + { + if ((ueRecfg->prdDlCqiRecfg.pres == TRUE) + && (ueRecfg->prdDlCqiRecfg.prdModeEnum != RGR_PRD_CQI_MOD10) + && (ueRecfg->prdDlCqiRecfg.prdModeEnum != RGR_PRD_CQI_MOD20)) + { + RLOG_ARG2(L_ERROR,DBG_CELLID,cell->cellId,"Unsupported periodic CQI " + "reporting mode %d for old CRNIT:%d", + (int)ueRecfg->prdDlCqiRecfg.prdModeEnum,ueRecfg->oldCrnti); + err->errCause = RGSCHERR_SCH_CFG; + RETVALUE(RFAILED); + } + ue->dl.ueDlCqiCfg.prdCqiCfg = ueRecfg->prdDlCqiRecfg; + } +#endif + + if (ueRecfg->ueRecfgTypes & RGR_UE_ULPWR_RECFG) + { + if (rgSCHPwrUeRecfg(cell, ue, ueRecfg) != ROK) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId, + "Power Reconfiguration Failed for OLD CRNTI:%d",ueRecfg->oldCrnti); + RETVALUE(RFAILED); + } + } + + if (ueRecfg->ueRecfgTypes & RGR_UE_QOS_RECFG) + { + /* Uplink Sched related Initialization */ + if ((ueRecfg->ueQosRecfg.dlAmbr == 0) && (ueRecfg->ueQosRecfg.ueBr == 0)) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,"Ul Ambr and DL Ambr " + "configured as 0 for OLD CRNTI:%d",ueRecfg->oldCrnti); + err->errCause = RGSCHERR_SCH_CFG; + RETVALUE(RFAILED); + } + ue->ul.cfgdAmbr = (ueRecfg->ueQosRecfg.ueBr * \ + RG_SCH_CMN_REFRESH_TIME)/100; + /* Downlink Sched related Initialization */ + ue->dl.ambrCfgd = (ueRecfg->ueQosRecfg.dlAmbr * \ + RG_SCH_CMN_REFRESH_TIME)/100; + /* Fix: syed Update the effAmbr and effUeBR fields w.r.t the + * new QOS configuration */ + rgSCHCmnDelUeFrmRefreshQ(cell, ue); + /* Fix: syed align multiple UEs to refresh at same time */ + rgSCHCmnGetRefreshPer(cell, ue, &waitPer); + rgSCHCmnApplyUeRefresh(cell, ue); + rgSCHCmnAddUeToRefreshQ(cell, ue, waitPer); + } +#ifdef EMTC_ENABLE + if((cell->emtcEnable)&&(TRUE == ue->isEmtcUe)) + { + if ((cellSchCmn->apisEmtcUl->rgSCHRgrUlUeRecfg(cell, ue, ueRecfg, err)) != ROK) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId, + "Spec Sched UL UE ReCFG FAILED for CRNTI:%d",ue->ueId); + RETVALUE(RFAILED); + } + if ((cellSchCmn->apisEmtcDl->rgSCHRgrDlUeRecfg(cell, ue, ueRecfg, err)) != ROK) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId, + "Spec Sched DL UE ReCFG FAILED for CRNTI:%d",ue->ueId); + RETVALUE(RFAILED); + } + } + else +#endif + { + if ((cellSchCmn->apisUl->rgSCHRgrUlUeRecfg(cell, ue, ueRecfg, err)) != ROK) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId, + "Spec Sched UL UE ReCFG FAILED for CRNTI:%d",ue->ueId); + RETVALUE(RFAILED); + } + if ((cellSchCmn->apisDl->rgSCHRgrDlUeRecfg(cell, ue, ueRecfg, err)) != ROK) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId, + "Spec Sched DL UE ReCFG FAILED for CRNTI:%d",ue->ueId); + RETVALUE(RFAILED); + } + } + /* DLFS UE Config */ + if (cellSchCmn->dl.isDlFreqSel) + { + if ((cellSchCmn->apisDlfs->rgSCHDlfsUeRecfg(cell, ue, \ + ueRecfg, err)) != ROK) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId, + "DLFS UE re-config FAILED for CRNTI:%d",ue->ueId); + RETVALUE(RFAILED); + } + } + +#ifdef LTEMAC_SPS + /* Invoke re-configuration on SPS module */ + if (rgSCHCmnSpsUeRecfg(cell, ue, ueRecfg, err) != ROK) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId, + "DL SPS ReCFG FAILED for UE CRNTI:%d", ue->ueId); + RETVALUE(RFAILED); + } +#endif + + RETVALUE(ROK); +} /* rgSCHCmnRgrUeRecfg*/ + +/*********************************************************** + * + * Func : rgSCHCmnUlUeDelAllocs + * + * Desc : Deletion of all UE allocations. + * + * Ret : + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PRIVATE Void rgSCHCmnUlUeDelAllocs +( +RgSchCellCb *cell, +RgSchUeCb *ue +) +#else +PRIVATE Void rgSCHCmnUlUeDelAllocs(cell, ue) +RgSchCellCb *cell; +RgSchUeCb *ue; +#endif +{ + RgSchCmnUlCell *cellUl = RG_SCH_CMN_GET_UL_CELL(cell); + RgSchCmnUlUe *ueUl = RG_SCH_CMN_GET_UL_UE(ue, cell); + U8 i; +#ifdef LTEMAC_SPS + RgSchCmnUlUeSpsInfo *ulSpsUe = RG_SCH_CMN_GET_UL_SPS_UE(ue,cell); +#endif + TRC2(rgSCHCmnUlUeDelAllocs); + + for (i = 0; i < ueUl->hqEnt.numHqPrcs; ++i) + { + RgSchUlHqProcCb *proc = rgSCHUhmGetUlHqProc(cell, ue, i); + +#ifdef ERRCLS_KW + /* proc can't be NULL here */ + if (proc) +#endif + { + /* R8 Upgrade */ + proc->ndi = 0; + if (proc->alloc) + { + /* Added Insure Fixes Of reading Dangling memory.NULLed crntAlloc */ +#ifdef LTEMAC_SPS + if(proc->alloc == ulSpsUe->ulSpsSchdInfo.crntAlloc) + { + ulSpsUe->ulSpsSchdInfo.crntAlloc = NULLP; + ulSpsUe->ulSpsSchdInfo.crntAllocSf = NULLP; + } +#endif +#ifdef EMTC_ENABLE + rgSCHCmnUlFreeAllocation(cell, &cellUl->ulSfArr[proc->ulSfIdx], + proc->alloc,ue->isEmtcUe); +#else + rgSCHCmnUlFreeAllocation(cell, &cellUl->ulSfArr[proc->ulSfIdx], + proc->alloc); +#endif + /* PHY probably needn't be intimated since + * whatever intimation it needs happens at the last minute + */ + } + /* Fix: syed Adaptive Msg3 Retx crash. Remove the harqProc + * from adaptive retx List. */ + if (proc->reTxLnk.node) + { + { + //TODO_SID: Need to take care + cmLListDelFrm(&cellUl->reTxLst, &proc->reTxLnk); + proc->reTxLnk.node = (PTR)NULLP; + } + } + } + } + RETVOID; +} + +/*********************************************************** + * + * Func : rgSCHCmnDelUeFrmRefreshQ + * + * Desc : Adds a UE to refresh queue, so that the UE is + * periodically triggered to refresh it's GBR and + * AMBR values. + * + * Ret : + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PRIVATE Void rgSCHCmnDelUeFrmRefreshQ +( +RgSchCellCb *cell, +RgSchUeCb *ue +) +#else +PRIVATE Void rgSCHCmnDelUeFrmRefreshQ(cell, ue) +RgSchCellCb *cell; +RgSchUeCb *ue; +#endif +{ + RgSchCmnCell *sched = RG_SCH_CMN_GET_CELL(cell); + CmTmrArg arg; + RgSchCmnUeInfo *ueSchd = RG_SCH_CMN_GET_CMN_UE(ue); + + TRC2(rgSCHCmnDelUeFrmRefreshQ); + +#ifdef RGL_SPECIFIC_CHANGES + if(ue->refreshOffset < RGSCH_MAX_REFRESH_GRPSZ) + { + if(cell->refreshUeCnt[ue->refreshOffset]) + { + cell->refreshUeCnt[ue->refreshOffset]--; + } + } +#endif + + + cmMemset((U8 *)&arg, 0, sizeof(arg)); + arg.tqCp = &sched->tmrTqCp; + arg.tq = sched->tmrTq; + arg.timers = &ueSchd->tmr; + arg.cb = (PTR)ue; + arg.tNum = 0; + arg.max = 1; + arg.evnt = RG_SCH_CMN_EVNT_UE_REFRESH; + + cmRmvCbTq(&arg); + RETVOID; +} + +/*********************************************************** + * + * Func : rgSCHCmnUeCcchSduDel + * + * Desc : Clear CCCH SDU scheduling context. + * + * Ret : + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PRIVATE Void rgSCHCmnUeCcchSduDel +( +RgSchCellCb *cell, +RgSchUeCb *ueCb +) +#else +PRIVATE Void rgSCHCmnUeCcchSduDel(cell, ueCb) +RgSchCellCb *cell; +RgSchUeCb *ueCb; +#endif +{ + RgSchDlHqEnt *hqE = NULLP; + RgSchDlHqProcCb *ccchSduHqP = NULLP; + RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell); + + TRC2(rgSCHCmnUeCcchSduDel); + + hqE = RG_SCH_CMN_GET_UE_HQE(ueCb, cell); + if (hqE == NULLP) + { + RETVOID; + } + ccchSduHqP = hqE->ccchSduProc; + if(ueCb->ccchSduLnk.node != NULLP) + { + /* Remove the ccchSduProc if it is in the Tx list */ + cmLListDelFrm(&(cell->ccchSduUeLst), &(ueCb->ccchSduLnk)); + ueCb->ccchSduLnk.node = NULLP; + } + else if(ccchSduHqP != NULLP) + { + /* Fix for crash due to stale pdcch. Release ccch pdcch*/ + if(ccchSduHqP->pdcch) + { + cmLListDelFrm(&ccchSduHqP->subFrm->pdcchInfo.pdcchs, + &ccchSduHqP->pdcch->lnk); + cmLListAdd2Tail(&cell->pdcchLst, &ccchSduHqP->pdcch->lnk); + ccchSduHqP->pdcch = NULLP; + } + if(ccchSduHqP->tbInfo[0].ccchSchdInfo.retxLnk.node != NULLP) + { + /* Remove the ccchSduProc if it is in the retx list */ + cmLListDelFrm(&cellSch->dl.ccchSduRetxLst, + &ccchSduHqP->tbInfo[0].ccchSchdInfo.retxLnk); + /* ccchSduHqP->tbInfo[0].ccchSchdInfo.retxLnk.node = NULLP; */ + rgSCHDhmRlsHqpTb(ccchSduHqP, 0, TRUE); + } + else if ((ccchSduHqP->subFrm != NULLP) && + (ccchSduHqP->hqPSfLnk.node != NULLP)) + { + rgSCHUtlDlHqPTbRmvFrmTx(ccchSduHqP->subFrm, + ccchSduHqP, 0, FALSE); + rgSCHDhmRlsHqpTb(ccchSduHqP, 0, TRUE); + } + } + RETVOID; +} + + + + +/** + * @brief UE deletion for scheduler. + * + * @details + * + * Function : rgSCHCmnUeDel + * + * This functions deletes all scheduler information + * pertaining to an UE. + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ue + * @return Void + **/ +#ifdef ANSI +PUBLIC Void rgSCHCmnUeDel +( +RgSchCellCb *cell, +RgSchUeCb *ue +) +#else +PUBLIC Void rgSCHCmnUeDel(cell, ue) +RgSchCellCb *cell; +RgSchUeCb *ue; +#endif +{ + RgSchDlHqEnt *hqE = NULLP; + RgSchCmnUlUe *ueUl = RG_SCH_CMN_GET_UL_UE(ue,cell); + CmLList *node; + RgSchCmnAllocRecord *allRcd; + U8 cnt; + RgSchCmnCell *cellSchCmn = RG_SCH_CMN_GET_CELL(cell); + U32 idx = 0; + TRC2(rgSCHCmnUeDel); + + if (RG_SCH_CMN_GET_UE(ue,cell) == NULLP) + { + /* Common scheduler config has not happened yet */ + RETVOID; + } + hqE = RG_SCH_CMN_GET_UE_HQE(ue, cell); + if(hqE) + { + /* UE Free can be triggered before MSG4 done when dlHqE is not updated */ +#ifdef EMTC_ENABLE + if(ue->isEmtcUe) + { + rgSCHEmtcCmnUeCcchSduDel(cell, ue); + } + else +#endif + { + rgSCHCmnUeCcchSduDel(cell, ue); + } + } + rgSCHCmnDelUeFrmRefreshQ(cell, ue); + + rgSCHCmnUlUeDelAllocs(cell, ue); + + rgSCHCmnDelRachInfo(cell, ue); + +#ifdef EMTC_ENABLE + if(TRUE == ue->isEmtcUe) + { + cellSchCmn->apisEmtcUl->rgSCHFreeUlUe(cell, ue); + } + else +#endif + { + cellSchCmn->apisUl->rgSCHFreeUlUe(cell, ue); + } +#ifdef LTE_ADV + if (ue->numSCells) + { + for(idx = 1; idx <= RG_SCH_MAX_SCELL ; idx++) + { + if(ue->cellInfo[idx] != NULLP) + { + rgSCHSCellDelUeSCell(cell,ue,idx); + } + } + + } +#endif +#ifdef EMTC_ENABLE + if((cell->emtcEnable)&&(TRUE == ue->isEmtcUe)) + { + cellSchCmn->apisEmtcDl->rgSCHFreeDlUe(cell, ue); + } + else +#endif + { + cellSchCmn->apisDl->rgSCHFreeDlUe(cell, ue); + } + rgSCHPwrUeDel(cell, ue); + +#ifdef LTEMAC_SPS + rgSCHCmnSpsUeDel(cell, ue); +#endif /* LTEMAC_SPS*/ + + /* CA Dev Start*/ + rgSchCmnDlSfHqDel(ue, cell); + /* CA Dev End*/ + /* DLFS UE delete */ + if (cellSchCmn->dl.isDlFreqSel) + { + cellSchCmn->apisDlfs->rgSCHDlfsUeDel(cell, ue); + } + node = ueUl->ulAllocLst.first; + +/* ccpu00117052 - MOD - Passing double pointer in all the places of + rgSCHUtlFreeSBuf function call for proper NULLP assignment*/ + while(node) + { + allRcd = (RgSchCmnAllocRecord *)node->node; + node = node->next; + cmLListDelFrm(&ueUl->ulAllocLst, &allRcd->lnk); + rgSCHUtlFreeSBuf(cell->instIdx, + (Data**)(&allRcd), (sizeof(RgSchCmnAllocRecord))); + } + + for(cnt = 0; cnt < RGSCH_MAX_LCG_PER_UE; cnt++) + { + if (ue->ul.lcgArr[cnt].sch != NULLP) + { + rgSCHUtlFreeSBuf(cell->instIdx, + (Data**)(&(ue->ul.lcgArr[cnt].sch)), (sizeof(RgSchCmnLcg))); + } + } + + /* Fix : syed Moved hqEnt deinit to rgSCHCmnDlDeInitHqEnt */ + idx = (U8)((cell->cellId - rgSchCb[cell->instIdx].genCfg.startCellId) & (CM_LTE_MAX_CELLS - 1)); + rgSCHUtlFreeSBuf(cell->instIdx, + (Data**)(&(((ue->cellInfo[ue->cellIdToCellIdxMap[idx]])->sch))), (sizeof(RgSchCmnUe))); + RETVOID; +} /* rgSCHCmnUeDel */ + + +/** + * @brief This function handles the common code rate configurations + * done as part of RgrCellCfg/RgrCellRecfg. + * + * @details + * + * Function: rgSCHCmnDlCnsdrCmnRt + * Purpose: This function handles the common code rate configurations + * done as part of RgrCellCfg/RgrCellRecfg. + * + * Invoked by: Scheduler + * + * @param[in] RgSchCellCb *cell + * @param[in] RgrDlCmnCodeRateCfg *dlCmnCodeRate + * @return S16 + * + **/ +#ifdef ANSI +PRIVATE S16 rgSCHCmnDlCnsdrCmnRt +( +RgSchCellCb *cell, +RgrDlCmnCodeRateCfg *dlCmnCodeRate +) +#else +PRIVATE S16 rgSCHCmnDlCnsdrCmnRt(cell, dlCmnCodeRate) +RgSchCellCb *cell; +RgrDlCmnCodeRateCfg *dlCmnCodeRate; +#endif +{ + RgSchCmnCell *cellDl = RG_SCH_CMN_GET_CELL(cell); + U32 bitsPerRb; + U32 bitsPer2Rb; + U32 bitsPer3Rb; + U8 i, rbNum; + U32 pdcchBits; + + TRC2(rgSCHCmnDlCnsdrCmnRt); + + /* code rate is bits per 1024 phy bits, since modl'n scheme is 2. it is + * bits per 1024/2 REs */ + if (dlCmnCodeRate->bcchPchRaCodeRate != 0) + { + bitsPerRb = ((dlCmnCodeRate->bcchPchRaCodeRate * 2) * + cellDl->dl.noResPerRb[3])/1024; + } + else + { + bitsPerRb = ((RG_SCH_CMN_DEF_BCCHPCCH_CODERATE * 2) * + cellDl->dl.noResPerRb[3])/1024; + } + /* Store bitsPerRb in cellDl->dl to use later to determine + * Number of RBs for UEs with SI-RNTI, P-RNTI and RA-RNTI */ + cellDl->dl.bitsPerRb = bitsPerRb; + /* ccpu00115595 end*/ + /* calculate the ITbs for 2 RBs. Initialize ITbs to MAX value */ + i = 0; + rbNum = 2; + bitsPer2Rb = bitsPerRb * rbNum; + while ((i < 9) && (rgTbSzTbl[0][i][rbNum - 1] <= bitsPer2Rb)) + i++; + + (i <= 1)? (cellDl->dl.cmnChITbs.iTbs2Rbs = 0) : + (cellDl->dl.cmnChITbs.iTbs2Rbs = i-1); + + /* calculate the ITbs for 3 RBs. Initialize ITbs to MAX value */ + i = 0; + rbNum = 3; + bitsPer3Rb = bitsPerRb * rbNum; + while ((i < 9) && (rgTbSzTbl[0][i][rbNum - 1] <= bitsPer3Rb)) + i++; + + (i <= 1)? (cellDl->dl.cmnChITbs.iTbs3Rbs = 0) : + (cellDl->dl.cmnChITbs.iTbs3Rbs = i-1); + + + pdcchBits = 1 + /* Flag for format0/format1a differentiation */ + 1 + /* Localized/distributed VRB assignment flag */ + 5 + /* For mcs */ +#ifndef LTE_TDD + 3 + /* Harq process Id */ +#else + 4 + /* Harq process Id */ + 2 + /* UL Index or DAI */ +#endif + 1 + /* New Data Indicator */ + 2 + /* For RV */ + 2 + /* For tpc */ + 1 + rgSCHUtlLog32bitNbase2((cell->bwCfg.dlTotalBw * \ + (cell->bwCfg.dlTotalBw + 1))/2); + /* Resource block assignment ceil[log2(bw(bw+1)/2)] : \ + Since VRB is local */ + /* For TDD consider DAI */ + + /* Convert the pdcchBits to actual pdcchBits required for transmission */ + if (dlCmnCodeRate->pdcchCodeRate != 0) + { + pdcchBits = (pdcchBits * 1024)/dlCmnCodeRate->pdcchCodeRate; + if (pdcchBits <= 288) /* 288 : Num of pdcch bits for aggrLvl=4 */ + { + cellDl->dl.cmnChAggrLvl = CM_LTE_AGGR_LVL4; + } + else /* 576 : Num of pdcch bits for aggrLvl=8 */ + { + cellDl->dl.cmnChAggrLvl = CM_LTE_AGGR_LVL8; + } + } + else + { + cellDl->dl.cmnChAggrLvl = CM_LTE_AGGR_LVL4; + } + if (dlCmnCodeRate->ccchCqi == 0) + { + RETVALUE(RFAILED); + } + else + { + cellDl->dl.ccchCqi = dlCmnCodeRate->ccchCqi; + } + RETVALUE(ROK); +} + +#ifdef LTE_TDD +/** + * @brief This function handles the configuration of cell for the first + * time by the scheduler. + * + * @details + * + * Function: rgSCHCmnDlRgrCellCfg + * Purpose: Configuration received is stored into the data structures + * Also, update the scheduler with the number of frames of + * RACH preamble transmission. + * + * Invoked by: BO and Scheduler + * + * @param[in] RgSchCellCb* cell + * @param[in] RgrCellCfg* cfg + * @return S16 + * + **/ +#ifdef ANSI +PRIVATE S16 rgSCHCmnDlRgrCellCfg +( +RgSchCellCb *cell, +RgrCellCfg *cfg, +RgSchErrInfo *err +) +#else +PRIVATE S16 rgSCHCmnDlRgrCellCfg(cell, cfg, err) +RgSchCellCb *cell; +RgrCellCfg *cfg; +RgSchErrInfo *err; +#endif +{ + RgSchCmnCell *cellSch; + U8 cp; + U8 sfCount; + U8 numPdcchSym; + U8 noSymPerSlot; + U8 maxDlSubfrms = cell->numDlSubfrms; + U8 splSubfrmIdx = cfg->spclSfCfgIdx; + U8 swPtCnt = 0; + Bool isSplfrm; + RgSchTddSubfrmInfo subfrmInfo = rgSchTddMaxUlSubfrmTbl[cell->ulDlCfgIdx]; + S16 ret; + U8 splSfIdx; + U8 antPortIdx; + U8 numCrs; + U8 cfi; + U8 cfiIdx; + RgSchDlSf *sf; + U8 splSfCfi; + U8 mPhich; + + TRC2(rgSCHCmnDlRgrCellCfg); + + + cellSch = RG_SCH_CMN_GET_CELL(cell); + cellSch->dl.numRaSubFrms = rgRaPrmblToRaFrmTbl[cell->\ + rachCfg.preambleFormat]; + /*[ccpu00138532]-ADD-fill the Msg4 Harq data */ + cell->dlHqCfg.maxMsg4HqTx = cfg->dlHqCfg.maxMsg4HqTx; + + /* Msg4 Tx Delay = (HARQ_RTT * MAX_MSG4_HARQ_RETX) + + 3 TTI (MAX L1+L2 processing delay at the UE) */ + cellSch->dl.msg4TxDelay = (cfg->dlHqCfg.maxMsg4HqTx-1) * + rgSchCmnHarqRtt[cell->ulDlCfgIdx] + 3; + cellSch->dl.maxUePerDlSf = cfg->maxUePerDlSf; + cellSch->dl.maxUeNewTxPerTti = cfg->maxDlUeNewTxPerTti; + if (cfg->maxUePerDlSf == 0) + { + cellSch->dl.maxUePerDlSf = RG_SCH_CMN_MAX_UE_PER_DL_SF; + } + if (cellSch->dl.maxUePerDlSf < cellSch->dl.maxUeNewTxPerTti) + { + RETVALUE(RFAILED); + } + + + if (cell->bwCfg.dlTotalBw <= 10) + { + cfiIdx = 1; + numPdcchSym = 2; + } + else + { + cfiIdx = 0; + numPdcchSym = 1; + } + /* DwPTS Scheduling Changes Start */ + cellSch->dl.splSfCfg = splSubfrmIdx; + + if (cfg->isCpDlExtend == TRUE) + { + if((0 == splSubfrmIdx) || (4 == splSubfrmIdx) || + (7 == splSubfrmIdx) || (8 == splSubfrmIdx) + ) + { + cell->splSubfrmCfg.isDlDataAllowed = FALSE; + } + else + { + cell->splSubfrmCfg.isDlDataAllowed = TRUE; + } + } + else + { + /* Refer to 36.213 Section 7.1.7 */ + if((0 == splSubfrmIdx) || (5 == splSubfrmIdx)) + { + cell->splSubfrmCfg.isDlDataAllowed = FALSE; + } + else + { + cell->splSubfrmCfg.isDlDataAllowed = TRUE; + } + } + /* DwPTS Scheduling Changes End */ + + splSfCfi = RGSCH_MIN(cell->dynCfiCb.maxCfi, cellSch->cfiCfg.cfi); + RGSCH_GET_SPS_SF_CFI(cell->bwCfg.dlTotalBw, splSfCfi); + + for (sfCount = 0; sfCount < maxDlSubfrms; sfCount++) + { + sf = cell->subFrms[sfCount]; + /* Sfcount matches the first special subframe occurs at Index 0 + * or subsequent special subframes */ + if(subfrmInfo.switchPoints == 1) + { + isSplfrm = rgSCHCmnIsSplSubfrm(swPtCnt, sfCount, + RG_SCH_CMN_10_MS_PRD, &subfrmInfo); + } + else + { + isSplfrm = rgSCHCmnIsSplSubfrm(swPtCnt, sfCount, + RG_SCH_CMN_5_MS_PRD, &subfrmInfo); + } + if(isSplfrm == TRUE) + { + swPtCnt++; + /* DwPTS Scheduling Changes Start */ + if (cell->splSubfrmCfg.isDlDataAllowed == TRUE) + { + sf->sfType = RG_SCH_SPL_SF_DATA; + } + else + { + sf->sfType = RG_SCH_SPL_SF_NO_DATA; + } + /* DwPTS Scheduling Changes End */ + } + else + { + /* DwPTS Scheduling Changes Start */ + if (sf->sfNum != 0) + { + sf->sfType = RG_SCH_DL_SF; + } + else + { + sf->sfType = RG_SCH_DL_SF_0; + } + /* DwPTS Scheduling Changes End */ + } + + /* Calculate the number of CCEs per subframe in the cell */ + mPhich = rgSchTddPhichMValTbl[cell->ulDlCfgIdx][sf->sfNum]; + if(cell->dynCfiCb.isDynCfiEnb == TRUE) + { + /* In case if Dynamic CFI feature is enabled, default CFI + * value 1 is used */ + sf->nCce = cell->dynCfiCb.cfi2NCceTbl[mPhich][1]; + } + else + { + if (sf->sfType == RG_SCH_SPL_SF_DATA) + { + sf->nCce = cell->dynCfiCb.cfi2NCceTbl[mPhich][splSfCfi]; + } + else + { + sf->nCce = cell->dynCfiCb.cfi2NCceTbl[mPhich][RGSCH_MIN(cell->dynCfiCb.maxCfi, cellSch->cfiCfg.cfi)]; + } + } + } + + /* Intialize the RACH response scheduling related infromation */ + if(rgSCHCmnDlRachInfoInit(cell) != ROK) + { + RETVALUE(RFAILED); + } + + /* Allocate PRACH preamble list */ + rgSCHCmnDlCreateRachPrmLst(cell); + + /* Initialize PHICH offset information */ + rgSCHCmnDlPhichOffsetInit(cell); + + /* Update the size of HARQ ACK/NACK feedback table */ + /* The array size is increased by 2 to have enough free indices, where other + * indices are busy waiting for HARQ feedback */ + cell->ackNackFdbkArrSize = rgSchTddANFdbkMapTbl[cell->ulDlCfgIdx] + 2; + + /* Initialize expected HARQ ACK/NACK feedback time */ + rgSCHCmnDlANFdbkInit(cell); + + /* Initialize UL association set index */ + if(cell->ulDlCfgIdx != 0) + { + rgSCHCmnDlKdashUlAscInit(cell); + } + + if (cfg->isCpDlExtend == TRUE) + { + cp = RG_SCH_CMN_EXT_CP; + noSymPerSlot = 6; + cell->splSubfrmCfg.dwPts = + rgSchTddSplSubfrmInfoTbl[splSubfrmIdx].extDlDwPts; + + if ( cell->splSubfrmCfg.dwPts == 0 ) + { + cell->isDwPtsCnted = FALSE; + } + else + { + cell->isDwPtsCnted = TRUE; + } + + if(cfg->isCpUlExtend == TRUE) + { + cell->splSubfrmCfg.upPts = + rgSchTddSplSubfrmInfoTbl[splSubfrmIdx].extDlExtUpPts; + } + else + { + cell->splSubfrmCfg.upPts = + rgSchTddSplSubfrmInfoTbl[splSubfrmIdx].extDlNorUpPts; + } + } + else + { + cp = RG_SCH_CMN_NOR_CP; + noSymPerSlot = 7; + cell->splSubfrmCfg.dwPts = + rgSchTddSplSubfrmInfoTbl[splSubfrmIdx].norDlDwPts; + cell->isDwPtsCnted = TRUE; + + if(cfg->isCpUlExtend == TRUE) + { + cell->splSubfrmCfg.upPts = + rgSchTddSplSubfrmInfoTbl[splSubfrmIdx].norDlExtUpPts; + } + else + { + cell->splSubfrmCfg.upPts = + rgSchTddSplSubfrmInfoTbl[splSubfrmIdx].norDlNorUpPts; + } + } + + /* Initializing the cqiToEffTbl and cqiToTbsTbl for every CFI value */ + for(cfi = 1; cfi < RG_SCH_CMN_MAX_CFI; cfi++,cfiIdx++) + { + cellSch->dl.cqiToTbsTbl[0][cfi] = rgSchCmnCqiToTbs[0][cp][cfiIdx]; + cellSch->dl.cqiToEffTbl[0][cfi] = rgSchCmnEffTbl[0][cp][rgSchCmnAntIdx\ + [cell->numTxAntPorts]][cfiIdx]; + cellSch->dl.cqiToTbsTbl[1][cfi] = rgSchCmnCqiToTbs[1][cp][cfiIdx]; + cellSch->dl.cqiToEffTbl[1][cfi] = rgSchCmnEffTbl[1][cp][rgSchCmnAntIdx\ + [cell->numTxAntPorts]][cfiIdx]; + } + + /* Initializing the values of CFI parameters */ + if(cell->dynCfiCb.isDynCfiEnb) + { + /* If DCFI is enabled, current CFI value will start from 1 */ + cellSch->dl.currCfi = cellSch->dl.newCfi = 1; + } + else + { + /* If DCFI is disabled, current CFI value is set as default max allowed CFI value */ + cellSch->dl.currCfi = RGSCH_MIN(cell->dynCfiCb.maxCfi, cellSch->cfiCfg.cfi); + cellSch->dl.newCfi = cellSch->dl.currCfi; + } + + /* Include CRS REs while calculating Efficiency + * The number of Resource Elements occupied by CRS depends on Number of + * Antenna Ports. Please refer to Section 6.10.1 of 3GPP TS 36.211 V8.8.0. + * Also, please refer to Figures 6.10.1.2-1 and 6.10.1.2-2 for diagrammatic + * details of the same. Please note that PDCCH overlap symbols would not + * considered in CRS REs deduction */ + for (cfi = 1; cfi < RG_SCH_CMN_MAX_CFI; cfi++, numPdcchSym++) + { + cellSch->dl.noResPerRb[cfi] = (((noSymPerSlot * RG_SCH_CMN_NUM_SLOTS_PER_SF) + - numPdcchSym) *RB_SCH_CMN_NUM_SCS_PER_RB) - rgSchCmnNumResForCrs[cell->numTxAntPorts]; + } + + /* DwPTS Scheduling Changes Start */ + antPortIdx = (cell->numTxAntPorts == 1)? 0: + ((cell->numTxAntPorts == 2)? 1: 2); + + if (cp == RG_SCH_CMN_NOR_CP) + { + splSfIdx = (splSubfrmIdx == 4)? 1: 0; + } + else + { + splSfIdx = (splSubfrmIdx == 3)? 1: 0; + } + + numCrs = rgSchCmnDwptsCrs[splSfIdx][antPortIdx]; + + for (cfi = 1; cfi < RG_SCH_CMN_MAX_CFI-1; cfi++) + { + /* If CFI is 2 and Ant Port is 4, don't consider the sym 1 CRS REs */ + if (antPortIdx == 2 && cfi == 2) + { + numCrs -= 4; + } + cellSch->dl.numReDwPts[cfi] = ((cell->splSubfrmCfg.dwPts - cfi)* + RB_SCH_CMN_NUM_SCS_PER_RB) - numCrs; + } + /* DwPTS Scheduling Changes End */ + + if (cfg->maxDlBwPerUe == 0) + { + cellSch->dl.maxDlBwPerUe = RG_SCH_CMN_MAX_DL_BW_PERUE; + } + else + { + cellSch->dl.maxDlBwPerUe = cfg->maxDlBwPerUe; + } + if (cfg->maxDlRetxBw == 0) + { + cellSch->dl.maxDlRetxBw = RG_SCH_CMN_MAX_DL_RETX_BW; + } + else + { + cellSch->dl.maxDlRetxBw = cfg->maxDlRetxBw; + } + /* Fix: MUE_PERTTI_DL*/ + cellSch->dl.maxUePerDlSf = cfg->maxUePerDlSf; + cellSch->dl.maxUeNewTxPerTti = cfg->maxDlUeNewTxPerTti; + if (cfg->maxUePerDlSf == 0) + { + cellSch->dl.maxUePerDlSf = RG_SCH_CMN_MAX_UE_PER_DL_SF; + } + RG_SCH_RESET_HCSG_DL_PRB_CNTR(&cellSch->dl); + /*[ccpu00138609]-ADD- Configure the Max CCCH Counter */ + if (cfg->maxCcchPerDlSf > cfg->maxUePerDlSf) + { + RLOG_ARG2(L_ERROR,DBG_CELLID,cell->cellId, + "Invalid configuration !: " + "maxCcchPerDlSf %u > maxUePerDlSf %u", + cfg->maxCcchPerDlSf, cfg->maxUePerDlSf ); + + RETVALUE(RFAILED); + } + else if (!cfg->maxCcchPerDlSf) + { + /* ccpu00143032: maxCcchPerDlSf 0 means not configured by application + * hence setting to maxUePerDlSf. If maxCcchPerDlSf is 0 then scheduler + * does't consider CCCH allocation in MaxUePerTti cap. Hence more than + * 4UEs getting schduled & SCH expects >16 Hq PDUs in a TTI which causes + * FLE crash in PHY as PHY has limit of 16 max*/ + cellSch->dl.maxCcchPerDlSf = cfg->maxUePerDlSf; + } + else + { + cellSch->dl.maxCcchPerDlSf = cfg->maxCcchPerDlSf; + } + if (rgSCHCmnDlCnsdrCmnRt(cell, &cfg->dlCmnCodeRate) != ROK) + { + RETVALUE(RFAILED); + } + + /*ccpu00118273 - ADD - start */ + cmLListInit(&cellSch->dl.msg4RetxLst); +#ifdef RGR_V1 + cmLListInit(&cellSch->dl.ccchSduRetxLst); +#endif + +#ifdef RG_PHASE2_SCHED + if (cellSch->apisDlfs == NULLP) /* DFLS specific initialization */ + { + cellSch->apisDlfs = &rgSchDlfsSchdTbl[cfg->dlfsSchdType]; + } + if (cfg->dlfsCfg.isDlFreqSel) + { + ret = cellSch->apisDlfs->rgSCHDlfsCellCfg(cell, cfg, err); + if (ret != ROK) + { + RETVALUE(RFAILED); + } + } + cellSch->dl.isDlFreqSel = cfg->dlfsCfg.isDlFreqSel; +#endif + + /* Power related configuration */ + ret = rgSCHPwrCellCfg(cell, cfg); + if (ret != ROK) + { + RETVALUE(RFAILED); + } + + cellSch->dl.bcchTxPwrOffset = cfg->bcchTxPwrOffset; + cellSch->dl.pcchTxPwrOffset = cfg->pcchTxPwrOffset; + cellSch->dl.rarTxPwrOffset = cfg->rarTxPwrOffset; + cellSch->dl.phichTxPwrOffset = cfg->phichTxPwrOffset; + cellSch->dl.msg4pAVal = cfg->msg4pAVal; + RETVALUE(ROK); +} +#else /* LTE_TDD */ +/** + * @brief This function handles the configuration of cell for the first + * time by the scheduler. + * + * @details + * + * Function: rgSCHCmnDlRgrCellCfg + * Purpose: Configuration received is stored into the data structures + * Also, update the scheduler with the number of frames of + * RACH preamble transmission. + * + * Invoked by: BO and Scheduler + * + * @param[in] RgSchCellCb* cell + * @param[in] RgrCellCfg* cfg + * @param[in] RgSchErrInfo* err + * @return S16 + * + **/ +#ifdef ANSI +PRIVATE S16 rgSCHCmnDlRgrCellCfg +( +RgSchCellCb *cell, +RgrCellCfg *cfg, +RgSchErrInfo *err +) +#else +PRIVATE S16 rgSCHCmnDlRgrCellCfg(cell, cfg, err) +RgSchCellCb *cell; +RgrCellCfg *cfg; +RgSchErrInfo *err; +#endif +{ + S16 ret; + RgSchCmnCell *cellSch; + U8 cp; + U8 numPdcchSym; + U8 noSymPerSlot; + U8 cfi; + U8 cfiIdx; + + TRC2(rgSCHCmnDlRgrCellCfg); + + cellSch = RG_SCH_CMN_GET_CELL(cell); + + /* Initialize the parameters with the ones received in the */ + /* configuration. */ + + /* Added matrix 'rgRaPrmblToRaFrmTbl' for computation of RA + * sub-frames from preamble format */ + cellSch->dl.numRaSubFrms = rgRaPrmblToRaFrmTbl[cell->rachCfg.preambleFormat]; + + /*[ccpu00138532]-ADD-fill the Msg4 Harq data */ + cell->dlHqCfg.maxMsg4HqTx = cfg->dlHqCfg.maxMsg4HqTx; + + /* Msg4 Tx Delay = (HARQ_RTT * MAX_MSG4_HARQ_RETX) + + 3 TTI (MAX L1+L2 processing delay at the UE) */ + cellSch->dl.msg4TxDelay = (cfg->dlHqCfg.maxMsg4HqTx-1) * + rgSchCmnHarqRtt[7] + 3; + + if (cell->bwCfg.dlTotalBw <= 10) + { + cfiIdx = 1; + numPdcchSym = 2; + } + else + { + cfiIdx = 0; + numPdcchSym = 1; + } + + if (cell->isCpDlExtend == TRUE) + { + cp = RG_SCH_CMN_EXT_CP; + noSymPerSlot = 6; + } + else + { + cp = RG_SCH_CMN_NOR_CP; + noSymPerSlot = 7; + } + + /* Initializing the cqiToEffTbl and cqiToTbsTbl for every CFI value */ + for(cfi = 1; cfi < RG_SCH_CMN_MAX_CFI; cfi++, cfiIdx++) + { + cellSch->dl.cqiToTbsTbl[0][cfi] = rgSchCmnCqiToTbs[0][cp][cfiIdx]; +#ifdef EMTC_ENABLE + cellSch->dl.emtcCqiToTbsTbl[0][cfi] = rgSchEmtcCmnCqiToTbs[0][cp][cfiIdx]; +#endif + cellSch->dl.cqiToEffTbl[0][cfi] = rgSchCmnEffTbl[0][cp][rgSchCmnAntIdx\ + [cell->numTxAntPorts]][cfiIdx]; + cellSch->dl.cqiToTbsTbl[1][cfi] = rgSchCmnCqiToTbs[1][cp][cfiIdx]; +#ifdef EMTC_ENABLE + cellSch->dl.emtcCqiToTbsTbl[1][cfi] = rgSchEmtcCmnCqiToTbs[1][cp][cfiIdx]; +#endif + cellSch->dl.cqiToEffTbl[1][cfi] = rgSchCmnEffTbl[1][cp][rgSchCmnAntIdx\ + [cell->numTxAntPorts]][cfiIdx]; + } + + /* Initializing the values of CFI parameters */ + if(cell->dynCfiCb.isDynCfiEnb) + { + /* If DCFI is enabled, current CFI value will start from 1 */ + cellSch->dl.currCfi = cellSch->dl.newCfi = 1; + } + else + { + /* If DCFI is disabled, current CFI value is set as default CFI value */ + cellSch->dl.currCfi = cellSch->cfiCfg.cfi; + cellSch->dl.newCfi = cellSch->dl.currCfi; + } + + /* Include CRS REs while calculating Efficiency + * The number of Resource Elements occupied by CRS depends on Number of + * Antenna Ports. Please refer to Section 6.10.1 of 3GPP TS 36.211 V8.8.0. + * Also, please refer to Figures 6.10.1.2-1 and 6.10.1.2-2 for diagrammatic + * details of the same. Please note that PDCCH overlap symbols would not + * considered in CRS REs deduction */ + for (cfi = 1; cfi < RG_SCH_CMN_MAX_CFI; cfi++, numPdcchSym++) + { + cellSch->dl.noResPerRb[cfi] = (((noSymPerSlot * RG_SCH_CMN_NUM_SLOTS_PER_SF) + - numPdcchSym) * RB_SCH_CMN_NUM_SCS_PER_RB) - rgSchCmnNumResForCrs[cell->numTxAntPorts]; + } + + if (cfg->maxDlBwPerUe == 0) + { + cellSch->dl.maxDlBwPerUe = RG_SCH_CMN_MAX_DL_BW_PERUE; + } + else + { + cellSch->dl.maxDlBwPerUe = cfg->maxDlBwPerUe; + } + if (cfg->maxDlRetxBw == 0) + { + cellSch->dl.maxDlRetxBw = RG_SCH_CMN_MAX_DL_RETX_BW; + } + else + { + cellSch->dl.maxDlRetxBw = cfg->maxDlRetxBw; + } + + /* Fix: MUE_PERTTI_DL*/ + cellSch->dl.maxUePerDlSf = cfg->maxUePerDlSf; + cellSch->dl.maxUeNewTxPerTti = cfg->maxDlUeNewTxPerTti; + if (cfg->maxUePerDlSf == 0) + { + cellSch->dl.maxUePerDlSf = RG_SCH_CMN_MAX_UE_PER_DL_SF; + } + /* Fix: MUE_PERTTI_DL syed validating Cell Configuration */ + if (cellSch->dl.maxUePerDlSf < cellSch->dl.maxUeNewTxPerTti) + { + RLOG_ARG2(L_ERROR,DBG_CELLID,cell->cellId, + "FAILED MaxUePerDlSf(%u) < MaxDlUeNewTxPerTti(%u)", + cellSch->dl.maxUePerDlSf, + cellSch->dl.maxUeNewTxPerTti); + RETVALUE(RFAILED); + } + /*[ccpu00138609]-ADD- Configure the Max CCCH Counter */ + if (cfg->maxCcchPerDlSf > cfg->maxUePerDlSf) + { + RLOG_ARG2(L_ERROR,DBG_CELLID,cell->cellId,"Invalid configuration !: " + "maxCcchPerDlSf %u > maxUePerDlSf %u", + cfg->maxCcchPerDlSf, cfg->maxUePerDlSf ); + + RETVALUE(RFAILED); + } + else if (!cfg->maxCcchPerDlSf) + { + /* ccpu00143032: maxCcchPerDlSf 0 means not configured by application + * hence setting to maxUePerDlSf. If maxCcchPerDlSf is 0 then scheduler + * does't consider CCCH allocation in MaxUePerTti cap. Hence more than + * 4UEs getting schduled & SCH expects >16 Hq PDUs in a TTI which causes + * FLE crash in PHY as PHY has limit of 16 max*/ + cellSch->dl.maxCcchPerDlSf = cfg->maxUePerDlSf; + } + else + { + cellSch->dl.maxCcchPerDlSf = cfg->maxCcchPerDlSf; + } + + + if (rgSCHCmnDlCnsdrCmnRt(cell, &cfg->dlCmnCodeRate) != ROK) + { + RETVALUE(RFAILED); + } + cmLListInit(&cellSch->dl.msg4RetxLst); +#ifdef RGR_V1 + cmLListInit(&cellSch->dl.ccchSduRetxLst); +#endif + +#ifdef RG_PHASE2_SCHED + if (cellSch->apisDlfs == NULLP) /* DFLS specific initialization */ + { + cellSch->apisDlfs = &rgSchDlfsSchdTbl[cfg->dlfsSchdType]; + } + if (cfg->dlfsCfg.isDlFreqSel) + { + ret = cellSch->apisDlfs->rgSCHDlfsCellCfg(cell, cfg, err); + if (ret != ROK) + { + RETVALUE(RFAILED); + } + } + cellSch->dl.isDlFreqSel = cfg->dlfsCfg.isDlFreqSel; +#endif + + /* Power related configuration */ + ret = rgSCHPwrCellCfg(cell, cfg); + if (ret != ROK) + { + RETVALUE(RFAILED); + } + + cellSch->dl.bcchTxPwrOffset = cfg->bcchTxPwrOffset; + cellSch->dl.pcchTxPwrOffset = cfg->pcchTxPwrOffset; + cellSch->dl.rarTxPwrOffset = cfg->rarTxPwrOffset; + cellSch->dl.phichTxPwrOffset = cfg->phichTxPwrOffset; + RG_SCH_RESET_HCSG_DL_PRB_CNTR(&cellSch->dl); + RETVALUE(ROK); +} +#endif /* LTE_TDD */ + +/*********************************************************** + * + * Func : rgSCHCmnUlCalcReqRbCeil + * + * Desc : Calculate RB required to satisfy 'bytes' for + * a given CQI. + * Returns number of RBs such that requirement + * is necessarily satisfied (does a 'ceiling' + * computation). + * + * Ret : Required RBs (U8) + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PUBLIC U8 rgSCHCmnUlCalcReqRbCeil +( +U32 bytes, +U8 cqi, +RgSchCmnUlCell *cellUl +) +#else +PUBLIC U8 rgSCHCmnUlCalcReqRbCeil(bytes, cqi, cellUl) +U32 bytes; +U8 cqi; +RgSchCmnUlCell *cellUl; +#endif +{ + U32 numRe = RGSCH_CEIL((bytes * 8) * 1024, rgSchCmnUlCqiTbl[cqi].eff); + TRC2(rgSCHCmnUlCalcReqRbCeil); + RETVALUE((U8)RGSCH_CEIL(numRe, RG_SCH_CMN_UL_NUM_RE_PER_RB(cellUl))); +} + +/*********************************************************** + * + * Func : rgSCHCmnPrecompMsg3Vars + * + * Desc : Precomputes the following for msg3 allocation: + * 1. numSb and Imcs for msg size A + * 2. numSb and Imcs otherwise + * + * Ret : + * + * Notes: The corresponding vars in cellUl struct is filled + * up + * + * File : + * + **********************************************************/ +#ifdef ANSI +PRIVATE S16 rgSCHCmnPrecompMsg3Vars +( +RgSchCmnUlCell *cellUl, +U8 ccchCqi, +U16 msgSzA, +U8 sbSize, +Bool isEcp +) +#else +PRIVATE S16 rgSCHCmnPrecompMsg3Vars(cellUl, ccchCqi, msgSzA, sbSize, isEcp) +RgSchCmnUlCell *cellUl; +U8 ccchCqi; +U16 msgSzA; +U8 sbSize; +Bool isEcp; +#endif +{ + U8 numSb; + U8 ccchTbs; + U8 ccchMcs; + U8 numRb = 0; + U8 iTbs = 0; + U16 msg3GrntSz = 0; + + TRC2(rgSCHCmnPrecompMsg3Vars); + + if (ccchCqi > cellUl->max16qamCqi) + { + ccchCqi = cellUl->max16qamCqi; + } +/* #ifndef RG_SCH_CMN_EXP_CP_SUP For ECP Pick the index 1 */ + /* Fix */ + ccchTbs = rgSchCmnUlCqiToTbsTbl[(U8)isEcp][ccchCqi]; + ccchMcs = rgSCHCmnUlGetIMcsFrmITbs(ccchTbs, CM_LTE_UE_CAT_1); + + /* MCS should fit in 4 bits in RAR */ + if (ccchMcs >= 15) + { + ccchMcs = 15; + } + + /* Limit the ccchMcs to 15 as it + * can be inferred from 36.213, section 6.2 that msg3 imcs + * field is 4 bits. + * Since, UE doesn't exist right now, we use CAT_1 for ue + * category*/ + while((ccchMcs = (rgSCHCmnUlGetIMcsFrmITbs( + rgSchCmnUlCqiToTbsTbl[(U8)isEcp][ccchCqi],CM_LTE_UE_CAT_1)) + ) > + RG_SCH_CMN_MAX_MSG3_IMCS) + { + ccchCqi--; + } + + iTbs = rgSchCmnUlCqiToTbsTbl[(U8)isEcp][ccchCqi]; + + if (msgSzA < RGSCH_MIN_MSG3_GRNT_SZ) + { + RETVALUE(RFAILED); + } + numSb = RGSCH_CEIL(rgSCHCmnUlCalcReqRbCeil(msgSzA, ccchCqi, cellUl), sbSize); + + numRb = numSb * sbSize; + msg3GrntSz = 8 * msgSzA; + + while( (rgTbSzTbl[0][iTbs][numRb - 1]) < msg3GrntSz) + { + ++numSb; + numRb = numSb * sbSize; + } + while (rgSchCmnMult235Tbl[numSb].match != numSb) + { + ++numSb; + } + /* Reversed(Corrected) the assignment for preamble-GrpA + * Refer- TG36.321- section- 5.1.2*/ + cellUl->ra.prmblBNumSb = numSb; + cellUl->ra.prmblBIMcs = ccchMcs; + numSb = RGSCH_CEIL(rgSCHCmnUlCalcReqRbCeil(RGSCH_MIN_MSG3_GRNT_SZ, \ + ccchCqi, cellUl), + sbSize); + + numRb = numSb * sbSize; + msg3GrntSz = 8 * RGSCH_MIN_MSG3_GRNT_SZ; + while( (rgTbSzTbl[0][iTbs][numRb - 1]) < msg3GrntSz) + { + ++numSb; + numRb = numSb * sbSize; + } + while (rgSchCmnMult235Tbl[numSb].match != numSb) + { + ++numSb; + } + /* Reversed(Corrected) the assignment for preamble-GrpA + * Refer- TG36.321- section- 5.1.2*/ + cellUl->ra.prmblANumSb = numSb; + cellUl->ra.prmblAIMcs = ccchMcs; + RETVALUE(ROK); +} + +PUBLIC U32 gPrntPucchDet=0; + +#ifdef LTE_TDD +/*********************************************************** + * + * Func : rgSCHCmnUlCalcAvailBw + * + * Desc : Calculates bandwidth available for PUSCH scheduling. + * + * Ret : S16 (ROK/RFAILED) + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PRIVATE S16 rgSCHCmnUlCalcAvailBw +( +RgSchCellCb *cell, +RgrCellCfg *cellCfg, +U8 cfi, +U8 *rbStartRef, +U8 *bwAvailRef +) +#else +PRIVATE S16 rgSCHCmnUlCalcAvailBw(cell, cellCfg, cfi, rbStartRef, bwAvailRef) +RgSchCellCb *cell; +RgrCellCfg *cellCfg; +U8 cfi; +U8 *rbStartRef; +U8 *bwAvailRef; +#endif +{ + U8 c = 3; + U8 ulBw = cell->bwCfg.ulTotalBw; + U8 n2Rb = cell->pucchCfg.resourceSize; + U8 pucchDeltaShft = cell->pucchCfg.deltaShift; + U16 n1Pucch = cell->pucchCfg.n1PucchAn; + U8 n1Cs = cell->pucchCfg.cyclicShift; + + U8 n1PerRb; + U8 totalCce; + U16 n1Max; + U8 n1Rb; + U32 mixedRb; + U8 exclRb; /* RBs to exclude */ + U8 n1RbPart; + U8 puschRbStart; + /* To avoid PUCCH and PUSCH collision issue */ + U8 P; + U8 n1PlusOne; + U8 mi; + /* Maximum value of M as per Table 10.1-1 */ + U8 M[RGSCH_MAX_TDD_UL_DL_CFG] = {1, 2, 4, 3, 4, 9, 1}; + + TRC2(rgSCHCmnUlCalcAvailBw); + + if (cell->isCpUlExtend) + { + c = 2; + } + + n1PerRb = c * 12 / pucchDeltaShft; /* 12/18/36 */ + + /* Considering the max no. of CCEs for PUSCH BW calculation + * based on min mi value */ + if (cell->ulDlCfgIdx == 0 || cell->ulDlCfgIdx == 6) + { + mi = 1; + } + else + { + mi = 0; + } + + totalCce = cell->dynCfiCb.cfi2NCceTbl[mi][cfi]; + + P = rgSCHCmnGetPValFrmCCE(cell, totalCce-1); + n1PlusOne = cell->rgSchTddNpValTbl[P + 1]; + n1Max = (M[cell->ulDlCfgIdx] - 1)*n1PlusOne + (totalCce-1) + n1Pucch; + + /* ccpu00129978- MOD- excluding RBs based on formula in section 5.4.3 in + * TS 36.211 */ + n1RbPart = (c*n1Cs)/pucchDeltaShft; + n1Rb = (n1Max - n1RbPart)/ n1PerRb; + mixedRb = RGSCH_CEIL(n1Cs, 8); /* same as 'mixedRb = n1Cs ? 1 : 0' */ + + /* get the total Number of RB's to be excluded for PUSCH */ + /* ccpu00137339 */ + if(n1Pucch < n1RbPart) + { + exclRb = n2Rb; + } + else + { + exclRb = n2Rb + mixedRb + n1Rb; /* RBs to exclude */ + } + puschRbStart = exclRb/2 + 1; + + /* Num of PUCCH RBs = puschRbStart*2 */ + if (puschRbStart * 2 >= ulBw) + { + RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,"No bw available for PUSCH"); + RETVALUE(RFAILED); + } + + *rbStartRef = puschRbStart; + *bwAvailRef = ulBw - puschRbStart * 2; + + if(cell->pucchCfg.maxPucchRb !=0 && + (puschRbStart * 2 > cell->pucchCfg.maxPucchRb)) + { + cell->dynCfiCb.maxCfi = RGSCH_MIN(cfi-1, cell->dynCfiCb.maxCfi); + } + + RETVALUE(ROK); +} +#else + +/*********************************************************** + * + * Func : rgSCHCmnUlCalcAvailBw + * + * Desc : Calculates bandwidth available for PUSCH scheduling. + * + * Ret : S16 (ROK/RFAILED) + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PRIVATE S16 rgSCHCmnUlCalcAvailBw +( +RgSchCellCb *cell, +RgrCellCfg *cellCfg, +U8 cfi, +U8 *rbStartRef, +U8 *bwAvailRef +) +#else +PRIVATE S16 rgSCHCmnUlCalcAvailBw(cell, cellCfg, cfi, rbStartRef, bwAvailRef) +RgSchCellCb *cell; +RgrCellCfg *cellCfg; +U8 cfi; +U8 *rbStartRef; +U8 *bwAvailRef; +#endif +{ + U8 c = 3; + U8 ulBw = cell->bwCfg.ulTotalBw; + U8 n2Rb = cell->pucchCfg.resourceSize; + U8 pucchDeltaShft = cell->pucchCfg.deltaShift; + U16 n1Pucch = cell->pucchCfg.n1PucchAn; + U8 n1Cs = cell->pucchCfg.cyclicShift; + U8 n1PerRb; + U8 totalCce; + U16 n1Max; + U8 n1Rb; + U32 mixedRb; + U8 exclRb; /* RBs to exclude */ + U8 n1RbPart; + U8 puschRbStart; +#ifdef LTE_ADV + U16 numOfN3PucchRb; + RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell); +#endif + + TRC2(rgSCHCmnUlCalcAvailBw); + + if (cell->isCpUlExtend) + { + c = 2; + } + + n1PerRb = c * 12 / pucchDeltaShft; /* 12/18/36 */ + + totalCce = cell->dynCfiCb.cfi2NCceTbl[0][cfi]; + + n1Max = n1Pucch + totalCce-1; + + /* ccpu00129978- MOD- excluding RBs based on formula in section 5.4.3 in + * TS 36.211 */ + n1RbPart = (c*n1Cs)/pucchDeltaShft; + n1Rb = (U8)((n1Max - n1RbPart) / n1PerRb); + mixedRb = RGSCH_CEIL(n1Cs, 8); /* same as 'mixedRb = n1Cs ? 1 : 0' */ + + /* get the total Number of RB's to be excluded for PUSCH */ + /* ccpu00137339 */ + if(n1Pucch < n1RbPart) + { + exclRb = n2Rb; + } + else + { + exclRb = n2Rb + mixedRb + n1Rb; /* RBs to exclude */ + } + /*Support for PUCCH Format 3*/ +#ifdef LTE_ADV + if (cell->isPucchFormat3Sptd) + { + numOfN3PucchRb = RGSCH_CEIL(cellSch->dl.maxUePerDlSf,5); + exclRb = exclRb + numOfN3PucchRb; + } +#endif + puschRbStart = exclRb/2 + 1; + + if(gPrntPucchDet) + { +#ifndef ALIGN_64BIT + printf("CA_DBG:: puschRbStart:n1Rb:mixedRb:n1PerRb:totalCce:n1Max:n1RbPart:n2Rb::[%d:%d] [%d:%d:%ld:%d:%d:%d:%d:%d]\n", + cell->crntTime.sfn, cell->crntTime.subframe, puschRbStart, n1Rb, mixedRb,n1PerRb, totalCce, n1Max, n1RbPart, n2Rb); +#else + printf("CA_DBG:: puschRbStart:n1Rb:mixedRb:n1PerRb:totalCce:n1Max:n1RbPart:n2Rb::[%d:%d] [%d:%d:%d:%d:%d:%d:%d:%d]\n", + cell->crntTime.sfn, cell->crntTime.subframe, puschRbStart, n1Rb, mixedRb,n1PerRb, totalCce, n1Max, n1RbPart, n2Rb); +#endif + } + + if (puschRbStart*2 >= ulBw) + { + RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,"No bw available for PUSCH"); + RETVALUE(RFAILED); + } + + *rbStartRef = puschRbStart; + *bwAvailRef = ulBw - puschRbStart * 2; + + if(cell->pucchCfg.maxPucchRb !=0 && + (puschRbStart * 2 > cell->pucchCfg.maxPucchRb)) + { + cell->dynCfiCb.maxCfi = RGSCH_MIN(cfi-1, cell->dynCfiCb.maxCfi); + } + + RETVALUE(ROK); +} +#endif + + + +/*********************************************************** + * + * Func : rgSCHCmnUlCellInit + * + * Desc : Uplink scheduler initialisation for cell. + * + * Ret : S16 + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PRIVATE S16 rgSCHCmnUlCellInit +( + RgSchCellCb *cell, + RgrCellCfg *cellCfg + ) +#else +PRIVATE S16 rgSCHCmnUlCellInit(cell, cellCfg) + RgSchCellCb *cell; + RgrCellCfg *cellCfg; +#endif +{ + S16 ret; + RgSchCmnUlCell *cellUl = RG_SCH_CMN_GET_UL_CELL(cell); + U8 maxUePerUlSf = cellCfg->maxUePerUlSf; +#ifdef RGR_V1 + /* Added configuration for maximum number of MSG3s */ + U8 maxMsg3PerUlSf = cellCfg->maxMsg3PerUlSf; +#endif + U8 maxUlBwPerUe = cellCfg->maxUlBwPerUe; + U8 sbSize = cellCfg->puschSubBand.size; + U8 i; + U8 rbStart; + U8 bwAvail; + U8 cfi; + U8 maxSbPerUe; + U8 numSb; +#ifdef LTE_TDD + U16 ulDlCfgIdx = cell->ulDlCfgIdx; + /* [ccpu00127294]-MOD-Change the max Ul subfrms size in TDD */ + U8 maxSubfrms = 2 * rgSchTddNumUlSf[ulDlCfgIdx]; + U8 ulToDlMap[12] = {0}; /* maximum 6 Subframes in UL * 2 */ + U8 maxUlsubfrms = rgSchTddNumUlSubfrmTbl[ulDlCfgIdx]\ + [RGSCH_NUM_SUB_FRAMES-1]; + U16 subfrm; + S8 dlIdx; +#else + U8 maxSubfrms = RG_SCH_CMN_UL_NUM_SF; +#endif +#ifdef LTE_L2_MEAS + U8 idx; +#endif + U8 iTbs; +#if (defined(LTE_L2_MEAS) ) + Inst inst = cell->instIdx; +#endif /* #if (defined(LTE_L2_MEAS) || defined(DEBUGP) */ + RgSchCmnCell *cellSch = (RgSchCmnCell *)(cell->sc.sch); + + TRC2(rgSCHCmnUlCellInit); + + cellUl->maxUeNewTxPerTti = cellCfg->maxUlUeNewTxPerTti; + if (maxUePerUlSf == 0) + { + maxUePerUlSf = RG_SCH_CMN_MAX_UE_PER_UL_SF; + } +#ifdef RGR_V1 + if (maxMsg3PerUlSf == 0) + { + maxMsg3PerUlSf = RG_SCH_CMN_MAX_MSG3_PER_UL_SF; + } + /* fixed the problem while sending raRsp + * if maxMsg3PerUlSf is greater than + * RGSCH_MAX_RNTI_PER_RARNTI + * */ + if(maxMsg3PerUlSf > RGSCH_MAX_RNTI_PER_RARNTI) + { + maxMsg3PerUlSf = RGSCH_MAX_RNTI_PER_RARNTI; + } + + if(maxMsg3PerUlSf > maxUePerUlSf) + { + maxMsg3PerUlSf = maxUePerUlSf; + } + + /*cellUl->maxAllocPerUlSf = maxUePerUlSf + maxMsg3PerUlSf;*/ + /*Max MSG3 should be a subset of Max UEs*/ + cellUl->maxAllocPerUlSf = maxUePerUlSf; + cellUl->maxMsg3PerUlSf = maxMsg3PerUlSf; +#else + cellUl->maxAllocPerUlSf = maxUePerUlSf; +#endif + /* Fix: MUE_PERTTI_UL syed validating Cell Configuration */ + if (cellUl->maxAllocPerUlSf < cellUl->maxUeNewTxPerTti) + { + RLOG_ARG2(L_ERROR,DBG_CELLID,cell->cellId, + "FAILED: MaxUePerUlSf(%u) < MaxUlUeNewTxPerTti(%u)", + cellUl->maxAllocPerUlSf, + cellUl->maxUeNewTxPerTti); + RETVALUE(RFAILED); + } + +#ifdef LTE_L2_MEAS +#ifdef LTE_TDD + for(idx = 0; idx < RGSCH_SF_ALLOC_SIZE; idx++) +#else + for(idx = 0; idx < RGSCH_NUM_SUB_FRAMES; idx++) +#endif + { + + ret = rgSCHUtlAllocSBuf(inst, (Data **)&(cell->sfAllocArr[idx]. + ulUeInfo.ulAllocInfo), (cellUl->maxAllocPerUlSf * sizeof(RgInfUeUlAlloc))); + if (ret != ROK) + { + RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,"Memory allocation failed "); + RETVALUE(ret); + } + } +#endif + if (maxUlBwPerUe == 0) + { + /* ccpu00139362- Setting to configured UL BW instead of MAX BW(100)*/ + maxUlBwPerUe = cell->bwCfg.ulTotalBw; + } + cellUl->maxUlBwPerUe = maxUlBwPerUe; + + /* FOR RG_SCH_CMN_EXT_CP_SUP */ + if (!cellCfg->isCpUlExtend) + { + cellUl->ulNumRePerRb = 12 * (14 - RGSCH_UL_SYM_DMRS_SRS); + } + else + { + cellUl->ulNumRePerRb = 12 * (12 - RGSCH_UL_SYM_DMRS_SRS); + } + + if (sbSize != rgSchCmnMult235Tbl[sbSize].match) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,"Invalid subband size %d", sbSize); + RETVALUE(RFAILED); + } + //Setting the subband size to 4 which is size of VRBG in 5GTF +#ifdef RG_5GTF + sbSize = MAX_5GTF_VRBG_SIZE; +#endif + + maxSbPerUe = maxUlBwPerUe / sbSize; + if (maxSbPerUe == 0) + { + RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId, "rgSCHCmnUlCellInit(): " + "maxUlBwPerUe/sbSize is zero"); + RETVALUE(RFAILED); + } + cellUl->maxSbPerUe = rgSchCmnMult235Tbl[maxSbPerUe].prvMatch; + + /* CQI related updations */ + if ((!RG_SCH_CMN_UL_IS_CQI_VALID(cellCfg->ulCmnCodeRate.ccchCqi)) + || (!RG_SCH_CMN_UL_IS_CQI_VALID(cellCfg->trgUlCqi.trgCqi))) + { + RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,"rgSCHCmnUlCellInit(): " + "Invalid cqi"); + RETVALUE(RFAILED); + } + cellUl->dfltUlCqi = cellCfg->ulCmnCodeRate.ccchCqi; + + /* Changed the logic to determine maxUlCqi. + * For a 16qam UE, maxUlCqi is the CQI Index at which + * efficiency is as close as possible to RG_SCH_MAX_CODE_RATE_16QAM + * Refer to 36.213-8.6.1 */ + for (i = RG_SCH_CMN_UL_NUM_CQI - 1;i > 0; --i) + { + RLOG_ARG2(L_INFO,DBG_CELLID,cell->cellId, + "CQI %u:iTbs %u", + i, + rgSchCmnUlCqiToTbsTbl[cell->isCpUlExtend][i]); +#ifdef MAC_SCH_STATS + /* ccpu00128489 ADD Update mcs in hqFailStats here instead of at CRC + * since CQI to MCS mapping does not change. The only exception is for + * ITBS = 19 where the MCS can be 20 or 21 based on the UE cat. We + * choose 20, instead of 21, ie UE_CAT_3 */ + iTbs = rgSchCmnUlCqiToTbsTbl[cell->isCpUlExtend][i]; + RG_SCH_CMN_UL_TBS_TO_MCS(iTbs, hqFailStats.ulCqiStat[i - 1].mcs); +#endif + } + for (i = RG_SCH_CMN_UL_NUM_CQI - 1; i != 0; --i) + { + /* Fix for ccpu00123912*/ + iTbs = rgSchCmnUlCqiToTbsTbl[cell->isCpUlExtend][i]; + if (iTbs <= RGSCH_UL_16QAM_MAX_ITBS) /* corresponds to 16QAM */ + { + RLOG_ARG1(L_INFO,DBG_CELLID,cell->cellId, + "16 QAM CQI %u", i); + cellUl->max16qamCqi = i; + break; + } + } + +#ifdef EMTC_ENABLE + /* Precompute useful values for RA msg3 */ + ret = rgSCHCmnPrecompEmtcMsg3Vars(cellUl, cellCfg->ulCmnCodeRate.ccchCqi, + cell->rachCfg.msgSizeGrpA, sbSize, cell->isCpUlExtend); + if (ret != ROK) + { + RETVALUE(ret); + } +#endif + + /* Precompute useful values for RA msg3 */ + ret = rgSCHCmnPrecompMsg3Vars(cellUl, cellCfg->ulCmnCodeRate.ccchCqi, + cell->rachCfg.msgSizeGrpA, sbSize, cell->isCpUlExtend); + if (ret != ROK) + { + RETVALUE(ret); + } + + cellUl->sbSize = sbSize; + +#ifdef LTE_TDD + cellUl->numUlSubfrms = maxSubfrms; + + ret = rgSCHUtlAllocSBuf(cell->instIdx, (Data **)&cellUl->ulSfArr, + cellUl->numUlSubfrms * sizeof(RgSchUlSf)); + + if (ret != ROK) + { + cellUl->numUlSubfrms = 0; + RETVALUE(ret); + } + + /* store the DL subframe corresponding to the PUSCH offset + * in their respective UL subframe */ + for(i=0; i < RGSCH_NUM_SUB_FRAMES; i++) + { + if(rgSchTddPuschTxKTbl[ulDlCfgIdx][i] != 0) + { + subfrm = (i + rgSchTddPuschTxKTbl[ulDlCfgIdx][i]) % \ + RGSCH_NUM_SUB_FRAMES; + subfrm = rgSchTddNumUlSubfrmTbl[ulDlCfgIdx][subfrm]-1; + dlIdx = rgSchTddNumDlSubfrmTbl[ulDlCfgIdx][i]-1; + RGSCH_ARRAY_BOUND_CHECK( cell->instIdx, ulToDlMap, subfrm); + ulToDlMap[subfrm] = dlIdx; + } + } + /* Copy the information in the remaining UL subframes based + * on number of HARQ processes */ + for(i=maxUlsubfrms; i < maxSubfrms; i++) + { + subfrm = i-maxUlsubfrms; + RGSCH_ARRAY_BOUND_CHECK(cell->instIdx, ulToDlMap, i); + RGSCH_ARRAY_BOUND_CHECK(cell->instIdx, ulToDlMap, subfrm) + ulToDlMap[i] = ulToDlMap[subfrm]; + } +#endif + + for (cfi = 1; cfi < RG_SCH_CMN_MAX_CFI; cfi++) + { +#ifdef LTE_TDD + ret = rgSCHCmnUlCalcAvailBw(cell, cellCfg, cfi, &rbStart, &bwAvail); +#else + ret = rgSCHCmnUlCalcAvailBw(cell, cellCfg, cfi, &rbStart, &bwAvail); +#endif + if (ret != ROK) + { + RETVALUE(ret); + } + + if (cfi == 1) + { + cell->ulAvailBw = bwAvail; + } + + numSb = bwAvail/sbSize; + + cell->dynCfiCb.bwInfo[cfi].startRb = rbStart; + cell->dynCfiCb.bwInfo[cfi].numSb = numSb; + } + + if(0 == cell->dynCfiCb.maxCfi) + { + RLOG_ARG3(L_ERROR,DBG_CELLID,cell->cellId, + "Incorrect Default CFI(%u), maxCfi(%u), maxPucchRb(%d)", + cellSch->cfiCfg.cfi, cell->dynCfiCb.maxCfi, + cell->pucchCfg.maxPucchRb); + + RETVALUE(RFAILED); + } + + /* DMRS values */ + cellUl->dmrsArrSize = cell->dynCfiCb.bwInfo[1].numSb; + ret = rgSCHUtlAllocSBuf(cell->instIdx, (Data **)&cellUl->dmrsArr, + cellUl->dmrsArrSize * sizeof(*cellUl->dmrsArr)); + if (ret != ROK) + { + RETVALUE(ret); + } + for (i = 0; i < cellUl->dmrsArrSize; ++i) + { + cellUl->dmrsArr[i] = cellCfg->puschSubBand.dmrs[i]; + } + + /* Init subframes */ + for (i = 0; i < maxSubfrms; ++i) + { + ret = rgSCHUtlUlSfInit(cell, &cellUl->ulSfArr[i], i, + cellUl->maxAllocPerUlSf); + if (ret != ROK) + { + for (; i != 0; --i) + { + rgSCHUtlUlSfDeinit(cell, &cellUl->ulSfArr[i-1]); + } + /* ccpu00117052 - MOD - Passing double pointer + for proper NULLP assignment*/ + rgSCHUtlFreeSBuf(cell->instIdx, (Data **)(&(cellUl->dmrsArr)), + cellUl->dmrsArrSize * sizeof(*cellUl->dmrsArr)); +#ifdef LTE_TDD + /* ccpu00117052 - MOD - Passing double pointer + for proper NULLP assignment*/ + rgSCHUtlFreeSBuf(cell->instIdx, + (Data **)(&(cellUl->ulSfArr)), maxSubfrms * sizeof(RgSchUlSf)); +#endif + RETVALUE(ret); + } + } + RG_SCH_RESET_HCSG_UL_PRB_CNTR(cellUl); + RETVALUE(ROK); +} + +/** + * @brief Scheduler processing on cell configuration. + * + * @details + * + * Function : rgSCHCmnRgrCellCfg + * + * This function does requisite initialisation + * and setup for scheduler1 when a cell is + * configured. + * + * @param[in] RgSchCellCb *cell + * @param[in] RgrCellCfg *cellCfg + * @param[out] RgSchErrInfo *err + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 rgSCHCmnRgrCellCfg +( +RgSchCellCb *cell, +RgrCellCfg *cellCfg, +RgSchErrInfo *err +) +#else +PUBLIC S16 rgSCHCmnRgrCellCfg(cell, cellCfg, err) +RgSchCellCb *cell; +RgrCellCfg *cellCfg; +RgSchErrInfo *err; +#endif +{ + S16 ret; + RgSchCmnCell *cellSch; + TRC2(rgSCHCmnRgrCellCfg); + + /* As part of RGR cell configuration, validate the CRGCellCfg + * There is no trigger for crgCellCfg from SC1 */ + /* Removed failure check for Extended CP */ + + if (((ret = rgSCHUtlAllocSBuf(cell->instIdx, + (Data**)&(cell->sc.sch), (sizeof(RgSchCmnCell)))) != ROK)) + { + RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId, + "Memory allocation FAILED"); + err->errCause = RGSCHERR_SCH_CFG; + RETVALUE(ret); + } + cellSch = (RgSchCmnCell *)(cell->sc.sch); + cellSch->cfiCfg = cellCfg->cfiCfg; + cellSch->trgUlCqi.trgCqi = cellCfg->trgUlCqi.trgCqi; + /* Initialize the scheduler refresh timer queues */ + cellSch->tmrTqCp.nxtEnt = 0; + cellSch->tmrTqCp.tmrLen = RG_SCH_CMN_NUM_REFRESH_Q; + + /* RACHO Intialize the RACH ded Preamble Information */ + rgSCHCmnCfgRachDedPrm(cell); +#ifdef LTE_TDD + /* Initialize 'Np' value for each 'p' used for + * HARQ ACK/NACK reception */ + rgSCHCmnDlNpValInit(cell); +#endif + + /* Initialize 'Np' value for each 'p' used for + * HARQ ACK/NACK reception */ +#ifdef LTE_TDD + rgSCHCmnDlNpValInit(cell); +#endif + + /* Now perform uplink related initializations */ + ret = rgSCHCmnUlCellInit(cell, cellCfg); + if (ret != ROK) + { + /* There is no downlink deinit to be performed */ + err->errCause = RGSCHERR_SCH_CFG; + RETVALUE(ret); + } + ret = rgSCHCmnDlRgrCellCfg(cell, cellCfg, err); + if (ret != ROK) + { + err->errCause = RGSCHERR_SCH_CFG; + RETVALUE(ret); + } + /* DL scheduler has no initializations to make */ + /* As of now DL scheduler always returns ROK */ + + rgSCHCmnGetDciFrmtSizes(cell); + rgSCHCmnGetCqiDciFrmt2AggrLvl(cell); +#ifdef EMTC_ENABLE + rgSCHCmnGetEmtcDciFrmtSizes(cell); + rgSCHCmnGetCqiEmtcDciFrmt2AggrLvl(cell); +#endif /* EMTC_ENABLE */ + +#ifdef EMTC_ENABLE + if(TRUE == cellCfg->emtcEnable) + { + cellSch->apisEmtcUl = &rgSchEmtcUlSchdTbl[0]; + ret = cellSch->apisEmtcUl->rgSCHRgrUlCellCfg(cell, cellCfg, err); + if (ret != ROK) + { + RETVALUE(ret); + } + } +#endif + cellSch->apisUl = &rgSchUlSchdTbl[RG_SCH_CMN_GET_UL_SCHED_TYPE(cell)]; + ret = cellSch->apisUl->rgSCHRgrUlCellCfg(cell, cellCfg, err); + if (ret != ROK) + { + RETVALUE(ret); + } +#ifdef EMTC_ENABLE + if(TRUE == cellCfg->emtcEnable) + { + cellSch->apisEmtcDl = &rgSchEmtcDlSchdTbl[0]; + ret = cellSch->apisEmtcDl->rgSCHRgrDlCellCfg(cell, cellCfg, err); + if (ret != ROK) + { + RETVALUE(ret); + } + } +#endif + cellSch->apisDl = &rgSchDlSchdTbl[RG_SCH_CMN_GET_DL_SCHED_TYPE(cell)]; +#ifdef LTEMAC_SPS + /* Perform SPS specific initialization for the cell */ + ret = rgSCHCmnSpsCellCfg(cell, cellCfg, err); + if (ret != ROK) + { + RETVALUE(ret); + } +#endif + ret = cellSch->apisDl->rgSCHRgrDlCellCfg(cell, cellCfg, err); + if (ret != ROK) + { + RETVALUE(ret); + } + rgSCHCmnInitVars(cell); + + RETVALUE(ROK); +} /* rgSCHCmnRgrCellCfg*/ + + +/** + * @brief This function handles the reconfiguration of cell. + * + * @details + * + * Function: rgSCHCmnRgrCellRecfg + * Purpose: Update the reconfiguration parameters. + * + * Invoked by: Scheduler + * + * @param[in] RgSchCellCb* cell + * @return Void + * + **/ +#ifdef ANSI +PUBLIC S16 rgSCHCmnRgrCellRecfg +( +RgSchCellCb *cell, +RgrCellRecfg *recfg, +RgSchErrInfo *err +) +#else +PUBLIC S16 rgSCHCmnRgrCellRecfg(cell, recfg, err) +RgSchCellCb *cell; +RgrCellRecfg *recfg; +RgSchErrInfo *err; +#endif +{ + S16 ret; + RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell); + RgSchCmnUlCell *cellUl = RG_SCH_CMN_GET_UL_CELL(cell); + + TRC2(rgSCHCmnRgrCellRecfg); + + if (recfg->recfgTypes & RGR_CELL_UL_CMNRATE_RECFG) + { + U8 oldCqi = cellUl->dfltUlCqi; + if (!RG_SCH_CMN_UL_IS_CQI_VALID(recfg->ulCmnCodeRate.ccchCqi)) + { + err->errCause = RGSCHERR_SCH_CFG; + RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId, "rgSCHCmnRgrCellRecfg(): " + "Invalid cqi"); + RETVALUE(RFAILED); + } + cellUl->dfltUlCqi = recfg->ulCmnCodeRate.ccchCqi; + ret = rgSCHCmnPrecompMsg3Vars(cellUl, recfg->ulCmnCodeRate.ccchCqi, + cell->rachCfg.msgSizeGrpA, cellUl->sbSize, cell->isCpUlExtend); + if (ret != ROK) + { + cellUl->dfltUlCqi = oldCqi; + rgSCHCmnPrecompMsg3Vars(cellUl, recfg->ulCmnCodeRate.ccchCqi, + cell->rachCfg.msgSizeGrpA, cellUl->sbSize, cell->isCpUlExtend); + RETVALUE(ret); + } + } + + if (recfg->recfgTypes & RGR_CELL_DL_CMNRATE_RECFG) + { + if (rgSCHCmnDlCnsdrCmnRt(cell, &recfg->dlCmnCodeRate) != ROK) + { + err->errCause = RGSCHERR_SCH_CFG; + RETVALUE(RFAILED); + } + } + +#ifdef EMTC_ENABLE + if(TRUE == cell->emtcEnable) + { + /* Invoke UL sched for cell Recfg */ + ret = cellSch->apisEmtcUl->rgSCHRgrUlCellRecfg(cell, recfg, err); + if (ret != ROK) + { + RETVALUE(RFAILED); + } + + /* Invoke DL sched for cell Recfg */ + ret = cellSch->apisEmtcDl->rgSCHRgrDlCellRecfg(cell, recfg, err); + if (ret != ROK) + { + RETVALUE(RFAILED); + } + } + else +#endif + { + /* Invoke UL sched for cell Recfg */ + ret = cellSch->apisUl->rgSCHRgrUlCellRecfg(cell, recfg, err); + if (ret != ROK) + { + RETVALUE(RFAILED); + } + + /* Invoke DL sched for cell Recfg */ + ret = cellSch->apisDl->rgSCHRgrDlCellRecfg(cell, recfg, err); + if (ret != ROK) + { + RETVALUE(RFAILED); + } + } + + if (recfg->recfgTypes & RGR_CELL_DLFS_RECFG) + { + ret = cellSch->apisDlfs->rgSCHDlfsCellRecfg(cell, recfg, err); + if (ret != ROK) + { + RETVALUE(RFAILED); + } + cellSch->dl.isDlFreqSel = recfg->dlfsRecfg.isDlFreqSel; + } + + if (recfg->recfgTypes & RGR_CELL_PWR_RECFG) + { + ret = rgSCHPwrCellRecfg(cell, recfg); + if (ret != ROK) + { + RETVALUE(RFAILED); + } + } + + RETVALUE(ROK); +} + +/*********************************************************** + * + * Func : rgSCHCmnUlCellDeinit + * + * Desc : Uplink scheduler de-initialisation for cell. + * + * Ret : S16 + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PRIVATE Void rgSCHCmnUlCellDeinit +( +RgSchCellCb *cell +) +#else +PRIVATE Void rgSCHCmnUlCellDeinit(cell) +RgSchCellCb *cell; +#endif +{ + RgSchCmnUlCell *cellUl = RG_SCH_CMN_GET_UL_CELL(cell); + U8 ulSfIdx; +#ifdef LTE_TDD + U8 maxSubfrms = cellUl->numUlSubfrms; +#endif +#ifdef LTE_L2_MEAS + CmLList *lnk = NULLP; + RgSchL2MeasCb *measCb; +#endif + TRC2(rgSCHCmnUlCellDeinit); +#ifdef LTE_L2_MEAS +#ifdef LTE_TDD + for(ulSfIdx = 0; ulSfIdx < RGSCH_SF_ALLOC_SIZE; ulSfIdx++) +#else + for(ulSfIdx = 0; ulSfIdx < RGSCH_NUM_SUB_FRAMES; ulSfIdx++) +#endif + { + if(cell->sfAllocArr[ulSfIdx].ulUeInfo.ulAllocInfo != NULLP) + { + /* ccpu00117052 - MOD - Passing double pointer + for proper NULLP assignment*/ + rgSCHUtlFreeSBuf(cell->instIdx, + (Data **)(&(cell->sfAllocArr[ulSfIdx].ulUeInfo.ulAllocInfo)), + cellUl->maxAllocPerUlSf * sizeof(RgInfUeUlAlloc)); + + /* ccpu00117052 - DEL - removed explicit NULLP assignment + as it is done in above utility function */ + } + } + /* Free the memory allocated to measCb */ + lnk = cell->l2mList.first; + while(lnk != NULLP) + { + measCb = (RgSchL2MeasCb *)lnk->node; + cmLListDelFrm(&cell->l2mList, lnk); + lnk = lnk->next; + /* ccpu00117052 - MOD - Passing double pointer + for proper NULLP assignment*/ + rgSCHUtlFreeSBuf(cell->instIdx, (Data **)&measCb,\ + sizeof(RgSchL2MeasCb)); + } +#endif + if (cellUl->dmrsArr != NULLP) + { + /* ccpu00117052 - MOD - Passing double pointer + for proper NULLP assignment*/ + rgSCHUtlFreeSBuf(cell->instIdx,(Data **)(&(cellUl->dmrsArr)), + cellUl->dmrsArrSize * sizeof(*cellUl->dmrsArr)); + } + /* De-init subframes */ +#ifdef LTE_TDD + for (ulSfIdx = 0; ulSfIdx < maxSubfrms; ++ulSfIdx) +#else + for (ulSfIdx = 0; ulSfIdx < RG_SCH_CMN_UL_NUM_SF; ++ulSfIdx) +#endif + { + rgSCHUtlUlSfDeinit(cell, &cellUl->ulSfArr[ulSfIdx]); + } + +#ifdef LTE_TDD + if (cellUl->ulSfArr != NULLP) + { + /* ccpu00117052 - MOD - Passing double pointer + for proper NULLP assignment*/ + rgSCHUtlFreeSBuf(cell->instIdx, + (Data **)(&(cellUl->ulSfArr)), maxSubfrms * sizeof(RgSchUlSf)); + } +#endif + + RETVOID; +} + +/** + * @brief Scheduler processing for cell delete. + * + * @details + * + * Function : rgSCHCmnCellDel + * + * This functions de-initialises and frees memory + * taken up by scheduler1 for the entire cell. + * + * @param[in] RgSchCellCb *cell + * @return Void + **/ +#ifdef ANSI +PUBLIC Void rgSCHCmnCellDel +( +RgSchCellCb *cell +) +#else +PUBLIC Void rgSCHCmnCellDel(cell) +RgSchCellCb *cell; +#endif +{ + RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell); + TRC2(rgSCHCmnCellDel); + +#ifdef LTE_L2_MEAS + glblTtiCnt = 0; +#endif + if (cellSch == NULLP) + { + RETVOID; + } + /* Perform the deinit for the UL scheduler */ + rgSCHCmnUlCellDeinit(cell); +#ifdef EMTC_ENABLE + if(TRUE == cell->emtcEnable) + { + if (cellSch->apisEmtcUl) + { + cellSch->apisEmtcUl->rgSCHFreeUlCell(cell); + } + } +#endif + if (cellSch->apisUl) + { + /* api pointer checks added (here and below in + * this function). pl check. - antriksh */ + cellSch->apisUl->rgSCHFreeUlCell(cell); + } + + /* Perform the deinit for the DL scheduler */ + cmLListInit(&cellSch->dl.taLst); + if (cellSch->apisDl) + { + cellSch->apisDl->rgSCHFreeDlCell(cell); + } +#ifdef EMTC_ENABLE + if (cellSch->apisEmtcDl) + { + rgSCHEmtcInitTaLst(&cellSch->dl); + + cellSch->apisEmtcDl->rgSCHFreeDlCell(cell); + } +#endif + + /* DLFS de-initialization */ + if (cellSch->dl.isDlFreqSel && cellSch->apisDlfs) + { + cellSch->apisDlfs->rgSCHDlfsCellDel(cell); + } + + rgSCHPwrCellDel(cell); +#ifdef LTEMAC_SPS + rgSCHCmnSpsCellDel(cell); +#endif + + /* ccpu00117052 - MOD - Passing double pointer + for proper NULLP assignment*/ + rgSCHUtlFreeSBuf(cell->instIdx, + (Data**)(&(cell->sc.sch)), (sizeof(RgSchCmnCell))); + RETVOID; +} /* rgSCHCmnCellDel */ + + +/** + * @brief This function validates QOS parameters for DL. + * + * @details + * + * Function: rgSCHCmnValidateDlQos + * Purpose: This function validates QOS parameters for DL. + * + * Invoked by: Scheduler + * + * @param[in] CrgLchQosCfg *dlQos + * @return S16 + * + **/ +#ifdef ANSI +PRIVATE S16 rgSCHCmnValidateDlQos +( +RgrLchQosCfg *dlQos +) +#else +PRIVATE S16 rgSCHCmnValidateDlQos(dlQos) +RgrLchQosCfg *dlQos; +#endif +{ + U8 qci = dlQos->qci; + + TRC2(rgSCHCmnValidateDlQos); + + if ( qci < RG_SCH_CMN_MIN_QCI || qci > RG_SCH_CMN_MAX_QCI ) + { + RETVALUE(RFAILED); + } + + if ((qci >= RG_SCH_CMN_GBR_QCI_START) && + (qci <= RG_SCH_CMN_GBR_QCI_END)) + { + if ((dlQos->mbr == 0) || (dlQos->mbr < dlQos->gbr)) + { + RETVALUE(RFAILED); + } + } + RETVALUE(ROK); +} + +/** + * @brief Scheduler invocation on logical channel addition. + * + * @details + * + * Function : rgSCHCmnRgrLchCfg + * + * This functions does required processing when a new + * (dedicated) logical channel is added. Assumes lcg + * pointer in ulLc is set. + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ue + * @param[in] RgSchDlLcCb *dlLc + * @param[int] RgrLchCfg *lcCfg + * @param[out] RgSchErrInfo *err + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 rgSCHCmnRgrLchCfg +( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgSchDlLcCb *dlLc, +RgrLchCfg *lcCfg, +RgSchErrInfo *err +) +#else +PUBLIC S16 rgSCHCmnRgrLchCfg(cell, ue, dlLc, lcCfg, err) +RgSchCellCb *cell; +RgSchUeCb *ue; +RgSchDlLcCb *dlLc; +RgrLchCfg *lcCfg; +RgSchErrInfo *err; +#endif +{ + S16 ret; + + RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell); + + TRC2(rgSCHCmnRgrLchCfg); + + ret = rgSCHUtlAllocSBuf(cell->instIdx, + (Data**)&((dlLc)->sch), (sizeof(RgSchCmnDlSvc))); + if (ret != ROK) + { + RLOG_ARG2(L_ERROR,DBG_CELLID,cell->cellId,"rgSCHCmnRgrLchCfg(): " + "SCH struct alloc failed for CRNTI:%d LCID:%d",ue->ueId,lcCfg->lcId); + err->errCause = RGSCHERR_SCH_CFG; + RETVALUE(ret); + } + if(lcCfg->lcType != CM_LTE_LCH_DCCH) + { + ret = rgSCHCmnValidateDlQos(&lcCfg->dlInfo.dlQos); + if (ret != ROK) + { + RLOG_ARG2(L_ERROR,DBG_CELLID,cell->cellId,"rgSchCmnCrgLcCfg(): " + "DlQos validation failed for CRNTI:%d LCID:%d",ue->ueId,lcCfg->lcId); + err->errCause = RGSCHERR_SCH_CFG; + RETVALUE(ret); + } + /* Perform DL service activation in the scheduler */ + ((RgSchCmnDlSvc *)(dlLc->sch))->qci = lcCfg->dlInfo.dlQos.qci; + ((RgSchCmnDlSvc *)(dlLc->sch))->prio = rgSchCmnDlQciPrio[lcCfg->dlInfo.dlQos.qci - 1]; + ((RgSchCmnDlSvc *)(dlLc->sch))->gbr = (lcCfg->dlInfo.dlQos.gbr * \ + RG_SCH_CMN_REFRESH_TIME)/100; + ((RgSchCmnDlSvc *)(dlLc->sch))->mbr = (lcCfg->dlInfo.dlQos.mbr * \ + RG_SCH_CMN_REFRESH_TIME)/100; + } + else + { + /*assigning highest priority to DCCH */ + ((RgSchCmnDlSvc *)(dlLc->sch))->prio=RG_SCH_CMN_DCCH_PRIO; + } + dlLc->ue = ue; + dlLc->lcType=lcCfg->lcType; + +#ifdef EMTC_ENABLE + if((cell->emtcEnable)&&(TRUE == ue->isEmtcUe)) + { + ret = cellSch->apisEmtcDl->rgSCHRgrDlLcCfg(cell, ue,dlLc ,lcCfg, err); + if (ret != ROK) + { + RETVALUE(RFAILED); + } + } + else +#endif + { + ret = cellSch->apisDl->rgSCHRgrDlLcCfg(cell, ue, dlLc, lcCfg, err); + if (ret != ROK) + { + RETVALUE(RFAILED); + } + } + +#ifdef EMTC_ENABLE + if(TRUE == ue->isEmtcUe) + { + ret = cellSch->apisEmtcUl->rgSCHRgrUlLcCfg(cell, ue, lcCfg, err); + if (ret != ROK) + { + RETVALUE(RFAILED); + } + } + else +#endif + { + ret = cellSch->apisUl->rgSCHRgrUlLcCfg(cell, ue, lcCfg, err); + if (ret != ROK) + { + RETVALUE(RFAILED); + } + } + +#ifdef LTE_ADV + if (ue->numSCells) + { + rgSCHSCellDlLcCfg(cell, ue, dlLc); + } +#endif + + +#ifdef LTEMAC_SPS + if(lcCfg->dlInfo.dlSpsCfg.isSpsEnabled) + { + /* Invoke SPS module if SPS is enabled for the service */ + ret = rgSCHCmnSpsDlLcCfg(cell, ue, dlLc, lcCfg, err); + if (ret != ROK) + { + RLOG_ARG2(L_ERROR,DBG_CELLID,cell->cellId, "rgSchCmnRgrLchCfg(): " + "SPS configuration failed for DL LC for CRNTI:%d LCID:%d",ue->ueId,lcCfg->lcId); + err->errCause = RGSCHERR_SCH_CFG; + RETVALUE(RFAILED); + } + } +#endif + + RETVALUE(ROK); +} + +/** + * @brief Scheduler invocation on logical channel addition. + * + * @details + * + * Function : rgSCHCmnRgrLchRecfg + * + * This functions does required processing when an existing + * (dedicated) logical channel is reconfigured. Assumes lcg + * pointer in ulLc is set to the old value. + * Independent of whether new LCG is meant to be configured, + * the new LCG scheduler information is accessed and possibly modified. + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ue + * @param[in] RgSchDlLcCb *dlLc + * @param[int] RgrLchRecfg *lcRecfg + * @param[out] RgSchErrInfo *err + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 rgSCHCmnRgrLchRecfg +( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgSchDlLcCb *dlLc, +RgrLchRecfg *lcRecfg, +RgSchErrInfo *err +) +#else +PUBLIC S16 rgSCHCmnRgrLchRecfg(cell, ue, dlLc, lcRecfg, err) +RgSchCellCb *cell; +RgSchUeCb *ue; +RgSchDlLcCb *dlLc; +RgrLchRecfg *lcRecfg; +RgSchErrInfo *err; +#endif +{ + S16 ret; + RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell); + + TRC2(rgSCHCmnRgrLchRecfg) + + if(dlLc->lcType != CM_LTE_LCH_DCCH) + { + ret = rgSCHCmnValidateDlQos(&lcRecfg->dlRecfg.dlQos); + + if (ret != ROK) + { + RLOG_ARG2(L_ERROR,DBG_CELLID,cell->cellId, + "DlQos validation failed for CRNTI:%d LCID:%d",ue->ueId,lcRecfg->lcId); + err->errCause = RGSCHERR_SCH_CFG; + RETVALUE(ret); + } + if (((RgSchCmnDlSvc *)(dlLc->sch))->qci != lcRecfg->dlRecfg.dlQos.qci) + { + RLOG_ARG2(L_ERROR,DBG_CELLID,cell->cellId, "Qci, hence lc Priority change " + "not supported for CRNTI:%d LCID:%d",ue->ueId,lcRecfg->lcId); + err->errCause = RGSCHERR_SCH_CFG; + RETVALUE(ret); + } + ((RgSchCmnDlSvc *)(dlLc->sch))->gbr = (lcRecfg->dlRecfg.dlQos.gbr * \ + RG_SCH_CMN_REFRESH_TIME)/100; + ((RgSchCmnDlSvc *)(dlLc->sch))->mbr = (lcRecfg->dlRecfg.dlQos.mbr * \ + RG_SCH_CMN_REFRESH_TIME)/100; + } + else + { + /*assigning highest priority to DCCH */ + ((RgSchCmnDlSvc *)(dlLc->sch))->prio = RG_SCH_CMN_DCCH_PRIO; + } + +#ifdef EMTC_ENABLE + if((cell->emtcEnable)&&(TRUE == ue->isEmtcUe)) + { + ret = cellSch->apisEmtcDl->rgSCHRgrDlLcRecfg(cell, ue, dlLc, lcRecfg, err); + if (ret != ROK) + { + RETVALUE(RFAILED); + } + ret = cellSch->apisEmtcUl->rgSCHRgrUlLcRecfg(cell, ue, lcRecfg, err); + if (ret != ROK) + { + RETVALUE(RFAILED); + } + } + else +#endif + { + ret = cellSch->apisDl->rgSCHRgrDlLcRecfg(cell, ue, dlLc, lcRecfg, err); + if (ret != ROK) + { + RETVALUE(RFAILED); + } + ret = cellSch->apisUl->rgSCHRgrUlLcRecfg(cell, ue, lcRecfg, err); + if (ret != ROK) + { + RETVALUE(RFAILED); + } + } + +#ifdef LTEMAC_SPS + if (lcRecfg->recfgTypes & RGR_DL_LC_SPS_RECFG) + { + /* Invoke SPS module if SPS is enabled for the service */ + if(lcRecfg->dlRecfg.dlSpsRecfg.isSpsEnabled) + { + ret = rgSCHCmnSpsDlLcRecfg(cell, ue, dlLc, lcRecfg, err); + if (ret != ROK) + { + RLOG_ARG2(L_ERROR,DBG_CELLID,cell->cellId,"SPS re-configuration not " + "supported for dlLC Ignore this CRNTI:%d LCID:%d",ue->ueId,lcRecfg->lcId); + } + } + RETVALUE(ROK); + } +#endif + + RETVALUE(ROK); +} + +/** + * @brief Scheduler invocation on logical channel addition. + * + * @details + * + * Function : rgSCHCmnRgrLcgCfg + * + * This functions does required processing when a new + * (dedicated) logical channel is added. Assumes lcg + * pointer in ulLc is set. + * + * @param[in] RgSchCellCb *cell, + * @param[in] RgSchUeCb *ue, + * @param[in] RgSchLcgCb *lcg, + * @param[in] RgrLcgCfg *lcgCfg, + * @param[out] RgSchErrInfo *err + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 rgSCHCmnRgrLcgCfg +( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgSchLcgCb *lcg, +RgrLcgCfg *lcgCfg, +RgSchErrInfo *err +) +#else +PUBLIC S16 rgSCHCmnRgrLcgCfg(cell, ue, lcg, lcgCfg, err) +RgSchCellCb *cell; +RgSchUeCb *ue; +RgSchLcgCb *lcg; +RgrLcgCfg *lcgCfg; +RgSchErrInfo *err; +#endif +{ + S16 ret; + RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell); + RgSchCmnLcg *ulLcg = ((RgSchCmnLcg *)(ue->ul.lcgArr[lcgCfg->ulInfo.lcgId].sch)); + + TRC2(rgSCHCmnRgrLcgCfg); + + ulLcg->cfgdGbr = (lcgCfg->ulInfo.gbr * RG_SCH_CMN_REFRESH_TIME)/100; + ulLcg->effGbr = ulLcg->cfgdGbr; + ulLcg->deltaMbr = ((lcgCfg->ulInfo.mbr - lcgCfg->ulInfo.gbr) * RG_SCH_CMN_REFRESH_TIME)/100; + ulLcg->effDeltaMbr = ulLcg->deltaMbr; + +#ifdef EMTC_ENABLE + if(TRUE == ue->isEmtcUe) + { + ret = cellSch->apisEmtcUl->rgSCHRgrUlLcgCfg(cell, ue, lcg, lcgCfg, err); + if (ret != ROK) + { + RETVALUE(RFAILED); + } + } + else +#endif + { + ret = cellSch->apisUl->rgSCHRgrUlLcgCfg(cell, ue, lcg, lcgCfg, err); + if (ret != ROK) + { + RETVALUE(RFAILED); + } + } + if (RGSCH_IS_GBR_BEARER(ulLcg->cfgdGbr)) + { + /* Indicate MAC that this LCG is GBR LCG */ + rgSCHUtlBuildNSendLcgReg(cell, ue->ueId, lcgCfg->ulInfo.lcgId, TRUE); + } + RETVALUE(ROK); +} + +/** + * @brief Scheduler invocation on logical channel addition. + * + * @details + * + * Function : rgSCHCmnRgrLcgRecfg + * + * This functions does required processing when a new + * (dedicated) logical channel is added. Assumes lcg + * pointer in ulLc is set. + * + * @param[in] RgSchCellCb *cell, + * @param[in] RgSchUeCb *ue, + * @param[in] RgSchLcgCb *lcg, + * @param[in] RgrLcgRecfg *reCfg, + * @param[out] RgSchErrInfo *err + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 rgSCHCmnRgrLcgRecfg +( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgSchLcgCb *lcg, +RgrLcgRecfg *reCfg, +RgSchErrInfo *err +) +#else +PUBLIC S16 rgSCHCmnRgrLcgRecfg(cell, ue, lcg, reCfg, err) +RgSchCellCb *cell; +RgSchUeCb *ue; +RgSchLcgCb *lcg; +RgrLcgRecfg *reCfg; +RgSchErrInfo *err; +#endif +{ + S16 ret; + RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell); + RgSchCmnLcg *ulLcg = ((RgSchCmnLcg *)(ue->ul.lcgArr[reCfg->ulRecfg.lcgId].sch)); + + TRC2(rgSCHCmnRgrLcgRecfg); + + ulLcg->cfgdGbr = (reCfg->ulRecfg.gbr * RG_SCH_CMN_REFRESH_TIME)/100; + ulLcg->effGbr = ulLcg->cfgdGbr; + ulLcg->deltaMbr = ((reCfg->ulRecfg.mbr - reCfg->ulRecfg.gbr) * RG_SCH_CMN_REFRESH_TIME)/100; + ulLcg->effDeltaMbr = ulLcg->deltaMbr; + +#ifdef EMTC_ENABLE + if(TRUE == ue->isEmtcUe) + { + ret = cellSch->apisEmtcUl->rgSCHRgrUlLcgRecfg(cell, ue, lcg, reCfg, err); + if (ret != ROK) + { + RETVALUE(RFAILED); + } + } + else +#endif + { + ret = cellSch->apisUl->rgSCHRgrUlLcgRecfg(cell, ue, lcg, reCfg, err); + if (ret != ROK) + { + RETVALUE(RFAILED); + } + } + if (RGSCH_IS_GBR_BEARER(ulLcg->cfgdGbr)) + { + /* Indicate MAC that this LCG is GBR LCG */ + rgSCHUtlBuildNSendLcgReg(cell, ue->ueId, reCfg->ulRecfg.lcgId, TRUE); + } + else + { + /* In case of RAB modification */ + rgSCHUtlBuildNSendLcgReg(cell, ue->ueId, reCfg->ulRecfg.lcgId, FALSE); + } + RETVALUE(ROK); +} + +/*********************************************************** + * + * Func : rgSCHCmnRgrLchDel + * + * Desc : Scheduler handling for a (dedicated) + * uplink logical channel being deleted. + * + * Ret : + * + * Notes: + * + * File : + **********************************************************/ +#ifdef ANSI +PUBLIC S16 rgSCHCmnRgrLchDel +( +RgSchCellCb *cell, +RgSchUeCb *ue, +CmLteLcId lcId, +U8 lcgId +) +#else +PUBLIC S16 rgSCHCmnRgrLchDel(cell, ue, lcId, lcgId) +RgSchCellCb *cell; +RgSchUeCb *ue; +CmLteLcId lcId; +U8 lcgId; +#endif +{ + RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell); + TRC2(rgSCHCmnRgrLchDel); +#ifdef EMTC_ENABLE + if(TRUE == ue->isEmtcUe) + { + cellSch->apisEmtcUl->rgSCHRgrUlLchDel(cell, ue, lcId, lcgId); + } + else +#endif + { + cellSch->apisUl->rgSCHRgrUlLchDel(cell, ue, lcId, lcgId); + } + RETVALUE(ROK); +} + +/*********************************************************** + * + * Func : rgSCHCmnLcgDel + * + * Desc : Scheduler handling for a (dedicated) + * uplink logical channel being deleted. + * + * Ret : + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PUBLIC Void rgSCHCmnLcgDel +( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgSchLcgCb *lcg +) +#else +PUBLIC Void rgSCHCmnLcgDel(cell, ue, lcg) +RgSchCellCb *cell; +RgSchUeCb *ue; +RgSchLcgCb *lcg; +#endif +{ + RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell); + RgSchCmnLcg *lcgCmn = RG_SCH_CMN_GET_UL_LCG(lcg); + TRC2(rgSCHCmnLcgDel); + + if (lcgCmn == NULLP) + { + RETVOID; + } + + if (RGSCH_IS_GBR_BEARER(lcgCmn->cfgdGbr)) + { + /* Indicate MAC that this LCG is GBR LCG */ + rgSCHUtlBuildNSendLcgReg(cell, ue->ueId, lcg->lcgId, FALSE); + } + +#ifdef LTEMAC_SPS + if (ue->ul.ulSpsCfg.isUlSpsEnabled == TRUE) + { + rgSCHCmnSpsUlLcgDel(cell, ue, lcg); + } +#endif /* LTEMAC_SPS */ + + lcgCmn->effGbr = 0; + lcgCmn->reportedBs = 0; + lcgCmn->cfgdGbr = 0; + /* set lcg bs to 0. Deletion of control block happens + * at the time of UE deletion. */ + lcgCmn->bs = 0; +#ifdef EMTC_ENABLE + if(TRUE == ue->isEmtcUe) + { + cellSch->apisEmtcUl->rgSCHFreeUlLcg(cell, ue, lcg); + } + else +#endif + { + cellSch->apisUl->rgSCHFreeUlLcg(cell, ue, lcg); + } + RETVOID; +} + + +/** + * @brief This function deletes a service from scheduler. + * + * @details + * + * Function: rgSCHCmnFreeDlLc + * Purpose: This function is made available through a FP for + * making scheduler aware of a service being deleted from UE. + * + * Invoked by: BO and Scheduler + * + * @param[in] RgSchCellCb* cell + * @param[in] RgSchUeCb* ue + * @param[in] RgSchDlLcCb* svc + * @return Void + * + **/ +#ifdef ANSI +PUBLIC Void rgSCHCmnFreeDlLc +( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgSchDlLcCb *svc +) +#else +PUBLIC Void rgSCHCmnFreeDlLc(cell, ue, svc) +RgSchCellCb *cell; +RgSchUeCb *ue; +RgSchDlLcCb *svc; +#endif +{ + RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell); + TRC2(rgSCHCmnFreeDlLc); + if (svc->sch == NULLP) + { + RETVOID; + } +#ifdef EMTC_ENABLE + if((cell->emtcEnable)&&(TRUE == ue->isEmtcUe)) + { + cellSch->apisEmtcDl->rgSCHFreeDlLc(cell, ue, svc); + } + else +#endif + { + cellSch->apisDl->rgSCHFreeDlLc(cell, ue, svc); + } + +#ifdef LTE_ADV + if (ue->numSCells) + { + rgSCHSCellDlLcDel(cell, ue, svc); + } +#endif + +#ifdef LTEMAC_SPS + /* If SPS service, invoke SPS module */ + if (svc->dlLcSpsCfg.isSpsEnabled) + { + rgSCHCmnSpsDlLcDel(cell, ue, svc); + } +#endif + + /* ccpu00117052 - MOD - Passing double pointer + for proper NULLP assignment*/ + rgSCHUtlFreeSBuf(cell->instIdx, + (Data**)(&(svc->sch)), (sizeof(RgSchCmnDlSvc))); + +#ifdef LTE_ADV + rgSCHLaaDeInitDlLchCb(cell, svc); +#endif + + RETVOID; +} + +#ifdef RGR_V1 + +/** + * @brief This function Processes the Final Allocations + * made by the RB Allocator against the requested + * CCCH SDURetx Allocations. + * + * @details + * + * Function: rgSCHCmnDlCcchSduRetxFnlz + * Purpose: This function Processes the Final Allocations + * made by the RB Allocator against the requested + * CCCH Retx Allocations. + * Scans through the scheduled list of ccchSdu retrans + * fills the corresponding pdcch, adds the hqProc to + * the corresponding SubFrm and removes the hqP from + * cells retx List. + * + * Invoked by: Common Scheduler + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchCmnDlRbAllocInfo *allocInfo + * @return Void + * + **/ +#ifdef ANSI +PRIVATE Void rgSCHCmnDlCcchSduRetxFnlz +( +RgSchCellCb *cell, +RgSchCmnDlRbAllocInfo *allocInfo +) +#else +PRIVATE Void rgSCHCmnDlCcchSduRetxFnlz(cell, allocInfo) +RgSchCellCb *cell; +RgSchCmnDlRbAllocInfo *allocInfo; +#endif +{ + CmLList *node; + RgSchCmnDlCell *cmnCellDl = RG_SCH_CMN_GET_DL_CELL(cell); + RgSchDlRbAlloc *rbAllocInfo; + RgSchDlHqProcCb *hqP; + RgSchUeCb *ue; + TRC2(rgSCHCmnDlCcchSduRetxFnlz); + + /* Traverse through the Scheduled Retx List */ + node = allocInfo->ccchSduAlloc.schdCcchSduRetxLst.first; + while (node) + { + hqP = (RgSchDlHqProcCb *)(node->node); + ue = hqP->hqE->ue; + rbAllocInfo = RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ue, cell); + node = node->next; + rgSCHCmnFillHqPPdcch(cell, rbAllocInfo, hqP); + + /* Remove the HqP from cell's ccchSduRetxLst */ + cmLListDelFrm(&cmnCellDl->ccchSduRetxLst, &hqP->tbInfo[0].ccchSchdInfo.retxLnk); + hqP->tbInfo[0].ccchSchdInfo.retxLnk.node = (PTR)NULLP; + + /* Fix: syed dlAllocCb reset should be performed. + * zombie info in dlAllocCb leading to crash rbNum wraparound */ + rgSCHCmnDlUeResetTemp(ue, hqP); + } + /* Fix: syed dlAllocCb reset should be performed. + * zombie info in dlAllocCb leading to crash rbNum wraparound */ + node = allocInfo->ccchSduAlloc.nonSchdCcchSduRetxLst.first; + while(node) + { + hqP = (RgSchDlHqProcCb *)(node->node); + ue = hqP->hqE->ue; + node = node->next; + /* reset the UE allocation Information */ + rgSCHCmnDlUeResetTemp(ue, hqP); + } + RETVOID; +} +#endif +/** + * @brief This function Processes the Final Allocations + * made by the RB Allocator against the requested + * CCCH Retx Allocations. + * + * @details + * + * Function: rgSCHCmnDlCcchRetxFnlz + * Purpose: This function Processes the Final Allocations + * made by the RB Allocator against the requested + * CCCH Retx Allocations. + * Scans through the scheduled list of msg4 retrans + * fills the corresponding pdcch, adds the hqProc to + * the corresponding SubFrm and removes the hqP from + * cells retx List. + * + * Invoked by: Common Scheduler + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchCmnDlRbAllocInfo *allocInfo + * @return Void + * + **/ +#ifdef ANSI +PRIVATE Void rgSCHCmnDlCcchRetxFnlz +( +RgSchCellCb *cell, +RgSchCmnDlRbAllocInfo *allocInfo +) +#else +PRIVATE Void rgSCHCmnDlCcchRetxFnlz(cell, allocInfo) +RgSchCellCb *cell; +RgSchCmnDlRbAllocInfo *allocInfo; +#endif +{ + CmLList *node; + RgSchCmnDlCell *cmnCellDl = RG_SCH_CMN_GET_DL_CELL(cell); + RgSchDlRbAlloc *rbAllocInfo; + RgSchDlHqProcCb *hqP; + RgSchRaCb *raCb; + TRC2(rgSCHCmnDlCcchRetxFnlz); + + /* Traverse through the Scheduled Retx List */ + node = allocInfo->msg4Alloc.schdMsg4RetxLst.first; + while (node) + { + hqP = (RgSchDlHqProcCb *)(node->node); + raCb = hqP->hqE->raCb; + rbAllocInfo = &raCb->rbAllocInfo; + node = node->next; + rgSCHCmnFillHqPPdcch(cell, rbAllocInfo, hqP); + + /* Remove the HqP from cell's msg4RetxLst */ + cmLListDelFrm(&cmnCellDl->msg4RetxLst, &hqP->tbInfo[0].ccchSchdInfo.retxLnk); + hqP->tbInfo[0].ccchSchdInfo.retxLnk.node = (PTR)NULLP; + /* Fix: syed dlAllocCb reset should be performed. + * zombie info in dlAllocCb leading to crash rbNum wraparound */ + cmMemset((U8 *)rbAllocInfo, (U8)0, sizeof(*rbAllocInfo)); + rgSCHCmnDlHqPResetTemp(hqP); + } + /* Fix: syed dlAllocCb reset should be performed. + * zombie info in dlAllocCb leading to crash rbNum wraparound */ + node = allocInfo->msg4Alloc.nonSchdMsg4RetxLst.first; + while(node) + { + hqP = (RgSchDlHqProcCb *)(node->node); + raCb = hqP->hqE->raCb; + node = node->next; + cmMemset((U8 *)&raCb->rbAllocInfo, (U8)0, sizeof(raCb->rbAllocInfo)); + rgSCHCmnDlHqPResetTemp(hqP); + } + RETVOID; +} + +#ifdef RGR_V1 +/** + * @brief This function Processes the Final Allocations + * made by the RB Allocator against the requested + * CCCH SDU tx Allocations. + * + * @details + * + * Function: rgSCHCmnDlCcchSduTxFnlz + * Purpose: This function Processes the Final Allocations + * made by the RB Allocator against the requested + * CCCH tx Allocations. + * Scans through the scheduled list of CCCH SDU trans + * fills the corresponding pdcch, adds the hqProc to + * the corresponding SubFrm and removes the hqP from + * cells tx List. + * + * Invoked by: Common Scheduler + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchCmnDlRbAllocInfo *allocInfo + * @return Void + * + **/ +#ifdef ANSI +PRIVATE Void rgSCHCmnDlCcchSduTxFnlz +( +RgSchCellCb *cell, +RgSchCmnDlRbAllocInfo *allocInfo +) +#else +PRIVATE Void rgSCHCmnDlCcchSduTxFnlz(cell, allocInfo) +RgSchCellCb *cell; +RgSchCmnDlRbAllocInfo *allocInfo; +#endif +{ + CmLList *node; + RgSchUeCb *ueCb; + RgSchDlRbAlloc *rbAllocInfo; + RgSchDlHqProcCb *hqP; + RgSchLchAllocInfo lchSchdData; + TRC2(rgSCHCmnDlCcchSduTxFnlz); + + /* Traverse through the Scheduled Retx List */ + node = allocInfo->ccchSduAlloc.schdCcchSduTxLst.first; + while (node) + { + hqP = (RgSchDlHqProcCb *)(node->node); + ueCb = hqP->hqE->ue; + node = node->next; + rbAllocInfo = RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ueCb, cell); + + /* fill the pdcch and HqProc */ + rgSCHCmnFillHqPPdcch(cell, rbAllocInfo, hqP); + + /* Remove the raCb from cell's toBeSchdLst */ + cmLListDelFrm(&cell->ccchSduUeLst, &ueCb->ccchSduLnk); + ueCb->ccchSduLnk.node = (PTR)NULLP; + + /* Fix : Resetting this required to avoid complication + * in reestablishment case */ + ueCb->dlCcchInfo.bo = 0; + + /* Indicate DHM of the CCCH LC scheduling */ + hqP->tbInfo[0].contResCe = NOTPRSNT; + lchSchdData.lcId = 0; + lchSchdData.schdData = hqP->tbInfo[0].ccchSchdInfo.totBytes - + (RGSCH_MSG4_HDRSIZE); + rgSCHDhmAddLcData(cell->instIdx, &lchSchdData, &hqP->tbInfo[0]); + + /* Fix: syed dlAllocCb reset should be performed. + * zombie info in dlAllocCb leading to crash rbNum wraparound */ + rgSCHCmnDlUeResetTemp(ueCb, hqP); + } + /* Fix: syed dlAllocCb reset should be performed. + * zombie info in dlAllocCb leading to crash rbNum wraparound */ + node = allocInfo->ccchSduAlloc.nonSchdCcchSduTxLst.first; + while(node) + { + hqP = (RgSchDlHqProcCb *)(node->node); + ueCb = hqP->hqE->ue; + node = node->next; + /* Release HqProc */ + rgSCHDhmRlsHqpTb(hqP, 0, FALSE); + /*Fix: Removing releasing of TB1 as it will not exist for CCCH SDU and hence caused a crash*/ + /*rgSCHDhmRlsHqpTb(hqP, 1, FALSE);*/ + /* reset the UE allocation Information */ + rgSCHCmnDlUeResetTemp(ueCb, hqP); + } + RETVOID; +} + +#endif +/** + * @brief This function Processes the Final Allocations + * made by the RB Allocator against the requested + * CCCH tx Allocations. + * + * @details + * + * Function: rgSCHCmnDlCcchTxFnlz + * Purpose: This function Processes the Final Allocations + * made by the RB Allocator against the requested + * CCCH tx Allocations. + * Scans through the scheduled list of msg4 trans + * fills the corresponding pdcch, adds the hqProc to + * the corresponding SubFrm and removes the hqP from + * cells tx List. + * + * Invoked by: Common Scheduler + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchCmnDlRbAllocInfo *allocInfo + * @return Void + * + **/ +#ifdef ANSI +PRIVATE Void rgSCHCmnDlCcchTxFnlz +( +RgSchCellCb *cell, +RgSchCmnDlRbAllocInfo *allocInfo +) +#else +PRIVATE Void rgSCHCmnDlCcchTxFnlz(cell, allocInfo) +RgSchCellCb *cell; +RgSchCmnDlRbAllocInfo *allocInfo; +#endif +{ + CmLList *node; + RgSchRaCb *raCb; + RgSchDlRbAlloc *rbAllocInfo; + RgSchDlHqProcCb *hqP; + RgSchLchAllocInfo lchSchdData; + TRC2(rgSCHCmnDlCcchTxFnlz); + + /* Traverse through the Scheduled Retx List */ + node = allocInfo->msg4Alloc.schdMsg4TxLst.first; + while (node) + { + hqP = (RgSchDlHqProcCb *)(node->node); + raCb = hqP->hqE->raCb; + node = node->next; + rbAllocInfo = &raCb->rbAllocInfo; + + /* fill the pdcch and HqProc */ + rgSCHCmnFillHqPPdcch(cell, rbAllocInfo, hqP); + /* MSG4 Fix Start */ + + rgSCHRamRmvFrmRaInfoSchdLst(cell, raCb); + /* MSG4 Fix End */ + + /* Indicate DHM of the CCCH LC scheduling */ + lchSchdData.lcId = 0; + lchSchdData.schdData = hqP->tbInfo[0].ccchSchdInfo.totBytes - + (RGSCH_MSG4_HDRSIZE + RGSCH_CONT_RESID_SIZE); + /* TRansmitting presence of cont Res CE across MAC-SCH interface to + * identify CCCH SDU transmissions which need to be done + * without the + * contention resolution CE*/ + hqP->tbInfo[0].contResCe = PRSNT_NODEF; + /*Dont add lc if only cont res CE is being transmitted*/ + if(raCb->dlCcchInfo.bo) + { + rgSCHDhmAddLcData(cell->instIdx, &lchSchdData, &hqP->tbInfo[0]); + } + else + { + } + /* Fix: syed dlAllocCb reset should be performed. + * zombie info in dlAllocCb leading to crash rbNum wraparound */ + cmMemset((U8 *)&raCb->rbAllocInfo, (U8)0, sizeof(raCb->rbAllocInfo)); + rgSCHCmnDlHqPResetTemp(hqP); + } + node = allocInfo->msg4Alloc.nonSchdMsg4TxLst.first; + while(node) + { + hqP = (RgSchDlHqProcCb *)(node->node); + raCb = hqP->hqE->raCb; + node = node->next; + rbAllocInfo = &raCb->rbAllocInfo; + /* Release HqProc */ + rgSCHDhmRlsHqpTb(hqP, 0, FALSE); + /*Fix: Removing releasing of TB1 as it will not exist for MSG4 and hence caused a crash*/ + /* rgSCHDhmRlsHqpTb(hqP, 1, FALSE);*/ + /* reset the UE allocation Information */ + cmMemset((U8 *)rbAllocInfo, (U8)0, sizeof(*rbAllocInfo)); + rgSCHCmnDlHqPResetTemp(hqP); + } + + RETVOID; +} +/* R8 Upgrade */ +/** + * @brief This function calculates the BI Index to be sent in the Bi header + * field. + * + * @details + * Function: rgSCHCmnGetBiIndex + * Purpose: This function Processes utilizes the previous BI time value + * calculated and the difference last BI sent time and current time. To + * calculate the latest BI Index. It also considers the how many UE's + * Unserved in this subframe. + * + * Invoked by: Common Scheduler + * + * @param[in] RgSchCellCb *cell + * @param[in] U32 ueCount + * @return U8 + * + **/ +#ifdef ANSI +PUBLIC U8 rgSCHCmnGetBiIndex +( +RgSchCellCb *cell, +U32 ueCount +) +#else +PUBLIC U8 rgSCHCmnGetBiIndex(cell, ueCount) +RgSchCellCb *cell; +U32 ueCount; +#endif +{ + S16 prevVal = 0; /* To Store Intermediate Value */ + U16 newBiVal = 0; /* To store Bi Value in millisecond */ + U8 idx = 0; + U16 timeDiff = 0; + + TRC2(rgSCHCmnGetBiIndex) + + if (cell->biInfo.prevBiTime != 0) + { +#ifdef EMTC_ENABLE + if(cell->emtcEnable == TRUE) + { + timeDiff =(RGSCH_CALC_SF_DIFF_EMTC(cell->crntTime, cell->biInfo.biTime)); + } + else +#endif + { + timeDiff =(RGSCH_CALC_SF_DIFF(cell->crntTime, cell->biInfo.biTime)); + } + + prevVal = cell->biInfo.prevBiTime - timeDiff; + } + if (prevVal < 0) + { + prevVal = 0; + } + newBiVal = RG_SCH_CMN_GET_BI_VAL(prevVal,ueCount); + /* To be used next time when BI is calculated */ +#ifdef EMTC_ENABLE + if(cell->emtcEnable == TRUE) + { + RGSCHCPYTIMEINFO_EMTC(cell->crntTime, cell->biInfo.biTime) + } + else +#endif + { + RGSCHCPYTIMEINFO(cell->crntTime, cell->biInfo.biTime) + } + + /* Search the actual BI Index from table Backoff Parameters Value and + * return that Index */ + do + { + if (rgSchCmnBiTbl[idx] > newBiVal) + { + break; + } + idx++; + }while(idx < RG_SCH_CMN_NUM_BI_VAL-1); + cell->biInfo.prevBiTime = rgSchCmnBiTbl[idx]; + /* For 16 Entries in Table 7.2.1 36.321.880 - 3 reserved so total 13 Entries */ + RETVALUE(idx); /* Returning reserved value from table UE treats it has 960 ms */ +} /* rgSCHCmnGetBiIndex */ + + +/** + * @brief This function Processes the Final Allocations + * made by the RB Allocator against the requested + * RAR allocations. Assumption: The reuqested + * allocations are always satisfied completely. + * Hence no roll back. + * + * @details + * + * Function: rgSCHCmnDlRaRspFnlz + * Purpose: This function Processes the Final Allocations + * made by the RB Allocator against the requested. + * Takes care of PDCCH filling. + * + * Invoked by: Common Scheduler + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchCmnDlRbAllocInfo *allocInfo + * @return Void + * + **/ +#ifdef ANSI +PRIVATE Void rgSCHCmnDlRaRspFnlz +( +RgSchCellCb *cell, +RgSchCmnDlRbAllocInfo *allocInfo +) +#else +PRIVATE Void rgSCHCmnDlRaRspFnlz(cell, allocInfo) +RgSchCellCb *cell; +RgSchCmnDlRbAllocInfo *allocInfo; +#endif +{ + U32 rarCnt = 0; + RgSchDlRbAlloc *raRspAlloc; + RgSchDlSf *subFrm = NULLP; + RgSchRaCb *raCb; + RgSchErrInfo err; + CmLListCp *reqLst; + RgSchRaReqInfo *raReq; + Bool preamGrpA; + RgSchUlAlloc *ulAllocRef=NULLP; + RgSchCmnDlCell *cellDl = RG_SCH_CMN_GET_DL_CELL(cell); + U8 allocRapidCnt = 0; +#ifdef LTE_TDD + U32 msg3SchdIdx = 0; + U8 ulDlCfgIdx = cell->ulDlCfgIdx; + U8 msg3Subfrm; +#endif + + TRC2(rgSCHCmnDlRaRspFnlz); + + for (rarCnt=0; rarCntraRspAlloc[rarCnt]; + /* Having likely condition first for optimization */ + if (!raRspAlloc->pdcch) + { + continue; + } + else + { + subFrm = raRspAlloc->dlSf; + reqLst = &cell->raInfo.raReqLst[raRspAlloc->raIndex]; + /* Corrected RACH handling for multiple RAPIDs per RARNTI */ + allocRapidCnt = raRspAlloc->numRapids; + while (allocRapidCnt) + { + raReq = (RgSchRaReqInfo *)(reqLst->first->node); + /* RACHO: If dedicated preamble, then allocate UL Grant + * (consequence of handover/pdcchOrder) and continue */ + if (RGSCH_IS_DEDPRM(cell, raReq->raReq.rapId)) + { + rgSCHCmnHdlHoPo(cell, &subFrm->raRsp[rarCnt].contFreeUeLst, + raReq); + cmLListDelFrm(reqLst, reqLst->first); + allocRapidCnt--; + /* ccpu00117052 - MOD - Passing double pointer + for proper NULLP assignment*/ + rgSCHUtlFreeSBuf(cell->instIdx, (Data **)&raReq, + sizeof(RgSchRaReqInfo)); + continue; + } + /* ccpu00139815 */ + if(cell->overLoadBackOffEnab) + {/* rach Overlaod conrol is triggerd, Skipping this rach */ + cmLListDelFrm(reqLst, reqLst->first); + allocRapidCnt--; + rgSCHUtlFreeSBuf(cell->instIdx, (Data **)&raReq, + sizeof(RgSchRaReqInfo)); + continue; + } + /* Attempt to include each RA request into the RSP */ + /* Any failure in the procedure is considered to */ + /* affect futher allocations in the same TTI. When */ + /* a failure happens, we break out and complete */ + /* the processing for random access */ + if (rgSCHRamCreateRaCb(cell, &raCb, &err) != ROK) + { + break; + } + /* Msg3 allocation request to USM */ + if (raReq->raReq.rapId < cell->rachCfg.sizeRaPreambleGrpA) + preamGrpA = TRUE; + else + preamGrpA = FALSE; + /*ccpu00128820 - MOD - Msg3 alloc double delete issue*/ + rgSCHCmnMsg3GrntReq(cell, raCb->tmpCrnti, preamGrpA, \ + &(raCb->msg3HqProc), &ulAllocRef, &raCb->msg3HqProcId); + if (ulAllocRef == NULLP) + { + rgSCHRamDelRaCb(cell, raCb, TRUE); + break; + } + if (raReq->raReq.cqiPres) + { + raCb->ccchCqi = raReq->raReq.cqiIdx; + } + else + { + raCb->ccchCqi = cellDl->ccchCqi; + } + raCb->rapId = raReq->raReq.rapId; + raCb->ta.pres = TRUE; + raCb->ta.val = raReq->raReq.ta; + raCb->msg3Grnt = ulAllocRef->grnt; + /* Populating the tpc value received */ + raCb->msg3Grnt.tpc = raReq->raReq.tpc; + /* PHR handling for MSG3 */ + ulAllocRef->raCb = raCb; +#ifndef LTE_TDD + /* To the crntTime, add the MIN time at which UE will + * actually send MSG3 i.e DL_DELTA+6 */ + raCb->msg3AllocTime = cell->crntTime; + RGSCH_INCR_SUB_FRAME(raCb->msg3AllocTime, RG_SCH_CMN_MIN_MSG3_RECP_INTRVL); +#else + msg3SchdIdx = (cell->crntTime.subframe+RG_SCH_CMN_DL_DELTA) % + RGSCH_NUM_SUB_FRAMES; + /*[ccpu00134666]-MOD-Modify the check to schedule the RAR in + special subframe */ + if(rgSchTddUlDlSubfrmTbl[ulDlCfgIdx][msg3SchdIdx] != + RG_SCH_TDD_UL_SUBFRAME) + { + RGSCHCMNADDTOCRNTTIME(cell->crntTime,raCb->msg3AllocTime, + RG_SCH_CMN_DL_DELTA) + msg3Subfrm = rgSchTddMsg3SubfrmTbl[ulDlCfgIdx][ + raCb->msg3AllocTime.subframe]; + RGSCHCMNADDTOCRNTTIME(raCb->msg3AllocTime, raCb->msg3AllocTime, + msg3Subfrm); + } +#endif + cmLListAdd2Tail(&subFrm->raRsp[rarCnt].raRspLst, &raCb->rspLnk); + raCb->rspLnk.node = (PTR)raCb; + cmLListDelFrm(reqLst, reqLst->first); + allocRapidCnt--; + /* ccpu00117052 - MOD - Passing double pointer + for proper NULLP assignment*/ + rgSCHUtlFreeSBuf(cell->instIdx, (Data **)&raReq, + sizeof(RgSchRaReqInfo)); + + /* SR_RACH_STATS : RAR scheduled */ + rgNumRarSched++; + + } + /* R8 Upgrade */ + /* Fill subframe data members */ + subFrm->raRsp[rarCnt].raRnti = raRspAlloc->rnti; + subFrm->raRsp[rarCnt].pdcch = raRspAlloc->pdcch; + subFrm->raRsp[rarCnt].tbSz = raRspAlloc->tbInfo[0].bytesAlloc; + /* Fill PDCCH data members */ + rgSCHCmnFillPdcch(cell, subFrm->raRsp[rarCnt].pdcch, raRspAlloc); + + /* ccpu00139815 */ + if(cell->overLoadBackOffEnab) + {/* rach Overlaod conrol is triggerd, Skipping this rach */ + subFrm->raRsp[rarCnt].backOffInd.pres = PRSNT_NODEF; + subFrm->raRsp[rarCnt].backOffInd.val = cell->overLoadBackOffval; + continue; + } + else + { + subFrm->raRsp[rarCnt].backOffInd.pres = NOTPRSNT; + } + + /*[ccpu00125212] Avoiding sending of empty RAR in case of RAR window + is short and UE is sending unauthorised preamble.*/ + reqLst = &cell->raInfo.raReqLst[raRspAlloc->raIndex]; + if ((raRspAlloc->biEstmt) && (reqLst->count)) + { + subFrm->raRsp[0].backOffInd.pres = PRSNT_NODEF; + /* Added as part of Upgrade */ + subFrm->raRsp[0].backOffInd.val = + rgSCHCmnGetBiIndex(cell, reqLst->count); + + /* SR_RACH_STATS : Back Off Inds */ + rgNumBI++; + + } + else if ((subFrm->raRsp[rarCnt].raRspLst.first == NULLP) && + (subFrm->raRsp[rarCnt].contFreeUeLst.first == NULLP)) + { + /* Return the grabbed PDCCH */ + rgSCHUtlPdcchPut(cell, &subFrm->pdcchInfo, raRspAlloc->pdcch); + subFrm->raRsp[rarCnt].pdcch = NULLP; + RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,"rgSCHCmnRaRspAlloc(): " + "Not even one RaReq."); + RETVOID; + } + } + RLOG_ARG3(L_DEBUG,DBG_CELLID,cell->cellId, + "RNTI:%d Scheduled RAR @ (%u,%u) ", + raRspAlloc->rnti, + cell->crntTime.sfn, + cell->crntTime.subframe); + } + RETVOID; +} + +/** + * @brief This function computes rv. + * + * @details + * + * Function: rgSCHCmnDlCalcRvForBcch + * Purpose: This function computes rv. + * + * Invoked by: Common Scheduler + * + * @param[in] RgSchCellCb *cell + * @param[in] Bool si + * @param[in] U16 i + * @return U8 + * + **/ +#ifdef ANSI +PRIVATE U8 rgSCHCmnDlCalcRvForBcch +( +RgSchCellCb *cell, +Bool si, +U16 i +) +#else +PRIVATE U8 rgSCHCmnDlCalcRvForBcch(cell, si, i) +RgSchCellCb *cell; +Bool si; +U16 i; +#endif +{ + U8 k, rv; + CmLteTimingInfo frm; + TRC2(rgSCHCmnDlCalcRvForBcch); + + frm = cell->crntTime; + RGSCH_INCR_SUB_FRAME(frm, RG_SCH_CMN_DL_DELTA); + + if(si) + { + k = i % 4; + } + else + { + k = (frm.sfn/2) % 4; + } + rv = RGSCH_CEIL(3*k, 2) % 4; + RETVALUE(rv); +} + +/** + * @brief This function Processes the Final Allocations + * made by the RB Allocator against the requested + * BCCH/PCCH allocations. Assumption: The reuqested + * allocations are always satisfied completely. + * Hence no roll back. + * + * @details + * + * Function: rgSCHCmnDlBcchPcchFnlz + * Purpose: This function Processes the Final Allocations + * made by the RB Allocator against the requested. + * Takes care of PDCCH filling. + * + * Invoked by: Common Scheduler + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchCmnDlRbAllocInfo *allocInfo + * @return Void + * + **/ +#ifdef ANSI +PRIVATE Void rgSCHCmnDlBcchPcchFnlz +( +RgSchCellCb *cell, +RgSchCmnDlRbAllocInfo *allocInfo +) +#else +PRIVATE Void rgSCHCmnDlBcchPcchFnlz(cell, allocInfo) +RgSchCellCb *cell; +RgSchCmnDlRbAllocInfo *allocInfo; +#endif +{ + RgSchDlRbAlloc *rbAllocInfo; + RgSchDlSf *subFrm; + +#ifdef LTE_TDD + U8 nextSfIdx = (cell->crntSfIdx) % RGSCH_SF_ALLOC_SIZE; +#else +#ifdef LTEMAC_HDFDD + U8 nextSfIdx = (cell->crntSfIdx + RG_SCH_CMN_HARQ_INTERVAL) % RGSCH_NUM_SUB_FRAMES; +#else + U8 nextSfIdx = (cell->crntSfIdx) % RGSCH_NUM_SUB_FRAMES; +#endif +#endif + + /* Moving variables to available scope for optimization */ + RgSchClcDlLcCb *pcch; + RgSchClcBoRpt *bo; +#ifndef RGR_SI_SCH + RgSchClcDlLcCb *bcch; + Bool sendInd=TRUE; +#endif + RgSchCmnDlCell *cellDl = RG_SCH_CMN_GET_DL_CELL(cell); + + TRC2(rgSCHCmnDlBcchPcchFnlz); + + /* handle PCCH */ + rbAllocInfo = &allocInfo->pcchAlloc; + if (rbAllocInfo->pdcch) + { + RgInfSfAlloc *subfrmAlloc = &(cell->sfAllocArr[nextSfIdx]); + + /* Added sfIdx calculation for TDD as well */ +#ifndef LTE_TDD +#ifdef LTEMAC_HDFDD + nextSfIdx = (cell->crntSfIdx + RG_SCH_CMN_HARQ_INTERVAL) % RGSCH_NUM_SUB_FRAMES; +#else + nextSfIdx = (cell->crntSfIdx) % RGSCH_NUM_SUB_FRAMES; +#endif +#endif + subFrm = rbAllocInfo->dlSf; + pcch = rgSCHDbmGetPcch(cell); + if(pcch == NULLP) + { + RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,"rgSCHCmnDlBcchPcchFnlz( ): " + "No Pcch Present"); + RETVOID; + } + + /* Added Dl TB count for paging message transmission*/ +#ifdef LTE_L2_MEAS + cell->dlUlTbCnt.tbTransDlTotalCnt++; +#endif + bo = (RgSchClcBoRpt *)pcch->boLst.first->node; + cmLListDelFrm(&pcch->boLst, &bo->boLstEnt); + /* ccpu00117052 - MOD - Passing double pointer + for proper NULLP assignment*/ + rgSCHUtlFreeSBuf(cell->instIdx, (Data **)&bo, sizeof(RgSchClcBoRpt)); + /* Fill subframe data members */ + subFrm->pcch.tbSize = rbAllocInfo->tbInfo[0].bytesAlloc; + subFrm->pcch.pdcch = rbAllocInfo->pdcch; + /* Fill PDCCH data members */ + rgSCHCmnFillPdcch(cell, subFrm->pcch.pdcch, rbAllocInfo); + rgSCHUtlFillRgInfCmnLcInfo(subFrm, subfrmAlloc, pcch->lcId, TRUE); + /* ccpu00132314-ADD-Update the tx power allocation info + TODO-Need to add a check for max tx power per symbol */ + subfrmAlloc->cmnLcInfo.pcchInfo.txPwrOffset = cellDl->pcchTxPwrOffset; + } + + /* handle BCCH */ + rbAllocInfo = &allocInfo->bcchAlloc; + if (rbAllocInfo->pdcch) + { + RgInfSfAlloc *subfrmAlloc = &(cell->sfAllocArr[nextSfIdx]); +#ifndef LTE_TDD +#ifdef LTEMAC_HDFDD + nextSfIdx = (cell->crntSfIdx + RG_SCH_CMN_HARQ_INTERVAL) % RGSCH_NUM_SUB_FRAMES; +#else + nextSfIdx = (cell->crntSfIdx) % RGSCH_NUM_SUB_FRAMES; +#endif +#endif + subFrm = rbAllocInfo->dlSf; + + /* Fill subframe data members */ + subFrm->bcch.tbSize = rbAllocInfo->tbInfo[0].bytesAlloc; + subFrm->bcch.pdcch = rbAllocInfo->pdcch; + /* Fill PDCCH data members */ + rgSCHCmnFillPdcch(cell, subFrm->bcch.pdcch, rbAllocInfo); + + if(rbAllocInfo->schdFirst) + { +#ifndef RGR_SI_SCH + bcch = rgSCHDbmGetFirstBcchOnDlsch(cell); + bo = (RgSchClcBoRpt *)bcch->boLst.first->node; +#else + /*Copy the SIB1 msg buff into interface buffer */ + SCpyMsgMsg(cell->siCb.crntSiInfo.sib1Info.sib1, + rgSchCb[cell->instIdx].rgSchInit.region, + rgSchCb[cell->instIdx].rgSchInit.pool, + &subfrmAlloc->cmnLcInfo.bcchInfo.pdu); +#endif/*RGR_SI_SCH*/ + subFrm->bcch.pdcch->dci.u.format1aInfo.t.pdschInfo.allocInfo.rv = + rgSCHCmnDlCalcRvForBcch(cell, FALSE, 0); + } + else + { + U16 i; +#ifdef RGR_SI_SCH + Buffer *pdu; + + i = cell->siCb.siCtx.i; + /*Decrement the retransmission count */ + cell->siCb.siCtx.retxCntRem--; + + /*Copy the SI msg buff into interface buffer */ + if(cell->siCb.siCtx.warningSiFlag == FALSE) + { + SCpyMsgMsg(cell->siCb.siArray[cell->siCb.siCtx.siId-1].si, + rgSchCb[cell->instIdx].rgSchInit.region, + rgSchCb[cell->instIdx].rgSchInit.pool, + &subfrmAlloc->cmnLcInfo.bcchInfo.pdu); + } + else + { + pdu = rgSCHUtlGetWarningSiPdu(cell); + RGSCH_NULL_CHECK(cell->instIdx, pdu); + SCpyMsgMsg(pdu, + rgSchCb[cell->instIdx].rgSchInit.region, + rgSchCb[cell->instIdx].rgSchInit.pool, + &subfrmAlloc->cmnLcInfo.bcchInfo.pdu); + if(cell->siCb.siCtx.retxCntRem == 0) + { + rgSCHUtlFreeWarningSiPdu(cell); + cell->siCb.siCtx.warningSiFlag = FALSE; + + } + } +#else + bcch = rgSCHDbmGetSecondBcchOnDlsch(cell); + bo = (RgSchClcBoRpt *)bcch->boLst.first->node; + bo->retxCnt--; + if(bo->retxCnt != cell->siCfg.retxCnt-1) + { + sendInd=FALSE; + } + i = bo->i; +#endif/*RGR_SI_SCH*/ + subFrm->bcch.pdcch->dci.u.format1aInfo.t.pdschInfo.allocInfo.rv = + rgSCHCmnDlCalcRvForBcch(cell, TRUE, i); + } + + /* Added Dl TB count for SIB1 and SI messages transmission. + * This counter will be incremented only for the first transmission + * (with RV 0) of these messages*/ +#ifdef LTE_L2_MEAS + if(subFrm->bcch.pdcch->dci.u.format1aInfo.t.pdschInfo.allocInfo.rv == 0) + { + cell->dlUlTbCnt.tbTransDlTotalCnt++; + } +#endif +#ifndef RGR_SI_SCH + if(bo->retxCnt == 0) + { + cmLListDelFrm(&bcch->boLst, &bo->boLstEnt); + /* ccpu00117052 - MOD - Passing double pointer + for proper NULLP assignment*/ + rgSCHUtlFreeSBuf(cell->instIdx, (Data **)&bo, sizeof(RgSchClcBoRpt)); + } + rgSCHUtlFillRgInfCmnLcInfo(subFrm, subfrmAlloc, bcch->lcId, sendInd); +#else + /*Fill the interface info */ + rgSCHUtlFillRgInfCmnLcInfo(subFrm, subfrmAlloc, NULLD, NULLD); + + /* ccpu00132314-ADD-Update the tx power allocation info + TODO-Need to add a check for max tx power per symbol */ + subfrmAlloc->cmnLcInfo.bcchInfo.txPwrOffset = cellDl->bcchTxPwrOffset; + + /*mBuf has been already copied above */ +#endif/*RGR_SI_SCH*/ + } + + RETVOID; +} + + +#if RG_UNUSED +/** + * @brief + * + * @details + * + * Function: rgSCHCmnUlSetAllUnSched + * Purpose: + * + * Invoked by: Common Scheduler + * + * @param[out] RgSchCmnUlRbAllocInfo *allocInfo + * @return Void + * + **/ +#ifdef ANSI +PRIVATE Void rgSCHCmnUlSetAllUnSched +( +RgSchCmnUlRbAllocInfo *allocInfo +) +#else +PRIVATE Void rgSCHCmnUlSetAllUnSched(allocInfo) +RgSchCmnUlRbAllocInfo *allocInfo; +#endif +{ + CmLList *node; + + TRC2(rgSCHCmnUlSetAllUnSched); + + node = allocInfo->contResLst.first; + while (node) + { + rgSCHCmnUlMov2NonSchdCntResLst(allocInfo, (RgSchUeCb *)node->node); + node = allocInfo->contResLst.first; + } + + node = allocInfo->retxUeLst.first; + while (node) + { + rgSCHCmnUlMov2NonSchdRetxUeLst(allocInfo, (RgSchUeCb *)node->node); + node = allocInfo->retxUeLst.first; + } + + node = allocInfo->ueLst.first; + while (node) + { + rgSCHCmnUlMov2NonSchdUeLst(allocInfo, (RgSchUeCb *)node->node); + node = allocInfo->ueLst.first; + } + + RETVOID; +} +#endif + +/** + * @brief + * + * @details + * + * Function: rgSCHCmnUlAdd2CntResLst + * Purpose: + * + * Invoked by: Common Scheduler + * + * @param[out] RgSchCmnUlRbAllocInfo *allocInfo + * @param[in] RgSchUeCb *ue + * @return Void + * + **/ +#ifdef ANSI +PUBLIC Void rgSCHCmnUlAdd2CntResLst +( +RgSchCmnUlRbAllocInfo *allocInfo, +RgSchUeCb *ue +) +#else +PUBLIC Void rgSCHCmnUlAdd2CntResLst(allocInfo, ue) +RgSchCmnUlRbAllocInfo *allocInfo; +RgSchUeCb *ue; +#endif +{ + RgSchCmnUeUlAlloc *ulAllocInfo = &((RG_SCH_CMN_GET_UL_UE(ue,ue->cell))->alloc); + TRC2(rgSCHCmnUlAdd2CntResLst); + cmLListAdd2Tail(&allocInfo->contResLst, &ulAllocInfo->reqLnk); + ulAllocInfo->reqLnk.node = (PTR)ue; + RETVOID; +} + +/** + * @brief + * + * @details + * + * Function: rgSCHCmnUlAdd2UeLst + * Purpose: + * + * Invoked by: Common Scheduler + * + * @param[out] RgSchCmnUlRbAllocInfo *allocInfo + * @param[in] RgSchUeCb *ue + * @return Void + * + **/ +#ifdef ANSI +PUBLIC Void rgSCHCmnUlAdd2UeLst +( +RgSchCellCb *cell, +RgSchCmnUlRbAllocInfo *allocInfo, +RgSchUeCb *ue +) +#else +PUBLIC Void rgSCHCmnUlAdd2UeLst(cell, allocInfo, ue) +RgSchCellCb *cell; +RgSchCmnUlRbAllocInfo *allocInfo; +RgSchUeCb *ue; +#endif +{ + RgSchCmnUeUlAlloc *ulAllocInfo = &((RG_SCH_CMN_GET_UL_UE(ue,cell))->alloc); + TRC2(rgSCHCmnUlAdd2UeLst); + if (ulAllocInfo->reqLnk.node == NULLP) + { + cmLListAdd2Tail(&allocInfo->ueLst, &ulAllocInfo->reqLnk); + ulAllocInfo->reqLnk.node = (PTR)ue; + } + RETVOID; +} + +/** + * @brief + * + * @details + * + * Function: rgSCHCmnAllocUlRb + * Purpose: To do RB allocations for uplink + * + * Invoked by: Common Scheduler + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchCmnUlRbAllocInfo *allocInfo + * @return Void + **/ +#ifdef ANSI +PUBLIC Void rgSCHCmnAllocUlRb +( +RgSchCellCb *cell, +RgSchCmnUlRbAllocInfo *allocInfo +) +#else +PUBLIC Void rgSCHCmnAllocUlRb(cell, allocInfo) +RgSchCellCb *cell; +RgSchCmnUlRbAllocInfo *allocInfo; +#endif +{ + RgSchUlSf *sf = allocInfo->sf; + TRC2(rgSCHCmnAllocUlRb); + + /* Schedule for new transmissions */ + rgSCHCmnUlRbAllocForLst(cell, sf, allocInfo->ueLst.count, + &allocInfo->ueLst, &allocInfo->schdUeLst, + &allocInfo->nonSchdUeLst, (Bool)TRUE); + RETVOID; +} + +/*********************************************************** + * + * Func : rgSCHCmnUlRbAllocForLst + * + * Desc : Allocate for a list in cmn rb alloc information passed + * in a subframe. + * + * Ret : + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PRIVATE Void rgSCHCmnUlRbAllocForLst +( +RgSchCellCb *cell, +RgSchUlSf *sf, +U32 count, +CmLListCp *reqLst, +CmLListCp *schdLst, +CmLListCp *nonSchdLst, +Bool isNewTx +) +#else +PRIVATE Void rgSCHCmnUlRbAllocForLst(cell, sf, count, reqLst, schdLst, + nonSchdLst, isNewTx) +RgSchCellCb *cell; +RgSchUlSf *sf; +U32 count; +CmLListCp *reqLst; +CmLListCp *schdLst; +CmLListCp *nonSchdLst; +Bool isNewTx; +#endif +{ + CmLList *lnk; + RgSchUlHole *hole; +#ifdef LTE_L2_MEAS +#ifdef LTE_TDD + U8 k; + CmLteTimingInfo timeInfo; +#endif +#endif + TRC2(rgSCHCmnUlRbAllocForLst); + + if(schdLst->count == 0) + { + cmLListInit(schdLst); + } + + cmLListInit(nonSchdLst); +#ifdef LTE_L2_MEAS + if(isNewTx == TRUE) + { + cell->sfAllocArr[cell->crntSfIdx].ulUeInfo.numUes = (U8) count; +#ifdef LTE_TDD + RG_SCH_ADD_TO_CRNT_TIME(cell->crntTime, timeInfo, TFU_ULCNTRL_DLDELTA); + k = rgSchTddPuschTxKTbl[cell->ulDlCfgIdx][timeInfo.subframe]; + RG_SCH_ADD_TO_CRNT_TIME(timeInfo, + cell->sfAllocArr[cell->crntSfIdx].ulUeInfo.timingInfo, k); +#else + RG_SCH_ADD_TO_CRNT_TIME(cell->crntTime,cell->sfAllocArr[cell->crntSfIdx].ulUeInfo.timingInfo, + (TFU_ULCNTRL_DLDELTA + RGSCH_PDCCH_PUSCH_DELTA)); +#endif + } +#endif + + for (lnk = reqLst->first; count; lnk = lnk->next, --count) + { + RgSchUeCb *ue = (RgSchUeCb *)lnk->node; + RgSchCmnUlUe *ueUl = RG_SCH_CMN_GET_UL_UE(ue, cell); + S16 ret; + U8 maxRb; + + + if ((hole = rgSCHUtlUlHoleFirst(sf)) == NULLP) + { + break; + } + + ueUl->subbandShare = ueUl->subbandRequired; + if(isNewTx == TRUE) + { + maxRb = RGSCH_MIN((ueUl->subbandRequired * MAX_5GTF_VRBG_SIZE), ue->ue5gtfCb.maxPrb); + } + ret = rgSCHCmnUlRbAllocForUe(cell, sf, ue, maxRb, hole); + if (ret == ROK) + { + rgSCHCmnUlRbAllocAddUeToLst(cell, ue, schdLst); + rgSCHCmnUlUeFillAllocInfo(cell, ue); + } + else + { + gUl5gtfRbAllocFail++; +#if defined (TENB_STATS) && defined (RG_5GTF) + cell->tenbStats->sch.ul5gtfRbAllocFail++; +#endif + rgSCHCmnUlRbAllocAddUeToLst(cell, ue, nonSchdLst); + ue->isMsg4PdcchWithCrnti = FALSE; + ue->isSrGrant = FALSE; + } +#ifdef LTE_L2_MEAS + if(isNewTx == TRUE) + { + cell->sfAllocArr[cell->crntSfIdx].ulUeInfo. + ulAllocInfo[count - 1].rnti = ue->ueId; + cell->sfAllocArr[cell->crntSfIdx].ulUeInfo. + ulAllocInfo[count - 1].numPrb = ue->ul.nPrb; + } +#endif + ueUl->subbandShare = 0; /* This reset will take care of + * all scheduler types */ + } + for (; count; lnk = lnk->next, --count) + { + RgSchUeCb *ue = (RgSchUeCb *)lnk->node; + rgSCHCmnUlRbAllocAddUeToLst(cell, ue, nonSchdLst); + ue->isMsg4PdcchWithCrnti = FALSE; + } + RETVOID; +} + +#ifdef TFU_UPGRADE +/*********************************************************** + * + * Func : rgSCHCmnUlMdfyGrntForCqi + * + * Desc : Modify UL Grant to consider presence of + * CQI along with PUSCH Data. + * + * Ret : + * + * Notes: + * - Scale down iTbs based on betaOffset and + * size of Acqi Size. + * - Optionally attempt to increase numSb by 1 + * if input payload size does not fit in due + * to reduced tbSz as a result of iTbsNew. + * + * File : + * + **********************************************************/ +#ifdef ANSI +PRIVATE S16 rgSCHCmnUlMdfyGrntForCqi +( +RgSchCellCb *cell, +RgSchUeCb *ue, +U32 maxRb, +U32 *numSb, +U8 *iTbs, +U32 hqSz, +U32 stepDownItbs, +U32 effTgt +) +#else +PRIVATE S16 rgSCHCmnUlMdfyGrntForCqi(cell, ue, maxRb, numSb, iTbs, hqSz, stepDownItbs, effTgt) +RgSchCellCb *cell; +RgSchUeCb *ue; +U32 maxRb; +U32 *numSb; +U8 *iTbs; +U32 hqSz; +U32 stepDownItbs; +U32 effTgt; +#endif +{ + RgSchCmnUlCell *cellUl = RG_SCH_CMN_GET_UL_CELL(ue->cell); + U32 nPrb; + U32 totREs; + U32 cqiRiREs; + U32 hqREs; + U32 remREsForPusch; + U32 bitsPerRe; + U32 tbSz; + U32 betaOffVal = ue->ul.betaOffstVal; + U32 cqiRiRptSz = ue->ul.cqiRiSz; + U32 betaOffHqVal = rgSchCmnBetaHqOffstTbl[ue->ul.betaHqOffst]; + U32 resNumSb = *numSb; + U32 puschEff = 1000; + U8 modOdr; + U8 iMcs; + Bool mdfyiTbsFlg = FALSE; + U8 resiTbs = *iTbs; + + TRC2(rgSCHCmnUlMdfyGrntForCqi) + + + do + { + iMcs = rgSCHCmnUlGetIMcsFrmITbs(resiTbs, RG_SCH_CMN_GET_UE_CTGY(ue)); + RG_SCH_UL_MCS_TO_MODODR(iMcs, modOdr); + if (RG_SCH_CMN_GET_UE_CTGY(ue) != CM_LTE_UE_CAT_5) + { + modOdr = RGSCH_MIN(RGSCH_QM_QPSK, modOdr); + } + else + { + modOdr = RGSCH_MIN(RGSCH_QM_64QAM, modOdr); + } + nPrb = resNumSb * cellUl->sbSize; + /* Restricting the minumum iTbs requried to modify to 10 */ + if ((nPrb >= maxRb) && (resiTbs <= 10)) + { + /* Could not accomodate ACQI */ + RETVALUE(RFAILED); + } + totREs = nPrb * RG_SCH_CMN_UL_NUM_RE_PER_RB(cellUl); + tbSz = rgTbSzTbl[0][resiTbs][nPrb-1]; + /* totalREs/tbSz = num of bits perRE. */ + cqiRiREs = (totREs * betaOffVal * cqiRiRptSz)/(1000 * tbSz); /* betaOffVal is represented + as parts per 1000 */ + hqREs = (totREs * betaOffHqVal * hqSz)/(1000 * tbSz); + if ((cqiRiREs + hqREs) < totREs) + { + remREsForPusch = totREs - cqiRiREs - hqREs; + bitsPerRe = (tbSz * 1000)/remREsForPusch; /* Multiplying by 1000 for Interger Oper */ + puschEff = bitsPerRe/modOdr; + } + if (puschEff < effTgt) + { + /* ensure resultant efficiency for PUSCH Data is within 0.93*/ + break; + } + else + { + /* Alternate between increasing SB or decreasing iTbs until eff is met */ + if (mdfyiTbsFlg == FALSE) + { + if (nPrb < maxRb) + { + resNumSb = resNumSb + 1; + } + mdfyiTbsFlg = TRUE; + } + else + { + if (resiTbs > 10) + { + resiTbs-= stepDownItbs; + } + mdfyiTbsFlg = FALSE; + } + } + }while (1); /* Loop breaks if efficency is met + or returns RFAILED if not able to meet the efficiency */ + + *numSb = resNumSb; + *iTbs = resiTbs; + + RETVALUE(ROK); +} +#endif +/*********************************************************** + * + * Func : rgSCHCmnUlRbAllocForUe + * + * Desc : Do uplink RB allocation for an UE. + * + * Ret : + * + * Notes: Note that as of now, for retx, maxRb + * is not considered. Alternatives, such + * as dropping retx if it crosses maxRb + * could be considered. + * + * File : + * + **********************************************************/ +#ifdef ANSI +PRIVATE S16 rgSCHCmnUlRbAllocForUe +( +RgSchCellCb *cell, +RgSchUlSf *sf, +RgSchUeCb *ue, +U8 maxRb, +RgSchUlHole *hole +) +#else +PRIVATE S16 rgSCHCmnUlRbAllocForUe(cell, sf, ue, maxRb, hole) +RgSchCellCb *cell; +RgSchUlSf *sf; +RgSchUeCb *ue; +U8 maxRb; +RgSchUlHole *hole; +#endif +{ + RgSchCmnUlCell *cellUl = RG_SCH_CMN_GET_UL_CELL(cell); + RgSchCmnUlUe *ueUl = RG_SCH_CMN_GET_UL_UE(ue, cell); + RgSchUlAlloc *alloc = NULLP; + U32 nPrb = 0; + U8 numVrbg; + U8 iMcs; + U8 iMcsCrnt; +#ifndef RG_5GTF + RgSchUlHqProcCb *proc = &ueUl->hqEnt.hqProcCb[cellUl->schdHqProcIdx]; +#else + RgSchUlHqProcCb *proc = NULLP; +#endif + RgSchPdcch *pdcch; + U32 reqVrbg; + U8 numVrbgTemp; +#ifdef RG_5GTF + TfuDciFormat dciFrmt; + U8 numLyr; +#endif + + TRC2(rgSCHCmnUlRbAllocForUe); +#ifdef RG_5GTF + rgSCHUhmGetAvlHqProc(cell, ue, &proc); + if (proc == NULLP) + { + //printf("UE [%d] HQ Proc unavailable\n", ue->ueId); + RETVALUE(RFAILED); + } +#endif + + if (ue->ue5gtfCb.rank == 2) + { + dciFrmt = TFU_DCI_FORMAT_A2; + numLyr = 2; + } + else + { + dciFrmt = TFU_DCI_FORMAT_A1; + numLyr = 1; + } + /* 5gtf TODO : To pass dci frmt to this function */ + pdcch = rgSCHCmnPdcchAllocCrntSf(cell, ue); + if(pdcch == NULLP) + { + RLOG_ARG1(L_DEBUG,DBG_CELLID,cell->cellId, + "rgSCHCmnUlRbAllocForUe(): Could not get PDCCH for CRNTI:%d",ue->ueId); + RETVALUE(RFAILED); + } + gUl5gtfPdcchSchd++; +#if defined (TENB_STATS) && defined (RG_5GTF) + cell->tenbStats->sch.ul5gtfPdcchSchd++; +#endif + + //TODO_SID using configured prb as of now + nPrb = ue->ue5gtfCb.maxPrb; + reqVrbg = nPrb/MAX_5GTF_VRBG_SIZE; + iMcs = ue->ue5gtfCb.mcs; //gSCHCmnUlGetIMcsFrmITbs(iTbs,ueCtg); + iMcsCrnt = iMcs; + numVrbg = reqVrbg; + + if((sf->sfBeamInfo[ue->ue5gtfCb.BeamId].vrbgStart > MAX_5GTF_VRBG) + || (sf->sfBeamInfo[ue->ue5gtfCb.BeamId].totVrbgAllocated > MAX_5GTF_VRBG)) + { + printf("5GTF_ERROR vrbg > 25 valstart = %d valalloc %d\n", sf->sfBeamInfo[ue->ue5gtfCb.BeamId].vrbgStart + , sf->sfBeamInfo[ue->ue5gtfCb.BeamId].totVrbgAllocated); + int *p=NULLP; + *p = 10; + } + + /*TODO_SID: Workaround for alloc. Currently alloc is ulsf based. To handle multiple beams, we need a different + design. Now alloc are formed based on MAX_5GTF_UE_SCH macro. */ + numVrbgTemp = MAX_5GTF_VRBG/MAX_5GTF_UE_SCH; + if(numVrbg) + { + alloc = rgSCHCmnUlSbAlloc(sf, numVrbgTemp,\ + hole); + } + if (alloc == NULLP) + { + RLOG_ARG2(L_ERROR,DBG_CELLID,cell->cellId, + "rgSCHCmnUlRbAllocForUe(): Could not get UlAlloc %d CRNTI:%d",numVrbg,ue->ueId); + rgSCHCmnPdcchRlsCrntSf(cell, pdcch); + RETVALUE(RFAILED); + } + gUl5gtfAllocAllocated++; +#if defined (TENB_STATS) && defined (RG_5GTF) + cell->tenbStats->sch.ul5gtfAllocAllocated++; +#endif + alloc->grnt.vrbgStart = sf->sfBeamInfo[ue->ue5gtfCb.BeamId].vrbgStart; + alloc->grnt.numVrbg = numVrbg; + alloc->grnt.numLyr = numLyr; + alloc->grnt.dciFrmt = dciFrmt; + + sf->sfBeamInfo[ue->ue5gtfCb.BeamId].vrbgStart += numVrbg; + sf->sfBeamInfo[ue->ue5gtfCb.BeamId].totVrbgAllocated += numVrbg; + + //rgSCHCmnUlAllocFillRbInfo(cell, sf, alloc); +#ifdef LTE_L2_MEAS + sf->totPrb += alloc->grnt.numRb; + ue->ul.nPrb = alloc->grnt.numRb; +#endif + if (ue->csgMmbrSta != TRUE) + { + cellUl->ncsgPrbCnt += alloc->grnt.numRb; + } + cellUl->totPrbCnt += (alloc->grnt.numVrbg * MAX_5GTF_VRBG_SIZE); + alloc->pdcch = pdcch; + alloc->grnt.iMcs = iMcs; + alloc->grnt.iMcsCrnt = iMcsCrnt; + alloc->grnt.hop = 0; + /* Initial Num RBs support for UCI on PUSCH */ +#ifdef TFU_UPGRADE + ue->initNumRbs = (alloc->grnt.numVrbg * MAX_5GTF_VRBG_SIZE); +#endif + alloc->forMsg3 = FALSE; + //RGSCH_ARRAY_BOUND_CHECK(cell->instIdx, rgTb5gtfSzTbl[0], (iTbs)); + + //ueUl->alloc.allocdBytes = rgTbSzTbl[0][iTbs][alloc->grnt.numRb-1] / 8; + /* TODO_SID Allocating based on configured MCS as of now. + Currently for format A2. When doing multi grp per tti, need to update this. */ + ueUl->alloc.allocdBytes = (rgSch5gtfTbSzTbl[iMcs]/8) * ue->ue5gtfCb.rank; + + alloc->grnt.datSz = ueUl->alloc.allocdBytes; + //TODO_SID Need to check mod order. + RG_SCH_CMN_TBS_TO_MODODR(iMcs, alloc->grnt.modOdr); + //alloc->grnt.modOdr = 6; + alloc->grnt.isRtx = FALSE; + + alloc->grnt.rbAssign = rgSCHCmnCalcRiv(MAX_5GTF_VRBG, alloc->grnt.vrbgStart, alloc->grnt.numVrbg); + alloc->grnt.SCID = 0; + alloc->grnt.xPUSCHRange = MAX_5GTF_XPUSCH_RANGE; + alloc->grnt.PMI = 0; + alloc->grnt.uciOnxPUSCH = 0; + alloc->grnt.hqProcId = proc->procId; + + alloc->hqProc = proc; + alloc->hqProc->ulSfIdx = cellUl->schdIdx; + alloc->ue = ue; + /*commenting to retain the rnti used for transmission SPS/c-rnti */ + alloc->rnti = ue->ueId; + ueUl->alloc.alloc = alloc; + /*rntiwari-Adding the debug for generating the graph.*/ + /* No grant attr recorded now */ + RETVALUE(ROK); +} + +/*********************************************************** + * + * Func : rgSCHCmnUlRbAllocAddUeToLst + * + * Desc : Add UE to list (scheduled/non-scheduled list) + * for UL RB allocation information. + * + * Ret : + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PUBLIC Void rgSCHCmnUlRbAllocAddUeToLst +( +RgSchCellCb *cell, +RgSchUeCb *ue, +CmLListCp *lst +) +#else +PUBLIC Void rgSCHCmnUlRbAllocAddUeToLst(cell, ue, lst) +RgSchCellCb *cell; +RgSchUeCb *ue; +CmLListCp *lst; +#endif +{ + RgSchCmnUlUe *ueUl = RG_SCH_CMN_GET_UL_UE(ue,cell); + TRC2(rgSCHCmnUlRbAllocAddUeToLst); + UNUSED(cell); + + gUl5gtfUeRbAllocDone++; +#if defined (TENB_STATS) && defined (RG_5GTF) + cell->tenbStats->sch.ul5gtfUeRbAllocDone++; +#endif + cmLListAdd2Tail(lst, &ueUl->alloc.schdLstLnk); + ueUl->alloc.schdLstLnk.node = (PTR)ue; +} + + +/** + * @brief This function Processes the Final Allocations + * made by the RB Allocator against the requested. + * + * @details + * + * Function: rgSCHCmnUlAllocFnlz + * Purpose: This function Processes the Final Allocations + * made by the RB Allocator against the requested. + * + * Invoked by: Common Scheduler + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchCmnUlRbAllocInfo *allocInfo + * @return Void + * + **/ +#ifdef ANSI +PRIVATE Void rgSCHCmnUlAllocFnlz +( +RgSchCellCb *cell, +RgSchCmnUlRbAllocInfo *allocInfo +) +#else +PRIVATE Void rgSCHCmnUlAllocFnlz(cell, allocInfo) +RgSchCellCb *cell; +RgSchCmnUlRbAllocInfo *allocInfo; +#endif +{ + RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell); + TRC2(rgSCHCmnUlAllocFnlz); + + /* call scheduler specific Finalization */ + cellSch->apisUl->rgSCHUlAllocFnlz(cell, allocInfo); + + RETVOID; +} + +/** + * @brief This function Processes the Final Allocations + * made by the RB Allocator against the requested. + * + * @details + * + * Function: rgSCHCmnDlAllocFnlz + * Purpose: This function Processes the Final Allocations + * made by the RB Allocator against the requested. + * + * Invoked by: Common Scheduler + * + * @param[in] RgSchCellCb *cell + * @return Void + * + **/ +#ifdef ANSI +PUBLIC Void rgSCHCmnDlAllocFnlz +( +RgSchCellCb *cell +) +#else +PUBLIC Void rgSCHCmnDlAllocFnlz(cell) +RgSchCellCb *cell; +#endif +{ + RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell); + RgSchCmnDlRbAllocInfo *allocInfo = &cellSch->allocInfo; + + TRC2(rgSCHCmnDlAllocFnlz); + + rgSCHCmnDlCcchRetxFnlz(cell, allocInfo); + rgSCHCmnDlCcchTxFnlz(cell, allocInfo); +#ifdef RGR_V1 + /* Added below functions for handling CCCH SDU transmission received + * after + * * guard timer expiry*/ + rgSCHCmnDlCcchSduRetxFnlz(cell, allocInfo); + rgSCHCmnDlCcchSduTxFnlz(cell, allocInfo); +#endif + rgSCHCmnDlRaRspFnlz(cell, allocInfo); + /* call scheduler specific Finalization */ + cellSch->apisDl->rgSCHDlAllocFnlz(cell, allocInfo); + + /* Stack Crash problem for TRACE5 Changes. Added the return below */ + RETVOID; + +} + +#ifdef RG_UNUSED +/** + * @brief Update an uplink subframe. + * + * @details + * + * Function : rgSCHCmnUlUpdSf + * + * For each allocation + * - if no more tx needed + * - Release allocation + * - else + * - Perform retransmission + * + * @param[in] RgSchUlSf *sf + * @return Void + **/ +#ifdef ANSI +PRIVATE Void rgSCHCmnUlUpdSf +( +RgSchCellCb *cell, +RgSchCmnUlRbAllocInfo *allocInfo, +RgSchUlSf *sf +) +#else +PRIVATE Void rgSCHCmnUlUpdSf(cell, allocInfo, sf) +RgSchCellCb *cell; +RgSchCmnUlRbAllocInfo *allocInfo; +RgSchUlSf *sf; +#endif +{ + CmLList *lnk; + TRC2(rgSCHCmnUlUpdSf); + + while ((lnk = sf->allocs.first)) + { + RgSchUlAlloc *alloc = (RgSchUlAlloc *)lnk->node; + lnk = lnk->next; + + if ((alloc->hqProc->rcvdCrcInd) || (alloc->hqProc->remTx == 0)) + { + } + else + { + /* If need to handle all retx together, run another loop separately */ + rgSCHCmnUlHndlAllocRetx(cell, allocInfo, sf, alloc); + } + rgSCHCmnUlRlsUlAlloc(cell, sf, alloc); + } + + /* By this time, all allocs would have been cleared and + * SF is reset to be made ready for new allocations. */ + rgSCHCmnUlSfReset(cell, sf); + /* In case there are timing problems due to msg3 + * allocations being done in advance, (which will + * probably happen with the current FDD code that + * handles 8 subframes) one solution + * could be to hold the (recent) msg3 allocs in a separate + * list, and then possibly add that to the actual + * list later. So at this time while allocations are + * traversed, the recent msg3 ones are not seen. Anytime after + * this (a good time is when the usual allocations + * are made), msg3 allocations could be transferred to the + * normal list. Not doing this now as it is assumed + * that incorporation of TDD shall take care of this. + */ + + + RETVOID; +} + +/** + * @brief Handle uplink allocation for retransmission. + * + * @details + * + * Function : rgSCHCmnUlHndlAllocRetx + * + * Processing Steps: + * - Add to queue for retx. + * - Do not release here, release happends as part + * of the loop that calls this function. + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchCmnUlRbAllocInfo *allocInfo + * @param[in] RgSchUlSf *sf + * @param[in] RgSchUlAlloc *alloc + * @return Void + **/ +#ifdef ANSI +PRIVATE Void rgSCHCmnUlHndlAllocRetx +( +RgSchCellCb *cell, +RgSchCmnUlRbAllocInfo *allocInfo, +RgSchUlSf *sf, +RgSchUlAlloc *alloc +) +#else +PRIVATE Void rgSCHCmnUlHndlAllocRetx(cell, allocInfo, sf, alloc) +RgSchCellCb *cell; +RgSchCmnUlRbAllocInfo *allocInfo; +RgSchUlSf *sf; +RgSchUlAlloc *alloc; +#endif +{ + U32 bytes; + RgSchCmnUlUe *ueUl; + TRC2(rgSCHCmnUlHndlAllocRetx); + bytes = \ + rgTbSzTbl[0][rgSCHCmnUlGetITbsFrmIMcs(alloc->grnt.iMcs)]\ + [alloc->grnt.numRb-1]/8; + if (!alloc->forMsg3) + { + ueUl = RG_SCH_CMN_GET_UL_UE(alloc->ue); + ueUl->alloc.reqBytes = bytes; + rgSCHUhmRetx(alloc->hqProc); + rgSCHCmnUlAdd2RetxUeLst(allocInfo, alloc->ue); + } + else + { + /* RACHO msg3 retx handling. Part of RACH procedure changes. */ + retxAlloc = rgSCHCmnUlGetUlAlloc(cell, sf, alloc->numSb); + if (retxAlloc == NULLP) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId, + "rgSCHCmnUlRbAllocForUe():Could not get UlAlloc for msg3Retx RNTI:%d", + alloc->rnti); + RETVOID; + } + retxAlloc->grnt.iMcs = alloc->grnt.iMcs; + retxAlloc->grnt.iMcsCrnt = rgSchCmnUlRvIdxToIMcsTbl\ + [alloc->hqProc->rvIdx]; + retxAlloc->grnt.nDmrs = 0; + retxAlloc->grnt.hop = 0; + retxAlloc->grnt.delayBit = 0; + retxAlloc->rnti = alloc->rnti; + retxAlloc->ue = NULLP; + retxAlloc->pdcch = FALSE; + retxAlloc->forMsg3 = TRUE; + retxAlloc->raCb = alloc->raCb; + retxAlloc->hqProc = alloc->hqProc; + rgSCHUhmRetx(retxAlloc->hqProc); + } + RETVOID; +} +#endif + +/** + * @brief Uplink Scheduling Handler. + * + * @details + * + * Function: rgSCHCmnUlAlloc + * Purpose: This function Handles Uplink Scheduling. + * + * Invoked by: Common Scheduler + * + * @param[in] RgSchCellCb *cell + * @return Void + **/ +/* ccpu00132653- The definition of this function made common for TDD and FDD*/ +#ifdef ANSI +PRIVATE Void rgSCHCmnUlAlloc +( +RgSchCellCb *cell +) +#else +PRIVATE Void rgSCHCmnUlAlloc(cell) +RgSchCellCb *cell; +#endif +{ + RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell); + RgSchCmnUlCell *cellUl = RG_SCH_CMN_GET_UL_CELL(cell); + RgSchCmnDlCell *cellDl = RG_SCH_CMN_GET_DL_CELL(cell); + RgSchCmnUlRbAllocInfo allocInfo; + RgSchCmnUlRbAllocInfo *allocInfoRef = &allocInfo; +#ifdef RG_5GTF + U8 idx; + +#endif + + TRC2(rgSCHCmnUlAlloc); + + /* Initializing RgSchCmnUlRbAllocInfo structure */ + rgSCHCmnInitUlRbAllocInfo(allocInfoRef); + + /* Get Uplink Subframe */ + allocInfoRef->sf = &cellUl->ulSfArr[cellUl->schdIdx]; +#ifdef LTE_L2_MEAS + /* initializing the UL PRB count */ + allocInfoRef->sf->totPrb = 0; +#endif + +#ifdef LTEMAC_SPS + rgSCHCmnSpsUlTti(cell, allocInfoRef); +#endif + + if(*allocInfoRef->sf->allocCountRef == 0) + { + RgSchUlHole *hole; + + if ((hole = rgSCHUtlUlHoleFirst(allocInfoRef->sf)) != NULLP) + { + /* Sanity check of holeDb */ + if (allocInfoRef->sf->holeDb->count == 1 && hole->start == 0) + { + hole->num = cell->dynCfiCb.bwInfo[cellDl->currCfi].numSb; + /* Re-Initialize available subbands because of CFI change*/ + allocInfoRef->sf->availSubbands = cell->dynCfiCb.\ + bwInfo[cellDl->currCfi].numSb; + /*Currently initializing 5gtf ulsf specific initialization here. + need to do at proper place */ +#ifdef RG_5GTF + allocInfoRef->sf->numGrpPerTti = cell->cell5gtfCb.ueGrpPerTti; + allocInfoRef->sf->numUePerGrp = cell->cell5gtfCb.uePerGrpPerTti; + for(idx = 0; idx < MAX_5GTF_BEAMS; idx++) + { + allocInfoRef->sf->sfBeamInfo[idx].totVrbgAllocated = 0; + allocInfoRef->sf->sfBeamInfo[idx].totVrbgRequired = 0; + allocInfoRef->sf->sfBeamInfo[idx].vrbgStart = 0; + } +#endif + } + else + { + RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId, + "Error! holeDb sanity check failed"); + } + } + } + + /* Fix: Adaptive re-transmissions prioritised over other transmissions */ + /* perform adaptive retransmissions */ + rgSCHCmnUlSfReTxAllocs(cell, allocInfoRef->sf); + + g5gtfTtiCnt++; + + /* Fix: syed Adaptive Msg3 Retx crash. Release all + Harq processes for which adap Retx failed, to avoid + blocking. This step should be done before New TX + scheduling to make hqProc available. Right now we + dont check if proc is in adap Retx list for considering + it to be available. But now with this release that + functionality would be correct. */ +#ifndef RG_5GTF + rgSCHCmnUlSfRlsRetxProcs(cell, allocInfoRef->sf); +#endif + + /* Specific UL scheduler to perform UE scheduling */ + cellSch->apisUl->rgSCHUlSched(cell, allocInfoRef); + + /* Call UL RB allocator module */ + rgSCHCmnAllocUlRb(cell, allocInfoRef); + + /* Do group power control for PUSCH */ + rgSCHCmnGrpPwrCntrlPusch(cell, allocInfoRef->sf); + + cell->sc.apis->rgSCHDrxStrtInActvTmrInUl(cell); + + rgSCHCmnUlAllocFnlz(cell, allocInfoRef); + if(5000 == g5gtfTtiCnt) + { + ul5gtfsidDlAlreadyMarkUl = 0; + ul5gtfsidDlSchdPass = 0; + ul5gtfsidUlMarkUl = 0; + ul5gtfTotSchdCnt = 0; + g5gtfTtiCnt = 0; + } + + RETVOID; +} + +/** + * @brief send Subframe Allocations. + * + * @details + * + * Function: rgSCHCmnSndCnsldtInfo + * Purpose: Send the scheduled + * allocations to MAC for StaInd generation to Higher layers and + * for MUXing. PST's RgInfSfAlloc to MAC instance. + * + * Invoked by: Common Scheduler + * + * @param[in] RgSchCellCb *cell + * @return Void + **/ +#ifdef ANSI +PUBLIC Void rgSCHCmnSndCnsldtInfo +( +RgSchCellCb *cell +) +#else +PUBLIC Void rgSCHCmnSndCnsldtInfo(cell) +RgSchCellCb *cell; +#endif +{ + RgInfSfAlloc *subfrmAlloc; + Pst pst; + RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell); + + TRC2(rgSCHCmnSndCnsldtInfo); + + subfrmAlloc = &(cell->sfAllocArr[cell->crntSfIdx]); + + /* Send the allocations to MAC for MUXing */ + rgSCHUtlGetPstToLyr(&pst, &rgSchCb[cell->instIdx], cell->macInst); + subfrmAlloc->cellId = cell->cellId; + /* Populate the List of UEs needing PDB-based Flow control */ + cellSch->apisDl->rgSCHDlFillFlwCtrlInfo(cell, subfrmAlloc); +#ifdef LTE_L2_MEAS + if((subfrmAlloc->rarInfo.numRaRntis) || +#ifdef EMTC_ENABLE + (subfrmAlloc->emtcInfo.rarInfo.numRaRntis) || + (subfrmAlloc->emtcInfo.cmnLcInfo.bitMask) || + (subfrmAlloc->emtcInfo.ueInfo.numUes) || +#endif + (subfrmAlloc->ueInfo.numUes) || + (subfrmAlloc->cmnLcInfo.bitMask) || + (subfrmAlloc->ulUeInfo.numUes) || + (subfrmAlloc->flowCntrlInfo.numUes)) +#else + if((subfrmAlloc->rarInfo.numRaRntis) || +#ifdef EMTC_ENABLE + (subfrmAlloc->emtcInfo.rarInfo.numRaRntis) || + (subfrmAlloc->emtcInfo.cmnLcInfo.bitMask) || + (subfrmAlloc->emtcInfo.ueInfo.numUes) || +#endif + (subfrmAlloc->ueInfo.numUes) || + (subfrmAlloc->cmnLcInfo.bitMask) || + (subfrmAlloc->flowCntrlInfo.numUes)) +#endif + { + RgSchMacSfAlloc(&pst, subfrmAlloc); + } +#ifndef LTE_TDD + cell->crntSfIdx = (cell->crntSfIdx + 1) % RGSCH_NUM_SUB_FRAMES; +#else + cell->crntSfIdx = (cell->crntSfIdx + 1) % RGSCH_SF_ALLOC_SIZE; +#endif + + RETVOID; +} +/** + * @brief Consolidate Subframe Allocations. + * + * @details + * + * Function: rgSCHCmnCnsldtSfAlloc + * Purpose: Consolidate Subframe Allocations. + * + * Invoked by: Common Scheduler + * + * @param[in] RgSchCellCb *cell + * @return Void + **/ +#ifdef ANSI +PUBLIC Void rgSCHCmnCnsldtSfAlloc +( +RgSchCellCb *cell +) +#else +PUBLIC Void rgSCHCmnCnsldtSfAlloc(cell) +RgSchCellCb *cell; +#endif +{ + RgInfSfAlloc *subfrmAlloc; + CmLteTimingInfo frm; + RgSchDlSf *dlSf; + CmLListCp dlDrxInactvTmrLst; + CmLListCp dlInActvLst; + CmLListCp ulInActvLst; + RgSchCmnCell *cellSch = NULLP; + + TRC2(rgSCHCmnCnsldtSfAlloc); + + cmLListInit(&dlDrxInactvTmrLst); + cmLListInit(&dlInActvLst); + cmLListInit(&ulInActvLst); + + subfrmAlloc = &(cell->sfAllocArr[cell->crntSfIdx]); + + /* Get Downlink Subframe */ + frm = cell->crntTime; + RGSCH_INCR_SUB_FRAME(frm, RG_SCH_CMN_DL_DELTA); + dlSf = rgSCHUtlSubFrmGet(cell, frm); + + /* Fill the allocation Info */ + rgSCHUtlFillRgInfRarInfo(dlSf, subfrmAlloc, cell); + + /* CA dev Start */ + rgSCHUtlFillRgInfUeInfo(dlSf, cell, &dlDrxInactvTmrLst, + &dlInActvLst, &ulInActvLst); +#ifdef RG_PFS_STATS + cell->totalPrb += dlSf->bwAssigned; +#endif + /* Mark the following Ues inactive for UL*/ + cellSch = RG_SCH_CMN_GET_CELL(cell); + + /* Calling Scheduler specific function with DRX inactive UE list*/ + cellSch->apisUl->rgSCHUlInactvtUes(cell, &ulInActvLst); + cellSch->apisDl->rgSCHDlInactvtUes(cell, &dlInActvLst); + + /* CA dev End */ + /*re/start DRX inactivity timer for the UEs*/ + (Void)rgSCHDrxStrtInActvTmr(cell,&dlDrxInactvTmrLst,RG_SCH_DRX_DL); + + RETVOID; +} + +/** + * @brief Initialize the DL Allocation Information Structure. + * + * @details + * + * Function: rgSCHCmnInitDlRbAllocInfo + * Purpose: Initialize the DL Allocation Information Structure. + * + * Invoked by: Common Scheduler + * + * @param[out] RgSchCmnDlRbAllocInfo *allocInfo + * @return Void + **/ +#ifdef ANSI +PRIVATE Void rgSCHCmnInitDlRbAllocInfo +( +RgSchCmnDlRbAllocInfo *allocInfo +) +#else +PRIVATE Void rgSCHCmnInitDlRbAllocInfo(allocInfo) +RgSchCmnDlRbAllocInfo *allocInfo; +#endif +{ + TRC2(rgSCHCmnInitDlRbAllocInfo); + cmMemset((U8 *)&allocInfo->pcchAlloc, (U8)0, sizeof(RgSchDlRbAlloc)); + cmMemset((U8 *)&allocInfo->bcchAlloc, (U8)0, sizeof(RgSchDlRbAlloc)); + cmMemset((U8 *)allocInfo->raRspAlloc, (U8)0, + RG_SCH_CMN_MAX_CMN_PDCCH*sizeof(RgSchDlRbAlloc)); + + allocInfo->msg4Alloc.msg4DlSf = NULLP; + cmLListInit(&allocInfo->msg4Alloc.msg4TxLst); + cmLListInit(&allocInfo->msg4Alloc.msg4RetxLst); + cmLListInit(&allocInfo->msg4Alloc.schdMsg4TxLst); + cmLListInit(&allocInfo->msg4Alloc.schdMsg4RetxLst); + cmLListInit(&allocInfo->msg4Alloc.nonSchdMsg4TxLst); + cmLListInit(&allocInfo->msg4Alloc.nonSchdMsg4RetxLst); +#ifdef RGR_V1 + allocInfo->ccchSduAlloc.ccchSduDlSf = NULLP; + cmLListInit(&allocInfo->ccchSduAlloc.ccchSduTxLst); + cmLListInit(&allocInfo->ccchSduAlloc.ccchSduRetxLst); + cmLListInit(&allocInfo->ccchSduAlloc.schdCcchSduTxLst); + cmLListInit(&allocInfo->ccchSduAlloc.schdCcchSduRetxLst); + cmLListInit(&allocInfo->ccchSduAlloc.nonSchdCcchSduTxLst); + cmLListInit(&allocInfo->ccchSduAlloc.nonSchdCcchSduRetxLst); +#endif + + allocInfo->dedAlloc.dedDlSf = NULLP; + cmLListInit(&allocInfo->dedAlloc.txHqPLst); + cmLListInit(&allocInfo->dedAlloc.retxHqPLst); + cmLListInit(&allocInfo->dedAlloc.schdTxHqPLst); + cmLListInit(&allocInfo->dedAlloc.schdRetxHqPLst); + cmLListInit(&allocInfo->dedAlloc.nonSchdTxHqPLst); + cmLListInit(&allocInfo->dedAlloc.nonSchdRetxHqPLst); + + cmLListInit(&allocInfo->dedAlloc.txRetxHqPLst); + cmLListInit(&allocInfo->dedAlloc.schdTxRetxHqPLst); + cmLListInit(&allocInfo->dedAlloc.nonSchdTxRetxHqPLst); +#ifdef LTEMAC_SPS + cmLListInit(&allocInfo->dedAlloc.txSpsHqPLst); + cmLListInit(&allocInfo->dedAlloc.retxSpsHqPLst); + cmLListInit(&allocInfo->dedAlloc.schdTxSpsHqPLst); + cmLListInit(&allocInfo->dedAlloc.schdRetxSpsHqPLst); + cmLListInit(&allocInfo->dedAlloc.nonSchdTxSpsHqPLst); + cmLListInit(&allocInfo->dedAlloc.nonSchdRetxSpsHqPLst); +#endif + +#ifdef LTE_ADV + rgSCHLaaCmnInitDlRbAllocInfo (allocInfo); +#endif + + cmLListInit(&allocInfo->dedAlloc.errIndTxHqPLst); + cmLListInit(&allocInfo->dedAlloc.schdErrIndTxHqPLst); + cmLListInit(&allocInfo->dedAlloc.nonSchdErrIndTxHqPLst); + RETVOID; +} + +/** + * @brief Initialize the UL Allocation Information Structure. + * + * @details + * + * Function: rgSCHCmnInitUlRbAllocInfo + * Purpose: Initialize the UL Allocation Information Structure. + * + * Invoked by: Common Scheduler + * + * @param[out] RgSchCmnUlRbAllocInfo *allocInfo + * @return Void + **/ +#ifdef ANSI +PUBLIC Void rgSCHCmnInitUlRbAllocInfo +( +RgSchCmnUlRbAllocInfo *allocInfo +) +#else +PUBLIC Void rgSCHCmnInitUlRbAllocInfo(allocInfo) +RgSchCmnUlRbAllocInfo *allocInfo; +#endif +{ + TRC2(rgSCHCmnInitUlRbAllocInfo); + allocInfo->sf = NULLP; + cmLListInit(&allocInfo->contResLst); + cmLListInit(&allocInfo->schdContResLst); + cmLListInit(&allocInfo->nonSchdContResLst); + cmLListInit(&allocInfo->ueLst); + cmLListInit(&allocInfo->schdUeLst); + cmLListInit(&allocInfo->nonSchdUeLst); + + RETVOID; +} + +/** + * @brief Scheduling for PUCCH group power control. + * + * @details + * + * Function: rgSCHCmnGrpPwrCntrlPucch + * Purpose: This function does group power control for PUCCH + * corresponding to the subframe for which DL UE allocations + * have happended. + * + * Invoked by: Common Scheduler + * + * @param[in] RgSchCellCb *cell + * @return Void + **/ +#ifdef ANSI +PRIVATE Void rgSCHCmnGrpPwrCntrlPucch +( +RgSchCellCb *cell, +RgSchDlSf *dlSf +) +#else +PRIVATE Void rgSCHCmnGrpPwrCntrlPucch(cell, dlSf) +RgSchCellCb *cell; +RgSchDlSf *dlSf; +#endif +{ + TRC2(rgSCHCmnGrpPwrCntrlPucch); + + rgSCHPwrGrpCntrlPucch(cell, dlSf); + + RETVOID; +} + +/** + * @brief Scheduling for PUSCH group power control. + * + * @details + * + * Function: rgSCHCmnGrpPwrCntrlPusch + * Purpose: This function does group power control, for + * the subframe for which UL allocation has (just) happened. + * + * Invoked by: Common Scheduler + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUlSf *ulSf + * @return Void + **/ +#ifdef ANSI +PRIVATE Void rgSCHCmnGrpPwrCntrlPusch +( +RgSchCellCb *cell, +RgSchUlSf *ulSf +) +#else +PRIVATE Void rgSCHCmnGrpPwrCntrlPusch(cell, ulSf) +RgSchCellCb *cell; +RgSchUlSf *ulSf; +#endif +{ + /*removed unused variable *cellSch*/ + CmLteTimingInfo frm; + RgSchDlSf *dlSf; + + TRC2(rgSCHCmnGrpPwrCntrlPusch); + + /* Got to pass DL SF corresponding to UL SF, so get that first. + * There is no easy way of getting dlSf by having the RgSchUlSf*, + * so use the UL delta from current time to get the DL SF. */ + frm = cell->crntTime; + +#ifdef EMTC_ENABLE + if(cell->emtcEnable == TRUE) + { + RGSCH_INCR_SUB_FRAME_EMTC(frm, TFU_DLCNTRL_DLDELTA); + } + else +#endif + { + RGSCH_INCR_SUB_FRAME(frm, TFU_DLCNTRL_DLDELTA); + } + /* Del filling of dl.time */ + dlSf = rgSCHUtlSubFrmGet(cell, frm); + + rgSCHPwrGrpCntrlPusch(cell, dlSf, ulSf); + + RETVOID; +} + +/* Fix: syed align multiple UEs to refresh at same time */ +/*********************************************************** + * + * Func : rgSCHCmnApplyUeRefresh + * + * Desc : Apply UE refresh in CMN and Specific + * schedulers. Data rates and corresponding + * scratchpad variables are updated. + * + * Ret : + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PRIVATE S16 rgSCHCmnApplyUeRefresh +( +RgSchCellCb *cell, +RgSchUeCb *ue +) +#else +PRIVATE S16 rgSCHCmnApplyUeRefresh(cell, ue) +RgSchCellCb *cell; +RgSchUeCb *ue; +#endif +{ + RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell); + U32 effGbrBsr = 0; + U32 effNonGbrBsr = 0; + U32 lcgId; + + TRC2(rgSCHCmnApplyUeRefresh); + + /* Reset the refresh cycle variableCAP */ + ue->ul.effAmbr = ue->ul.cfgdAmbr; + + for (lcgId = 1; lcgId < RGSCH_MAX_LCG_PER_UE; lcgId++) + { + if (RGSCH_LCG_ISCFGD(&ue->ul.lcgArr[lcgId])) + { + RgSchCmnLcg *cmnLcg = ((RgSchCmnLcg *)(ue->ul.lcgArr[lcgId].sch)); + + if (RGSCH_IS_GBR_BEARER(cmnLcg->cfgdGbr)) + { + cmnLcg->effGbr = cmnLcg->cfgdGbr; + cmnLcg->effDeltaMbr = cmnLcg->deltaMbr; + cmnLcg->bs = RGSCH_MIN(cmnLcg->reportedBs, cmnLcg->effGbr + cmnLcg->effDeltaMbr); + /* Considering GBR LCG will be prioritised by UE */ + effGbrBsr += cmnLcg->bs; + }/* Else no remaing BS so nonLcg0 will be updated when BSR will be received */ + else + { + effNonGbrBsr += cmnLcg->reportedBs; + cmnLcg->bs = RGSCH_MIN(cmnLcg->reportedBs, ue->ul.effAmbr); + } + } + } + effNonGbrBsr = RGSCH_MIN(effNonGbrBsr,ue->ul.effAmbr); + ue->ul.nonGbrLcgBs = effNonGbrBsr; + + ue->ul.nonLcg0Bs = effGbrBsr + effNonGbrBsr; + ue->ul.effBsr = ue->ul.nonLcg0Bs +\ + ((RgSchCmnLcg *)(ue->ul.lcgArr[0].sch))->bs; + + + /* call scheduler specific event handlers + * for refresh timer expiry */ + cellSch->apisUl->rgSCHUlUeRefresh(cell, ue); + cellSch->apisDl->rgSCHDlUeRefresh(cell, ue); + + RETVALUE(ROK); +} + +/*********************************************************** + * + * Func : rgSCHCmnTmrExpiry + * + * Desc : Adds an UE to refresh queue, so that the UE is + * periodically triggered to refresh it's GBR and + * AMBR values. + * + * Ret : + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PRIVATE S16 rgSCHCmnTmrExpiry +( +PTR cb, /* Pointer to timer control block */ +S16 tmrEvnt /* Timer Event */ +) +#else +PRIVATE S16 rgSCHCmnTmrExpiry(cb, tmrEvnt) +PTR cb; /* Pointer to timer control block */ +S16 tmrEvnt; /* Timer Event */ +#endif +{ + RgSchUeCb *ue = (RgSchUeCb *)cb; + RgSchCellCb *cell = ue->cell; +#if (ERRCLASS & ERRCLS_DEBUG) +#endif + + TRC2(rgSCHCmnTmrExpiry); + +#if (ERRCLASS & ERRCLS_DEBUG) + if (tmrEvnt != RG_SCH_CMN_EVNT_UE_REFRESH) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,"rgSCHCmnTmrExpiry(): Invalid " + "timer event CRNTI:%d",ue->ueId); + RETVALUE(RFAILED); + } +#else + UNUSED(tmrEvnt); +#endif + + rgSCHCmnApplyUeRefresh(cell, ue); + + rgSCHCmnAddUeToRefreshQ(cell, ue, RG_SCH_CMN_REFRESH_TIME); + + RETVALUE(ROK); +} + +/*********************************************************** + * + * Func : rgSCHCmnTmrProc + * + * Desc : Timer entry point per cell. Timer + * processing is triggered at every frame boundary + * (every 10 ms). + * + * Ret : + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PRIVATE S16 rgSCHCmnTmrProc +( +RgSchCellCb *cell +) +#else +PRIVATE S16 rgSCHCmnTmrProc(cell) +RgSchCellCb *cell; +#endif +{ + RgSchCmnDlCell *cmnDlCell = RG_SCH_CMN_GET_DL_CELL(cell); + RgSchCmnUlCell *cmnUlCell = RG_SCH_CMN_GET_UL_CELL(cell); + /* Moving the assignment of scheduler pointer + to available scope for optimization */ + TRC2(rgSCHCmnTmrProc); + + if ((cell->crntTime.subframe % RGSCH_NUM_SUB_FRAMES_5G) == 0) + { + /* Reset the counters periodically */ + if ((cell->crntTime.sfn % RG_SCH_CMN_CSG_REFRESH_TIME) == 0) + { + RG_SCH_RESET_HCSG_DL_PRB_CNTR(cmnDlCell); + RG_SCH_RESET_HCSG_UL_PRB_CNTR(cmnUlCell); + } + if ((cell->crntTime.sfn % RG_SCH_CMN_OVRLDCTRL_REFRESH_TIME) == 0) + { + + cell->measurements.ulTpt = ((cell->measurements.ulTpt * 95) + ( cell->measurements.ulBytesCnt * 5))/100; + cell->measurements.dlTpt = ((cell->measurements.dlTpt * 95) + ( cell->measurements.dlBytesCnt * 5))/100; + + rgSCHUtlCpuOvrLdAdjItbsCap(cell); + /* reset cell level tpt measurements for next cycle */ + cell->measurements.ulBytesCnt = 0; + cell->measurements.dlBytesCnt = 0; + } + /* Comparing with Zero instead of % is being done for efficiency. + * If Timer resolution changes then accordingly update the + * macro RG_SCH_CMN_REFRESH_TIMERES */ + RgSchCmnCell *sched = RG_SCH_CMN_GET_CELL(cell); + cmPrcTmr(&sched->tmrTqCp, sched->tmrTq, (PFV)rgSCHCmnTmrExpiry); + } + + RETVALUE(ROK); +} + + +/*********************************************************** + * + * Func : rgSchCmnUpdCfiVal + * + * Desc : Update the CFI value if CFI switch was done + * + * Ret : + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PRIVATE Void rgSchCmnUpdCfiVal +( +RgSchCellCb *cell, +U8 delta +) +#else +PRIVATE Void rgSchCmnUpdCfiVal(cell, delta) +RgSchCellCb *cell; +U8 delta; +#endif +{ + RgSchDlSf *dlSf; + CmLteTimingInfo pdsch; + RgSchCmnDlCell *cellCmnDl = RG_SCH_CMN_GET_DL_CELL(cell); + U8 dlIdx; +#ifdef LTE_TDD + U8 mPhich; + RgSchDlSf *tddSf; + U8 idx; + U8 splSfCfi = 0; +#endif + + TRC2(rgSchCmnUpdCfiVal); + + pdsch = cell->crntTime; + RGSCH_INCR_SUB_FRAME(pdsch, delta); + dlSf = rgSCHUtlSubFrmGet(cell, pdsch); + /* Fix for DCFI FLE issue: when DL delta is 1 and UL delta is 0 and CFI + *change happens in that SF then UL PDCCH allocation happens with old CFI + *but CFI in control Req goes updated one since it was stored in the CELL + */ + dlSf->pdcchInfo.currCfi = cellCmnDl->currCfi; + if(cell->dynCfiCb.pdcchSfIdx != 0xFF) + { +#ifdef LTE_TDD + dlIdx = rgSCHUtlGetDlSfIdx(cell, &pdsch); +#else + dlIdx = (((pdsch.sfn & 1) * RGSCH_NUM_SUB_FRAMES) + (pdsch.subframe % RGSCH_NUM_SUB_FRAMES)); + RGSCH_ARRAY_BOUND_CHECK(cell->instIdx, cell->subFrms, dlIdx); +#endif + /* If current downlink subframe index is same as pdcch SF index, + * perform the switching of CFI in this subframe */ + if(cell->dynCfiCb.pdcchSfIdx == dlIdx) + { + cellCmnDl->currCfi = cellCmnDl->newCfi; + cell->dynCfiCb.pdcchSfIdx = 0xFF; + + /* Updating the nCce value based on the new CFI */ +#ifdef LTE_TDD + splSfCfi = cellCmnDl->newCfi; + for(idx = 0; idx < cell->numDlSubfrms; idx++) + { + tddSf = cell->subFrms[idx]; + + mPhich = rgSchTddPhichMValTbl[cell->ulDlCfgIdx][tddSf->sfNum]; + + if(tddSf->sfType == RG_SCH_SPL_SF_DATA) + { + RGSCH_GET_SPS_SF_CFI(cell->bwCfg.dlTotalBw, splSfCfi); + + tddSf->nCce = cell->dynCfiCb.cfi2NCceTbl[mPhich][splSfCfi]; + } + else + { + tddSf->nCce = cell->dynCfiCb.cfi2NCceTbl[mPhich][cellCmnDl->currCfi]; + } + } + /* Setting the switch over window length based on config index. + * During switch over period all the UL trnsmissions are Acked + * to UEs */ + cell->dynCfiCb.switchOvrWinLen = + rgSchCfiSwitchOvrWinLen[cell->ulDlCfgIdx]; +#else + cell->nCce = cell->dynCfiCb.cfi2NCceTbl[0][cellCmnDl->currCfi]; + /* Fix for DCFI FLE issue: when DL delta is 1 and UL delta is 0 and CFI + *change happens in that SF then UL PDCCH allocation happens with old CFI + *but CFI in control Req goes updated one since it was stored in the CELL + */ + dlSf->pdcchInfo.currCfi = cellCmnDl->currCfi; + cell->dynCfiCb.switchOvrWinLen = rgSchCfiSwitchOvrWinLen[7]; +#endif + } + } + + RETVOID; +} + +/*********************************************************** + * + * Func : rgSchCmnUpdtPdcchSfIdx + * + * Desc : Update the switch over window length + * + * Ret : void + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef LTE_TDD +#ifdef ANSI +PRIVATE Void rgSchCmnUpdtPdcchSfIdx +( +RgSchCellCb *cell, +U8 dlIdx, +U8 sfNum +) +#else +PRIVATE Void rgSchCmnUpdtPdcchSfIdx(cell, dlIdx, sfNum) +RgSchCellCb *cell; +U8 dlIdx; +U8 sfNum; +#endif +#else +#ifdef ANSI +PRIVATE Void rgSchCmnUpdtPdcchSfIdx +( +RgSchCellCb *cell, +U8 dlIdx +) +#else +PRIVATE Void rgSchCmnUpdtPdcchSfIdx(cell, dlIdx) +RgSchCellCb *cell; +U8 dlIdx; +#endif +#endif +{ + U8 idx; + + TRC2(rgSchCmnUpdtPdcchSfIdx); + + /* Resetting the parameters on CFI switching */ + cell->dynCfiCb.cceUsed = 0; + cell->dynCfiCb.lowCceCnt = 0; + + cell->dynCfiCb.cceFailSum = 0; + cell->dynCfiCb.cceFailCnt = 0; + cell->dynCfiCb.prevCceFailIdx = 0; + + cell->dynCfiCb.switchOvrInProgress = TRUE; + + for(idx = 0; idx < cell->dynCfiCb.numFailSamples; idx++) + { + cell->dynCfiCb.cceFailSamples[idx] = 0; + } + + cell->dynCfiCb.ttiCnt = 0; + + cell->dynCfiCb.cfiSwitches++; + cfiSwitchCnt = cell->dynCfiCb.cfiSwitches; + +#ifdef LTE_TDD + cell->dynCfiCb.pdcchSfIdx = (dlIdx + + rgSchTddPdcchSfIncTbl[cell->ulDlCfgIdx][sfNum]) % cell->numDlSubfrms; +#else + cell->dynCfiCb.pdcchSfIdx = (dlIdx + RG_SCH_CFI_APPLY_DELTA) % \ + RGSCH_NUM_DL_SUBFRAMES; +#endif +} + +/*********************************************************** + * + * Func : rgSchCmnUpdCfiDb + * + * Desc : Update the counters related to dynamic + * CFI feature in cellCb. + * + * Ret : + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PUBLIC Void rgSchCmnUpdCfiDb +( +RgSchCellCb *cell, +U8 delta +) +#else +PUBLIC Void rgSchCmnUpdCfiDb(cell, delta) +RgSchCellCb *cell; +U8 delta; +#endif +{ + CmLteTimingInfo frm; + RgSchDlSf *dlSf; +#ifdef LTE_TDD + U8 mPhich; + Bool isHiDci0; +#endif + RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell); + U8 nCceLowerCfi = 0; + U8 currCfi; + U8 cceFailIdx; + U32 totalCce; + U8 dlIdx; + U16 ttiMod; + + TRC2(rgSchCmnUpdCfiDb); + + /* Get Downlink Subframe */ + frm = cell->crntTime; + RGSCH_INCR_SUB_FRAME(frm, delta); + +#ifdef LTE_TDD + dlIdx = rgSCHUtlGetDlSfIdx(cell, &frm); + dlSf = cell->subFrms[dlIdx]; + isHiDci0 = rgSchTddPuschTxKTbl[cell->ulDlCfgIdx][dlSf->sfNum]; +#else + /* Changing the idexing + so that proper subframe is selected */ + dlIdx = (((frm.sfn & 1) * RGSCH_NUM_SUB_FRAMES) + (frm.subframe % RGSCH_NUM_SUB_FRAMES)); + RGSCH_ARRAY_BOUND_CHECK(cell->instIdx, cell->subFrms, dlIdx); + dlSf = cell->subFrms[dlIdx]; +#endif + + currCfi = cellSch->dl.currCfi; + + if(!cell->dynCfiCb.switchOvrInProgress) + { + do{ + if(!cell->dynCfiCb.isDynCfiEnb) + { + if(currCfi != cellSch->cfiCfg.cfi) + { + if(currCfi < cellSch->cfiCfg.cfi) + { + RG_SCH_CFI_STEP_UP(cell, cellSch, currCfi) + cfiIncr = cell->dynCfiCb.cfiIncr; + } + else + { + RG_SCH_CFI_STEP_DOWN(cell, cellSch, currCfi) + cfiDecr = cell->dynCfiCb.cfiDecr; + } + } + break; + } + +#ifdef LTE_TDD + /* Setting ttiMod to 0 for ttiCnt > 1000 in case if this + * function was not called in UL subframe*/ + if(cell->dynCfiCb.ttiCnt > RGSCH_CFI_TTI_MON_INTRVL) + { + ttiMod = 0; + } + else +#endif + { + ttiMod = cell->dynCfiCb.ttiCnt % RGSCH_CFI_TTI_MON_INTRVL; + } + + dlSf->dlUlBothCmplt++; +#ifdef LTE_TDD + if((dlSf->dlUlBothCmplt == 2) || (!isHiDci0)) +#else + if(dlSf->dlUlBothCmplt == 2) +#endif + { + /********************STEP UP CRITERIA********************/ + /* Updating the CCE failure count parameter */ + cell->dynCfiCb.cceFailCnt += dlSf->isCceFailure; + cell->dynCfiCb.cceFailSum += dlSf->isCceFailure; + + /* Check if cfi step up can be performed */ + if(currCfi < cell->dynCfiCb.maxCfi) + { + if(cell->dynCfiCb.cceFailSum >= cell->dynCfiCb.cfiStepUpTtiCnt) + { + RG_SCH_CFI_STEP_UP(cell, cellSch, currCfi) + cfiIncr = cell->dynCfiCb.cfiIncr; + break; + } + } + + /********************STEP DOWN CRITERIA********************/ + + /* Updating the no. of CCE used in this dl subframe */ + cell->dynCfiCb.cceUsed += dlSf->cceCnt; + + if(currCfi > RGSCH_MIN_CFI_VAL) + { + /* calculating the number of CCE for next lower CFI */ +#ifdef LTE_TDD + mPhich = rgSchTddPhichMValTbl[cell->ulDlCfgIdx][dlSf->sfNum]; + nCceLowerCfi = cell->dynCfiCb.cfi2NCceTbl[mPhich][currCfi-1]; +#else + nCceLowerCfi = cell->dynCfiCb.cfi2NCceTbl[0][currCfi-1]; +#endif + if(dlSf->cceCnt < nCceLowerCfi) + { + /* Updating the count of TTIs in which no. of CCEs + * used were less than the CCEs of next lower CFI */ + cell->dynCfiCb.lowCceCnt++; + } + + if(ttiMod == 0) + { + totalCce = (nCceLowerCfi * cell->dynCfiCb.cfiStepDownTtiCnt * + RGSCH_CFI_CCE_PERCNTG)/100; + + if((!cell->dynCfiCb.cceFailSum) && + (cell->dynCfiCb.lowCceCnt >= + cell->dynCfiCb.cfiStepDownTtiCnt) && + (cell->dynCfiCb.cceUsed < totalCce)) + { + RG_SCH_CFI_STEP_DOWN(cell, cellSch, currCfi) + cfiDecr = cell->dynCfiCb.cfiDecr; + break; + } + } + } + + cceFailIdx = ttiMod/cell->dynCfiCb.failSamplePrd; + + if(cceFailIdx != cell->dynCfiCb.prevCceFailIdx) + { + /* New sample period has started. Subtract the old count + * from the new sample period */ + cell->dynCfiCb.cceFailSum -= cell->dynCfiCb.cceFailSamples[cceFailIdx]; + + /* Store the previous sample period data */ + cell->dynCfiCb.cceFailSamples[cell->dynCfiCb.prevCceFailIdx] + = cell->dynCfiCb.cceFailCnt; + + cell->dynCfiCb.prevCceFailIdx = cceFailIdx; + + /* Resetting the CCE failure count as zero for next sample period */ + cell->dynCfiCb.cceFailCnt = 0; + } + + if(ttiMod == 0) + { + /* Restting the parametrs after Monitoring Interval expired */ + cell->dynCfiCb.cceUsed = 0; + cell->dynCfiCb.lowCceCnt = 0; + cell->dynCfiCb.ttiCnt = 0; + } + + cell->dynCfiCb.ttiCnt++; + } + }while(0); + + if(cellSch->dl.newCfi != cellSch->dl.currCfi) + { +#ifdef LTE_TDD + rgSchCmnUpdtPdcchSfIdx(cell, dlIdx, dlSf->sfNum); +#else + rgSchCmnUpdtPdcchSfIdx(cell, dlIdx); +#endif + } + } +} + +/** + * @brief Dl Scheduler for Broadcast and Common channel scheduling. + * + * @details + * + * Function: rgSCHCmnDlCommonChSch + * Purpose: This function schedules DL Common channels for LTE. + * Invoked by TTI processing in TOM. Scheduling is done for + * BCCH, PCCH, Msg4, CCCH SDU, RAR in that order + * + * Invoked by: TOM (TTI processing) + * + * @param[in] RgSchCellCb *cell + * @return Void + **/ +#ifdef ANSI +PUBLIC Void rgSCHCmnDlCommonChSch +( +RgSchCellCb *cell +) +#else +PUBLIC Void rgSCHCmnDlCommonChSch(cell) +RgSchCellCb *cell; +#endif +{ + RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell); + + TRC2(rgSCHCmnDlCommonChSch); + + cellSch->apisDl->rgSCHDlTickForPdbTrkng(cell); + rgSchCmnUpdCfiVal(cell, RG_SCH_CMN_DL_DELTA); + + /* handle Inactive UEs for DL */ + rgSCHCmnHdlDlInactUes(cell); + + /* Send a Tick to Refresh Timer */ + rgSCHCmnTmrProc(cell); + + if (cell->isDlDataAllwd && (cell->stopSiSch == FALSE)) + { + rgSCHCmnInitRbAlloc(cell); + /* Perform DL scheduling of BCCH, PCCH */ + rgSCHCmnDlBcchPcchAlloc(cell); + } + else + { + if(cell->siCb.inWindow != 0) + { + cell->siCb.inWindow--; + } + } + if (cell->isDlDataAllwd && (cell->stopDlSch == FALSE)) + { + rgSCHCmnDlCcchRarAlloc(cell); + } + RETVOID; +} + +/** + * @brief Scheduler invocation per TTI. + * + * @details + * + * Function: rgSCHCmnUlSch + * Purpose: This function implements UL scheduler alone. This is to + * be able to perform scheduling with more flexibility. + * + * Invoked by: TOM (TTI processing) + * + * @param[in] RgSchCellCb *cell + * @return Void + **/ +#ifdef ANSI +PUBLIC Void rgSCHCmnUlSch +( +RgSchCellCb *cell +) +#else +PUBLIC Void rgSCHCmnUlSch(cell) +RgSchCellCb *cell; +#endif +{ + RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell); + + TRC2(rgSCHCmnUlSch); + +#ifdef LTE_ADV + /* LAA_SCELL: */ + if(TRUE == rgSCHLaaSCellEnabled(cell)) + { + RETVOID; + } +#endif + + if(cellSch->ul.schdIdx != RGSCH_INVALID_INFO) + { + rgSchCmnUpdCfiVal(cell, TFU_ULCNTRL_DLDELTA); + + /* Handle Inactive UEs for UL */ + rgSCHCmnHdlUlInactUes(cell); + /* Perform UL Scheduling EVERY TTI */ + rgSCHCmnUlAlloc(cell); + + /* Calling function to update CFI parameters*/ + rgSchCmnUpdCfiDb(cell, TFU_ULCNTRL_DLDELTA); + + if(cell->dynCfiCb.switchOvrWinLen > 0) + { + /* Decrementing the switchover window length */ + cell->dynCfiCb.switchOvrWinLen--; + + if(!cell->dynCfiCb.switchOvrWinLen) + { + if(cell->dynCfiCb.dynCfiRecfgPend) + { + /* Toggling the Dynamic CFI enabling */ + cell->dynCfiCb.isDynCfiEnb ^= 1; + rgSCHDynCfiReCfg(cell, cell->dynCfiCb.isDynCfiEnb); + cell->dynCfiCb.dynCfiRecfgPend = FALSE; + } + cell->dynCfiCb.switchOvrInProgress = FALSE; + } + } + } +#ifdef LTE_TDD +#ifdef LTEMAC_SPS + else + { + rgSCHCmnSpsUlTti(cell, NULLP); + } +#endif +#endif + + RETVOID; +} + + +/** + * @brief This function updates the scheduler with service for an UE. + * + * @details + * + * Function: rgSCHCmnDlDedBoUpd + * Purpose: This function should be called whenever there is a + * change BO for a service. + * + * Invoked by: BO and Scheduler + * + * @param[in] RgSchCellCb* cell + * @param[in] RgSchUeCb* ue + * @param[in] RgSchDlLcCb* svc + * @return Void + * + **/ +#ifdef ANSI +PUBLIC Void rgSCHCmnDlDedBoUpd +( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgSchDlLcCb *svc +) +#else +PUBLIC Void rgSCHCmnDlDedBoUpd(cell, ue, svc) +RgSchCellCb *cell; +RgSchUeCb *ue; +RgSchDlLcCb *svc; +#endif +{ + RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell); + TRC2(rgSCHCmnDlDedBoUpd); + + /* RACHO : if UEs idle time exceeded and a BO update + * is received, then add UE to the pdcch Order Q */ + if (RG_SCH_CMN_IS_UE_PDCCHODR_INACTV(ue)) + { + RgSchCmnDlUe *ueDl = RG_SCH_CMN_GET_DL_UE(ue, cell); + /* If PDCCH order is already triggered and we are waiting for + * RACH from UE then do not add to PdcchOdrQ. */ + if (ueDl->rachInfo.rapIdLnk.node == NULLP) + { + rgSCHCmnDlAdd2PdcchOdrQ(cell, ue); + } + } + +#ifdef LTEMAC_SPS + + /* If SPS service, invoke SPS module */ + if (svc->dlLcSpsCfg.isSpsEnabled) + { + rgSCHCmnSpsDlDedBoUpd(cell, ue, svc); + /* Note: Retrun from here, no update needed in other schedulers */ + RETVOID; + } +#endif +#ifdef EMTC_ENABLE + if((cell->emtcEnable)&&(TRUE == ue->isEmtcUe)) + { + cellSch->apisEmtcDl->rgSCHDlDedBoUpd(cell, ue, svc); + //printf("rgSCHEMTCDlDedBoUpd\n"); + } + else +#endif + { + cellSch->apisDl->rgSCHDlDedBoUpd(cell, ue, svc); + } +#ifdef LTE_ADV + if (ue->numSCells) + { + rgSCHSCellDlDedBoUpd(cell, ue, svc); + } +#endif + RETVOID; +} + + +/** + * @brief Removes an UE from Cell's TA List. + * + * @details + * + * Function: rgSCHCmnRmvFrmTaLst + * Purpose: Removes an UE from Cell's TA List. + * + * Invoked by: Specific Scheduler + * + * @param[in] RgSchCellCb* cell + * @param[in] RgSchUeCb* ue + * @return Void + * + **/ +#ifdef ANSI +PUBLIC Void rgSCHCmnRmvFrmTaLst +( +RgSchCellCb *cell, +RgSchUeCb *ue +) +#else +PUBLIC Void rgSCHCmnRmvFrmTaLst(cell, ue) +RgSchCellCb *cell; +RgSchUeCb *ue; +#endif +{ + RgSchCmnDlCell *cellCmnDl = RG_SCH_CMN_GET_DL_CELL(cell); + TRC2(rgSCHCmnRmvFrmTaLst); + +#ifdef EMTC_ENABLE + if(cell->emtcEnable && ue->isEmtcUe) + { + rgSCHEmtcRmvFrmTaLst(cellCmnDl,ue); + } + else +#endif + { + cmLListDelFrm(&cellCmnDl->taLst, &ue->dlTaLnk); + ue->dlTaLnk.node = (PTR)NULLP; + } + RETVOID; +} + +/* Fix: syed Remove the msg4Proc from cell + * msg4Retx Queue. I have used CMN scheduler function + * directly. Please define a new API and call this + * function through that. */ + +/** + * @brief This function removes MSG4 HARQ process from cell RETX Queues. + * + * @details + * + * Function: rgSCHCmnDlMsg4ProcRmvFrmRetx + * Purpose: This function removes MSG4 HARQ process from cell RETX Queues. + * + * Invoked by: UE/RACB deletion. + * + * @param[in] RgSchCellCb* cell + * @param[in] RgSchDlHqProc* hqP + * @return Void + * + **/ +#ifdef ANSI +PUBLIC Void rgSCHCmnDlMsg4ProcRmvFrmRetx +( +RgSchCellCb *cell, +RgSchDlHqProcCb *hqP +) +#else +PUBLIC Void rgSCHCmnDlMsg4ProcRmvFrmRetx(cell, hqP) +RgSchCellCb *cell; +RgSchDlHqProcCb *hqP; +#endif +{ + RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell); + TRC2(rgSCHCmnDlMsg4ProcRmvFrmRetx); + + if (hqP->tbInfo[0].ccchSchdInfo.retxLnk.node) + { + if (hqP->hqE->msg4Proc == hqP) + { + cmLListDelFrm(&cellSch->dl.msg4RetxLst, \ + &hqP->tbInfo[0].ccchSchdInfo.retxLnk); + hqP->tbInfo[0].ccchSchdInfo.retxLnk.node = (PTR)NULLP; + } +#ifdef RGR_V1 + else if(hqP->hqE->ccchSduProc == hqP) + { + cmLListDelFrm(&cellSch->dl.ccchSduRetxLst, + &hqP->tbInfo[0].ccchSchdInfo.retxLnk); + hqP->tbInfo[0].ccchSchdInfo.retxLnk.node = (PTR)NULLP; + } +#endif + } + RETVOID; +} + + +/** + * @brief This function adds a HARQ process for retx. + * + * @details + * + * Function: rgSCHCmnDlProcAddToRetx + * Purpose: This function adds a HARQ process to retransmission + * queue. This may be performed when a HARQ ack is + * unsuccessful. + * + * Invoked by: HARQ feedback processing + * + * @param[in] RgSchCellCb* cell + * @param[in] RgSchDlHqProc* hqP + * @return Void + * + **/ +#ifdef ANSI +PUBLIC Void rgSCHCmnDlProcAddToRetx +( +RgSchCellCb *cell, +RgSchDlHqProcCb *hqP +) +#else +PUBLIC Void rgSCHCmnDlProcAddToRetx(cell, hqP) +RgSchCellCb *cell; +RgSchDlHqProcCb *hqP; +#endif +{ + RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell); + TRC2(rgSCHCmnDlProcAddToRetx); + + if (hqP->hqE->msg4Proc == hqP) /* indicating msg4 transmission */ + { + cmLListAdd2Tail(&cellSch->dl.msg4RetxLst, \ + &hqP->tbInfo[0].ccchSchdInfo.retxLnk); + hqP->tbInfo[0].ccchSchdInfo.retxLnk.node = (PTR)hqP; + } +#ifdef RGR_V1 + else if(hqP->hqE->ccchSduProc == hqP) + { + /*If CCCH SDU being transmitted without cont res CE*/ + cmLListAdd2Tail(&cellSch->dl.ccchSduRetxLst, + &hqP->tbInfo[0].ccchSchdInfo.retxLnk); + hqP->tbInfo[0].ccchSchdInfo.retxLnk.node = (PTR)hqP; + } +#endif + else + { +#ifdef LTEMAC_SPS + if (RG_SCH_CMN_SPS_DL_IS_SPS_HQP(hqP)) + { + /* Invoke SPS module for SPS HARQ proc re-transmission handling */ + rgSCHCmnSpsDlProcAddToRetx(cell, hqP); + RETVOID; + } +#endif /* LTEMAC_SPS */ +#ifdef EMTC_ENABLE + if((TRUE == cell->emtcEnable) + && (TRUE == hqP->hqE->ue->isEmtcUe)) + { + cellSch->apisEmtcDl->rgSCHDlProcAddToRetx(cell, hqP); + } + else +#endif + { + cellSch->apisDl->rgSCHDlProcAddToRetx(cell, hqP); + } + } + RETVOID; +} + + +/** + * @brief This function performs RI validation and + * updates it to the ueCb. + * + * @details + * + * Function: rgSCHCmnDlSetUeRi + * Purpose: This function performs RI validation and + * updates it to the ueCb. + * + * Invoked by: rgSCHCmnDlCqiInd + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ue + * @param[in] U8 ri + * @param[in] Bool isPeriodic + * @return Void + * + **/ +#ifdef ANSI +PRIVATE Void rgSCHCmnDlSetUeRi +( +RgSchCellCb *cell, +RgSchUeCb *ue, +U8 ri, +Bool isPer +) +#else +PRIVATE Void rgSCHCmnDlSetUeRi(cell, ue, ri, isPer) +RgSchCellCb *cell; +RgSchUeCb *ue; +U8 ri; +Bool isPer; +#endif +{ + RgSchCmnDlUe *ueDl = RG_SCH_CMN_GET_DL_UE(ue,cell); + RgSchCmnUeInfo *ueSchCmn = RG_SCH_CMN_GET_CMN_UE(ue); + TRC2(rgSCHCmnDlSetUeRi); + +#ifdef TFU_UPGRADE + RgSchUePCqiCb *cqiCb = RG_SCH_GET_UE_CELL_CQI_CB(ue,cell); + UNUSED(isPer); +#endif + + + /* FIX for RRC Reconfiguration issue */ + /* ccpu00140894- During Tx Mode transition RI report will not entertained for + * specific during which SCH expecting UE can complete TX mode transition*/ + if (ue->txModeTransCmplt == FALSE) + { + RETVOID; + } + + /* Restrict the Number of TX layers to cell->numTxAntPorts. + * Protection from invalid RI values. */ + ri = RGSCH_MIN(ri, cell->numTxAntPorts); + + /* Special case of converting PMI to sane value when + * there is a switch in RI from 1 to 2 and PMI reported + * for RI=1 is invalid for RI=2 */ + if ((cell->numTxAntPorts == 2) && (ue->mimoInfo.txMode == RGR_UE_TM_4)) + { + if ((ri == 2) && ( ueDl->mimoInfo.ri == 1)) + { + ueDl->mimoInfo.pmi = (ueDl->mimoInfo.pmi < 2)? 1:2; + } + } + + /* Restrict the Number of TX layers according to the UE Category */ + ueDl->mimoInfo.ri = RGSCH_MIN(ri, rgUeCatTbl[ueSchCmn->ueCat].maxTxLyrs); +#ifdef TENB_STATS + ue->tenbStats->stats.nonPersistent.sch[RG_SCH_CELLINDEX(cell)].riCnt[ueDl->mimoInfo.ri-1]++; + cell->tenbStats->sch.riCnt[ueDl->mimoInfo.ri-1]++; +#endif + +#ifdef TENB_STATS + ue->tenbStats->stats.nonPersistent.sch[0].riCnt[ueDl->mimoInfo.ri-1]++; + cell->tenbStats->sch.riCnt[ueDl->mimoInfo.ri-1]++; +#endif + +#ifdef TFU_UPGRADE + if (isPer) + { + /* If RI is from Periodic CQI report */ + cqiCb->perRiVal = ueDl->mimoInfo.ri; + /* Reset at every Periodic RI Reception */ + cqiCb->invalidateCqi = FALSE; + } + else + { + /* If RI is from Aperiodic CQI report */ + if (cqiCb->perRiVal != ueDl->mimoInfo.ri) + { + /* if this aperRI is different from last reported + * perRI then invalidate all CQI reports till next + * perRI */ + cqiCb->invalidateCqi = TRUE; + } + else + { + cqiCb->invalidateCqi = FALSE; + } + } +#endif + + if (ueDl->mimoInfo.ri > 1) + { + RG_SCH_CMN_UNSET_FORCE_TD(ue, cell, RG_SCH_CMN_TD_RI_1); + } + else if (ue->mimoInfo.txMode == RGR_UE_TM_3) /* ri == 1 */ + { + RG_SCH_CMN_SET_FORCE_TD(ue, cell, RG_SCH_CMN_TD_RI_1); + } + + RETVOID; +} + + +/** + * @brief This function performs PMI validation and + * updates it to the ueCb. + * + * @details + * + * Function: rgSCHCmnDlSetUePmi + * Purpose: This function performs PMI validation and + * updates it to the ueCb. + * + * Invoked by: rgSCHCmnDlCqiInd + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ue + * @param[in] U8 pmi + * @return Void + * + **/ +#ifdef ANSI +PRIVATE S16 rgSCHCmnDlSetUePmi +( +RgSchCellCb *cell, +RgSchUeCb *ue, +U8 pmi +) +#else +PRIVATE S16 rgSCHCmnDlSetUePmi(cell, ue, pmi) +RgSchCellCb *cell; +RgSchUeCb *ue; +U8 pmi; +#endif +{ + RgSchCmnDlUe *ueDl = RG_SCH_CMN_GET_DL_UE(ue,cell); + TRC2(rgSCHCmnDlSetUePmi); + + if (ue->txModeTransCmplt == FALSE) + { + RETVALUE(RFAILED); + } + + if (cell->numTxAntPorts == 2) + { + if (pmi > 3) + { + RETVALUE(RFAILED); + } + if (ueDl->mimoInfo.ri == 2) + { + /*ccpu00118150 - MOD - changed pmi value validation from 0 to 2*/ + /* PMI 2 and 3 are invalid incase of 2 TxAnt and 2 Layered SM */ + if (pmi == 2 || pmi == 3) + { + RETVALUE(RFAILED); + } + ueDl->mimoInfo.pmi = pmi+1; + } + else + { + ueDl->mimoInfo.pmi = pmi; + } + } + else if (cell->numTxAntPorts == 4) + { + if (pmi > 15) + { + RETVALUE(RFAILED); + } + ueDl->mimoInfo.pmi = pmi; + } + /* Reset the No PMI Flag in forceTD */ + RG_SCH_CMN_UNSET_FORCE_TD(ue, cell, RG_SCH_CMN_TD_NO_PMI); + RETVALUE(ROK); +} + +/** + * @brief This function Updates the DL CQI on PUCCH for the UE. + * + * @details + * + * Function: rgSCHCmnDlProcCqiMode10 + * + * This function updates the DL CQI on PUCCH for the UE. + * + * Invoked by: rgSCHCmnDlCqiOnPucchInd + * + * Processing Steps: + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ue + * @param[in] TfuDlCqiRpt *dlCqiRpt + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef RGR_CQI_REPT +#ifdef ANSI +PRIVATE INLINE Void rgSCHCmnDlProcCqiMode10 +( + RgSchCellCb *cell, + RgSchUeCb *ue, + TfuDlCqiPucch *pucchCqi, + Bool *isCqiAvail + ) +#else +PRIVATE INLINE Void rgSCHCmnDlProcCqiMode10(cell, ue, pucchCqi, isCqiAvail) + RgSchCellCb *cell; + RgSchUeCb *ue; + TfuDlCqiPucch *pucchCqi; + Bool *isCqiAvail; +#endif +#else +#ifdef ANSI +PRIVATE INLINE Void rgSCHCmnDlProcCqiMode10 +( + RgSchCellCb *cell, + RgSchUeCb *ue, + TfuDlCqiPucch *pucchCqi + ) +#else +PRIVATE INLINE Void rgSCHCmnDlProcCqiMode10(cell, ue, pucchCqi) + RgSchCellCb *cell; + RgSchUeCb *ue; + TfuDlCqiPucch *pucchCqi; +#endif +#endif +{ + RgSchCmnDlUe *ueDl = RG_SCH_CMN_GET_DL_UE(ue,cell); + TRC2(rgSCHCmnDlProcCqiMode10); + + if (pucchCqi->u.mode10Info.type == TFU_RPT_CQI) + { + /*ccpu00109787 - ADD - Check for non-zero CQI*/ + /* Checking whether the decoded CQI is a value between 1 and 15*/ + if((pucchCqi->u.mode10Info.u.cqi) && (pucchCqi->u.mode10Info.u.cqi + < RG_SCH_CMN_MAX_CQI)) + { + ueDl->cqiFlag = TRUE; + ueDl->mimoInfo.cwInfo[0].cqi = pucchCqi->u.mode10Info.u.cqi; + ueDl->mimoInfo.cwInfo[1].cqi = ueDl->mimoInfo.cwInfo[0].cqi; + /* ccpu00117452 - MOD - Changed macro name from + RGR_RRM_DLPWR_CNTRL to RGR_CQI_REPT */ +#ifdef RGR_CQI_REPT + *isCqiAvail = TRUE; +#endif + } + else + { + RETVOID; + } + } + else if (pucchCqi->u.mode10Info.type == TFU_RPT_RI) + { + if ( RG_SCH_CMN_IS_RI_VALID(pucchCqi->u.mode10Info.u.ri) ) + { + rgSCHCmnDlSetUeRi(cell, ue, pucchCqi->u.mode10Info.u.ri, + TRUE); + } + else + { + RLOG_ARG2(L_ERROR,DBG_CELLID,cell->cellId,"Invalid RI value(%x) CRNTI:%d", + pucchCqi->u.mode10Info.u.ri,ue->ueId); + RETVOID; + } + } +} + +/** + * @brief This function Updates the DL CQI on PUCCH for the UE. + * + * @details + * + * Function: rgSCHCmnDlProcCqiMode11 + * + * This function updates the DL CQI on PUCCH for the UE. + * + * Invoked by: rgSCHCmnDlCqiOnPucchInd + * + * Processing Steps: + * Process CQI MODE 11 + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ue + * @param[in] TfuDlCqiRpt *dlCqiRpt + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef RGR_CQI_REPT +#ifdef ANSI +PRIVATE INLINE Void rgSCHCmnDlProcCqiMode11 +( + RgSchCellCb *cell, + RgSchUeCb *ue, + TfuDlCqiPucch *pucchCqi, + Bool *isCqiAvail, + Bool *is2ndCwCqiAvail + ) +#else +PRIVATE INLINE Void rgSCHCmnDlProcCqiMode11(cell, ue, pucchCqi, isCqiAvail, is2ndCwCqiAvail) + RgSchCellCb *cell; + RgSchUeCb *ue; + TfuDlCqiPucch *pucchCqi; + Bool *isCqiAvail; + Bool *is2ndCwCqiAvail; +#endif +#else +#ifdef ANSI +PRIVATE INLINE Void rgSCHCmnDlProcCqiMode11 +( + RgSchCellCb *cell, + RgSchUeCb *ue, + TfuDlCqiPucch *pucchCqi + ) +#else +PRIVATE INLINE Void rgSCHCmnDlProcCqiMode11(cell, ue, pucchCqi) + RgSchCellCb *cell; + RgSchUeCb *ue; + TfuDlCqiPucch *pucchCqi; +#endif +#endif +{ + RgSchCmnDlUe *ueDl = RG_SCH_CMN_GET_DL_UE(ue,cell); + TRC2(rgSCHCmnDlProcCqiMode11); + + if (pucchCqi->u.mode11Info.type == TFU_RPT_CQI) + { + ue->mimoInfo.puschFdbkVld = FALSE; + /*ccpu00109787 - ADD - Check for non-zero CQI*/ + if((pucchCqi->u.mode11Info.u.cqi.cqi) && + (pucchCqi->u.mode11Info.u.cqi.cqi < RG_SCH_CMN_MAX_CQI)) + { + ueDl->cqiFlag = TRUE; + /* ccpu00117452 - MOD - Changed macro name from + RGR_RRM_DLPWR_CNTRL to RGR_CQI_REPT */ +#ifdef RGR_CQI_REPT + *isCqiAvail = TRUE; +#endif + ueDl->mimoInfo.cwInfo[0].cqi = pucchCqi->u.mode11Info.u.cqi.cqi; + if (pucchCqi->u.mode11Info.u.cqi.wideDiffCqi.pres) + { + RG_SCH_UPDT_CW2_CQI(ueDl->mimoInfo.cwInfo[0].cqi, \ + ueDl->mimoInfo.cwInfo[1].cqi, \ + pucchCqi->u.mode11Info.u.cqi.wideDiffCqi.val); +#ifdef RGR_CQI_REPT + /* ccpu00117259 - ADD - Considering second codeword CQI info + incase of MIMO for CQI Reporting */ + *is2ndCwCqiAvail = TRUE; +#endif + } + } + else + { + RETVOID; + } + rgSCHCmnDlSetUePmi(cell, ue, \ + pucchCqi->u.mode11Info.u.cqi.pmi); + } + else if (pucchCqi->u.mode11Info.type == TFU_RPT_RI) + { + if( RG_SCH_CMN_IS_RI_VALID(pucchCqi->u.mode11Info.u.ri)) + { + rgSCHCmnDlSetUeRi(cell, ue, pucchCqi->u.mode11Info.u.ri, + TRUE); + } + else + { + RLOG_ARG2(L_ERROR,DBG_CELLID,cell->cellId, "Invalid RI value(%x) CRNTI:%d", + pucchCqi->u.mode11Info.u.ri,ue->ueId); + RETVOID; + } + } +} + +/** + * @brief This function Updates the DL CQI on PUCCH for the UE. + * + * @details + * + * Function: rgSCHCmnDlProcCqiMode20 + * + * This function updates the DL CQI on PUCCH for the UE. + * + * Invoked by: rgSCHCmnDlCqiOnPucchInd + * + * Processing Steps: + * Process CQI MODE 20 + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ue + * @param[in] TfuDlCqiRpt *dlCqiRpt + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef RGR_CQI_REPT +#ifdef ANSI +PRIVATE INLINE Void rgSCHCmnDlProcCqiMode20 +( + RgSchCellCb *cell, + RgSchUeCb *ue, + TfuDlCqiPucch *pucchCqi, + Bool *isCqiAvail + ) +#else +PRIVATE INLINE Void rgSCHCmnDlProcCqiMode20(cell, ue, pucchCqi, isCqiAvail ) + RgSchCellCb *cell; + RgSchUeCb *ue; + TfuDlCqiPucch *pucchCqi; + Bool *isCqiAvail; +#endif +#else +#ifdef ANSI +PRIVATE INLINE Void rgSCHCmnDlProcCqiMode20 +( + RgSchCellCb *cell, + RgSchUeCb *ue, + TfuDlCqiPucch *pucchCqi + ) +#else +PRIVATE INLINE Void rgSCHCmnDlProcCqiMode20(cell, ue, pucchCqi) + RgSchCellCb *cell; + RgSchUeCb *ue; + TfuDlCqiPucch *pucchCqi; +#endif +#endif +{ + RgSchCmnDlUe *ueDl = RG_SCH_CMN_GET_DL_UE(ue,cell); + TRC2(rgSCHCmnDlProcCqiMode20); + + if (pucchCqi->u.mode20Info.type == TFU_RPT_CQI) + { + if (pucchCqi->u.mode20Info.u.cqi.isWideband) + { + /*ccpu00109787 - ADD - Check for non-zero CQI*/ + if((pucchCqi->u.mode20Info.u.cqi.u.wideCqi) && + (pucchCqi->u.mode20Info.u.cqi.u.wideCqi < RG_SCH_CMN_MAX_CQI)) + { + ueDl->cqiFlag = TRUE; + ueDl->mimoInfo.cwInfo[0].cqi = pucchCqi->u.mode20Info.u.cqi.\ + u.wideCqi; + ueDl->mimoInfo.cwInfo[1].cqi = ueDl->mimoInfo.cwInfo[0].cqi; + /* ccpu00117452 - MOD - Changed macro name from + RGR_RRM_DLPWR_CNTRL to RGR_CQI_REPT */ +#ifdef RGR_CQI_REPT + *isCqiAvail = TRUE; +#endif + } + else + { + RETVOID; + } + } + } + else if (pucchCqi->u.mode20Info.type == TFU_RPT_RI) + { + if(RG_SCH_CMN_IS_RI_VALID(pucchCqi->u.mode20Info.u.ri)) + { + rgSCHCmnDlSetUeRi(cell, ue, pucchCqi->u.mode20Info.u.ri, + TRUE); + } + else + { + RLOG_ARG2(L_ERROR,DBG_CELLID,cell->cellId,"Invalid RI value(%x) CRNTI:%d", + pucchCqi->u.mode20Info.u.ri,ue->ueId); + RETVOID; + } + } +} + + +/** + * @brief This function Updates the DL CQI on PUCCH for the UE. + * + * @details + * + * Function: rgSCHCmnDlProcCqiMode21 + * + * This function updates the DL CQI on PUCCH for the UE. + * + * Invoked by: rgSCHCmnDlCqiOnPucchInd + * + * Processing Steps: + * Process CQI MODE 21 + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ue + * @param[in] TfuDlCqiRpt *dlCqiRpt + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef RGR_CQI_REPT +#ifdef ANSI +PRIVATE INLINE Void rgSCHCmnDlProcCqiMode21 +( + RgSchCellCb *cell, + RgSchUeCb *ue, + TfuDlCqiPucch *pucchCqi, + Bool *isCqiAvail, + Bool *is2ndCwCqiAvail + ) +#else +PRIVATE INLINE Void rgSCHCmnDlProcCqiMode21(cell, ue, pucchCqi, isCqiAvail, is2ndCwCqiAvail) + RgSchCellCb *cell; + RgSchUeCb *ue; + TfuDlCqiPucch *pucchCqi; + TfuDlCqiRpt *dlCqiRpt; + Bool *isCqiAvail; + Bool *is2ndCwCqiAvail; +#endif +#else +#ifdef ANSI +PRIVATE INLINE Void rgSCHCmnDlProcCqiMode21 +( + RgSchCellCb *cell, + RgSchUeCb *ue, + TfuDlCqiPucch *pucchCqi + ) +#else +PRIVATE INLINE Void rgSCHCmnDlProcCqiMode21(cell, ue, pucchCqi) + RgSchCellCb *cell; + RgSchUeCb *ue; + TfuDlCqiPucch *pucchCqi; +#endif +#endif +{ + RgSchCmnDlUe *ueDl = RG_SCH_CMN_GET_DL_UE(ue,cell); + TRC2(rgSCHCmnDlProcCqiMode21); + + if (pucchCqi->u.mode21Info.type == TFU_RPT_CQI) + { + ue->mimoInfo.puschFdbkVld = FALSE; + if (pucchCqi->u.mode21Info.u.cqi.isWideband) + { + /*ccpu00109787 - ADD - Check for non-zero CQI*/ + if((pucchCqi->u.mode21Info.u.cqi.u.wideCqi.cqi) && + (pucchCqi->u.mode21Info.u.cqi.u.wideCqi.cqi < RG_SCH_CMN_MAX_CQI)) + { + ueDl->cqiFlag = TRUE; + ueDl->mimoInfo.cwInfo[0].cqi = pucchCqi->u.mode21Info.u.cqi.\ + u.wideCqi.cqi; + if (pucchCqi->u.mode21Info.u.cqi.u.wideCqi.diffCqi.pres) + { + RG_SCH_UPDT_CW2_CQI(ueDl->mimoInfo.cwInfo[0].cqi, \ + ueDl->mimoInfo.cwInfo[1].cqi, \ + pucchCqi->u.mode21Info.u.cqi.u.wideCqi.diffCqi.val); +#ifdef RGR_CQI_REPT + /* ccpu00117259 - ADD - Considering second codeword CQI info + incase of MIMO for CQI Reporting */ + *is2ndCwCqiAvail = TRUE; +#endif + } + /* ccpu00117452 - MOD - Changed macro name from + RGR_RRM_DLPWR_CNTRL to RGR_CQI_REPT */ +#ifdef RGR_CQI_REPT + *isCqiAvail = TRUE; +#endif + } + else + { + RETVOID; + } + rgSCHCmnDlSetUePmi(cell, ue, \ + pucchCqi->u.mode21Info.u.cqi.u.wideCqi.pmi); + } + } + else if (pucchCqi->u.mode21Info.type == TFU_RPT_RI) + { + if(RG_SCH_CMN_IS_RI_VALID(pucchCqi->u.mode21Info.u.ri)) + { + rgSCHCmnDlSetUeRi(cell, ue, pucchCqi->u.mode21Info.u.ri, + TRUE); + } + else + { + RLOG_ARG2(L_ERROR,DBG_CELLID,cell->cellId, "Invalid RI value(%x) CRNTI:%d", + pucchCqi->u.mode21Info.u.ri,ue->ueId); + RETVOID; + } + } +} + + +/** + * @brief This function Updates the DL CQI on PUCCH for the UE. + * + * @details + * + * Function: rgSCHCmnDlCqiOnPucchInd + * + * This function updates the DL CQI on PUCCH for the UE. + * + * Invoked by: rgSCHCmnDlCqiInd + * + * Processing Steps: + * - Depending on the reporting mode of the PUCCH, the CQI/PMI/RI values + * are updated and stored for each UE + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ue + * @param[in] TfuDlCqiRpt *dlCqiRpt + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef RGR_CQI_REPT +#ifdef ANSI +PRIVATE Void rgSCHCmnDlCqiOnPucchInd +( + RgSchCellCb *cell, + RgSchUeCb *ue, + TfuDlCqiPucch *pucchCqi, + RgrUeCqiRept *ueCqiRept, + Bool *isCqiAvail, + Bool *is2ndCwCqiAvail + ) +#else +PRIVATE Void rgSCHCmnDlCqiOnPucchInd(cell, ue, pucchCqi, ueCqiRept, isCqiAvail, is2ndCwCqiAvail) + RgSchCellCb *cell; + RgSchUeCb *ue; + TfuDlCqiPucch *pucchCqi; + RgrUeCqiRept *ueCqiRept; + Bool *isCqiAvail; + Bool *is2ndCwCqiAvail; +#endif +#else +#ifdef ANSI +PRIVATE Void rgSCHCmnDlCqiOnPucchInd +( + RgSchCellCb *cell, + RgSchUeCb *ue, + TfuDlCqiPucch *pucchCqi + ) +#else +PRIVATE Void rgSCHCmnDlCqiOnPucchInd(cell, ue, pucchCqi) + RgSchCellCb *cell; + RgSchUeCb *ue; + TfuDlCqiPucch *pucchCqi; +#endif +#endif +{ + RgSchCmnDlUe *ueDl = RG_SCH_CMN_GET_DL_UE(ue,cell); + TRC2(rgSCHCmnDlCqiOnPucchInd); + + /* ccpu00117452 - MOD - Changed + RGR_RRM_DLPWR_CNTRL to RGR_CQI_REPT */ +#ifdef RGR_CQI_REPT + /* Save CQI mode information in the report */ + ueCqiRept->cqiMode = pucchCqi->mode; +#endif + + switch(pucchCqi->mode) + { + case TFU_PUCCH_CQI_MODE10: +#ifdef RGR_CQI_REPT + rgSCHCmnDlProcCqiMode10(cell, ue, pucchCqi, isCqiAvail); +#else + rgSCHCmnDlProcCqiMode10(cell, ue, pucchCqi); +#endif + ueDl->cqiFlag = TRUE; + break; + case TFU_PUCCH_CQI_MODE11: +#ifdef RGR_CQI_REPT + rgSCHCmnDlProcCqiMode11(cell, ue, pucchCqi, isCqiAvail, + is2ndCwCqiAvail); +#else + rgSCHCmnDlProcCqiMode11(cell, ue, pucchCqi); +#endif + ueDl->cqiFlag = TRUE; + break; + case TFU_PUCCH_CQI_MODE20: +#ifdef RGR_CQI_REPT + rgSCHCmnDlProcCqiMode20(cell, ue, pucchCqi, isCqiAvail); +#else + rgSCHCmnDlProcCqiMode20(cell, ue, pucchCqi); +#endif + ueDl->cqiFlag = TRUE; + break; + case TFU_PUCCH_CQI_MODE21: +#ifdef RGR_CQI_REPT + rgSCHCmnDlProcCqiMode21(cell, ue, pucchCqi, isCqiAvail, + is2ndCwCqiAvail); +#else + rgSCHCmnDlProcCqiMode21(cell, ue, pucchCqi); +#endif + ueDl->cqiFlag = TRUE; + break; + default: + { + RLOG_ARG2(L_ERROR,DBG_CELLID,cell->cellId,"Unknown CQI Mode %d", + pucchCqi->mode,ue->ueId); + /* ccpu00117452 - MOD - Changed macro name from + RGR_RRM_DLPWR_CNTRL to RGR_CQI_REPT */ +#ifdef RGR_CQI_REPT + *isCqiAvail = FALSE; +#endif + } + break; + } + + RETVOID; +} /* rgSCHCmnDlCqiOnPucchInd */ + + +/** + * @brief This function Updates the DL CQI on PUSCH for the UE. + * + * @details + * + * Function: rgSCHCmnDlCqiOnPuschInd + * + * This function updates the DL CQI on PUSCH for the UE. + * + * Invoked by: rgSCHCmnDlCqiInd + * + * Processing Steps: + * - Depending on the reporting mode of the PUSCH, the CQI/PMI/RI values + * are updated and stored for each UE + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ue + * @param[in] TfuDlCqiRpt *dlCqiRpt + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef RGR_CQI_REPT +#ifdef ANSI +PRIVATE Void rgSCHCmnDlCqiOnPuschInd +( + RgSchCellCb *cell, + RgSchUeCb *ue, + TfuDlCqiPusch *puschCqi, + RgrUeCqiRept *ueCqiRept, + Bool *isCqiAvail, + Bool *is2ndCwCqiAvail + ) +#else +PRIVATE Void rgSCHCmnDlCqiOnPuschInd(cell, ue, puschCqi, ueCqiRept, isCqiAvail, is2ndCwCqiAvail) + RgSchCellCb *cell; + RgSchUeCb *ue; + TfuDlCqiPusch *puschCqi; + RgrUeCqiRept *ueCqiRept; + Bool *isCqiAvail; + Bool *is2ndCwCqiAvail; +#endif +#else +#ifdef ANSI +PRIVATE Void rgSCHCmnDlCqiOnPuschInd +( + RgSchCellCb *cell, + RgSchUeCb *ue, + TfuDlCqiPusch *puschCqi + ) +#else +PRIVATE Void rgSCHCmnDlCqiOnPuschInd(cell, ue, puschCqi) + RgSchCellCb *cell; + RgSchUeCb *ue; + TfuDlCqiPusch *puschCqi; +#endif +#endif +{ + RgSchCmnDlUe *ueDl = RG_SCH_CMN_GET_DL_UE(ue,cell); + U32 prevRiVal = 0; + TRC2(rgSCHCmnDlCqiOnPuschInd); + if (puschCqi->ri.pres == PRSNT_NODEF) + { + if (RG_SCH_CMN_IS_RI_VALID(puschCqi->ri.val)) + { + /* Saving the previous ri value to revert back + in case PMI update failed */ + if (RGR_UE_TM_4 == ue->mimoInfo.txMode ) /* Cheking for TM4. TM8 check later */ + { + prevRiVal = ueDl->mimoInfo.ri; + } + rgSCHCmnDlSetUeRi(cell, ue, puschCqi->ri.val, FALSE); + } + else + { + RLOG_ARG2(L_ERROR,DBG_CELLID,cell->cellId,"Invalid RI value(%x) CRNTI:%d", + puschCqi->ri.val,ue->ueId); + RETVOID; + } + } + ue->mimoInfo.puschFdbkVld = FALSE; + /* ccpu00117452 - MOD - Changed macro name from + RGR_RRM_DLPWR_CNTRL to RGR_CQI_REPT */ +#ifdef RGR_CQI_REPT + /* Save CQI mode information in the report */ + ueCqiRept->cqiMode = puschCqi->mode; + /* ccpu00117259 - DEL - removed default setting of isCqiAvail to TRUE */ +#endif + + switch(puschCqi->mode) + { + case TFU_PUSCH_CQI_MODE_20: + /*ccpu00109787 - ADD - Check for non-zero CQI*/ + /* Checking whether the decoded CQI is a value between 1 and 15*/ + if((puschCqi->u.mode20Info.wideBandCqi) && + (puschCqi->u.mode20Info.wideBandCqi < RG_SCH_CMN_MAX_CQI)) + { + ueDl->mimoInfo.cwInfo[0].cqi = puschCqi->u.mode20Info.wideBandCqi; + ueDl->mimoInfo.cwInfo[1].cqi = ueDl->mimoInfo.cwInfo[0].cqi; + /* ccpu00117452 - MOD - Changed macro name from + RGR_RRM_DLPWR_CNTRL to RGR_CQI_REPT */ +#ifdef RGR_CQI_REPT + *isCqiAvail = TRUE; +#endif + } + else + { + RETVOID; + } + break; + case TFU_PUSCH_CQI_MODE_30: + /*ccpu00109787 - ADD - Check for non-zero CQI*/ + if((puschCqi->u.mode30Info.wideBandCqi) && + (puschCqi->u.mode30Info.wideBandCqi < RG_SCH_CMN_MAX_CQI)) + { + ueDl->mimoInfo.cwInfo[0].cqi = puschCqi->u.mode30Info.wideBandCqi; + ueDl->mimoInfo.cwInfo[1].cqi = ueDl->mimoInfo.cwInfo[0].cqi; + /* ccpu00117452 - MOD - Changed macro name from + RGR_RRM_DLPWR_CNTRL to RGR_CQI_REPT */ +#ifdef RGR_CQI_REPT + *isCqiAvail = TRUE; +#endif +#ifdef CA_DBG + { + extern U32 gACqiRcvdCount; + gACqiRcvdCount++; + + } +#endif + } + else + { + RETVOID; + } + break; + case TFU_PUSCH_CQI_MODE_12: + /*ccpu00109787 - ADD - Check for non-zero CQI*/ + if((puschCqi->u.mode12Info.cqiIdx[0]) && + (puschCqi->u.mode12Info.cqiIdx[0] < RG_SCH_CMN_MAX_CQI)) + { + ueDl->mimoInfo.cwInfo[0].cqi = puschCqi->u.mode12Info.cqiIdx[0]; + /* ccpu00117452 - MOD - Changed macro name from + RGR_RRM_DLPWR_CNTRL to RGR_CQI_REPT */ +#ifdef RGR_CQI_REPT + *isCqiAvail = TRUE; +#endif + } + else + { + RETVOID; + } + if((puschCqi->u.mode12Info.cqiIdx[1]) && + (puschCqi->u.mode12Info.cqiIdx[1] < RG_SCH_CMN_MAX_CQI)) + { + ueDl->mimoInfo.cwInfo[1].cqi = puschCqi->u.mode12Info.cqiIdx[1]; + /* ccpu00117452 - MOD - Changed macro name from + RGR_RRM_DLPWR_CNTRL to RGR_CQI_REPT */ +#ifdef RGR_CQI_REPT + /* ccpu00117259 - ADD - Considering second codeword CQI info + incase of MIMO for CQI Reporting */ + *is2ndCwCqiAvail = TRUE; +#endif + } + else + { + RETVOID; + } + ue->mimoInfo.puschFdbkVld = TRUE; + ue->mimoInfo.puschPmiInfo.mode = TFU_PUSCH_CQI_MODE_12; + ue->mimoInfo.puschPmiInfo.u.mode12Info = puschCqi->u.mode12Info; + /* : resetting this is time based. Make use of CQI reporting + * periodicity, DELTA's in determining the exact time at which this + * need to be reset. */ + break; + case TFU_PUSCH_CQI_MODE_22: + /*ccpu00109787 - ADD - Check for non-zero CQI*/ + if((puschCqi->u.mode22Info.wideBandCqi[0]) && + (puschCqi->u.mode22Info.wideBandCqi[0] < RG_SCH_CMN_MAX_CQI)) + { + ueDl->mimoInfo.cwInfo[0].cqi = puschCqi->u.mode22Info.wideBandCqi[0]; + /* ccpu00117452 - MOD - Changed macro name from + RGR_RRM_DLPWR_CNTRL to RGR_CQI_REPT */ +#ifdef RGR_CQI_REPT + *isCqiAvail = TRUE; +#endif + } + else + { + RETVOID; + } + if((puschCqi->u.mode22Info.wideBandCqi[1]) && + (puschCqi->u.mode22Info.wideBandCqi[1] < RG_SCH_CMN_MAX_CQI)) + { + ueDl->mimoInfo.cwInfo[1].cqi = puschCqi->u.mode22Info.wideBandCqi[1]; + /* ccpu00117452 - MOD - Changed macro name from + RGR_RRM_DLPWR_CNTRL to RGR_CQI_REPT */ +#ifdef RGR_CQI_REPT + /* ccpu00117259 - ADD - Considering second codeword CQI info + incase of MIMO for CQI Reporting */ + *is2ndCwCqiAvail = TRUE; +#endif + } + else + { + RETVOID; + } + rgSCHCmnDlSetUePmi(cell, ue, puschCqi->u.mode22Info.wideBandPmi); + ue->mimoInfo.puschFdbkVld = TRUE; + ue->mimoInfo.puschPmiInfo.mode = TFU_PUSCH_CQI_MODE_22; + ue->mimoInfo.puschPmiInfo.u.mode22Info = puschCqi->u.mode22Info; + break; + case TFU_PUSCH_CQI_MODE_31: + /*ccpu00109787 - ADD - Check for non-zero CQI*/ + if((puschCqi->u.mode31Info.wideBandCqi[0]) && + (puschCqi->u.mode31Info.wideBandCqi[0] < RG_SCH_CMN_MAX_CQI)) + { + ueDl->mimoInfo.cwInfo[0].cqi = puschCqi->u.mode31Info.wideBandCqi[0]; + /* ccpu00117452 - MOD - Changed macro name from + RGR_RRM_DLPWR_CNTRL to RGR_CQI_REPT */ +#ifdef RGR_CQI_REPT + *isCqiAvail = TRUE; +#endif + } + if (ueDl->mimoInfo.ri > 1) + { + if((puschCqi->u.mode31Info.wideBandCqi[1]) && + (puschCqi->u.mode31Info.wideBandCqi[1] < RG_SCH_CMN_MAX_CQI)) + { + ueDl->mimoInfo.cwInfo[1].cqi = puschCqi->u.mode31Info.wideBandCqi[1]; + /* ccpu00117452 - MOD - Changed macro name from + RGR_RRM_DLPWR_CNTRL to RGR_CQI_REPT */ +#ifdef RGR_CQI_REPT + /* ccpu00117259 - ADD - Considering second codeword CQI info + incase of MIMO for CQI Reporting */ + *is2ndCwCqiAvail = TRUE; +#endif + } + } + if (rgSCHCmnDlSetUePmi(cell, ue, puschCqi->u.mode31Info.pmi) != ROK) + { + /* To avoid Rank and PMI inconsistency */ + if ((puschCqi->ri.pres == PRSNT_NODEF) && + (RGR_UE_TM_4 == ue->mimoInfo.txMode)) /* checking for TM4. TM8 check later */ + { + ueDl->mimoInfo.ri = prevRiVal; + } + } + ue->mimoInfo.puschPmiInfo.mode = TFU_PUSCH_CQI_MODE_31; + ue->mimoInfo.puschPmiInfo.u.mode31Info = puschCqi->u.mode31Info; + break; + default: + { + RLOG_ARG2(L_ERROR,DBG_CELLID,cell->cellId, "Unknown CQI Mode %d CRNTI:%d", + puschCqi->mode,ue->ueId); + /* CQI decoding failed revert the RI to previous value */ + if ((puschCqi->ri.pres == PRSNT_NODEF) && + (RGR_UE_TM_4 == ue->mimoInfo.txMode)) /* checking for TM4. TM8 check later */ + { + ueDl->mimoInfo.ri = prevRiVal; + } + /* ccpu00117452 - MOD - Changed macro name from + RGR_RRM_DLPWR_CNTRL to RGR_CQI_REPT */ +#ifdef RGR_CQI_REPT + *isCqiAvail = FALSE; + /* ccpu00117259 - ADD - Considering second codeword CQI info + incase of MIMO for CQI Reporting */ + *is2ndCwCqiAvail = FALSE; +#endif + } + break; + } + + RETVOID; +} /* rgSCHCmnDlCqiOnPuschInd */ + + +/** + * @brief This function Updates the DL CQI for the UE. + * + * @details + * + * Function: rgSCHCmnDlCqiInd + * Purpose: Updates the DL CQI for the UE + * + * Invoked by: TOM + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ue + * @param[in] TfuDlCqiRpt *dlCqi + * @return Void + * + **/ +#ifdef ANSI +PUBLIC Void rgSCHCmnDlCqiInd +( +RgSchCellCb *cell, +RgSchUeCb *ue, +Bool isPucchInfo, +Void *dlCqi, +CmLteTimingInfo timingInfo +) +#else +PUBLIC Void rgSCHCmnDlCqiInd(cell, ue, isPucchInfo, dlCqi, timingInfo) +RgSchCellCb *cell; +RgSchUeCb *ue; +Bool isPucchInfo; +Void *dlCqi; +CmLteTimingInfo timingInfo; +#endif +{ + RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell); +/* ccpu00117452 - MOD - Changed macro name from + RGR_RRM_DLPWR_CNTRL to RGR_CQI_REPT */ +#ifdef RGR_CQI_REPT + RgSchCmnDlUe *ueDl = RG_SCH_CMN_GET_DL_UE(ue,cell); + RgrUeCqiRept ueCqiRept = {{0}}; + Bool isCqiAvail = FALSE; + /* ccpu00117259 - ADD - Considering second codeword CQI info + incase of MIMO for CQI Reporting */ + Bool is2ndCwCqiAvail = FALSE; +#endif + + TRC2(rgSCHCmnDlCqiInd); + +#ifdef RGR_CQI_REPT + if (isPucchInfo) + { + rgSCHCmnDlCqiOnPucchInd(cell, ue, (TfuDlCqiPucch *)dlCqi, &ueCqiRept, &isCqiAvail, &is2ndCwCqiAvail); + } + else + { + rgSCHCmnDlCqiOnPuschInd(cell, ue, (TfuDlCqiPusch *)dlCqi, &ueCqiRept, &isCqiAvail, &is2ndCwCqiAvail); + } +#else + if (isPucchInfo) + { + rgSCHCmnDlCqiOnPucchInd(cell, ue, (TfuDlCqiPucch *)dlCqi); + } + else + { + rgSCHCmnDlCqiOnPuschInd(cell, ue, (TfuDlCqiPusch *)dlCqi); + } +#endif + +#ifdef CQI_CONFBITMASK_DROP + if(!ue->cqiConfBitMask) + { + if (ueDl->mimoInfo.cwInfo[0].cqi >15) + { + ueDl->mimoInfo.cwInfo[0].cqi = ue->prevCqi; + ueDl->mimoInfo.cwInfo[1].cqi = ue->prevCqi; + } + else if ( ueDl->mimoInfo.cwInfo[0].cqi >= ue->prevCqi) + { + ue->prevCqi = ueDl->mimoInfo.cwInfo[0].cqi; + } + else + { + U8 dlCqiDeltaPrev = 0; + dlCqiDeltaPrev = ue->prevCqi - ueDl->mimoInfo.cwInfo[0].cqi; + if (dlCqiDeltaPrev > 3) + dlCqiDeltaPrev = 3; + if ((ue->prevCqi - dlCqiDeltaPrev) < 6) + { + ue->prevCqi = 6; + } + else + { + ue->prevCqi = ue->prevCqi - dlCqiDeltaPrev; + } + ueDl->mimoInfo.cwInfo[0].cqi = ue->prevCqi; + ueDl->mimoInfo.cwInfo[1].cqi = ue->prevCqi; + + } + } +#endif + +/* ccpu00117452 - MOD - Changed macro name from + RGR_RRM_DLPWR_CNTRL to RGR_CQI_REPT */ +#ifdef RGR_CQI_REPT + /* ccpu00117259 - ADD - Considering second codeword CQI info + incase of MIMO for CQI Reporting - added is2ndCwCqiAvail\ + in 'if' condition*/ + if (RG_SCH_CQIR_IS_PUSHNCQI_ENBLE(ue) && (isCqiAvail || is2ndCwCqiAvail)) + { + ueCqiRept.cqi[0] = ueDl->mimoInfo.cwInfo[0].cqi; + + /* ccpu00117259 - ADD - Considering second codeword CQI info + incase of MIMO for CQI Reporting - added is2ndCwCqiAvail + in 'if' condition*/ + ueCqiRept.cqi[1] = 0; + if(is2ndCwCqiAvail) + { + ueCqiRept.cqi[1] = ueDl->mimoInfo.cwInfo[1].cqi; + } + rgSCHCmnUeDlPwrCtColltCqiRept(cell, ue, &ueCqiRept); + + } +#endif +#ifdef DL_LA + rgSCHCmnDlSetUeAllocLmtLa(cell, ue); + rgSCHCheckAndSetTxScheme(cell, ue); +#else +#ifdef EMTC_ENABLE + rgSCHCmnDlSetUeAllocLmt(cell, RG_SCH_CMN_GET_DL_UE(ue,cell), ue->isEmtcUe); +#else + rgSCHCmnDlSetUeAllocLmt(cell, RG_SCH_CMN_GET_DL_UE(ue,cell), FALSE); +#endif +#endif + + if (cellSch->dl.isDlFreqSel) + { + cellSch->apisDlfs->rgSCHDlfsDlCqiInd(cell, ue, isPucchInfo, dlCqi, timingInfo); + } +#ifdef LTEMAC_SPS + /* Call SPS module to update CQI indication */ + rgSCHCmnSpsDlCqiIndHndlr(cell, ue, timingInfo); +#endif + /* Call Specific scheduler to process on dlCqiInd */ +#ifdef EMTC_ENABLE + if((TRUE == cell->emtcEnable) && (TRUE == ue->isEmtcUe)) + { + cellSch->apisEmtcDl->rgSCHDlCqiInd(cell, ue, isPucchInfo, dlCqi); + } + else +#endif + { + cellSch->apisDl->rgSCHDlCqiInd(cell, ue, isPucchInfo, dlCqi); + } + +#ifdef RG_PFS_STATS + ue->pfsStats.cqiStats[(RG_SCH_GET_SCELL_INDEX(ue, cell))].avgCqi += + ueDl->mimoInfo.cwInfo[0].cqi; + ue->pfsStats.cqiStats[(RG_SCH_GET_SCELL_INDEX(ue, cell))].totalCqiOcc++; +#endif + +#ifdef SCH_STATS + ueDl->avgCqi += ueDl->mimoInfo.cwInfo[0].cqi; + ueDl->numCqiOccns++; + if (ueDl->mimoInfo.ri == 1) + { + ueDl->numRi1++; + } + else + { + ueDl->numRi2++; + } +#endif + +#ifdef TENB_STATS + ue->tenbStats->stats.nonPersistent.sch[RG_SCH_CELLINDEX(cell)].dlSumCw0Cqi += ueDl->mimoInfo.cwInfo[0].cqi; + ue->tenbStats->stats.nonPersistent.sch[RG_SCH_CELLINDEX(cell)].dlSumCw1Cqi += ueDl->mimoInfo.cwInfo[1].cqi; + ue->tenbStats->stats.nonPersistent.sch[RG_SCH_CELLINDEX(cell)].dlNumCw0Cqi ++; + ue->tenbStats->stats.nonPersistent.sch[RG_SCH_CELLINDEX(cell)].dlNumCw1Cqi ++; + cell->tenbStats->sch.dlSumCw0Cqi += ueDl->mimoInfo.cwInfo[0].cqi; + cell->tenbStats->sch.dlSumCw1Cqi += ueDl->mimoInfo.cwInfo[1].cqi; + cell->tenbStats->sch.dlNumCw0Cqi ++; + cell->tenbStats->sch.dlNumCw1Cqi ++; +#endif + RETVOID; +} + +#ifdef TFU_UPGRADE +/** + * @brief This function calculates the wideband CQI from SNR + * reported for each RB. + * + * @details + * + * Function: rgSCHCmnCalcWcqiFrmSnr + * Purpose: Wideband CQI calculation from SNR + * + * Invoked by: RG SCH + * + * @param[in] RgSchCellCb *cell + * @param[in] TfuSrsRpt *srsRpt, + * @return Wideband CQI + * + **/ +#ifdef ANSI +PRIVATE U8 rgSCHCmnCalcWcqiFrmSnr +( + RgSchCellCb *cell, + TfuSrsRpt *srsRpt + ) +#else +PRIVATE U8 rgSCHCmnCalcWcqiFrmSnr(cell,srsRpt) + RgSchCellCb *cell; + TfuSrsRpt *srsRpt; +#endif +{ + U8 wideCqi=1; /*Calculated value from SNR*/ + TRC2(rgSCHCmnCalcWcqiFrmSnr); + /*Need to map a certain SNR with a WideCQI value. + * The CQI calculation is still primitive. Further, need to + * use a improvized method for calculating WideCQI from SNR*/ + if (srsRpt->snr[0] <=50) + { + wideCqi=3; + } + else if (srsRpt->snr[0]>=51 && srsRpt->snr[0] <=100) + { + wideCqi=6; + } + else if (srsRpt->snr[0]>=101 && srsRpt->snr[0] <=150) + { + wideCqi=9; + } + else if (srsRpt->snr[0]>=151 && srsRpt->snr[0] <=200) + { + wideCqi=12; + } + else if (srsRpt->snr[0]>=201 && srsRpt->snr[0] <=250) + { + wideCqi=14; + } + else + { + wideCqi=15; + } + RETVALUE(wideCqi); +}/*rgSCHCmnCalcWcqiFrmSnr*/ + + +/** + * @brief This function Updates the SRS for the UE. + * + * @details + * + * Function: rgSCHCmnSrsInd + * Purpose: Updates the UL SRS for the UE + * + * Invoked by: TOM + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ue + * @param[in] TfuSrsRpt *srsRpt, + * @return Void + * + **/ +#ifdef ANSI +PUBLIC Void rgSCHCmnSrsInd +( + RgSchCellCb *cell, + RgSchUeCb *ue, + TfuSrsRpt *srsRpt, + CmLteTimingInfo timingInfo + ) +#else +PUBLIC Void rgSCHCmnSrsInd(cell, ue, srsRpt, timingInfo) + RgSchCellCb *cell; + RgSchUeCb *ue; + TfuSrsRpt *srsRpt; + CmLteTimingInfo timingInfo; +#endif +{ + U8 wideCqi; /*Calculated value from SNR*/ + U32 recReqTime; /*Received Time in TTI*/ + TRC2(rgSCHCmnSrsInd); + + recReqTime = (timingInfo.sfn * RGSCH_NUM_SUB_FRAMES_5G) + timingInfo.subframe; + ue->srsCb.selectedAnt = (recReqTime/ue->srsCb.peri)%2; + if(srsRpt->wideCqiPres) + { + wideCqi = srsRpt->wideCqi; + } + else + { + wideCqi = rgSCHCmnCalcWcqiFrmSnr(cell, srsRpt); + } + rgSCHCmnFindUlCqiUlTxAnt(cell, ue, wideCqi); + RETVOID; +}/*rgSCHCmnSrsInd*/ +#endif + + +/** + * @brief This function is a handler for TA report for an UE. + * + * @details + * + * Function: rgSCHCmnDlTARpt + * Purpose: Determine based on UE_IDLE_TIME threshold, + * whether UE needs to be Linked to the scheduler's TA list OR + * if it needs a PDCCH Order. + * + * + * Invoked by: TOM + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ue + * @return Void + * + **/ +#ifdef ANSI +PUBLIC Void rgSCHCmnDlTARpt +( +RgSchCellCb *cell, +RgSchUeCb *ue +) +#else +PUBLIC Void rgSCHCmnDlTARpt(cell, ue) +RgSchCellCb *cell; +RgSchUeCb *ue; +#endif +{ + RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell); + RgSchCmnDlCell *cellDl = RG_SCH_CMN_GET_DL_CELL(cell); + RgSchCmnDlUe *ueDl = RG_SCH_CMN_GET_DL_UE(ue,cell); + CmLListCp poInactvLst; + + TRC2(rgSCHCmnDlTARpt); + + /* RACHO: If UE idle time is more than threshold, then + * set its poInactv pdcch order inactivity */ + /* Fix : syed Ignore if TaTmr is not configured */ + if ((ue->dl.taCb.cfgTaTmr) && (rgSCHCmnUeIdleExdThrsld(cell, ue) == ROK)) + { + U32 prevDlMsk = ue->dl.dlInactvMask; + U32 prevUlMsk = ue->ul.ulInactvMask; + ue->dl.dlInactvMask |= RG_PDCCHODR_INACTIVE; + ue->ul.ulInactvMask |= RG_PDCCHODR_INACTIVE; + /* Indicate Specific scheduler for this UEs inactivity */ + cmLListInit(&poInactvLst); + cmLListAdd2Tail(&poInactvLst, &ueDl->rachInfo.inActUeLnk); + ueDl->rachInfo.inActUeLnk.node = (PTR)ue; + /* Send inactivate ind only if not already sent */ + if (prevDlMsk == 0) + { + cellSch->apisDl->rgSCHDlInactvtUes(cell, &poInactvLst); + } + if (prevUlMsk == 0) + { + cellSch->apisUl->rgSCHUlInactvtUes(cell, &poInactvLst); + } + } + else + { + /* Fix: ccpu00124009 Fix for loop in the linked list "cellDl->taLst" */ + if (!ue->dlTaLnk.node) + { +#ifdef EMTC_ENABLE + if(cell->emtcEnable) + { + if(ue->isEmtcUe) + { + rgSCHEmtcAddToTaLst(cellDl,ue); + } + } + else +#endif + { + + cmLListAdd2Tail(&cellDl->taLst, &ue->dlTaLnk); + ue->dlTaLnk.node = (PTR)ue; + } + } + else + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId, + "TA duplicate entry attempt failed: UEID:%u", + ue->ueId); + } + } + RETVOID; +} + +#ifdef TFU_UPGRADE +/** + * @brief Indication of UL CQI. + * + * @details + * + * Function : rgSCHCmnFindUlCqiUlTxAnt + * + * - Finds the Best Tx Antenna amongst the CQIs received + * from Two Tx Antennas. + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ue + * @param[in] U8 wideCqi + * @return Void + **/ +#ifdef ANSI +PRIVATE Void rgSCHCmnFindUlCqiUlTxAnt +( +RgSchCellCb *cell, +RgSchUeCb *ue, +U8 wideCqi +) +#else +PRIVATE Void rgSCHCmnFindUlCqiUlTxAnt(cell, ue, wideCqi) +RgSchCellCb *cell; +RgSchUeCb *ue; +U8 wideCqi; +#endif +{ + ue->validTxAnt = 1; + RETVOID; +} /* rgSCHCmnFindUlCqiUlTxAnt */ +#endif + +/** + * @brief Indication of UL CQI. + * + * @details + * + * Function : rgSCHCmnUlCqiInd + * + * - Updates uplink CQI information for the UE. Computes and + * stores the lowest CQI of CQIs reported in all subbands. + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ue + * @param[in] TfuUlCqiRpt *ulCqiInfo + * @return Void + **/ +#ifdef ANSI +PUBLIC Void rgSCHCmnUlCqiInd +( +RgSchCellCb *cell, +RgSchUeCb *ue, +TfuUlCqiRpt *ulCqiInfo +) +#else +PUBLIC Void rgSCHCmnUlCqiInd(cell, ue, ulCqiInfo) +RgSchCellCb *cell; +RgSchUeCb *ue; +TfuUlCqiRpt *ulCqiInfo; +#endif +{ + RgSchCmnUlUe *ueUl = RG_SCH_CMN_GET_UL_UE(ue,cell); + RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell); +#ifdef UL_LA + U8 iTbsNew; + S32 previTbs; +#endif +#if (defined(SCH_STATS) || defined(TENB_STATS)) + CmLteUeCategory ueCtg = (CmLteUeCategory)(RG_SCH_CMN_GET_UE_CTGY(ue)); +#endif + + TRC2(rgSCHCmnUlCqiInd); + /* consider inputs from SRS handlers about SRS occassions + * in determining the UL TX Antenna selection */ + ueUl->crntUlCqi[0] = ulCqiInfo->wideCqi; +#ifdef TFU_UPGRADE + ueUl->validUlCqi = ueUl->crntUlCqi[0]; + ue->validTxAnt = 0; +#ifdef UL_LA + iTbsNew = rgSchCmnUlCqiToTbsTbl[cell->isCpUlExtend][ueUl->validUlCqi]; + previTbs = (ueUl->ulLaCb.cqiBasediTbs + ueUl->ulLaCb.deltaiTbs)/100; + + if (RG_ITBS_DIFF(iTbsNew, previTbs) > 5) + { + /* Ignore this iTBS report and mark that last iTBS report was */ + /* ignored so that subsequently we reset the LA algorithm */ + ueUl->ulLaCb.lastiTbsIgnored = TRUE; + } + else + { + if (ueUl->ulLaCb.lastiTbsIgnored != TRUE) + { + ueUl->ulLaCb.cqiBasediTbs = ((20 * iTbsNew * 100) + + (80 * ueUl->ulLaCb.cqiBasediTbs))/100; + } + else + { + /* Reset the LA as iTbs in use caught up with the value */ + /* reported by UE. */ + ueUl->ulLaCb.cqiBasediTbs = ((20 * iTbsNew * 100) + + (80 * previTbs * 100))/100; + ueUl->ulLaCb.deltaiTbs = 0; + ueUl->ulLaCb.lastiTbsIgnored = FALSE; + } + } +#endif +#endif + rgSCHPwrUlCqiInd(cell, ue); +#ifdef LTEMAC_SPS + if (ue->ul.ulSpsCfg.isUlSpsEnabled == TRUE) + { + rgSCHCmnSpsUlCqiInd(cell, ue); + } +#endif + /* Applicable to only some schedulers */ +#ifdef EMTC_ENABLE + if((TRUE == cell->emtcEnable) && (TRUE == ue->isEmtcUe)) + { + cellSch->apisEmtcUl->rgSCHUlCqiInd(cell, ue, ulCqiInfo); + } + else +#endif + { + cellSch->apisUl->rgSCHUlCqiInd(cell, ue, ulCqiInfo); + } + +#ifdef SCH_STATS + ueUl->numCqiOccns++; + ueUl->avgCqi += rgSCHCmnUlGetCqi(cell, ue, ueCtg); +#endif + +#ifdef TENB_STATS + { + ue->tenbStats->stats.nonPersistent.sch[RG_SCH_CELLINDEX(cell)].ulSumCqi += rgSCHCmnUlGetCqi(cell, ue, ueCtg); + ue->tenbStats->stats.nonPersistent.sch[RG_SCH_CELLINDEX(cell)].ulNumCqi ++; + cell->tenbStats->sch.ulSumCqi += rgSCHCmnUlGetCqi(cell, ue, ueCtg); + cell->tenbStats->sch.ulNumCqi ++; + } +#endif + + RETVOID; +} /* rgSCHCmnUlCqiInd */ + +/** + * @brief Returns HARQ proc for which data expected now. + * + * @details + * + * Function: rgSCHCmnUlHqProcForUe + * Purpose: This function returns the harq process for + * which data is expected in the current subframe. + * It does not validate that the HARQ process + * has an allocation. + * + * Invoked by: TOM + * + * @param[in] RgSchCellCb *cell + * @param[in] CmLteTimingInfo frm + * @param[in] RgSchUeCb *ue + * @param[out] RgSchUlHqProcCb **procRef + * @return Void + **/ +#ifdef ANSI +PUBLIC Void rgSCHCmnUlHqProcForUe +( +RgSchCellCb *cell, +CmLteTimingInfo frm, +RgSchUeCb *ue, +RgSchUlHqProcCb **procRef +) +#else +PUBLIC Void rgSCHCmnUlHqProcForUe(cell, frm, ue, procRef) +RgSchCellCb *cell; +CmLteTimingInfo frm; +RgSchUeCb *ue; +RgSchUlHqProcCb **procRef; +#endif +{ +#ifndef RG_5GTF + U8 procId = rgSCHCmnGetUlHqProcIdx(&frm, cell); +#endif + TRC2(rgSCHCmnUlHqProcForUe); +#ifndef RG_5GTF + *procRef = rgSCHUhmGetUlHqProc(cell, ue, procId); +#else + *procRef = rgSCHUhmGetUlProcByTime(cell, ue, frm); +#endif + RETVOID; +} + +#ifdef RG_UNUSED +/** + * @brief Update harq process for allocation. + * + * @details + * + * Function : rgSCHCmnUpdUlHqProc + * + * This function is invoked when harq process + * control block is now in a new memory location + * thus requiring a pointer/reference update. + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUlHqProcCb *curProc + * @param[in] RgSchUlHqProcCb *oldProc + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 rgSCHCmnUpdUlHqProc +( +RgSchCellCb *cell, +RgSchUlHqProcCb *curProc, +RgSchUlHqProcCb *oldProc +) +#else +PUBLIC S16 rgSCHCmnUpdUlHqProc(cell, curProc, oldProc) +RgSchCellCb *cell; +RgSchUlHqProcCb *curProc; +RgSchUlHqProcCb *oldProc; +#endif +{ + TRC2(rgSCHCmnUpdUlHqProc); + + UNUSED(cell); + UNUSED(oldProc); +#if (ERRCLASS & ERRCLS_DEBUG) + if (curProc->alloc == NULLP) + { + RETVALUE(RFAILED); + } +#endif + curProc->alloc->hqProc = curProc; + RETVALUE(ROK); +} /* rgSCHCmnUpdUlHqProc */ +#endif + +/*MS_WORKAROUND for CR FIXME */ +/** + * @brief Hsndles BSR timer expiry + * + * @details + * + * Function : rgSCHCmnBsrTmrExpry + * + * This function is invoked when periodic BSR timer expires for a UE. + * + * @param[in] RgSchUeCb *ue + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 rgSCHCmnBsrTmrExpry +( +RgSchUeCb *ueCb +) +#else +PUBLIC S16 rgSCHCmnBsrTmrExpry(ueCb) +RgSchUeCb *ueCb; +#endif +{ + RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(ueCb->cell); + + TRC2(rgSCHCmnBsrTmrExpry) + + ueCb->isSrGrant = TRUE; + +#ifdef EMTC_ENABLE + emtcStatsUlBsrTmrTxp++; +#endif + +#ifdef EMTC_ENABLE + if(ueCb->cell->emtcEnable) + { + if(ueCb->isEmtcUe) + { + cellSch->apisEmtcUl->rgSCHSrRcvd(ueCb->cell, ueCb); + RETVALUE(ROK); + } + } + else +#endif + { + cellSch->apisUl->rgSCHSrRcvd(ueCb->cell, ueCb); + } + + RETVALUE (ROK); +} + +/** + * @brief Short BSR update. + * + * @details + * + * Function : rgSCHCmnUpdBsrShort + * + * This functions does requisite updates to handle short BSR reporting. + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ue + * @param[in] RgSchLcgCb *ulLcg + * @param[in] U8 bsr + * @param[out] RgSchErrInfo *err + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 rgSCHCmnUpdBsrShort +( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgSchLcgCb *ulLcg, +U8 bsr, +RgSchErrInfo *err +) +#else +PUBLIC S16 rgSCHCmnUpdBsrShort(cell, ue, ulLcg, bsr, err) +RgSchCellCb *cell; +RgSchUeCb *ue; +RgSchLcgCb *ulLcg; +U8 bsr; +RgSchErrInfo *err; +#endif +{ + U8 lcgCnt; +#ifdef LTE_L2_MEAS + RgSchCmnUlUe *ueUl = RG_SCH_CMN_GET_UL_UE(ue,cell); +#endif + RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell); + RgSchCmnLcg *cmnLcg = NULLP; + +#ifdef LTE_L2_MEAS + U8 idx; +#endif + TRC2(rgSCHCmnUpdBsrShort); + + if (!RGSCH_LCG_ISCFGD(ulLcg)) + { + err->errCause = RGSCHERR_SCH_LCG_NOT_CFGD; + RETVALUE(RFAILED); + } + for (lcgCnt=0; lcgCnt<4; lcgCnt++) + { +#ifdef LTE_L2_MEAS + /* Set BS of all other LCGs to Zero. + If Zero BSR is reported in Short BSR include this LCG too */ + if ((lcgCnt != ulLcg->lcgId) || + (!bsr && !ueUl->hqEnt.numBusyHqProcs)) + { + /* If old BO is zero do nothing */ + if(((RgSchCmnLcg *)(ue->ul.lcgArr[lcgCnt].sch))->bs != 0) + { + for(idx = 0; idx < ue->ul.lcgArr[lcgCnt].numLch; idx++) + { + if((ue->ul.lcgArr[lcgCnt].lcArray[idx]->qciCb->ulUeCount) && + (ue->ulActiveLCs & (1 << + (ue->ul.lcgArr[lcgCnt].lcArray[idx]->qciCb->qci -1)))) + { + /* L2_COUNTER */ + ue->ul.lcgArr[lcgCnt].lcArray[idx]->qciCb->ulUeCount--; + ue->ulActiveLCs &= ~(1 << + (ue->ul.lcgArr[lcgCnt].lcArray[idx]->qciCb->qci -1)); + } + } + } + } +#endif + if (RGSCH_LCG_ISCFGD(&ue->ul.lcgArr[lcgCnt])) + { + ((RgSchCmnLcg *)(ue->ul.lcgArr[lcgCnt].sch))->bs = 0; + ((RgSchCmnLcg *)(ue->ul.lcgArr[lcgCnt].sch))->reportedBs = 0; + } + } + +#ifdef LTE_L2_MEAS + if(ulLcg->lcgId && bsr && (((RgSchCmnLcg *)(ulLcg->sch))->bs == 0)) + { + for(idx = 0; idx < ulLcg->numLch; idx++) + { + /* L2_COUNTER */ + if (!(ue->ulActiveLCs & (1 << (ulLcg->lcArray[idx]->qciCb->qci -1)))) + { + ulLcg->lcArray[idx]->qciCb->ulUeCount++; + ue->ulActiveLCs |= (1 << (ulLcg->lcArray[idx]->qciCb->qci -1)); + } + } + } +#endif + /* Resetting the nonGbrLcgBs info here */ + ue->ul.nonGbrLcgBs = 0; + ue->ul.nonLcg0Bs = 0; + + cmnLcg = ((RgSchCmnLcg *)(ulLcg->sch)); + + if (TRUE == ue->ul.useExtBSRSizes) + { + cmnLcg->reportedBs = rgSchCmnExtBsrTbl[bsr]; + } + else + { + cmnLcg->reportedBs = rgSchCmnBsrTbl[bsr]; + } + if (RGSCH_IS_GBR_BEARER(cmnLcg->cfgdGbr)) + { + /* TBD check for effGbr != 0 */ + cmnLcg->bs = RGSCH_MIN(cmnLcg->reportedBs, cmnLcg->effGbr + cmnLcg->effDeltaMbr); + } + else if (0 == ulLcg->lcgId) + { + /* This is added for handling LCG0 */ + cmnLcg->bs = cmnLcg->reportedBs; + } + else + { + /* Update non GBR LCG's BS*/ + ue->ul.nonGbrLcgBs = RGSCH_MIN(cmnLcg->reportedBs,ue->ul.effAmbr); + cmnLcg->bs = ue->ul.nonGbrLcgBs; + } + ue->ul.totalBsr = cmnLcg->bs; + +#ifdef RGR_V1 + if ((ue->bsrTmr.tmrEvnt != TMR_NONE) && (bsr == 0)) + { + rgSCHTmrStopTmr(cell, ue->bsrTmr.tmrEvnt, ue); + } +#endif +#ifdef LTEMAC_SPS + if (ue->ul.ulSpsCfg.isUlSpsEnabled == TRUE) + { + rgSCHCmnSpsBsrRpt(cell, ue, ulLcg); + } +#endif + rgSCHCmnUpdUlCompEffBsr(ue); + +#ifdef EMTC_ENABLE + if(cell->emtcEnable) + { + if(ue->isEmtcUe) + { + cellSch->apisEmtcUl->rgSCHUpdBsrShort(cell, ue, ulLcg, bsr); + RETVALUE(ROK); + } + } + else +#endif + { + cellSch->apisUl->rgSCHUpdBsrShort(cell, ue, ulLcg, bsr); + } + +#ifdef LTE_ADV + if (ue->ul.isUlCaEnabled && ue->numSCells) + { + for(U8 sCellIdx = 1; sCellIdx <= RG_SCH_MAX_SCELL ; sCellIdx++) + { +#ifndef PAL_ENABLE_UL_CA + if((ue->cellInfo[sCellIdx] != NULLP) && + (ue->cellInfo[sCellIdx]->sCellState == RG_SCH_SCELL_ACTIVE)) +#else + if(ue->cellInfo[sCellIdx] != NULLP) +#endif + { + cellSch->apisUl->rgSCHUpdBsrShort(ue->cellInfo[sCellIdx]->cell, + ue, ulLcg, bsr); + } + } + } +#endif + + RETVALUE(ROK); +} + +/** + * @brief Truncated BSR update. + * + * @details + * + * Function : rgSCHCmnUpdBsrTrunc + * + * This functions does required updates to handle truncated BSR report. + * + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ue + * @param[in] RgSchLcgCb *ulLcg + * @param[in] U8 bsr + * @param[out] RgSchErrInfo *err + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 rgSCHCmnUpdBsrTrunc +( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgSchLcgCb *ulLcg, +U8 bsr, +RgSchErrInfo *err +) +#else +PUBLIC S16 rgSCHCmnUpdBsrTrunc(cell, ue, ulLcg, bsr, err) +RgSchCellCb *cell; +RgSchUeCb *ue; +RgSchLcgCb *ulLcg; +U8 bsr; +RgSchErrInfo *err; +#endif +{ + RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell); + RgSchCmnLcg *cmnLcg = NULLP; + S32 cnt; +#ifdef LTE_L2_MEAS + U8 idx; +#endif + + TRC2(rgSCHCmnUpdBsrTrunc); + + if (!RGSCH_LCG_ISCFGD(ulLcg)) + { + err->errCause = RGSCHERR_SCH_LCG_NOT_CFGD; + RETVALUE(RFAILED); + } + /* set all higher prio lcgs bs to 0 and update this lcgs bs and + total bsr= sumofall lcgs bs */ + if (ulLcg->lcgId) + { + for (cnt = ulLcg->lcgId-1; cnt >= 0; cnt--) + { +#ifdef LTE_L2_MEAS + /* If Existing BO is zero the don't do anything */ + if(((RgSchCmnLcg *)(ue->ul.lcgArr[cnt].sch))->bs != 0) + { + for(idx = 0; idx < ue->ul.lcgArr[cnt].numLch; idx++) + { + /* L2_COUNTERS */ + if((ue->ul.lcgArr[cnt].lcArray[idx]->qciCb->ulUeCount) && + (ue->ulActiveLCs & (1 << + (ue->ul.lcgArr[cnt].lcArray[idx]->qciCb->qci -1)))) + { + ue->ul.lcgArr[cnt].lcArray[idx]->qciCb->ulUeCount--; + ue->ulActiveLCs &= ~(1 << + (ue->ul.lcgArr[cnt].lcArray[idx]->qciCb->qci -1)); + } + } + } +#endif + ((RgSchCmnLcg *)(ue->ul.lcgArr[cnt].sch))->bs = 0; + ((RgSchCmnLcg *)(ue->ul.lcgArr[cnt].sch))->reportedBs = 0; + } + } + +#ifdef LTE_L2_MEAS + for (cnt = ulLcg->lcgId; cnt < RGSCH_MAX_LCG_PER_UE; cnt++) + { + if (ulLcg->lcgId == 0) + { + continue; + } + /* If Existing BO is zero the don't do anything */ + if(((RgSchCmnLcg *)(ue->ul.lcgArr[cnt].sch))->bs == 0) + { + for(idx = 0; idx < ue->ul.lcgArr[cnt].numLch; idx++) + { + /* L2_COUNTERS */ + if (!(ue->ulActiveLCs & (1 << + (ue->ul.lcgArr[cnt].lcArray[idx]->qciCb->qci -1)))) + { + ue->ul.lcgArr[cnt].lcArray[idx]->qciCb->ulUeCount++; + ue->ulActiveLCs |= (1 << + (ue->ul.lcgArr[cnt].lcArray[idx]->qciCb->qci -1)); + } + } + } + } +#endif + ue->ul.nonGbrLcgBs = 0; + ue->ul.nonLcg0Bs = 0; + cmnLcg = ((RgSchCmnLcg *)(ulLcg->sch)); + if (TRUE == ue->ul.useExtBSRSizes) + { + cmnLcg->reportedBs = rgSchCmnExtBsrTbl[bsr]; + } + else + { + cmnLcg->reportedBs = rgSchCmnBsrTbl[bsr]; + } + if (RGSCH_IS_GBR_BEARER(cmnLcg->cfgdGbr)) + { + cmnLcg->bs = RGSCH_MIN(cmnLcg->reportedBs, cmnLcg->effGbr + cmnLcg->effDeltaMbr); + } + else if(ulLcg->lcgId == 0) + { + /* This is for handeling LCG0 */ + cmnLcg->bs = cmnLcg->reportedBs; + } + else + { + ue->ul.nonGbrLcgBs = RGSCH_MIN(cmnLcg->reportedBs, ue->ul.effAmbr); + cmnLcg->bs = ue->ul.nonGbrLcgBs; + } + ue->ul.totalBsr = cmnLcg->bs; + + for (cnt = ulLcg->lcgId+1; cnt < RGSCH_MAX_LCG_PER_UE; cnt++) + { + /* TODO: The bs for the other LCGs may be stale because some or all of + * the part of bs may have been already scheduled/data received. Please + * consider this when truncated BSR is tested/implemented */ + ue->ul.totalBsr += ((RgSchCmnLcg *)(ue->ul.lcgArr[cnt].sch))->bs; + } + + rgSCHCmnUpdUlCompEffBsr(ue); + +#ifdef EMTC_ENABLE + if(cell->emtcEnable) + { + if(ue->isEmtcUe) + { + cellSch->apisEmtcUl->rgSCHUpdBsrTrunc(cell, ue, ulLcg, bsr); + RETVALUE(ROK); + } + } + else +#endif + { + cellSch->apisUl->rgSCHUpdBsrTrunc(cell, ue, ulLcg, bsr); + } + +#ifdef LTE_ADV + if (ue->ul.isUlCaEnabled && ue->numSCells) + { + for(U8 sCellIdx = 1; sCellIdx <= RG_SCH_MAX_SCELL ; sCellIdx++) + { +#ifndef PAL_ENABLE_UL_CA + if((ue->cellInfo[sCellIdx] != NULLP) && + (ue->cellInfo[sCellIdx]->sCellState == RG_SCH_SCELL_ACTIVE)) +#else + if(ue->cellInfo[sCellIdx] != NULLP) +#endif + { + cellSch->apisUl->rgSCHUpdBsrTrunc(ue->cellInfo[sCellIdx]->cell, ue, ulLcg, bsr); + } + } + } +#endif + + RETVALUE(ROK); +} + +/** + * @brief Long BSR update. + * + * @details + * + * Function : rgSCHCmnUpdBsrLong + * + * - Update BSRs for all configured LCGs. + * - Update priority of LCGs if needed. + * - Update UE's position within/across uplink scheduling queues. + * + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ue + * @param[in] U8 bsArr[] + * @param[out] RgSchErrInfo *err + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 rgSCHCmnUpdBsrLong +( +RgSchCellCb *cell, +RgSchUeCb *ue, +U8 *bsArr, +RgSchErrInfo *err +) +#else +PUBLIC S16 rgSCHCmnUpdBsrLong(cell, ue, bsArr, err) +RgSchCellCb *cell; +RgSchUeCb *ue; +U8 *bsArr; +RgSchErrInfo *err; +#endif +{ + RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell); + U32 tmpBsArr[4] = {0, 0, 0, 0}; + U32 nonGbrBs = 0; +#ifdef LTE_L2_MEAS + U8 idx1; + U8 idx2; +#endif + U32 lcgId; + + TRC2(rgSCHCmnUpdBsrLong); + +#ifdef LTE_L2_MEAS + for(idx1 = 1; idx1 < RGSCH_MAX_LCG_PER_UE; idx1++) + { + /* If Old BO is non zero then do nothing */ + if ((((RgSchCmnLcg *)(ue->ul.lcgArr[idx1].sch))->bs == 0) + && bsArr[idx1] ) + { + for(idx2 = 0; idx2 < ue->ul.lcgArr[idx1].numLch; idx2++) + { + /* L2_COUNTERS */ + if (!(ue->ulActiveLCs & (1 << + (ue->ul.lcgArr[idx1].lcArray[idx2]->qciCb->qci -1)))) + { + ue->ul.lcgArr[idx1].lcArray[idx2]->qciCb->ulUeCount++; + ue->ulActiveLCs |= (1 << + (ue->ul.lcgArr[idx1].lcArray[idx2]->qciCb->qci -1)); + } + } + } + } +#endif + ue->ul.nonGbrLcgBs = 0; + ue->ul.nonLcg0Bs = 0; + + if (RGSCH_LCG_ISCFGD(&ue->ul.lcgArr[0])) + { + if (TRUE == ue->ul.useExtBSRSizes) + { + ((RgSchCmnLcg *)(ue->ul.lcgArr[0].sch))->bs = rgSchCmnExtBsrTbl[bsArr[0]]; + ((RgSchCmnLcg *)(ue->ul.lcgArr[0].sch))->reportedBs = rgSchCmnExtBsrTbl[bsArr[0]]; + tmpBsArr[0] = rgSchCmnExtBsrTbl[bsArr[0]]; + } + else + { + ((RgSchCmnLcg *)(ue->ul.lcgArr[0].sch))->bs = rgSchCmnBsrTbl[bsArr[0]]; + ((RgSchCmnLcg *)(ue->ul.lcgArr[0].sch))->reportedBs = rgSchCmnBsrTbl[bsArr[0]]; + tmpBsArr[0] = rgSchCmnBsrTbl[bsArr[0]]; + } + } + for (lcgId = 1; lcgId < RGSCH_MAX_LCG_PER_UE; lcgId++) + { + if (RGSCH_LCG_ISCFGD(&ue->ul.lcgArr[lcgId])) + { + RgSchCmnLcg *cmnLcg = ((RgSchCmnLcg *)(ue->ul.lcgArr[lcgId].sch)); + + if (TRUE == ue->ul.useExtBSRSizes) + { + cmnLcg->reportedBs = rgSchCmnExtBsrTbl[bsArr[lcgId]]; + } + else + { + cmnLcg->reportedBs = rgSchCmnBsrTbl[bsArr[lcgId]]; + } + if (RGSCH_IS_GBR_BEARER(cmnLcg->cfgdGbr)) + { + cmnLcg->bs = RGSCH_MIN(cmnLcg->reportedBs, cmnLcg->effGbr + cmnLcg->effDeltaMbr); + tmpBsArr[lcgId] = cmnLcg->bs; + } + else + { + nonGbrBs += cmnLcg->reportedBs; + tmpBsArr[lcgId] = cmnLcg->reportedBs; + cmnLcg->bs = RGSCH_MIN(cmnLcg->reportedBs,ue->ul.effAmbr); + } + } + } + ue->ul.nonGbrLcgBs = RGSCH_MIN(nonGbrBs,ue->ul.effAmbr); + + ue->ul.totalBsr = tmpBsArr[0] + tmpBsArr[1] + tmpBsArr[2] + tmpBsArr[3]; +#ifdef RGR_V1 + if ((ue->bsrTmr.tmrEvnt != TMR_NONE) && (ue->ul.totalBsr == 0)) + { + rgSCHTmrStopTmr(cell, ue->bsrTmr.tmrEvnt, ue); + } +#endif + +#ifdef LTEMAC_SPS + if (ue->ul.ulSpsCfg.isUlSpsEnabled == TRUE) /* SPS_FIX */ + { + if(ue->ul.totalBsr - tmpBsArr[1] == 0) + {/* Updaing the BSR to SPS only if LCG1 BS is present in sps active state */ + rgSCHCmnSpsBsrRpt(cell, ue, &ue->ul.lcgArr[1]); + } + } +#endif + rgSCHCmnUpdUlCompEffBsr(ue); + +#ifdef EMTC_ENABLE + if(cell->emtcEnable) + { + if(ue->isEmtcUe) + { + cellSch->apisEmtcUl->rgSCHUpdBsrLong(cell, ue, bsArr); + RETVALUE(ROK); + } + } + else +#endif + { + cellSch->apisUl->rgSCHUpdBsrLong(cell, ue, bsArr); + } + +#ifdef LTE_ADV + if (ue->ul.isUlCaEnabled && ue->numSCells) + { + for(U8 idx = 1; idx <= RG_SCH_MAX_SCELL ; idx++) + { +#ifndef PAL_ENABLE_UL_CA + if((ue->cellInfo[idx] != NULLP) && + (ue->cellInfo[idx]->sCellState == RG_SCH_SCELL_ACTIVE)) +#else + if(ue->cellInfo[idx] != NULLP) +#endif + { + cellSch->apisUl->rgSCHUpdBsrLong(ue->cellInfo[idx]->cell, ue, bsArr); + } + } + } +#endif + + RETVALUE(ROK); +} + +/** + * @brief PHR update. + * + * @details + * + * Function : rgSCHCmnUpdExtPhr + * + * Updates extended power headroom information for an UE. + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ue + * @param[in] U8 phr + * @param[out] RgSchErrInfo *err + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 rgSCHCmnUpdExtPhr +( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgInfExtPhrCEInfo *extPhr, +RgSchErrInfo *err +) +#else +PUBLIC S16 rgSCHCmnUpdExtPhr(cell, ue, extPhr, err) +RgSchCellCb *cell; +RgSchUeCb *ue; +RgInfExtPhrCEInfo *extPhr; +RgSchErrInfo *err; +#endif +{ + RgSchCmnUlUe *ueUl = RG_SCH_CMN_GET_UL_UE(ue,cell); + RgSchCmnAllocRecord *allRcd; + CmLList *node = ueUl->ulAllocLst.last; + +#ifdef LTEMAC_SPS + RgSchCmnUlUeSpsInfo *ulSpsUe = RG_SCH_CMN_GET_UL_SPS_UE(ue,cell); +#endif + TRC2(rgSCHCmnUpdExtPhr); + + UNUSED(err); + + while (node) + { + allRcd = (RgSchCmnAllocRecord *)node->node; + node = node->prev; + if (RGSCH_TIMEINFO_SAME(ue->macCeRptTime, allRcd->allocTime)) + { + rgSCHPwrUpdExtPhr(cell, ue, extPhr, allRcd); + break; + } + } +#ifdef LTEMAC_SPS + if(ulSpsUe->isUlSpsActv) + { + rgSCHCmnSpsPhrInd(cell,ue); + } +#endif + + RETVALUE(ROK); +} /* rgSCHCmnUpdExtPhr */ + + + + +/** + * @brief PHR update. + * + * @details + * + * Function : rgSCHCmnUpdPhr + * + * Updates power headroom information for an UE. + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ue + * @param[in] U8 phr + * @param[out] RgSchErrInfo *err + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 rgSCHCmnUpdPhr +( +RgSchCellCb *cell, +RgSchUeCb *ue, +U8 phr, +RgSchErrInfo *err +) +#else +PUBLIC S16 rgSCHCmnUpdPhr(cell, ue, phr, err) +RgSchCellCb *cell; +RgSchUeCb *ue; +U8 phr; +RgSchErrInfo *err; +#endif +{ + RgSchCmnUlUe *ueUl = RG_SCH_CMN_GET_UL_UE(ue,cell); + RgSchCmnAllocRecord *allRcd; + CmLList *node = ueUl->ulAllocLst.last; + +#ifdef LTEMAC_SPS + RgSchCmnUlUeSpsInfo *ulSpsUe = RG_SCH_CMN_GET_UL_SPS_UE(ue,cell); +#endif + TRC2(rgSCHCmnUpdPhr); + + UNUSED(err); + + while (node) + { + allRcd = (RgSchCmnAllocRecord *)node->node; + node = node->prev; + if (RGSCH_TIMEINFO_SAME(ue->macCeRptTime, allRcd->allocTime)) + { + rgSCHPwrUpdPhr(cell, ue, phr, allRcd, RG_SCH_CMN_PWR_USE_CFG_MAX_PWR); + break; + } + } +#ifdef LTEMAC_SPS + if(ulSpsUe->isUlSpsActv) + { + rgSCHCmnSpsPhrInd(cell,ue); + } +#endif + + RETVALUE(ROK); +} /* rgSCHCmnUpdPhr */ + +/** + * @brief UL grant for contention resolution. + * + * @details + * + * Function : rgSCHCmnContResUlGrant + * + * Add UE to another queue specifically for CRNTI based contention + * resolution. + * + * + * @param[in] RgSchUeCb *ue + * @param[out] RgSchErrInfo *err + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 rgSCHCmnContResUlGrant +( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgSchErrInfo *err +) +#else +PUBLIC S16 rgSCHCmnContResUlGrant(cell, ue, err) +RgSchCellCb *cell; +RgSchUeCb *ue; +RgSchErrInfo *err; +#endif +{ + RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell); + TRC2(rgSCHCmnContResUlGrant); + + #ifdef EMTC_ENABLE + if(cell->emtcEnable) + { + if(ue->isEmtcUe) + { + cellSch->apisEmtcUl->rgSCHContResUlGrant(cell, ue); + RETVALUE(ROK); + } + } + else +#endif + { + cellSch->apisUl->rgSCHContResUlGrant(cell, ue); + } + RETVALUE(ROK); +} + +/** + * @brief SR reception handling. + * + * @details + * + * Function : rgSCHCmnSrRcvd + * + * - Update UE's position within/across uplink scheduling queues + * - Update priority of LCGs if needed. + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ue + * @param[in] CmLteTimingInfo frm + * @param[out] RgSchErrInfo *err + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 rgSCHCmnSrRcvd +( +RgSchCellCb *cell, +RgSchUeCb *ue, +CmLteTimingInfo frm, +RgSchErrInfo *err +) +#else +PUBLIC S16 rgSCHCmnSrRcvd(cell, ue, frm, err) +RgSchCellCb *cell; +RgSchUeCb *ue; +CmLteTimingInfo frm; +RgSchErrInfo *err; +#endif +{ + RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell); + RgSchCmnUlUe *ueUl = RG_SCH_CMN_GET_UL_UE(ue,cell); + CmLList *node = ueUl->ulAllocLst.last; + + TRC2(rgSCHCmnSrRcvd); + +#ifdef EMTC_ENABLE + emtcStatsUlTomSrInd++; +#endif + + RGSCH_INCR_SUB_FRAME(frm, 1); /* 1 TTI after the time SR was sent */ + while (node) + { + RgSchCmnAllocRecord *allRcd = (RgSchCmnAllocRecord *)node->node; + if (RGSCH_TIMEINFO_SAME(frm, allRcd->allocTime)) + { + break; + } + node = node->prev; + } + //TODO_SID Need to check when it is getting triggered + ue->isSrGrant = TRUE; +#ifdef EMTC_ENABLE + if(cell->emtcEnable) + { + if(ue->isEmtcUe) + { + cellSch->apisEmtcUl->rgSCHSrRcvd(cell, ue); + RETVALUE(ROK); + } + } + else +#endif + { + cellSch->apisUl->rgSCHSrRcvd(cell, ue); + } + RETVALUE(ROK); +} + +/** + * @brief Returns first uplink allocation to send reception + * request to PHY. + * + * @details + * + * Function: rgSCHCmnFirstRcptnReq(cell) + * Purpose: This function returns the first uplink allocation + * (or NULLP if there is none) in the subframe + * in which is expected to prepare and send reception + * request to PHY. + * + * Invoked by: TOM + * + * @param[in] RgSchCellCb *cell + * @return RgSchUlAlloc* + **/ +#ifdef ANSI +PUBLIC RgSchUlAlloc *rgSCHCmnFirstRcptnReq +( +RgSchCellCb *cell +) +#else +PUBLIC RgSchUlAlloc *rgSCHCmnFirstRcptnReq(cell) +RgSchCellCb *cell; +#endif +{ + RgSchCmnUlCell *cellUl = RG_SCH_CMN_GET_UL_CELL(cell); +/* ACC_TDD */ + RgSchUlAlloc* alloc = NULLP; + + TRC2(rgSCHCmnFirstRcptnReq); + + if (cellUl->rcpReqIdx != RGSCH_INVALID_INFO) + { + RgSchUlSf* sf = &cellUl->ulSfArr[cellUl->rcpReqIdx]; + alloc = rgSCHUtlUlAllocFirst(sf); + + if (alloc && alloc->hqProc == NULLP) + { + alloc = rgSCHUtlUlAllocNxt(sf, alloc); + } + } + + RETVALUE(alloc); +} + +/** + * @brief Returns first uplink allocation to send reception + * request to PHY. + * + * @details + * + * Function: rgSCHCmnNextRcptnReq(cell) + * Purpose: This function returns the next uplink allocation + * (or NULLP if there is none) in the subframe + * in which is expected to prepare and send reception + * request to PHY. + * + * Invoked by: TOM + * + * @param[in] RgSchCellCb *cell + * @return RgSchUlAlloc* + **/ +#ifdef ANSI +PUBLIC RgSchUlAlloc *rgSCHCmnNextRcptnReq +( +RgSchCellCb *cell, +RgSchUlAlloc *alloc +) +#else +PUBLIC RgSchUlAlloc *rgSCHCmnNextRcptnReq(cell, alloc) +RgSchCellCb *cell; +RgSchUlAlloc *alloc; +#endif +{ + RgSchCmnUlCell *cellUl = RG_SCH_CMN_GET_UL_CELL(cell); +/* ACC-TDD */ + //RgSchUlSf *sf = &cellUl->ulSfArr[cellUl->rcpReqIdx]; + + TRC2(rgSCHCmnNextRcptnReq); +/* ACC-TDD */ + if (cellUl->rcpReqIdx != RGSCH_INVALID_INFO) + { + RgSchUlSf *sf = &cellUl->ulSfArr[cellUl->rcpReqIdx]; + + alloc = rgSCHUtlUlAllocNxt(sf, alloc); + if (alloc && alloc->hqProc == NULLP) + { + alloc = rgSCHUtlUlAllocNxt(sf, alloc); + } + } + else + { + alloc = NULLP; + } + + RETVALUE(alloc); +} +/** + * @brief Collates DRX enabled UE's scheduled in this SF + * + * @details + * + * Function: rgSCHCmnDrxStrtInActvTmrInUl(cell) + * Purpose: This function collates the link + * of UE's scheduled in this SF who + * have drx enabled. It then calls + * DRX specific function to start/restart + * inactivity timer in Ul + * + * Invoked by: TOM + * + * @param[in] RgSchCellCb *cell + * @return Void + **/ +#ifdef ANSI +PUBLIC Void rgSCHCmnDrxStrtInActvTmrInUl +( +RgSchCellCb *cell +) +#else +PUBLIC Void rgSCHCmnDrxStrtInActvTmrInUl(cell) +RgSchCellCb *cell; +#endif +{ + RgSchCmnUlCell *cellUl = RG_SCH_CMN_GET_UL_CELL(cell); + RgSchUlSf *sf = &(cellUl->ulSfArr[cellUl->schdIdx]); + RgSchUlAlloc *alloc = rgSCHUtlUlAllocFirst(sf); + CmLListCp ulUeLst; + RgSchUeCb *ueCb; + + + TRC2(rgSCHCmnDrxStrtInActvTmrInUl); + + cmLListInit(&ulUeLst); + + while(alloc) + { + ueCb = alloc->ue; + + if (ueCb) + { + if (!(alloc->grnt.isRtx) && ueCb->isDrxEnabled && !(ueCb->isSrGrant) +#ifdef LTEMAC_SPS + /* ccpu00139513- DRX inactivity timer should not be started for + * UL SPS occasions */ + && (alloc->hqProc->isSpsOccnHqP == FALSE) +#endif + ) + { + cmLListAdd2Tail(&ulUeLst,&(ueCb->ulDrxInactvTmrLnk)); + ueCb->ulDrxInactvTmrLnk.node = (PTR)ueCb; + } + } + + alloc = rgSCHUtlUlAllocNxt(sf, alloc); + }/*while(alloc)*/ + + (Void)rgSCHDrxStrtInActvTmr(cell,&ulUeLst,RG_SCH_DRX_UL); + + RETVOID; +} + + +/** + * @brief Returns first uplink allocation to send HARQ feedback + * request to PHY. + * + * @details + * + * Function: rgSCHCmnFirstHqFdbkAlloc + * Purpose: This function returns the first uplink allocation + * (or NULLP if there is none) in the subframe + * for which it is expected to prepare and send HARQ + * feedback to PHY. + * + * Invoked by: TOM + * + * @param[in] RgSchCellCb *cell + * @param[in] U8 idx + * @return RgSchUlAlloc* + **/ +#ifdef ANSI +PUBLIC RgSchUlAlloc *rgSCHCmnFirstHqFdbkAlloc +( +RgSchCellCb *cell, +U8 idx +) +#else +PUBLIC RgSchUlAlloc *rgSCHCmnFirstHqFdbkAlloc(cell, idx) +RgSchCellCb *cell; +U8 idx; +#endif +{ + RgSchCmnUlCell *cellUl = RG_SCH_CMN_GET_UL_CELL(cell); +/* ACC-TDD */ + RgSchUlAlloc *alloc = NULLP; + + TRC2(rgSCHCmnFirstHqFdbkAlloc); + + if (cellUl->hqFdbkIdx[idx] != RGSCH_INVALID_INFO) + { + RgSchUlSf *sf = &cellUl->ulSfArr[cellUl->hqFdbkIdx[idx]]; + alloc = rgSCHUtlUlAllocFirst(sf); + + while (alloc && (alloc->hqProc == NULLP)) + { + alloc = rgSCHUtlUlAllocNxt(sf, alloc); + } + } + + RETVALUE(alloc); +} + +/** + * @brief Returns next allocation to send HARQ feedback for. + * + * @details + * + * Function: rgSCHCmnNextHqFdbkAlloc(cell) + * Purpose: This function returns the next uplink allocation + * (or NULLP if there is none) in the subframe + * for which HARQ feedback needs to be sent. + * + * Invoked by: TOM + * + * @param[in] RgSchCellCb *cell + * @return RgSchUlAlloc* + **/ +#ifdef ANSI +PUBLIC RgSchUlAlloc *rgSCHCmnNextHqFdbkAlloc +( +RgSchCellCb *cell, +RgSchUlAlloc *alloc, +U8 idx +) +#else +PUBLIC RgSchUlAlloc *rgSCHCmnNextHqFdbkAlloc(cell, alloc, idx) +RgSchCellCb *cell; +RgSchUlAlloc *alloc; +U8 idx; +#endif +{ + RgSchCmnUlCell *cellUl = RG_SCH_CMN_GET_UL_CELL(cell); + TRC2(rgSCHCmnNextHqFdbkAlloc); + + if (cellUl->hqFdbkIdx[idx] != RGSCH_INVALID_INFO) + { + RgSchUlSf *sf = &cellUl->ulSfArr[cellUl->hqFdbkIdx[idx]]; + + alloc = rgSCHUtlUlAllocNxt(sf, alloc); + while (alloc && (alloc->hqProc == NULLP)) + { + alloc = rgSCHUtlUlAllocNxt(sf, alloc); + } + } + else + { + alloc = NULLP; + } + RETVALUE(alloc); +} + +/*********************************************************** + * + * Func : rgSCHCmnUlGetITbsFrmIMcs + * + * Desc : Returns the Itbs that is mapped to an Imcs + * for the case of uplink. + * + * Ret : + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PUBLIC U8 rgSCHCmnUlGetITbsFrmIMcs +( +U8 iMcs +) +#else +PUBLIC U8 rgSCHCmnUlGetITbsFrmIMcs(iMcs) +U8 iMcs; +#endif +{ + TRC2(rgSCHCmnUlGetITbsFrmIMcs); + + RETVALUE(rgUlIMcsTbl[iMcs].iTbs); +} + +/*********************************************************** + * + * Func : rgSCHCmnUlGetIMcsFrmITbs + * + * Desc : Returns the Imcs that is mapped to an Itbs + * for the case of uplink. + * + * Ret : + * + * Notes: For iTbs 19, iMcs is dependant on modulation order. + * Refer to 36.213, Table 8.6.1-1 and 36.306 Table 4.1-2 + * for UE capability information + * + * File : + * + **********************************************************/ +#ifdef ANSI +PUBLIC U8 rgSCHCmnUlGetIMcsFrmITbs +( +U8 iTbs, +CmLteUeCategory ueCtg +) +#else +PUBLIC U8 rgSCHCmnUlGetIMcsFrmITbs(iTbs, ueCtg) +U8 iTbs; +CmLteUeCategory ueCtg; +#endif +{ + U8 iMcs; + TRC2(rgSCHCmnUlGetIMcsFrmITbs); + + if (iTbs <= 10) + { + iMcs = iTbs; + } + /*a higher layer can force a 64QAM UE to transmit at 16QAM. + * We currently do not support this. Once the support for such + * is added, ueCtg should be replaced by current transmit + * modulation configuration.Refer to 36.213 -8.6.1 + */ + else if ( iTbs < 19 ) + { + iMcs = iTbs + 1; + } + else if ((iTbs == 19) && (ueCtg != CM_LTE_UE_CAT_5)) + { + iMcs = iTbs + 1; + } + else + { + iMcs = iTbs + 2; + } + +#ifdef LTE_TDD + /* This is a Temp fix, done for TENBPLUS-3898, ULSCH SDU corruption + was seen when IMCS exceeds 20 on T2k TDD*/ + if (iMcs > 20) + { + iMcs = 20; + } +#endif + + RETVALUE(iMcs); +} + +/*********************************************************** + * + * Func : rgSCHCmnUlMinTbBitsForITbs + * + * Desc : Returns the minimum number of bits that can + * be given as grant for a specific CQI. + * + * Ret : + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PUBLIC U32 rgSCHCmnUlMinTbBitsForITbs +( +RgSchCmnUlCell *cellUl, +U8 iTbs +) +#else +PUBLIC U32 rgSCHCmnUlMinTbBitsForITbs(cellUl, iTbs) +RgSchCmnUlCell *cellUl; +U8 iTbs; +#endif +{ + TRC2(rgSCHCmnUlMinTbBitsForITbs); + + RGSCH_ARRAY_BOUND_CHECK(0, rgTbSzTbl[0], iTbs); + + RETVALUE(rgTbSzTbl[0][iTbs][cellUl->sbSize-1]); +} + +/*********************************************************** + * + * Func : rgSCHCmnUlSbAlloc + * + * Desc : Given a required 'number of subbands' and a hole, + * returns a suitable alloc such that the subband + * allocation size is valid + * + * Ret : + * + * Notes: Does not assume either passed numSb or hole size + * to be valid for allocation, and hence arrives at + * an acceptable value. + * File : + * + **********************************************************/ +#ifdef ANSI +PUBLIC RgSchUlAlloc *rgSCHCmnUlSbAlloc +( +RgSchUlSf *sf, +U8 numSb, +RgSchUlHole *hole +) +#else +PUBLIC RgSchUlAlloc *rgSCHCmnUlSbAlloc(sf, numSb, hole) +RgSchUlSf *sf; +U8 numSb; +RgSchUlHole *hole; +#endif +{ + U8 holeSz; /* valid hole size */ + RgSchUlAlloc *alloc; + TRC2(rgSCHCmnUlSbAlloc); + + if ((holeSz = rgSchCmnMult235Tbl[hole->num].prvMatch) == hole->num) + { + numSb = rgSchCmnMult235Tbl[numSb].match; + if (numSb >= holeSz) + { + alloc = rgSCHUtlUlAllocGetCompHole(sf, hole); + } + else + { + alloc = rgSCHUtlUlAllocGetPartHole(sf, numSb, hole); + } + } + else + { + if (numSb < holeSz) + { + numSb = rgSchCmnMult235Tbl[numSb].match; + } + else + { + numSb = rgSchCmnMult235Tbl[numSb].prvMatch; + } + + if ( numSb >= holeSz ) + { + numSb = holeSz; + } + alloc = rgSCHUtlUlAllocGetPartHole(sf, numSb, hole); + } + RETVALUE(alloc); +} + +/** + * @brief To fill the RgSchCmnUeUlAlloc structure of UeCb. + * + * @details + * + * Function: rgSCHCmnUlUeFillAllocInfo + * Purpose: Specific scheduler to call this API to fill the alloc + * information. + * + * Invoked by: Scheduler + * + * @param[in] RgSchCellCb *cell + * @param[out] RgSchUeCb *ue + * @return Void + **/ +#ifdef ANSI +PUBLIC Void rgSCHCmnUlUeFillAllocInfo +( +RgSchCellCb *cell, +RgSchUeCb *ue +) +#else +PUBLIC Void rgSCHCmnUlUeFillAllocInfo(cell, ue) +RgSchCellCb *cell; +RgSchUeCb *ue; +#endif +{ + RgSchCmnUlCell *cellUl = RG_SCH_CMN_GET_UL_CELL(cell); + RgSchCmnUeUlAlloc *ulAllocInfo; + RgSchCmnUlUe *ueUl; + + TRC2(rgSCHCmnUlUeFillAllocInfo); + + ueUl = RG_SCH_CMN_GET_UL_UE(ue,cell); + ulAllocInfo = &ueUl->alloc; + + /* Fill alloc structure */ + rgSCHCmnUlAllocFillTpc(cell, ue, ulAllocInfo->alloc); + rgSCHCmnUlAllocFillNdmrs(cellUl, ulAllocInfo->alloc); + rgSCHCmnUlAllocLnkHqProc(ue, ulAllocInfo->alloc, ulAllocInfo->alloc->hqProc, + ulAllocInfo->alloc->hqProc->isRetx); + /* Fill PDCCH */ + rgSCHCmnUlFillPdcchWithAlloc(ulAllocInfo->alloc->pdcch, + ulAllocInfo->alloc, ue); + /* Recording information about this allocation */ + rgSCHCmnUlRecordUeAlloc(cell, ue); + + /* Update the UE's outstanding allocation */ + if (!ulAllocInfo->alloc->hqProc->isRetx) + { + rgSCHCmnUlUpdOutStndAlloc(cell, ue, ulAllocInfo->allocdBytes); + } + + RETVOID; +} + +/** + * @brief Update the UEs outstanding alloc based on the BSR report's timing. + * + * + * @details + * + * Function: rgSCHCmnUpdUlCompEffBsr + * Purpose: Clear off all the allocations from outstanding allocation that + * are later than or equal to BSR timing information (stored in UEs datIndTime). + * + * Invoked by: Scheduler + * + * @param[in] RgSchUeCb *ue + * @return Void + **/ +#ifdef ANSI +PRIVATE Void rgSCHCmnUpdUlCompEffBsr +( +RgSchUeCb *ue +) +#else +PRIVATE Void rgSCHCmnUpdUlCompEffBsr(ue) +RgSchUeCb *ue; +#endif +{ + RgSchCmnUlUe *ueUl = RG_SCH_CMN_GET_UL_UE(ue,ue->cell); + CmLList *node = ueUl->ulAllocLst.last; + RgSchCmnAllocRecord *allRcd; + U32 outStndAlloc=0; + U32 nonLcg0OutStndAllocBs=0; + U32 nonLcg0Bsr=0; + U8 lcgId; + RgSchCmnLcg *cmnLcg = NULLP; + TRC2(rgSCHCmnUpdUlCompEffBsr); + + while (node) + { + allRcd = (RgSchCmnAllocRecord *)node->node; + if (RGSCH_TIMEINFO_SAME(ue->macCeRptTime, allRcd->allocTime)) + { + node = node->next; + break; + } + node = node->prev; + } + while (node) + { + allRcd = (RgSchCmnAllocRecord *)node->node; + node = node->next; + outStndAlloc += allRcd->alloc; + } + + cmnLcg = (RgSchCmnLcg *)(ue->ul.lcgArr[0].sch); + /* Update UEs LCG0's bs according to the total outstanding BSR allocation.*/ + if (cmnLcg->bs > outStndAlloc) + { + cmnLcg->bs -= outStndAlloc; + ue->ul.minReqBytes = cmnLcg->bs; + outStndAlloc = 0; + } + else + { + nonLcg0OutStndAllocBs = outStndAlloc - cmnLcg->bs; + cmnLcg->bs = 0; + } + + for(lcgId = 1;lcgId < RGSCH_MAX_LCG_PER_UE; lcgId++) + { + if(RGSCH_LCG_ISCFGD(&ue->ul.lcgArr[lcgId])) + { + cmnLcg = ((RgSchCmnLcg *) (ue->ul.lcgArr[lcgId].sch)); + if (RGSCH_IS_GBR_BEARER(cmnLcg->cfgdGbr)) + { + nonLcg0Bsr += cmnLcg->bs; + } + } + } + nonLcg0Bsr += ue->ul.nonGbrLcgBs; + if (nonLcg0OutStndAllocBs > nonLcg0Bsr) + { + nonLcg0Bsr = 0; + } + else + { + nonLcg0Bsr -= nonLcg0OutStndAllocBs; + } + ue->ul.nonLcg0Bs = nonLcg0Bsr; + /* Cap effBsr with nonLcg0Bsr and append lcg0 bs. + * nonLcg0Bsr limit applies only to lcg1,2,3 */ + /* better be handled in individual scheduler */ + ue->ul.effBsr = nonLcg0Bsr +\ + ((RgSchCmnLcg *)(ue->ul.lcgArr[0].sch))->bs; + RETVOID; +} + +/** + * @brief Records information about the current allocation. + * + * @details + * + * Function: rgSCHCmnUlRecordUeAlloc + * Purpose: Records information about the curent allocation. + * This includes the allocated bytes, as well + * as some power information. + * + * Invoked by: Scheduler + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ue + * @return Void + **/ +#ifdef ANSI +PUBLIC Void rgSCHCmnUlRecordUeAlloc +( +RgSchCellCb *cell, +RgSchUeCb *ue +) +#else +PUBLIC Void rgSCHCmnUlRecordUeAlloc(cell, ue) +RgSchCellCb *cell; +RgSchUeCb *ue; +#endif +{ +#ifdef LTE_TDD + RgSchCmnUlCell *cellUl = RG_SCH_CMN_GET_UL_CELL(cell); +#endif + RgSchCmnUlUe *ueUl = RG_SCH_CMN_GET_UL_UE(ue,cell); + CmLListCp *lst = &ueUl->ulAllocLst; + CmLList *node = ueUl->ulAllocLst.first; + RgSchCmnAllocRecord *allRcd = (RgSchCmnAllocRecord *)(node->node); + RgSchCmnUeUlAlloc *ulAllocInfo = &ueUl->alloc; + CmLteUeCategory ueCtg = (CmLteUeCategory)(RG_SCH_CMN_GET_UE_CTGY(ue)); + TRC2(rgSCHCmnUlRecordUeAlloc); + + cmLListDelFrm(lst, &allRcd->lnk); +#ifndef LTE_TDD + /* To the crntTime, add the MIN time at which UE will + * actually send the BSR i.e DELTA+4 */ + allRcd->allocTime = cell->crntTime; + /*ccpu00116293 - Correcting relation between UL subframe and DL subframe based on RG_UL_DELTA*/ +#ifdef EMTC_ENABLE + if(ue->isEmtcUe == TRUE) + { + RGSCH_INCR_SUB_FRAME_EMTC(allRcd->allocTime, + (TFU_ULCNTRL_DLDELTA + RGSCH_PDCCH_PUSCH_DELTA)); + } + else +#endif + { + RGSCH_INCR_SUB_FRAME(allRcd->allocTime, + (TFU_ULCNTRL_DLDELTA + RGSCH_PDCCH_PUSCH_DELTA)); + } +#else + allRcd->allocTime = cellUl->schdTime; +#endif + cmLListAdd2Tail(lst, &allRcd->lnk); + + /* Filling in the parameters to be recorded */ + allRcd->alloc = ulAllocInfo->allocdBytes; + //allRcd->numRb = ulAllocInfo->alloc->grnt.numRb; + allRcd->numRb = (ulAllocInfo->alloc->grnt.numVrbg * MAX_5GTF_VRBG_SIZE); + /*Recording the UL CQI derived from the maxUlCqi */ + allRcd->cqi = rgSCHCmnUlGetCqi(cell, ue, ueCtg); + allRcd->tpc = ulAllocInfo->alloc->grnt.tpc; + + rgSCHPwrRecordRbAlloc(cell, ue, allRcd->numRb); + + cell->measurements.ulBytesCnt += ulAllocInfo->allocdBytes; + + RETVOID; +} + +/** PHR handling for MSG3 + * @brief Records allocation information of msg3 in the the UE. + * + * @details + * + * Function: rgSCHCmnUlRecMsg3Alloc + * Purpose: Records information about msg3 allocation. + * This includes the allocated bytes, as well + * as some power information. + * + * Invoked by: Scheduler + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ue + * @param[in] RgSchRaCb *raCb + * @return Void + **/ +#ifdef ANSI +PUBLIC Void rgSCHCmnUlRecMsg3Alloc +( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgSchRaCb *raCb +) +#else +PUBLIC Void rgSCHCmnUlRecMsg3Alloc(cell, ue, raCb) +RgSchCellCb *cell; +RgSchUeCb *ue; +RgSchRaCb *raCb; +#endif +{ + RgSchCmnUlUe *ueUl = RG_SCH_CMN_GET_UL_UE(ue,cell); + CmLListCp *lst = &ueUl->ulAllocLst; + CmLList *node = ueUl->ulAllocLst.first; + RgSchCmnAllocRecord *allRcd = (RgSchCmnAllocRecord *)(node->node); + + /* Stack Crash problem for TRACE5 changes */ + TRC2(rgSCHCmnUlRecMsg3Alloc); + + cmLListDelFrm(lst, node); + allRcd->allocTime = raCb->msg3AllocTime; + cmLListAdd2Tail(lst, node); + + /* Filling in the parameters to be recorded */ + allRcd->alloc = raCb->msg3Grnt.datSz; + allRcd->numRb = raCb->msg3Grnt.numRb; + allRcd->cqi = raCb->ccchCqi; + allRcd->tpc = raCb->msg3Grnt.tpc; + + rgSCHPwrRecordRbAlloc(cell, ue, allRcd->numRb); + + RETVOID; +} +/** + * @brief Keeps track of the most recent RG_SCH_CMN_MAX_ALLOC_TRACK + * allocations to track. Adds this allocation to the ueUl's ulAllocLst. + * + * + * @details + * + * Function: rgSCHCmnUlUpdOutStndAlloc + * Purpose: Recent Allocation shall be at First Pos'n. + * Remove the last node, update the fields + * with the new allocation and add at front. + * + * Invoked by: Scheduler + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ue + * @param[in] U32 alloc + * @return Void + **/ +#ifdef ANSI +PUBLIC Void rgSCHCmnUlUpdOutStndAlloc +( +RgSchCellCb *cell, +RgSchUeCb *ue, +U32 alloc +) +#else +PUBLIC Void rgSCHCmnUlUpdOutStndAlloc(cell, ue, alloc) +RgSchCellCb *cell; +RgSchUeCb *ue; +U32 alloc; +#endif +{ + U32 nonLcg0Alloc=0; + TRC2(rgSCHCmnUlUpdOutStndAlloc); + + /* Update UEs LCG0's bs according to the total outstanding BSR allocation.*/ + if (((RgSchCmnLcg *)(ue->ul.lcgArr[0].sch))->bs > alloc) + { + ((RgSchCmnLcg *)(ue->ul.lcgArr[0].sch))->bs -= alloc; + } + else + { + nonLcg0Alloc = alloc - ((RgSchCmnLcg *)(ue->ul.lcgArr[0].sch))->bs; + ((RgSchCmnLcg *)(ue->ul.lcgArr[0].sch))->bs = 0; + } + + if (nonLcg0Alloc >= ue->ul.nonLcg0Bs) + { + ue->ul.nonLcg0Bs = 0; + } + else + { + ue->ul.nonLcg0Bs -= nonLcg0Alloc; + } + /* Cap effBsr with effAmbr and append lcg0 bs. + * effAmbr limit applies only to lcg1,2,3 non GBR LCG's*/ + /* better be handled in individual scheduler */ + ue->ul.effBsr = ue->ul.nonLcg0Bs +\ + ((RgSchCmnLcg *)(ue->ul.lcgArr[0].sch))->bs; +#ifdef RGR_V1 + if (ue->ul.effBsr == 0) + { + if (ue->bsrTmr.tmrEvnt != TMR_NONE) + { + rgSCHTmrStopTmr(cell, ue->bsrTmr.tmrEvnt, ue); + } + /* ccpu00133008 */ + if (FALSE == ue->isSrGrant) + { + if (ue->ul.bsrTmrCfg.isPrdBsrTmrPres) + { + /* + rgSCHTmrStartTmr(cell, ue, RG_SCH_TMR_BSR, + ue->ul.bsrTmrCfg.prdBsrTmr); + */ + } + } + } +#endif + /* Resetting UEs lower Cap */ + ue->ul.minReqBytes = 0; + + RETVOID; +} + + +/** + * @brief Returns the "Itbs" for a given UE. + * + * @details + * + * Function: rgSCHCmnUlGetITbs + * Purpose: This function returns the "Itbs" for a given UE. + * + * Invoked by: Scheduler + * + * @param[in] RgSchUeCb *ue + * @return U8 + **/ +#ifdef ANSI +PUBLIC U8 rgSCHCmnUlGetITbs +( +RgSchCellCb *cell, +RgSchUeCb *ue, +Bool isEcp +) +#else +PUBLIC U8 rgSCHCmnUlGetITbs(cell, ue, isEcp) +RgSchCellCb *cell; +RgSchUeCb *ue; +Bool isEcp; +#endif +{ + RgSchCmnUlUe *ueUl = RG_SCH_CMN_GET_UL_UE(ue,cell); + /* CQI will be capped to maxUlCqi for 16qam UEs */ + CmLteUeCategory ueCtgy = (CmLteUeCategory)(RG_SCH_CMN_GET_UE_CTGY(ue)); + U8 cqi; +#ifdef UL_LA + S32 iTbs; + U8 maxiTbs = rgSchCmnUlCqiToTbsTbl[(U8)isEcp][ueUl->maxUlCqi]; +#endif + + TRC2(rgSCHCmnUlGetITbs); + + /* #ifdef RG_SCH_CMN_EXT_CP_SUP For ECP pick index 1 */ +#ifdef TFU_UPGRADE + if ( (ueCtgy != CM_LTE_UE_CAT_5) && + (ueUl->validUlCqi > ueUl->maxUlCqi) + ) + { + cqi = ueUl->maxUlCqi; + } + else + { + cqi = ueUl->validUlCqi; + } + +#ifdef UL_LA + iTbs = (ueUl->ulLaCb.cqiBasediTbs + ueUl->ulLaCb.deltaiTbs)/100; + + RG_SCH_CHK_ITBS_RANGE(iTbs, maxiTbs); + + iTbs = RGSCH_MIN(iTbs, ue->cell->thresholds.maxUlItbs); + +#ifdef LTE_TDD + /* This is a Temp fix, done for TENBPLUS-3898, ULSCH SDU corruption + was seen when IMCS exceeds 20 on T2k TDD */ + if (iTbs > 19) + { + iTbs = 19; + } +#endif + RETVALUE(iTbs); +#endif +#else + if ( (ueCtgy != CM_LTE_UE_CAT_5) && (ueUl->crntUlCqi[0] > ueUl->maxUlCqi )) + { + cqi = ueUl->maxUlCqi; + } + else + { + cqi = ueUl->crntUlCqi[0]; + } +#endif + RETVALUE(rgSchCmnUlCqiToTbsTbl[(U8)isEcp][cqi]); +} + +/** + * @brief This function adds the UE to DLRbAllocInfo TX lst. + * + * @details + * + * Function: rgSCHCmnDlRbInfoAddUeTx + * Purpose: This function adds the UE to DLRbAllocInfo TX lst. + * + * Invoked by: Common Scheduler + * + * @param[out] RgSchCmnDlRbAllocInfo *allocInfo + * @param[in] RgSchUeCb *ue + * @param[in] RgSchDlHqProcCb *hqP + * @return Void + * + **/ +#ifdef ANSI +PRIVATE Void rgSCHCmnDlRbInfoAddUeTx +( +RgSchCellCb *cell, +RgSchCmnDlRbAllocInfo *allocInfo, +RgSchUeCb *ue, +RgSchDlHqProcCb *hqP +) +#else +PRIVATE Void rgSCHCmnDlRbInfoAddUeTx(cell, allocInfo, ue, hqP) +RgSchCellCb *cell; +RgSchCmnDlRbAllocInfo *allocInfo; +RgSchUeCb *ue; +RgSchDlHqProcCb *hqP; +#endif +{ + RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell); + + TRC2(rgSCHCmnDlRbInfoAddUeTx); + + if (hqP->reqLnk.node == NULLP) + { + if (cellSch->dl.isDlFreqSel) + { + cellSch->apisDlfs->rgSCHDlfsAddUeToLst(cell, + &allocInfo->dedAlloc.txHqPLst, hqP); + } + else + { + { + cmLListAdd2Tail(&allocInfo->dedAlloc.txHqPLst, &hqP->reqLnk); + } + hqP->reqLnk.node = (PTR)hqP; + } + } + RETVOID; +} + +/** + * @brief This function adds the UE to DLRbAllocInfo RETX lst. + * + * @details + * + * Function: rgSCHCmnDlRbInfoAddUeRetx + * Purpose: This function adds the UE to DLRbAllocInfo RETX lst. + * + * Invoked by: Common Scheduler + * + * @param[out] RgSchCmnDlRbAllocInfo *allocInfo + * @param[in] RgSchUeCb *ue + * @param[in] RgSchDlHqProcCb *hqP + * @return Void + * + **/ +#ifdef ANSI +PRIVATE Void rgSCHCmnDlRbInfoAddUeRetx +( +RgSchCellCb *cell, +RgSchCmnDlRbAllocInfo *allocInfo, +RgSchUeCb *ue, +RgSchDlHqProcCb *hqP +) +#else +PRIVATE Void rgSCHCmnDlRbInfoAddUeRetx(cell, allocInfo, ue, hqP) +RgSchCellCb *cell; +RgSchCmnDlRbAllocInfo *allocInfo; +RgSchUeCb *ue; +RgSchDlHqProcCb *hqP; +#endif +{ + RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(ue->cell); + + TRC2(rgSCHCmnDlRbInfoAddUeRetx); + + if (cellSch->dl.isDlFreqSel) + { + cellSch->apisDlfs->rgSCHDlfsAddUeToLst(cell, + &allocInfo->dedAlloc.retxHqPLst, hqP); + } + else + { + /* checking UE's presence in this lst is unnecessary */ + cmLListAdd2Tail(&allocInfo->dedAlloc.retxHqPLst, &hqP->reqLnk); + hqP->reqLnk.node = (PTR)hqP; + } + RETVOID; +} + +/** + * @brief This function adds the UE to DLRbAllocInfo TX-RETX lst. + * + * @details + * + * Function: rgSCHCmnDlRbInfoAddUeRetxTx + * Purpose: This adds the UE to DLRbAllocInfo TX-RETX lst. + * + * Invoked by: Common Scheduler + * + * @param[out] RgSchCmnDlRbAllocInfo *allocInfo + * @param[in] RgSchUeCb *ue + * @param[in] RgSchDlHqProcCb *hqP + * @return Void + * + **/ +#ifdef ANSI +PRIVATE Void rgSCHCmnDlRbInfoAddUeRetxTx +( +RgSchCellCb *cell, +RgSchCmnDlRbAllocInfo *allocInfo, +RgSchUeCb *ue, +RgSchDlHqProcCb *hqP +) +#else +PRIVATE Void rgSCHCmnDlRbInfoAddUeRetxTx(allocInfo, ue, hqP) +RgSchCellCb *cell; +RgSchCmnDlRbAllocInfo *allocInfo; +RgSchUeCb *ue; +RgSchDlHqProcCb *hqP; +#endif +{ + RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(ue->cell); + + TRC2(rgSCHCmnDlRbInfoAddUeRetxTx); + + if (cellSch->dl.isDlFreqSel) + { + cellSch->apisDlfs->rgSCHDlfsAddUeToLst(cell, + &allocInfo->dedAlloc.txRetxHqPLst, hqP); + } + else + { + cmLListAdd2Tail(&allocInfo->dedAlloc.txRetxHqPLst, &hqP->reqLnk); + hqP->reqLnk.node = (PTR)hqP; + } + RETVOID; +} + +/** + * @brief This function adds the UE to DLRbAllocInfo NonSchdRetxLst. + * + * @details + * + * Function: rgSCHCmnDlAdd2NonSchdRetxLst + * Purpose: During RB estimation for RETX, if allocation fails + * then appending it to NonSchdRetxLst, the further + * action is taken as part of Finalization in + * respective schedulers. + * + * Invoked by: Common Scheduler + * + * @param[out] RgSchCmnDlRbAllocInfo *allocInfo + * @param[in] RgSchUeCb *ue + * @param[in] RgSchDlHqProcCb *hqP + * @return Void + * + **/ +#ifdef ANSI +PRIVATE Void rgSCHCmnDlAdd2NonSchdRetxLst +( +RgSchCmnDlRbAllocInfo *allocInfo, +RgSchUeCb *ue, +RgSchDlHqProcCb *hqP +) +#else +PRIVATE Void rgSCHCmnDlAdd2NonSchdRetxLst(allocInfo, ue, hqP) +RgSchCmnDlRbAllocInfo *allocInfo; +RgSchUeCb *ue; +RgSchDlHqProcCb *hqP; +#endif +{ + CmLList *schdLnkNode; + + TRC2(rgSCHCmnDlAdd2NonSchdRetxLst); + +#ifdef LTEMAC_SPS + if ( (hqP->sch != (RgSchCmnDlHqProc *)NULLP) && + (RG_SCH_CMN_SPS_DL_IS_SPS_HQP(hqP))) + { + RETVOID; + } +#endif + + schdLnkNode = &hqP->schdLstLnk; + RG_SCH_CMN_INIT_SCHD_LNK(schdLnkNode, hqP); + cmLListAdd2Tail(&allocInfo->dedAlloc.nonSchdRetxHqPLst, schdLnkNode); + + RETVOID; +} + + + +/** + * @brief This function adds the UE to DLRbAllocInfo NonSchdTxRetxLst. + * + * @details + * + * Function: rgSCHCmnDlAdd2NonSchdTxRetxLst + * Purpose: During RB estimation for TXRETX, if allocation fails + * then appending it to NonSchdTxRetxLst, the further + * action is taken as part of Finalization in + * respective schedulers. + * + * Invoked by: Common Scheduler + * + * @param[out] RgSchCmnDlRbAllocInfo *allocInfo + * @param[in] RgSchUeCb *ue + * @param[in] RgSchDlHqProcCb *hqP + * @return Void + * + **/ +#ifdef LTE_TDD +/** + * @brief This function handles the initialisation of DL HARQ/ACK feedback + * timing information for eaach DL subframe. + * + * @details + * + * Function: rgSCHCmnDlANFdbkInit + * Purpose: Each DL subframe stores the sfn and subframe + * information of UL subframe in which it expects + * HARQ ACK/NACK feedback for this subframe.It + * generates the information based on Downlink + * Association Set Index table. + * + * Invoked by: Scheduler + * + * @param[in] RgSchCellCb* cell + * @return S16 + * + **/ +#ifdef ANSI +PRIVATE S16 rgSCHCmnDlANFdbkInit +( +RgSchCellCb *cell +) +#else +PRIVATE S16 rgSCHCmnDlANFdbkInit(cell) +RgSchCellCb *cell; +#endif +{ + U8 sfCount; + U8 ulDlCfgIdx = cell->ulDlCfgIdx; + U8 maxDlSubfrms = cell->numDlSubfrms; + U8 sfNum; + U8 idx; + U8 dlIdx; + U8 calcSfnOffset; + S8 calcSfNum; + U8 ulSfCnt =0; + RgSchTddSubfrmInfo ulSubfrmInfo; + U8 maxUlSubfrms; + + TRC2(rgSCHCmnDlANFdbkInit); + + ulSubfrmInfo = rgSchTddMaxUlSubfrmTbl[ulDlCfgIdx]; + maxUlSubfrms = rgSchTddNumUlSubfrmTbl[ulDlCfgIdx][RGSCH_NUM_SUB_FRAMES-1]; + + /* Generate HARQ ACK/NACK feedback information for each DL sf in a radio frame + * Calculate this information based on DL Association set Index table */ + for (sfCount = 0, sfNum = 0; sfCount < maxUlSubfrms; sfCount++) + { + while(rgSchTddUlDlSubfrmTbl[ulDlCfgIdx][sfNum] != + RG_SCH_TDD_UL_SUBFRAME) + { + sfNum = (sfNum+1) % RGSCH_NUM_SUB_FRAMES; + } + ulSfCnt++; + + for(idx=0; idx < rgSchTddDlAscSetIdxKTbl[ulDlCfgIdx][sfNum].\ + numFdbkSubfrms; idx++) + { + calcSfNum = sfNum - rgSchTddDlAscSetIdxKTbl[ulDlCfgIdx][sfNum].\ + subfrmNum[idx]; + if(calcSfNum < 0) + { + calcSfnOffset = RGSCH_CEIL(-calcSfNum, RGSCH_NUM_SUB_FRAMES); + } + else + { + calcSfnOffset = 0; + } + + calcSfNum = ((RGSCH_NUM_SUB_FRAMES * calcSfnOffset) + calcSfNum)\ + % RGSCH_NUM_SUB_FRAMES; + + if(calcSfNum <= RG_SCH_CMN_SPL_SUBFRM_1) + { + dlIdx = calcSfNum; + } + else if((ulSubfrmInfo.switchPoints == 2) && (calcSfNum <= \ + RG_SCH_CMN_SPL_SUBFRM_6)) + { + dlIdx = calcSfNum - ulSubfrmInfo.numFrmHf1; + } + else + { + dlIdx = calcSfNum - maxUlSubfrms; + } + + cell->subFrms[dlIdx]->dlFdbkInfo.subframe = sfNum; + cell->subFrms[dlIdx]->dlFdbkInfo.sfnOffset = calcSfnOffset; + cell->subFrms[dlIdx]->dlFdbkInfo.m = idx; + } + sfNum = (sfNum+1) % RGSCH_NUM_SUB_FRAMES; + } + + /* DL subframes in the subsequent radio frames are initialized + * with the previous radio frames */ + for(dlIdx = RGSCH_NUM_SUB_FRAMES - maxUlSubfrms; dlIdx < maxDlSubfrms;\ + dlIdx++) + { + sfNum = dlIdx - rgSchTddNumDlSubfrmTbl[ulDlCfgIdx]\ + [RGSCH_NUM_SUB_FRAMES-1]; + cell->subFrms[dlIdx]->dlFdbkInfo.subframe = \ + cell->subFrms[sfNum]->dlFdbkInfo.subframe; + cell->subFrms[dlIdx]->dlFdbkInfo.sfnOffset = \ + cell->subFrms[sfNum]->dlFdbkInfo.sfnOffset; + cell->subFrms[dlIdx]->dlFdbkInfo.m = cell->subFrms[sfNum]->dlFdbkInfo.m; + } + RETVALUE(ROK); +} + +/** + * @brief This function handles the initialization of uplink association + * set information for each DL subframe. + * + * + * @details + * + * Function: rgSCHCmnDlKdashUlAscInit + * Purpose: Each DL sf stores the sfn and sf information of UL sf + * in which it expects HQ ACK/NACK trans. It generates the information + * based on k` in UL association set index table. + * + * Invoked by: Scheduler + * + * @param[in] RgSchCellCb* cell + * @return S16 + * + **/ +#ifdef ANSI +PRIVATE S16 rgSCHCmnDlKdashUlAscInit +( +RgSchCellCb *cell +) +#else +PRIVATE S16 rgSCHCmnDlKdashUlAscInit(cell) +RgSchCellCb *cell; +#endif +{ + U8 sfCount; + U8 ulDlCfgIdx = cell->ulDlCfgIdx; + U8 maxDlSubfrms = cell->numDlSubfrms; + U8 sfNum; + U8 dlIdx; + S8 calcSfnOffset; + S8 calcSfNum; + U8 ulSfCnt =0; + RgSchTddSubfrmInfo ulSubfrmInfo = rgSchTddMaxUlSubfrmTbl[ulDlCfgIdx]; + U8 maxUlSubfrms = rgSchTddNumUlSubfrmTbl[ulDlCfgIdx]\ + [RGSCH_NUM_SUB_FRAMES-1]; + U8 dlPres = 0; + + TRC2(rgSCHCmnDlKdashUlAscInit); + + /* Generate ACK/NACK offset information for each DL subframe in a radio frame + * Calculate this information based on K` in UL Association Set table */ + for (sfCount = 0, sfNum = 0; sfCount < maxUlSubfrms; sfCount++) + { + while(rgSchTddUlDlSubfrmTbl[ulDlCfgIdx][sfNum] != + RG_SCH_TDD_UL_SUBFRAME) + { + sfNum = (sfNum+1) % RGSCH_NUM_SUB_FRAMES; + } + ulSfCnt++; + + calcSfNum = (sfNum - rgSchTddUlAscIdxKDashTbl[ulDlCfgIdx-1][sfNum] + \ + RGSCH_NUM_SUB_FRAMES) % RGSCH_NUM_SUB_FRAMES; + calcSfnOffset = sfNum - rgSchTddUlAscIdxKDashTbl[ulDlCfgIdx-1][sfNum]; + if(calcSfnOffset < 0) + { + calcSfnOffset = RGSCH_CEIL(-calcSfnOffset, RGSCH_NUM_SUB_FRAMES); + } + else + { + calcSfnOffset = 0; + } + + if(calcSfNum <= RG_SCH_CMN_SPL_SUBFRM_1) + { + dlIdx = calcSfNum; + } + else if((ulSubfrmInfo.switchPoints == 2) && + (calcSfNum <= RG_SCH_CMN_SPL_SUBFRM_6)) + { + dlIdx = calcSfNum - ulSubfrmInfo.numFrmHf1; + } + else + { + dlIdx = calcSfNum - maxUlSubfrms; + } + + cell->subFrms[dlIdx]->ulAscInfo.subframe = sfNum; + cell->subFrms[dlIdx]->ulAscInfo.sfnOffset = calcSfnOffset; + + /* set dlIdx for which ulAscInfo is updated */ + dlPres = dlPres | (1 << dlIdx); + sfNum = (sfNum+1) % RGSCH_NUM_SUB_FRAMES; + } + + /* Set Invalid information for which ulAscInfo is not present */ + for (sfCount = 0; + sfCount < rgSchTddNumDlSubfrmTbl[ulDlCfgIdx][RGSCH_NUM_SUB_FRAMES-1]; + sfCount++) + { + /* If dlPres is 0, ulAscInfo is not present in that DL index */ + if(! ((dlPres >> sfCount)&0x01)) + { + cell->subFrms[sfCount]->ulAscInfo.sfnOffset = + RGSCH_INVALID_INFO; + cell->subFrms[sfCount]->ulAscInfo.subframe = + RGSCH_INVALID_INFO; + } + } + + /* DL subframes in the subsequent radio frames are initialized + * with the previous radio frames */ + for(dlIdx = RGSCH_NUM_SUB_FRAMES - maxUlSubfrms; dlIdx < maxDlSubfrms; + dlIdx++) + { + sfNum = dlIdx - \ + rgSchTddNumDlSubfrmTbl[ulDlCfgIdx][RGSCH_NUM_SUB_FRAMES-1]; + cell->subFrms[dlIdx]->ulAscInfo.subframe = + cell->subFrms[sfNum]->ulAscInfo.subframe; + cell->subFrms[dlIdx]->ulAscInfo.sfnOffset = + cell->subFrms[sfNum]->ulAscInfo.sfnOffset; + } + RETVALUE(ROK); +} + + +/** + * @brief This function initialises the 'Np' value for 'p' + * + * @details + * + * Function: rgSCHCmnDlNpValInit + * Purpose: To initialise the 'Np' value for each 'p'. It is used + * to find the mapping between nCCE and 'p' and used in + * HARQ ACK/NACK reception. + * + * Invoked by: Scheduler + * + * @param[in] RgSchCellCb* cell + * @return S16 + * + **/ +#ifdef ANSI +PRIVATE S16 rgSCHCmnDlNpValInit +( +RgSchCellCb *cell +) +#else +PRIVATE S16 rgSCHCmnDlNpValInit(cell) +RgSchCellCb *cell; +#endif +{ + U8 idx; + U16 np; + TRC2(rgSCHCmnDlNpValInit); + + /* Always Np is 0 for p=0 */ + cell->rgSchTddNpValTbl[0] = 0; + + for(idx=1; idx < RGSCH_TDD_MAX_P_PLUS_ONE_VAL; idx++) + { + np = cell->bwCfg.dlTotalBw * (idx * RG_SCH_CMN_NUM_SUBCAR - 4); + cell->rgSchTddNpValTbl[idx] = (U8) (np/36); + } + + RETVALUE(ROK); +} + +/** + * @brief This function handles the creation of RACH preamble + * list to queue the preambles and process at the scheduled + * time. + * + * @details + * + * Function: rgSCHCmnDlCreateRachPrmLst + * Purpose: To create RACH preamble list based on RA window size. + * It is used to queue the preambles and process it at the + * scheduled time. + * + * Invoked by: Scheduler + * + * @param[in] RgSchCellCb* cell + * @return S16 + * + **/ +#ifdef ANSI +PRIVATE S16 rgSCHCmnDlCreateRachPrmLst +( +RgSchCellCb *cell +) +#else +PRIVATE S16 rgSCHCmnDlCreateRachPrmLst(cell) +RgSchCellCb *cell; +#endif +{ + U8 raArrSz; + S16 ret; + U8 lstSize; + + TRC2(rgSCHCmnDlCreateRachPrmLst); + + RG_SCH_CMN_CALC_RARSPLST_SIZE(cell, raArrSz); + + lstSize = raArrSz * RGSCH_MAX_RA_RNTI_PER_SUBFRM * RGSCH_NUM_SUB_FRAMES; + + cell->raInfo.maxRaSize = raArrSz; + ret = rgSCHUtlAllocSBuf(cell->instIdx, + (Data **)(&cell->raInfo.raReqLst), (Size)(lstSize * sizeof(CmLListCp))); + if (ret != ROK) + { + RETVALUE(ret); + } + + cell->raInfo.lstSize = lstSize; + + RETVALUE(ROK); +} + + +/** + * @brief This function handles the initialization of RACH Response + * information at each DL subframe. + * + * @details + * + * Function: rgSCHCmnDlRachInfoInit + * Purpose: Each DL subframe stores the sfn and subframe information of + * possible RACH response allowed for UL subframes. It generates + * the information based on PRACH configuration. + * + * Invoked by: Scheduler + * + * @param[in] RgSchCellCb* cell + * @return S16 + * + **/ +#ifdef ANSI +PRIVATE S16 rgSCHCmnDlRachInfoInit +( +RgSchCellCb *cell +) +#else +PRIVATE S16 rgSCHCmnDlRachInfoInit(cell) +RgSchCellCb *cell; +#endif +{ + U8 sfCount; + U8 ulDlCfgIdx = cell->ulDlCfgIdx; + U8 sfNum; + U8 ulSfCnt =0; + U8 maxUlSubfrms = rgSchTddNumUlSubfrmTbl[ulDlCfgIdx]\ + [RGSCH_NUM_SUB_FRAMES-1]; + U8 raArrSz; + RgSchTddRachRspLst rachRspLst[3][RGSCH_NUM_SUB_FRAMES]; + U8 startWin; + U8 endWin; + U8 sfnIdx; + U8 subfrmIdx; + U8 endSubfrmIdx; + U8 startSubfrmIdx; + S16 ret; + RgSchTddRachDelInfo *delInfo; + S8 sfnOffset; + U8 numSubfrms; + + TRC2(rgSCHCmnDlRachInfoInit); + + cmMemset((U8 *)rachRspLst, 0, sizeof(rachRspLst)); + + RG_SCH_CMN_CALC_RARSPLST_SIZE(cell, raArrSz); + + /* Include Special subframes */ + maxUlSubfrms = maxUlSubfrms + \ + rgSchTddMaxUlSubfrmTbl[ulDlCfgIdx].switchPoints; + for (sfCount = 0, sfNum = 0; sfCount < maxUlSubfrms; sfCount++) + { + while(rgSchTddUlDlSubfrmTbl[ulDlCfgIdx][sfNum] == + RG_SCH_TDD_DL_SUBFRAME) + { + sfNum = (sfNum+1) % RGSCH_NUM_SUB_FRAMES; + } + ulSfCnt++; + + startWin = (sfNum + RG_SCH_CMN_RARSP_WAIT_PRD + \ + ((RgSchCmnCell *)cell->sc.sch)->dl.numRaSubFrms); + endWin = (startWin + cell->rachCfg.raWinSize - 1); + startSubfrmIdx = + rgSchTddHighDlSubfrmIdxTbl[ulDlCfgIdx][startWin%RGSCH_NUM_SUB_FRAMES]; + /* Find the next DL subframe starting from Subframe 0 */ + if((startSubfrmIdx % RGSCH_NUM_SUB_FRAMES) == 0) + { + startWin = RGSCH_CEIL(startWin, RGSCH_NUM_SUB_FRAMES); + startWin = startWin * RGSCH_NUM_SUB_FRAMES; + } + + endSubfrmIdx = + rgSchTddLowDlSubfrmIdxTbl[ulDlCfgIdx][endWin%RGSCH_NUM_SUB_FRAMES]; + endWin = (endWin/RGSCH_NUM_SUB_FRAMES) * RGSCH_NUM_SUB_FRAMES \ + + endSubfrmIdx; + if(startWin > endWin) + { + continue; + } + /* Find all the possible RACH Response transmission + * time within the RA window size */ + startSubfrmIdx = startWin%RGSCH_NUM_SUB_FRAMES; + for(sfnIdx = startWin/RGSCH_NUM_SUB_FRAMES; + sfnIdx <= endWin/RGSCH_NUM_SUB_FRAMES; sfnIdx++) + { + if(sfnIdx == endWin/RGSCH_NUM_SUB_FRAMES) + { + endSubfrmIdx = endWin%RGSCH_NUM_SUB_FRAMES; + } + else + { + endSubfrmIdx = RGSCH_NUM_SUB_FRAMES-1; + } + + /* Find all the possible RACH Response transmission + * time within radio frame */ + for(subfrmIdx = startSubfrmIdx; + subfrmIdx <= endSubfrmIdx; subfrmIdx++) + { + if(rgSchTddUlDlSubfrmTbl[ulDlCfgIdx][subfrmIdx] == + RG_SCH_TDD_UL_SUBFRAME) + { + continue; + } + subfrmIdx = rgSchTddHighDlSubfrmIdxTbl[ulDlCfgIdx][subfrmIdx]; + /* Find the next DL subframe starting from Subframe 0 */ + if(subfrmIdx == RGSCH_NUM_SUB_FRAMES) + { + break; + } + RGSCH_ARRAY_BOUND_CHECK(cell->instIdx, rachRspLst[sfnIdx], subfrmIdx); + numSubfrms = + rachRspLst[sfnIdx][subfrmIdx].rachRsp[0].numSubfrms; + rachRspLst[sfnIdx][subfrmIdx].rachRsp[0].sfnOffset = sfnIdx; + rachRspLst[sfnIdx][subfrmIdx].rachRsp[0].subframe[numSubfrms] + = sfNum; + rachRspLst[sfnIdx][subfrmIdx].rachRsp[0].numSubfrms++; + } + startSubfrmIdx = RG_SCH_CMN_SUBFRM_0; + } + /* Update the subframes to be deleted at this subframe */ + /* Get the subframe after the end of RA window size */ + endWin++; + endSubfrmIdx++; + sfnOffset = endWin/RGSCH_NUM_SUB_FRAMES; + if(sfnOffset < 0) + { + sfnOffset += raArrSz; + } + sfnIdx = (endWin/RGSCH_NUM_SUB_FRAMES) % raArrSz; + + RGSCH_ARRAY_BOUND_CHECK(cell->instIdx, rgSchTddHighDlSubfrmIdxTbl[ulDlCfgIdx],endSubfrmIdx-1); + if((endSubfrmIdx == RGSCH_NUM_SUB_FRAMES) || + (rgSchTddHighDlSubfrmIdxTbl[ulDlCfgIdx][endSubfrmIdx] == + RGSCH_NUM_SUB_FRAMES)) + { + subfrmIdx = + rgSchTddHighDlSubfrmIdxTbl[ulDlCfgIdx][RG_SCH_CMN_SUBFRM_0]; + } + else + { + subfrmIdx = rgSchTddHighDlSubfrmIdxTbl[ulDlCfgIdx][endSubfrmIdx]; + } + + delInfo = &rachRspLst[sfnIdx][subfrmIdx].delInfo; + delInfo->sfnOffset = sfnOffset; + delInfo->subframe[delInfo->numSubfrms] = sfNum; + delInfo->numSubfrms++; + + sfNum = (sfNum+1) % RGSCH_NUM_SUB_FRAMES; + } + + ret = rgSCHCmnDlCpyRachInfo(cell, rachRspLst, raArrSz); + if (ret != ROK) + { + RETVALUE(ret); + } + + RETVALUE(ROK); +} + +/** + * @brief This function handles the initialization of PHICH information + * for each DL subframe based on PHICH table. + * + * @details + * + * Function: rgSCHCmnDlPhichOffsetInit + * Purpose: Each DL subf stores the sfn and subf information of UL subframe + * for which it trnsmts PHICH in this subframe. It generates the information + * based on PHICH table. + * + * Invoked by: Scheduler + * + * @param[in] RgSchCellCb* cell + * @return S16 + * + **/ +#ifdef ANSI +PRIVATE S16 rgSCHCmnDlPhichOffsetInit +( +RgSchCellCb *cell +) +#else +PRIVATE S16 rgSCHCmnDlPhichOffsetInit(cell) +RgSchCellCb *cell; +#endif +{ + U8 sfCount; + U8 ulDlCfgIdx = cell->ulDlCfgIdx; + U8 maxDlSubfrms = cell->numDlSubfrms; + U8 sfNum; + U8 dlIdx; + U8 dlPres = 0; + U8 calcSfnOffset; + U8 calcSfNum; + U8 ulSfCnt =0; + RgSchTddSubfrmInfo ulSubfrmInfo = rgSchTddMaxUlSubfrmTbl[ulDlCfgIdx]; + U8 maxUlSubfrms = rgSchTddNumUlSubfrmTbl[ulDlCfgIdx]\ + [RGSCH_NUM_SUB_FRAMES-1]; + + TRC2(rgSCHCmnDlPhichOffsetInit); + + /* Generate PHICH offset information for each DL subframe in a radio frame + * Calculate this information based on K in PHICH table */ + for (sfCount = 0, sfNum = 0; sfCount < maxUlSubfrms; sfCount++) + { + while(rgSchTddUlDlSubfrmTbl[ulDlCfgIdx][sfNum] != + RG_SCH_TDD_UL_SUBFRAME) + { + sfNum = (sfNum+1) % RGSCH_NUM_SUB_FRAMES; + } + ulSfCnt++; + + calcSfNum = (rgSchTddKPhichTbl[ulDlCfgIdx][sfNum] + sfNum) % \ + RGSCH_NUM_SUB_FRAMES; + calcSfnOffset = (rgSchTddKPhichTbl[ulDlCfgIdx][sfNum] + sfNum) / \ + RGSCH_NUM_SUB_FRAMES; + + if(calcSfNum <= RG_SCH_CMN_SPL_SUBFRM_1) + { + dlIdx = calcSfNum; + } + else if((ulSubfrmInfo.switchPoints == 2) && + (calcSfNum <= RG_SCH_CMN_SPL_SUBFRM_6)) + { + dlIdx = calcSfNum - ulSubfrmInfo.numFrmHf1; + } + else + { + dlIdx = calcSfNum - maxUlSubfrms; + } + + cell->subFrms[dlIdx]->phichOffInfo.subframe = sfNum; + cell->subFrms[dlIdx]->phichOffInfo.numSubfrms = 1; + + cell->subFrms[dlIdx]->phichOffInfo.sfnOffset = calcSfnOffset; + + /* set dlIdx for which phich offset is updated */ + dlPres = dlPres | (1 << dlIdx); + sfNum = (sfNum+1) % RGSCH_NUM_SUB_FRAMES; + } + + /* Set Invalid information for which phich offset is not present */ + for (sfCount = 0; + sfCount < rgSchTddNumDlSubfrmTbl[ulDlCfgIdx][RGSCH_NUM_SUB_FRAMES-1]; + sfCount++) + { + /* If dlPres is 0, phich offset is not present in that DL index */ + if(! ((dlPres >> sfCount)&0x01)) + { + cell->subFrms[sfCount]->phichOffInfo.sfnOffset = + RGSCH_INVALID_INFO; + cell->subFrms[sfCount]->phichOffInfo.subframe = + RGSCH_INVALID_INFO; + cell->subFrms[sfCount]->phichOffInfo.numSubfrms = 0; + } + } + + /* DL subframes in the subsequent radio frames are + * initialized with the previous radio frames */ + for(dlIdx = RGSCH_NUM_SUB_FRAMES - maxUlSubfrms; + dlIdx < maxDlSubfrms; dlIdx++) + { + sfNum = dlIdx - \ + rgSchTddNumDlSubfrmTbl[ulDlCfgIdx][RGSCH_NUM_SUB_FRAMES-1]; + + cell->subFrms[dlIdx]->phichOffInfo.subframe = + cell->subFrms[sfNum]->phichOffInfo.subframe; + + cell->subFrms[dlIdx]->phichOffInfo.sfnOffset = + cell->subFrms[sfNum]->phichOffInfo.sfnOffset; + } + RETVALUE(ROK); +} + + +/** + * @brief Updation of Sch vars per TTI. + * + * @details + * + * Function: rgSCHCmnUpdVars + * Purpose: Updation of Sch vars per TTI. + * + * @param[in] RgSchCellCb *cell + * @return Void + * + **/ +#ifdef ANSI +PUBLIC Void rgSCHCmnUpdVars +( +RgSchCellCb *cell +) +#else +PUBLIC Void rgSCHCmnUpdVars(cell) +RgSchCellCb *cell; +#endif +{ + RgSchCmnUlCell *cellUl = RG_SCH_CMN_GET_UL_CELL(cell); + CmLteTimingInfo timeInfo; + U8 idx; + U8 ulSubframe; + U8 ulDlCfgIdx = cell->ulDlCfgIdx; + U8 msg3Subfrm; + U8 Mval; + TRC2(rgSCHCmnUpdVars); + + /* ccpu00132654-ADD- Initializing all the indices in every subframe*/ + rgSCHCmnInitVars(cell); + + idx = (cell->crntTime.subframe + TFU_ULCNTRL_DLDELTA) % RGSCH_NUM_SUB_FRAMES; + /* Calculate the UL scheduling subframe idx based on the + Pusch k table */ + if(rgSchTddPuschTxKTbl[ulDlCfgIdx][idx] != 0) + { + /* PUSCH transmission is based on offset from DL + * PDCCH scheduling */ + RGSCHCMNADDTOCRNTTIME(cell->crntTime,timeInfo, TFU_ULCNTRL_DLDELTA); + ulSubframe = rgSchTddPuschTxKTbl[ulDlCfgIdx][timeInfo.subframe]; + /* Add the DCI-0 to PUSCH time to get the time of UL subframe */ + RGSCHCMNADDTOCRNTTIME(timeInfo, timeInfo, ulSubframe); +#ifdef LTEMAC_SPS + cellUl->schdTti = timeInfo.sfn * 10 + timeInfo.subframe; +#endif + /* Fetch the corresponding UL subframe Idx in UL sf array */ + cellUl->schdIdx = rgSCHCmnGetUlSfIdx(&timeInfo, cell); + /* Fetch the corresponding UL Harq Proc ID */ + cellUl->schdHqProcIdx = rgSCHCmnGetUlHqProcIdx(&timeInfo, cell); + cellUl->schdTime = timeInfo; + } + Mval = rgSchTddPhichMValTbl[ulDlCfgIdx][idx]; + if(Mval) + { + /* Fetch the tx time for DL HIDCI-0 */ + RGSCHCMNADDTOCRNTTIME(cell->crntTime,timeInfo, TFU_ULCNTRL_DLDELTA); + /* Fetch the corresponding n-k tx time of PUSCH */ + cellUl->hqFdbkIdx[0] = rgSCHCmnGetPhichUlSfIdx(&timeInfo, cell); + /* Retx will happen according to the Pusch k table */ + cellUl->reTxIdx[0] = cellUl->schdIdx; + + if(ulDlCfgIdx == 0) + { + /* Calculate the ReTxIdx corresponding to hqFdbkIdx[0] */ + cellUl->reTxIdx[0] = rgSchUtlCfg0ReTxIdx(cell,timeInfo, + cellUl->hqFdbkIdx[0]); + if(Mval == 2) + { + /* At Idx 1 store the UL SF adjacent(left) to the UL SF + given at idx 0 */ + cellUl->hqFdbkIdx[1] = (cellUl->hqFdbkIdx[0]-1 + + cellUl->numUlSubfrms) % cellUl->numUlSubfrms; + /* Calculate the ReTxIdx corresponding to hqFdbkIdx[1] */ + cellUl->reTxIdx[1] = rgSchUtlCfg0ReTxIdx(cell,timeInfo, + cellUl->hqFdbkIdx[1]); + } + } + } + + idx = (cell->crntTime.subframe + TFU_RECPREQ_DLDELTA) % RGSCH_NUM_SUB_FRAMES; + if (rgSchTddUlDlSubfrmTbl[ulDlCfgIdx][idx] == RG_SCH_TDD_UL_SUBFRAME) + { + RGSCHCMNADDTOCRNTTIME(cell->crntTime, timeInfo, TFU_RECPREQ_DLDELTA) + cellUl->rcpReqIdx = rgSCHCmnGetUlSfIdx(&timeInfo, cell); + } + idx = (cell->crntTime.subframe+RG_SCH_CMN_DL_DELTA) % RGSCH_NUM_SUB_FRAMES; + + /*[ccpu00134666]-MOD-Modify the check to schedule the RAR in + special subframe */ + if(rgSchTddUlDlSubfrmTbl[ulDlCfgIdx][idx] != RG_SCH_TDD_UL_SUBFRAME) + { + RGSCHCMNADDTOCRNTTIME(cell->crntTime,timeInfo,RG_SCH_CMN_DL_DELTA) + msg3Subfrm = rgSchTddMsg3SubfrmTbl[ulDlCfgIdx][timeInfo.subframe]; + RGSCHCMNADDTOCRNTTIME(timeInfo, timeInfo, msg3Subfrm); + cellUl->msg3SchdIdx = rgSCHCmnGetUlSfIdx(&timeInfo, cell); + cellUl->msg3SchdHqProcIdx = rgSCHCmnGetUlHqProcIdx(&timeInfo, cell); + } +#ifdef LTEMAC_SPS + if(!rgSchTddSpsUlRsrvTbl[ulDlCfgIdx][idx]) + { + cellUl->spsUlRsrvIdx = RGSCH_INVALID_INFO; + } + else + { + /* introduce some reuse with above code? */ + U8 offst; + RGSCHCMNADDTOCRNTTIME(cell->crntTime,timeInfo,RG_SCH_CMN_DL_DELTA) + //offst = rgSchTddMsg3SubfrmTbl[ulDlCfgIdx][timeInfo.subframe]; + offst = rgSchTddSpsUlRsrvTbl[ulDlCfgIdx][timeInfo.subframe]; + RGSCHCMNADDTOCRNTTIME(timeInfo, timeInfo, offst); + cellUl->spsUlRsrvIdx = rgSCHCmnGetUlSfIdx(&timeInfo, cell); + /* The harq proc continues to be accessed and used the same delta before + * actual data occurance, and hence use the same idx */ + cellUl->spsUlRsrvHqProcIdx = cellUl->schdHqProcIdx; + } +#endif + + /* RACHO: update cmn sched specific RACH variables, + * mainly the prachMaskIndex */ + rgSCHCmnUpdRachParam(cell); + + RETVOID; +} + +/** + * @brief To get 'p' value from nCCE. + * + * @details + * + * Function: rgSCHCmnGetPValFrmCCE + * Purpose: Gets 'p' value for HARQ ACK/NACK reception from CCE. + * + * @param[in] RgSchCellCb *cell + * @param[in] U8 cce + * @return U8 + * + **/ +#ifdef ANSI +PUBLIC U8 rgSCHCmnGetPValFrmCCE +( +RgSchCellCb *cell, +U8 cce +) +#else +PUBLIC U8 rgSCHCmnGetPValFrmCCE(cell, cce) +RgSchCellCb *cell; +U8 cce; +#endif +{ + U8 i; + TRC2(rgSCHCmnGetPValFrmCCE); + + for(i=1; i < RGSCH_TDD_MAX_P_PLUS_ONE_VAL; i++) + { + if(cce < cell->rgSchTddNpValTbl[i]) + { + RETVALUE(i-1); + } + } + RETVALUE(0); +} +#endif + +/*********************************************************** + * + * Func : rgSCHCmnUlAdapRetx + * + * Desc : Adaptive retransmission for an allocation. + * + * Ret : + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PRIVATE Void rgSCHCmnUlAdapRetx +( +RgSchUlAlloc *alloc, +RgSchUlHqProcCb *proc +) +#else +PRIVATE Void rgSCHCmnUlAdapRetx(alloc, proc) +RgSchUlAlloc *alloc; +RgSchUlHqProcCb *proc; +#endif +{ + TRC2(rgSCHCmnUlAdapRetx); + + rgSCHUhmRetx(proc, alloc); +#ifndef RG_5GTF + if (proc->rvIdx != 0) + { + alloc->grnt.iMcsCrnt = rgSchCmnUlRvIdxToIMcsTbl[proc->rvIdx]; + } + else +#endif + { + alloc->grnt.iMcsCrnt = alloc->grnt.iMcs; + } + RETVOID; +} + +/** + * @brief Scheduler invocation per TTI. + * + * @details + * + * Function: rgSCHCmnHdlUlInactUes + * Purpose: + * + * Invoked by: Common Scheduler + * + * @param[in] RgSchCellCb *cell + * @return Void + **/ +#ifdef ANSI +PRIVATE Void rgSCHCmnHdlUlInactUes +( +RgSchCellCb *cell +) +#else +PRIVATE Void rgSCHCmnHdlUlInactUes(cell) +RgSchCellCb *cell; +#endif +{ + RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell); + CmLListCp ulInactvLst; + TRC2(rgSCHCmnHdlUlInactUes); + /* Get a List of Inactv UEs for UL*/ + cmLListInit(&ulInactvLst); + + /* Trigger Spfc Schedulers with Inactive UEs */ + rgSCHMeasGapANRepGetUlInactvUe (cell, &ulInactvLst); + /* take care of this in UL retransmission */ + cellSch->apisUl->rgSCHUlInactvtUes(cell, &ulInactvLst); + + RETVOID; +} + +/** + * @brief Scheduler invocation per TTI. + * + * @details + * + * Function: rgSCHCmnHdlDlInactUes + * Purpose: + * + * Invoked by: Common Scheduler + * + * @param[in] RgSchCellCb *cell + * @return Void + **/ +#ifdef ANSI +PRIVATE Void rgSCHCmnHdlDlInactUes +( +RgSchCellCb *cell +) +#else +PRIVATE Void rgSCHCmnHdlDlInactUes(cell) +RgSchCellCb *cell; +#endif +{ + RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell); + CmLListCp dlInactvLst; + TRC2(rgSCHCmnHdlDlInactUes); + /* Get a List of Inactv UEs for DL */ + cmLListInit(&dlInactvLst); + + /* Trigger Spfc Schedulers with Inactive UEs */ + rgSCHMeasGapANRepGetDlInactvUe (cell, &dlInactvLst); + + cellSch->apisDl->rgSCHDlInactvtUes(cell, &dlInactvLst); + RETVOID; +} + +/* RACHO: Rach handover functions start here */ +/*********************************************************** + * + * Func : rgSCHCmnUeIdleExdThrsld + * + * Desc : RETURN ROK if UE has been idle more + * than threshold. + * + * Ret : + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PRIVATE S16 rgSCHCmnUeIdleExdThrsld +( +RgSchCellCb *cell, +RgSchUeCb *ue +) +#else +PRIVATE S16 rgSCHCmnUeIdleExdThrsld(cell, ue) +RgSchCellCb *cell; +RgSchUeCb *ue; +#endif +{ + /* Time difference in subframes */ + U32 sfDiff = RGSCH_CALC_SF_DIFF(cell->crntTime, ue->ul.ulTransTime); + + TRC2(rgSCHCmnUeIdleExdThrsld); + + if (sfDiff > (U32)RG_SCH_CMN_UE_IDLE_THRSLD(ue)) + { + RETVALUE(ROK); + } + else + { + RETVALUE(RFAILED); + } +} + + +/** + * @brief Scheduler processing for Ded Preambles on cell configuration. + * + * @details + * + * Function : rgSCHCmnCfgRachDedPrm + * + * This function does requisite initialisation + * for RACH Ded Preambles. + * + * + * @param[in] RgSchCellCb *cell + * @return Void + **/ +#ifdef ANSI +PRIVATE Void rgSCHCmnCfgRachDedPrm +( +RgSchCellCb *cell +) +#else +PRIVATE Void rgSCHCmnCfgRachDedPrm(cell) +RgSchCellCb *cell; +#endif +{ + RgSchCmnCell *cellSch = (RgSchCmnCell *)(cell->sc.sch); + U32 gap = RG_SCH_CMN_MIN_PRACH_OPPR_GAP; + U32 sfDiff; + U8 cnt; + TRC2(rgSCHCmnCfgRachDedPrm); + + if (cell->macPreambleSet.pres == NOTPRSNT) + { + RETVOID; + } + cellSch->rachCfg.numDedPrm = cell->macPreambleSet.size; + cellSch->rachCfg.dedPrmStart = cell->macPreambleSet.start; + /* Initialize handover List */ + cmLListInit(&cellSch->rachCfg.hoUeLst); + /* Initialize pdcch Order List */ + cmLListInit(&cellSch->rachCfg.pdcchOdrLst); + + /* Intialize the rapId to UE mapping structure */ + for (cnt = 0; cntrachCfg.numDedPrm; cnt++) + { + cellSch->rachCfg.rapIdMap[cnt].rapId = cellSch->rachCfg.dedPrmStart + \ + cnt; + cmLListInit(&cellSch->rachCfg.rapIdMap[cnt].assgndUes); + } + /* Perform Prach Mask Idx, remDedPrm, applFrm initializations */ + /* Set remDedPrm as numDedPrm */ + cellSch->rachCfg.remDedPrm = cellSch->rachCfg.numDedPrm; + /* Initialize applFrm */ + cellSch->rachCfg.prachMskIndx = 0; + if (cell->rachCfg.raOccasion.sfnEnum == RGR_SFN_EVEN) + { + cellSch->rachCfg.applFrm.sfn = (cell->crntTime.sfn + \ + (cell->crntTime.sfn % 2)) % RGSCH_MAX_SFN; + } +#ifdef LTE_TDD + else if (cell->rachCfg.raOccasion.sfnEnum == RGR_SFN_ODD) + { + if((cell->crntTime.sfn%2) == 0) + { + cellSch->rachCfg.applFrm.sfn = (cell->crntTime.sfn + 1)\ + % RGSCH_MAX_SFN; + } + } +#endif + else /* ANY sfn */ + { + cellSch->rachCfg.applFrm.sfn = cell->crntTime.sfn; + } + /* Initialize cellSch->rachCfg.applFrm as >= crntTime. + * This is because of RGSCH_CALC_SF_DIFF logic */ + if (cellSch->rachCfg.applFrm.sfn == cell->crntTime.sfn) + { + while (cellSch->rachCfg.prachMskIndx < cell->rachCfg.raOccasion.size) + { + if (cell->crntTime.subframe <\ + cell->rachCfg.raOccasion.subFrameNum[cellSch->rachCfg.prachMskIndx]) + { + break; + } + cellSch->rachCfg.prachMskIndx++; + } + if (cellSch->rachCfg.prachMskIndx == cell->rachCfg.raOccasion.size) + { + if (cell->rachCfg.raOccasion.sfnEnum == RGR_SFN_ANY) + { + cellSch->rachCfg.applFrm.sfn = (cellSch->rachCfg.applFrm.sfn+1) %\ + RGSCH_MAX_SFN; + } + else + { + cellSch->rachCfg.applFrm.sfn = (cellSch->rachCfg.applFrm.sfn+2) %\ + RGSCH_MAX_SFN; + } + cellSch->rachCfg.prachMskIndx = 0; + } + cellSch->rachCfg.applFrm.subframe = \ + cell->rachCfg.raOccasion.subFrameNum[cellSch->rachCfg.prachMskIndx]; + } + else + { + cellSch->rachCfg.applFrm.subframe = \ + cell->rachCfg.raOccasion.subFrameNum[cellSch->rachCfg.prachMskIndx]; + } + + /* Note first param to this macro should always be the latest in time */ + sfDiff = RGSCH_CALC_SF_DIFF(cellSch->rachCfg.applFrm, cell->crntTime); + while (sfDiff <= gap) + { + rgSCHCmnUpdNxtPrchMskIdx(cell); + sfDiff = RGSCH_CALC_SF_DIFF(cellSch->rachCfg.applFrm, cell->crntTime); + } + + RETVOID; +} + +/** + * @brief Updates the PRACH MASK INDEX. + * + * @details + * + * Function: rgSCHCmnUpdNxtPrchMskIdx + * Purpose: Ensures the "applFrm" field of Cmn Sched RACH + * CFG is always >= "n"+"DELTA", where "n" is the crntTime + * of the cell. If not, applFrm is updated to the next avl + * PRACH oppurtunity as per the PRACH Cfg Index configuration. + * + * + * Invoked by: Common Scheduler + * + * @param[in] RgSchCellCb *cell + * @return Void + **/ +#ifdef ANSI +PRIVATE Void rgSCHCmnUpdNxtPrchMskIdx +( +RgSchCellCb *cell +) +#else +PRIVATE Void rgSCHCmnUpdNxtPrchMskIdx(cell) +RgSchCellCb *cell; +#endif +{ + RgSchCmnCell *cellSch = (RgSchCmnCell *)(cell->sc.sch); + TRC2(rgSCHCmnUpdNxtPrchMskIdx); + + /* Determine the next prach mask Index */ + if (cellSch->rachCfg.prachMskIndx == cell->rachCfg.raOccasion.size - 1) + { + /* PRACH within applFrm.sfn are done, go to next AVL sfn */ + cellSch->rachCfg.prachMskIndx = 0; + if (cell->rachCfg.raOccasion.sfnEnum == RGR_SFN_ANY) + { + cellSch->rachCfg.applFrm.sfn = (cellSch->rachCfg.applFrm.sfn+1) % \ + RGSCH_MAX_SFN; + } + else/* RGR_SFN_EVEN or RGR_SFN_ODD */ + { + cellSch->rachCfg.applFrm.sfn = (cellSch->rachCfg.applFrm.sfn+2) % \ + RGSCH_MAX_SFN; + } + cellSch->rachCfg.applFrm.subframe = cell->rachCfg.raOccasion.\ + subFrameNum[0]; + } + else /* applFrm.sfn is still valid */ + { + cellSch->rachCfg.prachMskIndx += 1; + if ( cellSch->rachCfg.prachMskIndx < RGR_MAX_SUBFRAME_NUM ) + { + cellSch->rachCfg.applFrm.subframe = \ + cell->rachCfg.raOccasion.subFrameNum[cellSch->rachCfg.prachMskIndx]; + } + } + RETVOID; +} + +/** + * @brief Updates the Ded preamble RACH parameters + * every TTI. + * + * @details + * + * Function: rgSCHCmnUpdRachParam + * Purpose: Ensures the "applFrm" field of Cmn Sched RACH + * CFG is always >= "n"+"6"+"DELTA", where "n" is the crntTime + * of the cell. If not, applFrm is updated to the next avl + * PRACH oppurtunity as per the PRACH Cfg Index configuration, + * accordingly the "remDedPrm" is reset to "numDedPrm" and + * "prachMskIdx" field is updated as per "applFrm". + * + * + * Invoked by: Common Scheduler + * + * @param[in] RgSchCellCb *cell + * @return Void + **/ +#ifdef ANSI +PRIVATE Void rgSCHCmnUpdRachParam +( +RgSchCellCb *cell +) +#else +PRIVATE Void rgSCHCmnUpdRachParam(cell) +RgSchCellCb *cell; +#endif +{ + + RgSchCmnCell *cellSch = (RgSchCmnCell *)(cell->sc.sch); + U32 gap = RG_SCH_CMN_MIN_PRACH_OPPR_GAP; + U32 sfDiff; + TRC2(rgSCHCmnUpdRachParam); + + if (cell->macPreambleSet.pres == NOTPRSNT) + { + RETVOID; + } + sfDiff = RGSCH_CALC_SF_DIFF(cellSch->rachCfg.applFrm, \ + cell->crntTime); + if (sfDiff > gap) + { + /* applFrm is still a valid next Prach Oppurtunity */ + RETVOID; + } + rgSCHCmnUpdNxtPrchMskIdx(cell); + /* Reset remDedPrm as numDedPrm */ + cellSch->rachCfg.remDedPrm = cellSch->rachCfg.numDedPrm; + + RETVOID; +} + +/** + * @brief Dedicated Preamble allocation function. + * + * @details + * + * Function: rgSCHCmnAllocPOParam + * Purpose: Allocate pdcch, rapId and PrachMskIdx. + * Set mapping of UE with the allocated rapId. + * + * Invoked by: Common Scheduler + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchDlSf *dlSf + * @param[in] RgSchUeCb *ue + * @param[out] RgSchPdcch **pdcch + * @param[out] U8 *rapId + * @param[out] U8 *prachMskIdx + * @return Void + **/ +#ifdef ANSI +PRIVATE S16 rgSCHCmnAllocPOParam +( +RgSchCellCb *cell, +RgSchDlSf *dlSf, +RgSchUeCb *ue, +RgSchPdcch **pdcch, +U8 *rapId, +U8 *prachMskIdx +) +#else +PRIVATE S16 rgSCHCmnAllocPOParam(cell, dlSf, ue, pdcch, rapId, prachMskIdx) +RgSchCellCb *cell; +RgSchDlSf *dlSf; +RgSchUeCb *ue; +RgSchPdcch **pdcch; +U8 *rapId; +U8 *prachMskIdx; +#endif +{ + + RgSchCmnCell *cellSch = (RgSchCmnCell *)(cell->sc.sch); + RgSchCmnDlUe *ueDl = RG_SCH_CMN_GET_DL_UE(ue,cell); + + TRC2(rgSCHCmnAllocPOParam); + + if (cell->macPreambleSet.pres == PRSNT_NODEF) + { + if (cellSch->rachCfg.remDedPrm == 0) + { + RETVALUE(RFAILED); + } + /* DTX Changes: One Variable is passed to check whether it is DTX or Not */ + if ((*pdcch = rgSCHCmnPdcchAlloc(cell, ue, dlSf, ueDl->mimoInfo.cwInfo[0].cqi, TFU_DCI_FORMAT_1A, FALSE)) == NULLP) + { + RETVALUE(RFAILED); + } + /* The stored prachMskIdx is the index of PRACH Oppurtunities in + * raOccasions.subframes[]. + * Converting the same to the actual PRACHMskIdx to be transmitted. */ + *prachMskIdx = cellSch->rachCfg.prachMskIndx + 1; + /* Distribution starts from dedPrmStart till dedPrmStart + numDedPrm */ + *rapId = cellSch->rachCfg.dedPrmStart + + cellSch->rachCfg.numDedPrm - cellSch->rachCfg.remDedPrm; + cellSch->rachCfg.remDedPrm--; + /* Map UE with the allocated RapId */ + ueDl->rachInfo.asgnOppr = cellSch->rachCfg.applFrm; + RGSCH_ARRAY_BOUND_CHECK_WITH_POS_IDX(cell->instIdx, cellSch->rachCfg.rapIdMap, (*rapId - cellSch->rachCfg.dedPrmStart)); + cmLListAdd2Tail(&cellSch->rachCfg.rapIdMap[*rapId - cellSch->rachCfg.dedPrmStart].assgndUes, + &ueDl->rachInfo.rapIdLnk); + ueDl->rachInfo.rapIdLnk.node = (PTR)ue; + ueDl->rachInfo.poRapId = *rapId; + } + else /* if dedicated preambles not configured */ + { + /* DTX Changes: One Variable is passed to check whether it is DTX or Not */ + if ((*pdcch = rgSCHCmnPdcchAlloc(cell, ue, dlSf, ueDl->mimoInfo.cwInfo[0].cqi, TFU_DCI_FORMAT_1A, FALSE)) == NULLP) + { + RETVALUE(RFAILED); + } + *prachMskIdx = 0; + *rapId = 0; + } + + RETVALUE(ROK); +} + +/** + * @brief Dowlink Scheduling Handler. + * + * @details + * + * Function: rgSCHCmnGenPdcchOrder + * Purpose: For each UE in PO Q, grab a PDCCH, + * get an available ded RapId and fill PDCCH + * with PO information. + * + * Invoked by: Common Scheduler + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchDlSf *dlSf + * @return Void + **/ +#ifdef ANSI +PRIVATE Void rgSCHCmnGenPdcchOrder +( +RgSchCellCb *cell, +RgSchDlSf *dlSf +) +#else +PRIVATE Void rgSCHCmnGenPdcchOrder(cell, dlSf) +RgSchCellCb *cell; +RgSchDlSf *dlSf; +#endif +{ + RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell); + CmLList *node = cellSch->rachCfg.pdcchOdrLst.first; + RgSchUeCb *ue; + U8 rapId; + U8 prachMskIdx; + RgSchPdcch *pdcch = NULLP; + + TRC2(rgSCHCmnGenPdcchOrder); + + while (node) + { + ue = (RgSchUeCb *)node->node; + node = node->next; + /* Skip sending for this subframe is Measuring or inActive in UL due + * to MeasGap or inactie due to DRX + */ + if ((ue->measGapCb.isMeasuring == TRUE) || + (ue->ul.ulInactvMask & RG_MEASGAP_INACTIVE) || + (ue->isDrxEnabled && + ue->dl.dlInactvMask & RG_DRX_INACTIVE) + ) + { + continue; + } + if (rgSCHCmnAllocPOParam(cell, dlSf, ue, &pdcch, &rapId,\ + &prachMskIdx) != ROK) + { + /* No More rapIds left for the valid next avl Oppurtunity. + * Unsatisfied UEs here would be given a chance, when the + * prach Mask Index changes as per rachUpd every TTI */ + + /* PDDCH can also be ordered with rapId=0, prachMskIdx=0 + * so that UE triggers a RACH procedure with non-dedicated preamble. + * But the implementation here does not do this. Instead, the "break" + * here implies, that PDCCH Odr always given with valid rapId!=0, + * prachMskIdx!=0 if dedicated preambles are configured. + * If not configured, then trigger a PO with rapId=0,prchMskIdx=0*/ + break; + } + /* Fill pdcch with pdcch odr information */ + rgSCHCmnFillPdcchOdr2Sf(cell, ue, pdcch, rapId, prachMskIdx); + /* Remove this UE from the PDCCH ORDER QUEUE */ + rgSCHCmnDlRmvFrmPdcchOdrQ(cell, ue); + /* Reset UE's power state */ + rgSCHPwrUeReset(cell, ue); + } + RETVOID; +} + + +/** + * @brief This function add UE to PdcchOdr Q if not already present. + * + * @details + * + * Function: rgSCHCmnDlAdd2PdcchOdrQ + * Purpose: + * + * Invoked by: CMN Scheduler + * + * @param[in] RgSchCellCb* cell + * @param[in] RgSchUeCb* ue + * @return Void + * + **/ +#ifdef ANSI +PRIVATE Void rgSCHCmnDlAdd2PdcchOdrQ +( +RgSchCellCb *cell, +RgSchUeCb *ue +) +#else +PRIVATE Void rgSCHCmnDlAdd2PdcchOdrQ(cell, ue) +RgSchCellCb *cell; +RgSchUeCb *ue; +#endif +{ + RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell); + RgSchCmnDlUe *ueDl = RG_SCH_CMN_GET_DL_UE(ue,cell); + + TRC2(rgSCHCmnDlAdd2PdcchOdrQ); + + if (ueDl->rachInfo.poLnk.node == NULLP) + { + cmLListAdd2Tail(&cellSch->rachCfg.pdcchOdrLst, &ueDl->rachInfo.poLnk); + ueDl->rachInfo.poLnk.node = (PTR)ue; + } + RETVOID; +} + + +/** + * @brief This function rmvs UE to PdcchOdr Q if not already present. + * + * @details + * + * Function: rgSCHCmnDlRmvFrmPdcchOdrQ + * Purpose: + * + * Invoked by: CMN Scheduler + * + * @param[in] RgSchCellCb* cell + * @param[in] RgSchUeCb* ue + * @return Void + * + **/ +#ifdef ANSI +PRIVATE Void rgSCHCmnDlRmvFrmPdcchOdrQ +( +RgSchCellCb *cell, +RgSchUeCb *ue +) +#else +PRIVATE Void rgSCHCmnDlRmvFrmPdcchOdrQ(cell, ue) +RgSchCellCb *cell; +RgSchUeCb *ue; +#endif +{ + RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell); + RgSchCmnDlUe *ueDl = RG_SCH_CMN_GET_DL_UE(ue,cell); + + TRC2(rgSCHCmnDlRmvFrmPdcchOdrQ); + + cmLListDelFrm(&cellSch->rachCfg.pdcchOdrLst, &ueDl->rachInfo.poLnk); + ueDl->rachInfo.poLnk.node = NULLP; + RETVOID; +} + +/** + * @brief Fill pdcch with PDCCH order information. + * + * @details + * + * Function: rgSCHCmnFillPdcchOdr2Sf + * Purpose: Fill PDCCH with PDCCH order information, + * + * Invoked by: Common Scheduler + * + * @param[in] RgSchUeCb *ue + * @param[in] RgSchPdcch *pdcch + * @param[in] U8 rapId + * @param[in] U8 prachMskIdx + * @return Void + **/ +#ifdef ANSI +PRIVATE Void rgSCHCmnFillPdcchOdr2Sf +( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgSchPdcch *pdcch, +U8 rapId, +U8 prachMskIdx +) +#else +PRIVATE Void rgSCHCmnFillPdcchOdr2Sf(ue, pdcch, rapId, prachMskIdx) +RgSchCellCb *cell; +RgSchUeCb *ue; +RgSchPdcch *pdcch; +U8 rapId; +U8 prachMskIdx; +#endif +{ + RgSchUeACqiCb *acqiCb = RG_SCH_CMN_GET_ACQICB(ue,cell); + + TRC2(rgSCHCmnFillPdcchOdr2Sf); + + pdcch->rnti = ue->ueId; + pdcch->dci.dciFormat = TFU_DCI_FORMAT_1A; + pdcch->dci.u.format1aInfo.isPdcchOrder = TRUE; + pdcch->dci.u.format1aInfo.t.pdcchOrder.preambleIdx = rapId; + pdcch->dci.u.format1aInfo.t.pdcchOrder.prachMaskIdx = prachMskIdx; + + /* Request for APer CQI immediately after PDCCH Order */ + /* CR ccpu00144525 */ +#ifdef TFU_UPGRADE + if(ue->dl.ueDlCqiCfg.aprdCqiCfg.pres) + { + ue->dl.reqForCqi = RG_SCH_APCQI_SERVING_CC; + acqiCb->aCqiTrigWt = 0; + } +#endif + + RETVOID; +} + + +/** + * @brief UE deletion for scheduler. + * + * @details + * + * Function : rgSCHCmnDelRachInfo + * + * This functions deletes all scheduler information + * pertaining to an UE. + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ue + * @return Void + **/ +#ifdef ANSI +PRIVATE Void rgSCHCmnDelRachInfo +( +RgSchCellCb *cell, +RgSchUeCb *ue +) +#else +PRIVATE Void rgSCHCmnDelRachInfo(cell, ue) +RgSchCellCb *cell; +RgSchUeCb *ue; +#endif +{ + RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell); + RgSchCmnDlUe *ueDl = RG_SCH_CMN_GET_DL_UE(ue,cell); + U8 rapIdIdx; + + TRC2(rgSCHCmnDelRachInfo); + + if (ueDl->rachInfo.poLnk.node) + { + rgSCHCmnDlRmvFrmPdcchOdrQ(cell, ue); + } + if (ueDl->rachInfo.hoLnk.node) + { + cmLListDelFrm(&cellSch->rachCfg.hoUeLst, &ueDl->rachInfo.hoLnk); + ueDl->rachInfo.hoLnk.node = NULLP; + } + if (ueDl->rachInfo.rapIdLnk.node) + { + rapIdIdx = ueDl->rachInfo.poRapId - cellSch->rachCfg.dedPrmStart; + cmLListDelFrm(&cellSch->rachCfg.rapIdMap[rapIdIdx].assgndUes, + &ueDl->rachInfo.rapIdLnk); + ueDl->rachInfo.rapIdLnk.node = NULLP; + } + RETVOID; +} + +/** + * @brief This function retrieves the ue which has sent this raReq + * and it allocates grant for UEs undergoing (for which RAR + * is being generated) HandOver/PdcchOrder. + * + * + * @details + * + * Function: rgSCHCmnHdlHoPo + * Purpose: This function retrieves the ue which has sent this raReq + * and it allocates grant for UEs undergoing (for which RAR + * is being generated) HandOver/PdcchOrder. + * + * Invoked by: Common Scheduler + * + * @param[in] RgSchCellCb *cell + * @param[out] CmLListCp *raRspLst + * @param[in] RgSchRaReqInfo *raReq + * @return Void + * + **/ +#ifdef ANSI +PRIVATE Void rgSCHCmnHdlHoPo +( +RgSchCellCb *cell, +CmLListCp *raRspLst, +RgSchRaReqInfo *raReq +) +#else +PRIVATE Void rgSCHCmnHdlHoPo(cell, raRspLst, raReq) +RgSchCellCb *cell; +CmLListCp *raRspLst; +RgSchRaReqInfo *raReq; +#endif +{ + RgSchUeCb *ue = raReq->ue; + TRC2(rgSCHCmnHdlHoPo); + + if ( ue->isDrxEnabled ) + { + rgSCHDrxDedRa(cell,ue); + } + rgSCHCmnAllocPoHoGrnt(cell, raRspLst, ue, raReq); + RETVOID; +} + +/** + * @brief This function retrieves the UE which has sent this raReq + * for handover case. + * + * + * @details + * + * Function: rgSCHCmnGetHoUe + * Purpose: This function retrieves the UE which has sent this raReq + * for handover case. + * + * Invoked by: Common Scheduler + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchRaReqInfo *raReq + * @return RgSchUeCb* + * + **/ +#ifdef ANSI +PUBLIC RgSchUeCb* rgSCHCmnGetHoUe +( +RgSchCellCb *cell, +U16 rapId +) +#else +PUBLIC RgSchUeCb* rgSCHCmnGetHoUe(cell, rapId) +RgSchCellCb *cell; +U16 rapId +#endif +{ + RgSchCmnCell *cellSch = (RgSchCmnCell *)(cell->sc.sch); + CmLList *node; + CmLListCp *ueLst; + RgSchUeCb *ue; + RgSchCmnDlUe *ueDl; + TRC2(rgSCHCmnGetHoUe); + + ueLst = &cellSch->rachCfg.hoUeLst; + node = ueLst->first; + while (node) + { + ue = (RgSchUeCb *)node->node; + node = node->next; + ueDl = RG_SCH_CMN_GET_DL_UE(ue,cell); + if (ueDl->rachInfo.hoRapId == rapId) + { + RETVALUE(ue); + } + } + RETVALUE(NULLP); +} + +#ifdef ANSI +PRIVATE Void rgSCHCmnDelDedPreamble +( +RgSchCellCb *cell, +U8 preambleId +) +#else +PRIVATE rgSCHCmnDelDedPreamble(cell, preambleId) +RgSchCellCb *cell; +U8 preambleId; +#endif +{ + RgSchCmnCell *cellSch = (RgSchCmnCell *)(cell->sc.sch); + CmLList *node; + CmLListCp *ueLst; + RgSchUeCb *ue; + RgSchCmnDlUe *ueDl; + TRC2(rgSCHCmnDelDedPreamble); + + ueLst = &cellSch->rachCfg.hoUeLst; + node = ueLst->first; + while (node) + { + ue = (RgSchUeCb *)node->node; + node = node->next; + ueDl = RG_SCH_CMN_GET_DL_UE(ue,cell); + if (ueDl->rachInfo.hoRapId == preambleId) + { + cmLListDelFrm(ueLst, &ueDl->rachInfo.hoLnk); + ueDl->rachInfo.hoLnk.node = (PTR)NULLP; + } + } +} + +/** + * @brief This function retrieves the UE which has sent this raReq + * for PDCCh Order case. + * + * + * @details + * + * Function: rgSCHCmnGetPoUe + * Purpose: This function retrieves the UE which has sent this raReq + * for PDCCH Order case. + * + * Invoked by: Common Scheduler + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchRaReqInfo *raReq + * @return RgSchUeCb* + * + **/ +#ifdef ANSI +PUBLIC RgSchUeCb* rgSCHCmnGetPoUe +( +RgSchCellCb *cell, +U16 rapId, +CmLteTimingInfo timingInfo +) +#else +PUBLIC RgSchUeCb* rgSCHCmnGetPoUe(cell, rapId, timingInfo) +RgSchCellCb *cell; +U16 rapId; +CmLteTimingInfo timingInfo; +#endif +{ + RgSchCmnCell *cellSch = (RgSchCmnCell *)(cell->sc.sch); + CmLList *node; + CmLListCp *ueLst; + RgSchUeCb *ue; + RgSchCmnDlUe *ueDl; + U8 rapIdIdx; + TRC2(rgSCHCmnGetPoUe); + + rapIdIdx = rapId -cellSch->rachCfg.dedPrmStart; + ueLst = &cellSch->rachCfg.rapIdMap[rapIdIdx].assgndUes; + node = ueLst->first; + while (node) + { + ue = (RgSchUeCb *)node->node; + node = node->next; + ueDl = RG_SCH_CMN_GET_DL_UE(ue,cell); + /* Remove UEs irrespective. + * Old UE associations are removed.*/ + cmLListDelFrm(ueLst, &ueDl->rachInfo.rapIdLnk); + ueDl->rachInfo.rapIdLnk.node = (PTR)NULLP; + if (RGSCH_TIMEINFO_SAME(ueDl->rachInfo.asgnOppr, timingInfo)) + { + RETVALUE(ue); + } + } + + RETVALUE(NULLP); +} + + +/** + * @brief This function returns the valid UL cqi for a given UE. + * + * @details + * + * Function: rgSCHCmnUlGetCqi + * Purpose: This function returns the "valid UL cqi" for a given UE + * based on UE category + * + * Invoked by: Scheduler + * + * @param[in] RgSchUeCb *ue + * @param[in] U8 ueCtgy + * @return U8 + **/ +#ifdef ANSI +PUBLIC U8 rgSCHCmnUlGetCqi +( +RgSchCellCb *cell, +RgSchUeCb *ue, +CmLteUeCategory ueCtgy +) +#else +PUBLIC U8 rgSCHCmnUlGetCqi(cell, ue, ueCtgy) +RgSchCellCb *cell; +RgSchUeCb *ue; +CmLteUeCategory ueCtgy; +#endif +{ + RgSchCmnUlUe *ueUl = RG_SCH_CMN_GET_UL_UE(ue,cell); + U8 cqi; + + TRC2(rgSCHCmnUlGetCqi); + + cqi = ueUl->maxUlCqi; +#ifdef TFU_UPGRADE + if (!((ueCtgy != CM_LTE_UE_CAT_5) && + (ueUl->validUlCqi > ueUl->maxUlCqi))) + { + cqi = ueUl->validUlCqi; + } +#else + if (!((ueCtgy != CM_LTE_UE_CAT_5) && + (ueUl->crntUlCqi[0] > ueUl->maxUlCqi ))) + { + cqi = ueUl->crntUlCqi[0]; + } +#endif + RETVALUE(cqi); +}/* End of rgSCHCmnUlGetCqi */ + +/*********************************************************** + * + * Func : rgSCHCmnUlRbAllocForPoHoUe + * + * Desc : Do uplink RB allocation for a HO/PO UE. + * + * Ret : + * + * Notes: Note that as of now, for retx, maxRb + * is not considered. Alternatives, such + * as dropping retx if it crosses maxRb + * could be considered. + * + * File : + * + **********************************************************/ +#ifdef ANSI +PRIVATE S16 rgSCHCmnUlRbAllocForPoHoUe +( +RgSchCellCb *cell, +RgSchUlSf *sf, +RgSchUeCb *ue, +U8 maxRb +) +#else +PRIVATE S16 rgSCHCmnUlRbAllocForPoHoUe(cell, sf, ue, maxRb) +RgSchCellCb *cell; +RgSchUlSf *sf; +RgSchUeCb *ue; +U8 maxRb; +#endif +{ + RgSchCmnUlCell *cellUl = RG_SCH_CMN_GET_UL_CELL(cell); + RgSchCmnUlUe *ueUl = RG_SCH_CMN_GET_UL_UE(ue,cell); + U8 sbSize = cellUl->sbSize; + U32 maxBits = ue->ul.maxBytesPerUePerTti*8; + U32 bits; + RgSchUlAlloc *alloc; + U32 nPrb; + U8 iTbs; + U32 eff; + U32 numSb; + U8 iMcs; + U8 iMcsCrnt; + U8 cqi; + U8 modOdr; + RgSchUlHole *hole; + RgSchUlHqProcCb *proc = &ueUl->hqEnt.hqProcCb[cellUl->msg3SchdHqProcIdx]; + CmLteUeCategory ueCtg = (CmLteUeCategory)(RG_SCH_CMN_GET_UE_CTGY(ue)); + + TRC2(rgSCHCmnUlRbAllocForPoHoUe); + if ((hole = rgSCHUtlUlHoleFirst(sf)) == NULLP) + { + RETVALUE(RFAILED); + } + /*MS_WORKAROUND for HO ccpu00121116*/ + cqi = rgSCHCmnUlGetCqi(cell, ue, ueCtg); + RGSCH_ARRAY_BOUND_CHECK(cell->instIdx, rgSchCmnUlCqiToTbsTbl[(U8)cell->isCpUlExtend], cqi); + iTbs = rgSchCmnUlCqiToTbsTbl[(U8)cell->isCpUlExtend][cqi]; + iMcs = rgSCHCmnUlGetIMcsFrmITbs(iTbs,ueCtg); + while(iMcs > RG_SCH_CMN_MAX_MSG3_IMCS) + { + cqi--; + iTbs = rgSchCmnUlCqiToTbsTbl[(U8)cell->isCpUlExtend][cqi]; + iMcs = rgSCHCmnUlGetIMcsFrmITbs(iTbs, ueCtg); + } + /* Filling the modorder in the grant structure*/ + RG_SCH_UL_MCS_TO_MODODR(iMcs,modOdr); + if (!cell->isCpUlExtend) + { + eff = rgSchCmnNorUlEff[0][iTbs]; + } + else + { + eff = rgSchCmnExtUlEff[0][iTbs]; + } + + bits = ueUl->alloc.reqBytes * 8; + +#if (ERRCLASS & ERRCLS_DEBUG) + if (!bits) + { + RETVALUE(RFAILED); + } +#endif + + if (bits < rgSCHCmnUlMinTbBitsForITbs(cellUl, iTbs)) + { + numSb = 1; + nPrb = numSb * sbSize; + } + else + { + if (bits > maxBits) + { + bits = maxBits; + nPrb = bits * 1024 / eff / RG_SCH_CMN_UL_NUM_RE_PER_RB(cellUl); + if (nPrb > maxRb) + { + nPrb = maxRb; + } + numSb = nPrb / sbSize; + } + else + { + /*ccpu00128775:MOD-Change to get upper threshold nPrb*/ + nPrb = RGSCH_CEIL((RGSCH_CEIL(bits * 1024, eff)), + RG_SCH_CMN_UL_NUM_RE_PER_RB(cellUl)); + if (nPrb > maxRb) + { + nPrb = maxRb; + } + numSb = RGSCH_DIV_ROUND(nPrb, sbSize); + } + } + iMcsCrnt = iMcs; + + alloc = rgSCHCmnUlSbAlloc(sf, (U8)RGSCH_MIN(numSb, cellUl->maxSbPerUe),\ + hole); + if (alloc == NULLP) + { + RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId, + "rgSCHCmnUlRbAllocForPoHoUe(): Could not get UlAlloc"); + RETVALUE(RFAILED); + } + rgSCHCmnUlAllocFillRbInfo(cell, sf, alloc); + + /* Filling the modorder in the grant structure start*/ + alloc->grnt.modOdr = (TfuModScheme) modOdr; + alloc->grnt.iMcs = iMcs; + alloc->grnt.iMcsCrnt = iMcsCrnt; + alloc->grnt.hop = 0; + /* Fix for ccpu00123915*/ + alloc->forMsg3 = TRUE; + alloc->hqProc = proc; + alloc->hqProc->ulSfIdx = cellUl->msg3SchdIdx; + alloc->ue = ue; + alloc->rnti = ue->ueId; + /* updating initNumRbs in case of HO */ +#ifdef TFU_UPGRADE + ue->initNumRbs = alloc->grnt.numRb; +#endif + ueUl->alloc.alloc = alloc; + iTbs = rgSCHCmnUlGetITbsFrmIMcs(iMcs); + RGSCH_ARRAY_BOUND_CHECK(cell->instIdx, rgTbSzTbl[0], iTbs); + alloc->grnt.datSz = rgTbSzTbl[0][iTbs][alloc->grnt.numRb-1] / 8; + /* MS_WORKAROUND for HO ccpu00121124*/ + /*[Adi temp change] Need to fil modOdr */ + RG_SCH_UL_MCS_TO_MODODR(alloc->grnt.iMcsCrnt,alloc->grnt.modOdr); + rgSCHUhmNewTx(proc, ueUl->hqEnt.maxHqRetx, alloc); + /* No grant attr recorded now */ + RETVALUE(ROK); +} + +/** + * @brief This function allocates grant for UEs undergoing (for which RAR + * is being generated) HandOver/PdcchOrder. + * + * + * @details + * + * Function: rgSCHCmnAllocPoHoGrnt + * Purpose: This function allocates grant for UEs undergoing (for which RAR + * is being generated) HandOver/PdcchOrder. + * + * Invoked by: Common Scheduler + * + * @param[in] RgSchCellCb *cell + * @param[out] CmLListCp *raRspLst, + * @param[in] RgSchUeCb *ue + * @param[in] RgSchRaReqInfo *raReq + * @return Void + * + **/ +#ifdef ANSI +PRIVATE Void rgSCHCmnAllocPoHoGrnt +( +RgSchCellCb *cell, +CmLListCp *raRspLst, +RgSchUeCb *ue, +RgSchRaReqInfo *raReq +) +#else +PRIVATE Void rgSCHCmnAllocPoHoGrnt(cell, raRspLst, ue, raReq) +RgSchCellCb *cell; +CmLListCp *raRspLst; +RgSchUeCb *ue; +RgSchRaReqInfo *raReq; +#endif +{ + RgSchCmnUlCell *cellUl = RG_SCH_CMN_GET_UL_CELL(cell); + RgSchCmnUlUe *ueUl = RG_SCH_CMN_GET_UL_UE(ue,cell); + RgSchUlGrnt *grnt; + RgSchUlSf *sf = &cellUl->ulSfArr[cellUl->msg3SchdIdx]; + + TRC2(rgSCHCmnAllocPoHoGrnt); + + /* Clearing previous allocs if any*/ + rgSCHCmnUlUeDelAllocs(cell, ue); + /* Fix : syed allocs are limited */ + if (*sf->allocCountRef >= cellUl->maxAllocPerUlSf) + { + RETVOID; + } + ueUl->alloc.reqBytes = RG_SCH_MIN_GRNT_HOPO; + if (rgSCHCmnUlRbAllocForPoHoUe(cell, sf, ue, RGSCH_MAX_UL_RB) != ROK) + { + RETVOID; + } + + /* Fill grant information */ + grnt = &ueUl->alloc.alloc->grnt; + + /* KWork fix */ + if (grnt == NULLP) + { + RLOG_ARG1(L_ERROR,DBG_INSTID,cell->instIdx, "Failed to get" + "the grant for HO/PDCCH Order. CRNTI:%d",ue->ueId); + RETVOID; + } + ue->ul.rarGrnt.rapId = raReq->raReq.rapId; + ue->ul.rarGrnt.hop = grnt->hop; + ue->ul.rarGrnt.rbStart = grnt->rbStart; + ue->ul.rarGrnt.numRb = grnt->numRb; + ue->ul.rarGrnt.tpc = grnt->tpc; + ue->ul.rarGrnt.iMcsCrnt = grnt->iMcsCrnt; + ue->ul.rarGrnt.ta.pres = TRUE; + ue->ul.rarGrnt.ta.val = raReq->raReq.ta; + ue->ul.rarGrnt.datSz = grnt->datSz; + if((sf->numACqiCount < RG_SCH_MAX_ACQI_PER_ULSF) && (RG_SCH_APCQI_NO != ue->dl.reqForCqi)) + { +#ifdef LTE_ADV + U8 idx = 0; + /* Send two bits cqireq field if more than one cells are configured else one*/ + for (idx = 1;idx < CM_LTE_MAX_CELLS;idx++) + { + if (ue->cellInfo[idx] != NULLP) + { + ue->ul.rarGrnt.cqiReqBit = ue->dl.reqForCqi; + break; + } + } + if (idx == CM_LTE_MAX_CELLS) +#endif + { + ue->ul.rarGrnt.cqiReqBit = ue->dl.reqForCqi; + } + ue->dl.reqForCqi = RG_SCH_APCQI_NO; + sf->numACqiCount++; + } + else + { + ue->ul.rarGrnt.cqiReqBit = 0; + } + /* Attach Ho/Po allocation to RAR Rsp cont free Lst */ + cmLListAdd2Tail(raRspLst, &ue->ul.rarGrnt.raRspLnk); + ue->ul.rarGrnt.raRspLnk.node = (PTR)ue; + + RETVOID; +} + +/** + * @brief This is a utility function to set the fields in + * an UL harq proc which is identified for non-adaptive retx + * + * @details + * + * Function: rgSCHCmnUlNonadapRetx + * Purpose: Sets the fields in UL Harq proc for non-adaptive retx + * + * @param[in] RgSchCmnUlCell *cellUl + * @param[out] RgSchUlAlloc *alloc + * @param[in] U8 idx + * @return Void + * + **/ +#ifdef ANSI +PRIVATE Void rgSCHCmnUlNonadapRetx +( +RgSchCmnUlCell *cellUl, +RgSchUlAlloc *alloc, +U8 idx +) +#else +PRIVATE Void rgSCHCmnUlNonadapRetx(cellUl, alloc, idx) +RgSchCmnUlCell *cellUl; +RgSchUlAlloc *alloc; +U8 idx; +#endif +{ + TRC2(rgSCHCmnUlNonadapRetx); + rgSCHUhmRetx(alloc->hqProc, alloc); + + /* Update alloc to retx */ + alloc->hqProc->isRetx = TRUE; + alloc->hqProc->ulSfIdx = cellUl->reTxIdx[idx]; + + if (alloc->hqProc->rvIdx != 0) + { + alloc->grnt.iMcsCrnt = rgSchCmnUlRvIdxToIMcsTbl[alloc->hqProc->rvIdx]; + } + else + { + alloc->grnt.iMcsCrnt = alloc->grnt.iMcs; + } + alloc->grnt.isRtx = TRUE; + alloc->pdcch = NULLP; + RETVOID; +} + +/** + * @brief Check if 2 allocs overlap + * + * @details + * + * Function : rgSCHCmnUlAllocsOvrLap + * + * - Return TRUE if alloc1 and alloc2 overlap. + * + * @param[in] RgSchUlAlloc *alloc1 + * @param[in] RgSchUlAlloc *alloc2 + * @return Bool + **/ +#ifdef ANSI +PRIVATE Bool rgSCHCmnUlAllocsOvrLap +( +RgSchUlAlloc *alloc1, +RgSchUlAlloc *alloc2 +) +#else +PRIVATE Bool rgSCHCmnUlAllocsOvrLap(alloc1, alloc2) +RgSchUlAlloc *alloc1; +RgSchUlAlloc *alloc2; +#endif +{ + + TRC2(rgSCHCmnUlAllocsOvrLap); + + if (((alloc1->sbStart >= alloc2->sbStart) && + (alloc1->sbStart <= alloc2->sbStart + alloc2->numSb-1)) || + ((alloc2->sbStart >= alloc1->sbStart) && + (alloc2->sbStart <= alloc1->sbStart + alloc1->numSb-1))) + { + RETVALUE(TRUE); + } + RETVALUE(FALSE); +} + +/** + * @brief Copy allocation Info from src to dst. + * + * @details + * + * Function : rgSCHCmnUlCpyAllocInfo + * + * - Copy allocation Info from src to dst. + * + * @param[in] RgSchUlAlloc *srcAlloc + * @param[in] RgSchUlAlloc *dstAlloc + * @return Void + **/ +#ifdef ANSI +PRIVATE Void rgSCHCmnUlCpyAllocInfo +( +RgSchCellCb *cell, +RgSchUlAlloc *srcAlloc, +RgSchUlAlloc *dstAlloc +) +#else +PRIVATE Void rgSCHCmnUlCpyAllocInfo(cell, srcAlloc, dstAlloc) +RgSchCellCb *cell; +RgSchUlAlloc *srcAlloc; +RgSchUlAlloc *dstAlloc; +#endif +{ + RgSchCmnUlUe *ueUl; + TRC2(rgSCHCmnUlCpyAllocInfo); + + dstAlloc->grnt = srcAlloc->grnt; + dstAlloc->hqProc = srcAlloc->hqProc; + /* Fix : syed During UE context release, hqProc->alloc + * was pointing to srcAlloc instead of dstAlloc and + * freeing from incorrect sf->allocDb was + * corrupting the list. */ + /* In case of SPS Occasion Allocation is done in advance and + at a later time Hq Proc is linked. Hence HqProc + pointer in alloc shall be NULL */ +#ifdef LTEMAC_SPS + if (dstAlloc->hqProc) +#endif + { + dstAlloc->hqProc->alloc = dstAlloc; + } + dstAlloc->ue = srcAlloc->ue; + dstAlloc->rnti = srcAlloc->rnti; + dstAlloc->forMsg3 = srcAlloc->forMsg3; + dstAlloc->raCb = srcAlloc->raCb; + dstAlloc->pdcch = srcAlloc->pdcch; + /* Fix : syed HandIn Ue has forMsg3 and ue Set, but no RaCb */ + if (dstAlloc->ue) + { + ueUl = RG_SCH_CMN_GET_UL_UE(dstAlloc->ue,cell); + ueUl->alloc.alloc = dstAlloc; +#ifdef LTEMAC_SPS + if (dstAlloc->ue->ul.ulSpsCfg.isUlSpsEnabled == TRUE) + { + if((dstAlloc->ue->ul.ulSpsInfo.ulSpsSchdInfo.crntAlloc != NULLP) + && (dstAlloc->ue->ul.ulSpsInfo.ulSpsSchdInfo.crntAlloc == srcAlloc)) + { + dstAlloc->ue->ul.ulSpsInfo.ulSpsSchdInfo.crntAlloc = dstAlloc; + } + } +#endif + } + + RETVOID; +} + + +/** + * @brief Update TX and RETX subframe's allocation + * markings. + * + * @details + * + * Function : rgSCHCmnUlInsAllocFrmNewSf2OldSf + * + * - Release all preassigned allocations of newSf and merge + * them to oldSf. + * - If alloc of newSf collide with one or more allocs of oldSf + * - mark all such allocs of oldSf for Adaptive Retx. + * - Swap the alloc and hole DB references of oldSf and newSf. + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUlSf *newSf + * @param[in] RgSchUlSf *oldSf + * @param[in] RgSchUlAlloc *srcAlloc + * @return Void + **/ +#ifdef ANSI +PRIVATE Void rgSCHCmnUlInsAllocFrmNewSf2OldSf +( +RgSchCellCb *cell, +RgSchUlSf *newSf, +RgSchUlSf *oldSf, +RgSchUlAlloc *srcAlloc +) +#else +PRIVATE Void rgSCHCmnUlInsAllocFrmNewSf2OldSf(cell, newSf, oldSf, srcAlloc) +RgSchCellCb *cell; +RgSchUlSf *newSf; +RgSchUlSf *oldSf; +RgSchUlAlloc *srcAlloc; +#endif +{ + RgSchUlAlloc *alloc, *dstAlloc, *nxtAlloc; + + /* MS_WORKAROUND ccpu00120827 */ + RgSchCmnCell *schCmnCell = (RgSchCmnCell *)(cell->sc.sch); + U8 remAllocs; + TRC2(rgSCHCmnUlInsAllocFrmNewSf2OldSf); + + if ((alloc = rgSCHUtlUlAllocFirst(oldSf)) != NULLP) + { + do + { + nxtAlloc = rgSCHUtlUlAllocNxt(oldSf, alloc); + /* If there is an overlap between alloc and srcAlloc + * then alloc is marked for Adaptive retx and it is released + * from txSf */ + if (rgSCHCmnUlAllocsOvrLap(alloc, srcAlloc) == TRUE) + { + rgSCHCmnUlUpdAllocRetx(cell, alloc); + rgSCHUtlUlAllocRls(oldSf, alloc); + } + /* No further allocs spanning the srcAlloc subbands */ + if (srcAlloc->sbStart + srcAlloc->numSb - 1 <= alloc->sbStart) + { + break; + } + } while ((alloc = nxtAlloc) != NULLP); + } + + /* After freeing all the colliding allocs, request for an allocation + * specifying the start and numSb with in txSf. This function should + * always return positively with a nonNULL dstAlloc */ + /* MS_WORKAROUND ccpu00120827 */ + remAllocs = schCmnCell->ul.maxAllocPerUlSf - *oldSf->allocCountRef; + if (!remAllocs) + { + /* Fix : If oldSf already has max Allocs then release the + * old RETX alloc to make space for new alloc of newSf. + * newSf allocs(i.e new Msg3s) are given higher priority + * over retx allocs. */ + if ((alloc = rgSCHUtlUlAllocFirst(oldSf)) != NULLP) + { + do + { + nxtAlloc = rgSCHUtlUlAllocNxt(oldSf, alloc); + if (!alloc->mrgdNewTxAlloc) + { + /* If alloc is for RETX */ + /* TODO: Incase of this ad also in case of choosing + * and alloc for ADAP RETX, we need to send ACK for + * the corresponding alloc in PHICH */ +#ifndef EMTC_ENABLE + rgSCHCmnUlFreeAllocation(cell, oldSf, alloc); +#else + rgSCHCmnUlFreeAllocation(cell, oldSf, alloc,FALSE); +#endif + break; + } + }while((alloc = nxtAlloc) != NULLP); + } + } + dstAlloc = rgSCHUtlUlGetSpfcAlloc(oldSf, srcAlloc->sbStart, srcAlloc->numSb); +#ifdef ERRCLS_KW + /* This should never happen */ + if (dstAlloc == NULLP) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,"CRNTI:%d " + "rgSCHUtlUlGetSpfcAlloc failed in rgSCHCmnUlInsAllocFrmNewSf2OldSf", + srcAlloc->rnti); + RETVOID; + } +#endif + /* Copy the srcAlloc's state information in to dstAlloc */ + rgSCHCmnUlCpyAllocInfo(cell, srcAlloc, dstAlloc); + /* Set new Tx merged Alloc Flag to TRUE, indicating that this + * alloc shall not be processed for non-adaptive retransmission */ + dstAlloc->mrgdNewTxAlloc = TRUE; + RETVOID; +} + +/** + * @brief Merge all allocations of newSf to oldSf. + * + * @details + * + * Function : rgSCHCmnUlMergeSfAllocs + * + * - Merge all allocations of newSf to oldSf. + * - If newSf's alloc collides with oldSf's alloc + * then oldSf's alloc is marked for adaptive Retx + * and is released from oldSf to create space for + * newSf's alloc. + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUlSf *oldSf + * @param[in] RgSchUlSf *newSf + * @return Void + **/ +#ifdef ANSI +PRIVATE Void rgSCHCmnUlMergeSfAllocs +( +RgSchCellCb *cell, +RgSchUlSf *oldSf, +RgSchUlSf *newSf +) +#else +PRIVATE Void rgSCHCmnUlMergeSfAllocs(cell, oldSf, newSf) +RgSchCellCb *cell; +RgSchUlSf *oldSf; +RgSchUlSf *newSf; +#endif +{ + RgSchUlAlloc *alloc, *nxtAlloc; + TRC2(rgSCHCmnUlMergeSfAllocs); + UNUSED(cell); + + /* Merge each alloc of newSf in to oldSf + * and release it from newSf */ + if ((alloc = rgSCHUtlUlAllocFirst(newSf)) != NULLP) + { + do + { + nxtAlloc = rgSCHUtlUlAllocNxt(newSf, alloc); + rgSCHCmnUlInsAllocFrmNewSf2OldSf(cell, newSf, oldSf, alloc); + rgSCHUtlUlAllocRls(newSf, alloc); + } while((alloc = nxtAlloc) != NULLP); + } + RETVOID; +} + +/** + * @brief Swap Hole/Alloc DB context of newSf and oldSf. + * + * @details + * + * Function : rgSCHCmnUlSwapSfAllocs + * + * - Swap Hole/Alloc DB context of newSf and oldSf. + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUlSf *oldSf + * @param[in] RgSchUlSf *newSf + * @return Void + **/ +#ifdef ANSI +PRIVATE Void rgSCHCmnUlSwapSfAllocs +( +RgSchCellCb *cell, +RgSchUlSf *oldSf, +RgSchUlSf *newSf +) +#else +PRIVATE Void rgSCHCmnUlSwapSfAllocs(cell, oldSf, newSf) +RgSchCellCb *cell; +RgSchUlSf *oldSf; +RgSchUlSf *newSf; +#endif +{ + RgSchUlAllocDb *tempAllocDb = newSf->allocDb; + RgSchUlHoleDb *tempHoleDb = newSf->holeDb; + U8 tempAvailSbs = newSf->availSubbands; + + TRC2(rgSCHCmnUlSwapSfAllocs); + UNUSED(cell); + + newSf->allocDb = oldSf->allocDb; + newSf->holeDb = oldSf->holeDb; + newSf->availSubbands = oldSf->availSubbands; + + oldSf->allocDb = tempAllocDb; + oldSf->holeDb = tempHoleDb; + oldSf->availSubbands = tempAvailSbs; + + /* Fix ccpu00120610*/ + newSf->allocCountRef = &newSf->allocDb->count; + oldSf->allocCountRef = &oldSf->allocDb->count; + RETVOID; +} + +/** + * @brief Perform non-adaptive RETX for non-colliding allocs. + * + * @details + * + * Function : rgSCHCmnUlPrcNonAdptRetx + * + * - Perform non-adaptive RETX for non-colliding allocs. + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUlSf *newSf + * @param[in] U8 idx + * @return Void + **/ +#ifdef ANSI +PRIVATE Void rgSCHCmnUlPrcNonAdptRetx +( +RgSchCellCb *cell, +RgSchUlSf *newSf, +U8 idx +) +#else +PRIVATE Void rgSCHCmnUlPrcNonAdptRetx(cell, newSf, idx) +RgSchCellCb *cell; +RgSchUlSf *newSf; +U8 idx; +#endif +{ + RgSchCmnUlCell *cellUl = RG_SCH_CMN_GET_UL_CELL(cell); + RgSchUlAlloc *alloc, *nxtAlloc; + TRC2(rgSCHCmnUlPrcNonAdptRetx); + + /* perform non-adaptive retx allocation(adjustment) */ + if ((alloc = rgSCHUtlUlAllocFirst(newSf)) != NULLP) + { + do + { + nxtAlloc = rgSCHUtlUlAllocNxt(newSf, alloc); + /* A merged new TX alloc, reset the state and skip */ + if (alloc->mrgdNewTxAlloc) + { + alloc->mrgdNewTxAlloc = FALSE; + continue; + } + + + rgSCHCmnUlNonadapRetx(cellUl, alloc, idx); + + } while((alloc = nxtAlloc) != NULLP); + } + RETVOID; +} + +/** + * @brief Update TX and RETX subframe's allocation + * markings. + * + * @details + * + * Function : rgSCHCmnUlPrfmSfMerge + * + * - Release all preassigned allocations of newSf and merge + * them to oldSf. + * - If alloc of newSf collide with one or more allocs of oldSf + * - mark all such allocs of oldSf for Adaptive Retx. + * - Swap the alloc and hole DB references of oldSf and newSf. + * - The allocs which did not collide with pre-assigned msg3 + * allocs are marked for non-adaptive RETX. + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUlSf *oldSf + * @param[in] RgSchUlSf *newSf + * @param[in] U8 idx + * @return Void + **/ +#ifdef ANSI +PRIVATE Void rgSCHCmnUlPrfmSfMerge +( +RgSchCellCb *cell, +RgSchUlSf *oldSf, +RgSchUlSf *newSf, +U8 idx +) +#else +PRIVATE Void rgSCHCmnUlPrfmSfMerge(cell, oldSf, newSf, idx) +RgSchCellCb *cell; +RgSchUlSf *oldSf; +RgSchUlSf *newSf; +U8 idx; +#endif +{ + TRC2(rgSCHCmnUlPrfmSfMerge); + /* Preassigned resources for msg3 in newSf. + * Hence do adaptive retx for all NACKED TXs */ + rgSCHCmnUlMergeSfAllocs(cell, oldSf, newSf); + /* swap alloc and hole DBs of oldSf and newSf. */ + rgSCHCmnUlSwapSfAllocs(cell, oldSf, newSf); + /* Here newSf has the resultant merged allocs context */ + /* Perform non-adaptive RETX for non-colliding allocs */ + rgSCHCmnUlPrcNonAdptRetx(cell, newSf, idx); + + RETVOID; +} + +/** + * @brief Update TX and RETX subframe's allocation + * markings. + * + * @details + * + * Function : rgSCHCmnUlRmvCmpltdAllocs + * + * - Free all Transmission which are ACKED + * OR for which MAX retransmission have + * occurred. + * + * + * @param[in] RgSchCellCb *cell, + * @param[in] RgSchUlSf *sf + * @return Void + **/ +#ifdef ANSI +PRIVATE Void rgSCHCmnUlRmvCmpltdAllocs +( +RgSchCellCb *cell, +RgSchUlSf *sf +) +#else +PRIVATE Void rgSCHCmnUlRmvCmpltdAllocs(cell, sf) +RgSchCellCb *cell; +RgSchUlSf *sf; +#endif +{ + RgSchUlAlloc *alloc, *nxtAlloc; + TRC2(rgSCHCmnUlRmvCmpltdAllocs); + + if ((alloc = rgSCHUtlUlAllocFirst(sf)) == NULLP) + { + RETVOID; + } + do + { + nxtAlloc = rgSCHUtlUlAllocNxt(sf, alloc); +#ifdef UL_ADPT_DBG + printf("rgSCHCmnUlRmvCmpltdAllocs:time(%d %d) alloc->hqProc->remTx %d hqProcId(%d) \n",cell->crntTime.sfn,cell->crntTime.subframe,alloc->hqProc->remTx, alloc->grnt.hqProcId); +#endif + alloc->hqProc->rcvdCrcInd = TRUE; + if ((alloc->hqProc->rcvdCrcInd) || (alloc->hqProc->remTx == 0)) + { + + /* SR_RACH_STATS : MSG 3 MAX RETX FAIL*/ + if ((alloc->forMsg3 == TRUE) && (alloc->hqProc->remTx == 0)) + { + rgNumMsg3FailMaxRetx++; +#ifdef TENB_STATS + cell->tenbStats->sch.msg3Fail++; +#endif + } + +#ifdef MAC_SCH_STATS + if(alloc->ue != NULLP) + { + /* access from ulHarqProc*/ + RgSchUeCb *ueCb = alloc->ue; + RgSchCmnUe *cmnUe = (RgSchCmnUe*)ueCb->sch; + RgSchCmnUlUe *ulUe = &(cmnUe->ul); + U8 cqi = ulUe->crntUlCqi[0]; + U16 numUlRetx = ueCb->ul.hqEnt.maxHqRetx - alloc->hqProc->remTx; + + hqRetxStats.ulCqiStat[(cqi - 1)].mcs = alloc->grnt.iMcs; + + switch (numUlRetx) + { + case 1: + hqRetxStats.ulCqiStat[(cqi - 1)].numOfHQ_1++; + break; + case 2: + hqRetxStats.ulCqiStat[(cqi - 1)].numOfHQ_2++; + break; + case 3: + hqRetxStats.ulCqiStat[(cqi - 1)].numOfHQ_3++; + break; + case 4: + hqRetxStats.ulCqiStat[(cqi - 1)].numOfHQ_4++; + break; + } + hqRetxStats.ulCqiStat[(cqi - 1)].totalTx = \ + hqRetxStats.ulCqiStat[(cqi - 1)].numOfHQ_1 + \ + (hqRetxStats.ulCqiStat[(cqi - 1)].numOfHQ_2 * 2) + \ + (hqRetxStats.ulCqiStat[(cqi - 1)].numOfHQ_3 * 3) + \ + (hqRetxStats.ulCqiStat[(cqi - 1)].numOfHQ_4 * 4); + } + +#endif /*MAC_SCH_STATS*/ + rgSCHCmnUlFreeAllocation(cell, sf, alloc); + } + /*ccpu00106104 MOD added check for AckNackRep */ + /*added check for acknack so that adaptive retx considers ue + inactivity due to ack nack repetition*/ + else if((alloc->ue != NULLP) && (TRUE != alloc->forMsg3)) + { + rgSCHCmnUlUpdAllocRetx(cell, alloc); + rgSCHUtlUlAllocRls(sf, alloc); + } + } while ((alloc = nxtAlloc) != NULLP); + + RETVOID; +} + +/** + * @brief Update an uplink subframe. + * + * @details + * + * Function : rgSCHCmnRlsUlSf + * + * For each allocation + * - if no more tx needed + * - Release allocation + * - else + * - Perform retransmission + * + * @param[in] RgSchUlSf *sf + * @param[in] U8 idx + * @return Void + **/ +#ifdef ANSI +PUBLIC Void rgSCHCmnRlsUlSf +( +RgSchCellCb *cell, +U8 idx +) +#else +PUBLIC Void rgSCHCmnRlsUlSf(cell, idx) +RgSchCellCb *cell; +U8 idx; +#endif +{ + TRC2(rgSCHCmnRlsUlSf); + + RgSchCmnUlCell *cellUl = RG_SCH_CMN_GET_UL_CELL(cell); + + if (cellUl->hqFdbkIdx[idx] != RGSCH_INVALID_INFO) + { + RgSchUlSf *oldSf = &cellUl->ulSfArr[cellUl->hqFdbkIdx[idx]]; + + /* Initialize the reTxLst of UL HqProcs for RETX subframe */ + if (rgSCHUtlUlAllocFirst(oldSf) == NULLP) + { + RETVOID; + } + /* Release all completed TX allocs from sf */ + rgSCHCmnUlRmvCmpltdAllocs(cell, oldSf); + + oldSf->numACqiCount = 0; + } + RETVOID; +} + +/** + * @brief Handle uplink allocation for retransmission. + * + * @details + * + * Function : rgSCHCmnUlUpdAllocRetx + * + * - Perform adaptive retransmission + * + * @param[in] RgSchUlSf *sf + * @param[in] RgSchUlAlloc *alloc + * @return Void + **/ +#ifdef ANSI +PRIVATE Void rgSCHCmnUlUpdAllocRetx +( +RgSchCellCb *cell, +RgSchUlAlloc *alloc +) +#else +PRIVATE Void rgSCHCmnUlUpdAllocRetx(cell, alloc) +RgSchCellCb *cell; +RgSchUlAlloc *alloc; +#endif +{ + RgSchCmnUlCell *cmnUlCell = RG_SCH_CMN_GET_UL_CELL(cell); + + TRC2(rgSCHCmnUlUpdAllocRetx); + + alloc->hqProc->reTxAlloc.rnti = alloc->rnti; + alloc->hqProc->reTxAlloc.numSb = alloc->numSb; + alloc->hqProc->reTxAlloc.iMcs = alloc->grnt.iMcs; +#ifdef RG_5GTF + alloc->hqProc->reTxAlloc.dciFrmt = alloc->grnt.dciFrmt; + alloc->hqProc->reTxAlloc.numLyr = alloc->grnt.numLyr; + alloc->hqProc->reTxAlloc.vrbgStart = alloc->grnt.vrbgStart; + alloc->hqProc->reTxAlloc.numVrbg = alloc->grnt.numVrbg; + alloc->hqProc->reTxAlloc.modOdr = alloc->grnt.modOdr; +#endif + //iTbs = rgSCHCmnUlGetITbsFrmIMcs(alloc->grnt.iMcs); + //iTbs = alloc->grnt.iMcs; + //RGSCH_ARRAY_BOUND_CHECK( 0, rgTbSzTbl[0], iTbs); + alloc->hqProc->reTxAlloc.tbSz = alloc->grnt.datSz; + //rgTbSzTbl[0][iTbs][alloc->grnt.numRb-1]/8; + alloc->hqProc->reTxAlloc.ue = alloc->ue; + alloc->hqProc->reTxAlloc.forMsg3 = alloc->forMsg3; + alloc->hqProc->reTxAlloc.raCb = alloc->raCb; + + /* Set as retransmission is pending */ + alloc->hqProc->isRetx = TRUE; + alloc->hqProc->alloc = NULLP; + alloc->hqProc->ulSfIdx = RGSCH_INVALID_INFO; +#ifdef UL_ADPT_DBG + printf("Adding Harq Proc Id in the retx list hqProcId %d \n",alloc->grnt.hqProcId); +#endif + cmLListAdd2Tail(&cmnUlCell->reTxLst, &alloc->hqProc->reTxLnk); + alloc->hqProc->reTxLnk.node = (PTR)alloc->hqProc; + RETVOID; +} + +/** + * @brief Attempts allocation for msg3s for which ADAP retransmissions + * are required. + * + * @details + * + * Function : rgSCHCmnUlAdapRetxAlloc + * + * Attempts allocation for msg3s for which ADAP retransmissions + * are required. + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUlSf *sf + * @param[in] RgSchUlHqProcCb *proc; + * @param[in] RgSchUlHole *hole; + * @return U8 + **/ +#ifdef ANSI +PRIVATE Bool rgSCHCmnUlAdapRetxAlloc +( +RgSchCellCb *cell, +RgSchUlSf *sf, +RgSchUlHqProcCb *proc, +RgSchUlHole *hole +) +#else +PRIVATE Bool rgSCHCmnUlAdapRetxAlloc(cell, sf, proc, hole) +RgSchCellCb *cell; +RgSchUlSf *sf; +RgSchUlHqProcCb *proc; +RgSchUlHole *hole; +#endif +{ + U8 numSb = proc->reTxAlloc.numSb; + U8 iMcs = proc->reTxAlloc.iMcs; + CmLteTimingInfo frm = cell->crntTime; + RgSchCmnUlCell *cellUl = RG_SCH_CMN_GET_UL_CELL(cell); + RgSchDlSf *dlSf; + RgSchPdcch *pdcch; + RgSchUlAlloc *alloc; + TRC2(rgSCHCmnUlAdapRetxAlloc); + + /* Fetch PDCCH for msg3 */ + /* ccpu00116293 - Correcting relation between UL subframe and DL subframe based on RG_UL_DELTA*/ + /* Introduced timing delta for UL control */ + RGSCH_INCR_SUB_FRAME(frm, TFU_ULCNTRL_DLDELTA); + dlSf = rgSCHUtlSubFrmGet(cell, frm); + pdcch = rgSCHCmnCmnPdcchAlloc(cell, dlSf); + if (pdcch == NULLP) + { + RETVALUE(FALSE); + } + + /* Fetch UL Alloc for msg3 */ + if (numSb <= hole->num) + { + alloc = rgSCHUtlUlAllocGetHole(sf, numSb, hole); + + /* KWork fix */ + if(alloc == NULLP) + { + rgSCHUtlPdcchPut(cell, &dlSf->pdcchInfo, pdcch); + RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId, + "UL Alloc fail for msg3 retx for rnti: %d\n", + proc->reTxAlloc.rnti); + RETVALUE(FALSE); + } + + rgSCHCmnUlAllocFillRbInfo(cell, sf, alloc); + alloc->grnt.iMcs = iMcs; + alloc->grnt.datSz = proc->reTxAlloc.tbSz; +#ifdef RG_5GTF +#else + //RG_SCH_UL_MCS_TO_MODODR(iMcs, alloc->grnt.modOdr); +#endif + /* Fill UL Alloc for msg3 */ + /* RACHO : setting nDmrs to 0 and UlDelaybit to 0*/ + alloc->grnt.nDmrs = 0; + alloc->grnt.hop = 0; + alloc->grnt.delayBit = 0; + alloc->grnt.isRtx = TRUE; + proc->ulSfIdx = cellUl->schdIdx; +#ifdef RG_5GTF + proc->schdTime = cellUl->schdTime; + alloc->grnt.hqProcId = proc->procId; + alloc->grnt.dciFrmt = proc->reTxAlloc.dciFrmt; + alloc->grnt.numLyr = proc->reTxAlloc.numLyr; + alloc->grnt.vrbgStart = proc->reTxAlloc.vrbgStart; + alloc->grnt.numVrbg = proc->reTxAlloc.numVrbg; + alloc->grnt.rbAssign = rgSCHCmnCalcRiv(MAX_5GTF_VRBG, alloc->grnt.vrbgStart, alloc->grnt.numVrbg); + alloc->grnt.modOdr = proc->reTxAlloc.modOdr; + + /* TODO : Hardcoding these as of now */ + alloc->grnt.hop = 0; + alloc->grnt.SCID = 0; + alloc->grnt.xPUSCHRange = MAX_5GTF_XPUSCH_RANGE; + alloc->grnt.PMI = 0; + alloc->grnt.uciOnxPUSCH = 0; +#endif + alloc->rnti = proc->reTxAlloc.rnti; + /* Fix : syed HandIn Ue has forMsg3 and ue Set, but no RaCb */ + alloc->ue = proc->reTxAlloc.ue; + alloc->pdcch = pdcch; + alloc->forMsg3 = proc->reTxAlloc.forMsg3; + alloc->raCb = proc->reTxAlloc.raCb; + alloc->hqProc = proc; + alloc->isAdaptive = TRUE; +#ifdef LTE_L2_MEAS + sf->totPrb += alloc->grnt.numRb; +#endif + /* FIX : syed HandIn Ue has forMsg3 and ue Set, but no RaCb */ + if (alloc->raCb) + { + alloc->raCb->msg3Grnt= alloc->grnt; +#ifndef LTE_TDD + /* To the crntTime, add the time at which UE will + * actually send MSG3 */ + alloc->raCb->msg3AllocTime = cell->crntTime; + RGSCH_INCR_SUB_FRAME(alloc->raCb->msg3AllocTime, RG_SCH_CMN_MIN_RETXMSG3_RECP_INTRVL); +#else + alloc->raCb->msg3AllocTime = cellUl->schdTime; +#endif + rgSCHCmnUlAdapRetx(alloc, proc); + /* Fill PDCCH with alloc info */ + pdcch->rnti = alloc->rnti; + pdcch->dci.dciFormat = TFU_DCI_FORMAT_0; + pdcch->dci.u.format0Info.hoppingEnbld = alloc->grnt.hop; + pdcch->dci.u.format0Info.rbStart = alloc->grnt.rbStart; + pdcch->dci.u.format0Info.numRb = alloc->grnt.numRb; + pdcch->dci.u.format0Info.mcs = alloc->grnt.iMcsCrnt; + pdcch->dci.u.format0Info.ndi = alloc->hqProc->ndi; + pdcch->dci.u.format0Info.nDmrs = alloc->grnt.nDmrs; + pdcch->dci.u.format0Info.tpcCmd = alloc->grnt.tpc; + +#ifdef LTE_TDD +#ifdef TFU_TDD + /* ulIdx setting for cfg 0 shall be appropriately fixed thru ccpu00109015 */ + pdcch->dci.u.format0Info.ulIdx = RG_SCH_ULIDX_MSB; + pdcch->dci.u.format0Info.dai = RG_SCH_MAX_DAI_IDX; +#endif +#endif + pdcch->dciNumOfBits = cell->dciSize.size[TFU_DCI_FORMAT_0]; + } + else + { + RgSchCmnUlUe *ueUl = RG_SCH_CMN_GET_UL_UE(alloc->ue,cell); +#ifdef TFU_UPGRADE + alloc->ue->initNumRbs = (alloc->grnt.numVrbg * MAX_5GTF_VRBG_SIZE); +#endif +#ifdef LTE_L2_MEAS + ue->ul.nPrb = alloc->grnt.numRb; +#endif + ueUl->alloc.alloc = alloc; + /* FIx: Removed the call to rgSCHCmnUlAdapRetx */ + rgSCHCmnUlUeFillAllocInfo(cell, alloc->ue); + /* Setting csireq as false for Adaptive Retx*/ + ueUl->alloc.alloc->pdcch->dci.u.format0Info.cqiReq = RG_SCH_APCQI_NO; + pdcch->dciNumOfBits = alloc->ue->dciSize.cmnSize[TFU_DCI_FORMAT_0]; + } + /* Reset as retransmission is done */ + proc->isRetx = FALSE; + } + else /* Intg fix */ + { + rgSCHUtlPdcchPut(cell, &dlSf->pdcchInfo, pdcch); + RLOG_ARG1(L_DEBUG,DBG_CELLID,cell->cellId, + "Num SB not suffiecient for adap retx for rnti: %d", + proc->reTxAlloc.rnti); + RETVALUE(FALSE); + } + RETVALUE(TRUE); +} + +/* Fix: syed Adaptive Msg3 Retx crash. */ +/** + * @brief Releases all Adaptive Retx HqProcs which failed for + * allocations in this scheduling occassion. + * + * @details + * + * Function : rgSCHCmnUlSfRlsRetxProcs + * + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUlSf *sf + * @return U8 + **/ +#ifdef ANSI +PRIVATE Void rgSCHCmnUlSfRlsRetxProcs +( +RgSchCellCb *cell, +RgSchUlSf *sf +) +#else +PRIVATE Void rgSCHCmnUlSfRlsRetxProcs(cell, sf) +RgSchCellCb *cell; +RgSchUlSf *sf; +#endif +{ + CmLListCp *cp; + CmLList *node; + RgSchUlHqProcCb *proc; + RgSchCmnUlCell *cellUl = RG_SCH_CMN_GET_UL_CELL(cell); + + TRC2(rgSCHCmnUlSfRlsRetxProcs); + + cp = &(cellUl->reTxLst); + node = cp->first; + while (node) + { + proc = (RgSchUlHqProcCb *)node->node; + node = node->next; + /* ccpu00137834 : Deleting reTxLnk from the respective reTxLst */ + cmLListDelFrm(&cellUl->reTxLst, &proc->reTxLnk); + proc->reTxLnk.node = (PTR)NULLP; + } + RETVOID; +} + + +/** + * @brief Attempts allocation for UEs for which retransmissions + * are required. + * + * @details + * + * Function : rgSCHCmnUlSfReTxAllocs + * + * Attempts allocation for UEs for which retransmissions + * are required. + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUlSf *sf + * @return U8 + **/ +#ifdef ANSI +PRIVATE Void rgSCHCmnUlSfReTxAllocs +( +RgSchCellCb *cell, +RgSchUlSf *sf +) +#else +PRIVATE Void rgSCHCmnUlSfReTxAllocs(cell, sf) +RgSchCellCb *cell; +RgSchUlSf *sf; +#endif +{ + CmLListCp *cp; + CmLList *node; + RgSchUlHqProcCb *proc; + RgSchUlHole *hole; + RgSchUeCb *ue; + RgSchCmnCell *schCmnCell = (RgSchCmnCell *)(cell->sc.sch); + RgSchCmnUlCell *cellUl = RG_SCH_CMN_GET_UL_CELL(cell); + TRC2(rgSCHCmnUlSfReTxAllocs); + + cp = &(cellUl->reTxLst); + node = cp->first; + while ((node)) + { + proc = (RgSchUlHqProcCb *)node->node; + ue = proc->reTxAlloc.ue; + node = node->next; + /*ccpu00106104 MOD added check for AckNackRep */ + /*added check for acknack so that adaptive retx considers ue + inactivity due to ack nack repetition*/ + if((ue != NULLP) && + ((ue->measGapCb.isMeasuring == TRUE)|| + (ue->ackNakRepCb.isAckNakRep == TRUE))) + { + continue; + } + /* Fix for ccpu00123917: Check if maximum allocs per UL sf have been exhausted */ + if (((hole = rgSCHUtlUlHoleFirst(sf)) == NULLP) + || (sf->allocDb->count == schCmnCell->ul.maxAllocPerUlSf)) + { + /* No more UL BW then return */ + break; + } + /* perform adaptive retx for UE's */ + if (rgSCHCmnUlAdapRetxAlloc(cell, sf, proc, hole) == FALSE) + { + continue; + } + /* ccpu00137834 : Deleting reTxLnk from the respective reTxLst */ + cmLListDelFrm(&cellUl->reTxLst, &proc->reTxLnk); + /* Fix: syed Adaptive Msg3 Retx crash. */ + proc->reTxLnk.node = (PTR)NULLP; + } + RETVOID; +} + +/** + * @brief Handles RB allocation for downlink. + * + * @details + * + * Function : rgSCHCmnDlRbAlloc + * + * Invoking Module Processing: + * - This function is invoked for DL RB allocation + * + * Processing Steps: + * - If cell is frequency selecive, + * - Call rgSCHDlfsAllocRb(). + * - else, + * - Call rgSCHCmnNonDlfsRbAlloc(). + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchDlRbAllocInfo *allocInfo + * @return Void + **/ + +#ifdef ANSI +PRIVATE Void rgSCHCmnDlRbAlloc +( +RgSchCellCb *cell, +RgSchCmnDlRbAllocInfo *allocInfo +) +#else +PRIVATE Void rgSCHCmnDlRbAlloc(cell, allocInfo) +RgSchCellCb *cell; +RgSchCmnDlRbAllocInfo *allocInfo; +#endif +{ + RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell); + TRC2(rgSCHCmnDlRbAlloc); + + if (cellSch->dl.isDlFreqSel) + { + printf("5GTF_ERROR DLFS SCH Enabled\n"); + cellSch->apisDlfs->rgSCHDlfsAllocRb(cell, allocInfo); + } + else + { + rgSCHCmnNonDlfsRbAlloc(cell, allocInfo); + } + RETVOID; +} + +#ifdef LTEMAC_SPS + +/** + * @brief Determines number of RBGs and RBG subset sizes for the given DL + * bandwidth and rbgSize + * + * @details + * Function : rgSCHCmnDlGetRbgInfo + * + * + * Processing Steps: + * - Fill-up rbgInfo data structure for given DL bandwidth and rbgSize + * + * @param[in] U8 dlTotalBw + * @param[in] U8 dlSubsetBw + * @param[in] U8 maxRaType1SubsetBw + * @param[in] U8 rbgSize + * @param[out] RgSchBwRbgInfo *rbgInfo + * @return Void + **/ +#ifdef ANSI +PUBLIC Void rgSCHCmnDlGetRbgInfo +( +U8 dlTotalBw, +U8 dlSubsetBw, +U8 maxRaType1SubsetBw, +U8 rbgSize, +RgSchBwRbgInfo *rbgInfo +) +#else +PUBLIC Void rgSCHCmnDlGetRbgInfo(dlTotalBw, dlSubsetBw, maxRaType1SubsetBw, + rbgSize, rbgInfo) +U8 dlTotalBw; +U8 dlSubsetBw; +U8 maxRaType1SubsetBw; +U8 rbgSize; +RgSchBwRbgInfo *rbgInfo; +#endif +{ +#ifdef RGSCH_SPS_UNUSED + U8 idx = 0; + U8 lastRbgIdx = ((dlTotalBw + rbgSize - 1)/rbgSize) - 1; + U8 currRbgSize = rbgSize; + U8 subsetSizeIdx = 0; + U8 subsetSize[RG_SCH_NUM_RATYPE1_SUBSETS] = {0}; + U8 lastRbgSize = rbgSize - (dlTotalBw - ((dlTotalBw/rbgSize) * rbgSize)); + U8 numRaType1Rbgs = (maxRaType1SubsetBw + rbgSize - 1)/rbgSize; +#endif + + /* Compute maximum number of SPS RBGs for the cell */ + rbgInfo->numRbgs = ((dlSubsetBw + rbgSize - 1)/rbgSize); + +#ifdef RGSCH_SPS_UNUSED + /* Distribute RBGs across subsets except last RBG */ + for (;idx < numRaType1Rbgs - 1; ++idx) + { + subsetSize[subsetSizeIdx] += currRbgSize; + subsetSizeIdx = (subsetSizeIdx + 1) % rbgSize; + } + + /* Computation for last RBG */ + if (idx == lastRbgIdx) + { + currRbgSize = lastRbgSize; + } + subsetSize[subsetSizeIdx] += currRbgSize; + subsetSizeIdx = (subsetSizeIdx + 1) % rbgSize; +#endif + + /* Update the computed sizes */ +#ifdef RGSCH_SPS_UNUSED + rbgInfo->lastRbgSize = currRbgSize; +#endif + rbgInfo->lastRbgSize = rbgSize - + (dlSubsetBw - ((dlSubsetBw/rbgSize) * rbgSize)); +#ifdef RGSCH_SPS_UNUSED + cmMemcpy((U8 *)rbgInfo->rbgSubsetSize, (U8 *) subsetSize, 4 * sizeof(U8)); +#endif + rbgInfo->numRbs = (rbgInfo->numRbgs * rbgSize > dlTotalBw) ? + dlTotalBw:(rbgInfo->numRbgs * rbgSize); + rbgInfo->rbgSize = rbgSize; +} + +/** + * @brief Handles RB allocation for Resource allocation type 0 + * + * @details + * + * Function : rgSCHCmnDlRaType0Alloc + * + * Invoking Module Processing: + * - This function is invoked for DL RB allocation for resource allocation + * type 0 + * + * Processing Steps: + * - Determine the available positions in the rbgMask. + * - Allocate RBGs in the available positions. + * - Update RA Type 0, RA Type 1 and RA type 2 masks. + * + * @param[in] RgSchDlSfAllocInfo *allocedInfo + * @param[in] U8 rbsReq + * @param[in] RgSchBwRbgInfo *rbgInfo + * @param[out] U8 *numAllocRbs + * @param[out] RgSchDlSfAllocInfo *resAllocInfo + * @param[in] Bool isPartialAlloc + * + * @return Void + **/ + +#ifdef ANSI +PUBLIC U8 rgSCHCmnDlRaType0Alloc +( +RgSchDlSfAllocInfo *allocedInfo, +U8 rbsReq, +RgSchBwRbgInfo *rbgInfo, +U8 *numAllocRbs, +RgSchDlSfAllocInfo *resAllocInfo, +Bool isPartialAlloc +) +#else +PUBLIC U8 rgSCHCmnDlRaType0Alloc(allocedInfo, rbsReq, rbgInfo, + numAllocRbs, resAllocInfo, isPartialAlloc) +RgSchDlSfAllocInfo *allocedInfo; +U8 rbsReq; +RgSchBwRbgInfo *rbgInfo; +U8 *numAllocRbs; +RgSchDlSfAllocInfo *resAllocInfo; +Bool isPartialAlloc; +#endif +{ + /* Note: This function atttempts allocation only full allocation */ + U32 remNumRbs, rbgPosInRbgMask, ueRaType2Mask; + U8 type2MaskIdx, cnt, rbIdx; + U8 maskSize, rbg; + U8 bestNumAvailRbs = 0; + U8 usedRbs = 0; + U8 numAllocRbgs = 0; + U8 rbgSize = rbgInfo->rbgSize; + U32 *rbgMask = &(resAllocInfo->raType0Mask); +#ifdef RGSCH_SPS_UNUSED + U8 rbgSubset; + U32 ueRaType1Mask; + U32 *raType1Mask = resAllocInfo->raType1Mask; + U32 *raType1UsedRbs = resAllocInfo->raType1UsedRbs; +#endif + U32 *raType2Mask = resAllocInfo->raType2Mask; + + U32 allocedMask = allocedInfo->raType0Mask; + + maskSize = rbgInfo->numRbgs; + + *numAllocRbs = 0; + RG_SCH_CMN_DL_COUNT_ONES(allocedMask, maskSize, &usedRbs); + if (maskSize == usedRbs) + { + /* All RBGs are allocated, including the last one */ + remNumRbs = 0; + } + else + { + remNumRbs = (maskSize - usedRbs - 1) * rbgSize; /* vamsee: removed minus 1 */ + + /* If last RBG is available, add last RBG size */ + if (!(allocedMask & (1 << RG_SCH_CMN_DL_GET_POS_FRM_LSB(maskSize - 1)))) + { + remNumRbs += rbgInfo->lastRbgSize; + } + } + + /* If complete allocation is needed, check if total requested RBs are available else + * check the best available RBs */ + if (!isPartialAlloc) + { + if (remNumRbs >= rbsReq) + { + bestNumAvailRbs = rbsReq; + } + } + else + { + bestNumAvailRbs = remNumRbs > rbsReq ? rbsReq : remNumRbs; + } + + /* Allocate for bestNumAvailRbs */ + if (bestNumAvailRbs) + { + for (rbg = 0; rbg < maskSize - 1; ++rbg) + { + rbgPosInRbgMask = 1 << RG_SCH_CMN_DL_GET_POS_FRM_LSB(rbg); + if (!(allocedMask & rbgPosInRbgMask)) + { + /* Update RBG mask */ + *rbgMask |= rbgPosInRbgMask; + + /* Compute RB index of the first RB of the RBG allocated */ + rbIdx = rbg * rbgSize; + + for (cnt = 0; cnt < rbgSize; ++cnt) + { +#ifdef RGSCH_SPS_UNUSED + ueRaType1Mask = rgSCHCmnGetRaType1Mask(rbIdx, rbgSize, &rbgSubset); +#endif + ueRaType2Mask = rgSCHCmnGetRaType2Mask(rbIdx, &type2MaskIdx); +#ifdef RGSCH_SPS_UNUSED + /* Update RBG mask for RA type 1 */ + raType1Mask[rbgSubset] |= ueRaType1Mask; + raType1UsedRbs[rbgSubset]++; +#endif + /* Update RA type 2 mask */ + raType2Mask[type2MaskIdx] |= ueRaType2Mask; + rbIdx++; + } + *numAllocRbs += rbgSize; + remNumRbs -= rbgSize; + ++numAllocRbgs; + if (*numAllocRbs >= bestNumAvailRbs) + { + break; + } + } + } + /* If last RBG available and allocation is not completed, allocate + * last RBG */ + if (*numAllocRbs < bestNumAvailRbs) + { + rbgPosInRbgMask = 1 << RG_SCH_CMN_DL_GET_POS_FRM_LSB(rbg); + *rbgMask |= rbgPosInRbgMask; + *numAllocRbs += rbgInfo->lastRbgSize; + + /* Compute RB index of the first RB of the last RBG */ + rbIdx = ((rbgInfo->numRbgs - 1 ) * rbgSize ); /* removed minus 1 vamsee */ + + for (cnt = 0; cnt < rbgInfo->lastRbgSize; ++cnt) + { +#ifdef RGSCH_SPS_UNUSED + ueRaType1Mask = rgSCHCmnGetRaType1Mask(rbIdx, rbgSize, &rbgSubset); +#endif + ueRaType2Mask = rgSCHCmnGetRaType2Mask(rbIdx, &type2MaskIdx); +#ifdef RGSCH_SPS_UNUSED + /* Update RBG mask for RA type 1 */ + raType1Mask[rbgSubset] |= ueRaType1Mask; + raType1UsedRbs[rbgSubset]++; +#endif + /* Update RA type 2 mask */ + raType2Mask[type2MaskIdx] |= ueRaType2Mask; + rbIdx++; + } + remNumRbs -= rbgInfo->lastRbgSize; + ++numAllocRbgs; + } + /* Note: this should complete allocation, not checking for the + * same */ + } + + RETVALUE(numAllocRbgs); +} + +#ifdef RGSCH_SPS_UNUSED +/** + * @brief Handles RB allocation for Resource allocation type 1 + * + * @details + * + * Function : rgSCHCmnDlRaType1Alloc + * + * Invoking Module Processing: + * - This function is invoked for DL RB allocation for resource allocation + * type 1 + * + * Processing Steps: + * - Determine the available positions in the subsets. + * - Allocate RB in the available subset. + * - Update RA Type1, RA type 0 and RA type 2 masks. + * + * @param[in] RgSchDlSfAllocInfo *allocedInfo + * @param[in] U8 rbsReq + * @param[in] RgSchBwRbgInfo *rbgInfo + * @param[in] U8 startRbgSubset + * @param[in] U8 *allocRbgSubset + * @param[out] rgSchDlSfAllocInfo *resAllocInfo + * @param[in] Bool isPartialAlloc + * + * @return U8 + * Number of allocated RBs + **/ + +#ifdef ANSI +PUBLIC U8 rgSCHCmnDlRaType1Alloc +( +RgSchDlSfAllocInfo *allocedInfo, +U8 rbsReq, +RgSchBwRbgInfo *rbgInfo, +U8 startRbgSubset, +U8 *allocRbgSubset, +RgSchDlSfAllocInfo *resAllocInfo, +Bool isPartialAlloc +) +#else +PUBLIC U8 rgSCHCmnDlRaType1Alloc(allocedInfo, rbsReq,rbgInfo,startRbgSubset, + allocRbgSubset, resAllocInfo, isPartialAlloc) +RgSchDlSfAllocInfo *allocedInfo; +U8 rbsReq; +RgSchBwRbgInfo *rbgInfo; +U8 startRbgSubset; +U8 *allocRbgSubset; +RgSchDlSfAllocInfo *resAllocInfo; +Bool isPartialAlloc; +#endif +{ + /* Note: This function atttempts only full allocation */ + U8 *rbgSubsetSzArr; + U8 type2MaskIdx, subsetIdx, rbIdx, rbInSubset, rbgInSubset; + U8 offset, rbg, maskSize, bestSubsetIdx; + U8 startPos = 0; + U8 bestNumAvailRbs = 0; + U8 numAllocRbs = 0; + U32 ueRaType2Mask, ueRaType0Mask, rbPosInSubset; + U32 remNumRbs, allocedMask; + U8 usedRbs = 0; + U8 rbgSize = rbgInfo->rbgSize; + U8 rbgSubset = startRbgSubset; + U32 *rbgMask = &resAllocInfo->raType0Mask; + U32 *raType1Mask = resAllocInfo->raType1Mask; + U32 *raType2Mask = resAllocInfo->raType2Mask; + U32 *raType1UsedRbs = resAllocInfo->raType1UsedRbs; + U32 *allocMask = allocedInfo->raType1Mask; + + /* Initialize the subset size Array */ + rbgSubsetSzArr = rbgInfo->rbgSubsetSize; + + /* Perform allocation for RA type 1 */ + for (subsetIdx = 0;subsetIdx < rbgSize; ++subsetIdx) + { + allocedMask = allocMask[rbgSubset]; + maskSize = rbgSubsetSzArr[rbgSubset]; + + /* Determine number of available RBs in the subset */ + usedRbs = allocedInfo->raType1UsedRbs[subsetIdx]; + remNumRbs = maskSize - usedRbs; + + if (remNumRbs >= rbsReq) + { + bestNumAvailRbs = rbsReq; + bestSubsetIdx = rbgSubset; + break; + } + else if (isPartialAlloc && (remNumRbs > bestNumAvailRbs)) + { + bestNumAvailRbs = remNumRbs; + bestSubsetIdx = rbgSubset; + } + + rbgSubset = (rbgSubset + 1) % rbgSize; + } /* End of for (each rbgsubset) */ + + if (bestNumAvailRbs) + { + /* Initialize alloced mask and subsetSize depending on the RBG + * subset of allocation */ + U8 startIdx = 0; + maskSize = rbgSubsetSzArr[bestSubsetIdx]; + allocedMask = allocMask[bestSubsetIdx]; + RG_SCH_CMN_DL_GET_START_POS(allocedMask, maskSize, + &startPos); + for (; startIdx < rbgSize; ++startIdx, ++startPos) + { + for (rbInSubset = startPos; rbInSubset < maskSize; + rbInSubset = rbInSubset + rbgSize) + { + rbPosInSubset = 1 << RG_SCH_CMN_DL_GET_POS_FRM_LSB(rbInSubset); + if (!(allocedMask & rbPosInSubset)) + { + raType1Mask[bestSubsetIdx] |= rbPosInSubset; + raType1UsedRbs[bestSubsetIdx]++; + + /* Compute RB index value for the RB being allocated */ + rbgInSubset = rbInSubset /rbgSize; + offset = rbInSubset % rbgSize; + rbg = (rbgInSubset * rbgSize) + bestSubsetIdx; + rbIdx = (rbg * rbgSize) + offset; + + /* Update RBG mask for RA type 0 allocation */ + ueRaType0Mask = rgSCHCmnGetRaType0Mask(rbIdx, rbgSize); + *rbgMask |= ueRaType0Mask; + + /* Update RA type 2 mask */ + ueRaType2Mask = rgSCHCmnGetRaType2Mask(rbIdx, &type2MaskIdx); + raType2Mask[type2MaskIdx] |= ueRaType2Mask; + + /* Update the counters */ + numAllocRbs++; + remNumRbs--; + if (numAllocRbs == bestNumAvailRbs) + { + break; + } + } + } /* End of for (each position in the subset mask) */ + if (numAllocRbs == bestNumAvailRbs) + { + break; + } + } /* End of for startIdx = 0 to rbgSize */ + + *allocRbgSubset = bestSubsetIdx; + } /* End of if (bestNumAvailRbs) */ + + RETVALUE(numAllocRbs); +} +#endif +/** + * @brief Handles RB allocation for Resource allocation type 2 + * + * @details + * + * Function : rgSCHCmnDlRaType2Alloc + * + * Invoking Module Processing: + * - This function is invoked for DL RB allocation for resource allocation + * type 2 + * + * Processing Steps: + * - Determine the available positions in the mask + * - Allocate best fit cosecutive RBs. + * - Update RA Type2, RA type 1 and RA type 0 masks. + * + * @param[in] RgSchDlSfAllocInfo *allocedInfo + * @param[in] U8 rbsReq + * @param[in] RgSchBwRbgInfo *rbgInfo + * @param[out] U8 *rbStart + * @param[out] rgSchDlSfAllocInfo *resAllocInfo + * @param[in] Bool isPartialAlloc + * + * @return U8 + * Number of allocated RBs + **/ + +#ifdef ANSI +PUBLIC U8 rgSCHCmnDlRaType2Alloc +( +RgSchDlSfAllocInfo *allocedInfo, +U8 rbsReq, +RgSchBwRbgInfo *rbgInfo, +U8 *rbStart, +RgSchDlSfAllocInfo *resAllocInfo, +Bool isPartialAlloc +) +#else +PUBLIC U8 rgSCHCmnDlRaType2Alloc(allocedInfo, rbsReq, rbgInfo, rbStart, + resAllocInfo, isPartialAlloc) +RgSchDlSfAllocInfo *allocedInfo; +U8 rbsReq; +RgSchBwRbgInfo *rbgInfo; +U8 *rbStart; +RgSchDlSfAllocInfo *resAllocInfo; +Bool isPartialAlloc; +#endif +{ + U8 numAllocRbs = 0; + U8 rbIdx; + U8 rbgSize = rbgInfo->rbgSize; + U32 *rbgMask = &resAllocInfo->raType0Mask; +#ifdef RGSCH_SPS_UNUSED + U32 *raType1Mask = resAllocInfo->raType1Mask; +#endif + U32 *raType2Mask = resAllocInfo->raType2Mask; +#ifdef RGSCH_SPS_UNUSED + U32 *raType1UsedRbs = resAllocInfo->raType1UsedRbs; +#endif + U32 *allocedMask = allocedInfo->raType2Mask; + + /* Note: This function atttempts only full allocation */ + rgSCHCmnDlGetBestFitHole(allocedMask, rbgInfo->numRbs, + raType2Mask, rbsReq, rbStart, &numAllocRbs, isPartialAlloc); + if (numAllocRbs) + { + /* Update the allocation in RA type 0 and RA type 1 masks */ + U8 rbCnt = numAllocRbs; +#ifdef RGSCH_SPS_UNUSED + U8 rbgSubset; + U32 ueRaType1Mask; +#endif + U32 ueRaType0Mask; + rbIdx = *rbStart; + + while(rbCnt) + { + /* Update RBG mask for RA type 0 allocation */ + ueRaType0Mask = rgSCHCmnGetRaType0Mask(rbIdx, rbgSize); + *rbgMask |= ueRaType0Mask; + +#ifdef RGSCH_SPS_UNUSED + /* Update RBG mask for RA type 1 */ + ueRaType1Mask = rgSCHCmnGetRaType1Mask(rbIdx, rbgSize, &rbgSubset); + raType1Mask[rbgSubset] |= ueRaType1Mask; + raType1UsedRbs[rbgSubset]++; +#endif + /* Update the counters */ + --rbCnt; + rbIdx++; + } + } + + RETVALUE(numAllocRbs); +} + +/** + * @brief Determines RA type 0 mask from given RB index. + * + * @details + * + * Function : rgSCHCmnGetRaType0Mask + * + * + * Processing Steps: + * - Determine RA Type 0 mask for given rbIdex and rbg size. + * + * @param[in] U8 rbIdx + * @param[in] U8 rbgSize + * @return U32 RA type 0 mask + **/ +#ifdef ANSI +PRIVATE U32 rgSCHCmnGetRaType0Mask +( +U8 rbIdx, +U8 rbgSize +) +#else +PRIVATE U32 rgSCHCmnGetRaType0Mask(rbIdx, rbgSize) +U8 rbIdx; +U8 rbgSize; +#endif +{ + U8 rbg; + U32 rbgPosInRbgMask = 0; + + rbg = rbIdx/rbgSize; + rbgPosInRbgMask = 1 << RG_SCH_CMN_DL_GET_POS_FRM_LSB(rbg); + + RETVALUE(rbgPosInRbgMask); +} + +#ifdef RGSCH_SPS_UNUSED +/** + * @brief Determines RA type 1 mask from given RB index. + * + * @details + * + * Function : rgSCHCmnGetRaType1Mask + * + * + * Processing Steps: + * - Determine RA Type 1 mask for given rbIdex and rbg size. + * + * @param[in] U8 rbIdx + * @param[in] U8 rbgSize + * @param[out] U8 *type1Subset + * @return U32 RA type 1 mask + **/ +#ifdef ANSI +PRIVATE U32 rgSCHCmnGetRaType1Mask +( +U8 rbIdx, +U8 rbgSize, +U8 *type1Subset +) +#else +PRIVATE U32 rgSCHCmnGetRaType1Mask(rbIdx, rbgSize, type1Subset) +U8 rbIdx; +U8 rbgSize; +U8 *type1Subset; +#endif +{ + U8 rbg, rbgSubset, rbgInSubset, offset, rbInSubset; + U32 rbPosInSubset; + + rbg = rbIdx/rbgSize; + rbgSubset = rbg % rbgSize; + rbgInSubset = rbg/rbgSize; + offset = rbIdx % rbgSize; + rbInSubset = rbgInSubset * rbgSize + offset; + rbPosInSubset = 1 << RG_SCH_CMN_DL_GET_POS_FRM_LSB(rbInSubset); + + *type1Subset = rbgSubset; + RETVALUE(rbPosInSubset); +} +#endif /* RGSCH_SPS_UNUSED */ +/** + * @brief Determines RA type 2 mask from given RB index. + * + * @details + * + * Function : rgSCHCmnGetRaType2Mask + * + * + * Processing Steps: + * - Determine RA Type 2 mask for given rbIdx and rbg size. + * + * @param[in] U8 rbIdx + * @param[out] U8 *maskIdx + * @return U32 RA type 2 mask + **/ +#ifdef ANSI +PRIVATE U32 rgSCHCmnGetRaType2Mask +( +U8 rbIdx, +U8 *maskIdx +) +#else +PRIVATE U32 rgSCHCmnGetRaType2Mask(rbIdx, maskIdx) +U8 rbIdx; +U8 *maskIdx; +#endif +{ + U32 rbPosInType2; + + *maskIdx = rbIdx / 32; + rbPosInType2 = 1 << RG_SCH_CMN_DL_GET_POS_FRM_LSB(rbIdx % 32); + + RETVALUE(rbPosInType2); +} + +/** + * @brief Performs resource allocation for a non-SPS UE in SPS bandwidth + * + * @details + * + * Function : rgSCHCmnAllocUeInSpsBw + * + * + * Processing Steps: + * - Determine allocation for the UE. + * - Use resource allocation type 0, 1 and 2 for allocation + * within maximum SPS bandwidth. + * + * @param[in] RgSchDlSf *dlSf + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ue + * @param[in] RgSchDlRbAlloc *rbAllocInfo + * @param[in] Bool isPartialAlloc + * @return Bool + * ROK success + * RFAILED failed + **/ +#ifdef ANSI +PUBLIC Bool rgSCHCmnAllocUeInSpsBw +( +RgSchDlSf *dlSf, +RgSchCellCb *cell, +RgSchUeCb *ue, +RgSchDlRbAlloc *rbAllocInfo, +Bool isPartialAlloc +) +#else +PUBLIC Bool rgSCHCmnAllocUeInSpsBw(dlSf, cell, ue, rbAllocInfo, isPartialAlloc) +RgSchDlSf *dlSf; +RgSchCellCb *cell; +RgSchUeCb *ue; +RgSchDlRbAlloc *rbAllocInfo; +Bool isPartialAlloc; +#endif +{ + U8 rbgSize = cell->rbgSize; + U8 numAllocRbs = 0; + U8 numAllocRbgs = 0; + U8 rbStart = 0; + U8 idx, noLyr, iTbs; + RgSchCmnDlUe *dlUe = RG_SCH_CMN_GET_DL_UE(ue,cell); + RgSchDlSfAllocInfo *dlSfAlloc = &rbAllocInfo->dlSf->dlSfAllocInfo; + RgSchBwRbgInfo *spsRbgInfo = &cell->spsBwRbgInfo; + + /* SPS_FIX : Check if this Hq proc is scheduled */ + if ((0 == rbAllocInfo->tbInfo[0].schdlngForTb) && + (0 == rbAllocInfo->tbInfo[1].schdlngForTb)) + { + RETVALUE(TRUE); + } + + /* Check if the requirement can be accomodated in SPS BW */ + if (dlSf->spsAllocdBw == spsRbgInfo->numRbs) + { + /* SPS Bandwidth has been exhausted: no further allocations possible */ + RETVALUE(FALSE); + } + if (!isPartialAlloc) + { + if((dlSf->spsAllocdBw + rbAllocInfo->rbsReq) > spsRbgInfo->numRbs) + { + RETVALUE(TRUE); + } + } + + /* Perform allocation for RA type 0 if rbsReq is multiple of RBG size (also + * if RBG size = 1) */ + if (rbAllocInfo->raType == RG_SCH_CMN_RA_TYPE0) + { + rbAllocInfo->rbsReq += (rbgSize - rbAllocInfo->rbsReq % rbgSize); + numAllocRbgs = rgSCHCmnDlRaType0Alloc(dlSfAlloc, + rbAllocInfo->rbsReq, spsRbgInfo, &numAllocRbs, + &rbAllocInfo->resAllocInfo, isPartialAlloc); + } +#ifdef RGSCH_SPS_UNUSED + else if (rbAllocInfo->raType == RG_SCH_CMN_RA_TYPE1) + { + /* If no RBS could be allocated, attempt RA TYPE 1 */ + + numAllocRbs = rgSCHCmnDlRaType1Alloc(dlSfAlloc, + rbAllocInfo->rbsReq, spsRbgInfo, (U8)dlSfAlloc->nxtRbgSubset, + &rbAllocInfo->allocInfo.raType1.rbgSubset, + &rbAllocInfo->resAllocInfo, isPartialAlloc); + + if(numAllocRbs) + { + dlSfAlloc->nxtRbgSubset = + (rbAllocInfo->allocInfo.raType1.rbgSubset + 1 ) % rbgSize; + } + } +#endif + else if (rbAllocInfo->raType == RG_SCH_CMN_RA_TYPE2) + { + numAllocRbs = rgSCHCmnDlRaType2Alloc(dlSfAlloc, + rbAllocInfo->rbsReq, spsRbgInfo, + &rbStart, &rbAllocInfo->resAllocInfo, isPartialAlloc); + } + if (!numAllocRbs) + { + RETVALUE(TRUE); + } + + if (!(rbAllocInfo->pdcch = + rgSCHCmnPdcchAlloc(cell, ue, dlSf, dlUe->mimoInfo.cwInfo[0].cqi,\ + rbAllocInfo->dciFormat, FALSE))) + { + /* Note: Returning TRUE since PDCCH might be available for another UE */ + RETVALUE(TRUE); + } + + /* Update Tb info for each scheduled TB */ + iTbs = rbAllocInfo->tbInfo[0].iTbs; + noLyr = rbAllocInfo->tbInfo[0].noLyr; + rbAllocInfo->tbInfo[0].bytesAlloc = + rgTbSzTbl[noLyr - 1][iTbs][numAllocRbs - 1]/8; + + if (rbAllocInfo->tbInfo[1].schdlngForTb) + { + iTbs = rbAllocInfo->tbInfo[1].iTbs; + noLyr = rbAllocInfo->tbInfo[1].noLyr; + rbAllocInfo->tbInfo[1].bytesAlloc = + rgTbSzTbl[noLyr - 1][iTbs][numAllocRbs - 1]/8;; + } + + /* Update rbAllocInfo with the allocation information */ + if (rbAllocInfo->raType == RG_SCH_CMN_RA_TYPE0) + { + rbAllocInfo->allocInfo.raType0.dlAllocBitMask = + rbAllocInfo->resAllocInfo.raType0Mask; + rbAllocInfo->allocInfo.raType0.numDlAlloc = numAllocRbgs; + } +#ifdef RGSCH_SPS_UNUSED + else if (rbAllocInfo->raType == RG_SCH_CMN_RA_TYPE1) + { + rbAllocInfo->allocInfo.raType1.dlAllocBitMask = + rbAllocInfo->resAllocInfo.raType1Mask[rbAllocInfo->allocInfo.raType1.rbgSubset]; + rbAllocInfo->allocInfo.raType1.numDlAlloc = numAllocRbs; + rbAllocInfo->allocInfo.raType1.shift = 0; + } +#endif + else if (rbAllocInfo->raType == RG_SCH_CMN_RA_TYPE2) + { + rbAllocInfo->allocInfo.raType2.isLocal = TRUE; + rbAllocInfo->allocInfo.raType2.rbStart = rbStart; + rbAllocInfo->allocInfo.raType2.numRb = numAllocRbs; + } + + rbAllocInfo->rbsAlloc = numAllocRbs; + rbAllocInfo->tbInfo[0].schdlngForTb = TRUE; + + /* Update allocation masks for RA types 0, 1 and 2 in DL SF */ + + /* Update type 0 allocation mask */ + dlSfAlloc->raType0Mask |= rbAllocInfo->resAllocInfo.raType0Mask; +#ifdef RGSCH_SPS_UNUSED + /* Update type 1 allocation masks */ + for (idx = 0; idx < RG_SCH_NUM_RATYPE1_32BIT_MASK; ++idx) + { + dlSfAlloc->raType1Mask[idx] |= rbAllocInfo->resAllocInfo.raType1Mask[idx]; + dlSfAlloc->raType1UsedRbs[idx] += + rbAllocInfo->resAllocInfo.raType1UsedRbs[idx]; + } +#endif + /* Update type 2 allocation masks */ + for (idx = 0; idx < RG_SCH_NUM_RATYPE2_32BIT_MASK; ++idx) + { + dlSfAlloc->raType2Mask[idx] |= rbAllocInfo->resAllocInfo.raType2Mask[idx]; + } + + dlSf->spsAllocdBw += numAllocRbs; + RETVALUE(TRUE); +} + +/*********************************************************** + * + * Func : rgSCHCmnDlGetBestFitHole + * + * + * Desc : Converts the best fit hole into allocation and returns the + * allocation information. + * + * + * Ret : Void + * + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PRIVATE Void rgSCHCmnDlGetBestFitHole +( +U32 *allocMask, +U8 numMaskRbs, +U32 *crntAllocMask, +U8 rbsReq, +U8 *allocStart, +U8 *allocNumRbs, +Bool isPartialAlloc +) +#else +PRIVATE Void rgSCHCmnDlGetBestFitHole (allocMask, numMaskRbs, + crntAllocMask, rbsReq, allocStart, allocNumRbs, isPartialAlloc) +U32 *allocMask; +U8 numMaskRbs; +U32 *crntAllocMask; +U8 rbsReq; +U8 *allocStart; +U8 *allocNumRbs; +Bool isPartialAlloc; +#endif +{ + U8 maskSz = (numMaskRbs + 31)/32; + U8 maxMaskPos = (numMaskRbs % 32); + U8 maskIdx, maskPos; + U8 numAvailRbs = 0; + U8 bestAvailNumRbs = 0; + S8 bestStartPos = -1; + S8 startPos = -1; + U32 tmpMask[RG_SCH_NUM_RATYPE2_32BIT_MASK] = {0}; + U32 bestMask[RG_SCH_NUM_RATYPE2_32BIT_MASK] = {0}; + + *allocNumRbs = numAvailRbs; + *allocStart = 0; + + for (maskIdx = 0; maskIdx < maskSz; ++maskIdx) + { + maxMaskPos = 31; + if (maskIdx == (maskSz - 1)) + { + if (numMaskRbs % 32) + { + maxMaskPos = numMaskRbs % 32; + } + } + for (maskPos = 0; maskPos < maxMaskPos; ++maskPos) + { + if (!(allocMask[maskIdx] & (1 << (31 - maskPos)))) + { + tmpMask[maskIdx] |= (1 << (31 - maskPos)); + if (startPos == -1) + { + startPos = maskIdx * 32 + maskPos; + } + ++numAvailRbs; + if (numAvailRbs == rbsReq) + { + *allocStart = (U8)startPos; + *allocNumRbs = rbsReq; + break; + } + } + else + { + if (numAvailRbs > bestAvailNumRbs) + { + bestAvailNumRbs = numAvailRbs; + bestStartPos = startPos; + cmMemcpy((U8 *)bestMask, (U8 *) tmpMask, 4 * sizeof(U32)); + } + numAvailRbs = 0; + startPos = -1; + cmMemset((U8 *)tmpMask, 0, 4 * sizeof(U32)); + } + } + if (*allocNumRbs == rbsReq) + { + break; + } + } + + if (*allocNumRbs == rbsReq) + { + /* Convert the hole into allocation */ + cmMemcpy((U8 *)crntAllocMask, (U8 *) tmpMask, 4 * sizeof(U32)); + RETVOID; + } + else + { + if (bestAvailNumRbs && isPartialAlloc) + { + /* Partial allocation could have been done */ + *allocStart = (U8)bestStartPos; + *allocNumRbs = bestAvailNumRbs; + /* Convert the hole into allocation */ + cmMemcpy((U8 *)crntAllocMask, (U8 *) bestMask, 4 * sizeof(U32)); + } + } + + RETVOID; +} +#endif /* LTEMAC_SPS */ + +/*************************************************************************** + * + * NON-DLFS Allocation functions + * + * *************************************************************************/ +#ifndef LTE_TDD +#ifdef DEBUGP +/** + * @brief Function to find out code rate + * + * @details + * + * Function : rgSCHCmnFindCodeRate + * + * Processing Steps: + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchDlSf *dlSf + * @param[in,out] RgSchDlRbAlloc *allocInfo + * @return void + **/ +#ifdef ANSI +PRIVATE Void rgSCHCmnFindCodeRate +( +RgSchCellCb *cell, +RgSchDlSf *dlSf, +RgSchDlRbAlloc *allocInfo, +U8 idx +) +#else +PRIVATE Void rgSCHCmnFindCodeRate(cell,dlSf,allocInfo,idx) +RgSchCellCb *cell; +RgSchDlSf *dlSf; +RgSchDlRbAlloc *allocInfo; +U8 idx; +#endif +{ + RETVOID; + +} +#endif + +/* Adjust the Imcs and bytes allocated also with respect to the adjusted + RBs - Here we will find out the Imcs by identifying first Highest + number of bits compared to the original bytes allocated. */ +/** + * @brief Adjust IMCS according to tbSize and ITBS + * + * @details + * + * Function : rgSCHCmnNonDlfsPbchTbImcsAdj + * + * Processing Steps: + * - Adjust Imcs according to tbSize and ITBS. + * + * @param[in,out] RgSchDlRbAlloc *allocInfo + * @param[in] U8 *idx + * @return void + **/ +#ifdef ANSI +PRIVATE Void rgSCHCmnNonDlfsPbchTbImcsAdj +( +RgSchCellCb *cell, +RgSchDlRbAlloc *allocInfo, +U8 idx, +U8 rbsReq +) +#else +PRIVATE Void rgSCHCmnNonDlfsPbchTbImcsAdj(cell,allocInfo, idx, rbsReq) +RgSchCellCb *cell; +RgSchDlRbAlloc *allocInfo; +U8 idx; +U8 rbsReq; +#endif +{ + U8 noLyrs = 0; + U8 tbs = 0; + U32 origBytesReq; + U8 noRbgs = 0; + U8 noRbs = 0; + RgSchDlSf *dlSf = allocInfo->dlSf; + + RG_SCH_CMN_DL_MCS_TO_TBS(allocInfo->tbInfo[idx].imcs, tbs); + noLyrs = allocInfo->tbInfo[idx].noLyr; + + if((allocInfo->raType == RG_SCH_CMN_RA_TYPE0)) + { + noRbgs = RGSCH_CEIL((allocInfo->rbsReq + dlSf->lstRbgDfct), cell->rbgSize); + noRbs = (noRbgs * cell->rbgSize) - dlSf->lstRbgDfct; + } + else + { + noRbs = allocInfo->rbsReq; + } + + /* This line will help in case if tbs is zero and reduction in MCS is not possible */ + if (allocInfo->rbsReq == 0 ) + { + RETVOID; + } + origBytesReq = rgTbSzTbl[noLyrs - 1][tbs][rbsReq - 1]/8; + + /* Find out the ITbs & Imcs by identifying first Highest + number of bits compared to the original bytes allocated.*/ + if(tbs > 0) + { + if(((rgTbSzTbl[noLyrs - 1][0][noRbs - 1])/8) < origBytesReq) + { + RGSCH_ARRAY_BOUND_CHECK(cell->instIdx, rgTbSzTbl[noLyrs - 1], tbs); + while(((rgTbSzTbl[noLyrs - 1][tbs][noRbs - 1])/8) > origBytesReq) + { + tbs--; + } + } + else + { + tbs = 0; + } + allocInfo->tbInfo[idx].bytesReq = rgTbSzTbl[noLyrs - 1][tbs][noRbs - 1]/8; + allocInfo->tbInfo[idx].iTbs = tbs; + RG_SCH_CMN_DL_TBS_TO_MCS(tbs,allocInfo->tbInfo[idx].imcs); + } + + RETVOID; +} +/* Added funcion to adjust TBSize*/ +/** + * @brief Function to adjust the tbsize in case of subframe 0 & 5 when + * we were not able to do RB alloc adjustment by adding extra required Rbs + * + * @details + * + * Function : rgSCHCmnNonDlfsPbchTbSizeAdj + * + * Processing Steps: + * + * @param[in,out] RgSchDlRbAlloc *allocInfo + * @param[in] U8 numOvrlapgPbchRb + * @param[in] U8 idx + * @param[in] U8 pbchSsRsSym + * @return void + **/ +#ifdef ANSI +PRIVATE Void rgSCHCmnNonDlfsPbchTbSizeAdj +( +RgSchDlRbAlloc *allocInfo, +U8 numOvrlapgPbchRb, +U8 pbchSsRsSym, +U8 idx, +U32 bytesReq +) +#else +PRIVATE Void rgSCHCmnNonDlfsPbchTbSizeAdj(allocInfo,numOvrlapgPbchRb,pbchSsRsSym,idx,bytesReq) +RgSchDlRbAlloc *allocInfo; +U8 numOvrlapgPbchRb; +U8 pbchSsRsSym; +U8 idx; +U32 bytesReq; +#endif +{ + U32 reducedTbs = 0; + U8 noLyrs = 0; + U8 tbs = 0; + + noLyrs = allocInfo->tbInfo[idx].noLyr; + + RG_SCH_CMN_DL_MCS_TO_TBS(allocInfo->tbInfo[idx].imcs, tbs); + + reducedTbs = bytesReq - (((U32)numOvrlapgPbchRb * (U32)pbchSsRsSym * 6)/8); + + /* find out the ITbs & Imcs by identifying first Highest + number of bits compared with reduced bits considering the bits that are + reserved for PBCH/PSS/SSS */ + if(((rgTbSzTbl[noLyrs - 1][0][allocInfo->rbsReq - 1])/8) < reducedTbs) + { + while(((rgTbSzTbl[noLyrs - 1][tbs][allocInfo->rbsReq - 1])/8) > reducedTbs) + { + tbs--; + } + } + else + { + tbs = 0; + } + allocInfo->tbInfo[idx].bytesReq = rgTbSzTbl[noLyrs - 1][tbs][allocInfo->rbsReq - 1]/8; + allocInfo->tbInfo[idx].iTbs = tbs; + RG_SCH_CMN_DL_TBS_TO_MCS(tbs,allocInfo->tbInfo[idx].imcs); + + RETVOID; +} + +/* Added this function to find num of ovrlapping PBCH rb*/ +/** + * @brief Function to find out how many additional rbs are available + * in the entire bw which can be allocated to a UE + * @details + * + * Function : rgSCHCmnFindNumAddtlRbsAvl + * + * Processing Steps: + * - Calculates number of additinal rbs available + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchDlSf *dlSf + * @param[in,out] RgSchDlRbAlloc *allocInfo + * @param[out] U8 addtlRbsAvl + * @return void + **/ +#ifdef ANSI +PRIVATE U8 rgSCHCmnFindNumAddtlRbsAvl +( +RgSchCellCb *cell, +RgSchDlSf *dlSf, +RgSchDlRbAlloc *allocInfo +) +#else +PRIVATE U8 rgSCHCmnFindNumAddtlRbsAvl(cell,dlSf,allocInfo) +RgSchCellCb *cell; +RgSchDlSf *dlSf; +RgSchDlRbAlloc *allocInfo; +#endif +{ + U8 addtlRbsAvl = 0; + + TRC2(rgSCHCmnFindNumAddtlRbsAvl) + + if (allocInfo->raType == RG_SCH_CMN_RA_TYPE0) + { + addtlRbsAvl = (((dlSf->type0End - dlSf->type2End + 1)*\ + cell->rbgSize) - dlSf->lstRbgDfct) - allocInfo->rbsReq; + } + else if (allocInfo->raType == RG_SCH_CMN_RA_TYPE2) + { + addtlRbsAvl = (dlSf->bw - dlSf->bwAlloced) - allocInfo->rbsReq; + } + + RETVALUE(addtlRbsAvl); + +} +/* Added this function to find num of ovrlapping PBCH rb*/ +/** + * @brief Function to find out how many of the requested RBs are + * falling in the center 6 RBs of the downlink bandwidth. + * @details + * + * Function : rgSCHCmnFindNumPbchOvrlapRbs + * + * Processing Steps: + * - Calculates number of overlapping rbs + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchDlSf *dlSf + * @param[in,out] RgSchDlRbAlloc *allocInfo + * @param[out] U8* numOvrlapgPbchRb + * @return void + **/ +#ifdef ANSI +PRIVATE Void rgSCHCmnFindNumPbchOvrlapRbs +( +RgSchCellCb *cell, +RgSchDlSf *dlSf, +RgSchDlRbAlloc *allocInfo, +U8 *numOvrlapgPbchRb +) +#else +PRIVATE Void rgSCHCmnFindNumPbchOvrlapRbs(cell,dlSf,allocInfo,numOvrlapgPbchRb) +RgSchCellCb *cell; +RgSchDlSf *dlSf; +RgSchDlRbAlloc *allocInfo; +U8 *numOvrlapgPbchRb; +#endif +{ + *numOvrlapgPbchRb = 0; + TRC2(rgSCHCmnFindNumPbchOvrlapRbs) + /*Find if we have already crossed the start boundary for PBCH 6 RBs, + * if yes then lets find the number of RBs which are getting overlapped + * with this allocation.*/ + if(dlSf->bwAlloced <= (cell->pbchRbStart)) + { + /*We have not crossed the start boundary of PBCH RBs. Now we need + * to know that if take this allocation then how much PBCH RBs + * are overlapping with this allocation.*/ + /* Find out the overlapping RBs in the centre 6 RBs */ + if((dlSf->bwAlloced + allocInfo->rbsReq) > cell->pbchRbStart) + { + *numOvrlapgPbchRb = (dlSf->bwAlloced + allocInfo->rbsReq) - (cell->pbchRbStart); + if(*numOvrlapgPbchRb > 6) + *numOvrlapgPbchRb = 6; + } + } + else if ((dlSf->bwAlloced > (cell->pbchRbStart)) && + (dlSf->bwAlloced < (cell->pbchRbEnd))) + { + /*We have already crossed the start boundary of PBCH RBs.We need to + * find that if we take this allocation then how much of the RBs for + * this allocation will overlap with PBCH RBs.*/ + /* Find out the overlapping RBs in the centre 6 RBs */ + if(dlSf->bwAlloced + allocInfo->rbsReq < (cell->pbchRbEnd)) + { + /*If we take this allocation then also we are not crossing the + * end boundary of PBCH 6 RBs.*/ + *numOvrlapgPbchRb = allocInfo->rbsReq; + } + else + { + /*If we take this allocation then we are crossing the + * end boundary of PBCH 6 RBs.*/ + *numOvrlapgPbchRb = (cell->pbchRbEnd) - dlSf->bwAlloced; + } + } + RETVOID; + +} +/** + * @brief Performs RB allocation adjustment if the requested RBs are + * falling in the center 6 RBs of the downlink bandwidth. + * @details + * + * Function : rgSCHCmnNonDlfsPbchRbAllocAdj + * + * Processing Steps: + * - Allocate consecutively available RBs. + * + * @param[in] RgSchCellCb *cell + * @param[in,out] RgSchDlRbAlloc *allocInfo + * @param[in] U8 pbchSsRsSym + * @return void + **/ +#ifdef ANSI +PRIVATE Void rgSCHCmnNonDlfsPbchRbAllocAdj +( +RgSchCellCb *cell, +RgSchDlRbAlloc *allocInfo, +U8 pbchSsRsSym, +Bool isBcchPcch +) +#else +PRIVATE Void rgSCHCmnNonDlfsPbchRbAllocAdj(cell, allocInfo,pbchSsRsSym) +RgSchCellCb *cell; +RgSchDlRbAlloc *allocInfo; +U8 pbchSsRsSym; +Bool isBcchPcch; +#endif +{ + RgSchDlSf *dlSf = allocInfo->dlSf; + U8 numOvrlapgPbchRb = 0; + U8 numOvrlapgAdtlPbchRb = 0; + U8 totSym; + U8 addtlRbsReq = 0; + U8 moreAddtlRbsReq = 0; + U8 addtlRbsAdd = 0; + U8 moreAddtlRbsAdd = 0; + U8 tbs; + U8 origRbsReq = 0; + U32 bytesReq; + U8 noLyr; + U8 divResult; + + + TRC2(rgSCHCmnNonDlfsPbchRbAllocAdj); + + + origRbsReq = allocInfo->rbsReq; + rgSCHCmnFindNumPbchOvrlapRbs(cell,dlSf,allocInfo,&numOvrlapgPbchRb); + + totSym = (cell->isCpDlExtend) ? RGSCH_TOT_NUM_SYM_EXTCP : RGSCH_TOT_NUM_SYM_NORCP; + + /* Additional RBs are allocated by considering the loss due to + the reserved symbols for CFICH, PBCH, PSS, SSS and cell specific RS */ + + divResult = (numOvrlapgPbchRb * pbchSsRsSym)/totSym; + if((numOvrlapgPbchRb * pbchSsRsSym) % totSym) + { + divResult++; + } + addtlRbsReq = divResult; + + RG_SCH_CMN_UPD_RBS_TO_ADD(cell, dlSf, allocInfo, addtlRbsReq, addtlRbsAdd) + + /*Now RBs requires is original requested RBs + these additional RBs to make + * up for PSS/SSS/BCCH.*/ + allocInfo->rbsReq = allocInfo->rbsReq + addtlRbsAdd; + + /*Check if with these additional RBs we have taken up, these are also falling + * under PBCH RBs range, if yes then we would need to account for + * PSS/BSS/BCCH for these additional RBs too.*/ + if(addtlRbsAdd && ((dlSf->bwAlloced + allocInfo->rbsReq - addtlRbsAdd) < (cell->pbchRbEnd))) + { + if((dlSf->bwAlloced + allocInfo->rbsReq) <= (cell->pbchRbEnd)) + { + /*With additional RBs taken into account, we are not crossing the + * PBCH RB end boundary.Thus here we need to account just for + * overlapping PBCH RBs for these additonal RBs.*/ + divResult = (addtlRbsAdd * pbchSsRsSym)/totSym; + if((addtlRbsAdd * pbchSsRsSym) % totSym) + { + divResult++; + } + + moreAddtlRbsReq = divResult; + + RG_SCH_CMN_UPD_RBS_TO_ADD(cell, dlSf, allocInfo, moreAddtlRbsReq, moreAddtlRbsAdd) + + allocInfo->rbsReq = allocInfo->rbsReq + moreAddtlRbsAdd; + } + else + { + + /*Here we have crossed the PBCH RB end boundary, thus we need to take + * into account the overlapping RBs for additional RBs which will be + * subset of addtlRbs.*/ + numOvrlapgAdtlPbchRb = (cell->pbchRbEnd) - ((dlSf->bwAlloced + allocInfo->rbsReq) - addtlRbsAdd); + + divResult = (numOvrlapgAdtlPbchRb * pbchSsRsSym)/totSym; + if((numOvrlapgAdtlPbchRb * pbchSsRsSym) % totSym) + { + divResult++; + } + + moreAddtlRbsReq = divResult; + + RG_SCH_CMN_UPD_RBS_TO_ADD(cell, dlSf, allocInfo, moreAddtlRbsReq, moreAddtlRbsAdd) + + allocInfo->rbsReq = allocInfo->rbsReq + moreAddtlRbsAdd; + } + } + if (isBcchPcch == TRUE) + { + RETVOID; + } + + RG_SCH_CMN_DL_MCS_TO_TBS(allocInfo->tbInfo[0].imcs, tbs); + if(tbs == 6) + { + /* This case might be for Imcs value 6 and NPrb = 1 case - Not + Adjusting either RBs or Imcs or Bytes Allocated */ + allocInfo->rbsReq = allocInfo->rbsReq - addtlRbsAdd - moreAddtlRbsAdd; + } + else if(tbs && ((0 == addtlRbsAdd) && (moreAddtlRbsAdd == 0))) + { + /*In case of a situation where we the entire bandwidth is already occupied + * and we dont have room to add additional Rbs then in order to decrease the + * code rate we reduce the tbsize such that we reduce the present calculated + * tbsize by number of bytes that would be occupied by PBCH/PSS/SSS in overlapping + * rbs and find the nearest tbsize which would be less than this deduced value*/ + + rgSCHCmnFindNumPbchOvrlapRbs(cell,dlSf,allocInfo,&numOvrlapgPbchRb); + + noLyr = allocInfo->tbInfo[0].noLyr; + RGSCH_ARRAY_BOUND_CHECK(cell->instIdx, rgTbSzTbl[noLyr - 1], tbs); + bytesReq = rgTbSzTbl[noLyr - 1][tbs][allocInfo->rbsReq - 1]/8; + + rgSCHCmnNonDlfsPbchTbSizeAdj(allocInfo,numOvrlapgPbchRb,pbchSsRsSym,0,bytesReq); + + if(allocInfo->tbInfo[1].schdlngForTb == TRUE) + { + noLyr = allocInfo->tbInfo[1].noLyr; + bytesReq = rgTbSzTbl[noLyr - 1][tbs][allocInfo->rbsReq - 1]/8; + rgSCHCmnNonDlfsPbchTbSizeAdj(allocInfo,numOvrlapgPbchRb,pbchSsRsSym,1,bytesReq); + } + + } + else if(tbs && ((addtlRbsAdd != addtlRbsReq) || + (addtlRbsAdd && (moreAddtlRbsReq != moreAddtlRbsAdd)))) + { + /*In case of a situation where we were not able to add required number of + * additional RBs then we adjust the Imcs based on original RBs requested. + * Doing this would comensate for the few extra Rbs we have added but inorder + * to comensate for number of RBS we couldnt add we again do the TBSize adjustment*/ + + rgSCHCmnNonDlfsPbchTbImcsAdj(cell, allocInfo, 0 , origRbsReq); + + if(allocInfo->tbInfo[1].schdlngForTb == TRUE) + { + rgSCHCmnNonDlfsPbchTbImcsAdj(cell, allocInfo, 1 , origRbsReq); + } + + rgSCHCmnFindNumPbchOvrlapRbs(cell,dlSf,allocInfo,&numOvrlapgPbchRb); + numOvrlapgPbchRb = numOvrlapgPbchRb - (addtlRbsAdd + moreAddtlRbsAdd); + + rgSCHCmnNonDlfsPbchTbSizeAdj(allocInfo,numOvrlapgPbchRb,pbchSsRsSym,0,allocInfo->tbInfo[0].bytesReq); + + if(allocInfo->tbInfo[1].schdlngForTb == TRUE) + { + rgSCHCmnNonDlfsPbchTbSizeAdj(allocInfo,numOvrlapgPbchRb,pbchSsRsSym,1,allocInfo->tbInfo[1].bytesReq); + } + + } + else + { + /*We hit this code when we were able to add the required additional RBS + * hence we should adjust the IMcs based on orignals RBs requested*/ + + rgSCHCmnNonDlfsPbchTbImcsAdj(cell, allocInfo, 0 , origRbsReq); + + if(allocInfo->tbInfo[1].schdlngForTb == TRUE) + { + rgSCHCmnNonDlfsPbchTbImcsAdj(cell, allocInfo, 1 , origRbsReq); + } + } + + RETVOID; +} /* end of rgSCHCmnNonDlfsPbchRbAllocAdj */ +#endif + +/** + * @brief Performs RB allocation for frequency non-selective cell. + * + * @details + * + * Function : rgSCHCmnNonDlfsCmnRbAlloc + * + * Processing Steps: + * - Allocate consecutively available RBs for BCCH/PCCH/RAR. + * + * @param[in] RgSchCellCb *cell + * @param[in, out] RgSchDlRbAlloc *allocInfo + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PRIVATE S16 rgSCHCmnNonDlfsCmnRbAlloc +( +RgSchCellCb *cell, +RgSchDlRbAlloc *allocInfo +) +#else +PRIVATE S16 rgSCHCmnNonDlfsCmnRbAlloc(cell, allocInfo) +RgSchCellCb *cell; +RgSchDlRbAlloc *allocInfo; +#endif +{ +#ifndef LTE_TDD +#ifdef LTEMAC_SPS +#endif + U8 pbchSsRsSym = 0; + U8 pbchFrame = 0; + U8 tbs = 0; + RgSchCmnDlCell *cellDl = RG_SCH_CMN_GET_DL_CELL(cell); +#endif + RgSchDlSf *dlSf = allocInfo->dlSf; +#ifdef LTEMAC_SPS + U8 rbStart = 0; + U8 spsRbsAlloc = 0; + RgSchDlSfAllocInfo *dlSfAlloc = &allocInfo->dlSf->dlSfAllocInfo; +#endif + TRC2(rgSCHCmnNonDlfsCmnRbAlloc); + + allocInfo->tbInfo[0].noLyr = 1; + +#ifdef LTEMAC_SPS + /* Note: Initialize the masks to 0, this might not be needed since alloInfo + * is initialized to 0 at the beginning of allcoation */ + allocInfo->resAllocInfo.raType0Mask = 0; + cmMemset((U8*)allocInfo->resAllocInfo.raType1Mask, 0, + RG_SCH_NUM_RATYPE1_32BIT_MASK * sizeof (U32)); + cmMemset((U8*)allocInfo->resAllocInfo.raType2Mask, 0, + RG_SCH_NUM_RATYPE2_32BIT_MASK * sizeof (U32)); + + if ((dlSf->spsAllocdBw >= cell->spsBwRbgInfo.numRbs) && + (dlSf->bwAlloced == dlSf->bw)) +#else + if(dlSf->bwAlloced == dlSf->bw) +#endif + { + RETVALUE(RFAILED); + } +#ifndef LTE_TDD + if (allocInfo->rbsReq > (dlSf->bw - dlSf->bwAlloced)) + { +#ifdef LTEMAC_SPS + if ((allocInfo->tbInfo[0].imcs < 29) && (dlSf->bwAlloced < dlSf->bw)) +#else + if(allocInfo->tbInfo[0].imcs < 29) +#endif + { + /* set the remaining RBs for the requested UE */ + allocInfo->rbsReq = dlSf->bw - dlSf->bwAlloced; + RG_SCH_CMN_DL_MCS_TO_TBS(allocInfo->tbInfo[0].imcs, tbs); + allocInfo->tbInfo[0].bytesReq = rgTbSzTbl[0][tbs][allocInfo->rbsReq - 1]/8; + } + else + { +#ifdef LTEMAC_SPS + /* Attempt RA Type 2 allocation in SPS Bandwidth */ + if (dlSf->spsAllocdBw < cell->spsBwRbgInfo.numRbs) + { + spsRbsAlloc = + rgSCHCmnDlRaType2Alloc(dlSfAlloc, + allocInfo->rbsReq, &cell->spsBwRbgInfo, &rbStart, + &allocInfo->resAllocInfo, FALSE); + /* rbsAlloc assignment moved from line 16671 to here to avoid + * compilation error. Recheck */ + dlSf->spsAllocdBw += spsRbsAlloc; + } + if (!spsRbsAlloc) +#endif /* LTEMAC_SPS */ + { + RETVALUE(RFAILED); + } + } + } +#endif + + /* Update allocation information */ + allocInfo->pdcch = rgSCHCmnCmnPdcchAlloc(cell, dlSf); + if (allocInfo->pdcch == NULLP) + { + RETVALUE(RFAILED); + } + allocInfo->dciFormat = TFU_DCI_FORMAT_1A; + allocInfo->pdcch->dciNumOfBits = cell->dciSize.size[TFU_DCI_FORMAT_1A]; + allocInfo->raType = RG_SCH_CMN_RA_TYPE2; + allocInfo->allocInfo.raType2.isLocal = TRUE; +#ifdef LTEMAC_SPS + if (spsRbsAlloc) + { + allocInfo->allocInfo.raType2.rbStart = rbStart; + allocInfo->allocInfo.raType2.numRb = allocInfo->rbsReq; + allocInfo->rbsAlloc = allocInfo->rbsReq; + } +#endif + +#ifdef LTEMAC_SPS + if (!spsRbsAlloc) + { +#endif +#ifndef LTE_TDD + if(dlSf->sfNum) + { + if(!(dlSf->sfNum == 5)) + { + /* case for subframes 1 to 9 except 5 */ +#ifdef LTEMAC_SPS + allocInfo->allocInfo.raType2.rbStart = rbStart; +#else + /*Fix for ccpu00123918*/ + allocInfo->allocInfo.raType2.rbStart = (U8)dlSf->type2Start; +#endif + } + else + { + pbchFrame = 1; /* case for subframe 5 */ + /* In subframe 5, symbols are reserved for PSS and SSS and CFICH + and Cell Specific Reference Signals */ + pbchSsRsSym = (((cellDl->currCfi) + RGSCH_NUM_PSS_SSS_SYM) * + RGSCH_NUM_SC_IN_RB + cell->numCellRSPerSf); + } + } + else + { + pbchFrame = 1; + /* In subframe 0, symbols are reserved for PSS, SSS, PBCH, CFICH and + and Cell Specific Reference signals */ + pbchSsRsSym = (((cellDl->currCfi) + RGSCH_NUM_PBCH_SYM + + RGSCH_NUM_PSS_SSS_SYM) * RGSCH_NUM_SC_IN_RB + + cell->numCellRSPerSf); + } /* end of outer else */ + + if((pbchFrame) && + (((dlSf->bwAlloced + allocInfo->rbsReq) - cell->pbchRbStart) > 0)&& + (dlSf->bwAlloced < cell->pbchRbEnd)) + { + if(allocInfo->tbInfo[0].imcs < 29) + { + rgSCHCmnNonDlfsPbchRbAllocAdj(cell, allocInfo, pbchSsRsSym, TRUE); + } + } +#endif +#ifdef LTEMAC_SPS + } +#endif + +#ifdef LTEMAC_SPS + if (!spsRbsAlloc) + { +#endif + /*Fix for ccpu00123918*/ + allocInfo->allocInfo.raType2.rbStart = (U8)dlSf->type2Start; + allocInfo->allocInfo.raType2.numRb = allocInfo->rbsReq; + allocInfo->rbsAlloc = allocInfo->rbsReq; + + /* LTE_ADV_FLAG_REMOVED_START */ +#ifndef LTE_TDD + if (cell->lteAdvCb.sfrCfg.status == RGR_ENABLE) + { + rgSCHCmnNonDlfsSFRCmnChannelUpdTyp2Alloc(cell, dlSf, \ + allocInfo->allocInfo.raType2.rbStart, \ + allocInfo->allocInfo.raType2.numRb); + } + else +#endif + { + rgSCHCmnNonDlfsUpdTyp2Alloc(cell, dlSf, \ + allocInfo->allocInfo.raType2.rbStart, \ + allocInfo->allocInfo.raType2.numRb); + } + +#ifdef LTEMAC_SPS + } +#endif + /* LTE_ADV_FLAG_REMOVED_END */ + allocInfo->tbInfo[0].bytesAlloc = allocInfo->tbInfo[0].bytesReq; + + +#ifdef LTEMAC_SPS + if (spsRbsAlloc) + { + U8 idx; + /* Update type 0, 1 and 2 masks */ + dlSfAlloc->raType0Mask |= allocInfo->resAllocInfo.raType0Mask; +#ifdef RGSCH_SPS_UNUSED + for (idx = 0; idx < RG_SCH_NUM_RATYPE1_32BIT_MASK; ++idx) + { + dlSfAlloc->raType1Mask[idx] |= + allocInfo->resAllocInfo.raType1Mask[idx]; + dlSfAlloc->raType1UsedRbs[idx] += + allocInfo->resAllocInfo.raType1UsedRbs[idx]; + } +#endif + for (idx = 0; idx < RG_SCH_NUM_RATYPE2_32BIT_MASK; ++idx) + { + dlSfAlloc->raType2Mask[idx] |= + allocInfo->resAllocInfo.raType2Mask[idx]; + } + } +#endif + + RETVALUE(ROK); +} + + +/** + * @brief Performs RB allocation for frequency non-selective cell. + * + * @details + * + * Function : rgSCHCmnNonDlfsCmnRbAllocRar + * + * Processing Steps: + * - Allocate consecutively available RBs for BCCH/PCCH/RAR. + * + * @param[in] RgSchCellCb *cell + * @param[in, out] RgSchDlRbAlloc *allocInfo + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PRIVATE S16 rgSCHCmnNonDlfsCmnRbAllocRar +( + RgSchCellCb *cell, + RgSchDlRbAlloc *allocInfo + ) +#else +PRIVATE S16 rgSCHCmnNonDlfsCmnRbAlloc(cell, allocInfo) + RgSchCellCb *cell; + RgSchDlRbAlloc *allocInfo; +#endif +{ + U8 tbs = 0; + RgSchCmnDlCell *cellDl = RG_SCH_CMN_GET_DL_CELL(cell); + RgSchDlSf *dlSf = allocInfo->dlSf; + TRC2(rgSCHCmnNonDlfsCmnRbAllocRar); + + + if(dlSf->bwAlloced == dlSf->bw) + { + RETVALUE(RFAILED); + } + + allocInfo->tbInfo[0].noLyr = 1; +#ifndef RG_5GTF + /* Update allocation information */ + allocInfo->pdcch = rgSCHCmnCmnPdcchAlloc(cell, dlSf); + if (allocInfo->pdcch == NULLP) + { + RETVALUE(RFAILED); + } + allocInfo->dciFormat = TFU_DCI_FORMAT_1A; + allocInfo->pdcch->dciNumOfBits = cell->dciSize.size[TFU_DCI_FORMAT_1A]; + allocInfo->raType = RG_SCH_CMN_RA_TYPE2; + allocInfo->allocInfo.raType2.isLocal = TRUE; + + /*Fix for ccpu00123918*/ + allocInfo->allocInfo.raType2.rbStart = (U8)dlSf->type2Start; + allocInfo->allocInfo.raType2.numRb = allocInfo->rbsReq; + allocInfo->rbsAlloc = allocInfo->rbsReq; + + /* LTE_ADV_FLAG_REMOVED_END */ + allocInfo->tbInfo[0].bytesAlloc = allocInfo->tbInfo[0].bytesReq; + +#else + allocInfo->pdcch = rgSCHCmnPdcchAlloc(cell, NULLP, dlSf, 13, TFU_DCI_FORMAT_B1, FALSE); + if (allocInfo->pdcch == NULLP) + { + RETVALUE(RFAILED); + } + RgSchSfBeamInfo *beamInfo = &(dlSf->sfBeamInfo[0]); + if(beamInfo->totVrbgAllocated > MAX_5GTF_VRBG) + { + printf("5GTF_ERROR vrbg allocated > 25\n"); + RETVALUE(RFAILED); + } + + allocInfo->tbInfo[0].cmnGrnt.vrbgStart = beamInfo->vrbgStart; + allocInfo->tbInfo[0].cmnGrnt.numVrbg = allocInfo->vrbgReq; + + /* Update allocation information */ + allocInfo->dciFormat = TFU_DCI_FORMAT_B1; + + allocInfo->tbInfo[0].cmnGrnt.xPDSCHRange = 1; + allocInfo->tbInfo[0].cmnGrnt.rbAssign = rgSCHCmnCalcRiv(MAX_5GTF_VRBG, + allocInfo->tbInfo[0].cmnGrnt.vrbgStart, allocInfo->tbInfo[0].cmnGrnt.numVrbg); + + allocInfo->tbInfo[0].cmnGrnt.rbStrt = (allocInfo->tbInfo[0].cmnGrnt.vrbgStart * MAX_5GTF_VRBG_SIZE); + allocInfo->tbInfo[0].cmnGrnt.numRb = (allocInfo->tbInfo[0].cmnGrnt.numVrbg * MAX_5GTF_VRBG_SIZE); + + beamInfo->vrbgStart += allocInfo->tbInfo[0].cmnGrnt.numVrbg; + beamInfo->totVrbgAllocated += allocInfo->tbInfo[0].cmnGrnt.numVrbg; + allocInfo->tbInfo[0].cmnGrnt.rv = 0; + allocInfo->tbInfo[0].bytesAlloc = allocInfo->tbInfo[0].bytesReq; + +#endif + printf("\n[%s],allocInfo->tbInfo[0].bytesAlloc:%u,vrbgReq:%u\n", + __func__,allocInfo->tbInfo[0].bytesAlloc,allocInfo->vrbgReq); + + RETVALUE(ROK); +} + + +/* LTE_ADV_FLAG_REMOVED_START */ +#ifndef LTE_TDD +/** + * @brief To check if DL BW available for non-DLFS allocation. + * + * @details + * + * Function : rgSCHCmnNonDlfsBwAvlbl + * + * Processing Steps: + * - Determine availability based on RA Type. + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchDlSf *dlSf + * @param[in] RgSchDlRbAlloc *allocInfo + * + * @return Bool + * -# TRUE + * -# FALSE + **/ +#ifdef ANSI +PRIVATE Bool rgSCHCmnNonDlfsSFRBwAvlbl +( +RgSchCellCb *cell, +RgSchSFRPoolInfo **sfrpoolInfo, +RgSchDlSf *dlSf, +RgSchDlRbAlloc *allocInfo, +Bool isUeCellEdge +) +#else +PRIVATE Bool rgSCHCmnNonDlfsSFRBwAvlbl(cell, sfrpoolInfo, dlSf, allocInfo, isUeCellEdge) +RgSchCellCb *cell; +RgSchSFRPoolInfo **sfrpoolInfo; +RgSchDlSf *dlSf; +RgSchDlRbAlloc *allocInfo; +Bool isUeCellEdge; +#endif +{ + CmLListCp *l; + CmLListCp *l1; + CmLList *n; + CmLList *n1; + RgSchSFRPoolInfo *sfrPool; + RgSchSFRPoolInfo *sfrCEPool; + + U8 tbs; + U8 noLyrs; + RgSchSFRPoolInfo *poolWithMaxAvlblBw = NULLP; + U32 bwAvlbl = 0; + U32 addtnlPRBs = 0; + + if (dlSf->bw <= dlSf->bwAlloced) + { + RLOG_ARG2(L_ERROR,DBG_CELLID,cell->cellId, + "BW is fully allocated for subframe (%d) CRNTI:%d", dlSf->sfNum,allocInfo->rnti); + return FALSE; + } + + if (dlSf->sfrTotalPoolInfo.ccBwFull == TRUE) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId, + "BW is fully allocated for CC Pool CRNTI:%d",allocInfo->rnti); + return FALSE; + } + + if ((dlSf->sfrTotalPoolInfo.ceBwFull == TRUE) && (isUeCellEdge)) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId, + "BW is fully allocated for CE Pool CRNTI:%d",allocInfo->rnti); + return FALSE; + } + + /* We first check if the ue scheduled is a cell edge or cell centre and accordingly check the avaialble + memory in their pool. If the cell centre UE doesnt have Bw available in its pool, then it will check + Bw availability in cell edge pool but the other way around is NOT possible. */ + if(isUeCellEdge) + { + l = &dlSf->sfrTotalPoolInfo.cePool; + } + else + { + l = &dlSf->sfrTotalPoolInfo.ccPool; + } + + n = cmLListFirst(l); + + while(n) + { + if (allocInfo->raType == RG_SCH_CMN_RA_TYPE0) + { + sfrPool = (RgSchSFRPoolInfo*)(n->node); + + /* MS_FIX for ccpu00123919 : Number of RBs in case of RETX should be same as that of initial transmission. */ + if(allocInfo->tbInfo[0].tbCb->txCntr) + { + /* If RB assignment is being done for RETX. Then if reqRbs are a multiple of rbgSize then ignore lstRbgDfct. If reqRbs is + * not a multiple of rbgSize then check if lsgRbgDfct exists */ + if (allocInfo->rbsReq % cell->rbgSize == 0) + { + if ((sfrPool->type2End == dlSf->type2End) && dlSf->lstRbgDfct) + { + /* In this scenario we are wasting the last RBG for this dlSf */ + sfrPool->type0End--; + sfrPool->bwAlloced += (cell->rbgSize - dlSf->lstRbgDfct); + + dlSf->lstRbgDfct = 0; + + /*ABHINAV To check if these variables need to be taken care of*/ + dlSf->type0End--; + dlSf->bwAlloced += (cell->rbgSize - dlSf->lstRbgDfct); + } + } + else + { + if (dlSf->lstRbgDfct) + { + /* Check if type0 allocation can cater to this RETX requirement */ + if ((allocInfo->rbsReq % cell->rbgSize) != (cell->rbgSize - dlSf->lstRbgDfct)) + { + RETVALUE(FALSE); + } + else + { + if (sfrPool->type2End != dlSf->type2End) /*Search again for some pool which has the END RBG of the BandWidth*/ + { + continue; + } + } + } + else + { + /* cannot allocate same number of required RBs */ + RETVALUE(FALSE); + } + } + } + + /*rg002.301 ccpu00120391 MOD condition is modified approprialtely to find if rbsReq is less than available RBS*/ + if(allocInfo->rbsReq <= (((sfrPool->type0End - sfrPool->type2End + 1)*\ + cell->rbgSize) - dlSf->lstRbgDfct)) + { + *sfrpoolInfo = sfrPool; + RETVALUE(TRUE); + } + else + { + if (sfrPool->bw <= sfrPool->bwAlloced + cell->rbgSize) + { + n = cmLListNext(l); + /* If the ue is cell centre then it will simply check the memory available in next pool. + But if there are no more memory pools available, then cell centre Ue will try to look for memory in cell edge pool */ + + if((!isUeCellEdge) && (!n->node)) + { + l = &dlSf->sfrTotalPoolInfo.cePool; + n = cmLListFirst(l); + } + + continue; + } + + /* MS_FIX: Number of RBs in case of RETX should be same as that of initial transmission */ + if(allocInfo->tbInfo[0].tbCb->txCntr == 0) + { + /*rg002.301 ccpu00120391 MOD setting the remaining RBs for the requested UE*/ + allocInfo->rbsReq = (((sfrPool->type0End - sfrPool->type2End + 1)*\ + cell->rbgSize) - dlSf->lstRbgDfct); + RG_SCH_CMN_DL_MCS_TO_TBS(allocInfo->tbInfo[0].imcs, tbs); + noLyrs = allocInfo->tbInfo[0].noLyr; + allocInfo->tbInfo[0].bytesReq = rgTbSzTbl[noLyrs-1][tbs][allocInfo->rbsReq - 1]/8; + *sfrpoolInfo = sfrPool; + RETVALUE(TRUE); + } + else + { + n = cmLListNext(l); + + /* If the ue is cell centre then it will simply check the memory available in next pool. + But if there are no more memory pools available, then cell centre Ue will try to look for memory in cell edge pool */ + if((!isUeCellEdge) && (!n->node)) + { + l = &dlSf->sfrTotalPoolInfo.cePool; + n = cmLListFirst(l); + } + + continue; + } + + // RETVALUE(FALSE); + } + } + else if (allocInfo->raType == RG_SCH_CMN_RA_TYPE2) + { + sfrPool = (RgSchSFRPoolInfo*)(n->node); + /* This is a Case where a UE was CC and had more RBs allocated than present in CE pool. + In case this UE whn become CE with retx going on, then BW is not sufficient for Retx */ + if ((isUeCellEdge) && + (allocInfo->tbInfo[0].tbCb->txCntr != 0)) + { + if(allocInfo->rbsReq > (sfrPool->bw - sfrPool->bwAlloced)) + { + /* Adjust CE BW such that Retx alloc is successful */ + /* Check if merging CE with adjacent CC pool will be sufficient to process Retx */ + + /* If no Type 0 allocations are made from this pool */ + if (sfrPool->type0End == (((sfrPool->poolendRB + 1) / cell->rbgSize) - 1)) + { + if (sfrPool->adjCCPool && + (sfrPool->adjCCPool->type2Start == sfrPool->poolendRB + 1) && + (allocInfo->rbsReq <= ((sfrPool->bw - sfrPool->bwAlloced) + + ((sfrPool->adjCCPool->bw - sfrPool->adjCCPool->bwAlloced))))) + { + addtnlPRBs = allocInfo->rbsReq - (sfrPool->bw - sfrPool->bwAlloced); + + /* Adjusting CE Pool Info */ + sfrPool->bw += addtnlPRBs; + sfrPool->type0End = ((sfrPool->poolendRB + addtnlPRBs + 1) / + cell->rbgSize) - 1; + + /* Adjusting CC Pool Info */ + sfrPool->adjCCPool->type2Start += addtnlPRBs; + sfrPool->adjCCPool->type2End = RGSCH_CEIL(sfrPool->adjCCPool->type2Start, + cell->rbgSize); + sfrPool->adjCCPool->bw -= addtnlPRBs; + *sfrpoolInfo = sfrPool; + RETVALUE(TRUE); + } + } + } + } + + /* Check if CC pool is one of the following: + * 1. |CE| + |CC "CCPool2Exists" = TRUE| + * 2. |CC "CCPool2Exists" = FALSE| + |CE| + |CC "CCPool2Exists" = TRUE| + */ + if(TRUE == sfrPool->CCPool2Exists) + { + l1 = &dlSf->sfrTotalPoolInfo.cePool; + n1 = cmLListFirst(l1); + sfrCEPool = (RgSchSFRPoolInfo*)(n1->node); + if(allocInfo->rbsReq <= (sfrCEPool->bw - sfrCEPool->bwAlloced)) + { + *sfrpoolInfo = sfrCEPool; + RETVALUE(TRUE); + } + else if(allocInfo->rbsReq <= (sfrPool->bw - sfrPool->bwAlloced)) + { + *sfrpoolInfo = sfrPool; + RETVALUE(TRUE); + } + /* Check if CE and CC boundary has unallocated prbs */ + else if ((sfrPool->poolstartRB == sfrPool->type2Start) && + (sfrCEPool->type0End == ((sfrCEPool->poolendRB + 1) / cell->rbgSize) - 1)) + { + if(allocInfo->rbsReq <= (sfrCEPool->bw - sfrCEPool->bwAlloced) + + (sfrPool->bw - sfrPool->bwAlloced)) + { + /* Checking if BW can be allocated partly from CE pool and partly + * from CC pool + */ + addtnlPRBs = allocInfo->rbsReq - (sfrPool->bw - sfrPool->bwAlloced); + /* Updating CE and CC type2 parametrs based on the RBs allocated + * from these pools*/ + sfrPool->type2Start -= addtnlPRBs; + sfrPool->type2End = RGSCH_CEIL(sfrPool->type2Start, cell->rbgSize); + sfrPool->bw += addtnlPRBs; + if (addtnlPRBs == (sfrCEPool->bw - sfrCEPool->bwAlloced)) + { + sfrCEPool->bwAlloced = sfrCEPool->bw; + dlSf->sfrTotalPoolInfo.ceBwFull = TRUE; + } + else + { + sfrCEPool->bw -= addtnlPRBs; + sfrCEPool->type0End = ((sfrCEPool->poolendRB + 1 - addtnlPRBs) / cell->rbgSize) - 1; + } + *sfrpoolInfo = sfrPool; + RETVALUE(TRUE); + } + else if ( bwAvlbl < + ((sfrCEPool->bw - sfrCEPool->bwAlloced) + + (sfrPool->bw - sfrPool->bwAlloced))) + { + /* All the Prbs from CE BW shall be allocated */ + if(allocInfo->tbInfo[0].tbCb->txCntr == 0) + { + sfrPool->type2Start = sfrCEPool->type2Start; + sfrPool->bw += sfrCEPool->bw - sfrCEPool->bwAlloced; + sfrCEPool->type2Start = sfrCEPool->poolendRB + 1; + sfrCEPool->bwAlloced = sfrCEPool->bw; + dlSf->sfrTotalPoolInfo.ceBwFull = TRUE; + + /* set the remaining RBs for the requested UE */ + allocInfo->rbsReq = (sfrPool->bw - sfrPool->bwAlloced); + RG_SCH_CMN_DL_MCS_TO_TBS(allocInfo->tbInfo[0].imcs, tbs); + noLyrs = allocInfo->tbInfo[0].noLyr; + allocInfo->tbInfo[0].bytesReq = + rgTbSzTbl[noLyrs-1][tbs][allocInfo->rbsReq - 1]/8; + *sfrpoolInfo = sfrPool; + RETVALUE(TRUE); + } + else + { + RETVALUE(FALSE); + } + } + } + } + + /* Checking if no. of RBs required can be allocated from + * SFR pool. + * 1. If available return the SFR pool. + * 2. Else update the RBs required parameter based on the + * BW available in the pool + * 3. Return FALSE if no B/W is available. + */ + if (allocInfo->rbsReq <= (sfrPool->bw - sfrPool->bwAlloced)) + { + *sfrpoolInfo = sfrPool; + RETVALUE(TRUE); + } + else + { + if(allocInfo->tbInfo[0].tbCb->txCntr == 0) + { + if (bwAvlbl < sfrPool->bw - sfrPool->bwAlloced) + { + if (isUeCellEdge) + { + dlSf->sfrTotalPoolInfo.ceBwFull = TRUE; + } + bwAvlbl = sfrPool->bw - sfrPool->bwAlloced; + poolWithMaxAvlblBw = sfrPool; + } + n = cmLListNext(l); + + if ((isUeCellEdge == FALSE) && (n == NULLP)) + { + if(l != &dlSf->sfrTotalPoolInfo.cePool) + { + l = &dlSf->sfrTotalPoolInfo.cePool; + n = cmLListFirst(l); + } + } + + if (n == NULLP) + { + if (bwAvlbl == 0) + { + if (isUeCellEdge) + { + dlSf->sfrTotalPoolInfo.ceBwFull = TRUE; + } + else + { + dlSf->sfrTotalPoolInfo.ccBwFull = TRUE; + } + RETVALUE(FALSE); + } + else + { + /* set the remaining RBs for the requested UE */ + allocInfo->rbsReq = poolWithMaxAvlblBw->bw - + poolWithMaxAvlblBw->bwAlloced; + RG_SCH_CMN_DL_MCS_TO_TBS(allocInfo->tbInfo[0].imcs, tbs); + noLyrs = allocInfo->tbInfo[0].noLyr; + allocInfo->tbInfo[0].bytesReq = + rgTbSzTbl[noLyrs-1][tbs][allocInfo->rbsReq - 1]/8; + *sfrpoolInfo = poolWithMaxAvlblBw; + RETVALUE(TRUE); + } + } + } + else + { + n = cmLListNext(l); + + if ((isUeCellEdge == FALSE) && (n == NULLP)) + { + if(l != &dlSf->sfrTotalPoolInfo.cePool) + { + l = &dlSf->sfrTotalPoolInfo.cePool; + n = cmLListFirst(l); + } + } + + if (n == NULLP) + { + RETVALUE(FALSE); + } + } + + } + } + } + RETVALUE(FALSE); +} +#endif /* end of ifndef LTE_TDD*/ +/* LTE_ADV_FLAG_REMOVED_END */ + +/** + * @brief To check if DL BW available for non-DLFS allocation. + * + * @details + * + * Function : rgSCHCmnNonDlfsUeRbAlloc + * + * Processing Steps: + * - Determine availability based on RA Type. + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchDlSf *dlSf + * @param[in] RgSchDlRbAlloc *allocInfo + * + * @return Bool + * -# TRUE + * -# FALSE + **/ +#ifdef ANSI +PRIVATE Bool rgSCHCmnNonDlfsBwAvlbl +( +RgSchCellCb *cell, +RgSchDlSf *dlSf, +RgSchDlRbAlloc *allocInfo +) +#else +PRIVATE Bool rgSCHCmnNonDlfsBwAvlbl(cell, dlSf, allocInfo) +RgSchCellCb *cell; +RgSchDlSf *dlSf; +RgSchDlRbAlloc *allocInfo; +#endif +{ + U8 tbs; + U8 noLyrs; + U8 ignoredDfctRbg = FALSE; + + TRC2(rgSCHCmnNonDlfsBwAvlbl); + if (dlSf->bw <= dlSf->bwAlloced) + { + RLOG_ARG3(L_DEBUG,DBG_CELLID,cell->cellId, "(%d:%d)FAILED CRNTI:%d", + dlSf->bw, dlSf->bwAlloced,allocInfo->rnti); + RETVALUE(FALSE); + } + if (allocInfo->raType == RG_SCH_CMN_RA_TYPE0) + { + /* Fix for ccpu00123919 : Number of RBs in case of RETX should be same as + * that of initial transmission. */ + if(allocInfo->tbInfo[0].tbCb->txCntr) + { + /* If RB assignment is being done for RETX. Then if reqRbs are + * a multiple of rbgSize then ignore lstRbgDfct. If reqRbs is + * not a multiple of rbgSize then check if lsgRbgDfct exists */ + if (allocInfo->rbsReq % cell->rbgSize == 0) + { + if (dlSf->lstRbgDfct) + { + /* In this scenario we are wasting the last RBG for this dlSf */ + + dlSf->type0End--; + dlSf->bwAlloced += (cell->rbgSize - dlSf->lstRbgDfct); + /* Fix: MUE_PERTTI_DL */ + dlSf->lstRbgDfct = 0; + ignoredDfctRbg = TRUE; + + } + } + else + { + if (dlSf->lstRbgDfct) + { + /* Check if type0 allocation can cater to this RETX requirement */ + if ((allocInfo->rbsReq % cell->rbgSize) != (cell->rbgSize - dlSf->lstRbgDfct)) + { + RETVALUE(FALSE); + } + } + else + { + /* cannot allocate same number of required RBs */ + RETVALUE(FALSE); + } + } + } + + /* Condition is modified approprialtely to find + * if rbsReq is less than available RBS*/ + if(allocInfo->rbsReq <= (((dlSf->type0End - dlSf->type2End + 1)*\ + cell->rbgSize) - dlSf->lstRbgDfct)) + { + RETVALUE(TRUE); + } + /* ccpu00132358:MOD- Removing "ifndef LTE_TDD" for unblocking the RB + * allocation in TDD when requested RBs are more than available RBs*/ + else + { + /* MS_WORKAROUND for ccpu00122022 */ + if (dlSf->bw < dlSf->bwAlloced + cell->rbgSize) + { + /* ccpu00132358- Re-assigning the values which were updated above + * if it is RETX and Last RBG available*/ + if(ignoredDfctRbg == TRUE) + { + dlSf->type0End++; + dlSf->bwAlloced -= (cell->rbgSize - dlSf->lstRbgDfct); + dlSf->lstRbgDfct = 1; + } + + + RETVALUE(FALSE); + } + /* Fix: Number of RBs in case of RETX should be same as + * that of initial transmission. */ + if(allocInfo->tbInfo[0].tbCb->txCntr == 0 +#ifdef LTE_ADV + && (FALSE == rgSCHLaaIsLaaTB(allocInfo)) +#endif + ) + { + /* Setting the remaining RBs for the requested UE*/ + allocInfo->rbsReq = (((dlSf->type0End - dlSf->type2End + 1)*\ + cell->rbgSize) - dlSf->lstRbgDfct); + RG_SCH_CMN_DL_MCS_TO_TBS(allocInfo->tbInfo[0].imcs, tbs); + noLyrs = allocInfo->tbInfo[0].noLyr; + allocInfo->tbInfo[0].bytesReq = rgTbSzTbl[noLyrs-1][tbs][allocInfo->rbsReq - 1]/8; + /* DwPts Scheduling Changes Start */ +#if LTE_TDD + if (dlSf->sfType == RG_SCH_SPL_SF_DATA) + { + allocInfo->tbInfo[0].bytesReq = + rgTbSzTbl[noLyrs-1][tbs][RGSCH_MAX(allocInfo->rbsReq*3/4,1) - 1]/8; + } +#endif + /* DwPts Scheduling Changes End */ + } + else + { + /* ccpu00132358- Re-assigning the values which were updated above + * if it is RETX and Last RBG available*/ + if(ignoredDfctRbg == TRUE) + { + dlSf->type0End++; + dlSf->bwAlloced -= (cell->rbgSize - dlSf->lstRbgDfct); + dlSf->lstRbgDfct = 1; + } + + RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId, "FAILED for CRNTI:%d", + allocInfo->rnti); + printf ("RB Alloc failed for LAA TB type 0\n"); + RETVALUE(FALSE); + } + RETVALUE(TRUE); + } + } + else if (allocInfo->raType == RG_SCH_CMN_RA_TYPE2) + { + if (allocInfo->rbsReq <= (dlSf->bw - dlSf->bwAlloced)) + { + RETVALUE(TRUE); + } + /* ccpu00132358:MOD- Removing "ifndef LTE_TDD" for unblocking the RB + * allocation in TDD when requested RBs are more than available RBs*/ + else + { + /* Fix: Number of RBs in case of RETX should be same as + * that of initial transmission. */ + if((allocInfo->tbInfo[0].tbCb->txCntr == 0) +#ifdef LTE_ADV + && (FALSE == rgSCHLaaIsLaaTB(allocInfo)) +#endif + ) + { + /* set the remaining RBs for the requested UE */ + allocInfo->rbsReq = dlSf->bw - dlSf->bwAlloced; + RG_SCH_CMN_DL_MCS_TO_TBS(allocInfo->tbInfo[0].imcs, tbs); + noLyrs = allocInfo->tbInfo[0].noLyr; + allocInfo->tbInfo[0].bytesReq = rgTbSzTbl[noLyrs-1][tbs][allocInfo->rbsReq - 1]/8; + /* DwPts Scheduling Changes Start */ +#ifdef LTE_TDD + if (dlSf->sfType == RG_SCH_SPL_SF_DATA) + { + allocInfo->tbInfo[0].bytesReq = + rgTbSzTbl[noLyrs-1][tbs][RGSCH_MAX(allocInfo->rbsReq*3/4,1) - 1]/8; + } +#endif + /* DwPts Scheduling Changes End */ + } + else + { + printf ("RB Alloc failed for LAA TB type 2\n"); + RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,"FAILED for CRNTI:%d",allocInfo->rnti); + RETVALUE(FALSE); + } + /* Fix: Number of RBs in case of RETX should be same as + * that of initial transmission. */ + RETVALUE(TRUE); + } + } + RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,"FAILED for CRNTI:%d",allocInfo->rnti); + RETVALUE(FALSE); +} +/* LTE_ADV_FLAG_REMOVED_START */ +#ifndef LTE_TDD +/** + * @brief To update non-DLFS alloc'n parameters after TYPE2 Allocation. + * + * @details + * + * Function : rgSCHCmnNonDlfsSFRCmnChannelUpdTyp2Alloc + * + * Processing Steps: + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchDlSf *dlSf + * @param[in] U8 rbStrt + * @param[in] U8 numRb + * + * @return Void + **/ +#ifdef ANSI +PUBLIC Void rgSCHCmnNonDlfsSFRCmnChannelUpdTyp2Alloc +( +RgSchCellCb *cell, +RgSchDlSf *dlSf, +U8 rbStrt, +U8 numRb +) +#else +PUBLIC Void rgSCHCmnNonDlfsSFRCmnChannelUpdTyp2Alloc(cell, dlSf, rbStrt, numRb) +RgSchCellCb *cell; +RgSchDlSf *dlSf; +U8 rbStrt; +U8 numRb; +#endif +{ + CmLListCp *l; + CmLList *n; + RgSchSFRPoolInfo *sfrPool; + TRC2(rgSCHCmnNonDlfsSFRCmnChannelUpdTyp2Alloc); + + l = &dlSf->sfrTotalPoolInfo.ccPool; + + dlSf->type2End = RGSCH_CEIL((rbStrt+numRb), cell->rbgSize); + dlSf->bwAlloced += numRb; + dlSf->type2Start += numRb; + n = cmLListFirst(l); + + while(n->node) + { + sfrPool = (RgSchSFRPoolInfo*)(n->node); + n = cmLListNext(l); + + /* If the pool contains some RBs allocated in this allocation, e.g: Pool is [30.50]. Pool->type2Start is 40 , dlSf->type2Start is 45. then update the variables in pool */ + if((sfrPool->poolendRB >= dlSf->type2Start) && (sfrPool->type2Start < dlSf->type2Start)) + { + sfrPool->type2End = dlSf->type2End; + sfrPool->bwAlloced = dlSf->type2Start - sfrPool->poolstartRB; + sfrPool->type2Start = dlSf->type2Start; + } + else + { + /* If the pool contains all RBs allocated in this allocation*/ + if(dlSf->type2Start > sfrPool->poolendRB) + { + sfrPool->type2End = sfrPool->type0End + 1; + sfrPool->bwAlloced = sfrPool->bw; + sfrPool->type2Start = sfrPool->poolendRB + 1; + } + } + if (!n) + { + if (l != &dlSf->sfrTotalPoolInfo.cePool) + { + l = &dlSf->sfrTotalPoolInfo.cePool; + n = cmLListFirst(l); + } + else + RETVOID; + } + } + RETVOID; +} + +/** + * @brief To update non-DLFS alloc'n parameters after TYPE2 Allocation. + * + * @details + * + * Function : rgSCHCmnNonDlfsUpdDSFRTyp2Alloc + * + * Processing Steps: + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchDlSf *dlSf + * @param[in] U8 rbStrt + * @param[in] U8 numRb + * + * @return Void + **/ +#ifdef ANSI +PRIVATE S16 rgSCHCmnNonDlfsUpdDSFRTyp2Alloc +( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgSchDlSf *dlSf, +U8 rbStrt, +U8 numRb +) +#else +PRIVATE S16 rgSCHCmnNonDlfsUpdDSFRTyp2Alloc(cell, ue, dlSf, rbStrt, numRb) +RgSchCellCb *cell; +RgSchUeCb *ue; +RgSchDlSf *dlSf; +U8 rbStrt; +U8 numRb; +#endif +{ + CmLListCp *l; + CmLList *n; + RgSchSFRPoolInfo *sfrCCPool1 = NULL; + RgSchSFRPoolInfo *sfrCCPool2 = NULL; + S16 ret = RFAILED; + + TRC2(rgSCHCmnNonDlfsUpdDSFRTyp2Alloc); + /* Move the type2End pivot forward */ + + + l = &dlSf->sfrTotalPoolInfo.ccPool; + n = cmLListFirst(l); + while(n) + { + sfrCCPool1 = (RgSchSFRPoolInfo*)(n->node); + /* KWork fix */ + if (sfrCCPool1 == NULLP) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId, "rgSCHCmnNonDlfsUpdDSFRTyp2Alloc():" + "sfrCCPool1 is NULL for CRNTI:%d",ue->ueId); + RETVALUE(RFAILED); + } + n = cmLListNext(l); + if(n) + { + sfrCCPool2 = (RgSchSFRPoolInfo*)(n->node); + n = cmLListNext(l); + } + if((sfrCCPool1) && (sfrCCPool2)) + { + /* Based on RNTP info, the CC user is assigned high power per subframe basis */ + if(((dlSf->type2Start >= sfrCCPool1->pwrHiCCRange.startRb) && + (dlSf->type2Start + numRb < sfrCCPool1->pwrHiCCRange.endRb)) || + ((dlSf->type2Start >= sfrCCPool2->pwrHiCCRange.startRb) && + (dlSf->type2Start + numRb < sfrCCPool2->pwrHiCCRange.endRb))) + { + ue->lteAdvUeCb.isCCUePHigh = TRUE; + + /* Calling rgSCHCmnBuildRntpInfo function to update RNTP BitMap */ + ret = rgSCHCmnBuildRntpInfo(cell, dlSf->rntpInfo.val, dlSf->type2Start, numRb, dlSf->bw); + if (ret != ROK) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId, "rgSCHCmnNonDlfsUpdDSFRTyp2Alloc():" + "rgSCHCmnBuildRntpInfo() function returned RFAILED for CRNTI:%d",ue->ueId); + RETVALUE(RFAILED); + } + } + } + else + { + if((dlSf->type2Start >= sfrCCPool1->pwrHiCCRange.startRb) && + (dlSf->type2Start + numRb < sfrCCPool1->pwrHiCCRange.endRb)) + { + ue->lteAdvUeCb.isCCUePHigh = TRUE; + + /* Calling rgSCHCmnBuildRntpInfo function to update RNTP BitMap */ + ret = rgSCHCmnBuildRntpInfo(cell, dlSf->rntpInfo.val, dlSf->type2Start, numRb, dlSf->bw); + if (ret != ROK) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId, "rgSCHCmnNonDlfsUpdDSFRTyp2Alloc():" + "rgSCHCmnBuildRntpInfo() function returned RFAILED CRNTI:%d",ue->ueId); + RETVALUE(RFAILED); + } + } + } + } + dlSf->type2End = RGSCH_CEIL((rbStrt+numRb), cell->rbgSize); +#ifndef LTEMAC_SPS + dlSf->bwAlloced += numRb; + /*MS_FIX for ccpu00123918*/ + dlSf->type2Start += numRb; +#endif + RETVALUE(ROK); +} +#endif /* end of ifndef LTE_TDD*/ +/* LTE_ADV_FLAG_REMOVED_END */ +/** + * @brief To update non-DLFS alloc'n parameters after TYPE2 Allocation. + * + * @details + * + * Function : rgSCHCmnNonDlfsUpdTyp2Alloc + * + * Processing Steps: + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchDlSf *dlSf + * @param[in] U8 rbStrt + * @param[in] U8 numRb + * + * @return Void + **/ +#ifdef ANSI +PRIVATE Void rgSCHCmnNonDlfsUpdTyp2Alloc +( +RgSchCellCb *cell, +RgSchDlSf *dlSf, +U8 rbStrt, +U8 numRb +) +#else +PRIVATE Void rgSCHCmnNonDlfsUpdTyp2Alloc(cell, dlSf, rbStrt, numRb) +RgSchCellCb *cell; +RgSchDlSf *dlSf; +U8 rbStrt; +U8 numRb; +#endif +{ + TRC2(rgSCHCmnNonDlfsUpdTyp2Alloc); + /* Move the type2End pivot forward */ + dlSf->type2End = RGSCH_CEIL((rbStrt+numRb), cell->rbgSize); +//#ifndef LTEMAC_SPS + dlSf->bwAlloced += numRb; + /*Fix for ccpu00123918*/ + dlSf->type2Start += numRb; +//#endif + RETVOID; +} + +/** + * @brief To do DL allocation using TYPE0 RA. + * + * @details + * + * Function : rgSCHCmnNonDlfsType0Alloc + * + * Processing Steps: + * - Perform TYPE0 allocation using the RBGs between + * type0End and type2End. + * - Build the allocation mask as per RBG positioning. + * - Update the allocation parameters. + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchDlSf *dlSf + * @param[in] RgSchDlRbAlloc *allocInfo + * + * @return Void + **/ +#ifdef ANSI +PRIVATE Void rgSCHCmnNonDlfsType0Alloc +( +RgSchCellCb *cell, +RgSchDlSf *dlSf, +RgSchDlRbAlloc *allocInfo, +RgSchUeCb *ue +) +#else +PRIVATE Void rgSCHCmnNonDlfsType0Alloc(cell, dlSf, allocInfo, dlUe) +RgSchCellCb *cell; +RgSchDlSf *dlSf; +RgSchDlRbAlloc *allocInfo; +RgSchUeCb *ue; +#endif +{ + U32 dlAllocMsk = 0; + U8 rbgFiller = dlSf->lstRbgDfct; + U8 noRbgs = RGSCH_CEIL((allocInfo->rbsReq + rbgFiller), cell->rbgSize); + //U8 noRbgs = (allocInfo->rbsReq + rbgFiller)/ cell->rbgSize; + U8 noRbs; + U8 noLyr; + U8 iTbs; + U32 tb1BytesAlloc = 0; + U32 tb2BytesAlloc = 0; + RgSchCmnDlUe *dlUe = RG_SCH_CMN_GET_DL_UE(ue,cell); + + TRC2(rgSCHCmnNonDlfsType0Alloc); + //if(noRbgs == 0) noRbgs = 1; /* Not required as ceilling is used above*/ + + /* Fix for ccpu00123919*/ + noRbs = (noRbgs * cell->rbgSize) - rbgFiller; + if (dlSf->bwAlloced + noRbs > dlSf->bw) + { + if (--noRbgs == 0) + { + RETVOID; + } + noRbs = (noRbgs * cell->rbgSize) - rbgFiller; + } + + /* Fix for ccpu00138701: Ceilling is using to derive num of RBGs, Therefore, + * after this operation,checking Max TB size and Max RBs are not crossed + * if it is crossed then decrement num of RBGs. */ + //if((noRbs + rbgFiller) % cell->rbgSize) + if((noRbs > allocInfo->rbsReq) && + (allocInfo->rbsReq + rbgFiller) % cell->rbgSize) + {/* considering ue category limitation + * due to ceiling */ + +#ifdef LTE_ADV + if (rgSCHLaaIsLaaTB(allocInfo)== FALSE) +#endif + { + if ((allocInfo->tbInfo[0].schdlngForTb) && (!allocInfo->tbInfo[0].tbCb->txCntr)) + { + iTbs = allocInfo->tbInfo[0].iTbs; + noLyr = allocInfo->tbInfo[0].noLyr; + tb1BytesAlloc = rgTbSzTbl[noLyr - 1][iTbs][noRbs - 1]/8; + } + + if ((allocInfo->tbInfo[1].schdlngForTb) && (!allocInfo->tbInfo[1].tbCb->txCntr)) + { + iTbs = allocInfo->tbInfo[1].iTbs; + noLyr = allocInfo->tbInfo[1].noLyr; + tb2BytesAlloc = rgTbSzTbl[noLyr - 1][iTbs][noRbs - 1]/8; + } + } + + /* Only Check for New Tx No need for Retx */ + if (tb1BytesAlloc || tb2BytesAlloc) + { + if (( ue->dl.aggTbBits >= dlUe->maxTbBits) || + (tb1BytesAlloc >= dlUe->maxTbSz/8) || + (tb2BytesAlloc >= dlUe->maxTbSz/8) || + (noRbs >= dlUe->maxRb)) + { + if (--noRbgs == 0) + { + RETVOID; + } + noRbs = (noRbgs * cell->rbgSize) - rbgFiller; + } + } + } + /* type0End would have been initially (during subfrm Init) at the bit position + * (cell->noOfRbgs - 1), 0 being the most significant. + * Getting DlAllocMsk for noRbgs and at the appropriate position */ + dlAllocMsk |= (((1 << noRbgs) - 1) << (31 - dlSf->type0End)); + /* Move backwards the type0End pivot */ + dlSf->type0End -= noRbgs; + /*Fix for ccpu00123919*/ + /*noRbs = (noRbgs * cell->rbgSize) - rbgFiller;*/ + /* Update the bwAlloced field accordingly */ +//#ifndef LTEMAC_SPS /* ccpu00129474*/ + dlSf->bwAlloced += noRbs; +//#endif + /* Update Type0 Alloc Info */ + allocInfo->allocInfo.raType0.numDlAlloc = noRbgs; + allocInfo->allocInfo.raType0.dlAllocBitMask |= dlAllocMsk; + allocInfo->rbsAlloc = noRbs; + + /* Update Tb info for each scheduled TB */ + iTbs = allocInfo->tbInfo[0].iTbs; + noLyr = allocInfo->tbInfo[0].noLyr; + /* Fix for ccpu00123919: For a RETX TB the iTbs is irrelevant. + * RETX TB Size is same as Init TX TB Size */ + if (allocInfo->tbInfo[0].tbCb->txCntr) + { + allocInfo->tbInfo[0].bytesAlloc = + allocInfo->tbInfo[0].bytesReq; + } + else + { + allocInfo->tbInfo[0].bytesAlloc = + rgTbSzTbl[noLyr - 1][iTbs][noRbs - 1]/8; + /* DwPts Scheduling Changes Start */ +#ifdef LTE_TDD + if (dlSf->sfType == RG_SCH_SPL_SF_DATA) + { + allocInfo->tbInfo[0].bytesAlloc = + rgTbSzTbl[noLyr - 1][iTbs][RGSCH_MAX(noRbs*3/4,1) - 1]/8; + } +#endif + /* DwPts Scheduling Changes End */ + } + + if (allocInfo->tbInfo[1].schdlngForTb) + { + iTbs = allocInfo->tbInfo[1].iTbs; + noLyr = allocInfo->tbInfo[1].noLyr; + /* Fix for ccpu00123919: For a RETX TB the iTbs is irrelevant + * RETX TB Size is same as Init TX TB Size */ + if (allocInfo->tbInfo[1].tbCb->txCntr) + { + allocInfo->tbInfo[1].bytesAlloc = + allocInfo->tbInfo[1].bytesReq; + } + else + { + allocInfo->tbInfo[1].bytesAlloc = + rgTbSzTbl[noLyr - 1][iTbs][noRbs - 1]/8;; + /* DwPts Scheduling Changes Start */ +#ifdef LTE_TDD + if (dlSf->sfType == RG_SCH_SPL_SF_DATA) + { + allocInfo->tbInfo[1].bytesAlloc = + rgTbSzTbl[noLyr - 1][iTbs][RGSCH_MAX(noRbs*3/4,1) - 1]/8; + } +#endif + /* DwPts Scheduling Changes End */ + } + } + + /* The last RBG which can be smaller than the RBG size is consedered + * only for the first time allocation of TYPE0 UE */ + dlSf->lstRbgDfct = 0; + RETVOID; +} +#ifndef LTE_TDD + +/** + * @brief To prepare RNTP value from the PRB allocation (P-High -> 1 and P-Low -> 0) + * + * @details + * + * Function : rgSCHCmnBuildRntpInfo + * + * Processing Steps: + * + * @param[in] U8 *rntpPtr + * @param[in] U8 startRb + * @param[in] U8 numRb + * + * @return Void + **/ +#ifdef ANSI +PRIVATE S16 rgSCHCmnBuildRntpInfo +( +RgSchCellCb *cell, +U8 *rntpPtr, +U8 startRb, +U8 nmbRb, +U16 bw +) +#else +PRIVATE S16 rgSCHCmnBuildRntpInfo(cell, rntpPtr, startRb, nmbRb, bw) +RgSchCellCb *cell; +U8 *rntpPtr; +U8 startRb; +U8 nmbRb; +U16 bw; +#endif +{ + U16 rbPtrStartIdx; /* Start Index of Octete Buffer to be filled */ + U16 rbPtrEndIdx; /* End Index of Octete Buffer to be filled */ + U16 rbBitLoc; /* Bit Location to be set as 1 in the current Byte */ + U16 nmbRbPerByte; /* PRB's to be set in the current Byte (in case of multiple Bytes) */ + + TRC2(rgSCHCmnBuildRntpInfo); + + rbPtrStartIdx = (startRb)/8; + rbPtrEndIdx = (startRb + nmbRb)/8; + + if (rntpPtr == NULLP) + { + RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId, + "rgSCHCmnBuildRntpInfo():" + "rntpPtr can't be NULLP (Memory Allocation Failed)"); + RETVALUE(RFAILED); + } + + while(rbPtrStartIdx <= rbPtrEndIdx) + { + rbBitLoc = (startRb)%8; + + /* case 1: startRb and endRb lies in same Byte */ + if (rbPtrStartIdx == rbPtrEndIdx) + { + rntpPtr[rbPtrStartIdx] = rntpPtr[rbPtrStartIdx] + | (((1<type2End = RGSCH_CEIL((rbStrt+numRb), cell->rbgSize); + sfrPool->type2End = RGSCH_CEIL((rbStrt+numRb), cell->rbgSize); + +#ifndef LTEMAC_SPS + dlSf->type2Start += numRb; + dlSf->bwAlloced += numRb; + + if(cell->lteAdvCb.dsfrCfg.status == RGR_ENABLE) + { + /* Based on RNTP info, the CC user is assigned high power per subframe basis */ + if(FALSE == ue->lteAdvUeCb.rgrLteAdvUeCfg.isUeCellEdge) + { + if((sfrPool->type2Start >= sfrPool->pwrHiCCRange.startRb) && + (sfrPool->type2Start + numRb < sfrPool->pwrHiCCRange.endRb)) + { + ue->lteAdvUeCb.isCCUePHigh = TRUE; + + /* Calling rgSCHCmnBuildRntpInfo function to update RNTP BitMap */ + ret = rgSCHCmnBuildRntpInfo(cell, dlSf->rntpInfo.val, sfrPool->type2Start, numRb, dlSf->bw); + if (ret != ROK) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,"rgSCHCmnNonDlfsUpdSFRPoolTyp2Alloc():" + "rgSCHCmnBuildRntpInfo() function returned RFAILED for CRNTI:%d",ue->ueId); + RETVALUE(RFAILED); + } + } + } + else + { + /* Calling rgSCHCmnBuildRntpInfo function to update RNTP BitMap */ + ret = rgSCHCmnBuildRntpInfo(cell, dlSf->rntpInfo.val, sfrPool->type2Start, numRb, dlSf->bw); + if (ret != ROK) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId, "rgSCHCmnNonDlfsUpdSFRPoolTyp2Alloc():" + "rgSCHCmnBuildRntpInfo() function returned RFAILED for CRNTI:%d",ue->ueId); + RETVALUE(RFAILED); + } + } + } + sfrPool->type2Start += numRb; + sfrPool->bwAlloced += numRb; +#endif + + RETVALUE(ROK); +} + +/** + * @brief To do DL allocation using TYPE0 RA. + * + * @details + * + * Function : rgSCHCmnNonDlfsSFRPoolType0Alloc + * + * Processing Steps: + * - Perform TYPE0 allocation using the RBGs between type0End and type2End. + * - Build the allocation mask as per RBG positioning. + * - Update the allocation parameters. + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchDlSf *dlSf + * @param[in] RgSchDlRbAlloc *allocInfo + * + * @return Void + **/ +#ifdef ANSI +PRIVATE Void rgSCHCmnNonDlfsSFRPoolType0Alloc +( +RgSchCellCb *cell, +RgSchDlSf *dlSf, +RgSchSFRPoolInfo *poolInfo, +RgSchDlRbAlloc *allocInfo +) +#else +PRIVATE Void rgSCHCmnNonDlfsSFRPoolType0Alloc(cell, dlSf, poolInfo, allocInfo) +RgSchCellCb *cell; +RgSchDlSf *dlSf; +RgSchSFRPoolInfo *poolInfo; +RgSchDlRbAlloc *allocInfo; +#endif +{ + U32 dlAllocMsk = 0; + U8 rbgFiller = 0; + U8 noRbgs = 0; + U8 noRbs; + U8 noLyr; + U8 iTbs; + + TRC2(rgSCHCmnNonDlfsSFRPoolType0Alloc); + + if (poolInfo->poolstartRB + poolInfo->bw == dlSf->bw) + { + if (poolInfo->type0End == dlSf->bw/4) + { + rbgFiller = dlSf->lstRbgDfct; + /* The last RBG which can be smaller than the RBG size is consedered + * only for the first time allocation of TYPE0 UE */ + dlSf->lstRbgDfct = 0; + } + } + + noRbgs = RGSCH_CEIL((allocInfo->rbsReq + rbgFiller), cell->rbgSize); + + /* Abhinav to-do start */ + /* MS_FIX for ccpu00123919*/ + noRbs = (noRbgs * cell->rbgSize) - rbgFiller; + if (dlSf->bwAlloced + noRbs > dlSf->bw) + { + if (--noRbgs == 0) + { + RETVOID; + } + noRbs = (noRbgs * cell->rbgSize) - rbgFiller; + } + /* Abhinav to-do end */ + + + + /* type0End would have been initially (during subfrm Init) at the bit position + * (cell->noOfRbgs - 1), 0 being the most significant. + * Getting DlAllocMsk for noRbgs and at the appropriate position */ + dlAllocMsk |= (((1 << noRbgs) - 1) << (31 - poolInfo->type0End)); + /* Move backwards the type0End pivot */ + poolInfo->type0End -= noRbgs; + /*MS_FIX for ccpu00123919*/ + /*noRbs = (noRbgs * cell->rbgSize) - rbgFiller;*/ + /* Update the bwAlloced field accordingly */ + poolInfo->bwAlloced += noRbs + dlSf->lstRbgDfct; + dlSf->bwAlloced += noRbs + dlSf->lstRbgDfct; + + /* Update Type0 Alloc Info */ + allocInfo->allocInfo.raType0.numDlAlloc = noRbgs; + allocInfo->allocInfo.raType0.dlAllocBitMask |= dlAllocMsk; + allocInfo->rbsAlloc = noRbs; + + /* Update Tb info for each scheduled TB */ + iTbs = allocInfo->tbInfo[0].iTbs; + noLyr = allocInfo->tbInfo[0].noLyr; + /* Fix for ccpu00123919: For a RETX TB the iTbs is irrelevant. + * RETX TB Size is same as Init TX TB Size */ + if (allocInfo->tbInfo[0].tbCb->txCntr) + { + allocInfo->tbInfo[0].bytesAlloc = + allocInfo->tbInfo[0].bytesReq; + } + else + { + allocInfo->tbInfo[0].bytesAlloc = + rgTbSzTbl[noLyr - 1][iTbs][noRbs - 1]/8; + } + + if (allocInfo->tbInfo[1].schdlngForTb) + { + iTbs = allocInfo->tbInfo[1].iTbs; + noLyr = allocInfo->tbInfo[1].noLyr; + /* Fix for ccpu00123919: For a RETX TB the iTbs is irrelevant + * RETX TB Size is same as Init TX TB Size */ + if (allocInfo->tbInfo[1].tbCb->txCntr) + { + allocInfo->tbInfo[1].bytesAlloc = + allocInfo->tbInfo[1].bytesReq; + } + else + { + allocInfo->tbInfo[1].bytesAlloc = + rgTbSzTbl[noLyr - 1][iTbs][noRbs - 1]/8;; + } + } + + /* The last RBG which can be smaller than the RBG size is consedered + * only for the first time allocation of TYPE0 UE */ + dlSf->lstRbgDfct = 0; + RETVOID; +} + +/** + * @brief Computes RNTP Info for a subframe. + * + * @details + * + * Function : rgSCHCmnNonDlfsDsfrRntpComp + * + * Processing Steps: + * - Computes RNTP info from individual pools. + * + * @param[in] RgSchDlSf *dlSf + * + * @return void + + **/ +#ifdef ANSI +PRIVATE void rgSCHCmnNonDlfsDsfrRntpComp +( +RgSchCellCb *cell, +RgSchDlSf *dlSf +) +#else +PRIVATE void rgSCHCmnNonDlfsDsfrRntpComp(cell, dlSf) +RgSchCellCb *cell; +RgSchDlSf *dlSf; +#endif +{ + PRIVATE U16 samples = 0; + U16 i; + U16 bwBytes = (dlSf->bw-1)/8; + RgrLoadInfIndInfo *rgrLoadInf; + U16 len; + U16 ret = ROK; + + TRC2(rgSCHCmnNonDlfsDsfrRntpComp); + + len = (dlSf->bw % 8 == 0) ? dlSf->bw/8 : dlSf->bw/8 + 1; + + /* RNTP info is ORed every TTI and the sample is stored in cell control block */ + for(i = 0; i <= bwBytes; i++) + { + cell->rntpAggrInfo.val[i] |= dlSf->rntpInfo.val[i]; + } + samples = samples + 1; + /* After every 1000 ms, the RNTP info will be sent to application to be further sent to all neighbouring eNB + informing them about the load indication for cell edge users */ + if(RG_SCH_MAX_RNTP_SAMPLES == samples) + { + /* ccpu00134492 */ + ret = rgSCHUtlAllocSBuf (cell->instIdx,(Data**)&rgrLoadInf, + sizeof(RgrLoadInfIndInfo)); + if (ret != ROK) + { + RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId, "Could not " + "allocate memory for sending LoadInfo"); + RETVOID; + } + + rgrLoadInf->u.rntpInfo.pres = cell->rntpAggrInfo.pres; + /* dsfr_pal_fixes ** 21-March-2013 ** SKS */ + rgrLoadInf->u.rntpInfo.len = len; + + /* dsfr_pal_fixes ** 21-March-2013 ** SKS */ + rgrLoadInf->u.rntpInfo.val = cell->rntpAggrInfo.val; + rgrLoadInf->cellId = cell->cellId; + + /* dsfr_pal_fixes ** 22-March-2013 ** SKS */ + rgrLoadInf->bw = dlSf->bw; + rgrLoadInf->type = RGR_SFR; + + ret = rgSCHUtlRgrLoadInfInd(cell, rgrLoadInf); + if(ret == RFAILED) + { + RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId, "rgSCHCmnNonDlfsDsfrRntpComp():" + "rgSCHUtlRgrLoadInfInd() returned RFAILED"); + } + + cmMemset(cell->rntpAggrInfo.val,0,len); + samples = 0; + } + } +/* LTE_ADV_FLAG_REMOVED_END */ + +/* LTE_ADV_FLAG_REMOVED_START */ +/** + * @brief Performs RB allocation per UE from a pool. + * + * @details + * + * Function : rgSCHCmnSFRNonDlfsUeRbAlloc + * + * Processing Steps: + * - Allocate consecutively available RBs. + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ue + * @param[in] RgSchDlSf *dlSf + * @param[out] U8 *isDlBwAvail + * + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PRIVATE S16 rgSCHCmnSFRNonDlfsUeRbAlloc +( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgSchDlSf *dlSf, +U8 *isDlBwAvail +) +#else +PRIVATE S16 rgSCHCmnSFRNonDlfsUeRbAlloc(cell, ue, dlSf, isDlBwAvail) +RgSchCellCb *cell; +RgSchUeCb *ue; +RgSchDlSf *dlSf; +U8 *isDlBwAvail; +#endif +{ + U32 y; + RgSchDlRbAlloc *allocInfo; + RgSchCmnDlUe *dlUe; + Bool isUECellEdge; + RgSchSFRPoolInfo *sfrpoolInfo = NULLP; + + TRC2(rgSCHCmnSFRNonDlfsUeRbAlloc); + + isUECellEdge = RG_SCH_CMN_IS_UE_CELL_EDGE(ue); + + dlUe = RG_SCH_CMN_GET_DL_UE(ue,cell); + allocInfo = RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ue,cell); + *isDlBwAvail = TRUE; + + /*Find which pool is available for this UE*/ + if (rgSCHCmnNonDlfsSFRBwAvlbl(cell, &sfrpoolInfo, dlSf, allocInfo, isUECellEdge) != TRUE) + { + /* SFR_FIX - If this is CE UE there may be BW available in CC Pool + So CC UEs will be scheduled */ + if (isUECellEdge) + { + *isDlBwAvail = TRUE; + } + else + { + *isDlBwAvail = FALSE; + } + RETVALUE(RFAILED); + } + + if (dlUe->proc->tbInfo[0].isAckNackDtx == TFU_HQFDB_DTX || dlUe->proc->tbInfo[1].isAckNackDtx) + { + allocInfo->pdcch = rgSCHCmnPdcchAlloc(cell, ue, dlSf, dlUe->mimoInfo.cwInfo[0].cqi, allocInfo->dciFormat, TRUE); + } + else + { + allocInfo->pdcch = rgSCHCmnPdcchAlloc(cell, ue, dlSf, dlUe->mimoInfo.cwInfo[0].cqi, allocInfo->dciFormat,FALSE); + } + + if (!(allocInfo->pdcch)) + { + /* Returning ROK since PDCCH might be available for another UE and further allocations could be done */ + RETVALUE(RFAILED); + } + +#ifdef LTEMAC_SPS + allocInfo->rnti = ue->ueId; +#endif + + if (allocInfo->raType == RG_SCH_CMN_RA_TYPE2) + { + allocInfo->allocInfo.raType2.isLocal = TRUE; + /* rg004.201 patch - ccpu00109921 fix end */ + /* MS_FIX for ccpu00123918*/ + allocInfo->allocInfo.raType2.rbStart = (U8)sfrpoolInfo->type2Start; + allocInfo->allocInfo.raType2.numRb = allocInfo->rbsReq; + /* rg007.201 - Changes for MIMO feature addition */ + /* rg008.201 - Removed dependency on MIMO compile-time flag */ + rgSCHCmnNonDlfsUpdSFRPoolTyp2Alloc(cell, ue, dlSf, sfrpoolInfo, \ + allocInfo->allocInfo.raType2.rbStart, \ + allocInfo->allocInfo.raType2.numRb); + allocInfo->rbsAlloc = allocInfo->rbsReq; + allocInfo->tbInfo[0].bytesAlloc = allocInfo->tbInfo[0].bytesReq; + } + else if (allocInfo->raType == RG_SCH_CMN_RA_TYPE0) + { + rgSCHCmnNonDlfsSFRPoolType0Alloc(cell, dlSf, sfrpoolInfo, allocInfo); + } +#ifndef LTE_TDD +#ifdef DEBUGP + rgSCHCmnFindCodeRate(cell,dlSf,allocInfo,0); + if(allocInfo->tbInfo[1].schdlngForTb == TRUE) + { + rgSCHCmnFindCodeRate(cell,dlSf,allocInfo,1); + } +#endif +#endif + +#if defined(LTEMAC_SPS) + /* Update the sub-frame with new allocation */ + dlSf->bwAlloced += allocInfo->rbsReq; +#endif + + RETVALUE(ROK); +} +/* LTE_ADV_FLAG_REMOVED_END */ +#endif /* LTE_TDD */ + +/** + * @brief Performs RB allocation per UE for frequency non-selective cell. + * + * @details + * + * Function : rgSCHCmnNonDlfsUeRbAlloc + * + * Processing Steps: + * - Allocate consecutively available RBs. + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ue + * @param[in] RgSchDlSf *dlSf + * @param[out] U8 *isDlBwAvail + * + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PRIVATE S16 rgSCHCmnNonDlfsUeRbAlloc +( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgSchDlSf *dlSf, +U8 *isDlBwAvail +) +#else +PRIVATE S16 rgSCHCmnNonDlfsUeRbAlloc(cell, ue, dlSf, isDlBwAvail) +RgSchCellCb *cell; +RgSchUeCb *ue; +RgSchDlSf *dlSf; +U8 *isDlBwAvail; +#endif +{ + RgSchDlRbAlloc *allocInfo; + RgSchCmnDlUe *dlUe; +#ifdef LAA_DBG + U32 dbgRbsReq = 0; +#endif + TRC2(rgSCHCmnNonDlfsUeRbAlloc); + +#ifdef RG_5GTF + RgSch5gtfUeCb *ue5gtfCb = &(ue->ue5gtfCb); + RgSchSfBeamInfo *beamInfo = &(dlSf->sfBeamInfo[ue5gtfCb->BeamId]); +#endif + dlUe = RG_SCH_CMN_GET_DL_UE(ue,cell); + allocInfo = RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ue,cell); + *isDlBwAvail = TRUE; + + if(beamInfo->totVrbgAllocated > MAX_5GTF_VRBG) + { + RLOG_ARG1(L_ERROR ,DBG_CELLID,cell->cellId, + "5GTF_ERROR : vrbg allocated > 25 :ue (%u)", + ue->ueId); + printf("5GTF_ERROR vrbg allocated > 25\n"); + RETVALUE(RFAILED); + } + + if (dlUe->proc->tbInfo[0].isAckNackDtx == TFU_HQFDB_DTX + || dlUe->proc->tbInfo[1].isAckNackDtx) + { + allocInfo->pdcch = rgSCHCmnPdcchAlloc(cell, ue, dlSf, dlUe->mimoInfo.cwInfo[0].cqi, allocInfo->dciFormat, TRUE); + } + else + { + allocInfo->pdcch = rgSCHCmnPdcchAlloc(cell, ue, dlSf, dlUe->mimoInfo.cwInfo[0].cqi, allocInfo->dciFormat,FALSE); + } + if (!(allocInfo->pdcch)) + { + /* Returning ROK since PDCCH might be available for another UE and + * further allocations could be done */ + RLOG_ARG1(L_ERROR ,DBG_CELLID,cell->cellId, + "5GTF_ERROR : PDCCH allocation failed :ue (%u)", + ue->ueId); + printf("5GTF_ERROR PDCCH allocation failed\n"); + RETVALUE(RFAILED); + } +#ifdef RG_5GTF + //maxPrb = RGSCH_MIN((allocInfo->vrbgReq * MAX_5GTF_VRBG_SIZE), ue5gtfCb->maxPrb); + //maxPrb = RGSCH_MIN(maxPrb, + //((beamInfo->totVrbgAvail - beamInfo->vrbgStart)* MAX_5GTF_VRBG_SIZE))); + //TODO_SID Need to check for vrbg available after scheduling for same beam. + allocInfo->tbInfo[0].tbCb->dlGrnt.vrbgStart = beamInfo->vrbgStart; + allocInfo->tbInfo[0].tbCb->dlGrnt.numVrbg = allocInfo->vrbgReq; + //TODO_SID: Setting for max TP + allocInfo->tbInfo[0].tbCb->dlGrnt.xPDSCHRange = 1; + allocInfo->tbInfo[0].tbCb->dlGrnt.rbAssign = rgSCHCmnCalcRiv(MAX_5GTF_VRBG, + allocInfo->tbInfo[0].tbCb->dlGrnt.vrbgStart, allocInfo->tbInfo[0].tbCb->dlGrnt.numVrbg); + allocInfo->tbInfo[0].tbCb->dlGrnt.SCID = 0; + allocInfo->tbInfo[0].tbCb->dlGrnt.dciFormat = allocInfo->dciFormat; + //Filling temporarily + allocInfo->tbInfo[0].tbCb->dlGrnt.rbStrt = (allocInfo->tbInfo[0].tbCb->dlGrnt.vrbgStart * MAX_5GTF_VRBG_SIZE); + allocInfo->tbInfo[0].tbCb->dlGrnt.numRb = (allocInfo->tbInfo[0].tbCb->dlGrnt.numVrbg * MAX_5GTF_VRBG_SIZE); + + beamInfo->vrbgStart += allocInfo->tbInfo[0].tbCb->dlGrnt.numVrbg; + beamInfo->totVrbgAllocated += allocInfo->tbInfo[0].tbCb->dlGrnt.numVrbg; + allocInfo->tbInfo[0].bytesAlloc = allocInfo->tbInfo[0].bytesReq; +#endif + + RETVALUE(ROK); +} + +#ifdef RGR_V1 +/** + * @brief Performs RB allocation for Msg4 for frequency non-selective cell. + * + * @details + * + * Function : rgSCHCmnNonDlfsCcchSduAlloc + * + * Processing Steps: + * - For each element in the list, Call rgSCHCmnNonDlfsCcchSduRbAlloc(). + * - If allocation is successful, add the ueCb to scheduled list of CCCH + * SDU. + * - else, add UeCb to non-scheduled list. + * + * @param[in] RgSchCellCb *cell + * @param[in, out] RgSchCmnCcchSduRbAlloc *allocInfo + * @param[in] U8 isRetx + * + * @return Void + **/ +#ifdef ANSI +PRIVATE Void rgSCHCmnNonDlfsCcchSduAlloc +( +RgSchCellCb *cell, +RgSchCmnCcchSduRbAlloc *allocInfo, +U8 isRetx +) +#else +PRIVATE Void rgSCHCmnNonDlfsCcchSduAlloc(cell, allocInfo, isRetx) +RgSchCellCb *cell; +RgSchCmnCcchSduRbAlloc *allocInfo; +U8 isRetx; +#endif +{ + S16 ret; + CmLListCp *ccchSduLst = NULLP; + CmLListCp *schdCcchSduLst = NULLP; + CmLListCp *nonSchdCcchSduLst = NULLP; + CmLList *schdLnkNode = NULLP; + CmLList *toBeSchdLnk = NULLP; + RgSchDlSf *dlSf = allocInfo->ccchSduDlSf; + RgSchUeCb *ueCb = NULLP; + RgSchDlHqProcCb *hqP = NULLP; + TRC2(rgSCHCmnNonDlfsCcchSduAlloc); + + if (isRetx) + { + /* Initialize re-transmitting lists */ + ccchSduLst = &(allocInfo->ccchSduRetxLst); + schdCcchSduLst = &(allocInfo->schdCcchSduRetxLst); + nonSchdCcchSduLst = &(allocInfo->nonSchdCcchSduRetxLst); + } + else + { + /* Initialize transmitting lists */ + ccchSduLst = &(allocInfo->ccchSduTxLst); + schdCcchSduLst = &(allocInfo->schdCcchSduTxLst); + nonSchdCcchSduLst = &(allocInfo->nonSchdCcchSduTxLst); + } + + /* Perform allocaations for the list */ + toBeSchdLnk = cmLListFirst(ccchSduLst); + for (; toBeSchdLnk; toBeSchdLnk = toBeSchdLnk->next) + { + hqP = (RgSchDlHqProcCb *)(toBeSchdLnk->node); + ueCb = hqP->hqE->ue; + schdLnkNode = &hqP->schdLstLnk; + RG_SCH_CMN_INIT_SCHD_LNK(schdLnkNode, hqP); + ret = rgSCHCmnNonDlfsCcchSduRbAlloc(cell, ueCb, dlSf); + if (ret != ROK) + { + /* Allocation failed: Add remaining MSG4 nodes to non-scheduled + * list and return */ + do + { + hqP = (RgSchDlHqProcCb *)(toBeSchdLnk->node); + ueCb = hqP->hqE->ue; + schdLnkNode = &hqP->schdLstLnk; + RG_SCH_CMN_INIT_SCHD_LNK(schdLnkNode, hqP); + cmLListAdd2Tail(nonSchdCcchSduLst, schdLnkNode); + toBeSchdLnk = toBeSchdLnk->next; + } while(toBeSchdLnk); + RETVOID; + } + + /* Allocation successful: Add UE to the scheduled list */ + cmLListAdd2Tail(schdCcchSduLst, schdLnkNode); + } + + + RETVOID; +} + +/** + * @brief Performs RB allocation for CcchSdu for frequency non-selective cell. + * + * @details + * + * Function : rgSCHCmnNonDlfsCcchSduRbAlloc + * + * Processing Steps: + * - Fetch PDCCH + * - Allocate consecutively available RBs + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ueCb + * @param[in] RgSchDlSf *dlSf + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PRIVATE S16 rgSCHCmnNonDlfsCcchSduRbAlloc +( +RgSchCellCb *cell, +RgSchUeCb *ueCb, +RgSchDlSf *dlSf +) +#else +PRIVATE S16 rgSCHCmnNonDlfsCcchSduRbAlloc(cell, ueCb, dlSf) +RgSchCellCb *cell; +RgSchUeCb *ueCb; +RgSchDlSf *dlSf; +#endif +{ + RgSchDlRbAlloc *allocInfo; + RgSchCmnDlUe *ueDl = RG_SCH_CMN_GET_DL_UE(ueCb,cell); + + TRC2(rgSCHCmnNonDlfsCcchSduRbAlloc); + + + allocInfo = RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ueCb,cell); + + /* [ccpu00138802]-MOD-If Bw is less than required, return fail + It will be allocated in next TTI */ +#ifdef LTEMAC_SPS + if ((dlSf->spsAllocdBw >= cell->spsBwRbgInfo.numRbs) && + (dlSf->bwAlloced == dlSf->bw)) +#else + if((dlSf->bwAlloced == dlSf->bw) || + (allocInfo->rbsReq > (dlSf->bw - dlSf->bwAlloced))) +#endif + { + RETVALUE(RFAILED); + } + /* Retrieve PDCCH */ + /* DTX Changes: One Variable is passed to check whether it is DTX or Not */ + if (ueDl->proc->tbInfo[0].isAckNackDtx == TFU_HQFDB_DTX) + { + /* allocInfo->pdcch = rgSCHCmnPdcchAlloc(cell, dlSf, y, ueDl->cqi, + * TFU_DCI_FORMAT_1A, TRUE);*/ + allocInfo->pdcch = rgSCHCmnPdcchAlloc(cell, ueCb, dlSf, ueDl->mimoInfo.cwInfo[0].cqi, TFU_DCI_FORMAT_1A, TRUE); + } + else + { + allocInfo->pdcch = rgSCHCmnPdcchAlloc(cell, ueCb, dlSf, ueDl->mimoInfo.cwInfo[0].cqi, TFU_DCI_FORMAT_1A, FALSE); + } + if (!(allocInfo->pdcch)) + { + /* Returning RFAILED since PDCCH not available for any CCCH allocations */ + RETVALUE(RFAILED); + } + + /* Update allocation information */ + allocInfo->dciFormat = TFU_DCI_FORMAT_1A; + allocInfo->raType = RG_SCH_CMN_RA_TYPE2; + allocInfo->allocInfo.raType2.isLocal = TRUE; + + /*Fix for ccpu00123918*/ + /* Push this harq process back to the free queue */ + allocInfo->allocInfo.raType2.rbStart = (U8)dlSf->type2Start; + allocInfo->allocInfo.raType2.numRb = allocInfo->rbsReq; + allocInfo->rbsAlloc = allocInfo->rbsReq; + allocInfo->tbInfo[0].bytesAlloc = allocInfo->tbInfo[0].bytesReq; + /* Update the sub-frame with new allocation */ + /* ccpu00129469 */ + /* LTE_ADV_FLAG_REMOVED_START */ +#ifndef LTE_TDD + if (cell->lteAdvCb.sfrCfg.status == RGR_ENABLE) + { + rgSCHCmnNonDlfsSFRCmnChannelUpdTyp2Alloc(cell, dlSf, + allocInfo->allocInfo.raType2.rbStart, + allocInfo->allocInfo.raType2.numRb); + } + else +#endif /* end of ifndef LTE_TDD*/ + { + rgSCHCmnNonDlfsUpdTyp2Alloc(cell, dlSf, + allocInfo->allocInfo.raType2.rbStart, + allocInfo->allocInfo.raType2.numRb); + } + + /* LTE_ADV_FLAG_REMOVED_END */ + /* ccpu00131941 - bwAlloced is updated from SPS bandwidth */ + + + RETVALUE(ROK); +} +#endif + +/** + * @brief Performs RB allocation for Msg4 for frequency non-selective cell. + * + * @details + * + * Function : rgSCHCmnNonDlfsMsg4RbAlloc + * + * Processing Steps: + * - Fetch PDCCH + * - Allocate consecutively available RBs + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchRaCb *raCb + * @param[in] RgSchDlSf *dlSf + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PRIVATE S16 rgSCHCmnNonDlfsMsg4RbAlloc +( +RgSchCellCb *cell, +RgSchRaCb *raCb, +RgSchDlSf *dlSf +) +#else +PRIVATE S16 rgSCHCmnNonDlfsMsg4RbAlloc(cell, raCb, dlSf) +RgSchCellCb *cell; +RgSchRaCb *raCb; +RgSchDlSf *dlSf; +#endif +{ + RgSchDlRbAlloc *allocInfo; + TRC2(rgSCHCmnNonDlfsMsg4RbAlloc); + + + allocInfo = RG_SCH_CMN_GET_ALLOCCB_FRM_RACB(raCb); + +#ifdef RG_5GTF + RgSchSfBeamInfo *beamInfo = &(dlSf->sfBeamInfo[0]); + if(beamInfo->totVrbgAllocated > MAX_5GTF_VRBG) + { + RLOG_ARG1(L_ERROR ,DBG_CELLID,cell->cellId, + "5GTF_ERROR : vrbg allocated > 25 :ue (%u)", + raCb->ue->ueId); + printf("5GTF_ERROR vrbg allocated > 25\n"); + RETVALUE(RFAILED); + } +#endif +#ifdef LTEMAC_SPS + if ((dlSf->spsAllocdBw >= cell->spsBwRbgInfo.numRbs) && + (dlSf->bwAlloced == dlSf->bw)) +#else + if((dlSf->bwAlloced == dlSf->bw) || + (allocInfo->rbsReq > (dlSf->bw - dlSf->bwAlloced))) +#endif + { + + RETVALUE(RFAILED); + } + + /* DTX Changes: One Variable is passed to check whether it is DTX or Not */ + if (raCb->dlHqE->msg4Proc->tbInfo[0].isAckNackDtx == TFU_HQFDB_DTX) + { + allocInfo->pdcch = rgSCHCmnPdcchAlloc(cell, raCb->ue, dlSf, raCb->ccchCqi, TFU_DCI_FORMAT_B1, TRUE); + } + else + { + allocInfo->pdcch = rgSCHCmnPdcchAlloc(cell, raCb->ue, dlSf, raCb->ccchCqi, TFU_DCI_FORMAT_B1, FALSE); + } + if (!(allocInfo->pdcch)) + { + /* Returning RFAILED since PDCCH not available for any CCCH allocations */ + RETVALUE(RFAILED); + } + +#ifndef RG_5GTF + /* SR_RACH_STATS : MSG4 TX Failed */ + allocInfo->pdcch->dci.u.format1aInfo.t.pdschInfo.isTBMsg4 = TRUE; + + /* Update allocation information */ + allocInfo->dciFormat = TFU_DCI_FORMAT_1A; + allocInfo->raType = RG_SCH_CMN_RA_TYPE2; + allocInfo->allocInfo.raType2.isLocal = TRUE; + + + /*Fix for ccpu00123918*/ + allocInfo->allocInfo.raType2.rbStart = (U8)dlSf->type2Start; + allocInfo->allocInfo.raType2.numRb = allocInfo->rbsReq; + /* LTE_ADV_FLAG_REMOVED_START */ +#ifndef LTE_TDD + if (cell->lteAdvCb.sfrCfg.status == RGR_ENABLE) + { + rgSCHCmnNonDlfsSFRCmnChannelUpdTyp2Alloc(cell, dlSf, \ + allocInfo->allocInfo.raType2.rbStart, \ + allocInfo->allocInfo.raType2.numRb); + } + else +#endif /* end of ifndef LTE_TDD */ + { + rgSCHCmnNonDlfsUpdTyp2Alloc(cell, dlSf, \ + allocInfo->allocInfo.raType2.rbStart, \ + allocInfo->allocInfo.raType2.numRb); + } + /* LTE_ADV_FLAG_REMOVED_END */ + + allocInfo->rbsAlloc = allocInfo->rbsReq; + allocInfo->tbInfo[0].bytesAlloc = allocInfo->tbInfo[0].bytesReq; + +#else + + allocInfo->pdcch->dci.u.format1aInfo.t.pdschInfo.isTBMsg4 = TRUE; + + allocInfo->tbInfo[0].tbCb->dlGrnt.vrbgStart = beamInfo->vrbgStart; + allocInfo->tbInfo[0].tbCb->dlGrnt.numVrbg = allocInfo->vrbgReq; + + /* Update allocation information */ + allocInfo->dciFormat = TFU_DCI_FORMAT_B1; + + allocInfo->tbInfo[0].tbCb->dlGrnt.xPDSCHRange = 1; + allocInfo->tbInfo[0].tbCb->dlGrnt.rbAssign = rgSCHCmnCalcRiv(MAX_5GTF_VRBG, + allocInfo->tbInfo[0].tbCb->dlGrnt.vrbgStart, allocInfo->tbInfo[0].tbCb->dlGrnt.numVrbg); + + allocInfo->tbInfo[0].tbCb->dlGrnt.rbStrt = (allocInfo->tbInfo[0].tbCb->dlGrnt.vrbgStart * MAX_5GTF_VRBG_SIZE); + allocInfo->tbInfo[0].tbCb->dlGrnt.numRb = (allocInfo->tbInfo[0].tbCb->dlGrnt.numVrbg * MAX_5GTF_VRBG_SIZE); + + + beamInfo->vrbgStart += allocInfo->tbInfo[0].tbCb->dlGrnt.numVrbg; + beamInfo->totVrbgAllocated += allocInfo->tbInfo[0].tbCb->dlGrnt.numVrbg; + allocInfo->tbInfo[0].bytesAlloc = allocInfo->tbInfo[0].bytesReq; + +#endif + + RETVALUE(ROK); +} + +/** + * @brief Performs RB allocation for Msg4 lists of frequency non-selective cell. + * + * @details + * + * Function : rgSCHCmnNonDlfsMsg4Alloc + * + * Processing Steps: + * - For each element in the list, Call rgSCHCmnNonDlfsMsg4RbAlloc(). + * - If allocation is successful, add the raCb to scheduled list of MSG4. + * - else, add RaCb to non-scheduled list. + * + * @param[in] RgSchCellCb *cell + * @param[in, out] RgSchCmnMsg4RbAlloc *allocInfo + * @param[in] U8 isRetx + * + * @return Void + **/ +#ifdef ANSI +PRIVATE Void rgSCHCmnNonDlfsMsg4Alloc +( +RgSchCellCb *cell, +RgSchCmnMsg4RbAlloc *allocInfo, +U8 isRetx +) +#else +PRIVATE Void rgSCHCmnNonDlfsMsg4Alloc(cell, allocInfo, isRetx) +RgSchCellCb *cell; +RgSchCmnMsg4RbAlloc *allocInfo; +U8 isRetx; +#endif +{ + S16 ret; + CmLListCp *msg4Lst = NULLP; + CmLListCp *schdMsg4Lst = NULLP; + CmLListCp *nonSchdMsg4Lst = NULLP; + CmLList *schdLnkNode = NULLP; + CmLList *toBeSchdLnk = NULLP; + RgSchDlSf *dlSf = allocInfo->msg4DlSf; + RgSchRaCb *raCb = NULLP; + RgSchDlHqProcCb *hqP = NULLP; + TRC2(rgSCHCmnNonDlfsMsg4Alloc); + + if (isRetx) + { + /* Initialize re-transmitting lists */ + msg4Lst = &(allocInfo->msg4RetxLst); + schdMsg4Lst = &(allocInfo->schdMsg4RetxLst); + nonSchdMsg4Lst = &(allocInfo->nonSchdMsg4RetxLst); + } + else + { + /* Initialize transmitting lists */ + msg4Lst = &(allocInfo->msg4TxLst); + schdMsg4Lst = &(allocInfo->schdMsg4TxLst); + nonSchdMsg4Lst = &(allocInfo->nonSchdMsg4TxLst); + } + + /* Perform allocaations for the list */ + toBeSchdLnk = cmLListFirst(msg4Lst); + for (; toBeSchdLnk; toBeSchdLnk = toBeSchdLnk->next) + { + hqP = (RgSchDlHqProcCb *)(toBeSchdLnk->node); + raCb = hqP->hqE->raCb; + schdLnkNode = &hqP->schdLstLnk; + RG_SCH_CMN_INIT_SCHD_LNK(schdLnkNode, hqP); + ret = rgSCHCmnNonDlfsMsg4RbAlloc(cell, raCb, dlSf); + if (ret != ROK) + { + /* Allocation failed: Add remaining MSG4 nodes to non-scheduled + * list and return */ + do + { + hqP = (RgSchDlHqProcCb *)(toBeSchdLnk->node); + raCb = hqP->hqE->raCb; + schdLnkNode = &hqP->schdLstLnk; + RG_SCH_CMN_INIT_SCHD_LNK(schdLnkNode, hqP); + cmLListAdd2Tail(nonSchdMsg4Lst, schdLnkNode); + toBeSchdLnk = toBeSchdLnk->next; + } while(toBeSchdLnk); + RETVOID; + } + + /* Allocation successful: Add UE to the scheduled list */ + cmLListAdd2Tail(schdMsg4Lst, schdLnkNode); + if (isRetx) + { + } + } + + + RETVOID; +} + +/** + * @brief Performs RB allocation for the list of UEs of a frequency + * non-selective cell. + * + * @details + * + * Function : rgSCHCmnNonDlfsDedRbAlloc + * + * Processing Steps: + * - For each element in the list, Call rgSCHCmnNonDlfsUeRbAlloc(). + * - If allocation is successful, add the ueCb to scheduled list of UEs. + * - else, add ueCb to non-scheduled list of UEs. + * + * @param[in] RgSchCellCb *cell + * @param[in, out] RgSchCmnUeRbAlloc *allocInfo + * @param[in] CmLListCp *ueLst, + * @param[in, out] CmLListCp *schdHqPLst, + * @param[in, out] CmLListCp *nonSchdHqPLst + * + * @return Void + **/ +#ifdef ANSI +PUBLIC Void rgSCHCmnNonDlfsDedRbAlloc +( +RgSchCellCb *cell, +RgSchCmnUeRbAlloc *allocInfo, +CmLListCp *ueLst, +CmLListCp *schdHqPLst, +CmLListCp *nonSchdHqPLst +) +#else +PUBLIC Void rgSCHCmnNonDlfsDedRbAlloc(cell, allocInfo, ueLst, + schdHqPLst, nonSchdHqPLst) +RgSchCellCb *cell; +RgSchCmnUeRbAlloc *allocInfo; +CmLListCp *ueLst; +CmLListCp *schdHqPLst; +CmLListCp *nonSchdHqPLst; +#endif +{ + S16 ret; + CmLList *schdLnkNode = NULLP; + CmLList *toBeSchdLnk = NULLP; + RgSchDlSf *dlSf = allocInfo->dedDlSf; + RgSchUeCb *ue = NULLP; + RgSchDlHqProcCb *hqP = NULLP; + U8 isDlBwAvail; + TRC2(rgSCHCmnNonDlfsDedRbAlloc); + + + /* Perform allocaations for the list */ + toBeSchdLnk = cmLListFirst(ueLst); + for (; toBeSchdLnk; toBeSchdLnk = toBeSchdLnk->next) + { + hqP = (RgSchDlHqProcCb *)(toBeSchdLnk->node); + ue = hqP->hqE->ue; + schdLnkNode = &hqP->schdLstLnk; + RG_SCH_CMN_INIT_SCHD_LNK(schdLnkNode, hqP); + + ret = rgSCHCmnNonDlfsUeRbAlloc(cell, ue, dlSf, &isDlBwAvail); + if (!isDlBwAvail) + { + /* Allocation failed: Add remaining UEs to non-scheduled + * list and return */ + do + { + hqP = (RgSchDlHqProcCb *)(toBeSchdLnk->node); + ue = hqP->hqE->ue; + schdLnkNode = &hqP->schdLstLnk; + RG_SCH_CMN_INIT_SCHD_LNK(schdLnkNode, hqP); + cmLListAdd2Tail(nonSchdHqPLst, schdLnkNode); + toBeSchdLnk = toBeSchdLnk->next; + } while(toBeSchdLnk); + break; + } + + if (ret == ROK) + { +#if defined (TENB_STATS) && defined (RG_5GTF) + cell->tenbStats->sch.dl5gtfRbAllocPass++; +#endif + /* Allocation successful: Add UE to the scheduled list */ + cmLListAdd2Tail(schdHqPLst, schdLnkNode); + } + else + { +#if defined (TENB_STATS) && defined (RG_5GTF) + cell->tenbStats->sch.dl5gtfRbAllocFail++; +#endif + /* Allocation failed : Add UE to the non-scheduled list */ + printf("5GTF_ERROR Dl rb alloc failed adding nonSchdHqPLst\n"); + cmLListAdd2Tail(nonSchdHqPLst, schdLnkNode); + } + } + + RETVOID; +} + +/** + * @brief Handles RB allocation for frequency non-selective cell. + * + * @details + * + * Function : rgSCHCmnNonDlfsRbAlloc + * + * Invoking Module Processing: + * - SCH shall invoke this if downlink frequency selective is disabled for + * the cell for RB allocation. + * - MAX C/I/PFS/RR shall provide the requiredBytes, required RBs + * estimate and subframe for each allocation to be made to SCH. + * + * Processing Steps: + * - Allocate sequentially for common channels. + * - For transmitting and re-transmitting UE list. + * - For each UE: + * - Perform wide-band allocations for UE in increasing order of + * frequency. + * - Determine Imcs for the allocation. + * - Determine RA type. + * - Determine DCI format. + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchCmnDlRbAllocInfo *allocInfo + * @return Void + **/ + +#ifdef ANSI +PUBLIC Void rgSCHCmnNonDlfsRbAlloc +( +RgSchCellCb *cell, +RgSchCmnDlRbAllocInfo *allocInfo +) +#else +PUBLIC Void rgSCHCmnNonDlfsRbAlloc(cell, allocInfo) +RgSchCellCb *cell; +RgSchCmnDlRbAllocInfo *allocInfo; +#endif +{ + U8 raRspCnt = 0; + RgSchDlRbAlloc *reqAllocInfo; + TRC2(rgSCHCmnNonDlfsRbAlloc); + + /* Allocate for MSG4 retransmissions */ + if (allocInfo->msg4Alloc.msg4RetxLst.count) + { + printf("5GTF_ERROR rgSCHCmnNonDlfsMsg4Alloc RetxLst\n"); + rgSCHCmnNonDlfsMsg4Alloc(cell, &(allocInfo->msg4Alloc), TRUE); + } + + /* Allocate for MSG4 transmissions */ + /* Assuming all the nodes in the list need allocations: rbsReq is valid */ + if (allocInfo->msg4Alloc.msg4TxLst.count) + { + printf("5GTF_ERROR rgSCHCmnNonDlfsMsg4Alloc txLst\n"); + rgSCHCmnNonDlfsMsg4Alloc(cell, &(allocInfo->msg4Alloc), FALSE); + } +#ifdef RGR_V1 + /* Allocate for CCCH SDU (received after guard timer expiry) + * retransmissions */ + if (allocInfo->ccchSduAlloc.ccchSduRetxLst.count) + { + printf("5GTF_ERROR rgSCHCmnNonDlfsCcchSduAlloc\n"); + rgSCHCmnNonDlfsCcchSduAlloc(cell, &(allocInfo->ccchSduAlloc), TRUE); + } + + /* Allocate for CCCD SDU transmissions */ + /* Allocate for CCCH SDU (received after guard timer expiry) transmissions */ + if (allocInfo->ccchSduAlloc.ccchSduTxLst.count) + { + printf("5GTF_ERROR rgSCHCmnNonDlfsCcchSduAlloc\n"); + rgSCHCmnNonDlfsCcchSduAlloc(cell, &(allocInfo->ccchSduAlloc), FALSE); + } +#endif + + /* Allocate for Random access response */ + for (raRspCnt = 0; raRspCnt < RG_SCH_CMN_MAX_CMN_PDCCH; ++raRspCnt) + { + /* Assuming that the requests will be filled in sequentially */ + reqAllocInfo = &(allocInfo->raRspAlloc[raRspCnt]); + if (!reqAllocInfo->rbsReq) + { + break; + } + printf("5GTF_ERROR calling RAR rgSCHCmnNonDlfsCmnRbAlloc\n"); + // if ((rgSCHCmnNonDlfsCmnRbAlloc(cell, reqAllocInfo)) != ROK) + if ((rgSCHCmnNonDlfsCmnRbAllocRar(cell, reqAllocInfo)) != ROK) + { + break; + } + } + + /* Allocate for RETX+TX UEs */ + if(allocInfo->dedAlloc.txRetxHqPLst.count) + { + printf("5GTF_ERROR TX RETX rgSCHCmnNonDlfsDedRbAlloc\n"); + rgSCHCmnNonDlfsDedRbAlloc(cell, &(allocInfo->dedAlloc), + &(allocInfo->dedAlloc.txRetxHqPLst), + &(allocInfo->dedAlloc.schdTxRetxHqPLst), + &(allocInfo->dedAlloc.nonSchdTxRetxHqPLst)); + } + + if((allocInfo->dedAlloc.retxHqPLst.count)) + { + rgSCHCmnNonDlfsDedRbAlloc(cell, &(allocInfo->dedAlloc), + &(allocInfo->dedAlloc.retxHqPLst), + &(allocInfo->dedAlloc.schdRetxHqPLst), + &(allocInfo->dedAlloc.nonSchdRetxHqPLst)); + } + + /* Allocate for transmitting UEs */ + if((allocInfo->dedAlloc.txHqPLst.count)) + { + rgSCHCmnNonDlfsDedRbAlloc(cell, &(allocInfo->dedAlloc), + &(allocInfo->dedAlloc.txHqPLst), + &(allocInfo->dedAlloc.schdTxHqPLst), + &(allocInfo->dedAlloc.nonSchdTxHqPLst)); + } + { + RgSchCmnCell *cmnCell = RG_SCH_CMN_GET_CELL(cell); + if ((allocInfo->dedAlloc.txRetxHqPLst.count + + allocInfo->dedAlloc.retxHqPLst.count + + allocInfo->dedAlloc.txHqPLst.count) > + cmnCell->dl.maxUePerDlSf) + { +#ifndef ALIGN_64BIT + RGSCHDBGERRNEW(cell->instIdx,(rgSchPBuf(cell->instIdx),"UEs selected by" + " scheduler exceed maximumUePerDlSf(%u)tx-retx %ld retx %ld tx %ld\n", + cmnCell->dl.maxUePerDlSf, allocInfo->dedAlloc.txRetxHqPLst.count, + allocInfo->dedAlloc.retxHqPLst.count, + allocInfo->dedAlloc.txHqPLst.count)); +#else + RGSCHDBGERRNEW(cell->instIdx,(rgSchPBuf(cell->instIdx),"UEs selected by" + " scheduler exceed maximumUePerDlSf(%u)tx-retx %d retx %d tx %d\n", + cmnCell->dl.maxUePerDlSf, allocInfo->dedAlloc.txRetxHqPLst.count, + allocInfo->dedAlloc.retxHqPLst.count, + allocInfo->dedAlloc.txHqPLst.count)); +#endif + } + } +#ifndef LTE_TDD + /* LTE_ADV_FLAG_REMOVED_START */ + if(cell->lteAdvCb.dsfrCfg.status == RGR_ENABLE) + { + printf("5GTF_ERROR RETX rgSCHCmnNonDlfsDsfrRntpComp\n"); + rgSCHCmnNonDlfsDsfrRntpComp(cell, allocInfo->dedAlloc.dedDlSf); + } + /* LTE_ADV_FLAG_REMOVED_END */ +#endif /* LTE_TDD */ + RETVOID; +} + +/*********************************************************** + * + * Func : rgSCHCmnCalcRiv + * + * Desc : This function calculates RIV. + * + * Ret : None. + * + * Notes: None. + * + * File : rg_sch_utl.c + * + **********************************************************/ +#ifdef LTEMAC_SPS +#ifdef ANSI +PUBLIC U32 rgSCHCmnCalcRiv +( +U8 bw, +U8 rbStart, +U8 numRb +) +#else +PUBLIC U32 rgSCHCmnCalcRiv(bw, rbStart, numRb) +U8 bw; +U8 rbStart; +U8 numRb; +#endif +#else +#ifdef ANSI +PUBLIC U32 rgSCHCmnCalcRiv +( +U8 bw, +U8 rbStart, +U8 numRb +) +#else +PUBLIC U32 rgSCHCmnCalcRiv(bw, rbStart, numRb) +U8 bw; +U8 rbStart; +U8 numRb; +#endif +#endif +{ + U8 numRbMinus1 = numRb - 1; + U32 riv; + + TRC2(rgSCHCmnCalcRiv); + + if (numRbMinus1 <= bw/2) + { + riv = bw * numRbMinus1 + rbStart; + } + else + { + riv = bw * (bw - numRbMinus1) + (bw - rbStart - 1); + } + RETVALUE(riv); +} /* rgSCHCmnCalcRiv */ + +#ifdef LTE_TDD +/** + * @brief This function allocates and copies the RACH response scheduling + * related information into cell control block. + * + * @details + * + * Function: rgSCHCmnDlCpyRachInfo + * Purpose: This function allocates and copies the RACH response + * scheduling related information into cell control block + * for each DL subframe. + * + * + * Invoked by: Scheduler + * + * @param[in] RgSchCellCb* cell + * @param[in] RgSchTddRachRspLst rachRspLst[][RGSCH_NUM_SUB_FRAMES] + * @param[in] U8 raArrSz + * @return S16 + * + **/ +#ifdef ANSI +PRIVATE S16 rgSCHCmnDlCpyRachInfo +( +RgSchCellCb *cell, +RgSchTddRachRspLst rachRspLst[][RGSCH_NUM_SUB_FRAMES], +U8 raArrSz +) +#else +PRIVATE S16 rgSCHCmnDlCpyRachInfo(cell, rachRspLst, raArrSz) +RgSchCellCb *cell; +RgSchTddRachRspLst rachRspLst[][RGSCH_NUM_SUB_FRAMES]; +U8 raArrSz; +#endif +{ + U8 ulDlCfgIdx = cell->ulDlCfgIdx; + U8 sfNum; + S16 sfnIdx; + U16 subfrmIdx; + U8 numRfs; + U8 numSubfrms; + U8 sfcount; + S16 ret; + + TRC2(rgSCHCmnDlCpyRachInfo); + + /* Allocate RACH response information for each DL + * subframe in a radio frame */ + ret = rgSCHUtlAllocSBuf(cell->instIdx, (Data **)&cell->rachRspLst, + rgSchTddNumDlSubfrmTbl[ulDlCfgIdx][RGSCH_NUM_SUB_FRAMES-1] * + sizeof(RgSchTddRachRspLst)); + if (ret != ROK) + { + RETVALUE(ret); + } + + for(sfnIdx=raArrSz-1; sfnIdx>=0; sfnIdx--) + { + for(subfrmIdx=0; subfrmIdx < RGSCH_NUM_SUB_FRAMES; subfrmIdx++) + { + subfrmIdx = rgSchTddHighDlSubfrmIdxTbl[ulDlCfgIdx][subfrmIdx]; + if(subfrmIdx == RGSCH_NUM_SUB_FRAMES) + { + break; + } + + RGSCH_ARRAY_BOUND_CHECK(cell->instIdx, rachRspLst[sfnIdx],subfrmIdx); + numSubfrms = + rachRspLst[sfnIdx][subfrmIdx].rachRsp[0].numSubfrms; + + RGSCH_ARRAY_BOUND_CHECK(cell->instIdx, rgSchTddNumDlSubfrmTbl[ulDlCfgIdx],subfrmIdx); + sfNum = rgSchTddNumDlSubfrmTbl[ulDlCfgIdx][subfrmIdx]-1; + numRfs = cell->rachRspLst[sfNum].numRadiofrms; + /* For each DL subframe in which RACH response can + * be sent is updated */ + if(numSubfrms > 0) + { + cell->rachRspLst[sfNum].rachRsp[numRfs].sfnOffset = + rachRspLst[sfnIdx][subfrmIdx].rachRsp[0].sfnOffset; + for(sfcount=0; sfcount < numSubfrms; sfcount++) + { + cell->rachRspLst[sfNum].rachRsp[numRfs].\ + subframe[sfcount] = + rachRspLst[sfnIdx][subfrmIdx].rachRsp[0].\ + subframe[sfcount]; + } + cell->rachRspLst[sfNum].rachRsp[numRfs].numSubfrms = + rachRspLst[sfnIdx][subfrmIdx].rachRsp[0].numSubfrms; + cell->rachRspLst[sfNum].numRadiofrms++; + } + + /* Copy the subframes to be deleted at ths subframe */ + numSubfrms = + rachRspLst[sfnIdx][subfrmIdx].delInfo.numSubfrms; + if(numSubfrms > 0) + { + cell->rachRspLst[sfNum].delInfo.sfnOffset = + rachRspLst[sfnIdx][subfrmIdx].delInfo.sfnOffset; + for(sfcount=0; sfcount < numSubfrms; sfcount++) + { + cell->rachRspLst[sfNum].delInfo.subframe[sfcount] = + rachRspLst[sfnIdx][subfrmIdx].delInfo.subframe[sfcount]; + } + cell->rachRspLst[sfNum].delInfo.numSubfrms = + rachRspLst[sfnIdx][subfrmIdx].delInfo.numSubfrms; + } + } + } + RETVALUE(ROK); +} +#endif +/** + * @brief This function determines the iTbs based on the new CFI, + * CQI and BLER based delta iTbs + * + * @details + * + * Function: rgSchCmnFetchItbs + * Purpose: Fetch the new iTbs when CFI changes. + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchCmnDlUe *ueDl + * @param[in] U8 cqi + * + * @return S32 iTbs + * + **/ +#ifdef LTE_TDD +#ifdef ANSI +PRIVATE S32 rgSchCmnFetchItbs +( +RgSchCellCb *cell, +RgSchCmnDlUe *ueDl, +RgSchDlSf *subFrm, +U8 cqi, +U8 cfi, +U8 cwIdx, +U8 noLyr +) +#else +PRIVATE S32 rgSchCmnFetchItbs (cell, ueDl, subFrm, cqi, cfi, cwIdx, noLyr) +RgSchCellCb *cell; +RgSchCmnDlUe *ueDl; +RgSchDlSf *subFrm; +U8 cqi; +U8 cfi; +U8 cwIdx; +U8 noLyr; +#endif +#else +#ifdef ANSI +PRIVATE S32 rgSchCmnFetchItbs +( +RgSchCellCb *cell, +RgSchCmnDlUe *ueDl, +U8 cqi, +U8 cfi, +U8 cwIdx, +U8 noLyr +) +#else +PRIVATE S32 rgSchCmnFetchItbs (cell, ueDl, cqi, cfi, cwIdx, noLyr) +RgSchCellCb *cell; +RgSchCmnDlUe *ueDl; +U8 cqi; +U8 cfi; +U8 cwIdx; +U8 noLyr; +#endif +#endif +{ + + RgSchCmnDlCell *cellDl = RG_SCH_CMN_GET_DL_CELL(cell); + S32 iTbs = 0; + + TRC2(rgSchCmnFetchItbs); + +#ifdef LTE_TDD + /* Special Handling for Spl Sf when CFI is 3 as + * CFI in Spl Sf will be max 2 */ + if(subFrm->sfType == RG_SCH_SPL_SF_DATA) + { + if((cellDl->currCfi == 3) || + ((cell->bwCfg.dlTotalBw <= 10) && (cellDl->currCfi == 1))) + { + /* Use CFI 2 in this case */ + iTbs = (ueDl->laCb[cwIdx].deltaiTbs + + ((*(RgSchCmnCqiToTbs *)(cellDl->cqiToTbsTbl[0][2]))[cqi])* 100)/100; + + RG_SCH_CHK_ITBS_RANGE(iTbs, RGSCH_NUM_ITBS - 1); + } + else + { + iTbs = ueDl->mimoInfo.cwInfo[cwIdx].iTbs[noLyr - 1]; + } + iTbs = RGSCH_MIN(iTbs, cell->thresholds.maxDlItbs); + } + else /* CFI Changed. Update with new iTbs Reset the BLER*/ +#endif + { + S32 tmpiTbs = (*(RgSchCmnCqiToTbs *)(cellDl->cqiToTbsTbl[0][cfi]))[cqi]; + + iTbs = (ueDl->laCb[cwIdx].deltaiTbs + tmpiTbs*100)/100; + + RG_SCH_CHK_ITBS_RANGE(iTbs, tmpiTbs); + + iTbs = RGSCH_MIN(iTbs, cell->thresholds.maxDlItbs); + + ueDl->mimoInfo.cwInfo[cwIdx].iTbs[noLyr - 1] = iTbs; + + ueDl->lastCfi = cfi; + ueDl->laCb[cwIdx].deltaiTbs = 0; + } + + RETVALUE(iTbs); +} + +/** + * @brief This function determines the RBs and Bytes required for BO + * transmission for UEs configured with TM 1/2/6/7. + * + * @details + * + * Function: rgSCHCmnDlAllocTxRb1Tb1Cw + * Purpose: Allocate TB1 on CW1. + * + * Reference Parameter effBo is filled with alloced bytes. + * Returns RFAILED if BO not satisfied at all. + * + * Invoked by: rgSCHCmnDlAllocTxRbTM1/2/6/7 + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchDlSf *subFrm + * @param[in] RgSchUeCb *ue + * @param[in] U32 bo + * @param[out] U32 *effBo + * @param[in] RgSchDlHqProcCb *proc + * @param[out] RgSchCmnDlRbAllocInfo *cellWdAllocInfo + * @return Void + * + **/ +#ifdef ANSI +PRIVATE Void rgSCHCmnDlAllocTxRb1Tb1Cw +( +RgSchCellCb *cell, +RgSchDlSf *subFrm, +RgSchUeCb *ue, +U32 bo, +U32 *effBo, +RgSchDlHqProcCb *proc, +RgSchCmnDlRbAllocInfo *cellWdAllocInfo +) +#else +PRIVATE Void rgSCHCmnDlAllocTxRb1Tb1Cw(cell, subFrm, ue, bo, effBo, proc, cellWdAllocInfo) +RgSchCellCb *cell; +RgSchDlSf *subFrm; +RgSchUeCb *ue; +U32 bo; +U32 *effBo; +RgSchDlHqProcCb *proc; +RgSchCmnDlRbAllocInfo *cellWdAllocInfo; +#endif +{ + RgSchDlRbAlloc *allocInfo; + S16 ret; + U8 numRb; + TRC2(rgSCHCmnDlAllocTxRb1Tb1Cw); + + ret = ROK; + allocInfo = RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ue,cell); +#ifdef RG_5GTF + if (ue->ue5gtfCb.rank == 2) + { + allocInfo->dciFormat = TFU_DCI_FORMAT_B2; + } + else + { + allocInfo->dciFormat = TFU_DCI_FORMAT_B1; + } +#else + allocInfo->dciFormat = rgSCHCmnSlctPdcchFrmt(cell, ue, \ + allocInfo->raType); +#endif + ret = rgSCHCmnDlAlloc1CwTxRb(cell, subFrm, ue, &proc->tbInfo[0],\ + bo, &numRb, effBo); + if (ret == RFAILED) + { + /* If allocation couldn't be made then return */ + RETVOID; + } + /* Adding UE to RbAllocInfo TX Lst */ + rgSCHCmnDlRbInfoAddUeTx(cell, cellWdAllocInfo, ue, proc); + /* Fill UE alloc Info */ + allocInfo->rbsReq = numRb; + allocInfo->dlSf = subFrm; +#ifdef RG_5GTF + allocInfo->vrbgReq = numRb/MAX_5GTF_VRBG_SIZE; +#endif + + RETVOID; +} + + +/** + * @brief This function determines the RBs and Bytes required for BO + * retransmission for UEs configured with TM 1/2/6/7. + * + * @details + * + * Function: rgSCHCmnDlAllocRetxRb1Tb1Cw + * Purpose: Allocate TB1 on CW1. + * + * Reference Parameter effBo is filled with alloced bytes. + * Returns RFAILED if BO not satisfied at all. + * + * Invoked by: rgSCHCmnDlAllocRetxRbTM1/2/6/7 + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchDlSf *subFrm + * @param[in] RgSchUeCb *ue + * @param[in] U32 bo + * @param[out] U32 *effBo + * @param[in] RgSchDlHqProcCb *proc + * @param[out] RgSchCmnDlRbAllocInfo *cellWdAllocInfo + * @return Void + * + **/ +#ifdef ANSI +PRIVATE Void rgSCHCmnDlAllocRetxRb1Tb1Cw +( +RgSchCellCb *cell, +RgSchDlSf *subFrm, +RgSchUeCb *ue, +U32 bo, +U32 *effBo, +RgSchDlHqProcCb *proc, +RgSchCmnDlRbAllocInfo *cellWdAllocInfo +) +#else +PRIVATE Void rgSCHCmnDlAllocRetxRb1Tb1Cw(cell, subFrm, ue, bo, effBo, proc, cellWdAllocInfo) +RgSchCellCb *cell; +RgSchDlSf *subFrm; +RgSchUeCb *ue; +U32 bo; +U32 *effBo; +RgSchDlHqProcCb *proc; +RgSchCmnDlRbAllocInfo *cellWdAllocInfo; +#endif +{ + RgSchDlRbAlloc *allocInfo; + S16 ret; + U8 numRb; + TRC2(rgSCHCmnDlAllocRetxRb1Tb1Cw); + + ret = ROK; + allocInfo = RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ue,cell); + +#ifndef RG_5GTF + /* 5GTF: RETX DCI format same as TX */ + allocInfo->dciFormat = rgSCHCmnSlctPdcchFrmt(cell, ue, \ + &allocInfo->raType); +#endif + + /* Get the Allocation in terms of RBs that are required for + * this retx of TB1 */ + ret = rgSCHCmnDlAlloc1CwRetxRb(cell, subFrm, ue, &proc->tbInfo[0], + 1, &numRb, effBo); + if (ret == RFAILED) + { + /* Allocation couldn't be made for Retx */ + /* Fix : syed If TxRetx allocation failed then add the UE along with the proc + * to the nonSchdTxRetxUeLst and let spfc scheduler take care of it during + * finalization. */ + rgSCHCmnDlAdd2NonSchdRetxLst(cellWdAllocInfo, ue, proc); + RETVOID; + } + rgSCHCmnDlRbInfoAddUeRetx(cell, cellWdAllocInfo, ue, proc); + /* Fill UE alloc Info */ + allocInfo->rbsReq = numRb; + allocInfo->dlSf = subFrm; +#ifdef RG_5GTF + allocInfo->vrbgReq = numRb/MAX_5GTF_VRBG_SIZE; +#endif + + RETVOID; +} + + +/** + * @brief This function determines the RBs and Bytes required for BO + * transmission for UEs configured with TM 2. + * + * @details + * + * Function: rgSCHCmnDlAllocTxRbTM1 + * Purpose: + * + * Reference Parameter effBo is filled with alloced bytes. + * Returns RFAILED if BO not satisfied at all. + * + * Invoked by: rgSCHCmnDlAllocTxRb + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchDlSf *subFrm + * @param[in] RgSchUeCb *ue + * @param[in] U32 bo + * @param[out] U32 *effBo + * @param[in] RgSchDlHqProcCb *proc + * @param[out] RgSchCmnDlRbAllocInfo *cellWdAllocInfo + * @return Void + * + **/ +#ifdef ANSI +PRIVATE Void rgSCHCmnDlAllocTxRbTM1 +( +RgSchCellCb *cell, +RgSchDlSf *subFrm, +RgSchUeCb *ue, +U32 bo, +U32 *effBo, +RgSchDlHqProcCb *proc, +RgSchCmnDlRbAllocInfo *cellWdAllocInfo +) +#else +PRIVATE Void rgSCHCmnDlAllocTxRbTM1(cell, subFrm, ue, bo, effBo, proc, cellWdAllocInfo) +RgSchCellCb *cell; +RgSchDlSf *subFrm; +RgSchUeCb *ue; +U32 bo; +U32 *effBo; +RgSchDlHqProcCb *proc; +RgSchCmnDlRbAllocInfo *cellWdAllocInfo; +#endif +{ + TRC2(rgSCHCmnDlAllocTxRbTM1); + rgSCHCmnDlAllocTxRb1Tb1Cw(cell, subFrm, ue, bo, effBo, proc, cellWdAllocInfo); + RETVOID; +} + + +/** + * @brief This function determines the RBs and Bytes required for BO + * retransmission for UEs configured with TM 2. + * + * @details + * + * Function: rgSCHCmnDlAllocRetxRbTM1 + * Purpose: + * + * Reference Parameter effBo is filled with alloced bytes. + * Returns RFAILED if BO not satisfied at all. + * + * Invoked by: rgSCHCmnDlAllocRetxRb + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchDlSf *subFrm + * @param[in] RgSchUeCb *ue + * @param[in] U32 bo + * @param[out] U32 *effBo + * @param[in] RgSchDlHqProcCb *proc + * @param[out] RgSchCmnDlRbAllocInfo *cellWdAllocInfo + * @return Void + * + **/ +#ifdef ANSI +PRIVATE Void rgSCHCmnDlAllocRetxRbTM1 +( +RgSchCellCb *cell, +RgSchDlSf *subFrm, +RgSchUeCb *ue, +U32 bo, +U32 *effBo, +RgSchDlHqProcCb *proc, +RgSchCmnDlRbAllocInfo *cellWdAllocInfo +) +#else +PRIVATE Void rgSCHCmnDlAllocRetxRbTM1(cell, subFrm, ue, bo, effBo, proc, cellWdAllocInfo) +RgSchCellCb *cell; +RgSchDlSf *subFrm; +RgSchUeCb *ue; +U32 bo; +U32 *effBo; +RgSchDlHqProcCb *proc; +RgSchCmnDlRbAllocInfo *cellWdAllocInfo; +#endif +{ + TRC2(rgSCHCmnDlAllocRetxRbTM1); + rgSCHCmnDlAllocRetxRb1Tb1Cw(cell, subFrm, ue, bo, effBo, proc, cellWdAllocInfo); + RETVOID; +} + + +/** + * @brief This function determines the RBs and Bytes required for BO + * transmission for UEs configured with TM 2. + * + * @details + * + * Function: rgSCHCmnDlAllocTxRbTM2 + * Purpose: + * + * Reference Parameter effBo is filled with alloced bytes. + * Returns RFAILED if BO not satisfied at all. + * + * Invoked by: rgSCHCmnDlAllocTxRb + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchDlSf *subFrm + * @param[in] RgSchUeCb *ue + * @param[in] U32 bo + * @param[out] U32 *effBo + * @param[in] RgSchDlHqProcCb *proc + * @param[out] RgSchCmnDlRbAllocInfo *cellWdAllocInfo + * @return Void + * + **/ +#ifdef ANSI +PRIVATE Void rgSCHCmnDlAllocTxRbTM2 +( +RgSchCellCb *cell, +RgSchDlSf *subFrm, +RgSchUeCb *ue, +U32 bo, +U32 *effBo, +RgSchDlHqProcCb *proc, +RgSchCmnDlRbAllocInfo *cellWdAllocInfo +) +#else +PRIVATE Void rgSCHCmnDlAllocTxRbTM2(cell, subFrm, ue, bo, effBo, proc, cellWdAllocInfo) +RgSchCellCb *cell; +RgSchDlSf *subFrm; +RgSchUeCb *ue; +U32 bo; +U32 *effBo; +RgSchDlHqProcCb *proc; +RgSchCmnDlRbAllocInfo *cellWdAllocInfo; +#endif +{ + TRC2(rgSCHCmnDlAllocTxRbTM2); + rgSCHCmnDlAllocTxRb1Tb1Cw(cell, subFrm, ue, bo, effBo, proc, cellWdAllocInfo); + RETVOID; +} + + +/** + * @brief This function determines the RBs and Bytes required for BO + * retransmission for UEs configured with TM 2. + * + * @details + * + * Function: rgSCHCmnDlAllocRetxRbTM2 + * Purpose: + * + * Reference Parameter effBo is filled with alloced bytes. + * Returns RFAILED if BO not satisfied at all. + * + * Invoked by: rgSCHCmnDlAllocRetxRb + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchDlSf *subFrm + * @param[in] RgSchUeCb *ue + * @param[in] U32 bo + * @param[out] U32 *effBo + * @param[in] RgSchDlHqProcCb *proc + * @param[out] RgSchCmnDlRbAllocInfo *cellWdAllocInfo + * @return Void + * + **/ +#ifdef ANSI +PRIVATE Void rgSCHCmnDlAllocRetxRbTM2 +( +RgSchCellCb *cell, +RgSchDlSf *subFrm, +RgSchUeCb *ue, +U32 bo, +U32 *effBo, +RgSchDlHqProcCb *proc, +RgSchCmnDlRbAllocInfo *cellWdAllocInfo +) +#else +PRIVATE Void rgSCHCmnDlAllocRetxRbTM2(cell, subFrm, ue, bo, effBo, proc, cellWdAllocInfo) +RgSchCellCb *cell; +RgSchDlSf *subFrm; +RgSchUeCb *ue; +U32 bo; +U32 *effBo; +RgSchDlHqProcCb *proc; +RgSchCmnDlRbAllocInfo *cellWdAllocInfo; +#endif +{ + TRC2(rgSCHCmnDlAllocRetxRbTM2); + rgSCHCmnDlAllocRetxRb1Tb1Cw(cell, subFrm, ue, bo, effBo, proc, cellWdAllocInfo); + RETVOID; +} + + +/** + * @brief This function determines the RBs and Bytes required for BO + * transmission for UEs configured with TM 3. + * + * @details + * + * Function: rgSCHCmnDlAllocTxRbTM3 + * Purpose: + * + * Reference Parameter effBo is filled with alloced bytes. + * Returns RFAILED if BO not satisfied at all. + * + * Invoked by: rgSCHCmnDlAllocTxRb + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchDlSf *subFrm + * @param[in] RgSchUeCb *ue + * @param[in] U32 bo + * @param[out] U32 *effBo + * @param[in] RgSchDlHqProcCb *proc + * @param[out] RgSchCmnDlRbAllocInfo *cellWdAllocInfo + * @return Void + * + **/ +#ifdef ANSI +PRIVATE Void rgSCHCmnDlAllocTxRbTM3 +( +RgSchCellCb *cell, +RgSchDlSf *subFrm, +RgSchUeCb *ue, +U32 bo, +U32 *effBo, +RgSchDlHqProcCb *proc, +RgSchCmnDlRbAllocInfo *cellWdAllocInfo +) +#else +PRIVATE Void rgSCHCmnDlAllocTxRbTM3(cell, subFrm, ue, bo, effBo, proc, cellWdAllocInfo) +RgSchCellCb *cell; +RgSchDlSf *subFrm; +RgSchUeCb *ue; +U32 bo; +U32 *effBo; +RgSchDlHqProcCb *proc; +RgSchCmnDlRbAllocInfo *cellWdAllocInfo; +#endif +{ + + TRC2(rgSCHCmnDlAllocTxRbTM3); + + /* Both TBs free for TX allocation */ + rgSCHCmnDlTM3TxTx(cell, subFrm, ue, bo, effBo,\ + proc, cellWdAllocInfo); + + RETVOID; +} + + +/** + * @brief This function determines the RBs and Bytes required for BO + * retransmission for UEs configured with TM 3. + * + * @details + * + * Function: rgSCHCmnDlAllocRetxRbTM3 + * Purpose: + * + * Reference Parameter effBo is filled with alloced bytes. + * Returns RFAILED if BO not satisfied at all. + * + * Invoked by: rgSCHCmnDlAllocRetxRb + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchDlSf *subFrm + * @param[in] RgSchUeCb *ue + * @param[in] U32 bo + * @param[out] U32 *effBo + * @param[in] RgSchDlHqProcCb *proc + * @param[out] RgSchCmnDlRbAllocInfo *cellWdAllocInfo + * @return Void + * + **/ +#ifdef ANSI +PRIVATE Void rgSCHCmnDlAllocRetxRbTM3 +( +RgSchCellCb *cell, +RgSchDlSf *subFrm, +RgSchUeCb *ue, +U32 bo, +U32 *effBo, +RgSchDlHqProcCb *proc, +RgSchCmnDlRbAllocInfo *cellWdAllocInfo +) +#else +PRIVATE Void rgSCHCmnDlAllocRetxRbTM3(cell, subFrm, ue, bo, effBo, proc, cellWdAllocInfo) +RgSchCellCb *cell; +RgSchDlSf *subFrm; +RgSchUeCb *ue; +U32 bo; +U32 *effBo; +RgSchDlHqProcCb *proc; +RgSchCmnDlRbAllocInfo *cellWdAllocInfo; +#endif +{ + + TRC2(rgSCHCmnDlAllocRetxRbTM3); + + if ((proc->tbInfo[0].state == HQ_TB_NACKED) && + (proc->tbInfo[1].state == HQ_TB_NACKED)) + { +#ifdef LAA_DBG_LOG + printf ("RETX RB TM3 nack for both hqp %d cell %d \n", proc->procId, proc->hqE->cell->cellId); +#endif + /* Both TBs require RETX allocation */ + rgSCHCmnDlTM3RetxRetx(cell, subFrm, ue, bo, effBo,\ + proc, cellWdAllocInfo); + } + else + { + /* One of the TBs need RETX allocation. Other TB may/maynot + * be available for new TX allocation. */ + rgSCHCmnDlTM3TxRetx(cell, subFrm, ue, bo, effBo,\ + proc, cellWdAllocInfo); + } + + RETVOID; +} + + +/** + * @brief This function performs the DCI format selection in case of + * Transmit Diversity scheme where there can be more + * than 1 option for DCI format selection. + * + * @details + * + * Function: rgSCHCmnSlctPdcchFrmt + * Purpose: 1. If DLFS is enabled, then choose TM specific + * DCI format for Transmit diversity. All the + * TM Specific DCI Formats support Type0 and/or + * Type1 resource allocation scheme. DLFS + * supports only Type-0&1 Resource allocation. + * 2. If DLFS is not enabled, select a DCI format + * which is of smaller size. Since Non-DLFS + * scheduler supports all Resource allocation + * schemes, selection is based on efficiency. + * + * Invoked by: DL UE Allocation by Common Scheduler. + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ue + * @param[out] U8 *raType + * @return TfuDciFormat + * + **/ +#ifdef ANSI +PUBLIC TfuDciFormat rgSCHCmnSlctPdcchFrmt +( +RgSchCellCb *cell, +RgSchUeCb *ue, +U8 *raType +) +#else +PUBLIC TfuDciFormat rgSCHCmnSlctPdcchFrmt(cell, ue, raType) +RgSchCellCb *cell; +RgSchUeCb *ue; +U8 *raType; +#endif +{ + RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell); + + TRC2(rgSCHCmnSlctPdcchFrmt); + + /* ccpu00140894- Selective DCI Format and RA type should be selected only + * after TX Mode transition is completed*/ + if ((cellSch->dl.isDlFreqSel) && (ue->txModeTransCmplt)) + { + *raType = rgSchCmnDciFrmtOptns[ue->mimoInfo.txMode-1].spfcDciRAType; + RETVALUE(rgSchCmnDciFrmtOptns[ue->mimoInfo.txMode-1].spfcDciFrmt); + } + else + { + *raType = rgSchCmnDciFrmtOptns[ue->mimoInfo.txMode-1].prfrdDciRAType; + RETVALUE(rgSchCmnDciFrmtOptns[ue->mimoInfo.txMode-1].prfrdDciFrmt); + } +} + + +/** + * @brief This function handles Retx allocation in case of TM3 UEs + * where both the TBs were NACKED previously. + * + * @details + * + * Function: rgSCHCmnDlTM3RetxRetx + * Purpose: If forceTD flag enabled + * TD for TB1 on CW1. + * Else + * DCI Frmt 2A and RA Type 0 + * RI layered SM of both TBs on 2 CWs + * Add UE to cell Alloc Info. + * Fill UE alloc Info. + * + * + * Successful allocation is indicated by non-zero effBo value. + * + * Invoked by: rgSCHCmnDlAllocRbTM3 + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchDlSf *subFrm + * @param[in] RgSchUeCb *ue + * @param[in] U32 bo + * @param[out] U32 *effBo + * @param[in] RgSchDlHqProcCb *proc + * @param[out] RgSchCmnDlRbAllocInfo *cellWdAllocInfo + * @return Void + * + **/ +#ifdef ANSI +PRIVATE Void rgSCHCmnDlTM3RetxRetx +( +RgSchCellCb *cell, +RgSchDlSf *subFrm, +RgSchUeCb *ue, +U32 bo, +U32 *effBo, +RgSchDlHqProcCb *proc, +RgSchCmnDlRbAllocInfo *cellWdAllocInfo +) +#else +PRIVATE Void rgSCHCmnDlTM3RetxRetx(cell, subFrm, ue, bo, effBo, proc, cellWdAllocInfo) +RgSchCellCb *cell; +RgSchDlSf *subFrm; +RgSchUeCb *ue; +U32 bo; +U32 *effBo; +RgSchDlHqProcCb *proc; +RgSchCmnDlRbAllocInfo *cellWdAllocInfo; +#endif +{ + S16 ret; + RgSchDlRbAlloc *allocInfo; + U8 numRb; + Bool swpFlg; + U8 precInfo; + U8 noTxLyrs; + U8 precInfoAntIdx; + + TRC2(rgSCHCmnDlTM3RetxRetx); + + ret = ROK; + allocInfo = RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ue,cell); + swpFlg = FALSE; +/* Fix for ccpu00123927: Retransmit 2 codewords irrespective of current rank */ + { + allocInfo->dciFormat = TFU_DCI_FORMAT_2A; + allocInfo->raType = RG_SCH_CMN_RA_TYPE0; + + ret = rgSCHCmnDlAlloc2CwRetxRb(cell, subFrm, ue, proc, &numRb, &swpFlg,\ + effBo); + if (ret == RFAILED) + { + /* Allocation couldn't be made for Retx */ + rgSCHCmnDlAdd2NonSchdRetxLst(cellWdAllocInfo, ue, proc); + RETVOID; + } + /* Fix for ccpu00123927: Retransmit 2 codewords irrespective of current rank */ + noTxLyrs = proc->tbInfo[0].numLyrs + proc->tbInfo[1].numLyrs; +#ifdef FOUR_TX_ANTENNA + /*Chandra: For 4X4 MIM RETX with noTxLyrs=3, CW0 should be 1-LyrTB and CW1 should + * have 2-LyrTB as per Table 6.3.3.2-1 of 36.211 */ + if(noTxLyrs == 3 && proc->tbInfo[0].numLyrs==2) + { + swpFlg = TRUE; + proc->cwSwpEnabled = TRUE; + } +#endif + precInfoAntIdx = cell->numTxAntPorts/2 - 1; + precInfo = (getPrecInfoFunc[0][precInfoAntIdx])(cell, ue, noTxLyrs, TRUE); + } + +#ifdef LTEMAC_SPS + if (!RG_SCH_CMN_SPS_DL_IS_SPS_HQP(proc)) +#endif + { + /* Adding UE to allocInfo RETX Lst */ + rgSCHCmnDlRbInfoAddUeRetx(cell, cellWdAllocInfo, ue, proc); + } + /* Fill UE alloc Info scratch pad */ + RG_SCH_CMN_FILL_DL_TXINFO(allocInfo, numRb, swpFlg, \ + precInfo, noTxLyrs, subFrm); + + RETVOID; +} + + +/** + * @brief This function handles Retx allocation in case of TM4 UEs + * where both the TBs were NACKED previously. + * + * @details + * + * Function: rgSCHCmnDlTM4RetxRetx + * Purpose: If forceTD flag enabled + * TD for TB1 on CW1. + * Else + * DCI Frmt 2 and RA Type 0 + * If RI == 1 + * 1 layer SM of TB1 on CW1. + * Else + * RI layered SM of both TBs on 2 CWs + * Add UE to cell Alloc Info. + * Fill UE alloc Info. + * + * + * Successful allocation is indicated by non-zero effBo value. + * + * Invoked by: rgSCHCmnDlAllocRbTM4 + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchDlSf *subFrm + * @param[in] RgSchUeCb *ue + * @param[in] U32 bo + * @param[out] U32 *effBo + * @param[in] RgSchDlHqProcCb *proc + * @param[out] RgSchCmnDlRbAllocInfo *cellWdAllocInfo + * @return Void + * + **/ +#ifdef ANSI +PRIVATE Void rgSCHCmnDlTM4RetxRetx +( +RgSchCellCb *cell, +RgSchDlSf *subFrm, +RgSchUeCb *ue, +U32 bo, +U32 *effBo, +RgSchDlHqProcCb *proc, +RgSchCmnDlRbAllocInfo *cellWdAllocInfo +) +#else +PRIVATE Void rgSCHCmnDlTM4RetxRetx(cell, subFrm, ue, bo, effBo, proc, cellWdAllocInfo) +RgSchCellCb *cell; +RgSchDlSf *subFrm; +RgSchUeCb *ue; +U32 bo; +U32 *effBo; +RgSchDlHqProcCb *proc; +RgSchCmnDlRbAllocInfo *cellWdAllocInfo; +#endif +{ + S16 ret; + RgSchDlRbAlloc *allocInfo; + U8 numRb; + Bool swpFlg = FALSE; + U8 precInfo; +#ifdef FOUR_TX_ANTENNA + U8 precInfoAntIdx; +#endif + U8 noTxLyrs; + + TRC2(rgSCHCmnDlTM4RetxRetx); + + ret = ROK; + allocInfo = RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ue,cell); + + /* Irrespective of RI Schedule both CWs */ + allocInfo->dciFormat = TFU_DCI_FORMAT_2; + allocInfo->raType = RG_SCH_CMN_RA_TYPE0; + + ret = rgSCHCmnDlAlloc2CwRetxRb(cell, subFrm, ue, proc, &numRb, &swpFlg,\ + effBo); + if (ret == RFAILED) + { + /* Allocation couldn't be made for Retx */ + rgSCHCmnDlAdd2NonSchdRetxLst(cellWdAllocInfo, ue, proc); + RETVOID; + } + noTxLyrs = proc->tbInfo[0].numLyrs + proc->tbInfo[1].numLyrs; + precInfo = 0; +#ifdef FOUR_TX_ANTENNA + /*Chandra: For 4X4 MIM RETX with noTxLyrs=3, CW0 should be 1-LyrTB and CW1 + * should have 2-LyrTB as per Table 6.3.3.2-1 of 36.211 */ + if(noTxLyrs == 3 && proc->tbInfo[0].numLyrs==2) + { + swpFlg = TRUE; + proc->cwSwpEnabled = TRUE; +} +precInfoAntIdx = cell->numTxAntPorts/2 - 1; +precInfo = (getPrecInfoFunc[1][precInfoAntIdx])(cell, ue, noTxLyrs, TRUE); +#endif + +#ifdef LTEMAC_SPS + if (!RG_SCH_CMN_SPS_DL_IS_SPS_HQP(proc)) +#endif + { + /* Adding UE to allocInfo RETX Lst */ + rgSCHCmnDlRbInfoAddUeRetx(cell, cellWdAllocInfo, ue, proc); + } + /* Fill UE alloc Info scratch pad */ + RG_SCH_CMN_FILL_DL_TXINFO(allocInfo, numRb, swpFlg, \ + precInfo, noTxLyrs, subFrm); + + RETVOID; +} + + + +/** + * @brief This function determines Transmission attributes + * incase of Spatial multiplexing for TX and RETX TBs. + * + * @details + * + * Function: rgSCHCmnDlSMGetAttrForTxRetx + * Purpose: 1. Reached here for a TM3/4 UE's HqP whose one of the TBs is + * NACKED and the other TB is either NACKED or WAITING. + * 2. Select the NACKED TB for RETX allocation. + * 3. Allocation preference for RETX TB by mapping it to a better + * CW (better in terms of efficiency). + * 4. Determine the state of the other TB. + * Determine if swapFlag were to be set. + * Swap flag would be set if Retx TB is cross + * mapped to a CW. + * 5. If UE has new data available for TX and if the other TB's state + * is ACKED then set furtherScope as TRUE. + * + * Invoked by: rgSCHCmnDlTM3[4]TxRetx + * + * @param[in] RgSchUeCb *ue + * @param[in] RgSchDlHqProcCb *proc + * @param[out] RgSchDlHqTbCb **retxTb + * @param[out] RgSchDlHqTbCb **txTb + * @param[out] Bool *frthrScp + * @param[out] Bool *swpFlg + * @return Void + * + **/ +#ifdef ANSI +PRIVATE Void rgSCHCmnDlSMGetAttrForTxRetx +( +RgSchUeCb *ue, +RgSchDlHqProcCb *proc, +RgSchDlHqTbCb **retxTb, +RgSchDlHqTbCb **txTb, +Bool *frthrScp, +Bool *swpFlg +) +#else +PRIVATE Void rgSCHCmnDlSMGetAttrForTxRetx(ue, proc, retxTb, txTb, frthrScp,\ + swpFlg) +RgSchUeCb *ue; +RgSchDlHqProcCb *proc; +RgSchDlHqTbCb **retxTb; +RgSchDlHqTbCb **txTb; +Bool *frthrScp; +Bool *swpFlg; +#endif +{ + RgSchCmnDlUe *ueDl = RG_SCH_CMN_GET_DL_UE(ue,proc->hqE->cell); + RgSchDlRbAlloc *allocInfo; + + TRC2(rgSCHCmnDlSMGetAttrForTxRetx); + + if (proc->tbInfo[0].state == HQ_TB_NACKED) + { + *retxTb = &proc->tbInfo[0]; + *txTb = &proc->tbInfo[1]; + /* TENB_BRDCM_TM4- Currently disabling swapflag for TM3/TM4, since + * HqFeedback processing does not consider a swapped hq feedback */ + if ((ue->mimoInfo.txMode == RGR_UE_TM_4) && (ueDl->mimoInfo.btrCwIdx == 1)) + { + *swpFlg = TRUE; + proc->cwSwpEnabled = TRUE; + } + if (proc->tbInfo[1].state == HQ_TB_ACKED) + { + allocInfo = RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ue, proc->hqE->cell); + *frthrScp = allocInfo->mimoAllocInfo.hasNewTxData; + } + } + else + { + *retxTb = &proc->tbInfo[1]; + *txTb = &proc->tbInfo[0]; + /* TENB_BRDCM_TM4 - Currently disabling swapflag for TM3/TM4, since + * HqFeedback processing does not consider a swapped hq feedback */ + if ((ue->mimoInfo.txMode == RGR_UE_TM_4) && (ueDl->mimoInfo.btrCwIdx == 0)) + { + *swpFlg = TRUE; + proc->cwSwpEnabled = TRUE; + } + if (proc->tbInfo[0].state == HQ_TB_ACKED) + { + allocInfo = RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ue, proc->hqE->cell); + *frthrScp = allocInfo->mimoAllocInfo.hasNewTxData; + } + } + RETVOID; +} + + +/** + * @brief Determine Precoding information for TM3 2 TX Antenna. + * + * @details + * + * Function: rgSCHCmnDlTM3PrecInf2 + * Purpose: + * + * Invoked by: rgSCHCmnDlGetAttrForTM3 + * + * @param[in] RgSchUeCb *ue + * @param[in] U8 numTxLyrs + * @param[in] Bool bothCwEnbld + * @return U8 + * + **/ +#ifdef ANSI +PRIVATE U8 rgSCHCmnDlTM3PrecInf2 +( +RgSchCellCb *cell, +RgSchUeCb *ue, +U8 numTxLyrs, +Bool bothCwEnbld +) +#else +PRIVATE U8 rgSCHCmnDlTM3PrecInf2(ue, numTxLyrs, bothCwEnbld) +RgSchCellCb *cell; +RgSchUeCb *ue; +U8 numTxLyrs; +Bool bothCwEnbld; +#endif +{ + TRC2(rgSCHCmnDlTM3PrecInf2); + + RETVALUE(0); +} + + +/** + * @brief Determine Precoding information for TM4 2 TX Antenna. + * + * @details + * + * Function: rgSCHCmnDlTM4PrecInf2 + * Purpose: To determine a logic of deriving precoding index + * information from 36.212 table 5.3.3.1.5-4 + * + * Invoked by: rgSCHCmnDlGetAttrForTM4 + * + * @param[in] RgSchUeCb *ue + * @param[in] U8 numTxLyrs + * @param[in] Bool bothCwEnbld + * @return U8 + * + **/ +#ifdef ANSI +PRIVATE U8 rgSCHCmnDlTM4PrecInf2 +( +RgSchCellCb *cell, +RgSchUeCb *ue, +U8 numTxLyrs, +Bool bothCwEnbld +) +#else +PRIVATE U8 rgSCHCmnDlTM4PrecInf2(ue, numTxLyrs, bothCwEnbld) +RgSchCellCb *cell; +RgSchUeCb *ue; +U8 numTxLyrs; +Bool bothCwEnbld; +#endif +{ + RgSchCmnDlUe *ueDl = RG_SCH_CMN_GET_DL_UE(ue,cell); + U8 precIdx; + + TRC2(rgSCHCmnDlTM4PrecInf2); + + if (ueDl->mimoInfo.ri == numTxLyrs) + { + if (ueDl->mimoInfo.ri == 2) + { + /* PrecInfo corresponding to 2 CW + Transmission */ + if (ue->mimoInfo.puschFdbkVld) + { + precIdx = 2; + } + else + { + precIdx = ueDl->mimoInfo.pmi - 1; + } + } + else + { + /* PrecInfo corresponding to 1 CW + * Transmission */ + if (ue->mimoInfo.puschFdbkVld) + { + precIdx = 5; + } + else + { + precIdx = ueDl->mimoInfo.pmi + 1; + } + } + } + else if (ueDl->mimoInfo.ri > numTxLyrs) + { + /* In case of choosing among the columns of a + * precoding matrix, choose the column corresponding + * to the MAX-CQI */ + if (ue->mimoInfo.puschFdbkVld) + { + precIdx = 5; + } + else + { + precIdx = (ueDl->mimoInfo.pmi- 1)* 2 + 1; + } + } + else /* if RI < numTxLyrs */ + { + precIdx = (ueDl->mimoInfo.pmi < 2)? 0:1; + } + RETVALUE(precIdx); +} + + +/** + * @brief Determine Precoding information for TM3 4 TX Antenna. + * + * @details + * + * Function: rgSCHCmnDlTM3PrecInf4 + * Purpose: To determine a logic of deriving precoding index + * information from 36.212 table 5.3.3.1.5A-2 + * + * Invoked by: rgSCHCmnDlGetAttrForTM3 + * + * @param[in] RgSchUeCb *ue + * @param[in] U8 numTxLyrs + * @param[in] Bool bothCwEnbld + * @return U8 + * + **/ +#ifdef ANSI +PRIVATE U8 rgSCHCmnDlTM3PrecInf4 +( +RgSchCellCb *cell, +RgSchUeCb *ue, +U8 numTxLyrs, +Bool bothCwEnbld +) +#else +PRIVATE U8 rgSCHCmnDlTM3PrecInf4(ue, numTxLyrs, bothCwEnbld) +RgSchCellCb *cell; +RgSchUeCb *ue; +U8 numTxLyrs; +Bool bothCwEnbld; +#endif +{ + U8 precIdx; + + TRC2(rgSCHCmnDlTM3PrecInf4); + + if (bothCwEnbld) + { + precIdx = numTxLyrs - 2; + } + else /* one 1 CW transmission */ + { + precIdx = 1; + } + RETVALUE(precIdx); +} + + +/** + * @brief Determine Precoding information for TM4 4 TX Antenna. + * + * @details + * + * Function: rgSCHCmnDlTM4PrecInf4 + * Purpose: To determine a logic of deriving precoding index + * information from 36.212 table 5.3.3.1.5-5 + * + * Invoked by: rgSCHCmnDlGetAttrForTM4 + * + * @param[in] RgSchUeCb *ue + * @param[in] U8 numTxLyrs + * @param[in] Bool bothCwEnbld + * @return U8 + * + **/ +#ifdef ANSI +PRIVATE U8 rgSCHCmnDlTM4PrecInf4 +( +RgSchCellCb *cell, +RgSchUeCb *ue, +U8 numTxLyrs, +Bool bothCwEnbld +) +#else +PRIVATE U8 rgSCHCmnDlTM4PrecInf4(cell, ue, numTxLyrs, bothCwEnbld) +RgSchCellCb *cell; +RgSchUeCb *ue; +U8 numTxLyrs; +Bool bothCwEnbld; +#endif +{ + RgSchCmnDlUe *ueDl = RG_SCH_CMN_GET_DL_UE(ue,cell); + U8 precInfoBaseIdx, precIdx; + + TRC2(rgSCHCmnDlTM4PrecInf4); + + precInfoBaseIdx = (ue->mimoInfo.puschFdbkVld)? (16): + (ueDl->mimoInfo.pmi); + if (bothCwEnbld) + { + precIdx = precInfoBaseIdx + (numTxLyrs-2)*17; + } + else /* one 1 CW transmission */ + { + precInfoBaseIdx += 1; + precIdx = precInfoBaseIdx + (numTxLyrs-1)*17; + } + RETVALUE(precIdx); +} + + +/** + * @brief This function determines Transmission attributes + * incase of TM3 scheduling. + * + * @details + * + * Function: rgSCHCmnDlGetAttrForTM3 + * Purpose: Determine retx TB and tx TB based on TB states. + * If forceTD enabled + * perform only retx TB allocation. + * If retxTB == TB2 then DCI Frmt = 2A, RA Type = 0. + * Else DCI Frmt and RA Type based on cell->isDlfsEnbld + * If RI == 1 + * perform retxTB allocation on CW1. + * Else if RI > 1 + * Determine further Scope and Swap Flag attributes + * assuming a 2 CW transmission of RetxTB and new Tx TB. + * If no further scope for new TX allocation + * Allocate only retx TB using 2 layers if + * this TB was previously transmitted using 2 layers AND + * number of Tx antenna ports == 4. + * otherwise do single layer precoding. + * + * Invoked by: rgSCHCmnDlTM3TxRetx + * + * @param[in] RgSchUeCb *ue + * @param[in] RgSchDlHqProcCb *proc + * @param[out] U8 *numTxLyrs + * @param[out] Bool *isTraDiv + * @param[out] U8 *prcdngInf + * @param[out] U8 *raType + * @return Void + * + **/ +#ifdef ANSI +PRIVATE Void rgSCHCmnDlGetAttrForTM3 +( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgSchDlHqProcCb *proc, +U8 *numTxLyrs, +TfuDciFormat *dciFrmt, +U8 *prcdngInf, +RgSchDlHqTbCb **retxTb, +RgSchDlHqTbCb **txTb, +Bool *frthrScp, +Bool *swpFlg, +U8 *raType +) +#else +PRIVATE Void rgSCHCmnDlGetAttrForTM3(cell, ue, proc, numTxLyrs, dciFrmt,\ + prcdngInf, retxTb, txTb, frthrScp, swpFlg, raType) +RgSchCellCb *cell; +RgSchUeCb *ue; +RgSchDlHqProcCb *proc; +U8 *numTxLyrs; +TfuDciFormat *dciFrmt; +U8 *prcdngInf; +RgSchDlHqTbCb **retxTb; +RgSchDlHqTbCb **txTb; +Bool *frthrScp; +Bool *swpFlg; +U8 *raType; +#endif +{ + RgSchCmnDlUe *ueDl = RG_SCH_CMN_GET_DL_UE(ue,cell); + U8 precInfoAntIdx; + + TRC2(rgSCHCmnDlGetAttrForTM3); + + /* Avoiding Tx-Retx for LAA cell as firstSchedTime is associated with + HQP */ + /* Integration_fix: SPS Proc shall always have only one Cw */ +#ifdef LTEMAC_SPS + if (((RG_SCH_CMN_SPS_DL_IS_SPS_HQP(proc)) || + (ueDl->mimoInfo.forceTD)) +#ifdef LTE_ADV + ||(TRUE == rgSCHLaaSCellEnabled(cell)) +#endif + ) +#else + if ((ueDl->mimoInfo.forceTD) +#ifdef LTE_ADV + || (TRUE == rgSCHLaaSCellEnabled(cell)) +#endif + ) +#endif + { + /* Transmit Diversity. Format based on dlfsEnabled + * No further scope */ + if (proc->tbInfo[0].state == HQ_TB_NACKED) + { + *retxTb = &proc->tbInfo[0]; + *dciFrmt = rgSCHCmnSlctPdcchFrmt(cell, ue, raType); + } + else + { + *retxTb = &proc->tbInfo[1]; + *dciFrmt = TFU_DCI_FORMAT_2A; + *raType = RG_SCH_CMN_RA_TYPE0; + } + *numTxLyrs = 1; + *frthrScp = FALSE; + *prcdngInf = 0; + RETVOID; + } + + /* Determine the 2 TB transmission attributes */ + rgSCHCmnDlSMGetAttrForTxRetx(ue, proc, retxTb, txTb, \ + frthrScp, swpFlg); + if (*frthrScp) + { + /* Prefer allocation of RETX TB over 2 layers rather than combining + * it with a new TX. */ + if ((ueDl->mimoInfo.ri == 2) + && ((*retxTb)->numLyrs == 2) && (cell->numTxAntPorts == 4)) + { + /* Allocate TB on CW1, using 2 Lyrs, + * Format 2, precoding accordingly */ + *numTxLyrs = 2; + *frthrScp = FALSE; + } + else + { + *numTxLyrs= ((*retxTb)->numLyrs + ueDl->mimoInfo.cwInfo[!(ueDl->mimoInfo.btrCwIdx)].noLyr); + + if((*retxTb)->tbIdx == 0 && ((*retxTb)->numLyrs == 2 ) && *numTxLyrs ==3) + { + *swpFlg = TRUE; + proc->cwSwpEnabled = TRUE; + } + else if((*retxTb)->tbIdx == 1 && ((*retxTb)->numLyrs == 1) && *numTxLyrs ==3) + { + *swpFlg = TRUE; + proc->cwSwpEnabled = TRUE; + } + } + + precInfoAntIdx = cell->numTxAntPorts/2 - 1; + *prcdngInf = (getPrecInfoFunc[0][precInfoAntIdx])\ + (cell, ue, ueDl->mimoInfo.ri, *frthrScp); + *dciFrmt = TFU_DCI_FORMAT_2A; + *raType = RG_SCH_CMN_RA_TYPE0; + } + else /* frthrScp == FALSE */ + { + if (cell->numTxAntPorts == 2) + { + /* Transmit Diversity */ + *numTxLyrs = 1; + if ((*retxTb)->tbIdx == 0) + { + *dciFrmt = rgSCHCmnSlctPdcchFrmt(cell, ue, raType); + } + else + { + /* If retxTB is TB2 then use format 2A */ + *dciFrmt = TFU_DCI_FORMAT_2A; + *raType = RG_SCH_CMN_RA_TYPE0; + } + *prcdngInf = 0; + RETVOID; + } + else /* NumAntPorts == 4 */ + { + if ((*retxTb)->numLyrs == 2) + { + /* Allocate TB on CW1, using 2 Lyrs, + * Format 2A, precoding accordingly */ + *numTxLyrs = 2; + *dciFrmt = TFU_DCI_FORMAT_2A; + *raType = RG_SCH_CMN_RA_TYPE0; + precInfoAntIdx = cell->numTxAntPorts/2 - 1; + *prcdngInf = (getPrecInfoFunc[0][precInfoAntIdx])(cell, ue, *numTxLyrs, *frthrScp); + RETVOID; + } + else + { + /* Transmit Diversity */ + *numTxLyrs = 1; + if ((*retxTb)->tbIdx == 0) + { + *dciFrmt = rgSCHCmnSlctPdcchFrmt(cell, ue, raType); + } + else + { + /* If retxTB is TB2 then use format 2A */ + *dciFrmt = TFU_DCI_FORMAT_2A; + *raType = RG_SCH_CMN_RA_TYPE0; + } + *prcdngInf = 0; + RETVOID; + } + } + } + + RETVOID; +} + + + +/** + * @brief This function determines Transmission attributes + * incase of TM4 scheduling. + * + * @details + * + * Function: rgSCHCmnDlGetAttrForTM4 + * Purpose: Determine retx TB and tx TB based on TB states. + * If forceTD enabled + * perform only retx TB allocation. + * If retxTB == TB2 then DCI Frmt = 2, RA Type = 0. + * Else DCI Frmt and RA Type based on cell->isDlfsEnbld + * If RI == 1 + * perform retxTB allocation on CW1. + * Else if RI > 1 + * Determine further Scope and Swap Flag attributes + * assuming a 2 CW transmission of RetxTB and new Tx TB. + * If no further scope for new TX allocation + * Allocate only retx TB using 2 layers if + * this TB was previously transmitted using 2 layers AND + * number of Tx antenna ports == 4. + * otherwise do single layer precoding. + * + * Invoked by: rgSCHCmnDlTM4TxRetx + * + * @param[in] RgSchUeCb *ue + * @param[in] RgSchDlHqProcCb *proc + * @param[out] U8 *numTxLyrs + * @param[out] Bool *isTraDiv + * @param[out] U8 *prcdngInf + * @param[out] U8 *raType + * @return Void + * + **/ +#ifdef ANSI +PRIVATE Void rgSCHCmnDlGetAttrForTM4 +( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgSchDlHqProcCb *proc, +U8 *numTxLyrs, +TfuDciFormat *dciFrmt, +U8 *prcdngInf, +RgSchDlHqTbCb **retxTb, +RgSchDlHqTbCb **txTb, +Bool *frthrScp, +Bool *swpFlg, +U8 *raType +) +#else +PRIVATE Void rgSCHCmnDlGetAttrForTM4(cell, ue, proc, numTxLyrs, dciFrmt,\ + prcdngInf, retxTb, txTb, frthrScp, swpFlg, raType) +RgSchCellCb *cell; +RgSchUeCb *ue; +RgSchDlHqProcCb *proc; +U8 *numTxLyrs; +TfuDciFormat *dciFrmt; +U8 *prcdngInf; +RgSchDlHqTbCb **retxTb; +RgSchDlHqTbCb **txTb; +Bool *frthrScp; +Bool *swpFlg; +U8 *raType; +#endif +{ + RgSchCmnDlUe *ueDl = RG_SCH_CMN_GET_DL_UE(ue,cell); + U8 precInfoAntIdx; + + TRC2(rgSCHCmnDlGetAttrForTM4); + + *frthrScp = FALSE; + /* Integration_fix: SPS Proc shall always have only one Cw */ +#ifdef LTEMAC_SPS + if (((RG_SCH_CMN_SPS_DL_IS_SPS_HQP(proc)) || + (ueDl->mimoInfo.forceTD)) +#ifdef LTE_ADV + ||(TRUE == rgSCHLaaSCellEnabled(cell)) +#endif + ) +#else + if ((ueDl->mimoInfo.forceTD) +#ifdef LTE_ADV + || (TRUE == rgSCHLaaSCellEnabled(cell)) +#endif + ) +#endif + { + /* Transmit Diversity. Format based on dlfsEnabled + * No further scope */ + if (proc->tbInfo[0].state == HQ_TB_NACKED) + { + *retxTb = &proc->tbInfo[0]; + *dciFrmt = rgSCHCmnSlctPdcchFrmt(cell, ue, raType); + } + else + { + *retxTb = &proc->tbInfo[1]; + *dciFrmt = TFU_DCI_FORMAT_2; + *raType = RG_SCH_CMN_RA_TYPE0; + } + *numTxLyrs = 1; + *frthrScp = FALSE; + *prcdngInf = 0; + RETVOID; + } + + if (ueDl->mimoInfo.ri == 1) + { + /* single layer precoding. Format 2. + * No further scope */ + if (proc->tbInfo[0].state == HQ_TB_NACKED) + { + *retxTb = &proc->tbInfo[0]; + } + else + { + *retxTb = &proc->tbInfo[1]; + } + *numTxLyrs = 1; + *dciFrmt = TFU_DCI_FORMAT_2; + *raType = RG_SCH_CMN_RA_TYPE0; + *frthrScp = FALSE; + *prcdngInf = 0; /*When RI= 1*/ + RETVOID; + } + + /* Determine the 2 TB transmission attributes */ + rgSCHCmnDlSMGetAttrForTxRetx(ue, proc, retxTb, txTb, \ + frthrScp, swpFlg); + *dciFrmt = TFU_DCI_FORMAT_2; + *raType = RG_SCH_CMN_RA_TYPE0; + if (*frthrScp) + { + /* Prefer allocation of RETX TB over 2 layers rather than combining + * it with a new TX. */ + if ((ueDl->mimoInfo.ri == 2) + && ((*retxTb)->numLyrs == 2) && (cell->numTxAntPorts == 4)) + { + /* Allocate TB on CW1, using 2 Lyrs, + * Format 2, precoding accordingly */ + *numTxLyrs = 2; + *frthrScp = FALSE; + } + precInfoAntIdx = cell->numTxAntPorts/2 - 1; + *prcdngInf = (getPrecInfoFunc[1][precInfoAntIdx]) + (cell, ue, ueDl->mimoInfo.ri, *frthrScp); + } + else /* frthrScp == FALSE */ + { + if (cell->numTxAntPorts == 2) + { + /* single layer precoding. Format 2. */ + *numTxLyrs = 1; + *prcdngInf = (getPrecInfoFunc[1][cell->numTxAntPorts/2 - 1])\ + (cell, ue, *numTxLyrs, *frthrScp); + RETVOID; + } + else /* NumAntPorts == 4 */ + { + if ((*retxTb)->numLyrs == 2) + { + /* Allocate TB on CW1, using 2 Lyrs, + * Format 2, precoding accordingly */ + *numTxLyrs = 2; + precInfoAntIdx = cell->numTxAntPorts/2 - 1; + *prcdngInf = (getPrecInfoFunc[1][precInfoAntIdx])\ + (cell, ue, *numTxLyrs, *frthrScp); + RETVOID; + } + else + { + /* Allocate TB with 1 lyr precoding, + * Format 2, precoding info accordingly */ + *numTxLyrs = 1; + precInfoAntIdx = cell->numTxAntPorts/2 - 1; + *prcdngInf = (getPrecInfoFunc[1][precInfoAntIdx])\ + (cell, ue, *numTxLyrs, *frthrScp); + RETVOID; + } + } + } + + RETVOID; +} + + +/** + * @brief This function handles Retx allocation in case of TM3 UEs + * where previously one of the TBs was NACKED and the other + * TB is either ACKED/WAITING. + * + * @details + * + * Function: rgSCHCmnDlTM3TxRetx + * Purpose: Determine the TX attributes for TM3 TxRetx Allocation. + * If futher Scope for New Tx Allocation on other TB + * Perform RETX alloc'n on 1 CW and TX alloc'n on other. + * Add UE to cell wide RetxTx List. + * Else + * Perform only RETX alloc'n on CW1. + * Add UE to cell wide Retx List. + * + * effBo is set to a non-zero value if allocation is + * successful. + * + * Invoked by: rgSCHCmnDlAllocRbTM3 + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchDlSf *subFrm + * @param[in] RgSchUeCb *ue + * @param[in] U32 bo + * @param[out] U32 *effBo + * @param[in] RgSchDlHqProcCb *proc + * @param[out] RgSchCmnDlRbAllocInfo *cellWdAllocInfo + * @return Void + * + **/ +#ifdef ANSI +PRIVATE Void rgSCHCmnDlTM3TxRetx +( +RgSchCellCb *cell, +RgSchDlSf *subFrm, +RgSchUeCb *ue, +U32 bo, +U32 *effBo, +RgSchDlHqProcCb *proc, +RgSchCmnDlRbAllocInfo *cellWdAllocInfo +) +#else +PRIVATE Void rgSCHCmnDlTM3TxRetx(cell, subFrm, ue, bo, effBo, proc, cellWdAllocInfo) +RgSchCellCb *cell; +RgSchDlSf *subFrm; +RgSchUeCb *ue; +U32 bo; +U32 *effBo; +RgSchDlHqProcCb *proc; +RgSchCmnDlRbAllocInfo *cellWdAllocInfo; +#endif +{ + S16 ret; + RgSchDlRbAlloc *allocInfo; + U8 numRb; + RgSchDlHqTbCb *retxTb, *txTb; + Bool frthrScp; + Bool swpFlg; + U8 prcdngInf; + U8 numTxLyrs; + + TRC2(rgSCHCmnDlTM3TxRetx); + frthrScp = FALSE; + + ret = ROK; + allocInfo = RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ue,cell); + swpFlg = FALSE; + + /* Determine the transmission attributes */ + rgSCHCmnDlGetAttrForTM3(cell, ue, proc, &numTxLyrs, &allocInfo->dciFormat,\ + &prcdngInf, &retxTb, &txTb, &frthrScp, &swpFlg,\ + &allocInfo->raType); + + if (frthrScp) + { +#ifdef LAA_DBG_LOG + printf ("TX RETX called from proc %d cell %d \n",proc->procId, cell->cellId); +#endif + ret = rgSCHCmnDlAlloc2CwTxRetxRb(cell, subFrm, ue, retxTb, txTb,\ + &numRb, effBo); + if (ret == RFAILED) + { + /* Allocation couldn't be made for Retx */ + rgSCHCmnDlAdd2NonSchdRetxLst(cellWdAllocInfo, ue, proc); + RETVOID; + } + /* Adding UE to RbAllocInfo RETX-TX Lst */ + rgSCHCmnDlRbInfoAddUeRetxTx(cell, cellWdAllocInfo, ue, proc); + } + else + { + ret = rgSCHCmnDlAlloc1CwRetxRb(cell, subFrm, ue, retxTb, + numTxLyrs, &numRb, effBo); + if (ret == RFAILED) + { + /* Allocation couldn't be made for Retx */ + rgSCHCmnDlAdd2NonSchdRetxLst(cellWdAllocInfo, ue, proc); + RETVOID; + } +#ifdef LTEMAC_SPS + if (!RG_SCH_CMN_SPS_DL_IS_SPS_HQP(proc)) +#endif + { + /* Adding UE to allocInfo RETX Lst */ + rgSCHCmnDlRbInfoAddUeRetx(cell, cellWdAllocInfo, ue, proc); + } + } + RG_SCH_CMN_FILL_DL_TXINFO(allocInfo, numRb, swpFlg, \ + prcdngInf, numTxLyrs, subFrm); + + RETVOID; +} + + +/** + * @brief This function handles Retx allocation in case of TM4 UEs + * where previously one of the TBs was NACKED and the other + * TB is either ACKED/WAITING. + * + * @details + * + * Function: rgSCHCmnDlTM4TxRetx + * Purpose: Determine the TX attributes for TM4 TxRetx Allocation. + * If futher Scope for New Tx Allocation on other TB + * Perform RETX alloc'n on 1 CW and TX alloc'n on other. + * Add UE to cell wide RetxTx List. + * Else + * Perform only RETX alloc'n on CW1. + * Add UE to cell wide Retx List. + * + * effBo is set to a non-zero value if allocation is + * successful. + * + * Invoked by: rgSCHCmnDlAllocRbTM4 + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchDlSf *subFrm + * @param[in] RgSchUeCb *ue + * @param[in] U32 bo + * @param[out] U32 *effBo + * @param[in] RgSchDlHqProcCb *proc + * @param[out] RgSchCmnDlRbAllocInfo *cellWdAllocInfo + * @return Void + * + **/ +#ifdef ANSI +PRIVATE Void rgSCHCmnDlTM4TxRetx +( +RgSchCellCb *cell, +RgSchDlSf *subFrm, +RgSchUeCb *ue, +U32 bo, +U32 *effBo, +RgSchDlHqProcCb *proc, +RgSchCmnDlRbAllocInfo *cellWdAllocInfo +) +#else +PRIVATE Void rgSCHCmnDlTM4TxRetx(cell, subFrm, ue, bo, effBo, proc, cellWdAllocInfo) +RgSchCellCb *cell; +RgSchDlSf *subFrm; +RgSchUeCb *ue; +U32 bo; +U32 *effBo; +RgSchDlHqProcCb *proc; +RgSchCmnDlRbAllocInfo *cellWdAllocInfo; +#endif +{ + S16 ret; + RgSchDlRbAlloc *allocInfo; + U8 numRb; + RgSchDlHqTbCb *retxTb, *txTb; + Bool frthrScp; + Bool swpFlg; + U8 prcdngInf; + U8 numTxLyrs; + + TRC2(rgSCHCmnDlTM4TxRetx); + + ret = ROK; + allocInfo = RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ue,cell); + swpFlg = FALSE; + + /* Determine the transmission attributes */ + rgSCHCmnDlGetAttrForTM4(cell, ue, proc, &numTxLyrs, &allocInfo->dciFormat,\ + &prcdngInf, &retxTb, &txTb, &frthrScp, &swpFlg,\ + &allocInfo->raType); + + if (frthrScp) + { + ret = rgSCHCmnDlAlloc2CwTxRetxRb(cell, subFrm, ue, retxTb, txTb,\ + &numRb, effBo); + if (ret == RFAILED) + { + /* Fix : syed If TxRetx allocation failed then add the UE along + * with the proc to the nonSchdTxRetxUeLst and let spfc scheduler + * take care of it during finalization. */ + rgSCHCmnDlAdd2NonSchdRetxLst(cellWdAllocInfo, ue, proc); + RETVOID; + } + /* Adding UE to RbAllocInfo RETX-TX Lst */ + rgSCHCmnDlRbInfoAddUeRetxTx(cell, cellWdAllocInfo, ue, proc); + } + else + { + ret = rgSCHCmnDlAlloc1CwRetxRb(cell, subFrm, ue, retxTb, + numTxLyrs, &numRb, effBo); + if (ret == RFAILED) + { + /* Allocation couldn't be made for Retx */ + rgSCHCmnDlAdd2NonSchdRetxLst(cellWdAllocInfo, ue, proc); + RETVOID; + } +#ifdef LTEMAC_SPS + if (!RG_SCH_CMN_SPS_DL_IS_SPS_HQP(proc)) +#endif + { + /* Adding UE to allocInfo RETX Lst */ + rgSCHCmnDlRbInfoAddUeRetx(cell, cellWdAllocInfo, ue, proc); + } + } + RG_SCH_CMN_FILL_DL_TXINFO(allocInfo, numRb, swpFlg, \ + prcdngInf, numTxLyrs, subFrm) + + RETVOID; +} + + +/** + * @brief This function handles Retx allocation in case of TM4 UEs + * where previously both the TBs were ACKED and ACKED + * respectively. + * + * @details + * + * Function: rgSCHCmnDlTM3TxTx + * Purpose: Reached here for a TM3 UE's HqP's fresh allocation + * where both the TBs are free for TX scheduling. + * If forceTD flag is set + * perform TD on CW1 with TB1. + * precInfo = 0 + * else + * DCI Format = 2A. + * RA Type = Type0. + * RI layered precoding 2 TB on 2 CW. + * Set precoding info. + * Add UE to cellAllocInfo. + * Fill ueAllocInfo. + * + * effBo is set to a non-zero value if allocation is + * successful. + * + * Invoked by: rgSCHCmnDlAllocRbTM3 + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchDlSf *subFrm + * @param[in] RgSchUeCb *ue + * @param[in] U32 bo + * @param[out] U32 *effBo + * @param[in] RgSchDlHqProcCb *proc + * @param[out] RgSchCmnDlRbAllocInfo *cellWdAllocInfo + * @return Void + * + **/ +#ifdef ANSI +PRIVATE Void rgSCHCmnDlTM3TxTx +( +RgSchCellCb *cell, +RgSchDlSf *subFrm, +RgSchUeCb *ue, +U32 bo, +U32 *effBo, +RgSchDlHqProcCb *proc, +RgSchCmnDlRbAllocInfo *cellWdAllocInfo +) +#else +PRIVATE Void rgSCHCmnDlTM3TxTx(cell, subFrm, ue, bo, effBo, proc, cellWdAllocInfo) +RgSchCellCb *cell; +RgSchDlSf *subFrm; +RgSchUeCb *ue; +U32 bo; +U32 *effBo; +RgSchDlHqProcCb *proc; +RgSchCmnDlRbAllocInfo *cellWdAllocInfo; +#endif +{ + RgSchCmnDlUe *ueDl; + RgSchDlRbAlloc *allocInfo; + U8 numRb; + U8 noTxLyrs; + U8 precInfo; + S16 ret; + U8 precInfoAntIdx; + + TRC2(rgSCHCmnDlTM3TxTx); + + ret = ROK; + ueDl = RG_SCH_CMN_GET_DL_UE(ue,cell); + allocInfo = RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ue,cell); + + /* Integration_fix: SPS Proc shall always have only one Cw */ +#ifdef LTEMAC_SPS +#ifdef FOUR_TX_ANTENNA + if ((RG_SCH_CMN_SPS_DL_IS_SPS_HQP(proc)) || + (ueDl->mimoInfo.forceTD) || proc->hasDcch) /*Chandra Avoid DCCH to be SM */ +#else + if ((RG_SCH_CMN_SPS_DL_IS_SPS_HQP(proc)) || + (ueDl->mimoInfo.forceTD)) +#endif +#else + if (ueDl->mimoInfo.forceTD) /* Transmit Diversity (TD) */ +#endif + { + allocInfo->dciFormat = rgSCHCmnSlctPdcchFrmt(cell, ue, \ + &allocInfo->raType); + ret = rgSCHCmnDlAlloc1CwTxRb(cell, subFrm, ue, &proc->tbInfo[0],\ + bo, &numRb, effBo); + if (ret == RFAILED) + { + /* If allocation couldn't be made then return */ + RETVOID; + } + noTxLyrs = 1; + precInfo = 0; /* TD */ + } + else /* Precoding */ + { + allocInfo->dciFormat = TFU_DCI_FORMAT_2A; + allocInfo->raType = RG_SCH_CMN_RA_TYPE0; + + /* Spatial Multiplexing using 2 CWs */ + ret = rgSCHCmnDlAlloc2CwTxRb(cell, subFrm, ue, proc, bo, &numRb, effBo); + if (ret == RFAILED) + { + /* If allocation couldn't be made then return */ + RETVOID; + } + noTxLyrs = ueDl->mimoInfo.ri; + precInfoAntIdx = cell->numTxAntPorts/2 - 1; + RGSCH_ARRAY_BOUND_CHECK(cell->instIdx, getPrecInfoFunc[0], precInfoAntIdx); + precInfo = (getPrecInfoFunc[0][precInfoAntIdx])(cell, ue, noTxLyrs, TRUE); + } + +#ifdef LTEMAC_SPS + if (!RG_SCH_CMN_SPS_DL_IS_SPS_HQP(proc)) +#endif + { + /* Adding UE to RbAllocInfo TX Lst */ + rgSCHCmnDlRbInfoAddUeTx(cell, cellWdAllocInfo, ue, proc); + } + /* Fill UE allocInfo scrath pad */ + RG_SCH_CMN_FILL_DL_TXINFO(allocInfo, numRb, FALSE, \ + precInfo, noTxLyrs, subFrm); + + RETVOID; +} + + +/** + * @brief This function handles Retx allocation in case of TM4 UEs + * where previously both the TBs were ACKED and ACKED + * respectively. + * + * @details + * + * Function: rgSCHCmnDlTM4TxTx + * Purpose: Reached here for a TM4 UE's HqP's fresh allocation + * where both the TBs are free for TX scheduling. + * If forceTD flag is set + * perform TD on CW1 with TB1. + * precInfo = 0 + * else + * DCI Format = 2. + * RA Type = Type0. + * If Rank == 1 + * Single layer precoding of TB1 on CW1. + * Set precoding info. + * else + * RI layered precoding 2 TB on 2 CW. + * Set precoding info. + * Add UE to cellAllocInfo. + * Fill ueAllocInfo. + * + * effBo is set to a non-zero value if allocation is + * successful. + * + * Invoked by: rgSCHCmnDlAllocRbTM4 + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchDlSf *subFrm + * @param[in] RgSchUeCb *ue + * @param[in] U32 bo + * @param[out] U32 *effBo + * @param[in] RgSchDlHqProcCb *proc + * @param[out] RgSchCmnDlRbAllocInfo *cellWdAllocInfo + * @return Void + * + **/ +#ifdef ANSI +PRIVATE Void rgSCHCmnDlTM4TxTx +( +RgSchCellCb *cell, +RgSchDlSf *subFrm, +RgSchUeCb *ue, +U32 bo, +U32 *effBo, +RgSchDlHqProcCb *proc, +RgSchCmnDlRbAllocInfo *cellWdAllocInfo +) +#else +PRIVATE Void rgSCHCmnDlTM4TxTx(cell, subFrm, ue, bo, effBo, proc, cellWdAllocInfo) +RgSchCellCb *cell; +RgSchDlSf *subFrm; +RgSchUeCb *ue; +U32 bo; +U32 *effBo; +RgSchDlHqProcCb *proc; +RgSchCmnDlRbAllocInfo *cellWdAllocInfo; +#endif +{ + RgSchCmnDlUe *ueDl; + RgSchDlRbAlloc *allocInfo; + U8 numRb; + U8 precInfo; + U8 noTxLyrs; + U8 precInfoAntIdx; + S16 ret; + + TRC2(rgSCHCmnDlTM4TxTx); + + ret = ROK; + ueDl = RG_SCH_CMN_GET_DL_UE(ue,cell); + allocInfo = RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ue,cell); + + /* Integration_fix: SPS Proc shall always have only one Cw */ +#ifdef LTEMAC_SPS +#ifdef FOUR_TX_ANTENNA + if ((RG_SCH_CMN_SPS_DL_IS_SPS_HQP(proc)) || + (ueDl->mimoInfo.forceTD) || proc->hasDcch) /*Chandra Avoid DCCH to be SM */ +#else + if ((RG_SCH_CMN_SPS_DL_IS_SPS_HQP(proc)) || + (ueDl->mimoInfo.forceTD)) +#endif +#else + if (ueDl->mimoInfo.forceTD) /* Transmit Diversity (TD) */ +#endif + { + allocInfo->dciFormat = rgSCHCmnSlctPdcchFrmt(cell, ue, \ + &allocInfo->raType); + + ret = rgSCHCmnDlAlloc1CwTxRb(cell, subFrm, ue, &proc->tbInfo[0],\ + bo, &numRb, effBo); + if (ret == RFAILED) + { + /* If allocation couldn't be made then return */ + RETVOID; + } + noTxLyrs = 1; + precInfo = 0; /* TD */ + } + else /* Precoding */ + { + allocInfo->dciFormat = TFU_DCI_FORMAT_2; + allocInfo->raType = RG_SCH_CMN_RA_TYPE0; + + if (ueDl->mimoInfo.ri == 1) + { + /* Single Layer SM using FORMAT 2 */ + ret = rgSCHCmnDlAlloc1CwTxRb(cell, subFrm, ue, &proc->tbInfo[0],\ + bo, &numRb, effBo); + if (ret == RFAILED) + { + /* If allocation couldn't be made then return */ + RETVOID; + } + noTxLyrs = 1; + precInfo = 0; /* PrecInfo as 0 for RI=1*/ + } + else + { + /* Spatial Multiplexing using 2 CWs */ + ret = rgSCHCmnDlAlloc2CwTxRb(cell, subFrm, ue, proc, bo, &numRb, effBo); + if (ret == RFAILED) + { + /* If allocation couldn't be made then return */ + RETVOID; + } + noTxLyrs = ueDl->mimoInfo.ri; + precInfoAntIdx = cell->numTxAntPorts/2 - 1; + precInfo = (getPrecInfoFunc[1][precInfoAntIdx])(cell, ue, noTxLyrs, TRUE); + } + } + + +#ifdef LTEMAC_SPS + if (!RG_SCH_CMN_SPS_DL_IS_SPS_HQP(proc)) +#endif + { + /* Adding UE to RbAllocInfo TX Lst */ + rgSCHCmnDlRbInfoAddUeTx(cell, cellWdAllocInfo, ue, proc); + } + + /* Fill UE allocInfo scrath pad */ + RG_SCH_CMN_FILL_DL_TXINFO(allocInfo, numRb, FALSE, \ + precInfo, noTxLyrs, subFrm); + + RETVOID; +} + + +/** + * @brief This function determines the RBs and Bytes required for BO + * transmission for UEs configured with TM 4. + * + * @details + * + * Function: rgSCHCmnDlAllocTxRbTM4 + * Purpose: Invokes the functionality particular to the + * current state of the TBs of the "proc". + * + * Reference Parameter effBo is filled with alloced bytes. + * Returns RFAILED if BO not satisfied at all. + * + * Invoked by: rgSCHCmnDlAllocTxRb + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchDlSf *subFrm + * @param[in] RgSchUeCb *ue + * @param[in] U32 bo + * @param[out] U32 *effBo + * @param[in] RgSchDlHqProcCb *proc + * @param[out] RgSchCmnDlRbAllocInfo *cellWdAllocInfo + * @return Void + * + **/ +#ifdef ANSI +PRIVATE Void rgSCHCmnDlAllocTxRbTM4 +( +RgSchCellCb *cell, +RgSchDlSf *subFrm, +RgSchUeCb *ue, +U32 bo, +U32 *effBo, +RgSchDlHqProcCb *proc, +RgSchCmnDlRbAllocInfo *cellWdAllocInfo +) +#else +PRIVATE Void rgSCHCmnDlAllocTxRbTM4(cell, subFrm, ue, bo, effBo, proc, cellWdAllocInfo) +RgSchCellCb *cell; +RgSchDlSf *subFrm; +RgSchUeCb *ue; +U32 bo; +U32 *effBo; +RgSchDlHqProcCb *proc; +RgSchCmnDlRbAllocInfo *cellWdAllocInfo; +#endif +{ + TRC2(rgSCHCmnDlAllocTxRbTM4); + + /* Both TBs free for TX allocation */ + rgSCHCmnDlTM4TxTx(cell, subFrm, ue, bo, effBo,\ + proc, cellWdAllocInfo); + + RETVOID; +} + + +/** + * @brief This function determines the RBs and Bytes required for BO + * retransmission for UEs configured with TM 4. + * + * @details + * + * Function: rgSCHCmnDlAllocRetxRbTM4 + * Purpose: Invokes the functionality particular to the + * current state of the TBs of the "proc". + * + * Reference Parameter effBo is filled with alloced bytes. + * Returns RFAILED if BO not satisfied at all. + * + * Invoked by: rgSCHCmnDlAllocRetxRb + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchDlSf *subFrm + * @param[in] RgSchUeCb *ue + * @param[in] U32 bo + * @param[out] U32 *effBo + * @param[in] RgSchDlHqProcCb *proc + * @param[out] RgSchCmnDlRbAllocInfo *cellWdAllocInfo + * @return Void + * + **/ +#ifdef ANSI +PRIVATE Void rgSCHCmnDlAllocRetxRbTM4 +( +RgSchCellCb *cell, +RgSchDlSf *subFrm, +RgSchUeCb *ue, +U32 bo, +U32 *effBo, +RgSchDlHqProcCb *proc, +RgSchCmnDlRbAllocInfo *cellWdAllocInfo +) +#else +PRIVATE Void rgSCHCmnDlAllocRetxRbTM4(cell, subFrm, ue, bo, effBo, proc, cellWdAllocInfo) +RgSchCellCb *cell; +RgSchDlSf *subFrm; +RgSchUeCb *ue; +U32 bo; +U32 *effBo; +RgSchDlHqProcCb *proc; +RgSchCmnDlRbAllocInfo *cellWdAllocInfo; +#endif +{ + TRC2(rgSCHCmnDlAllocRetxRbTM4); + + if ((proc->tbInfo[0].state == HQ_TB_NACKED) && + (proc->tbInfo[1].state == HQ_TB_NACKED)) + { + /* Both TBs require RETX allocation */ + rgSCHCmnDlTM4RetxRetx(cell, subFrm, ue, bo, effBo,\ + proc, cellWdAllocInfo); + } + else + { + /* One of the TBs need RETX allocation. Other TB may/maynot + * be available for new TX allocation. */ + rgSCHCmnDlTM4TxRetx(cell, subFrm, ue, bo, effBo,\ + proc, cellWdAllocInfo); + } + + RETVOID; +} + +#ifdef RG_UNUSED + +/** + * @brief This function determines the RBs and Bytes required for BO + * transmission for UEs configured with TM 5. + * + * @details + * + * Function: rgSCHCmnDlAllocTxRbTM5 + * Purpose: + * + * Reference Parameter effBo is filled with alloced bytes. + * Returns RFAILED if BO not satisfied at all. + * + * Invoked by: rgSCHCmnDlAllocTxRb + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchDlSf *subFrm + * @param[in] RgSchUeCb *ue + * @param[in] U32 bo + * @param[out] U32 *effBo + * @param[in] RgSchDlHqProcCb *proc + * @param[out] RgSchCmnDlRbAllocInfo *cellWdAllocInfo + * @return Void + * + **/ +#ifdef ANSI +PRIVATE Void rgSCHCmnDlAllocTxRbTM5 +( +RgSchCellCb *cell, +RgSchDlSf *subFrm, +RgSchUeCb *ue, +U32 bo, +U32 *effBo, +RgSchDlHqProcCb *proc, +RgSchCmnDlRbAllocInfo *cellWdAllocInfo +) +#else +PRIVATE Void rgSCHCmnDlAllocTxRbTM5(cell, subFrm, ue, bo, effBo, proc, cellWdAllocInfo) +RgSchCellCb *cell; +RgSchDlSf *subFrm; +RgSchUeCb *ue; +U32 bo; +U32 *effBo; +RgSchDlHqProcCb *proc; +RgSchCmnDlRbAllocInfo *cellWdAllocInfo; +#endif +{ + TRC2(rgSCHCmnDlAllocTxRbTM5); +#if (ERRCLASS & ERRCLS_DEBUG) + RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId, "Invalid TM 5 for CRNTI:%d",ue->ueId); +#endif + RETVOID; +} + + +/** + * @brief This function determines the RBs and Bytes required for BO + * retransmission for UEs configured with TM 5. + * + * @details + * + * Function: rgSCHCmnDlAllocRetxRbTM5 + * Purpose: + * + * Reference Parameter effBo is filled with alloced bytes. + * Returns RFAILED if BO not satisfied at all. + * + * Invoked by: rgSCHCmnDlAllocRetxRb + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchDlSf *subFrm + * @param[in] RgSchUeCb *ue + * @param[in] U32 bo + * @param[out] U32 *effBo + * @param[in] RgSchDlHqProcCb *proc + * @param[out] RgSchCmnDlRbAllocInfo *cellWdAllocInfo + * @return Void + * + **/ +#ifdef ANSI +PRIVATE Void rgSCHCmnDlAllocRetxRbTM5 +( +RgSchCellCb *cell, +RgSchDlSf *subFrm, +RgSchUeCb *ue, +U32 bo, +U32 *effBo, +RgSchDlHqProcCb *proc, +RgSchCmnDlRbAllocInfo *cellWdAllocInfo +) +#else +PRIVATE Void rgSCHCmnDlAllocRetxRbTM5(cell, subFrm, ue, bo, effBo, proc, cellWdAllocInfo) +RgSchCellCb *cell; +RgSchDlSf *subFrm; +RgSchUeCb *ue; +U32 bo; +U32 *effBo; +RgSchDlHqProcCb *proc; +RgSchCmnDlRbAllocInfo *cellWdAllocInfo; +#endif +{ + TRC2(rgSCHCmnDlAllocRetxRbTM5); +#if (ERRCLASS & ERRCLS_DEBUG) + RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId, "Invalid TM 5 for CRNTI:%d",ue->ueId); +#endif + RETVOID; +} +#endif + + +/** + * @brief This function determines the RBs and Bytes required for BO + * transmission for UEs configured with TM 6. + * + * @details + * + * Function: rgSCHCmnDlAllocTxRbTM6 + * Purpose: + * + * Reference Parameter effBo is filled with alloced bytes. + * Returns RFAILED if BO not satisfied at all. + * + * Invoked by: rgSCHCmnDlAllocTxRb + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchDlSf *subFrm + * @param[in] RgSchUeCb *ue + * @param[in] U32 bo + * @param[out] U32 *effBo + * @param[in] RgSchDlHqProcCb *proc + * @param[out] RgSchCmnDlRbAllocInfo *cellWdAllocInfo + * @return Void + * + **/ +#ifdef ANSI +PRIVATE Void rgSCHCmnDlAllocTxRbTM6 +( +RgSchCellCb *cell, +RgSchDlSf *subFrm, +RgSchUeCb *ue, +U32 bo, +U32 *effBo, +RgSchDlHqProcCb *proc, +RgSchCmnDlRbAllocInfo *cellWdAllocInfo +) +#else +PRIVATE Void rgSCHCmnDlAllocTxRbTM6(cell, subFrm, ue, bo, effBo, proc, cellWdAllocInfo) +RgSchCellCb *cell; +RgSchDlSf *subFrm; +RgSchUeCb *ue; +U32 bo; +U32 *effBo; +RgSchDlHqProcCb *proc; +RgSchCmnDlRbAllocInfo *cellWdAllocInfo; +#endif +{ + RgSchDlRbAlloc *allocInfo; + RgSchCmnDlUe *ueDl; + S16 ret; + U8 numRb; + + TRC2(rgSCHCmnDlAllocTxRbTM6); + + ret = ROK; + ueDl = RG_SCH_CMN_GET_DL_UE(ue,cell); + allocInfo = RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ue,cell); + + if (ueDl->mimoInfo.forceTD) + { + allocInfo->dciFormat = TFU_DCI_FORMAT_1A; + allocInfo->raType = RG_SCH_CMN_RA_TYPE2; + } + else + { + allocInfo->dciFormat = TFU_DCI_FORMAT_1B; + allocInfo->raType = RG_SCH_CMN_RA_TYPE2; + /* Fill precoding information for FORMAT 1B */ + /* First 4 least significant bits to indicate PMI. + * 4th most significant corresponds to pmi Confirmation. + */ + allocInfo->mimoAllocInfo.precIdxInfo |= ue->mimoInfo.puschFdbkVld << 4; + allocInfo->mimoAllocInfo.precIdxInfo |= ueDl->mimoInfo.pmi; + } + ret = rgSCHCmnDlAlloc1CwTxRb(cell, subFrm, ue, &proc->tbInfo[0],\ + bo, &numRb, effBo); + if (ret == RFAILED) + { + /* If allocation couldn't be made then return */ + RETVOID; + } + +#ifdef LTEMAC_SPS + if (!RG_SCH_CMN_SPS_DL_IS_SPS_HQP(proc)) +#endif + { + /* Adding UE to RbAllocInfo TX Lst */ + rgSCHCmnDlRbInfoAddUeTx(cell, cellWdAllocInfo, ue, proc); + } + /* Fill UE alloc Info */ + allocInfo->rbsReq = numRb; + allocInfo->dlSf = subFrm; + RETVOID; +} + + +/** + * @brief This function determines the RBs and Bytes required for BO + * retransmission for UEs configured with TM 6. + * + * @details + * + * Function: rgSCHCmnDlAllocRetxRbTM6 + * Purpose: + * + * Reference Parameter effBo is filled with alloced bytes. + * Returns RFAILED if BO not satisfied at all. + * + * Invoked by: rgSCHCmnDlAllocRetxRb + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchDlSf *subFrm + * @param[in] RgSchUeCb *ue + * @param[in] U32 bo + * @param[out] U32 *effBo + * @param[in] RgSchDlHqProcCb *proc + * @param[out] RgSchCmnDlRbAllocInfo *cellWdAllocInfo + * @return Void + * + **/ +#ifdef ANSI +PRIVATE Void rgSCHCmnDlAllocRetxRbTM6 +( +RgSchCellCb *cell, +RgSchDlSf *subFrm, +RgSchUeCb *ue, +U32 bo, +U32 *effBo, +RgSchDlHqProcCb *proc, +RgSchCmnDlRbAllocInfo *cellWdAllocInfo +) +#else +PRIVATE Void rgSCHCmnDlAllocRetxRbTM6(cell, subFrm, ue, bo, effBo, proc, cellWdAllocInfo) +RgSchCellCb *cell; +RgSchDlSf *subFrm; +RgSchUeCb *ue; +U32 bo; +U32 *effBo; +RgSchDlHqProcCb *proc; +RgSchCmnDlRbAllocInfo *cellWdAllocInfo; +#endif +{ + RgSchDlRbAlloc *allocInfo; + RgSchCmnDlUe *ueDl; + S16 ret; + U8 numRb; + + TRC2(rgSCHCmnDlAllocRetxRbTM6); + + ret = ROK; + allocInfo = RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ue,cell); + ueDl = RG_SCH_CMN_GET_DL_UE(ue,cell); + + if (ueDl->mimoInfo.forceTD) + { + allocInfo->dciFormat = TFU_DCI_FORMAT_1A; + allocInfo->raType = RG_SCH_CMN_RA_TYPE2; + } + else + { + allocInfo->dciFormat = TFU_DCI_FORMAT_1B; + allocInfo->raType = RG_SCH_CMN_RA_TYPE2; + /* Fill precoding information for FORMAT 1B */ + /* First 4 least significant bits to indicate PMI. + * 4th most significant corresponds to pmi Confirmation. + */ + allocInfo->mimoAllocInfo.precIdxInfo |= ue->mimoInfo.puschFdbkVld << 4; + allocInfo->mimoAllocInfo.precIdxInfo |= ueDl->mimoInfo.pmi; + } + + /* Get the Allocation in terms of RBs that are required for + * this retx of TB1 */ + ret = rgSCHCmnDlAlloc1CwRetxRb(cell, subFrm, ue, &proc->tbInfo[0], + 1, &numRb, effBo); + if (ret == RFAILED) + { + /* Allocation couldn't be made for Retx */ + rgSCHCmnDlAdd2NonSchdRetxLst(cellWdAllocInfo, ue, proc); + RETVOID; + } + /* Adding UE to allocInfo RETX Lst */ + rgSCHCmnDlRbInfoAddUeRetx(cell, cellWdAllocInfo, ue, proc); + /* Fill UE alloc Info */ + allocInfo->rbsReq = numRb; + allocInfo->dlSf = subFrm; + RETVOID; +} + + +/** + * @brief This function determines the RBs and Bytes required for BO + * transmission for UEs configured with TM 7. + * + * @details + * + * Function: rgSCHCmnDlAllocTxRbTM7 + * Purpose: + * + * Reference Parameter effBo is filled with alloced bytes. + * Returns RFAILED if BO not satisfied at all. + * + * Invoked by: rgSCHCmnDlAllocTxRb + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchDlSf *subFrm + * @param[in] RgSchUeCb *ue + * @param[in] U32 bo + * @param[out] U32 *effBo + * @param[in] RgSchDlHqProcCb *proc + * @param[out] RgSchCmnDlRbAllocInfo *cellWdAllocInfo + * @return Void + * + **/ +#ifdef ANSI +PRIVATE Void rgSCHCmnDlAllocTxRbTM7 +( +RgSchCellCb *cell, +RgSchDlSf *subFrm, +RgSchUeCb *ue, +U32 bo, +U32 *effBo, +RgSchDlHqProcCb *proc, +RgSchCmnDlRbAllocInfo *cellWdAllocInfo +) +#else +PRIVATE Void rgSCHCmnDlAllocTxRbTM7(cell, subFrm, ue, bo, effBo, proc, cellWdAllocInfo) +RgSchCellCb *cell; +RgSchDlSf *subFrm; +RgSchUeCb *ue; +U32 bo; +U32 *effBo; +RgSchDlHqProcCb *proc; +RgSchCmnDlRbAllocInfo *cellWdAllocInfo; +#endif +{ + TRC2(rgSCHCmnDlAllocTxRbTM7); + rgSCHCmnDlAllocTxRb1Tb1Cw(cell, subFrm, ue, bo, effBo, proc, cellWdAllocInfo); + RETVOID; +} + + +/** + * @brief This function determines the RBs and Bytes required for BO + * retransmission for UEs configured with TM 7. + * + * @details + * + * Function: rgSCHCmnDlAllocRetxRbTM7 + * Purpose: + * + * Reference Parameter effBo is filled with alloced bytes. + * Returns RFAILED if BO not satisfied at all. + * + * Invoked by: rgSCHCmnDlAllocRetxRb + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchDlSf *subFrm + * @param[in] RgSchUeCb *ue + * @param[in] U32 bo + * @param[out] U32 *effBo + * @param[in] RgSchDlHqProcCb *proc + * @param[out] RgSchCmnDlRbAllocInfo *cellWdAllocInfo + * @return Void + * + **/ +#ifdef ANSI +PRIVATE Void rgSCHCmnDlAllocRetxRbTM7 +( +RgSchCellCb *cell, +RgSchDlSf *subFrm, +RgSchUeCb *ue, +U32 bo, +U32 *effBo, +RgSchDlHqProcCb *proc, +RgSchCmnDlRbAllocInfo *cellWdAllocInfo +) +#else +PRIVATE Void rgSCHCmnDlAllocRetxRbTM7(cell, subFrm, ue, bo, effBo, proc, cellWdAllocInfo) +RgSchCellCb *cell; +RgSchDlSf *subFrm; +RgSchUeCb *ue; +U32 bo; +U32 *effBo; +RgSchDlHqProcCb *proc; +RgSchCmnDlRbAllocInfo *cellWdAllocInfo; +#endif +{ + TRC2(rgSCHCmnDlAllocRetxRbTM7); + rgSCHCmnDlAllocRetxRb1Tb1Cw(cell, subFrm, ue, bo, effBo, proc, cellWdAllocInfo); + RETVOID; +} + + +/** + * @brief This function invokes the TM specific DL TX RB Allocation routine. + * + * @details + * + * Function: rgSCHCmnDlAllocTxRb + * Purpose: This function invokes the TM specific + * DL TX RB Allocation routine. + * + * Invoked by: Specific Schedulers + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchDlSf *subFrm + * @param[in] RgSchUeCb *ue + * @param[in] U32 bo + * @param[out] U32 *effBo + * @param[in] RgSchDlHqProcCb *proc + * @param[out] RgSchCmnDlRbAllocInfo *cellWdAllocInfo + * @return S16 + * + **/ +#ifdef ANSI +PUBLIC S16 rgSCHCmnDlAllocTxRb +( +RgSchCellCb *cell, +RgSchDlSf *subFrm, +RgSchUeCb *ue, +U32 bo, +U32 *effBo, +RgSchDlHqProcCb *proc, +RgSchCmnDlRbAllocInfo *cellWdAllocInfo +) +#else +PUBLIC S16 rgSCHCmnDlAllocTxRb(cell, subFrm, ue, bo, effBo, proc, cellWdAllocInfo) +RgSchCellCb *cell; +RgSchDlSf *subFrm; +RgSchUeCb *ue; +U32 bo; +U32 *effBo; +RgSchDlHqProcCb *proc; +RgSchCmnDlRbAllocInfo *cellWdAllocInfo; +#endif +{ + U32 newSchBits = 0; + U32 prevSchBits = 0; + RgSchDlRbAlloc *allocInfo; + + TRC2(rgSCHCmnDlAllocTxRb); + + if ( !RGSCH_TIMEINFO_SAME((cell->crntTime),(ue->dl.lstSchTime) )) + { + ue->dl.aggTbBits = 0; + } + *effBo = 0; + + /* Calculate totals bits previously allocated */ + allocInfo = RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ue,cell); + if (allocInfo->tbInfo[0].schdlngForTb) + { + prevSchBits += allocInfo->tbInfo[0].bytesReq; + } + if (allocInfo->tbInfo[1].schdlngForTb) + { + prevSchBits += allocInfo->tbInfo[1].bytesReq; + } + + /* Call TM specific RB allocation routine */ + (dlAllocTxRbFunc[ue->mimoInfo.txMode - 1])(cell, subFrm, ue, bo, effBo, \ + proc, cellWdAllocInfo); + + if (*effBo) + { + /* Calculate totals bits newly allocated */ + if (allocInfo->tbInfo[0].schdlngForTb) + { + newSchBits += allocInfo->tbInfo[0].bytesReq; + } + if (allocInfo->tbInfo[1].schdlngForTb) + { + newSchBits += allocInfo->tbInfo[1].bytesReq; + } + if (newSchBits > prevSchBits) + { + ue->dl.aggTbBits += ((newSchBits - prevSchBits) * 8); + RGSCHCPYTIMEINFO((cell->crntTime),(ue->dl.lstSchTime)) + } + } + + RETVALUE(ROK); +} + +/* DwPTS Scheduling Changes Start */ +#ifdef LTE_TDD +/** + * @brief Retransmit decision for TDD. Retx is avoided in below cases + * 1) DL Sf -> Spl Sf + * 2) DL SF -> DL SF 0 + * + * @details + * + * Function: rgSCHCmnRetxAvoidTdd + * Purpose: Avoid allocating RETX for cases 1, 2 + * + * Invoked by: rgSCHCmnRetxAvoidTdd + * + * @param[in] RgSchDlSf *curSf + * @param[in] RgSchCellCb *cell + * @param[in] RgSchDlHqProcCb *proc + * @return Bool + * + **/ +#ifdef ANSI +PUBLIC Bool rgSCHCmnRetxAvoidTdd +( +RgSchDlSf *curSf, +RgSchCellCb *cell, +RgSchDlHqProcCb *proc +) +#else +PUBLIC Bool rgSCHCmnRetxAvoidTdd(curSf, cell, proc) +RgSchDlSf *curSf; +RgSchCellCb *cell; +RgSchDlHqProcCb *proc; +#endif +{ + RgSchTddSfType txSfType = 0; + + TRC2(rgSCHCmnRetxAvoidTdd); + + /* Get the RBs of TB that will be retransmitted */ + if (proc->tbInfo[0].state == HQ_TB_NACKED) + { + txSfType = proc->tbInfo[0].sfType; + +#ifdef XEON_SPECIFIC_CHANGES +#ifndef XEON_TDD_SPCL + /* Avoid re-transmission on Normal SF when the corresponding TB wss transmitted on SPCL SF */ + if(txSfType <= RG_SCH_SPL_SF_DATA && curSf->sfType >= RG_SCH_DL_SF_0) + { + RETVALUE(TRUE); + } +#endif +#endif + } + if (proc->tbInfo[1].state == HQ_TB_NACKED) + { + /* Select the TxSf with the highest num of possible REs + * In ascending order -> 1) SPL SF 2) DL_SF_0 3) DL_SF */ + txSfType = RGSCH_MAX(txSfType, proc->tbInfo[1].sfType); + +#ifdef XEON_SPECIFIC_CHANGES +#ifndef XEON_TDD_SPCL + /* Avoid re-transmission on Normal SF when the corresponding TB wss tranmitted on SPCL SF */ + if(txSfType <= RG_SCH_SPL_SF_DATA && curSf->sfType >= RG_SCH_DL_SF_0) + { + RETVALUE(TRUE); + } +#endif +#endif + } + + if (txSfType > curSf->sfType) + { + /* Avoid retx */ + RETVALUE(TRUE); + } + + /* Allow Retx */ + RETVALUE(FALSE); +} + +#else +/* DwPTS Scheduling Changes End */ + +/** + * @brief Avoid allocating RETX incase of collision + * with reserved resources for BCH/PSS/SSS occassions. + * + * @details + * + * Function: rgSCHCmnRetxAllocAvoid + * Purpose: Avoid allocating RETX incase of collision + * with reserved resources for BCH/PSS/SSS occassions + * + * Invoked by: rgSCHCmnDlAllocRetxRb + * + * @param[in] RgSchDlSf *subFrm + * @param[in] RgSchUeCb *ue + * @param[in] RgSchDlHqProcCb *proc + * @return Bool + * + **/ +#ifdef ANSI +PUBLIC Bool rgSCHCmnRetxAllocAvoid +( +RgSchDlSf *subFrm, +RgSchCellCb *cell, +RgSchDlHqProcCb *proc +) +#else +PUBLIC Bool rgSCHCmnRetxAllocAvoid(subFrm, cell, proc) +RgSchDlSf *subFrm; +RgSchCellCb *cell; +RgSchDlHqProcCb *proc; +#endif +{ + U8 reqRbs; + + TRC2(rgSCHCmnRetxAllocAvoid); + + if (proc->tbInfo[0].state == HQ_TB_NACKED) + { + reqRbs = proc->tbInfo[0].dlGrnt.numRb; + } + else + { + reqRbs = proc->tbInfo[1].dlGrnt.numRb; + } + /* Consider the dlGrnt.numRb of the Retransmitting proc->tbInfo + * and current available RBs to determine if this RETX TB + * will collide with the BCH/PSS/SSS occassion */ + if (subFrm->sfNum % 5 == 0) + { + if ((subFrm->bwAssigned < cell->pbchRbEnd) && + (((subFrm->bwAssigned + reqRbs) - cell->pbchRbStart) > 0)) + { + RETVALUE(TRUE); + } + } + RETVALUE(FALSE); +} + +#endif + + +/** + * @brief This function invokes the TM specific DL RETX RB Allocation routine. + * + * @details + * + * Function: rgSCHCmnDlAllocRetxRb + * Purpose: This function invokes the TM specific + * DL RETX RB Allocation routine. + * + * Invoked by: Specific Schedulers + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchDlSf *subFrm + * @param[in] RgSchUeCb *ue + * @param[in] U32 bo + * @param[out] U32 *effBo + * @param[in] RgSchDlHqProcCb *proc + * @param[out] RgSchCmnDlRbAllocInfo *cellWdAllocInfo + * @return S16 + * + **/ +#ifdef ANSI +PUBLIC S16 rgSCHCmnDlAllocRetxRb +( +RgSchCellCb *cell, +RgSchDlSf *subFrm, +RgSchUeCb *ue, +U32 bo, +U32 *effBo, +RgSchDlHqProcCb *proc, +RgSchCmnDlRbAllocInfo *cellWdAllocInfo +) +#else +PUBLIC S16 rgSCHCmnDlAllocRetxRb(cell, subFrm, ue, bo, effBo, proc, cellWdAllocInfo) +RgSchCellCb *cell; +RgSchDlSf *subFrm; +RgSchUeCb *ue; +U32 bo; +U32 *effBo; +RgSchDlHqProcCb *proc; +RgSchCmnDlRbAllocInfo *cellWdAllocInfo; +#endif +{ + U32 newSchBits = 0; + RgSchDlRbAlloc *allocInfo; + + TRC2(rgSCHCmnDlAllocRetxRb); + + if ( !RGSCH_TIMEINFO_SAME((cell->crntTime),(ue->dl.lstSchTime) )) + { + ue->dl.aggTbBits = 0; + } + + *effBo = 0; + /* Check for DL BW exhaustion */ + if (subFrm->bw <= subFrm->bwAssigned) + { + RETVALUE(RFAILED); + } + /* Call TM specific RB allocation routine */ + (dlAllocRetxRbFunc[ue->mimoInfo.txMode - 1])(cell, subFrm, ue, bo, effBo, \ + proc, cellWdAllocInfo); + + if (*effBo) + { + allocInfo = RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ue,cell); + /* Calculate totals bits newly allocated */ + if (allocInfo->tbInfo[0].schdlngForTb) + { + newSchBits += allocInfo->tbInfo[0].bytesReq; + } + if (allocInfo->tbInfo[1].schdlngForTb) + { + newSchBits += allocInfo->tbInfo[1].bytesReq; + } + ue->dl.aggTbBits += (newSchBits * 8); + RGSCHCPYTIMEINFO((cell->crntTime),(ue->dl.lstSchTime)) + } + + RETVALUE(ROK); +} + + +/** + * @brief This function determines the RBs and Bytes required for + * Transmission on 1 CW. + * + * @details + * + * Function: rgSCHCmnDlAlloc1CwTxRb + * Purpose: This function determines the RBs and Bytes required + * for Transmission of DL SVC BO on 1 CW. + * Also, takes care of SVC by SVC allocation by tracking + * previous SVCs allocations. + * Returns RFAILED if BO not satisfied at all. + * + * Invoked by: DL UE Allocation + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchDlSf *subFrm + * @param[in] RgSchUeCb *ue + * @param[in] RgSchDlHqTbCb *tbInfo + * @param[in] U32 bo + * @param[out] U8 *numRb + * @param[out] U32 *effBo + * @return S16 + * + **/ +#ifdef ANSI +PRIVATE S16 rgSCHCmnDlAlloc1CwTxRb +( +RgSchCellCb *cell, +RgSchDlSf *subFrm, +RgSchUeCb *ue, +RgSchDlHqTbCb *tbInfo, +U32 bo, +U8 *numRb, +U32 *effBo +) +#else +PRIVATE S16 rgSCHCmnDlAlloc1CwTxRb(cell, subFrm, ue, tbInfo, bo, numRb, effBo) +RgSchCellCb *cell; +RgSchDlSf *subFrm; +RgSchUeCb *ue; +RgSchDlHqTbCb *tbInfo; +U32 bo; +U8 *numRb; +U32 *effBo; +#endif +{ + U32 tbSz; + U8 imcs; + U8 iTbs; + RgSchCmnDlUe *ueDl; + RgSchDlRbAlloc *allocInfo; + U32 oldReq; + U32 reqBytes; + /* Correcting wrap around issue. + * This change has been done at mutliple places in this function.*/ + U32 tempNumRb; + TRC2(rgSCHCmnDlAlloc1CwTxRb); + + reqBytes = bo; + ueDl = RG_SCH_CMN_GET_DL_UE(ue,cell); + allocInfo = RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ue,cell); + oldReq = ueDl->outStndAlloc; + +#ifdef RG_5GTF + //TODO_SID: Currently setting max Tb size wrt to 5GTF TM3 + iTbs = ue->ue5gtfCb.mcs; + ueDl->maxTbSz = MAX_5GTF_TB_SIZE * ue->ue5gtfCb.rank; + ueDl->maxRb = MAX_5GTF_PRBS; +#endif + ueDl->outStndAlloc += bo; + /* consider Cumulative amount of this BO and bytes so far allocated */ + bo = RGSCH_MIN(ueDl->outStndAlloc, ueDl->maxTbSz/8); + /* Get the number of REs needed for this bo. */ + //noRes = ((bo * 8 * 1024) / eff); + + /* Get the number of RBs needed for this transmission */ + /* Number of RBs = No of REs / No of REs per RB */ + //tempNumRb = RGSCH_CEIL(noRes, cellDl->noResPerRb[cfi]); + tempNumRb = MAX_5GTF_PRBS; + tbSz = RGSCH_MIN(bo, (rgSch5gtfTbSzTbl[iTbs]/8) * ue->ue5gtfCb.rank); + + /* DwPts Scheduling Changes End */ + *effBo = RGSCH_MIN(tbSz - oldReq, reqBytes); + +#ifdef RG_5GTF + //RG_SCH_CMN_DL_TBS_TO_MCS(iTbs, imcs); + imcs = iTbs; +#endif + + + RG_SCH_CMN_FILL_DL_TBINFO(&allocInfo->tbInfo[0], tbSz, \ + iTbs, imcs, tbInfo, ue->ue5gtfCb.rank); + *numRb = (U8) tempNumRb; + + /* Update the subframe Allocated BW field */ + subFrm->bwAssigned = subFrm->bwAssigned + tempNumRb - allocInfo->rbsReq; + + RETVALUE(ROK); +} + + +/** + * @brief This function is invoked in the event of any TB's allocation + * being underutilized by the specific scheduler. Here we reduce iMcs + * to increase redundancy and hence increase reception quality at UE. + * + * @details + * + * Function: rgSCHCmnRdcImcsTxTb + * Purpose: This function shall reduce the iMcs in accordance with + * the total consumed bytes by the UE at allocation + * finalization. + * + * Invoked by: UE DL Allocation finalization routine + * of specific scheduler. + * + * @param[in] RgSchDlRbAlloc *allocInfo + * @param[in] U8 tbInfoIdx + * @param[in] U32 cnsmdBytes + * @return Void + * + **/ +#ifdef ANSI +PUBLIC Void rgSCHCmnRdcImcsTxTb +( +RgSchDlRbAlloc *allocInfo, +U8 tbInfoIdx, +U32 cnsmdBytes +) +#else +PUBLIC Void rgSCHCmnRdcImcsTxTb(allocInfo, tbInfoIdx, cnsmdBytes) +RgSchDlRbAlloc *allocInfo; +U8 tbInfoIdx; +U32 cnsmdBytes; +#endif +{ + RETVOID; + /*The below functionality is not needed.*/ + U8 noLyr; + U8 iTbs; + U16 numRb; + + TRC2(rgSCHCmnRdcImcsTxTb); + + iTbs = allocInfo->tbInfo[tbInfoIdx].iTbs; + noLyr = allocInfo->tbInfo[tbInfoIdx].noLyr; + numRb = allocInfo->rbsAlloc; + if ( numRb > 0) + { + if ((rgTbSzTbl[noLyr-1][iTbs][numRb-1]/8) == cnsmdBytes) + { + RETVOID; + } + } + /* Get iTbs as suitable for the consumed bytes */ + while((rgTbSzTbl[noLyr-1][iTbs][numRb-1]/8) > cnsmdBytes) + { + if (iTbs == 0) + { + RG_SCH_CMN_DL_TBS_TO_MCS(iTbs, allocInfo->tbInfo[tbInfoIdx].\ + tbCb->dlGrnt.iMcs); + RETVOID; + } + iTbs--; + } + iTbs++; + RG_SCH_CMN_DL_TBS_TO_MCS(iTbs, allocInfo->tbInfo[tbInfoIdx].tbCb->dlGrnt.iMcs); + + RETVOID; +} + + +/** + * @brief This function determines the RBs and Bytes required for + * Transmission on 2 CWs. + * + * @details + * + * Function: rgSCHCmnDlAlloc2CwTxRb + * Purpose: This function determines the RBs and Bytes required + * for Transmission of DL SVC BO on 2 CWs. + * Also, takes care of SVC by SVC allocation by tracking + * previous SVCs allocations. + * Returns RFAILED if BO not satisfied at all. + * + * Invoked by: TM3 and TM4 DL UE Allocation + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchDlSf *subFrm + * @param[in] RgSchUeCb *ue + * @param[in] RgSchDlHqProcCb *proc + * @param[in] RgSchDlHqProcCb bo + * @param[out] U8 *numRb + * @param[out] U32 *effBo + * @return Void + * + **/ +#ifdef ANSI +PRIVATE S16 rgSCHCmnDlAlloc2CwTxRb +( +RgSchCellCb *cell, +RgSchDlSf *subFrm, +RgSchUeCb *ue, +RgSchDlHqProcCb *proc, +U32 bo, +U8 *numRbRef, +U32 *effBo +) +#else +PRIVATE S16 rgSCHCmnDlAlloc2CwTxRb(cell, subFrm, ue, proc, bo, numRbRef, effBo) +RgSchCellCb *cell; +RgSchDlSf *subFrm; +RgSchUeCb *ue; +RgSchDlHqProcCb *proc; +U32 bo; +U8 *numRbRef; +U32 *effBo; +#endif +{ + U32 noRes; + U32 eff1, eff2; + U32 tb1Sz, tb2Sz; + U8 imcs1, imcs2; + U8 noLyr1, noLyr2; + U8 iTbs1, iTbs2; + RgSchCmnDlCell *cellDl; + RgSchCmnDlUe *ueDl; + RgSchDlRbAlloc *allocInfo; + U32 oldReq; + U32 reqBytes; + /* Fix: MUE_PERTTI_DL */ + U32 numRb; + RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell); + U8 cfi = cellSch->dl.currCfi; + S16 availBw; + U32 availBits = 0; +#ifdef LTE_ADV + U32 boTmp = bo; +#endif + + TRC2(rgSCHCmnDlAlloc2CwTxRb); + + reqBytes = bo; + cellDl = RG_SCH_CMN_GET_DL_CELL(cell); + ueDl = RG_SCH_CMN_GET_DL_UE(ue,cell); + allocInfo = RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ue,cell); + oldReq = ueDl->outStndAlloc; + + + if (ueDl->maxTbBits > ue->dl.aggTbBits) + { + availBits = ueDl->maxTbBits - ue->dl.aggTbBits; + } + /* check if we can further allocate to this UE */ + if ((ue->dl.aggTbBits >= ueDl->maxTbBits) || + (allocInfo->tbInfo[0].bytesReq >= ueDl->maxTbSz/8) || + (allocInfo->tbInfo[1].bytesReq >= ueDl->maxTbSz/8) || + (allocInfo->rbsReq >= ueDl->maxRb)) + { + RLOG_ARG0(L_DEBUG,DBG_CELLID,cell->cellId, + "rgSCHCmnDlAllocRb(): UEs max allocation exceed"); + RETVALUE(RFAILED); + } + + noLyr1 = ueDl->mimoInfo.cwInfo[0].noLyr; + noLyr2 = ueDl->mimoInfo.cwInfo[1].noLyr; + + /* If there is no CFI change, continue to use the BLER based + * iTBS value */ + if (ueDl->lastCfi == cfi) + { + iTbs1 = ueDl->mimoInfo.cwInfo[0].iTbs[noLyr1 - 1]; + iTbs2 = ueDl->mimoInfo.cwInfo[1].iTbs[noLyr2 - 1]; + } + else + { + U8 cqi = ueDl->mimoInfo.cwInfo[0].cqi; +#ifdef LTE_TDD + iTbs1 = (U8) rgSchCmnFetchItbs(cell, ueDl, subFrm, cqi, cfi, 0, noLyr1); +#else + iTbs1 = (U8) rgSchCmnFetchItbs(cell, ueDl, cqi, cfi, 0, noLyr1); +#endif + + cqi = ueDl->mimoInfo.cwInfo[1].cqi; +#ifdef LTE_TDD + iTbs2 = (U8) rgSchCmnFetchItbs(cell, ueDl, subFrm, cqi, cfi, 1, noLyr2); +#else + iTbs2 = (U8) rgSchCmnFetchItbs(cell, ueDl, cqi, cfi, 1, noLyr2); +#endif + } + + /*ccpu00131191 and ccpu00131317 - Fix for RRC Reconfig failure + * issue for VoLTE call */ + //if ((proc->hasDcch) || (TRUE == rgSCHLaaSCellEnabled(cell))) + if (proc->hasDcch) + { + if (iTbs1 > 5) + { + iTbs1 = iTbs1 - 5; + } + else + { + iTbs1 = 0; + } + if (iTbs2 > 5) + { + iTbs2 = iTbs2 - 5; + } + else + { + iTbs2 = 0; + } + } + else if(!cellSch->dl.isDlFreqSel) + { +#ifdef LTE_TDD + /* for Tdd reduce iTbs only for SF0. SF5 contains only + * SSS and can be ignored */ + if (subFrm->sfNum == 0) + { + (iTbs1 > 1)? (iTbs1 -= 1) : (iTbs1 = 0); + (iTbs2 > 1)? (iTbs2 -= 1) : (iTbs2 = 0); + } + /* For SF 3 and 8 CRC is getting failed in DL. + Need to do proper fix after the replay from + BRCM PHY team*/ +#ifdef CA_PHY_BRDCM_61765 + if ((subFrm->sfNum == 3) || (subFrm->sfNum == 8)) + { + (iTbs1 > 2)? (iTbs1 -= 2) : (iTbs1 = 0); + (iTbs2 > 2)? (iTbs2 -= 2) : (iTbs2 = 0); + } +#endif +#else +#endif + } + +#ifdef LTE_TDD + if(subFrm->sfType == RG_SCH_SPL_SF_DATA) + { + RGSCH_GET_SPS_SF_CFI(cell->bwCfg.dlTotalBw, cfi); + } +#endif + + eff1 = (*(RgSchCmnTbSzEff *)(cellSch->dl.cqiToEffTbl[noLyr1 - 1][cfi]))[iTbs1]; + eff2 = (*(RgSchCmnTbSzEff *)(cellSch->dl.cqiToEffTbl[noLyr2 - 1][cfi]))[iTbs2]; + + + bo = RGSCH_MIN(bo,availBits/8); + ueDl->outStndAlloc += bo; + /* consider Cumulative amount of this BO and bytes so far allocated */ + bo = RGSCH_MIN(ueDl->outStndAlloc, ueDl->maxTbBits/8); + bo = RGSCH_MIN(RGSCH_MAX(RGSCH_CMN_MIN_GRNT_HDR, (bo*eff1)/(eff1+eff2)), + ueDl->maxTbSz/8) + + RGSCH_MIN(RGSCH_MAX(RGSCH_CMN_MIN_GRNT_HDR, (bo*eff2)/(eff1+eff2)), + (ueDl->maxTbSz)/8) + + 1; /* Add 1 to adjust the truncation at weighted averaging */ + /* Get the number of REs needed for this bo. */ + noRes = ((bo * 8 * 1024) / (eff1 + eff2)); + + /* Get the number of RBs needed for this transmission */ + /* Number of RBs = No of REs / No of REs per RB */ + numRb = RGSCH_CEIL(noRes, cellDl->noResPerRb[cfi]); + /* Cannot exceed the maximum number of RBs per UE */ + if (numRb > ueDl->maxRb) + { + numRb = ueDl->maxRb; + } + else + { +#ifdef LTE_ADV + if(RFAILED == rgSCHLaaCmn2CwAdjustPrb(allocInfo, boTmp, &numRb, ueDl, noLyr1, noLyr2, iTbs1, iTbs2)) +#endif + { + while ((numRb <= ueDl->maxRb) && + (rgTbSzTbl[noLyr1 - 1][iTbs1][numRb-1] <= ueDl->maxTbSz) && + (rgTbSzTbl[noLyr2 - 1][iTbs2][numRb-1] <= ueDl->maxTbSz) && + ((rgTbSzTbl[noLyr1 - 1][iTbs1][numRb-1]/8 + + rgTbSzTbl[noLyr2 - 1][iTbs2][numRb-1]/8) <= bo)) + { + (numRb)++; + } + } + } + availBw = subFrm->bw - subFrm->bwAssigned; + /* Cannot exceed the total number of RBs in the cell */ + if ((S16)(numRb - allocInfo->rbsReq) > availBw) + { + numRb = availBw + allocInfo->rbsReq; + } + tb1Sz = rgTbSzTbl[noLyr1 - 1][iTbs1][numRb-1]/8; + tb2Sz = rgTbSzTbl[noLyr2 - 1][iTbs2][numRb-1]/8; + /* DwPts Scheduling Changes Start */ +#ifdef LTE_TDD + if(subFrm->sfType == RG_SCH_SPL_SF_DATA) + { + /* Max Rb for Special Sf is approximated as 4/3 of maxRb */ + rgSCHCmnCalcDwPtsTbSz2Cw(cell, bo, (U8*)&numRb, ueDl->maxRb*4/3, + &iTbs1, &iTbs2, noLyr1, + noLyr2, &tb1Sz, &tb2Sz, cfi); + /* Check for available Bw */ + if ((S16)numRb - allocInfo->rbsReq > availBw) + { + numRb = availBw + allocInfo->rbsReq; + tb1Sz = rgTbSzTbl[noLyr1-1][iTbs1][RGSCH_MAX(numRb*3/4,1)-1]/8; + tb2Sz = rgTbSzTbl[noLyr2-1][iTbs2][RGSCH_MAX(numRb*3/4,1)-1]/8; + } + } +#endif + /* DwPts Scheduling Changes End */ + /* Update the subframe Allocated BW field */ + subFrm->bwAssigned = subFrm->bwAssigned + numRb - \ + allocInfo->rbsReq; + + *effBo = RGSCH_MIN((tb1Sz + tb2Sz) - oldReq, reqBytes); + +#ifdef LTE_ADV + if (ROK != rgSCHLaaCmn2TBPrbCheck(allocInfo, tb1Sz, tb2Sz, boTmp, effBo, iTbs1, iTbs2, numRb, proc)) + { + RETVALUE(RFAILED); + } +#endif + + RG_SCH_CMN_DL_TBS_TO_MCS(iTbs1, imcs1); + RG_SCH_CMN_DL_TBS_TO_MCS(iTbs2, imcs2); + RG_SCH_CMN_FILL_DL_TBINFO(&allocInfo->tbInfo[0], tb1Sz, \ + iTbs1, imcs1, &proc->tbInfo[0], noLyr1); + RG_SCH_CMN_FILL_DL_TBINFO(&allocInfo->tbInfo[1], tb2Sz, \ + iTbs2, imcs2, &proc->tbInfo[1], noLyr2); + *numRbRef = (U8)numRb; + + + RETVALUE(ROK); +} + + +/** + * @brief This function determines the RBs and Bytes required for + * Transmission & Retransmission on 2 CWs. + * + * @details + * + * Function: rgSCHCmnDlAlloc2CwTxRetxRb + * Purpose: This function determines the RBs and Bytes required + * for Transmission & Retransmission on 2 CWs. Allocate + * RETX TB on a better CW and restrict new TX TB by + * RETX allocation. + * Returns RFAILED if BO not satisfied at all. + * + * Invoked by: TM3 and TM4 DL UE Allocation + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchDlSf *subFrm + * @param[in] RgSchUeCb *ue + * @param[in] RgSchDlHqTbCb *reTxTb + * @param[in] RgSchDlHqTbCb *txTb + * @param[out] U8 *numRb + * @param[out] U32 *effBo + * @return Void + * + **/ +#ifdef ANSI +PRIVATE S16 rgSCHCmnDlAlloc2CwTxRetxRb +( +RgSchCellCb *cell, +RgSchDlSf *subFrm, +RgSchUeCb *ue, +RgSchDlHqTbCb *reTxTb, +RgSchDlHqTbCb *txTb, +U8 *numRb, +U32 *effBo +) +#else +PRIVATE S16 rgSCHCmnDlAlloc2CwTxRetxRb(cell, subFrm, ue, reTxTb, txTb, numRb,\ + effBo) +RgSchCellCb *cell; +RgSchDlSf *subFrm; +RgSchUeCb *ue; +RgSchDlHqTbCb *reTxTb; +RgSchDlHqTbCb *txTb; +U8 *numRb; +U32 *effBo; +#endif +{ + RgSchCmnDlUe *ueDl; + RgSchDlRbAlloc *allocInfo; + U8 imcs1, imcs2; + U8 noLyr2; + U16 tb2Sz; + RgSchCmnDlUeCwInfo *otherCw; + S16 availBw; + RgSchCmnDlCell *cellDl = RG_SCH_CMN_GET_DL_CELL(cell); + U8 cfi = cellDl->currCfi; + U8 iTbs; + + TRC2(rgSCHCmnDlAlloc2CwTxRetxRb); + + ueDl = RG_SCH_CMN_GET_DL_UE(ue,cell); + allocInfo = RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ue,cell); + otherCw = &ueDl->mimoInfo.cwInfo[!(ueDl->mimoInfo.btrCwIdx)]; + + + /* Fix for ccpu00123919: In case of RETX TB scheduling avoiding recomputation of RB + * and Tbs. Set all parameters same as Init TX except RV(only for NACKED) and + * MCS. */ + availBw = subFrm->bw - subFrm->bwAssigned; + *numRb = reTxTb->dlGrnt.numRb; + +#ifdef XEON_TDD_SPCL + *numRb = (reTxTb->initTxNumRbs); + if(reTxTb->sfType == RG_SCH_SPL_SF_DATA && subFrm->sfType != RG_SCH_SPL_SF_DATA) + { + *numRb = (reTxTb->initTxNumRbs*3/4); + + if(*numRb <= 3) + { + RLOG1(L_ERROR," Number of RBs [%d] are less than or equal to 3",*numRb); + RETVALUE(RFAILED); + } + } +#endif + + if ((S16)*numRb > availBw) + { + RETVALUE(RFAILED); + } + /* Update the subframe Allocated BW field */ + subFrm->bwAssigned += *numRb; + noLyr2 = otherCw->noLyr; + RG_SCH_CMN_GET_MCS_FOR_RETX(reTxTb, imcs1); + + /* If there is no CFI change, continue to use the BLER based + * iTBS value */ + if (ueDl->lastCfi == cfi) + { + iTbs = otherCw->iTbs[noLyr2-1]; + } + else + { +#ifdef LTE_TDD + iTbs = (U8) rgSchCmnFetchItbs(cell, ueDl, subFrm, otherCw->cqi, cfi, + !(ueDl->mimoInfo.btrCwIdx), noLyr2); +#else + iTbs = (U8) rgSchCmnFetchItbs(cell, ueDl, otherCw->cqi, cfi, + !(ueDl->mimoInfo.btrCwIdx), noLyr2); +#endif + } + tb2Sz = rgTbSzTbl[noLyr2-1][iTbs][*numRb-1]/8; + /* DwPts Scheduling Changes Start */ +#ifdef LTE_TDD +#endif + /* DwPts Scheduling Changes End */ + RG_SCH_CMN_DL_TBS_TO_MCS(iTbs, imcs2); + + RG_SCH_CMN_FILL_DL_TBINFO(&allocInfo->tbInfo[0], reTxTb->tbSz, \ + 0, imcs1, reTxTb, reTxTb->numLyrs); + + RG_SCH_CMN_FILL_DL_TBINFO(&allocInfo->tbInfo[1], tb2Sz, \ + iTbs, imcs2, txTb, noLyr2); + + *effBo = reTxTb->tbSz + tb2Sz; + + RETVALUE(ROK); +} + + +/** + * @brief This function determines the RBs and Bytes required for BO + * Retransmission on 2 CWs. + * + * @details + * + * Function: rgSCHCmnDlAlloc2CwRetxRb + * Purpose: This function determines the RBs and Bytes required + * for BO Retransmission on 2 CWs. Allocate larger TB + * on a better CW and check if the smaller TB can be + * accomodated on the other CW. + * Returns RFAILED if BO not satisfied at all. + * + * Invoked by: Common Scheduler + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchDlSf *subFrm + * @param[in] RgSchUeCb *ue + * @param[in] RgSchDlHqProcCb *proc + * @param[out] U8 *numRb + * @param[out] Bool *swpFlg + * @param[out] U32 *effBo + * @return Void + * + **/ +#ifdef ANSI +PRIVATE S16 rgSCHCmnDlAlloc2CwRetxRb +( +RgSchCellCb *cell, +RgSchDlSf *subFrm, +RgSchUeCb *ue, +RgSchDlHqProcCb *proc, +U8 *numRb, +Bool *swpFlg, +U32 *effBo +) +#else +PRIVATE S16 rgSCHCmnDlAlloc2CwRetxRb(cell, subFrm, ue, proc,\ + numRb, swpFlg, effBo) +RgSchCellCb *cell; +RgSchDlSf *subFrm; +RgSchUeCb *ue; +RgSchDlHqProcCb *proc; +U8 *numRb; +Bool *swpFlg; +U32 *effBo; +#endif +{ + RgSchDlRbAlloc *allocInfo; + U8 imcs1; + U8 imcs2; + RgSchDlHqTbCb *lrgTbInfo, *othrTbInfo; + + TRC2(rgSCHCmnDlAlloc2CwRetxRb); + + allocInfo = RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ue,cell); + + + /* Fix for ccpu00123919: In case of RETX TB scheduling avoiding recomputation of RB + * and Tbs. Set all parameters same as Init TX except RV(only for NACKED) and + * MCS. */ + lrgTbInfo = &proc->tbInfo[0]; + othrTbInfo = &proc->tbInfo[1]; + *numRb = lrgTbInfo->dlGrnt.numRb; +#ifdef XEON_TDD_SPCL + if((lrgTbInfo->sfType == RG_SCH_SPL_SF_DATA || othrTbInfo->sfType == RG_SCH_SPL_SF_DATA)) + { + if(lrgTbInfo->sfType == RG_SCH_SPL_SF_DATA) + { + *numRb = (lrgTbInfo->initTxNumRbs); + } + else + { + *numRb = (othrTbInfo->initTxNumRbs); + } + + if(subFrm->sfType != RG_SCH_SPL_SF_DATA) + { + *numRb = (*numRb)*3/4; + } + + if(*numRb <= 3) + { + RLOG1(L_ERROR," Number of RBs [%d] are less than or equal to 3",*numRb); + RETVALUE(RFAILED); + } + } +#endif + if ((S16)*numRb > (S16)(subFrm->bw - subFrm->bwAssigned)) + { + RETVALUE(RFAILED); + } + /* Update the subframe Allocated BW field */ + subFrm->bwAssigned += *numRb; + RG_SCH_CMN_GET_MCS_FOR_RETX(lrgTbInfo, imcs1); + RG_SCH_CMN_GET_MCS_FOR_RETX(othrTbInfo, imcs2); + RG_SCH_CMN_FILL_DL_TBINFO(&allocInfo->tbInfo[0], lrgTbInfo->tbSz, \ + 0, imcs1, lrgTbInfo, lrgTbInfo->numLyrs); + RG_SCH_CMN_FILL_DL_TBINFO(&allocInfo->tbInfo[1], othrTbInfo->tbSz, \ + 0, imcs2, othrTbInfo, othrTbInfo->numLyrs); + *effBo = lrgTbInfo->tbSz + othrTbInfo->tbSz; + + + + RETVALUE(ROK); +} + + +/** + * @brief This function determines the RBs and Bytes required for BO + * Retransmission on 1 CW. + * + * @details + * + * Function: rgSCHCmnDlAlloc1CwRetxRb + * Purpose: This function determines the RBs and Bytes required + * for BO Retransmission on 1 CW, the first CW. + * Returns RFAILED if BO not satisfied at all. + * + * Invoked by: Common Scheduler + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchDlSf *subFrm + * @param[in] RgSchUeCb *ue + * @param[in] RgSchDlHqTbCb *tbInfo + * @param[in] U8 noLyr + * @param[out] U8 *numRb + * @param[out] U32 *effBo + * @return S16 + * + **/ +#ifdef ANSI +PRIVATE S16 rgSCHCmnDlAlloc1CwRetxRb +( +RgSchCellCb *cell, +RgSchDlSf *subFrm, +RgSchUeCb *ue, +RgSchDlHqTbCb *tbInfo, +U8 noLyr, +U8 *numRb, +U32 *effBo +) +#else +PRIVATE S16 rgSCHCmnDlAlloc1CwRetxRb(cell, subFrm, ue, tbInfo, noLyr,\ + numRb, effBo) +RgSchCellCb *cell; +RgSchDlSf *subFrm; +RgSchUeCb *ue; +RgSchDlHqTbCb *tbInfo; +U8 noLyr; +U8 *numRb; +U32 *effBo; +#endif +{ + RgSchDlRbAlloc *allocInfo; + U8 imcs; + + TRC2(rgSCHCmnDlAlloc1CwRetxRb); + + allocInfo = RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ue,cell); + + + /* Fix for ccpu00123919: In case of RETX TB scheduling avoiding recomputation of RB + * and Tbs. Set all parameters same as Init TX except RV(only for NACKED) and + * MCS. */ + *numRb = tbInfo->dlGrnt.numRb; + if ((S16)*numRb > (S16)(subFrm->bw - subFrm->bwAssigned)) + { + RETVALUE(RFAILED); + } + /* Update the subframe Allocated BW field */ + subFrm->bwAssigned += *numRb; + imcs = tbInfo->dlGrnt.iMcs; + allocInfo->dciFormat = tbInfo->dlGrnt.dciFormat; + /* Fix: For a RETX TB the iTbs is irrelevant, hence setting 0 */ + RG_SCH_CMN_FILL_DL_TBINFO(&allocInfo->tbInfo[0], tbInfo->tbSz, \ + 0, imcs, tbInfo, tbInfo->numLyrs); + *effBo = tbInfo->tbSz; + + RETVALUE(ROK); +} + +#ifdef LTEMAC_SPS + +/** + * @brief This function is called to handle Release PDCCH feedback for SPS UE + * + * @details + * + * Function: rgSCHCmnDlRelPdcchFbk + * Purpose: Invokes SPS module to handle release PDCCH feedback + * + * Invoked by: DHM + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ue + * @param[in] Bool isAck + * @return Void + * + **/ +#ifdef ANSI +PUBLIC Void rgSCHCmnDlRelPdcchFbk +( +RgSchCellCb *cell, +RgSchUeCb *ue, +Bool isAck +) +#else +PUBLIC Void rgSCHCmnDlRelPdcchFbk(cell, ue, isAck) +RgSchCellCb *cell; +RgSchUeCb *ue; +Bool isAck; +#endif +{ + + TRC2(rgSCHCmnDlRelPdcchFbk); + rgSCHCmnSpsDlRelPdcchFbk(cell, ue, isAck); + RETVOID; + +} + + +/** + * @brief This function is invoked to handle Ack processing for a HARQ proc. + * + * @details + * + * Function: rgSCHCmnDlProcAck + * Purpose: DTX processing for HARQ proc + * + * Invoked by: DHM + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchDlHqProcCb *hqP + * @return Void + * + **/ +#ifdef ANSI +PUBLIC Void rgSCHCmnDlProcAck +( +RgSchCellCb *cell, +RgSchDlHqProcCb *hqP +) +#else +PUBLIC Void rgSCHCmnDlProcAck(cell, hqP) +RgSchCellCb *cell; +RgSchDlHqProcCb *hqP; +#endif +{ + + TRC2(rgSCHCmnDlProcAck); + + if (RG_SCH_CMN_SPS_DL_IS_SPS_HQP(hqP)) + { + /* Invoke SPS module if SPS service was scheduled for this HARQ proc */ + rgSCHCmnSpsDlProcAck(cell, hqP); + } + RETVOID; +} +#ifdef RGSCH_SPS_STATS +extern U32 rgSchStatCrntiCeRcvCnt; +#endif +/** + * @brief This function is invoked to handle CRNTI CE reception for an UE + * + * @details + * + * Function: rgSCHCmnHdlCrntiCE + * Purpose: Handle CRNTI CE reception + * + * Invoked by: DHM + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchDlHqProcCb *hqP + * @return Void + * + **/ +#ifdef ANSI +PUBLIC Void rgSCHCmnHdlCrntiCE +( +RgSchCellCb *cell, +RgSchUeCb *ue +) +#else +PUBLIC Void rgSCHCmnHdlCrntiCE(cell, ue) +RgSchCellCb *cell; +RgSchUeCb *ue; +#endif +{ + + TRC2(rgSCHCmnHdlCrntiCE); +#ifdef RGSCH_SPS_STATS + rgSchStatCrntiCeRcvCnt++; +#endif + + /* When UL sync lost happened due to TA timer expiry UE is being moved to + PDCCH order inactivity list.But when CRNTI CE received in msg3 from UE + we are not moving UE into active state due to that RRC Reconfiguration is + not happening. + So here we are moving UE to active list whenever we receive the CRNTI CE and + UE is inactive */ + /* CR ccpu00144525 */ + if (RG_SCH_CMN_IS_UE_PDCCHODR_INACTV(ue)) + { + /* Activate this UE if it was inactive */ + RG_SCH_CMN_DL_UPDT_INACTV_MASK ( cell, ue, RG_PDCCHODR_INACTIVE); + RG_SCH_CMN_UL_UPDT_INACTV_MASK ( cell, ue, RG_PDCCHODR_INACTIVE); + } + + /* Handling is same as reception of UE RESET for both DL and UL */ + if (ue->dl.dlSpsCfg.isDlSpsEnabled) + { + rgSCHCmnSpsDlUeReset(cell, ue); + } + if (ue->ul.ulSpsCfg.isUlSpsEnabled == TRUE) + { + rgSCHCmnSpsUlUeReset(cell, ue); + } + + RETVOID; +} + + +/** + * @brief This function is called to handle relInd from MAC for a UE + * + * @details + * + * Function: rgSCHCmnUlSpsRelInd + * Purpose: Invokes SPS module to handle UL SPS release for a UE + * + * Invoked by: SCH_UTL + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ue + * @param[in] Bool isExplRel + * @return Void + * + **/ +#ifdef ANSI +PUBLIC Void rgSCHCmnUlSpsRelInd +( +RgSchCellCb *cell, +RgSchUeCb *ue, +Bool isExplRel +) +#else +PUBLIC Void rgSCHCmnUlSpsRelInd(cell, ue, isExplRel) +RgSchCellCb *cell; +RgSchUeCb *ue; +Bool isExplRel; +#endif +{ + + TRC2(rgSCHCmnUlSpsRelInd); + rgSCHCmnSpsUlProcRelInd(cell, ue, isExplRel); + RETVOID; + +} /* end of rgSCHCmnUlSpsRelInd */ + +/** + * @brief This function is called to handle SPS Activate Ind from MAC for a UE + * + * @details + * + * Function: rgSCHCmnUlSpsActInd + * Purpose: Invokes SPS module to handle UL SPS activate for a UE + * + * Invoked by: SCH_UTL + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ue + * @return Void + * + **/ +#ifdef ANSI +PUBLIC Void rgSCHCmnUlSpsActInd +( +RgSchCellCb *cell, +RgSchUeCb *ue, +U16 spsSduSize +) +#else +PUBLIC Void rgSCHCmnUlSpsActInd(cell, ue,spsSduSize) +RgSchCellCb *cell; +RgSchUeCb *ue; +U16 spsSduSize; +#endif +{ + + TRC2(rgSCHCmnUlSpsActInd); + + if (ue->ul.ulSpsCfg.isUlSpsEnabled == TRUE) + { + rgSCHCmnSpsUlProcActInd(cell, ue,spsSduSize); + } + RETVOID; + +} /* end of rgSCHCmnUlSpsActInd */ + +/** + * @brief This function is called to handle CRC in UL for UEs + * undergoing SPS release + * + * @details + * + * Function: rgSCHCmnUlCrcInd + * Purpose: Invokes SPS module to handle CRC in UL for SPS UE + * + * Invoked by: SCH_UTL + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ue + * @param[in] CmLteTimingInfo crcTime + * @return Void + * + **/ +#ifdef ANSI +PUBLIC Void rgSCHCmnUlCrcInd +( +RgSchCellCb *cell, +RgSchUeCb *ue, +CmLteTimingInfo crcTime +) +#else +PUBLIC Void rgSCHCmnUlCrcInd(cell, ue, crcTime) +RgSchCellCb *cell; +RgSchUeCb *ue; +CmLteTimingInfo crcTime; +#endif +{ + + TRC2(rgSCHCmnUlCrcInd); + if (ue->ul.ulSpsCfg.isUlSpsEnabled == TRUE) + { + rgSCHCmnSpsUlProcCrcInd(cell, ue, crcTime); + } + RETVOID; + +} /* end of rgSCHCmnUlCrcFailInd */ + +/** + * @brief This function is called to handle CRC failure in UL + * + * @details + * + * Function: rgSCHCmnUlCrcFailInd + * Purpose: Invokes SPS module to handle CRC failure in UL for SPS UE + * + * Invoked by: SCH_UTL + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ue + * @param[in] CmLteTimingInfo crcTime + * @return Void + * + **/ +#ifdef ANSI +PUBLIC Void rgSCHCmnUlCrcFailInd +( +RgSchCellCb *cell, +RgSchUeCb *ue, +CmLteTimingInfo crcTime +) +#else +PUBLIC Void rgSCHCmnUlCrcFailInd(cell, ue, crcTime) +RgSchCellCb *cell; +RgSchUeCb *ue; +CmLteTimingInfo crcTime; +#endif +{ + + TRC2(rgSCHCmnUlCrcFailInd); + if (ue->ul.ulSpsCfg.isUlSpsEnabled == TRUE) + { + rgSCHCmnSpsUlProcDtxInd(cell, ue, crcTime); + } + RETVOID; + +} /* end of rgSCHCmnUlCrcFailInd */ + +#endif /* LTEMAC_SPS */ + +/** + * @brief BCH,BCCH,PCCH Dowlink Scheduling Handler. + * + * @details + * + * Function: rgSCHCmnDlBcchPcchAlloc + * Purpose: This function calls common scheduler APIs to + * schedule for BCCH/PCCH. + * It then invokes Allocator for actual RB + * allocations. It processes on the actual resources allocated + * against requested to the allocator module. + * + * Invoked by: Common Scheduler + * + * @param[in] RgSchCellCb *cell + * @return Void + **/ +#ifdef ANSI +PRIVATE Void rgSCHCmnDlBcchPcchAlloc +( +RgSchCellCb *cell +) +#else +PRIVATE Void rgSCHCmnDlBcchPcchAlloc(cell) +RgSchCellCb *cell; +#endif +{ +#ifdef LTE_TDD + U8 nextSfIdx = (cell->crntSfIdx) % RGSCH_SF_ALLOC_SIZE; +#else +#ifdef LTEMAC_HDFDD + U8 nextSfIdx = (cell->crntSfIdx + RG_SCH_CMN_HARQ_INTERVAL) % RGSCH_NUM_SUB_FRAMES; +#else + U8 nextSfIdx = (cell->crntSfIdx) % RGSCH_NUM_SUB_FRAMES; +#endif +#endif + RgInfSfAlloc *nextsfAlloc = &(cell->sfAllocArr[nextSfIdx]); + RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell); + RgSchCmnDlRbAllocInfo *allocInfo = &cellSch->allocInfo; + + TRC2(rgSCHCmnDlBcchPcchAlloc); + + + /*Reset the bitmask for BCCH/PCCH*/ + rgSCHUtlResetSfAlloc(nextsfAlloc,TRUE,FALSE); +#ifndef DISABLE_MIB_SIB /* Not sending MIB and SIB to CL */ +#ifdef RGR_SI_SCH + rgSCHChkNUpdSiCfg(cell); + rgSCHSelectSi(cell); +#endif + + /*Perform the scheduling for BCCH,PCCH*/ + rgSCHCmnDlBcchPcch(cell, allocInfo, nextsfAlloc); + + /* Call common allocator for RB Allocation */ + rgSCHBcchPcchDlRbAlloc(cell, allocInfo); + + /* Finalize the Allocations for reqested Against alloced */ + rgSCHCmnDlBcchPcchFnlz(cell, allocInfo); +#endif /* DISABLE_MIB_SIB */ + RETVOID; +} + +/** + * @brief Handles RB allocation for BCCH/PCCH for downlink. + * + * @details + * + * Function : rgSCHBcchPcchDlRbAlloc + * + * Invoking Module Processing: + * - This function is invoked for DL RB allocation of BCCH/PCCH + * + * Processing Steps: + * - If cell is frequency selecive, + * - Call rgSCHDlfsBcchPcchAllocRb(). + * - else, + * - Do the processing + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchDlRbAllocInfo *allocInfo + * @return Void + **/ + +#ifdef ANSI +PRIVATE Void rgSCHBcchPcchDlRbAlloc +( +RgSchCellCb *cell, +RgSchCmnDlRbAllocInfo *allocInfo +) +#else +PRIVATE Void rgSCHBcchPcchDlRbAlloc(cell, allocInfo) +RgSchCellCb *cell; +RgSchCmnDlRbAllocInfo *allocInfo; +#endif +{ + RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell); + + TRC2(rgSCHBcchPcchDlRbAlloc); + + + if (cellSch->dl.isDlFreqSel) + { + cellSch->apisDlfs->rgSCHDlfsBcchPcchAllocRb(cell, allocInfo); + } + else + { + rgSCHCmnNonDlfsBcchPcchRbAlloc(cell, allocInfo); + } + + RETVOID; +} + +/** + * @brief Handles RB allocation for BCCH,PCCH for frequency + * non-selective cell. + * + * @details + * + * Function : rgSCHCmnNonDlfsBcchPcchRbAlloc + * + * Invoking Module Processing: + * - SCH shall invoke this if downlink frequency selective is disabled for + * the cell for RB allocation. + * - MAX C/I/PFS/RR shall provide the requiredBytes, required RBs + * estimate and subframe for each allocation to be made to SCH. + * + * Processing Steps: + * - Allocate sequentially for BCCH,PCCH common channels. + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchCmnDlRbAllocInfo *allocInfo + * @return Void + **/ + +#ifdef ANSI +PRIVATE Void rgSCHCmnNonDlfsBcchPcchRbAlloc +( +RgSchCellCb *cell, +RgSchCmnDlRbAllocInfo *allocInfo +) +#else +PRIVATE Void rgSCHCmnNonDlfsBcchPcchRbAlloc(cell, allocInfo) +RgSchCellCb *cell; +RgSchCmnDlRbAllocInfo *allocInfo; +#endif +{ + RgSchDlRbAlloc *reqAllocInfo; + + TRC2(rgSCHCmnNonDlfsBcchPcchRbAlloc); + + /* 143473 */ + /* Allocate for PCCH */ + reqAllocInfo = &(allocInfo->pcchAlloc); + if (reqAllocInfo->rbsReq) + { + rgSCHCmnNonDlfsCmnRbAlloc(cell, reqAllocInfo); + } + /* Allocate for BCCH on DLSCH */ + reqAllocInfo = &(allocInfo->bcchAlloc); + if (reqAllocInfo->rbsReq) + { + rgSCHCmnNonDlfsCmnRbAlloc(cell, reqAllocInfo); + } + RETVOID; +} + + +#ifdef RGR_SI_SCH +/** + * @brief This function implements the handling to check and + * update the SI cfg at the start of the modificiation period. + * + * @details + * + * Function: rgSCHChkNUpdSiCfg + * Purpose: This function implements handling for update of SI Cfg + * at the start of modification period. + * + * Invoked by: Scheduler + * + * @param[in] RgSchCellCb* cell + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PRIVATE Void rgSCHChkNUpdSiCfg +( +RgSchCellCb *cell +) +#else +PRIVATE Void rgSCHChkNUpdSiCfg(cell) +RgSchCellCb *cell; +#endif +{ + CmLteTimingInfo pdSchTmInfo; + + TRC2(rgSCHChkNUpdSiCfg); + + + pdSchTmInfo = cell->crntTime; +#ifdef LTEMAC_HDFDD + /* For HDFDD we need scheduling information at least RG_SCH_CMN_DL_DELTA + + RG_SCH_CMN_HARQ_INTERVAL (7) subframes ahead */ + RGSCH_INCR_SUB_FRAME(pdSchTmInfo, RG_SCH_CMN_DL_DELTA + RG_SCH_CMN_HARQ_INTERVAL); +#else + RGSCH_INCR_SUB_FRAME(pdSchTmInfo, RG_SCH_CMN_DL_DELTA); +#endif + + + /* Updating the SIB1 for Warning SI message immediately after it is received + * from application. No need to wait for next modification period. + */ + if((pdSchTmInfo.sfn % RGSCH_SIB1_RPT_PERIODICITY == 0) + && (RGSCH_SIB1_TX_SF_NUM == (pdSchTmInfo.subframe % RGSCH_NUM_SUB_FRAMES))) + { + /*Check whether SIB1 with PWS has been updated*/ + if(cell->siCb.siBitMask & RGSCH_SI_SIB1_PWS_UPD) + { + RGSCH_SET_SI_INFO(cell->siCb.crntSiInfo.sib1Info.sib1, + cell->siCb.newSiInfo.sib1Info.sib1); + cell->siCb.crntSiInfo.sib1Info.mcs = + cell->siCb.newSiInfo.sib1Info.mcs; + cell->siCb.crntSiInfo.sib1Info.nPrb = + cell->siCb.newSiInfo.sib1Info.nPrb; + cell->siCb.crntSiInfo.sib1Info.msgLen = + cell->siCb.newSiInfo.sib1Info.msgLen; + cell->siCb.siBitMask &= ~RGSCH_SI_SIB1_PWS_UPD; + } + } + + /*Check if this SFN and SF No marks the start of next modification + period. If current SFN,SF No doesn't marks the start of next + modification period, then return. */ + if(!((pdSchTmInfo.sfn % cell->siCfg.modPrd == 0) + && (0 == pdSchTmInfo.subframe))) + /*if(!((((pdSchTmInfo.hSfn * 1024) + pdSchTmInfo.sfn) % cell->siCfg.modPrd == 0) + && (0 == pdSchTmInfo.subframe)))*/ + { + RETVOID; + } + + /*Check whether MIB has been updated*/ + if(cell->siCb.siBitMask & RGSCH_SI_MIB_UPD) + { + RGSCH_SET_SI_INFO(cell->siCb.crntSiInfo.mib, + cell->siCb.newSiInfo.mib); + cell->siCb.siBitMask &= ~RGSCH_SI_MIB_UPD; + } + + /*Check whether SIB1 has been updated*/ + if(cell->siCb.siBitMask & RGSCH_SI_SIB1_UPD) + { + RGSCH_SET_SI_INFO(cell->siCb.crntSiInfo.sib1Info.sib1, + cell->siCb.newSiInfo.sib1Info.sib1); + cell->siCb.crntSiInfo.sib1Info.mcs = cell->siCb.newSiInfo.sib1Info.mcs; + cell->siCb.crntSiInfo.sib1Info.nPrb = cell->siCb.newSiInfo.sib1Info.nPrb; + cell->siCb.crntSiInfo.sib1Info.msgLen = + cell->siCb.newSiInfo.sib1Info.msgLen; + cell->siCb.siBitMask &= ~RGSCH_SI_SIB1_UPD; + } + + /*Check whether SIs have been updated*/ + if(cell->siCb.siBitMask & RGSCH_SI_SI_UPD) + { + U8 idx; + + /*Check if SI cfg have been modified And Check if numSi have + been changed, if yes then we would need to update the + pointers for all the SIs */ + if((cell->siCb.siBitMask & RGSCH_SI_SICFG_UPD) && + (cell->siCfg.numSi != cell->siCb.newSiCfg.numSi)) + { + for(idx = 0;idx < cell->siCb.newSiCfg.numSi;idx++) + { + RGSCH_SET_SI_INFO(cell->siCb.crntSiInfo.siInfo[idx].si, + cell->siCb.newSiInfo.siInfo[idx].si); + cell->siCb.siArray[idx].si = cell->siCb.crntSiInfo.siInfo[idx].si; + cell->siCb.siArray[idx].isWarningSi = FALSE; + + cell->siCb.crntSiInfo.siInfo[idx].mcs = cell->siCb.newSiInfo.siInfo[idx].mcs; + cell->siCb.crntSiInfo.siInfo[idx].nPrb = cell->siCb.newSiInfo.siInfo[idx].nPrb; + cell->siCb.crntSiInfo.siInfo[idx].msgLen = cell->siCb.newSiInfo.siInfo[idx].msgLen; + } + + /*If numSi have been reduced then we need to free the + pointers at the indexes in crntSiInfo which haven't + been exercised. If numSi has increased then nothing + additional is requires as above handling has taken + care.*/ + if(cell->siCfg.numSi > cell->siCb.newSiCfg.numSi) + { + for(idx = cell->siCb.newSiCfg.numSi; + idx < cell->siCfg.numSi;idx++) + { + RGSCH_FREE_MSG(cell->siCb.crntSiInfo.siInfo[idx].si); + cell->siCb.siArray[idx].si = NULLP; + } + } + } + else + { + /*numSi has not been updated, we just need to update the + pointers for the SIs which are set to NON NULLP */ + /*ccpu00118260 - Correct Update of SIB2 */ + for(idx = 0;idx < cell->siCfg.numSi;idx++) + { + if(NULLP != cell->siCb.newSiInfo.siInfo[idx].si) + { + RGSCH_SET_SI_INFO(cell->siCb.crntSiInfo.siInfo[idx].si, + cell->siCb.newSiInfo.siInfo[idx].si); + + cell->siCb.siArray[idx].si = cell->siCb.crntSiInfo.siInfo[idx].si; + cell->siCb.siArray[idx].isWarningSi = FALSE; + cell->siCb.crntSiInfo.siInfo[idx].mcs = cell->siCb.newSiInfo.siInfo[idx].mcs; + cell->siCb.crntSiInfo.siInfo[idx].nPrb = cell->siCb.newSiInfo.siInfo[idx].nPrb; + cell->siCb.crntSiInfo.siInfo[idx].msgLen = cell->siCb.newSiInfo.siInfo[idx].msgLen; + } + } + } + cell->siCb.siBitMask &= ~RGSCH_SI_SI_UPD; + } + + /*Check whether SI cfg have been updated*/ + if(cell->siCb.siBitMask & RGSCH_SI_SICFG_UPD) + { + cell->siCfg = cell->siCb.newSiCfg; + cell->siCb.siBitMask &= ~RGSCH_SI_SICFG_UPD; + } + + RETVOID; +} + + +/** + * @brief This function implements the selection of the SI + * that is to be scheduled. + * + * @details + * + * Function: rgSCHSelectSi + * Purpose: This function implements the selection of SI + * that is to be scheduled. + * + * Invoked by: Scheduler + * + * @param[in] RgSchCellCb* cell + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PRIVATE Void rgSCHSelectSi +( +RgSchCellCb *cell +) +#else +PRIVATE Void rgSCHSelectSi(cell) +RgSchCellCb *cell; +#endif +{ + CmLteTimingInfo crntTmInfo; + U8 siWinSize; + U16 x; + U16 windowId; + + TRC2(rgSCHSelectSi); + + + crntTmInfo = cell->crntTime; +#ifdef LTEMAC_HDFDD + /* For HDFDD we need scheduling information at least RG_SCH_CMN_DL_DELTA + + RG_SCH_CMN_HARQ_INTERVAL (7) subframes ahead */ + RGSCH_INCR_SUB_FRAME(crntTmInfo, RG_SCH_CMN_DL_DELTA + RG_SCH_CMN_HARQ_INTERVAL); +#else + RGSCH_INCR_SUB_FRAME(crntTmInfo, RG_SCH_CMN_DL_DELTA); +#endif + + siWinSize = cell->siCfg.siWinSize; + + /* Select SI only once at the starting of the new window */ + if(cell->siCb.inWindow) + { + if ((crntTmInfo.sfn % cell->siCfg.minPeriodicity) == 0 && + crntTmInfo.subframe == 0) + { + /* Reinit inWindow at the beginning of every SI window */ + cell->siCb.inWindow = siWinSize - 1; + } + else + { + cell->siCb.inWindow--; + RETVOID; + } + } + else /* New window. Re-init the winSize counter with the window length */ + { + if((cell->siCb.siArray[cell->siCb.siCtx.siId - 1].isWarningSi == TRUE)&& + (cell->siCb.siCtx.retxCntRem != 0)) + { + rgSCHUtlFreeWarningSiPdu(cell); + cell->siCb.siCtx.warningSiFlag = FALSE; + } + + cell->siCb.inWindow = siWinSize - 1; + } + + x = rgSCHCmnGetSiSetId(crntTmInfo.sfn, crntTmInfo.subframe, + cell->siCfg.minPeriodicity); + + /* Window Id within a SI set. This window Id directly maps to a + * unique SI Id */ + windowId = (((crntTmInfo.sfn * RGSCH_NUM_SUB_FRAMES_5G) + + crntTmInfo.subframe) - (x * (cell->siCfg.minPeriodicity * 10))) + / siWinSize; + + if(windowId >= RGR_MAX_NUM_SI) + RETVOID; + + /* Update the siCtx if there is a valid SI and its periodicity + * has occurred */ + if (NULLP != cell->siCb.siArray[windowId].si) + { + /* Warning SI Periodicity is same as SIB2 Periodicity */ + if(((cell->siCb.siArray[windowId].isWarningSi == FALSE) && + (x % (cell->siCfg.siPeriodicity[windowId] + /cell->siCfg.minPeriodicity) == 0)) || + ((cell->siCb.siArray[windowId].isWarningSi == TRUE) && + (x % (cell->siCfg.siPeriodicity[0] + /cell->siCfg.minPeriodicity) == 0))) + { + cell->siCb.siCtx.siId = windowId+1; + cell->siCb.siCtx.retxCntRem = cell->siCfg.retxCnt; + cell->siCb.siCtx.warningSiFlag = cell->siCb.siArray[windowId]. + isWarningSi; + cell->siCb.siCtx.timeToTx.sfn = crntTmInfo.sfn; + cell->siCb.siCtx.timeToTx.subframe = crntTmInfo.subframe; + + RG_SCH_ADD_TO_CRNT_TIME(cell->siCb.siCtx.timeToTx, + cell->siCb.siCtx.maxTimeToTx, (siWinSize - 1)) + } + } + else + {/* Update the siCtx with invalid si Id */ + cell->siCb.siCtx.siId = 0; + } + + RETVOID; +} + + +/** + * @brief This function implements scheduler DL allocation for + * SI. + * + * @details + * + * Function: rgSCHDlSiSched + * Purpose: This function implements scheduler for DL allocation + * for SI. + * + * Invoked by: Scheduler + * + * @param[in] RgSchCellCb* cell + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PRIVATE Void rgSCHDlSiSched +( +RgSchCellCb *cell, +RgSchCmnDlRbAllocInfo *allocInfo, +RgInfSfAlloc *subfrmAlloc +) +#else +PRIVATE Void rgSCHDlSiSched(cell, allocInfo, subfrmAlloc) +RgSchCellCb *cell; +RgSchCmnDlRbAllocInfo *allocInfo; +RgInfSfAlloc *subfrmAlloc; +#endif +{ + CmLteTimingInfo crntTimInfo; + RgSchDlSf *sf; + U8 nPrb = 0; + U8 mcs = 0; + MsgLen msgLen = 0; + U32 rb=0; + RgSchCmnDlCell *cellDl = RG_SCH_CMN_GET_DL_CELL(cell); + /* DwPTS Scheduling Changes Start */ +#ifdef LTE_TDD + U16 lostRe; + U8 cfi = cellDl->currCfi; +#endif + /* DwPTS Scheduling Changes End */ + + TRC2(rgSCHDlSiSched); + + + crntTimInfo = cell->crntTime; +#ifdef LTEMAC_HDFDD + /* For HDFDD we need scheduling information at least RG_SCH_CMN_DL_DELTA + + RG_SCH_CMN_HARQ_INTERVAL (7) subframes ahead */ + RGSCH_INCR_SUB_FRAME(crntTimInfo, RG_SCH_CMN_DL_DELTA + RG_SCH_CMN_HARQ_INTERVAL); +#else + RGSCH_INCR_SUB_FRAME(crntTimInfo, RG_SCH_CMN_DL_DELTA); +#endif + + /* Compute the subframe for which allocation is being made. + Essentially, we need pointer to the dl frame for this subframe */ + sf = rgSCHUtlSubFrmGet(cell, crntTimInfo); + + /*Check if scheduling of MIB is required */ +#ifdef EMTC_ENABLE + /* since we are adding the MIB repetition logic for EMTC UEs, checking if + * emtcEnabled or not, If enabled MIB would be repeted at as part of EMTC + * feature, otherwise scheduling at (n,0) */ + if(0 == cell->emtcEnable) + { +#endif + if((crntTimInfo.sfn % RGSCH_MIB_PERIODICITY == 0) + && (RGSCH_MIB_TX_SF_NUM == crntTimInfo.subframe)) + { + MsgLen mibLen = 0; + U8 sfnOctet, mibOct2 = 0; + U8 mibOct1 = 0; + /*If MIB has not been yet setup by Application, return*/ + if(NULLP == cell->siCb.crntSiInfo.mib) + RETVOID; + + SFndLenMsg(cell->siCb.crntSiInfo.mib, &mibLen); + sf->bch.tbSize = mibLen; + /*Fill the interface information */ + rgSCHUtlFillRgInfCmnLcInfo(sf, subfrmAlloc, NULLD, NULLD); + + /*Set the bits of MIB to reflect SFN */ + /*First get the Most signficant 8 bits of SFN */ + sfnOctet = (U8)(crntTimInfo.sfn >> 2); + /*Get the first two octets of MIB, and then update them + using the SFN octet value obtained above.*/ + if(ROK != SExamMsg((Data *)(&mibOct1), + cell->siCb.crntSiInfo.mib, 0)) + RETVOID; + + if(ROK != SExamMsg((Data *)(&mibOct2), + cell->siCb.crntSiInfo.mib, 1)) + RETVOID; + + /* ccpu00114572- Fix for improper way of MIB Octet setting for SFN */ + mibOct1 = (mibOct1 & 0xFC) | (sfnOctet >> 6); + mibOct2 = (mibOct2 & 0x03) | (sfnOctet << 2); + /* ccpu00114572- Fix ends*/ + + /*Now, replace the two octets in MIB */ + if(ROK != SRepMsg((Data)(mibOct1), + cell->siCb.crntSiInfo.mib, 0)) + RETVOID; + + if(ROK != SRepMsg((Data)(mibOct2), + cell->siCb.crntSiInfo.mib, 1)) + RETVOID; + + /*Copy the MIB msg buff into interface buffer */ + SCpyMsgMsg(cell->siCb.crntSiInfo.mib, + rgSchCb[cell->instIdx].rgSchInit.region, + rgSchCb[cell->instIdx].rgSchInit.pool, + &subfrmAlloc->cmnLcInfo.bchInfo.pdu); + /* Added Dl TB count for MIB message transmission + * This counter is incremented 4 times to consider + * the retransmission at the PHY level on PBCH channel*/ +#ifdef LTE_L2_MEAS + cell->dlUlTbCnt.tbTransDlTotalCnt += RG_SCH_MIB_CNT; +#endif + } +#ifdef EMTC_ENABLE + } +#endif + + allocInfo->bcchAlloc.schdFirst = FALSE; + /*Check if scheduling of SIB1 is required. + Check of (crntTimInfo.sfn % RGSCH_SIB1_PERIODICITY == 0) + is not required here since the below check takes care + of SFNs applicable for this one too.*/ + if((crntTimInfo.sfn % RGSCH_SIB1_RPT_PERIODICITY == 0) + && (RGSCH_SIB1_TX_SF_NUM == crntTimInfo.subframe)) + { + /*If SIB1 has not been yet setup by Application, return*/ + if(NULLP == (cell->siCb.crntSiInfo.sib1Info.sib1)) + { + RETVOID; + } + + allocInfo->bcchAlloc.schdFirst = TRUE; + mcs = cell->siCb.crntSiInfo.sib1Info.mcs; + nPrb = cell->siCb.crntSiInfo.sib1Info.nPrb; + msgLen = cell->siCb.crntSiInfo.sib1Info.msgLen; + } + else + { + /*Check if scheduling of SI can be performed.*/ + Bool invalid = FALSE; + + if(cell->siCb.siCtx.siId == 0) + RETVOID; + + /*Check if the Si-Window for the current Si-Context is completed*/ + invalid = rgSCHCmnChkPastWin(crntTimInfo, cell->siCb.siCtx.maxTimeToTx); + if(invalid) + { + /* LTE_ADV_FLAG_REMOVED_START */ + if(cell->siCb.siCtx.retxCntRem) + { + RGSCHLOGERROR(cell->instIdx,ERRCLS_INT_PAR,ERG011,(ErrVal)cell->siCb.siCtx.siId, + "rgSCHDlSiSched(): SI not scheduled and window expired"); + } + /* LTE_ADV_FLAG_REMOVED_END */ + if(cell->siCb.siCtx.warningSiFlag == TRUE) + { + rgSCHUtlFreeWarningSiPdu(cell); + cell->siCb.siCtx.warningSiFlag = FALSE; + } + RETVOID; + } + + /*Check the timinginfo of the current SI-Context to see if its + transmission can be scheduled. */ + if(FALSE == (rgSCHCmnChkInWin(crntTimInfo, + cell->siCb.siCtx.timeToTx, + cell->siCb.siCtx.maxTimeToTx))) + { + RETVOID; + + } + /*Check if retransmission count has become 0*/ + if(0 == cell->siCb.siCtx.retxCntRem) + { + RETVOID; + } + + /* LTE_ADV_FLAG_REMOVED_START */ + /* Check if ABS is enabled/configured */ + if(RGR_ENABLE == cell->lteAdvCb.absCfg.status) + { + /* The pattern type is RGR_ABS_MUTE, then eNB need to blank the subframe */ + if(cell->lteAdvCb.absCfg.absPatternType & RGR_ABS_MUTE) + { + /* Determine next scheduling subframe is ABS or not */ + if(RG_SCH_ABS_ENABLED_ABS_SF == (RgSchAbsSfEnum)(cell->lteAdvCb.absCfg.absPattern + [((crntTimInfo.sfn*RGSCH_NUM_SUB_FRAMES) + crntTimInfo.subframe) % RGR_ABS_PATTERN_LEN])) + { + /* Skip the SI scheduling to next tti */ + RETVOID; + } + } + } + /* LTE_ADV_FLAG_REMOVED_END */ + + /*Schedule the transmission of the current SI-Context */ + /*Find out the messg length for the SI message */ + /* warningSiFlag is to differentiate between Warning SI + * and Other SI */ + if((rgSCHUtlGetMcsAndNPrb(cell, &nPrb, &mcs, &msgLen)) != ROK) + { + RETVOID; + } + + cell->siCb.siCtx.i = RGSCH_CALC_SF_DIFF(crntTimInfo, + cell->siCb.siCtx.timeToTx); + } + + + /*Get the number of rb required */ + /*rgSCHCmnClcRbAllocForFxdTb(cell, msgLen, cellDl->ccchCqi, &rb);*/ + if(cellDl->bitsPerRb==0) + { + while ((rgTbSzTbl[0][0][rb]) < (U32) (msgLen*8)) + { + rb++; + } + rb = rb+1; + } + else + { + rb = RGSCH_CEIL((msgLen*8), cellDl->bitsPerRb); + } + /* DwPTS Scheduling Changes Start */ +#ifdef LTE_TDD + if (sf->sfType == RG_SCH_SPL_SF_DATA) + { + RGSCH_GET_SPS_SF_CFI(cell->bwCfg.dlTotalBw, cfi); + + /* Calculate the less RE's because of DwPTS */ + lostRe = rb * (cellDl->noResPerRb[cfi] - cellDl->numReDwPts[cfi]); + + /* Increase number of RBs in Spl SF to compensate for lost REs */ + rb += RGSCH_CEIL(lostRe, cellDl->numReDwPts[cfi]); + } +#endif + /* DwPTS Scheduling Changes End */ + /*ccpu00115595- end*/ + /* Additional check to see if required RBs + * exceeds the available */ + if (rb > sf->bw - sf->bwAssigned) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId, "rgSCHDlSiSched(): " + "BW allocation failed CRNTI:%d",RGSCH_SI_RNTI); + RETVOID; + } + + /* Update the subframe Allocated BW field */ + sf->bwAssigned = sf->bwAssigned + rb; + + /*Fill the parameters in allocInfo */ + allocInfo->bcchAlloc.rnti = RGSCH_SI_RNTI; + allocInfo->bcchAlloc.dlSf = sf; + allocInfo->bcchAlloc.rbsReq = rb; + /*ccpu00116710- MCS is not getting assigned */ + allocInfo->bcchAlloc.tbInfo[0].imcs = mcs; + + /* ccpu00117510 - ADD - Assignment of nPrb and other information */ + allocInfo->bcchAlloc.nPrb = nPrb; + allocInfo->bcchAlloc.tbInfo[0].bytesReq = msgLen; + allocInfo->bcchAlloc.tbInfo[0].noLyr = 1; + RETVOID; +} +#endif /*RGR_SI_SCH*/ + + +/* ccpu00117452 - MOD - Changed macro name from + RGR_RRM_DLPWR_CNTRL to RGR_CQI_REPT */ +#ifdef RGR_CQI_REPT +/** + * @brief This function Updates the DL CQI for the UE. + * + * @details + * + * Function: rgSCHCmnUeDlPwrCtColltCqiRept + * Purpose: Manages PUSH N CQI reporting + * Step 1: Store the CQI in collation array + * Step 2: Increament the tracking count + * Step 3: Check is it time to to send the report + * Step 4: if yes, Send StaInd to RRM + * Step 4.1: Fill StaInd for sending collated N CQI rpeorts + * Step 4.2: Call utility function (rgSCHUtlRgrStaInd) to send rpts to RRM + * Step 4.2.1: If sending was not sucessful, return RFAILED + * Step 4.2.2: If sending was sucessful, return ROK + * Step 5: If no, return + * Invoked by: rgSCHCmnDlCqiInd + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ue + * @param[in] RgrUeCqiRept *ueCqiRpt + * @return Void + * + **/ +#ifdef ANSI +PRIVATE S16 rgSCHCmnUeDlPwrCtColltCqiRept +( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgrUeCqiRept *ueCqiRpt +) +#else +PRIVATE S16 rgSCHCmnUeDlPwrCtColltCqiRept(cell, ue, ueCqiRpt) +RgSchCellCb *cell; +RgSchUeCb *ue; +RgrUeCqiRept *ueCqiRpt; +#endif +{ + U8 *cqiCount = NULLP; + S16 retVal; + RgrStaIndInfo *staInfo = NULLP; + + TRC2(rgSCHCmnUeDlPwrCtColltCqiRept) + + /* Step 1: Store the CQI in collation array */ + /* Step 2: Increament the tracking count */ + cqiCount = &(ue->schCqiInfo.cqiCount); + ue->schCqiInfo.cqiRept[(*cqiCount)++] = + *ueCqiRpt; + + + /* Step 3: Check is it time to to send the report */ + if(RG_SCH_CQIR_IS_TIMTOSEND_CQIREPT(ue)) + { + /* Step 4: if yes, Send StaInd to RRM */ + retVal = rgSCHUtlAllocSBuf (cell->instIdx,(Data**)&staInfo, + sizeof(RgrStaIndInfo)); + if (retVal != ROK) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId, "Could not " + "allocate memory for sending StaInd CRNTI:%d",ue->ueId); + RETVALUE(retVal); + } + + /* Step 4.1: Fill StaInd for sending collated N CQI rpeorts */ +#ifdef CA_DBG + { + extern U32 gCqiReptToAppCount; + gCqiReptToAppCount++; + + } + +#endif + retVal = rgSCHUtlFillSndStaInd(cell, ue, staInfo, + ue->cqiReptCfgInfo.numColltdCqiRept); + RETVALUE(retVal); + + } + + RETVALUE(ROK); +} /* End of rgSCHCmnUeDlPwrCtColltCqiRept */ + +#endif /* End of RGR_CQI_REPT */ + +/** + * @brief This function checks for the retransmisson + * for a DTX scenario. + * @details + * + * Function: + * Purpose: + * Invoked by: + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ue + * @param[in] + * @return Void + * + **/ +#ifdef ANSI +PUBLIC Void rgSCHCmnChkRetxAllowDtx +( +RgSchCellCb *cell, +RgSchUeCb *ueCb, +RgSchDlHqProcCb *proc, +Bool *reTxAllwd +) +#else +PUBLIC Void rgSCHCmnChkRetxAllowDtx(cell, ueCb, proc, reTxAllwd) +RgSchCellCb *cell; +RgSchUeCb *ueCb; +RgSchDlHqProcCb *proc; +Bool *reTxAllwd; +#endif +{ + TRC3(rgSCHCmnChkRetxAllowDtx) + + + *reTxAllwd = TRUE; + /* Fix */ + if ((proc->tbInfo[0].isAckNackDtx == TFU_HQFDB_DTX)) + { + *reTxAllwd = FALSE; + } + + RETVOID; +} + +/** + * @brief API for calculating the SI Set Id + * + * @details + * + * Function: rgSCHCmnGetSiSetId + * + * This API is used for calculating the SI Set Id, as shown below + * + * siSetId = 0 siSetId = 1 + * |******************|******************|----------------> + * (0,0) (8,0) (16,0) (SFN, SF) + * + * + * @param[in] U16 sfn + * @param[in] U8 sf + * @return U16 siSetId + **/ +#ifdef ANSI +PUBLIC U16 rgSCHCmnGetSiSetId +( +U16 sfn, +U8 sf, +U16 minPeriodicity +) +#else +PUBLIC U16 rgSCHCmnGetSiSetId(sfn, sf, minPeriodicity) +U16 sfn; +U8 sf +U16 minPeriodicity; +#endif +{ + /* 80 is the minimum SI periodicity in sf. Also + * all other SI periodicities are multiples of 80 */ + RETVALUE (((sfn * RGSCH_NUM_SUB_FRAMES_5G) + sf) / (minPeriodicity * 10)); +} +#ifdef LTE_TDD +/** + * @brief API for calculating the DwPts Rb, Itbs and tbSz + * + * @details + * + * Function: rgSCHCmnCalcDwPtsTbSz + * + * @param[in] RgSchCellCb *cell + * @param[in] U32 bo + * @param[in/out] U8 *rb + * @param[in/out] U8 *iTbs + * @param[in] U8 lyr + * @param[in] U8 cfi + * @return U32 tbSz + **/ +#ifdef ANSI +PRIVATE U32 rgSCHCmnCalcDwPtsTbSz +( +RgSchCellCb *cell, +U32 bo, +U8 *rb, +U8 *iTbs, +U8 lyr, +U8 cfi +) +#else +PRIVATE U32 rgSCHCmnCalcDwPtsTbSz(cell, bo, rb, iTbs, lyr, cfi) +RgSchCellCb *cell; +U32 bo; +U8 *rb; +U8 *iTbs; +U8 lyr; +U8 cfi; +#endif +{ + U32 tbSz; + RgSchCmnDlCell *cellDl = RG_SCH_CMN_GET_DL_CELL(cell); + U32 numRE = *rb * cellDl->noResPerRb[cfi]; + U32 numDwPtsRb = RGSCH_CEIL(numRE, cellDl->numReDwPts[cfi]); + + TRC2(rgSCHCmnCalcDwPtsTbSz); + + /* DwPts Rb cannot exceed the cell Bw */ + numDwPtsRb = RGSCH_MIN(numDwPtsRb, cellDl->maxDlBwPerUe); + + /* Adjust the iTbs for optimum usage of the DwPts region. + * Using the same iTbs adjustment will not work for all + * special subframe configurations and iTbs levels. Hence use the + * static iTbs Delta table for adjusting the iTbs */ + RG_SCH_CMN_ADJ_DWPTS_ITBS(cellDl, *iTbs); + + if (bo) + { + while(rgTbSzTbl[lyr-1][*iTbs][RGSCH_MAX(numDwPtsRb*3/4,1)-1] < bo*8 && + numDwPtsRb < cellDl->maxDlBwPerUe) + { + (numDwPtsRb)++; + } + + tbSz = rgTbSzTbl[lyr-1][*iTbs][RGSCH_MAX(numDwPtsRb*3/4,1)-1]; + } + else + { + tbSz = rgTbSzTbl[lyr-1][*iTbs][RGSCH_MAX(numDwPtsRb*3/4,1)-1]; + } + *rb = numDwPtsRb; + + RETVALUE(tbSz/8); +} + +/** + * @brief API for calculating the DwPts Rb, Itbs and tbSz + * + * @details + * + * Function: rgSCHCmnCalcDwPtsTbSz2Cw + * + * @param[in] RgSchCellCb *cell + * @param[in] U32 bo + * @param[in/out] U8 *rb + * @param[in] U8 maxRb + * @param[in/out] U8 *iTbs1 + * @param[in/out] U8 *iTbs2 + * @param[in] U8 lyr1 + * @param[in] U8 lyr2 + * @return[in/out] U32 *tb1Sz + * @return[in/out] U32 *tb2Sz + * @param[in] U8 cfi + **/ +#ifdef ANSI +PRIVATE Void rgSCHCmnCalcDwPtsTbSz2Cw +( +RgSchCellCb *cell, +U32 bo, +U8 *rb, +U8 maxRb, +U8 *iTbs1, +U8 *iTbs2, +U8 lyr1, +U8 lyr2, +U32 *tb1Sz, +U32 *tb2Sz, +U8 cfi +) +#else +PRIVATE Void rgSCHCmnCalcDwPtsTbSz2Cw(cell, bo, rb, maxRb, iTbs1, iTbs2, + lyr1, lyr2, tb1Sz, tb2Sz, cfi) +RgSchCellCb *cell; +U32 bo; +U8 *rb; +U8 maxRb; +U8 *iTbs1; +U8 *iTbs2; +U8 lyr1; +U8 lyr2; +U32 *tb1Sz; +U32 *tb2Sz; +U8 cfi; +#endif +{ + RgSchCmnDlCell *cellDl = RG_SCH_CMN_GET_DL_CELL(cell); + U32 numRE = *rb * cellDl->noResPerRb[cfi]; + U32 numDwPtsRb = RGSCH_CEIL(numRE, cellDl->numReDwPts[cfi]); + + TRC2(rgSCHCmnCalcDwPtsTbSz2Cw); + + /* DwPts Rb cannot exceed the cell Bw */ + numDwPtsRb = RGSCH_MIN(numDwPtsRb, maxRb); + + /* Adjust the iTbs for optimum usage of the DwPts region. + * Using the same iTbs adjustment will not work for all + * special subframe configurations and iTbs levels. Hence use the + * static iTbs Delta table for adjusting the iTbs */ + RG_SCH_CMN_ADJ_DWPTS_ITBS(cellDl, *iTbs1); + RG_SCH_CMN_ADJ_DWPTS_ITBS(cellDl, *iTbs2); + + while((rgTbSzTbl[lyr1-1][*iTbs1][RGSCH_MAX(numDwPtsRb*3/4,1)-1] + + rgTbSzTbl[lyr2-1][*iTbs2][RGSCH_MAX(numDwPtsRb*3/4,1)-1])< bo*8 && + numDwPtsRb < maxRb) + { + (numDwPtsRb)++; + } + + *tb1Sz = rgTbSzTbl[lyr1-1][*iTbs1][RGSCH_MAX(numDwPtsRb*3/4,1)-1]/8; + *tb2Sz = rgTbSzTbl[lyr2-1][*iTbs2][RGSCH_MAX(numDwPtsRb*3/4,1)-1]/8; + + *rb = numDwPtsRb; + + RETVOID; +} + +#endif + +/** + * @brief Updates the GBR LCGs when datInd is received from MAC + * + * @details + * + * Function: rgSCHCmnUpdUeDataIndLcg(cell, ue, datInd) + * Purpose: This function updates the GBR LCGs + * when datInd is received from MAC. + * + * Invoked by: TOM + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ue + * @param[in] RgInfUeDatInd *datInd + * @return Void + **/ +#ifdef ANSI +PUBLIC Void rgSCHCmnUpdUeDataIndLcg +( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgInfUeDatInd *datInd +) +#else +PUBLIC Void rgSCHCmnUpdUeDataIndLcg(cell, ue, datInd) +RgSchCellCb *cell; +RgSchUeCb *ue; +RgInfUeDatInd *datInd; +#endif +{ + U32 idx = 0; + RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell); +#ifdef DEBUGP + Inst inst = cell->instIdx; +#endif + + TRC2(rgSCHCmnUpdUeDataIndLcg); + + for (idx = 0; (idx < RGINF_MAX_LCG_PER_UE - 1); idx++) + { + if (datInd->lcgInfo[idx].bytesRcvd != 0) + { + U8 lcgId = datInd->lcgInfo[idx].lcgId; + U32 bytesRcvd = datInd->lcgInfo[idx].bytesRcvd; + + if (RGSCH_LCG_ISCFGD(&ue->ul.lcgArr[lcgId])) + { + RgSchCmnLcg *cmnLcg = ((RgSchCmnLcg *)(ue->ul.lcgArr[lcgId].sch)); + if (RGSCH_IS_GBR_BEARER(cmnLcg->cfgdGbr)) + { + if(bytesRcvd > cmnLcg->effGbr) + { + bytesRcvd -= cmnLcg->effGbr; + cmnLcg->effDeltaMbr = (cmnLcg->effDeltaMbr > bytesRcvd) ? \ + (cmnLcg->effDeltaMbr - bytesRcvd) : (0); + cmnLcg->effGbr = 0; + } + else + { + cmnLcg->effGbr -= bytesRcvd; + } + /* To keep BS updated with the amount of data received for the GBR */ + cmnLcg->reportedBs = (cmnLcg->reportedBs > datInd->lcgInfo[idx].bytesRcvd) ? \ + (cmnLcg->reportedBs - datInd->lcgInfo[idx].bytesRcvd) : (0); + cmnLcg->bs = RGSCH_MIN(cmnLcg->reportedBs, cmnLcg->effGbr+cmnLcg->effDeltaMbr); + } + else if(lcgId != 0) + { + ue->ul.effAmbr = (ue->ul.effAmbr > datInd->lcgInfo[idx].bytesRcvd) ? \ + (ue->ul.effAmbr - datInd->lcgInfo[idx].bytesRcvd) : (0); + cmnLcg->reportedBs = (cmnLcg->reportedBs > datInd->lcgInfo[idx].bytesRcvd) ? \ + (cmnLcg->reportedBs - datInd->lcgInfo[idx].bytesRcvd) : (0); + cmnLcg->bs = RGSCH_MIN(cmnLcg->reportedBs, ue->ul.effAmbr); + ue->ul.nonGbrLcgBs = (ue->ul.nonGbrLcgBs > datInd->lcgInfo[idx].bytesRcvd) ? \ + (ue->ul.nonGbrLcgBs - datInd->lcgInfo[idx].bytesRcvd) : (0); + } + ue->ul.nonLcg0Bs = (ue->ul.nonLcg0Bs > datInd->lcgInfo[idx].bytesRcvd) ? \ + (ue->ul.nonLcg0Bs - datInd->lcgInfo[idx].bytesRcvd) : (0); + } + } + else + { + break; + } + } +#ifdef EMTC_ENABLE + if(TRUE == ue->isEmtcUe) + { + if (cellSch->apisEmtcUl->rgSCHRgrUlLcgUpd(cell, ue, datInd) != ROK) + { + RGSCHDBGERRNEW(inst, (rgSchPBuf(inst), "\n rgSCHCmnUpdUeDataIndLcg(): rgSCHRgrUlLcgUpd returned failure")); + } + + } + else +#endif + { + if (cellSch->apisUl->rgSCHRgrUlLcgUpd(cell, ue, datInd) != ROK) + { + RGSCHDBGERRNEW(inst, (rgSchPBuf(inst), "\n rgSCHCmnUpdUeDataIndLcg(): rgSCHRgrUlLcgUpd returned failure")); + } + } +} + + +/** @brief This function initializes DL allocation lists and prepares + * for scheduling + * + * @details + * + * Function: rgSCHCmnInitRbAlloc + * + * @param [in] RgSchCellCb *cell + * + * Returns: Void + * + */ +#ifdef ANSI +PRIVATE Void rgSCHCmnInitRbAlloc +( +RgSchCellCb *cell +) +#else +PRIVATE Void rgSCHCmnInitRbAlloc (cell) +RgSchCellCb *cell; +#endif +{ + RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell); + CmLteTimingInfo frm; + RgSchDlSf *dlSf; + U8 idx; + + TRC2(rgSCHCmnInitRbAlloc); + +/* Initializing RgSchCmnUlRbAllocInfo structure.*/ + rgSCHCmnInitDlRbAllocInfo(&cellSch->allocInfo); + + frm = cellSch->dl.time; + + dlSf = rgSCHUtlSubFrmGet(cell, frm); +#ifdef RG_5GTF + dlSf->numGrpPerTti = cell->cell5gtfCb.ueGrpPerTti; + dlSf->numUePerGrp = cell->cell5gtfCb.uePerGrpPerTti; + for(idx = 0; idx < MAX_5GTF_BEAMS; idx++) + { + dlSf->sfBeamInfo[idx].totVrbgAllocated = 0; + dlSf->sfBeamInfo[idx].totVrbgRequired = 0; + dlSf->sfBeamInfo[idx].vrbgStart = 0; + } +#endif + dlSf->remUeCnt = cellSch->dl.maxUePerDlSf; + /* Updating the Subframe information in RBAllocInfo */ + cellSch->allocInfo.dedAlloc.dedDlSf = dlSf; + cellSch->allocInfo.msg4Alloc.msg4DlSf = dlSf; + + /* LTE_ADV_FLAG_REMOVED_START */ + /* Determine next scheduling subframe is ABS or not */ + if(RGR_ENABLE == cell->lteAdvCb.absCfg.status) + { + cell->lteAdvCb.absPatternDlIdx = + ((frm.sfn*RGSCH_NUM_SUB_FRAMES_5G) + frm.subframe) % RGR_ABS_PATTERN_LEN; + cell->lteAdvCb.absDlSfInfo = (RgSchAbsSfEnum)(cell->lteAdvCb.absCfg.absPattern[ + cell->lteAdvCb.absPatternDlIdx]); + + } + else + { + cell->lteAdvCb.absDlSfInfo = RG_SCH_ABS_DISABLED; + } + /* LTE_ADV_FLAG_REMOVED_END */ + +#ifdef RGR_V1 + cellSch->allocInfo.ccchSduAlloc.ccchSduDlSf = dlSf; +#endif +#ifdef LTEMAC_SPS + /* Update subframe-wide allocation information with SPS allocation */ + rgSCHCmnSpsDlUpdDlSfAllocWithSps(cell, frm, dlSf); +#endif + RETVOID; +} + + + +#ifdef DL_LA +/** + * @brief Check & Updates the TM Mode chnage threashold based on cqiiTbs and + * actual iTbs + * + * @details + * + * Function: rgSCHCmnSendTxModeInd(cell, ueUl, newTxMode) + * Purpose: This function sends the TX mode Change + * indication to RRM + * change + * + * Invoked by: CMN + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ue + * @param[in] U8 newTxMode + * @return Void + **/ +#ifdef ANSI +PRIVATE Void rgSCHCmnSendTxModeInd +( +RgSchCellCb *cell, +RgSchUeCb *ue, +U8 newTxMode +) +#else +PRIVATE Void rgSCHCmnSendTxModeInd(cell, ue, newTxMode) +RgSchCellCb *cell; +RgSchUeCb *ue; +U8 newTxMode; +#endif +{ + RgmTransModeInd *txModeChgInd; + RgSchCmnDlUe *ueDl = RG_SCH_CMN_GET_DL_UE(ue,cell); + + TRC2(rgSCHCmnSendTxModeInd); + + if(!(ueDl->mimoInfo.forceTD & RG_SCH_CMN_TD_TXMODE_RECFG)) + { + /* Mem Alloc */ + if(SGetSBuf(cell->rgmSap->sapCfg.sapPst.region, + cell->rgmSap->sapCfg.sapPst.pool, (Data**)&txModeChgInd, + sizeof(RgmTransModeInd)) != ROK) + { + RETVOID; + } + RG_SCH_FILL_RGM_TRANSMODE_IND(ue->ueId, cell->cellId, newTxMode, txModeChgInd); + RgUiRgmChangeTransModeInd(&(cell->rgmSap->sapCfg.sapPst), + cell->rgmSap->sapCfg.suId, txModeChgInd); + } + + ue->mimoInfo.txModUpChgFactor = 0; + ue->mimoInfo.txModDownChgFactor = 0; + ueDl->laCb[0].deltaiTbs = 0; + + RETVOID; +} + +/** + * @brief Check & Updates the TM Mode chnage threashold based on cqiiTbs and + * actual iTbs + * + * @details + * + * Function: rgSchCheckAndTriggerModeChange(cell, ueUl, iTbsNew) + * Purpose: This function update and check for threashold for TM mode + * change + * + * Invoked by: CMN + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ue + * @param[in] U8 iTbs + * @return Void + **/ +#ifdef ANSI +PUBLIC Void rgSchCheckAndTriggerModeChange +( +RgSchCellCb *cell, +RgSchUeCb *ue, +U8 reportediTbs, +U8 previTbs, +U8 maxiTbs +) +#else +PUBLIC Void rgSchCheckAndTriggerModeChange(cell, ue, reportediTbs, previTbs, maxiTbs) +RgSchCellCb *cell; +RgSchUeCb *ue; +U8 reportediTbs; +U8 previTbs; +U8 maxiTbs; +#endif +{ + RgrTxMode txMode; /*!< UE's Transmission Mode */ + RgrTxMode modTxMode; /*!< UE's Transmission Mode */ + + TRC2(rgSchCheckAndTriggerModeChange); + + txMode = ue->mimoInfo.txMode; + + /* Check for Step down */ + /* Step down only when TM4 is configured. */ + if(RGR_UE_TM_4 == txMode) + { + if((previTbs <= reportediTbs) && ((reportediTbs - previTbs) >= RG_SCH_MODE_CHNG_STEPDOWN_CHECK_FACTOR)) + { + ue->mimoInfo.txModDownChgFactor += RG_SCH_MODE_CHNG_STEPUP_FACTOR; + } + else + { + ue->mimoInfo.txModDownChgFactor -= RG_SCH_MODE_CHNG_STEPDOWN_FACTOR; + } + + ue->mimoInfo.txModDownChgFactor = + RGSCH_MAX(ue->mimoInfo.txModDownChgFactor, -(RG_SCH_MODE_CHNG_STEPDOWN_THRSHD)); + + if(ue->mimoInfo.txModDownChgFactor >= RG_SCH_MODE_CHNG_STEPDOWN_THRSHD) + { + /* Trigger Mode step down */ + modTxMode = RGR_UE_TM_3; + rgSCHCmnSendTxModeInd(cell, ue, modTxMode); + } + } + + /* Check for Setup up */ + /* Step Up only when TM3 is configured, Max possible Mode is TM4*/ + if(RGR_UE_TM_3 == txMode) + { + if((previTbs > reportediTbs) || (maxiTbs == previTbs)) + { + ue->mimoInfo.txModUpChgFactor += RG_SCH_MODE_CHNG_STEPUP_FACTOR; + } + else + { + ue->mimoInfo.txModUpChgFactor -= RG_SCH_MODE_CHNG_STEPDOWN_FACTOR; + } + + ue->mimoInfo.txModUpChgFactor = + RGSCH_MAX(ue->mimoInfo.txModUpChgFactor, -(RG_SCH_MODE_CHNG_STEPUP_THRSHD)); + + /* Check if TM step up need to be triggered */ + if(ue->mimoInfo.txModUpChgFactor >= RG_SCH_MODE_CHNG_STEPUP_THRSHD) + { + /* Trigger mode chnage */ + modTxMode = RGR_UE_TM_4; + rgSCHCmnSendTxModeInd(cell, ue, modTxMode); + } + } + + RETVOID; +} +#endif + +/** +* @brief Updates the GBR LCGs when datInd is received from MAC + * + * @details + * + * Function: rgSCHCmnIsDlCsgPrio (cell) + * Purpose: This function returns if csg UEs are + * having priority at current time + * + * Invoked by: Scheduler + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ue + * @param[in] RgInfUeDatInd *datInd + * @return Void + **/ +#ifdef ANSI +PUBLIC Bool rgSCHCmnIsDlCsgPrio +( +RgSchCellCb *cell +) +#else +PUBLIC Bool rgSCHCmnIsDlCsgPrio(cell) +RgSchCellCb *cell; +#endif +{ + + RgSchCmnDlCell *cmnDlCell = RG_SCH_CMN_GET_DL_CELL(cell); + + TRC2(rgSCHCmnIsDlCsgPrio) + /* Calculating the percentage resource allocated */ + if(RGR_CELL_ACCS_HYBRID != rgSchCb[cell->instIdx].rgrSchedEnbCfg.accsMode) + { + RETVALUE(FALSE); + } + else + { + if(((cmnDlCell->ncsgPrbCnt * 100) / cmnDlCell->totPrbCnt) < cell->minDlResNonCsg) + { + RETVALUE(FALSE); + } + else + { + RETVALUE(TRUE); + } + } +} + +/** +* @brief Updates the GBR LCGs when datInd is received from MAC + * + * @details + * + * Function: rgSCHCmnIsUlCsgPrio (cell) + * Purpose: This function returns if csg UEs are + * having priority at current time + * + * Invoked by: Scheduler + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ue + * @param[in] RgInfUeDatInd *datInd + * @return Void + **/ +#ifdef ANSI +PUBLIC Bool rgSCHCmnIsUlCsgPrio +( +RgSchCellCb *cell +) +#else +PUBLIC Bool rgSCHCmnIsUlCsgPrio(cell) +RgSchCellCb *cell; +#endif +{ + RgSchCmnUlCell *cmnUlCell = RG_SCH_CMN_GET_UL_CELL(cell); + + TRC2(rgSCHCmnIsUlCsgPrio) + + /* Calculating the percentage resource allocated */ + if(RGR_CELL_ACCS_HYBRID != rgSchCb[cell->instIdx].rgrSchedEnbCfg.accsMode) + { + RETVALUE(FALSE); + } + else + { + if (((cmnUlCell->ncsgPrbCnt * 100) /cmnUlCell->totPrbCnt) < cell->minUlResNonCsg) + { + RETVALUE(FALSE); + } + else + { + RETVALUE(TRUE); + } + } +} +/********************************************************************** + + End of file +**********************************************************************/ diff --git a/src/5gnrmac/rg_sch_cmn.h b/src/5gnrmac/rg_sch_cmn.h new file mode 100755 index 000000000..af8770626 --- /dev/null +++ b/src/5gnrmac/rg_sch_cmn.h @@ -0,0 +1,863 @@ +/******************************************************************************* +################################################################################ +# Copyright (c) [2017-2019] [Radisys] # +# # +# 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. # +################################################################################ +*******************************************************************************/ + +/********************************************************************** + Name: LTE MAC SC1 scheduler + + Type: C header file + + Desc: Defines required by SC1 scheduler + + File: rg_sch_cmn.h + +*********************************************************************21*/ + + +#ifndef __RGSCHCMNH__ +#define __RGSCHCMNH__ +#ifdef __cplusplus +extern "C" { +#endif + + +/*********************************************************************** + Macro Definitions + ***********************************************************************/ + +/* Scheduler1 tunable params */ +#define RG_SCH_CMN_GET_DL_SCHED_TYPE(cell) rgSchCb[cell->instIdx].rgrSchedEnbCfg.dlSchdType +#define RG_SCH_CMN_GET_UL_SCHED_TYPE(cell) rgSchCb[cell->instIdx].rgrSchedEnbCfg.ulSchdType +#define RG_SCH_CMN_GET_SCHED_CFG(cell) rgSchCb[cell->instIdx].rgrSchedEnbCfg +#define RG_SCH_CMN_GET_ANT_PORTS(cell) rgSchCb[cell->instIdx].rgrSchedEnbCfg.numTxAntPorts +#define RG_SCH_CMN_GET_CELL(cell) ((RgSchCmnCell *)((cell)->sc.sch)) +#define RG_SCH_CMN_GET_UL_CELL(cell) &(((RgSchCmnCell *)((cell)->sc.sch))->ul) +#define RG_SCH_CMN_GET_DL_CELL(cell) &(((RgSchCmnCell *)((cell)->sc.sch))->dl) +#define RG_SCH_CMN_GET_CMN_UE(ue) &(((RgSchCmnUe *)(((ue)->cellInfo[0])->sch))->cmn) +#define RG_SCH_CMN_GET_UE(_ue,_cell) ((RgSchCmnUe *)((_ue->cellInfo[(_ue->cellIdToCellIdxMap\ + [RG_SCH_CELLINDEX(_cell)])])->sch)) +#define RG_SCH_CMN_GET_UL_UE(_ue,_cell) (&(((RgSchCmnUe *)((_ue->cellInfo[_ue->cellIdToCellIdxMap\ + [RG_SCH_CELLINDEX(_cell)]])->sch))->ul)) +#define RG_SCH_CMN_GET_DL_UE(_ue,_cell) (&(((RgSchCmnUe *)((_ue->cellInfo[_ue->cellIdToCellIdxMap\ + [RG_SCH_CELLINDEX(_cell)]])->sch))->dl)) +#define RG_SCH_CMN_GET_UE_HQE(_ue,_cell) (_ue->cellInfo[_ue->cellIdToCellIdxMap\ + [RG_SCH_CELLINDEX(_cell)]]->hqEnt) + +#define RG_SCH_CMN_GET_DL_HQP(hqP) ((RgSchCmnDlHqProc *)((hqP)->sch)) +#define RG_SCH_CMN_GET_DL_SVC(svc) ((RgSchCmnDlSvc *)((svc)->sch)) +#define RG_SCH_CMN_GET_UL_LCG(lcg) ((RgSchCmnLcg *)((lcg)->sch)) + +/*f1b_Sprint3*/ +#define RG_SCH_IS_CELL_SEC(ue,cell) (((ue)->cellInfo[0]->sCellId != cell->cellId)? TRUE: FALSE) +/*#define RG_SCH_IS_CELL_SEC(_ue,_cell) (((_ue)->cell != _cell)? TRUE: FALSE)*/ +/*f1b_Sprint3*/ + +#define RG_SCH_CMN_GET_LC_SCH_SPFC(_ue,_svc,_cell) (((RgSchCmnDlSvc *)(_svc->sch))->schSpfc[\ + _ue->cellIdToCellIdxMap[RG_SCH_CELLINDEX(_cell)]]) +#define RG_SCH_CMN_GET_PA(_ue,_cell) (_ue->cellInfo[_ue->cellIdToCellIdxMap\ + [RG_SCH_CELLINDEX(_cell)]]->pA) +/* Changing the check for retransmission - now checking if alloc + * is non NULL instead of using the isRetx field of the harq Proc. + */ +#define RG_SCH_CMN_IS_UL_UE_RETX(_ue, _cell) ((&RG_SCH_CMN_GET_UL_UE(_ue, _cell)->hqEnt.hqProcCb[\ + ((RgSchCmnCell *)(ue->cell->sc.sch))->ul.schdHqProcIdx])->alloc) + + /* Get acqiCb from appropiate ScellInfo */ +#define RG_SCH_CMN_GET_ACQICB(_ue,_cell) &(((_ue->cellInfo[_ue->cellIdToCellIdxMap\ + [RG_SCH_CELLINDEX(_cell)]])->acqiCb)) + +#define RG_SCH_CMN_GET_SCELL_INFO(_ue,_cell) (_ue->cellInfo[_ue->cellIdToCellIdxMap\ + [RG_SCH_CELLINDEX(_cell)]]) + +#define RG_SCH_CMN_GET_PCELL_INFO(_ue) (_ue->cellInfo[0]) + + /* Added support for SPS*/ +#ifdef LTEMAC_SPS +#define RGSCH_SPS_MAX_SPS_ACTVN_BO 400 +#define RGSCH_SPS_MAX_DL_HQP_TX 4 +#define RGSCH_SPS_MAX_UL_ACT_CRC_FAIL 3 +#define RGSCH_SPS_MAX_UL_SPS_OCC_CRC_FAIL 3 +#define RGSCH_SPS_MAX_UL_REL_PDCCH 2 +#define RG_SCH_CMN_GET_UL_SPS_CELL(cell) &(((RgSchCmnCell *)((cell)->sc.sch))->ul.ulSpsInfo) +#define RG_SCH_CMN_GET_UL_SPS_UE(_ue,_cell) &(_ue->ul.ulSpsInfo) +#define RG_SCH_CMN_SID_PACKET_SIZE 10 +#define RG_SCH_CMN_SPS_BSR_HEADROOM 6 /* PHR 2 bytes + Long BSR 4 bytes*/ + + +#define RGSCH_CMN_MIN_SCALABLE_CQI RGSCH_SPS_CQI_SCALE_FACTOR+1 +/* Introduced timing delta for DL control in FDD */ +#ifdef LTE_TDD +#define RGSCH_SPS_UL_LCM 40 /* Default lcm to start the spsSfTbl with */ +#else +#define RGSCH_SPS_UL_DELTA (TFU_DLCNTRL_DLDELTA + RGSCH_PDCCH_PUSCH_DELTA) +#define RGSCH_SPS_UL_LCM 20 /* Default lcm to start the spsSfTbl with */ +#endif + + + +#define RG_SCH_CMN_IS_SPS_SCHD(_ue, _cell) (((((&RG_SCH_CMN_GET_UL_UE(_ue, _ue->cell)->hqEnt.hqProcCb[\ + ((RgSchCmnCell *)(_ue->cell->sc.sch))->ul.schdHqProcIdx])->alloc) &&\ +((&RG_SCH_CMN_GET_UL_UE(_ue, _ue->cell)->hqEnt.hqProcCb[\ + ((RgSchCmnCell *)(_ue->cell->sc.sch))->ul.schdHqProcIdx])->alloc->rnti == _ue->spsRnti) ? TRUE:FALSE)) || \ + (_ue->ul.relPdcchSchdTime.sfn == _cell->crntTime.sfn && _ue->ul.relPdcchSchdTime.subframe == _cell->crntTime.subframe)) +#endif /* LTEMAC_SPS */ + +/* RRM_SP1_START */ +#define RG_SCH_CALC_GBR_UTILIZATION(_cell, _lcCb, _prbUsed) {\ + if(_lcCb->qciCb->qci <= RGM_MAX_QCI_REPORTS)\ + {\ + _cell->prbUsage.qciPrbRpts[_lcCb->qciCb->qci-1].dlTotPrbUsed += _prbUsed;\ + _cell->prbUsage.qciPrbRpts[_lcCb->qciCb->qci-1].qci = _lcCb->qciCb->qci;\ + }\ +} +/* RRM_SP1_END */ + + + /* This is added due to the limitation in BRDCM Platform + * BRDCM support only one Aperiodic Cqi reception in one UL Sf at lower MCS + * Note: Should be removed once BRDCM provides support for this */ +#define RG_SCH_MAX_ACQI_PER_ULSF 1 + +#define RG_SCH_CMN_IS_UE_SCHDLD(_ue, _cell) (((RgSchCmnUe *)((_ue->cellInfo[_ue->cellIdToCellIdxMap\ + [RG_SCH_CELLINDEX(_cell)]])->sch))->dl.proc != NULLP) +#define RG_SCH_CMN_PROC_SLCTD_FOR_RETX(proc) ((proc->tbInfo[0].txCntr!=0) ||\ + (proc->tbInfo[1].txCntr!=0)) +#define RG_SCH_CMN_DL_IS_UE_ACTIVE(ue) (ue->dl.dlInactvMask == 0) +#define RG_SCH_CMN_UL_IS_UE_ACTIVE(ue) (ue->ul.ulInactvMask == 0) +/* ulInactvMask and dlInactvMask are simulataneously set/reset + * hence check against one suffices */ +#define RG_SCH_CMN_IS_UE_PDCCHODR_INACTV(ue) (ue->ul.ulInactvMask & RG_PDCCHODR_INACTIVE) + +/* Adding routines to check Ue's Active state before triggering UE's Active transition */ +#define RG_SCH_CMN_DL_UPDT_INACTV_MASK( cellCb, ue, maskElmnt) \ + if(RG_SCH_CMN_DL_IS_UE_ACTIVE(ue)) \ + { \ + ue->dl.dlInactvMask &= ~maskElmnt; \ + } \ + else \ + { \ + ue->dl.dlInactvMask &= ~maskElmnt; \ + if(RG_SCH_CMN_DL_IS_UE_ACTIVE(ue)) \ + { \ + rgSCHUtlDlActvtUe(cellCb, ue); \ + } \ + } + +#define RG_SCH_CMN_UL_UPDT_INACTV_MASK( cellCb, ue, maskElmnt) \ + if(RG_SCH_CMN_UL_IS_UE_ACTIVE(ue)) \ + { \ + ue->ul.ulInactvMask &= ~maskElmnt; \ + } \ + else \ + { \ + ue->ul.ulInactvMask &= ~maskElmnt; \ + if(RG_SCH_CMN_UL_IS_UE_ACTIVE(ue)) \ + { \ + rgSCHUtlUlActvtUe(cellCb, ue); \ + } \ + } + +#define RG_SCH_CMN_CSG_REFRESH_TIME 16 +#define RG_SCH_CMN_OVRLDCTRL_REFRESH_TIME 50 + +/* totPrbCnt is set to 1 to avoid division by zero */ +#define RG_SCH_RESET_HCSG_DL_PRB_CNTR(_cmnDlCell) \ +{ \ + (_cmnDlCell)->ncsgPrbCnt = 0; \ + (_cmnDlCell)->totPrbCnt = 1; \ +} + +#define RG_SCH_RESET_HCSG_UL_PRB_CNTR(_cmnUlCell) \ +{ \ + (_cmnUlCell)->ncsgPrbCnt = 0; \ + (_cmnUlCell)->totPrbCnt = 1; \ +} + +#define RG_SCH_CMN_DL_SVC_IS_GBR(svc) ((((RgSchCmnDlSvc*)(svc->sch))->qci >= RG_SCH_CMN_GBR_QCI_START) && \ + (((RgSchCmnDlSvc*)(svc->sch))->qci <= RG_SCH_CMN_GBR_QCI_END)) + +/* Moved the below tables to rg_env_*.h files */ + + +#define RG_SCH_CMN_SET_FORCE_TD(_ue,_cell, _event)\ + {\ + RgSchCmnDlUe *_ueDl = RG_SCH_CMN_GET_DL_UE(_ue,_cell);\ + _ueDl->mimoInfo.forceTD |= (_event);\ + } +#define RG_SCH_CMN_UNSET_FORCE_TD(_ue,_cell, _event)\ + {\ + RgSchCmnDlUe *_ueDl = RG_SCH_CMN_GET_DL_UE(_ue,_cell);\ + _ueDl->mimoInfo.forceTD &= ~(_event);\ + } +#define RG_SCH_CMN_INIT_FORCE_TD(_ue,_cell, _val)\ + {\ + RgSchCmnDlUe *_ueDl = RG_SCH_CMN_GET_DL_UE(_ue,_cell);\ + _ueDl->mimoInfo.forceTD = (_val);\ + } + +#define RG_SCH_CMN_DL_TBS_TO_MCS(x, y) do {\ + if (x <= 9) y = x; \ + else if (x <= 15) y = x + 1; \ + else y = x + 2;\ +} while(0) + +#define RG_SCH_CMN_DL_MCS_TO_TBS(x, y) do {\ + if (x <= 9) y = x; \ + else if (x <= 16) y = x - 1; \ + else y = x - 2; \ +}while(0) + +#define RG_SCH_CMN_UL_TBS_TO_MCS(x, y) do {\ + if (x <= 10) y = x; \ + else if (x <= 19) y = x + 1; \ + else y = x + 2;\ +} while(0) + +#ifdef LTE_TDD +#define RG_SCH_CMN_CHK_DL_DATA_ALLOWED(_cell, _idx)\ +(rgSchTddUlDlSubfrmTbl[_cell->ulDlCfgIdx][_idx] == RG_SCH_TDD_DL_SUBFRAME) ||\ +((rgSchTddUlDlSubfrmTbl[_cell->ulDlCfgIdx][_idx] == RG_SCH_TDD_SPL_SUBFRAME) &&\ + (_cell->splSubfrmCfg.isDlDataAllowed == TRUE)) +#define RG_SCH_CMN_ADJ_DWPTS_ITBS(_cellDl, _iTbs) \ +{\ + if (_iTbs > 0)\ + {\ + _iTbs += rgSchCmnSplSfDeltaItbs[_cellDl->splSfCfg];\ + if ((S8)_iTbs < 0)\ + {\ + _iTbs = 0;\ + }\ + }\ + if (_iTbs > 26)\ + {\ + _iTbs = 26;\ + }\ +} +#endif + +/* RACHO start */ +/* minimum grant, in bytes, to be given to HO and pdcchOrdered UEs */ +#define RG_SCH_MIN_GRNT_HOPO 2 +/* maximum dedPrmbls */ +#define RG_SCH_MAX_DED_PRMBLS 60 +/* is PDCCH order generation supported */ +#define RG_SCH_CMN_IS_PO_SPRTD(cell) (cell->rachCfg.raOccasion.sfnEnum != RGR_SFN_NA) +/* Min gap value between crntTime and time of PRACH Oppurtunity */ +/* RG_SCH_CMN_DL_DELTA is the number of SFs from crntTime at which + * UE is expected to recieve PDCCH Order. + * n+6 as per 213 6.1.1 last para */ +#define RG_SCH_CMN_MIN_PRACH_OPPR_GAP (6+RG_SCH_CMN_DL_DELTA) +/* Idle time threshold in terms of subframes, implies + * the max duration between a TA expiry and latest UL + * data/Signal transmission time */ + /* Fix : syed Ignore if TaTmr is not configured */ +#define RG_SCH_CMN_UE_IDLE_THRSLD(ue) (RG_SCH_CMN_UE_IDLETIME_FCTR * ue->dl.taCb.cfgTaTmr) +/* R8 Upgrade */ +#define RG_SCH_CMN_GET_BI_VAL(prevVal,numUe) ( prevVal + ( numUe * RG_SCH_CMN_BI_NUMUE_FACTOR )) +#define RG_SCH_CMN_NUMUE_FACTOR 1 +#define RG_SCH_CMN_BITBL_INDEX(x) ((x/RG_SCH_CMN_NUMUE_FACTOR)>=12)? 12:(x/RG_SCH_CMN_NUMUE_FACTOR) +#define RG_SCH_CMN_GET_BI(numUe) rgSchCmnBiTbl[RG_SCH_CMN_BITBL_INDEX((numUe))] +/* RACHO end */ + +#define RG_SCH_CMN_SVC_IS_GBR(svc) ((((RgSchCmnDlSvc*)(svc->sch))->qci >= RG_SCH_CMN_GBR_QCI_START) && \ + (((RgSchCmnDlSvc*)(svc->sch))->qci <= RG_SCH_CMN_GBR_QCI_END)) + +#define RG_SCH_CMN_SVC_IS_AMBR(svc) ((((RgSchCmnDlSvc*)(svc->sch))->qci > RG_SCH_CMN_GBR_QCI_END) && \ + (((RgSchCmnDlSvc*)(svc->sch))->qci <= RG_SCH_CMN_MAX_QCI)) + +#define RG_SCH_CMN_TBS_TO_MODODR(x, y) do {\ + if (x <= 5) y = 2; \ + else if (x <= 10) y = 4; \ + else y = 6;\ +} while(0) + +/* To include the length and ModOrder in DataRecp Req. */ +#define RG_SCH_UL_MCS_TO_MODODR(x, y) do {\ + RGSCH_ARRAY_BOUND_CHECK(0, rgUlIMcsTbl, x); \ + y = (TfuModScheme)rgUlIMcsTbl[x].qm;\ +} while(0) + +#define RG_SCH_CMN_ITBS_TO_RETX_IMCS(iTbs, iMcs) do {\ + if ((iTbs) <= 9) (iMcs) = 29; \ + else if ((iTbs) <= 15) (iMcs) = 30; \ + else (iMcs) = 31;\ +} while(0) + +/* Fix for ccpu00123919: In case of RETX TB scheduling avoiding recomputation of RB + * and Tbs. Set all parameters same as Init TX except RV(only for NACKED) and + * MCS. */ +#define RG_SCH_CMN_GET_MCS_FOR_RETX(tb, retxMcs) do {\ + if ((tb->isAckNackDtx == TFU_HQFDB_DTX)) { \ + retxMcs = tb->dlGrnt.iMcs; \ + } \ + else { \ + if (tb->dlGrnt.iMcs < 29) {\ + U8 _iTbs;\ + RG_SCH_CMN_DL_MCS_TO_TBS(tb->dlGrnt.iMcs, _iTbs);\ + RG_SCH_CMN_ITBS_TO_RETX_IMCS(_iTbs, retxMcs); \ + } \ + else {\ + retxMcs = tb->dlGrnt.iMcs; \ + }\ + }\ +}while(0) + +#define RG_SCH_CMN_DL_TBS_TO_MCS_DTX(proc, iTbs, imcs) do {\ + if ((proc->isAckNackDtx == TFU_HQFDB_DTX)) { \ + RG_SCH_CMN_DL_TBS_TO_MCS(iTbs, imcs); \ + } \ + else { \ + RG_SCH_CMN_ITBS_TO_RETX_IMCS(iTbs, imcs); \ + } \ +}while(0) + +#define RG_SCH_CMN_UL_IS_CQI_VALID(cqi) ((cqi) > 0 && (cqi) < RG_SCH_CMN_UL_NUM_CQI) + +#ifdef CCPU_OPT +#define RG_SCH_CMN_DL_GET_HDR_EST(svc, hdrEst) do {\ + hdrEst = svc->estRlcHdrSz;\ + hdrEst += RG_SCH_CMN_DED_MAX_HDRSIZE * RG_SCH_CMN_MAX_DED_SDU;\ + if (svc->staPduPrsnt) \ + {\ + hdrEst += RG_SCH_CMN_DED_MAX_HDRSIZE;\ + }\ +} while(0) +#else +#define RG_SCH_CMN_DL_GET_HDR_EST(svc, hdrEst) do {\ + hdrEst = RG_SCH_CMN_DED_MAX_HDRSIZE * RG_SCH_CMN_MAX_DED_SDU;\ +} while(0) +#endif + +#define RGSCH_CMN_MIN_GRNT_HDR (RG_SCH_CMN_DED_MAX_HDRSIZE * RG_SCH_CMN_MAX_DED_SDU + 1) + +#define RG_SCH_CMN_MAX_UL_CONTRES_GRNT 4 +#define RG_SCH_CMN_UL_PRIOS RG_SCH_CMN_MAX_PRIO + 1 +#define RG_SCH_CMN_MAX_ALLOC_TRACK 10 +/* Introduced timing delta for UL control in FDD*/ +#define RG_SCH_CMN_MIN_BSR_RECP_INTRVL (TFU_ULCNTRL_DLDELTA + RGSCH_PDCCH_PUSCH_DELTA) +#define RG_SCH_CMN_MIN_MSG3_RECP_INTRVL RG_SCH_CMN_DL_DELTA + RGSCH_RARSP_MSG3_DELTA +/* Introduced timing delta for DL control in FDD */ +/* This interval RG_SCH_CMN_MIN_RETXMSG3_RECP_INTRVL is used in FDD only */ +#ifndef LTE_TDD +#define RG_SCH_CMN_MIN_RETXMSG3_RECP_INTRVL (TFU_DLCNTRL_DLDELTA + RGSCH_PDCCH_PUSCH_DELTA) +#endif +/* Fixing the priority table to be more in line with the spec 23.203,table + * 6.1.7 */ +#define RG_SCH_CMN_QCI_TO_PRIO {1, 3, 2, 4, 0, 5, 6, 7, 8} +#define RG_SCH_CMN_DCCH_PRIO 0 + +#define RG_SCH_CMN_GBR_QCI_START 1 +#define RG_SCH_CMN_GBR_QCI_END 4 +#define RG_SCH_CMN_NGBR_QCI_START 6 +#define RG_SCH_CMN_NGBR_QCI_END 9 + + +#define RG_SCH_CMN_UL_GBR_PRIO_START 1 +#define RG_SCH_CMN_UL_GBR_PRIO_END 4 +/* Introduced min & max qci for validation of qci */ +#define RG_SCH_CMN_MIN_QCI 1 +#define RG_SCH_CMN_MAX_QCI 9 +#define RG_SCH_CMN_NUM_QCI 9 +#define RG_SCH_CMN_MAX_CP 2 +#define RG_SCH_CMN_NOR_CP 0 +#define RG_SCH_CMN_EXT_CP 1 +#define RG_SCH_CMN_NUM_TBS 27 +#define RG_SCH_CMN_MAX_CQI 16 +#define RG_SCH_CMN_NUM_DCI 5 /* 6-0A, 6-1A, 6-0B, 6-1B and 6-2 */ +#define RB_SCH_CMN_NUM_SCS_PER_RB 12 +#define RG_SCH_CMN_NUM_RBS 110 +#define RG_SCH_CMN_UL_NUM_SF RGSCH_NUM_UL_HQ_PROC+8 +#define RG_SCH_CMN_UL_NUM_RE_PER_RB(cell) ((cell)->ulNumRePerRb) +#ifdef LTE_TDD +#define RG_SCH_CMN_MAX_CMN_PDCCH 6 +#else +#define RG_SCH_CMN_MAX_CMN_PDCCH 4 +#endif +#define RG_SCH_CMN_UL_MAX_CQI 16 +#define RG_SCH_CMN_UL_SR_BYTES 1 +/* Refresh Timer Defines */ +/* MS_WORKAROUND : syed tuning refresh time to 100ms for PFS */ +#define RG_SCH_CMN_REFRESH_TIME 32 /* Refresh time/cycle in frames (10ms) */ +/* Fix: syed align multiple UEs to refresh at same time */ +#define RG_SCH_CMN_REFRESH_TIMERES 10 +#define RG_SCH_CMN_NUM_REFRESH_Q 16 +#define RG_SCH_CMN_EVNT_UE_REFRESH 1 + +#define RG_SCH_CMN_TPC_ACC_DEC_THRESHOLD 1 +#define RG_SCH_CMN_TPC_ACC_INC_1DB_THRESHOLD 1 +#define RG_SCH_CMN_TPC_ACC_INC_3DB_THRESHOLD 3 +#define RG_SCH_CMN_TPC_ABS_DEC_4DB_THRESHOLD 4 +#define RG_SCH_CMN_TPC_ABS_DEC_1DB_THRESHOLD 1 +#define RG_SCH_CMN_TPC_ABS_INC_1DB_THRESHOLD 4 +#define RG_SCH_CMN_TPC_ABS_INC_4DB_THRESHOLD 4 + +/* ccpu00117606 - ADD - Include CRS REs while calculating Efficiency */ +#define RG_SCH_CMN_MAX_ANT_CONF 3 +#define RG_SCH_CMN_NUM_SLOTS_PER_SF 2 +/* ccpu00117606 - ADD - Defines for Effective Cell RS for different Tx Ant Ports */ +#define RG_SCH_CMN_EFF_CRS_ONE_ANT_PORT 6 +#define RG_SCH_CMN_EFF_CRS_TWO_ANT_PORT 12 +#define RG_SCH_CMN_EFF_CRS_FOUR_ANT_PORT 16 + +/* ADD-new defines for Min & Max RI values */ +#define RG_SCH_CMN_MIN_RI 1 +#define RG_SCH_CMN_MAX_RI 4 + +#define RG_SCH_CMN_MAX_CW_PER_UE 2 + +#define RG_SCH_CMN_IS_RI_VALID(ri) \ + (ri >= RG_SCH_CMN_MIN_RI && ri <= RG_SCH_CMN_MAX_RI) + +#define RGSCHCMNADDTOCRNTTIME(crntTime, toFill, incr) \ +{\ + U32 absoluteTime;\ + absoluteTime = crntTime.sfn * RGSCH_NUM_SUB_FRAMES_5G + crntTime.subframe;\ + absoluteTime += incr;\ + toFill.sfn = (absoluteTime /RGSCH_NUM_SUB_FRAMES_5G)% 1024;\ + toFill.subframe = absoluteTime % RGSCH_NUM_SUB_FRAMES_5G;\ + toFill.hSfn = 0;\ +} + +#define RG_SCH_CMN_PWR_USE_CFG_MAX_PWR (-128) + +#define RG_SCH_CMN_RARSP_WAIT_PRD 3 + +#define RG_SCH_CMN_MAX_SPL_CFI 2 +#define RG_SCH_CMN_INVALID_INFO 0xff +#define RG_SCH_CMN_NUM_SUBCAR 12 + +#define RG_SCH_CMN_SUBFRM_0 0 +#define RG_SCH_CMN_SPL_SUBFRM_1 1 +#define RG_SCH_CMN_SUBFRM_5 5 +#define RG_SCH_CMN_SPL_SUBFRM_6 6 + +#define RG_SCH_CMN_VALUE_ONE 1 + +#define RG_SCH_CMN_IS_ODD(x) ((x) & 0x01) + +#define RG_SCH_CMN_MAX_NUM_OF_SFN 10240 +#define RG_SCH_CMN_MAX_SFN_NUM 1023 + +#define RG_SCH_CMN_NUM_DL_AT_SWTCHPT 2 + +#define RG_SCH_CMN_10_MS_PRD 10 +#define RG_SCH_CMN_5_MS_PRD 5 + +#define RG_SCH_CMN_DECR_FRAME(_x, _y) {\ + S16 _tmpNo = (_x) - (_y); \ + if(_tmpNo < 0) { \ + (_x) = _tmpNo + RGSCH_MAX_SFN; \ + }\ + else {\ + (_x) = _tmpNo; \ + }\ +} + +#ifdef EMTC_ENABLE +/* ADD-new hash define for max msg3 mcs val */ +#define RG_SCH_CMN_MAX_EMTC_MSG3_IMCS 7 +#endif + +#define RG_SCH_CMN_MAX_MSG3_IMCS 15 + +#define RG_SCH_CMN_CALC_RARSPLST_SIZE(cell, raArrsz) {\ + S16 _sfNum=0; \ + /* Get the last UL subframe no */ \ + for(_sfNum=RGSCH_NUM_SUB_FRAMES-1; _sfNum >= 0; _sfNum--) \ + { \ + if(rgSchTddUlDlSubfrmTbl[(cell)->ulDlCfgIdx][_sfNum] == \ + RG_SCH_TDD_UL_SUBFRAME) \ + { \ + break; \ + } \ + } \ + (raArrSz) = (_sfNum + ((RgSchCmnCell *)(cell)->sc.sch)->dl.numRaSubFrms \ + + RG_SCH_CMN_RARSP_WAIT_PRD + \ + (cell)->rachCfg.raWinSize - 1) / RGSCH_NUM_SUB_FRAMES + 1; \ +} + +/* Resource allocation type MACROs */ +#define RG_SCH_CMN_RA_TYPE0 0 +#define RG_SCH_CMN_RA_TYPE1 1 +#define RG_SCH_CMN_RA_TYPE2 2 +/* Added support for SPS*/ +#ifdef LTEMAC_SPS +#define RG_SCH_SPS_CONS_DYN_SCHD 5 +#define RG_SCH_SPS_CONS_RED_BO 5 +#define RG_SCH_DL_SPS_ADDTL_BO RGSCH_TA_SIZE /* 2 Bytes for TA */ +/* RBG subset MACROs for RA type 1 */ +#define RG_SCH_CMN_RBG_SUBSET0 0 +#define RG_SCH_CMN_RBG_SUBSET1 1 +#define RG_SCH_CMN_RBG_SUBSET2 2 +#define RG_SCH_CMN_RBG_SUBSET3 3 +#define RG_SCH_CMN_DL_NUM_ALLOCMASK 9 +#define RG_SCH_CMN_SPS_MAX_PRD 640 +#define RG_SCH_SPS_SID_INTERVAL 80 +#define RG_SCH_CMN_SPS_DL_ACTV (1 << 0) +#define RG_SCH_CMN_SPS_DL_REACTV_FREQ (1 << 1) +#define RG_SCH_CMN_SPS_DL_REACTV_TIME (1 << 2) +#define RG_SCH_CMN_SPS_DL_REACTV \ +(RG_SCH_CMN_SPS_DL_REACTV_FREQ | RG_SCH_CMN_SPS_DL_REACTV_TIME) +#define RG_SCH_CMN_SPS_DL_REL (1 << 3) +#define RG_SCH_CMN_SPS_DL_MAX_N1PUCCH_IDX_PER_UE 4 +/* Number of 32 bit bitmasks for marking measurement gap for SPS */ +#define RG_SCH_CMN_SPS_DL_MEASGAP_32BITMASK_SIZE 3 + +/* 32 Bit mask size for n1Pucch: RG_SCH_SPS_DL_MAX_N1PUCCH_PER_SF/32 */ +#define RG_SCH_CMN_SPS_DL_N1PUCCH_32BITMASK_SIZE \ + ((RG_SCH_SPS_DL_MAX_N1PUCCH_PER_SF + 31)/32) +#define RG_SCH_CMN_SPS_DL_INVALIDCQI_VAL 20 + +/* Maximum number of feasible periodicity values for SPS, SRS, CQI and SR */ +#define RG_SCH_CMN_SPS_MAX_NUM_PRD 21 + +/* Maximum value of iMcs for SPS UE */ +#define RG_SCH_CMN_SPS_DL_MAX_MCS 15 + +/* Minimum gap between SPEECH_GOOD packet and SID packet */ +#define RG_SCH_CMN_MIN_GAP_FOR_SID 60 + +/* DL SPS function MACROs */ + + +#define RG_SCH_CMN_SPS_GET_DL_CELL(cell) &(((RgSchCmnCell *)((cell)->sc.sch))->dl.dlSpsInfo) +#define RG_SCH_CMN_SPS_GET_DL_UE(_ue) &(((RgSchCmnUe *)(((_ue)->cellInfo[0])->sch))->dl.dlSpsInfo) +#define RG_SCH_CMN_SPS_GET_DL_SVC(svc) &(((RgSchCmnDlSvc *)((svc)->sch))->dlSvcSpsInfo) +#define RG_SCH_CMN_SPS_DL_IS_SPS_HQP(hqP) (((RgSchCmnDlHqProc *)((hqP)->sch))->isSpsSvcSchd) +#define RG_SCH_CMN_SPS_DL_IS_SPS_TX_HQP(hqP) (((RgSchCmnDlHqProc *)((hqP)->sch))->isSpsActv) +#define RG_SCH_CMN_IS_UE_SPS_SCHDLD(_ue, _cell, _schdTime)\ + ((((_ue)->cellInfo[(_ue->cellIdToCellIdxMap[RG_SCH_CELLINDEX(_cell)])])->dlAllocCb.spsSchdTime.sfn == _schdTime.sfn) &&\ + (((_ue)->cellInfo[(_ue->cellIdToCellIdxMap[RG_SCH_CELLINDEX(_cell)])])->dlAllocCb.spsSchdTime.subframe == _schdTime.subframe)) + +#define RG_SCH_CMN_DL_COUNT_ONES(_bitMask, _size, _numOnes)\ +{\ + U8 _pos = 0;\ + *_numOnes = 0;\ + for (_pos = 0; _pos < _size; ++_pos)\ + {\ + *_numOnes += (_bitMask & (1 << (31 - _pos))) ? 1: 0;\ + }\ +} + +#define RG_SCH_CMN_DL_GET_START_POS(_allocedBitmask, _size, _startPos)\ +{\ + U8 _pos = 0;\ + for (_pos = 0; _pos < _size; ++_pos)\ + {\ + if ((_allocedBitmask & (1 << (31 -_pos))))\ + {\ + continue;\ + }\ + else\ + {\ + *_startPos = _pos;\ + break;\ + }\ + }\ +} + +/* This macros returns position of idx in a 32 bit bitmask from LSB */ +#define RG_SCH_CMN_DL_GET_POS_FRM_LSB(_idx) (31 - (_idx)) + +#define RG_SCH_CMN_SPS_GET_PRD_IDX(_prdVal, _prdIdx)\ +{\ + switch (_prdVal)\ + {\ + case 2: *_prdIdx = RG_SCH_CMN_SPS_PRD_2SF; break;\ + case 5: *_prdIdx = RG_SCH_CMN_SPS_PRD_5SF; break;\ + case 10: *_prdIdx = RG_SCH_CMN_SPS_PRD_10SF; break;\ + case 20: *_prdIdx = RG_SCH_CMN_SPS_PRD_20SF; break;\ + case 30: *_prdIdx = RG_SCH_CMN_SPS_PRD_30SF; break;\ + case 32: *_prdIdx = RG_SCH_CMN_SPS_PRD_32SF; break;\ + case 40: *_prdIdx = RG_SCH_CMN_SPS_PRD_40SF; break;\ + case 60: *_prdIdx = RG_SCH_CMN_SPS_PRD_60SF; break;\ + case 64: *_prdIdx = RG_SCH_CMN_SPS_PRD_64SF; break;\ + case 80: *_prdIdx = RG_SCH_CMN_SPS_PRD_80SF; break;\ + case 120: *_prdIdx = RG_SCH_CMN_SPS_PRD_120SF; break;\ + case 128: *_prdIdx = RG_SCH_CMN_SPS_PRD_128SF; break;\ + case 160: *_prdIdx = RG_SCH_CMN_SPS_PRD_160SF; break;\ + case 256: *_prdIdx = RG_SCH_CMN_SPS_PRD_256SF; break;\ + case 320: *_prdIdx = RG_SCH_CMN_SPS_PRD_320SF; break;\ + case 512: *_prdIdx = RG_SCH_CMN_SPS_PRD_512SF; break;\ + case 640: *_prdIdx = RG_SCH_CMN_SPS_PRD_640SF; break;\ + case 1024: *_prdIdx = RG_SCH_CMN_SPS_PRD_1024SF; break;\ + case 1280: *_prdIdx = RG_SCH_CMN_SPS_PRD_1280SF; break;\ + case 2048: *_prdIdx = RG_SCH_CMN_SPS_PRD_2048SF; break;\ + case 2560: *_prdIdx = RG_SCH_CMN_SPS_PRD_2560SF; break;\ + default: *_prdIdx = RG_SCH_CMN_SPS_PRD_INVALID;break;\ + }\ +} + +/* To be part of rg_env.h */ +/* Maximum n1Pucch values per sub-frame: multiple of 32 */ +#define RG_SCH_SPS_DL_MAX_N1PUCCH_PER_SF 96 +#define RG_SCH_SPS_DFLT_PRD 20 +#define RG_SCH_SPS_CQI_DECR_VAL 2 + +#ifdef LTE_TDD +/* Added RgrSpsPrd casting to overcome G++ compilation warning*/ +#define RGSCH_SPS_GET_PRDCTY(_prdEnum, _prd) \ +{ \ + switch((_prdEnum)) \ + { \ + case RGR_SPS_PRD_10SF: \ + (_prd) = (RgrSpsPrd)10; \ + break; \ + case RGR_SPS_PRD_20SF: \ + (_prd) = (RgrSpsPrd)20; \ + break; \ + case RGR_SPS_PRD_32SF: \ + (_prd) = (RgrSpsPrd)30; \ + break; \ + case RGR_SPS_PRD_40SF: \ + (_prd) = (RgrSpsPrd)40; \ + break; \ + case RGR_SPS_PRD_64SF: \ + (_prd) =(RgrSpsPrd)60; \ + break; \ + case RGR_SPS_PRD_80SF: \ + (_prd) = (RgrSpsPrd)80; \ + break; \ + case RGR_SPS_PRD_128SF: \ + (_prd) = (RgrSpsPrd)120; \ + break; \ + case RGR_SPS_PRD_160SF: \ + (_prd) = (RgrSpsPrd)160; \ + break; \ + case RGR_SPS_PRD_320SF: \ + (_prd) = (RgrSpsPrd)320; \ + break; \ + case RGR_SPS_PRD_640SF: \ + (_prd) = (RgrSpsPrd)640; \ + break; \ + default:\ + (_prd) = RGR_SPS_PRD_INVALID;\ + } \ +} +#endif /*LTE_TDD*/ +/* ADD-hash define for actual transmission time */ +/* Feedback for RelPdcch should be received at MAC by HARQ_INTERVAL+ + * RG_TFU_HQ_IND_DELTA time.*/ +#define RG_SCH_CMN_SPS_TX_TIME (RG_SCH_CMN_HARQ_INTERVAL + TFU_HQFBKIND_ULDELTA) +#endif /* LTEMAC_SPS */ + +/* LTE_ADV_FLAG_REMOVED_START */ +#define RG_SCH_CMN_IS_UE_CELL_EDGE(_ue) _ue->lteAdvUeCb.rgrLteAdvUeCfg.isUeCellEdge; +#define RG_SCH_CMN_IS_SFR_ENB(_rgSchCellCb) _rgSchCellCb->lteAdvCb.sfrCfg.status; +#define RG_SCH_CMN_SFR_POOL(_subFrm) _subFrm->sfrTotalPoolInfo; + +#define RG_SCH_MAX_RNTP_SAMPLES 10000 +/* LTE_ADV_FLAG_REMOVED_END */ + +#ifdef LTE_ADV +#define RG_SCH_CMN_IS_SCELL_ACTV(_ue,_sCellIdx) (((_ue)->cellInfo[_sCellIdx] != NULLP) && \ + ((_ue)->cellInfo[_sCellIdx]->sCellState == RG_SCH_SCELL_ACTIVE)) + +/* As per spec 36.133 sec 7.7.3*/ +#define RG_SCH_CMN_MAX_SCELL_ACT_DELAY 24 +#ifndef TDD +#define RG_SCH_CMN_SCELL_ACT_DELAY_TMR (RG_SCH_CMN_MAX_SCELL_ACT_DELAY - TFU_HQFBKIND_ULDELTA - RG_SCH_CMN_HARQ_INTERVAL) +#endif + +/* Is this harq proc belongs to P-cell or S-cell */ +#define RG_SCH_CMN_IS_PCELL_HQP(hqP) (((hqP->hqE->ue)&&(hqP->hqE->ue->cell == hqP->hqE->cell))?TRUE:FALSE) +#define RG_SCH_CMN_GET_CELL_IDX_FROM_HQP(hqP) hqP->hqE->ue->cellIdToCellIdxMap[hqP->hqE->cell->cellId] +#endif + +/* DL allocation MACROs */ + +#define RG_SCH_CMN_GET_ALLOCCB_FRM_UE(_ue,_cell) &(((_ue)->cellInfo[(_ue)->cellIdToCellIdxMap\ + [RG_SCH_CELLINDEX(_cell)]])->dlAllocCb); +#define RG_SCH_CMN_GET_ALLOCCB_FRM_RACB(_raCb) &((_raCb)->rbAllocInfo); +#define RG_SCH_CMN_INIT_SCHD_LNK(_schdLstLnk, _node)\ +{\ + (_schdLstLnk)->node = (PTR)_node;\ + (_schdLstLnk)->prev = NULLP;\ + (_schdLstLnk)->next = NULLP;\ +} + +/* Changes for MIMO feature addition */ +#define RG_SCH_CMN_FILL_DL_TXINFO(_allocInfo, _rb, _sFlg, _prcInf, _numLyr, _sf)\ +{\ + _allocInfo->rbsReq = _rb;\ + _allocInfo->mimoAllocInfo.swpFlg = _sFlg;\ + _allocInfo->mimoAllocInfo.precIdxInfo = _prcInf;\ + _allocInfo->mimoAllocInfo.numTxLyrs = _numLyr;\ + _allocInfo->dlSf = _sf;\ +} + +#define RG_SCH_CMN_FILL_DL_TBINFO(_tbInfo, _bytsReq, _iTbs, _imcs, _tbCb, _noLyr)\ +{\ + (_tbInfo)->schdlngForTb = TRUE;\ + (_tbInfo)->bytesReq = _bytsReq;\ + (_tbInfo)->iTbs = _iTbs;\ + (_tbInfo)->imcs = _imcs;\ + (_tbInfo)->tbCb = _tbCb;\ + (_tbInfo)->noLyr = _noLyr;\ +} + +/* Bit Masks to Force Transmit diversity scheme */ +#define RG_SCH_CMN_TD_RI_1 0x01 /* Transmit Diversity due to RI==1 in case + of TM3 */ +#define RG_SCH_CMN_TD_NO_PMI 0x02 /* Transmit Diversity due to No PMI */ +#define RG_SCH_CMN_TD_TXMODE_RECFG 0x04 /* Transmit Diversity due to TXMODE ReCfg */ +#define RG_SCH_CMN_TD_TXSCHEME_CHNG 0x08 /* Transmit Diversity due to TX scheme + change */ +#define RG_SCH_CMN_TD_LAA_SINGLE_TB 0x10 /* Transmit Diversity due to one LAA TB + scheduled */ + +#define RG_SCH_MAX_UL_TX_ANT 2 + +/*Maximum achievable code rate for non 64QAM UEs. + *Value should NEVER be > than 93. Refer to 36.213, Table 7.2.3-1*/ +#define RG_SCH_CMN_MAX_CODE_RATE_16QAM 85 /* 85% code rate*/ +#define RG_SCH_CMN_MAX_EFF_BITS 4096 + +/* Refer BI table from 36.321 Table 7.2.1 */ +#define RG_SCH_CMN_NUM_BI_VAL 13 + +/*New macro to determine UE Category. We use the stored "ueCat" to + * index a UE category array. Therefore, the stored ueCat is 1 less + * than actual UE cateogry.*/ +#define RG_SCH_CMN_GET_UE_CTGY(ue) ((RG_SCH_CMN_GET_CMN_UE(ue))->ueCat + 1) +/*ccpu00117270-ADD-END*/ + +#define RG_SCH_CMN_UPD_RBS_TO_ADD(_CELL,_DLSF,_ALLCINFO,_RBSREQ,_RBSTOADD) \ +{\ + U8 addtlRbsAvl;\ + addtlRbsAvl = rgSCHCmnFindNumAddtlRbsAvl(_CELL,_DLSF,_ALLCINFO);\ + if(_RBSREQ > addtlRbsAvl)\ + {\ + _RBSTOADD = addtlRbsAvl;\ + }\ + else\ + {\ + _RBSTOADD = _RBSREQ;\ + }\ +} + /* ccpu00126002 ADD macro added to check wrap around when index is reached + MAX_CQI_RI_RPT_BUFF*/ +#define RG_SCH_INCR_CQIRI_INDEX(idx)\ +{\ + (idx)++;\ + if(MAX_CQI_RI_RPT_BUFF == idx)\ + {\ + idx = 0;\ + }\ + if(MAX_CQI_RI_RPT_BUFF <= idx)\ + {\ + printf("\n Invalid CQI write index:%d ",idx);\ + }\ +} +#define RG_SCH_DECR_CQIRI_INDEX(idx)\ +{\ + if(0 == idx)\ + {\ + idx = (MAX_CQI_RI_RPT_BUFF -1 );\ + }\ + else\ + (idx)--;\ + if(0 > idx)\ + {\ + printf("\n Invalid CQI write index:%d ",idx);\ + }\ +} + + +#define RG_SCH_CHK_ITBS_RANGE(_iTbs, _maxiTbs) \ +{\ + if (_iTbs < 0) \ + {\ + _iTbs = 0;\ + }\ + else if (_iTbs > (_maxiTbs))\ + {\ + _iTbs = (_maxiTbs);\ + }\ +} + + +/* LTE_ADV_FLAG_REMOVED_START */ +#define RG_SCH_CMN_SFR_UPD_RBS_TO_ADD_IN_POOL(_CELL,_DLSF,_POOLINFO,_ALLCINFO,_RBSREQ,_RBSTOADD) \ +{\ + U8 addtlRbsAvl;\ + addtlRbsAvl = rgSCHCmnSFRFindNumAddtlRbsAvl(_CELL,_DLSF,_POOLINFO,_ALLCINFO);\ + if(_RBSREQ > addtlRbsAvl)\ + {\ + _RBSTOADD = addtlRbsAvl;\ + }\ + else\ + {\ + _RBSTOADD = _RBSREQ;\ + }\ +} +/* LTE_ADV_FLAG_REMOVED_END */ + +/* DELTA for CFI applying */ +#define RG_SCH_CFI_APPLY_DELTA 4 +#define RG_SCH_MAX_TX_LYRS_4 4 /*CA dev*/ + +#define RG_SCH_CFI_STEP_UP(_cell, _cellSch, _currCfi)\ +{ \ + _cellSch->dl.newCfi = ((_currCfi) < _cell->dynCfiCb.maxCfi) ? \ + (_currCfi + 1):_cell->dynCfiCb.maxCfi; \ + _cell->dynCfiCb.cfiIncr++; \ +} + +#define RG_SCH_CFI_STEP_DOWN(_cell, _cellSch, _currCfi)\ +{ \ + _cellSch->dl.newCfi = _currCfi-1; \ + _cell->dynCfiCb.cfiDecr++; \ +} + +#define RG_SCH_UPDT_CW2_CQI(_cqiCw1,_cqiCw2,_diffCqi)\ + if (_cqiCw1 > rgSchCmnDlCqiDiffOfst[_diffCqi]) \ + {\ + _cqiCw2 = _cqiCw1 - rgSchCmnDlCqiDiffOfst[_diffCqi]; \ + } \ + else \ + { \ + _cqiCw2 = 1; \ + } + +#ifdef DL_LA +/* TM Mode Step Up/Down Factor macros */ +#define RG_SCH_MODE_CHNG_STEPUP_FACTOR 1 +#define RG_SCH_MODE_CHNG_STEPDOWN_FACTOR 1 +#define RG_SCH_MODE_CHNG_STEPUP_THRSHD 150 +#define RG_SCH_MODE_CHNG_STEPDOWN_CHECK_FACTOR 10 +#define RG_SCH_MODE_CHNG_STEPDOWN_THRSHD 100 + +#define RG_SCH_TXSCHEME_CHNG_THRSHD 5 +#define RG_SCH_TXSCHEME_CHNG_ITBS_FACTOR 5 + +#define RG_SCH_FILL_RGM_TRANSMODE_IND(_ueId, _cellId, _mode, _txModChgInd)\ +{\ + _txModChgInd->usCrnti = _ueId;\ + _txModChgInd->bCellId = _cellId;\ + _txModChgInd->eMode = _mode - 1;\ +} +#endif +#ifdef __cplusplus +} +#endif +#endif /* __RGSCHCMNH__ */ + +/********************************************************************30** + + End of file +**********************************************************************/ diff --git a/src/5gnrmac/rg_sch_cmn.x b/src/5gnrmac/rg_sch_cmn.x new file mode 100755 index 000000000..db3c00e53 --- /dev/null +++ b/src/5gnrmac/rg_sch_cmn.x @@ -0,0 +1,2248 @@ +/******************************************************************************* +################################################################################ +# Copyright (c) [2017-2019] [Radisys] # +# # +# 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. # +################################################################################ +*******************************************************************************/ + +/********************************************************************** + + Name: LTE MAC SC1 scheduler + + Type: C include file + + Desc: Defines required by SC1 scheduler + + File: rg_sch_cmn.x + +**********************************************************************/ +/** @file rg_sch_cmn.x +@brief This file contains data structures for the common module of the scheuler. +*/ + +#ifndef __RGSCHCMNX__ +#define __RGSCHCMNX__ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/*-------------------------------------* + * Common Scheduler DataStructure START + *-------------------------------------*/ +typedef struct _rgDlSchdApis RgDlSchdApis; +typedef struct _rgUlSchdApis RgUlSchdApis; +typedef struct _rgDlfsSchdApis RgDlfsSchdApis; +typedef Void (*RgDlSchdInits[RGSCH_NUM_SCHEDULERS]) ARGS((RgDlSchdApis *apis)); +typedef Void (*RgUlSchdInits[RGSCH_NUM_SCHEDULERS]) ARGS((RgUlSchdApis *apis)); +typedef Void (*RgDlfsSchdInits[RGSCH_NUM_SCHEDULERS]) ARGS((RgDlfsSchdApis *apis)); +#ifdef EMTC_ENABLE +typedef struct _rgDlEmtcSchdApis RgDlEmtcSchdApis; +typedef Void (*RgEmtcDlSchdInits[RGSCH_NUM_EMTC_SCHEDULERS]) ARGS((RgDlEmtcSchdApis *apis)); +typedef Void (*RgEmtcUlSchdInits[RGSCH_NUM_EMTC_SCHEDULERS]) ARGS((RgUlSchdApis *apis)); +#endif +typedef struct rgSchCmnDlRbAllocInfo RgSchCmnDlRbAllocInfo; +typedef struct rgSchCmnUeUlAlloc RgSchCmnUeUlAlloc; +typedef struct rgSchCmnUlRbAllocInfo RgSchCmnUlRbAllocInfo; + +/** + * @brief + * Uplink Scheduler APIs. + */ +struct _rgUlSchdApis +{ + S16 (*rgSCHRgrUlUeCfg) ARGS((RgSchCellCb *cell, RgSchUeCb *ue, RgrUeCfg *cfg, + RgSchErrInfo *err)); + S16 (*rgSCHRgrUlUeRecfg) ARGS((RgSchCellCb *cell, RgSchUeCb *ue, RgrUeRecfg *recfg, + RgSchErrInfo *err)); + Void (*rgSCHFreeUlUe) ARGS((RgSchCellCb *cell, RgSchUeCb *ue)); + S16 (*rgSCHRgrUlCellCfg) ARGS((RgSchCellCb *cell, RgrCellCfg *cfg, + RgSchErrInfo *err)); + S16 (*rgSCHRgrUlCellRecfg) ARGS((RgSchCellCb *cell, RgrCellRecfg *recfg, + RgSchErrInfo *err)); + Void (*rgSCHFreeUlCell) ARGS((RgSchCellCb *cell)); + S16 (*rgSCHRgrUlLcgCfg) ARGS((RgSchCellCb *cell, RgSchUeCb *ue, + RgSchLcgCb *lcg, RgrLcgCfg *cfg, RgSchErrInfo *errInfo)); + S16 (*rgSCHRgrUlLcCfg) ARGS((RgSchCellCb *cell, RgSchUeCb *ue, + RgrLchCfg *cfg, RgSchErrInfo *errInfo)); + S16 (*rgSCHRgrUlLcgRecfg) ARGS((RgSchCellCb *cell, RgSchUeCb *ue, + RgSchLcgCb *lcg, RgrLcgRecfg *recfg, RgSchErrInfo *errInfo)); + S16 (*rgSCHRgrUlLcRecfg) ARGS((RgSchCellCb *cell, RgSchUeCb *ue, + RgrLchRecfg *recfg, RgSchErrInfo *errInfo)); + Void (*rgSCHFreeUlLcg) ARGS((RgSchCellCb *cell, RgSchUeCb *ue, RgSchLcgCb *lcg)); + S16 (*rgSCHRgrUlLchDel) ARGS((RgSchCellCb *cell, RgSchUeCb *ue, CmLteLcId lcId, U8 lcgId)); + Void (*rgSCHUlActvtUe) ARGS((RgSchCellCb *cell, RgSchUeCb *ue)); + Void (*rgSCHUpdBsrShort) ARGS((RgSchCellCb *cell, RgSchUeCb *ue, RgSchLcgCb *ulLcg, U8 bsr)); + Void (*rgSCHUpdBsrTrunc) ARGS((RgSchCellCb *cell, RgSchUeCb *ue, RgSchLcgCb *ulLcg, U8 bsr)); + Void (*rgSCHUpdBsrLong) ARGS((RgSchCellCb *cell, RgSchUeCb *ue, U8 bsArr[])); + Void (*rgSCHContResUlGrant) ARGS((RgSchCellCb *cell, RgSchUeCb *ue)); + Void (*rgSCHSrRcvd) ARGS((RgSchCellCb *cell, RgSchUeCb *ue)); + Void (*rgSCHUlSched) ARGS((RgSchCellCb *cell, RgSchCmnUlRbAllocInfo + *allocInfo)); + Void (*rgSCHUlRetxSched) ARGS((RgSchCellCb *cell, RgSchCmnUlRbAllocInfo *allocInfo)); + Void (*rgSCHUlCqiInd) ARGS(( RgSchCellCb *cell, RgSchUeCb *ue, TfuUlCqiRpt *ulCqiInfo)); + S16 (*rgSCHRgrUlLcgUpd) ARGS((RgSchCellCb *cell, RgSchUeCb *ue, RgInfUeDatInd *datInd)); + Void (*rgSCHUlUeRefresh) ARGS((RgSchCellCb *cell, RgSchUeCb *ue)); + Void (*rgSCHUlUeReset) ARGS((RgSchCellCb *cell, RgSchUeCb *ue)); + Void (*rgSCHUlAllocFnlz) ARGS((RgSchCellCb *cell, RgSchCmnUlRbAllocInfo + *allocInfo)); + Void (*rgSCHUlInactvtUes) ARGS((RgSchCellCb *cell, CmLListCp *lst)); +#ifdef EMTC_ENABLE + Void (*rgSCHUlProcAddToRetx) ARGS((RgSchCellCb *cell,RgSchUlHqProcCb *hqP)); + S16 (*rgSCHUlUeHqEntInit) ARGS((RgSchCellCb *cell, RgUeUlHqCb *hqE)); + S16 (*rgSCHUlUeHqEntDeInit) ARGS((RgSchCellCb *cell, RgUeUlHqCb *hqE)); +#endif +}; +#ifdef EMTC_ENABLE +/** + * @brief + * DL Scheduler APIs For EMTC. + */ +struct _rgDlEmtcSchdApis +{ + S16 (*rgSCHRgrDlUeCfg) ARGS((RgSchCellCb *cell, RgSchUeCb *ue, RgrUeCfg *cfg, + RgSchErrInfo *err)); + S16 (*rgSCHRgrDlUeRecfg) ARGS((RgSchCellCb *cell, RgSchUeCb *ue, RgrUeRecfg *recfg, + RgSchErrInfo *err)); + Void (*rgSCHFreeDlUe) ARGS((RgSchCellCb *cell, RgSchUeCb *ue)); + S16 (*rgSCHRgrDlCellCfg) ARGS((RgSchCellCb *cell, RgrCellCfg *cfg, + RgSchErrInfo *err)); + S16 (*rgSCHRgrDlCellRecfg) ARGS((RgSchCellCb *cell, RgrCellRecfg *recfg, + RgSchErrInfo *err)); + Void (*rgSCHFreeDlCell) ARGS((RgSchCellCb *cell)); + S16 (*rgSCHRgrDlLcCfg) ARGS((RgSchCellCb *cell, RgSchUeCb *ue, + RgSchDlLcCb *dl, RgrLchCfg *cfg, + RgSchErrInfo *errInfo)); + S16 (*rgSCHRgrDlLcRecfg) ARGS((RgSchCellCb *cell, RgSchUeCb *ue, + RgSchDlLcCb *dl, RgrLchRecfg *recfg, + RgSchErrInfo *errInfo)); + Void (*rgSCHFreeDlLc) ARGS((RgSchCellCb *cell, RgSchUeCb *ue, RgSchDlLcCb *dlLc)); + Void (*rgSCHDlActvtUe) ARGS((RgSchCellCb *cell, RgSchUeCb *ue)); + Void (*rgSCHDlNewSched) ARGS((RgSchCellCb *cell, RgSchEmtcDlSf *cntrlDlsf,RgSchEmtcDlSf *datDlsf)); + Void (*rgSCHDlPreSched) ARGS((RgSchCellCb *cell)); + Void (*rgSCHDlPstSched) ARGS((Inst schInst)); + Void (*rgSCHDlRetxSched) ARGS((RgSchCellCb *cell, RgSchEmtcDlSf *cntrlDlsf, RgSchEmtcDlSf *datDlsf)); + Void (*rgSCHDlCeSched) ARGS((RgSchCellCb *cell, RgSchCmnDlRbAllocInfo *allocInfo)); + Void (*rgSCHDlDedBoUpd) ARGS((RgSchCellCb *cell, RgSchUeCb *ue, RgSchDlLcCb *svc)); + Void (*rgSCHDlProcAddToRetx) ARGS((RgSchCellCb *cell,RgSchDlHqProcCb *hqP)); + Void (*rgSCHDlCqiInd) ARGS((RgSchCellCb *cell, RgSchUeCb *ue, Bool isPucchInfo, Void *dlCqi)); + #ifdef TFU_UPGRADE + Void (*rgSCHSrsInd) ARGS((RgSchCellCb *cell, RgSchUeCb *ue, TfuSrsRpt*srsInd)); + #endif + Void (*rgSCHDlAllocFnlz) ARGS((RgSchCellCb *cell, RgSchCmnDlRbAllocInfo + *allocInfo)); + Void (*rgSCHDlUeRefresh) ARGS((RgSchCellCb *cell, RgSchUeCb *ue)); + Void (*rgSCHDlUeReset) ARGS((RgSchCellCb *cell, RgSchUeCb *ue)); + Void (*rgSCHDlInactvtUes) ARGS((RgSchCellCb *cell, CmLListCp *lst)); + + S16 (*rgSCHDlUeHqEntInit) ARGS((RgSchCellCb *cell, RgSchDlHqEnt *hqE)); + + S16 (*rgSCHDlUeHqEntDeInit) ARGS((RgSchCellCb *cell, RgSchDlHqEnt *hqE)); + Void (*rgSCHDlProcRmvFrmRetx) ARGS((RgSchCellCb *cell, RgSchUeCb *ue, RgSchDlHqProcCb *hqP)); +#ifdef LTE_ADV + S16 (*rgSCHRgrSCellDlUeCfg) ARGS((RgSchCellCb *cell, RgSchUeCb *ue, + RgSchErrInfo *err)); + S16 (*rgSCHRgrSCellDlUeDel) ARGS((RgSchUeCellInfo *sCellInfo, RgSchUeCb *ue)); + S16 (*rgSCHDlSCellDeactv) ARGS((RgSchCellCb *cell, RgSchUeCb *ue)); + S16 (*rgSCHDlSCellActv) ARGS((RgSchCellCb *cell, RgSchUeCb *ue)); +#endif + Void (*rgSCHDlTickForPdbTrkng ) ARGS((RgSchCellCb *cell)); + S16 (*rgSCHDlFillFlwCtrlInfo) ARGS((RgSchCellCb *cell, RgInfSfAlloc *sfAlloc)); +}; + +#endif +/** + * @brief + * DL Scheduler APIs. + */ +struct _rgDlSchdApis +{ + S16 (*rgSCHRgrDlUeCfg) ARGS((RgSchCellCb *cell, RgSchUeCb *ue, RgrUeCfg *cfg, + RgSchErrInfo *err)); + S16 (*rgSCHRgrDlUeRecfg) ARGS((RgSchCellCb *cell, RgSchUeCb *ue, RgrUeRecfg *recfg, + RgSchErrInfo *err)); + Void (*rgSCHFreeDlUe) ARGS((RgSchCellCb *cell, RgSchUeCb *ue)); + S16 (*rgSCHRgrDlCellCfg) ARGS((RgSchCellCb *cell, RgrCellCfg *cfg, + RgSchErrInfo *err)); + S16 (*rgSCHRgrDlCellRecfg) ARGS((RgSchCellCb *cell, RgrCellRecfg *recfg, + RgSchErrInfo *err)); + Void (*rgSCHFreeDlCell) ARGS((RgSchCellCb *cell)); + S16 (*rgSCHRgrDlLcCfg) ARGS((RgSchCellCb *cell, RgSchUeCb *ue, + RgSchDlLcCb *dl, RgrLchCfg *cfg, + RgSchErrInfo *errInfo)); + S16 (*rgSCHRgrDlLcRecfg) ARGS((RgSchCellCb *cell, RgSchUeCb *ue, + RgSchDlLcCb *dl, RgrLchRecfg *recfg, + RgSchErrInfo *errInfo)); + Void (*rgSCHFreeDlLc) ARGS((RgSchCellCb *cell, RgSchUeCb *ue, RgSchDlLcCb *dlLc)); + Void (*rgSCHDlActvtUe) ARGS((RgSchCellCb *cell, RgSchUeCb *ue)); + Void (*rgSCHDlNewSched) ARGS((RgSchCellCb *cell, RgSchCmnDlRbAllocInfo *allocInfo)); + Void (*rgSCHDlPreSched) ARGS((RgSchCellCb *cell)); + Void (*rgSCHDlPstSched) ARGS((Inst schInst)); + Void (*rgSCHDlRetxSched) ARGS((RgSchCellCb *cell, RgSchCmnDlRbAllocInfo *allocInfo)); + Void (*rgSCHDlCeSched) ARGS((RgSchCellCb *cell, RgSchCmnDlRbAllocInfo *allocInfo)); + Void (*rgSCHDlDedBoUpd) ARGS((RgSchCellCb *cell, RgSchUeCb *ue, RgSchDlLcCb *svc)); + Void (*rgSCHDlProcAddToRetx) ARGS((RgSchCellCb *cell,RgSchDlHqProcCb *hqP)); + Void (*rgSCHDlCqiInd) ARGS((RgSchCellCb *cell, RgSchUeCb *ue, Bool isPucchInfo, Void *dlCqi)); + #ifdef TFU_UPGRADE + Void (*rgSCHSrsInd) ARGS((RgSchCellCb *cell, RgSchUeCb *ue, TfuSrsRpt*srsInd)); + #endif + Void (*rgSCHDlAllocFnlz) ARGS((RgSchCellCb *cell, RgSchCmnDlRbAllocInfo + *allocInfo)); + Void (*rgSCHDlUeRefresh) ARGS((RgSchCellCb *cell, RgSchUeCb *ue)); + Void (*rgSCHDlUeReset) ARGS((RgSchCellCb *cell, RgSchUeCb *ue)); + Void (*rgSCHDlInactvtUes) ARGS((RgSchCellCb *cell, CmLListCp *lst)); + + S16 (*rgSCHDlUeHqEntInit) ARGS((RgSchCellCb *cell, RgSchDlHqEnt *hqE)); + + S16 (*rgSCHDlUeHqEntDeInit) ARGS((RgSchCellCb *cell, RgSchDlHqEnt *hqE)); + Void (*rgSCHDlProcRmvFrmRetx) ARGS((RgSchCellCb *cell, RgSchUeCb *ue, RgSchDlHqProcCb *hqP)); +#ifdef LTE_ADV + S16 (*rgSCHRgrSCellDlUeCfg) ARGS((RgSchCellCb *cell, RgSchUeCb *ue, + RgSchErrInfo *err)); + S16 (*rgSCHRgrSCellDlUeDel) ARGS((RgSchUeCellInfo *sCellInfo, RgSchUeCb *ue)); + S16 (*rgSCHDlSCellDeactv) ARGS((RgSchCellCb *cell, RgSchUeCb *ue)); + S16 (*rgSCHDlSCellActv) ARGS((RgSchCellCb *cell, RgSchUeCb *ue)); +#endif + Void (*rgSCHDlTickForPdbTrkng ) ARGS((RgSchCellCb *cell)); + S16 (*rgSCHDlFillFlwCtrlInfo) ARGS((RgSchCellCb *cell, RgInfSfAlloc *sfAlloc)); +}; + +/** + * @brief + * DLFS Scheduler APIs. + */ +struct _rgDlfsSchdApis +{ + S16 (*rgSCHDlfsCellCfg) ARGS((RgSchCellCb *cell, RgrCellCfg *cfg, + RgSchErrInfo *err)); + S16 (*rgSCHDlfsCellRecfg) ARGS((RgSchCellCb *cell, RgrCellRecfg *recfg, + RgSchErrInfo *err)); + Void (*rgSCHDlfsCellDel) ARGS((RgSchCellCb *cell)); + S16 (*rgSCHDlfsUeCfg) ARGS((RgSchCellCb *cell, RgSchUeCb *ue, + RgrUeCfg *cfg, RgSchErrInfo *err)); + S16 (*rgSCHDlfsUeRecfg) ARGS((RgSchCellCb *cell, RgSchUeCb *ue, + RgrUeRecfg *recfg, RgSchErrInfo *err)); + Void (*rgSCHDlfsUeDel) ARGS((RgSchCellCb *cell, RgSchUeCb *ue)); + Void (*rgSCHDlfsDlCqiInd) ARGS((RgSchCellCb *cell, RgSchUeCb *ue, + Bool isPucchInfo, + Void *dlCqiRpt, + CmLteTimingInfo timingInfo)); + Void (*rgSCHDlfsReinitSf) ARGS((RgSchCellCb *cell, RgSchDlSf *dlSf)); + Void (*rgSCHDlfsAllocRb) ARGS((RgSchCellCb *cell, RgSchCmnDlRbAllocInfo + *dlRbAllocInfo)); + /* Added for BCCH/PCCH handling */ + Void (*rgSCHDlfsBcchPcchAllocRb) ARGS((RgSchCellCb *cell, RgSchCmnDlRbAllocInfo *dlRbAllocInfo)); + Void (*rgSCHDlfsAddUeToLst) ARGS((RgSchCellCb *cell, CmLListCp *lCp, RgSchDlHqProcCb *hqP)); +#ifdef LTE_ADV + S16 (*rgSCHDlfsSCellUeCfg) ARGS((RgSchCellCb *sCell, RgSchUeCb *ueCb, RgrUeSecCellCfg *sCellCfg,RgSchErrInfo *err)); + S16 (*rgSCHDlfsSCellUeDel) ARGS((RgSchCellCb *sCell, RgSchUeCb *ueCb)); +#endif +}; + +typedef enum rgSchCmnTpcAccVal +{ + RG_SCH_CMN_TPC_ACC_NEG_1DB = 0, + RG_SCH_CMN_TPC_ACC_0DB = 1, + RG_SCH_CMN_TPC_ACC_1DB = 2, + RG_SCH_CMN_TPC_ACC_3DB = 3 +} RgSchCmnTpcAccVal; + +typedef enum rgSchCmnTpcAbsVal +{ + RG_SCH_CMN_TPC_ABS_NEG_4DB = 0, + RG_SCH_CMN_TPC_ABS_NEG_1DB = 1, + RG_SCH_CMN_TPC_ABS_1DB = 2, + RG_SCH_CMN_TPC_ABS_4DB = 3 +} RgSchCmnTpcAbsVal; +/* Added changes of TFU_UPGRADE */ +#ifdef TFU_UPGRADE +typedef enum rgSchCmnRank +{ + RG_SCH_CMN_RANK_1 = 1, + RG_SCH_CMN_RANK_2 = 2, + RG_SCH_CMN_RANK_3 = 3, + RG_SCH_CMN_RANK_4 = 4 +} RgSchCmnRank; +#endif + +typedef struct rgSchCmnUlCqiInfo +{ + U8 qm; + U16 eff; /* Efficiency in terms of bits/RE */ +} RgSchCmnUlCqiInfo; + +EXTERN RgSchCmnUlCqiInfo rgSchCmnUlCqiTbl[RG_SCH_CMN_UL_NUM_CQI]; +EXTERN S8 rgSchCmnDlCqiDiffOfst[8]; +/* Added changes of TFU_UPGRADE */ +#ifdef TFU_UPGRADE +EXTERN S8 rgSchCmnApUeSelDiffCqi[4]; +EXTERN S8 rgSchCmnApEnbConfDiffCqi[4]; +#endif + + +EXTERN U8 rgSchCmnUlCqiToTbsTbl[RG_SCH_CMN_MAX_CP][RG_SCH_CMN_UL_NUM_CQI]; + +#if (LTEMAC_SPS & LTE_TDD) +/* subframe offset values to be used when twoIntervalsConfig is enabled in UL + * SPS for a UE */ +typedef S8 RgSchTddSfOffTbl[RGSCH_MAX_TDD_UL_DL_CFG][RGSCH_NUM_SUB_FRAMES]; +EXTERN RgSchTddSfOffTbl rgSchTddSfOffTbl; + +#endif /* LTEMAC_SPS & LTE_TDD */ + +/*--------------------------* + * SPS specific declarations + *---------------------------*/ +#ifdef LTEMAC_SPS + +/** + * @brief + * Downlink SPS scheduling information per UE + */ +typedef struct rgSchCmnSpsDlUeSchdInfo +{ + U8 scaledCqi; /*!< Assumed value of CQI for transmission */ + U16 actvSfTblIdx; /*!< Index into cell-wide DL SPS sub-frame + table during activation */ + CmLteTimingInfo schdKey; /*!< Key into the list of DL SPS active + UEs: next DL SPS ocassion */ + RgSchDlRbAlloc spsAllocInfo; /*!< Allocation information for an SPS active + UE */ + U8 allocN1PucchIdx; /*!< Index value in UE's n1Pucch array + of the allocated n1Pucch */ + //Bool pdcchPndng; /*!< Indicates if the activaton/ + // reactivation PDCCH needs to be sent + // for this allocation */ +} RgSchCmnSpsDlUeSchdInfo; + +/** + * @brief + * Downlink stats information for SPS per UE + */ +typedef struct rgSchCmnDlUeSpsStatInfo +{ + U32 numSchedSPSRnti; /*!< Number of SPS occasions sched using SPS RNTI*/ + U32 totalSPSSchedOcc; /*!< Number of SPS occasions sched + using SPS RNTI + CRNTI*/ + U32 numSpsReactv; /*!< Number of Reactivations */ + U32 numSpsActv; /*!< Number of activations */ + U32 numSpsRel; /*!< Number of Deactivations */ +}RgSchCmnDlUeSpsStatInfo; + +/** + * @brief + * Downlink information for SPS per UE + */ +typedef struct rgSchCmnDlUeSpsInfo +{ + CmLteTimingInfo prevDlBoUpdTm; /*!< BO updation interval*/ + CmLList zeroBOSvcUesEnt; /*!< Linked list entity for zeroBOSvcUes lst */ + CmLList actvUeLstEnt; /*!< Linked List entry for DL SPS + active UE list*/ + CmLList pndngUeLstEnt;/*!< Linked List entry for UE list with + pending SPS action: + activation/reactivation/release */ + /* Added handling to retrnasmit RelPDCCH in case no + feedback is received */ + CmLList wtngForRelFdbkUeEnt;/*!< Linked list entry for UE who + have a feedback pending for + Release PDCCH */ + RgSchDlLcCb *spsSvc; /*!< Pointer to the SPS service of the + UE */ + CmLListCp *spsList; /*!< Pointer to the SPS list of which + UE is a part */ + U32 measGapMask[RG_SCH_CMN_SPS_DL_MEASGAP_32BITMASK_SIZE]; + /*!< Indicates the DL sub-frames with + ongoing measurement gap */ + U16 n1PucchIdx[RG_SCH_CMN_SPS_DL_MAX_N1PUCCH_IDX_PER_UE]; + /*!< N1Pucch indices configured for the UE */ + U8 actionPndng; /*!< Indicates the action pending on the UE + activation/re-activation/release */ + U8 dlSpsStatus; /*!< Indicates the current status of DL SPS */ + U8 prdIdx; /*!< DL SPS periodicity index for the + configured peridicity */ + RgSchCmnSpsDlUeSchdInfo dlSpsUeSchdInfo; /*!< Scheduled info for DL SPS + active UE */ + Bool isRelPdcchSent; /*!< Indicates if release PDCCH is sent for + this UE. For TDD, Used while sending DAI + in DCI formats 0/1/1A/1B/1D/2/2A. + For FDD, used to not repeat relPdcch + till the feddback is recieved */ + U8 numRelPdcchSent; /*!< Number of times RelPdcch has been sent. */ + + RgSchCmnDlUeSpsStatInfo statInfo; /*!< SPS Metric Info */ + U8 dynSchedCount; /*!< To track num of consecutive times SPS BO + is sched dynamically */ + U8 reducedBoCount; /*!< To track num of consecutive times BO + is lesser than SPS BO */ + U32 maxChgdBo; /* !< The Maximum of BO which is different from the + BO for which SPS has been activated */ + U32 spsSchedBo; /* !< BO for which SPS is activated */ + Bool isDynSched; /* !< BO is dynamically scheduled */ +} RgSchCmnDlUeSpsInfo; + +/** + * @brief + * Downlink information for SPS per Cell + */ +typedef struct rgSchCmnSpsDlSf +{ + U32 rbsAlloc; /*!< Allocated BW for this subframe (in actual number of + RBs) */ + RgSchDlSfAllocInfo spsAllocInfo; /*!< Allocation information for SPS BW */ + U32 n1PucchMask[RG_SCH_CMN_SPS_DL_N1PUCCH_32BITMASK_SIZE]; + /*!< N1Pucch allocation mask per Sub-frame */ + U8 numDlSpsActiveUes; /*!< number of DL SPS UEs that + have been activated */ +} RgSchCmnSpsDlSf; + +/** + * @brief + * SPS N1Pucch Database for the cell + */ +typedef struct rgSchCmnSpsDlN1Pucch RgSchCmnSpsDlN1Pucch; +struct rgSchCmnSpsDlN1Pucch +{ + U16 idx; /*!< Index in the n1PucchLst */ + U16 n1PucchVal; /*!< Pucch Value corresponding to the index */ + U32 numUes; /*!< Count of UEs with this N1Pucch value configured */ + U16 next; /*!< Next available index */ +}; + +/** + * @brief + * SPS N1Pucch Database for the cell + */ +typedef struct rgSchCmnSpsDlN1PucchDb +{ + U16 numFreeN1Pucch; /*!< Number of free n1Pucch values */ + U16 numInUseN1Pucch; /*!< Number of inUse n1Pucch values + */ + RgSchCmnSpsDlN1Pucch *freeN1PucchStart; /*!< Start for free n1Pucch list */ + RgSchCmnSpsDlN1Pucch *inUseN1PucchStart;/*!< Start for in-use n1Pucch list + */ + RgSchCmnSpsDlN1Pucch n1PucchLst[RG_SCH_SPS_DL_MAX_N1PUCCH_PER_SF]; + /*!< List of cell wide n1Pucch + values*/ +} RgSchCmnSpsDlN1PucchDb; + +/** + * @brief + * Downlink information for SPS per Cell + */ +typedef struct rgSchCmnDlCellSpsInfo +{ + CmLListCp zeroBOSvcUes; /*!< List of SPS services which + are not sched at SPS Occasion due + to zero BO*//* REVANTH_SPS_FIX */ + CmLListCp toBeSchdSvcs; /*!< List of SPS services to be scheduled */ + CmLListCp retxHqProcs; /*!< List of SPS HARQ procs for + re-transmission: all the HARQ procs + with isSpsSvcSchd = TRUE shall be + part of this list */ + CmLListCp actvDlSpsUeLsts[RG_SCH_CMN_SPS_MAX_PRD]; + /*!< Array of list of UE control blocks with + DL SPS activated: index - next time of + transmission */ + CmLListCp toBeActvtdUes; /*!< List of DL SPS UEs with pending + activation/re-activation */ + CmLListCp toBeRelUes; /*!< List of DL SPS enabled UEs with release + pending */ + /* Added handling when no feedback is received + for the Release PDCCH sent + */ + CmLListCp wtngForRelFdbkUeLst[RGSCH_NUM_SUB_FRAMES]; /*!< List of DL SPS + enabled UEs waiting + for feedback for + Release PDCCH sent + */ + U16 spsPrdLcmVal; /*!< LCM value for all configured + SPS periodicities: maxVal = 640 for FDD + and (640 * 3) for TDD */ + U8 lcmIdx; /*!< Index value for computed LCM */ + RgSchCmnSpsDlSf *spsSfTbl; /*!< DL sub-frame information for the cell*/ + RgSchCmnSpsDlN1PucchDb n1PucchDb; /*!< Database of configured n1Pucch values + */ +} RgSchCmnDlCellSpsInfo; + +/** + * @brief + * Information per uplink SPS allocation + */ +typedef struct rgSchCmnSpsUlAlloc +{ + U8 sbStart; /*!< Starting subband of the alloc */ + U8 numSb; /*!< Num of subbands in the alloc */ +} RgSchCmnSpsUlAlloc; + +/** + * @brief + * Uplink information for SPS per subframe + */ +typedef struct rgSchCmnSpsUlSf +{ + U32 ulBwBitMask[RGSCH_SPS_ULBW_MASK_LEN]; /*!< Bitmask indicating the alloc/hole info + for SPS BW. Bit set at position 'x' + indicates subband 'x' is occupied */ + U8 maskLen; /*!< Length of ulBwBitMask based on numSb */ + U8 numUlSpsActiveUes; /*!< Number of UL SPS Active UEs in this Subframe */ + RgSchCmnSpsUlAlloc allocInfo; /*!< Info per SPS Allocation - Used to mark + previous allocations in a subframe */ +} RgSchCmnSpsUlSf; + +/** + * @brief + * Uplink information for SPS per Cell + */ +typedef struct rgSchCmnUlCellSpsInfo +{ + U8 spsSbStart; /*!< Starting subband of SPS BW */ + U8 numSpsSb; /*!< number of subbands for SPS */ + U16 spsPrdLcmVal; /*!< LCM value for all configured UL + SPS periodicities:maxVal = 640 for FDD + and (640 * 3) for TDD */ + RgSchCmnSpsUlSf *spsSfLst; /*!< UL subframe information for the cell*/ + CmLListCp actvUlSpsUeLsts[RG_SCH_CMN_SPS_MAX_PRD]; + /*!< Array of list of UeCbs with + UL SPS activated: index - next time of + transmission */ + CmLListCp toBeActvtdUeLst; /*!< List of ULSPS enabled UEs with pending + activation */ + CmLListCp toBeRelUeLst; /*!< List of ULSPS enabled UEs with release + pending */ +} RgSchCmnUlCellSpsInfo; + + +#endif +/*--------------------------* + * SPS specific declarations End + *---------------------------*/ +/** + * @brief + * Scheduler uplink scheduling parameters related to random access. + */ +typedef struct rgSchCmnUlCellRa +{ + U8 prmblANumSb; /*!< Number of msg3 RBs to allocate for preamble A */ + U8 prmblAIMcs; /*!< Imcs for msg3 when preamble A was used */ + U8 prmblBNumSb; /*!< Number of msg3 RBs to allocate for preamble B */ + U8 prmblBIMcs; /*!< Imcs for msg3 when preamble B was used */ +} RgSchCmnUlCellRa; + +typedef struct rgSchCmnCellClcITbs +{ + U8 iTbs2Rbs; /*!< iTbs value for 2 Rbs precomputed at cell cfg */ + U8 iTbs3Rbs; /*!< iTbs value for 3 Rbs precomputed at cell cfg */ +}RgSchCmnCellClcITbs; + +typedef struct rgSchCmnDlCell +{ + Bool isDlFreqSel; /*!< Bool indicating if cell is frequency + selective or not */ + U8 maxUeNewTxPerTti; /*!< Max UEs to be considered for New Tx Alloc in DL */ + U8 numRaSubFrms; /*!< Number of frames of RA transmission */ + U8 iTbsCap; /*!< Max value DL iTbs capped to */ + U16 nCce; /*!< Number of CCEs computed based on CFI */ + U8 maxDlBwPerUe; /*!< Max DL B/W per UE */ + U8 maxDlRetxBw; /*!< Max DL retx B/W, as part of 256 */ + U8 maxUePerDlSf; /*!< Max UE to be considered for DL scheduling + * in a TTI */ + /*[ccpu00138609]-ADD- max Msg4/ DL CCCH UE configuration */ + U8 maxCcchPerDlSf; /*!< Max Msg4/DL CCCH UE sched in Dlsf */ + U8 msg4TxDelay; /*!< Max estimated time for HARQ tx + of msg4 based on the Harq RTT and + max Harq retries for msg4 */ + RgSchCmnCellClcITbs cmnChITbs; /*!< iTbs value for 2 Rbs precomputed at cell cfg */ + CmLteAggrLvl cmnChAggrLvl; /*!< Precomputed aggregation level for common channel */ + U8 ccchCqi; /*!< Default Cqi to be used for Msg4 and UE */ + CmLListCp msg4RetxLst; /*!< Queue to hold Msg4 procs for retransmission */ + /* Changes for CR timer */ +#ifdef RGR_V1 + CmLListCp ccchSduRetxLst; /*!< Queue to hold CCCH SDU procs for retransmission */ +#endif +#ifdef EMTC_ENABLE + Void *emtcCqiToTbsTbl[RGSCH_MAX_NUM_LYR_PERCW][RG_SCH_CMN_MAX_CFI]; +#endif + Void *cqiToTbsTbl[RGSCH_MAX_NUM_LYR_PERCW][RG_SCH_CMN_MAX_CFI]; + /* cqi to Tbs tables for each 1 and 2 layer TbSz table */ + /*!< CQI to efficiency translation */ + Void *cqiToEffTbl[RGSCH_MAX_NUM_LYR_PERCW][RG_SCH_CMN_MAX_CFI]; + U8 newCfi; /*!< New CFI value */ + U8 currCfi; /*!< Current CFI value */ + + U16 noResPerRb[RG_SCH_CMN_MAX_CFI]; /*!< Num REs per RB */ + CmLteTimingInfo time; /*!< Timing info for current allocation */ + Void *schSpfc; /*!< Scheduler Specific Cell DL dereferencing */ + Void *dlfsCell; /*!< DLFS specific information per cell */ + CmLListCp taLst; /*!< TA queues, holds the UEs for which TA + has to be scheduled */ +#ifdef LTEMAC_SPS + RgSchCmnDlCellSpsInfo dlSpsInfo; /*!< DL SPS info for the cell */ +#endif + /* Member to store no. of Bits per RB */ + U32 bitsPerRb; /*!< Bits per RB calculated from + BcchPcchRaRsp Code rate configured through + RGR */ +#ifdef LTE_TDD + U16 numReDwPts[RG_SCH_CMN_MAX_CFI-1]; /*!< Num of RE in DwPTS RB */ + U8 splSfCfg; /*! 10000, + representing -6 dB to 4 dB in 0.001 + dB steps */ + U16 pcchTxPwrOffset; /*!< Tx Pwr Offset for PCCH tx. + Offset to the reference signal + power. Value: 0 -> 10000, + representing -6 dB to 4 dB in 0.001 + dB steps */ + U16 rarTxPwrOffset; /*!< Tx Pwr Offset for RAR tx. + Offset to the reference signal + power. Value: 0 -> 10000, + representing -6 dB to 4 dB in 0.001 + dB steps */ + /* ccpu00138898 - Added Tx pwr offset for PHICH Tx*/ + U16 phichTxPwrOffset; /*!< Tx Pwr Offset for PHICH tx. + Offset to the reference signal + power. Value: 0 -> 10000, + representing -6 dB to 4 dB in 0.001 + dB steps */ + U32 ncsgPrbCnt; /*!< Cumulative sum of PDSCH PRBs assigned to non-Csg UEs */ + U32 totPrbCnt; /*!< Cumulative sum of PDSCH PRBs assigned to all UEs */ + RgrUeDlPwrCntrlPaCfg msg4pAVal; /*!< Default value (Enum) of PA that is + used by Scheduler for msg4 */ +#ifdef LTE_ADV + CmLListCp secCellActCeLst; /*!< List for holding the UE's + for which sec cell act CE's needs to scheduled */ + +#endif +#ifdef EMTC_ENABLE + CmLListCp emtcTaLst; /*!< TA queues, holds the EMTC UEs for which TA + has to be scheduled */ + Void *schSpfcEmtc; /*!< Scheduler Specific Cell DL dereferencing */ +#endif +} RgSchCmnDlCell; + +/** + @brief Information related to TPC-PUCCH-RNTI/TPC-PUSCH-RNTI. */ +typedef struct rgSchCmnTpcRntiCb +{ + CmLteRnti tpcRnti; /*!< TPC-PUCCH-RNTI/TPC-PUSCH-RNTI*/ + Bool isFmt3a; /*!< DCI format type: 3/3A */ + CmLListCp toBeSchdUes; /*!< List of UEs requiring power adjustment + for this TPC-RNTI */ + CmLListCp cfgdUes; /*!< List of UEs */ + CmLList schdLnk; /*!< Link to the list of TPC RNTIs to be + scheduled */ +} RgSchCmnTpcRntiCb; + +/** + @brief Uplink Power control related information per cell. */ +typedef struct rgSchCmnUlPwrCb +{ + U8 tpcPucchRntiCnt;/*!< Count of TPC-PUCCH-RNTIs for the cell */ + RgSchCmnTpcRntiCb tpcPucchRntiLst[RG_SCH_CMN_MAX_NUM_TPC_PUCCH_RNTI]; + /*!< List of TPC-PUCCH-RNTIs */ + U8 tpcPuschRntiCnt;/*!< Count of TPC-PUSCH-RNTIs for the cell */ + RgSchCmnTpcRntiCb tpcPuschRntiLst[RG_SCH_CMN_MAX_NUM_TPC_PUSCH_RNTI]; + /*!< List of TPC-PUSCH-RNTIs */ + CmLListCp pucchGrpPwr; /*!< List of TPC-PUCCH-RNTIs for PUCCH group + power control: 'RgSchCmnTpcRntiCb' */ + CmLListCp puschGrpPwr; /*!< List of TPC-PUSCH-RNTIs for PUSCH group + power control: 'RgSchCmnTpcRntiCb' */ + S8 pMax; /*!< Max allowed uplink power in cell */ + U8 trgUlCqi; /*!< Default target CQI */ +} RgSchCmnUlPwrCb; + +/** + * @brief + * Cell specific uplink scheduling information for Scheduler type 1. + */ +typedef struct rgSchCmnUlCell +{ + U8 maxUeNewTxPerTti; /*!< Max UEs to be considered for New Tx Alloc in UL */ + /* Added new variable maxUlBwPerUe */ + U8 maxUlBwPerUe; /*!< Max UL BW per UE */ + U8 maxSbPerUe; /*!< Max subbands per UE */ + U8 dfltUlCqi; /*!< Default uplink CQI assumed intitially */ + U8 max16qamCqi; /*!< Highest CQI supporting 16 QAM */ + U8 maxUlSpsCqi; /*!< Highest CQI supporting 16 QAM */ + U8 iTbsCap; /*!< Max value UL iTbs capped to */ + U8 sbSize; /*!< Subband size */ + U8 dmrsArrSize; /*!< DMRS array size */ + U8 *dmrsArr; /*!< DMRS array */ + RgSchCmnUlCellRa ra; /*!< RA related info */ + U8 idx; /*!< Current subframe - maps to HARQ process ID */ + U8 schdIdx; /*!< Subframe to schedule for */ + U8 schdHqProcIdx; /*!< Proc to schedule for */ + U8 msg3SchdIdx; /*!< Subframe to schedule for msg3 */ +#ifdef EMTC_ENABLE + RgSchCmnUlCellRa emtcRa; /*!< RA related info */ + U8 emtcMsg3SchdIdx; + Void *schSpfcEmtc; /*!< Scheduler Specific Cell UL dereferencing */ +#endif + U8 msg3SchdHqProcIdx;/*!< Proc to schedule for */ + U8 rcpReqIdx; /*!< Subframe to send reception req for */ + /* ccpu00130688 -MOD- for config-0 changes */ + U8 hqFdbkIdx[2]; /*!< In FDD only Idx 0 is used. + In TDD n+k value is updated at idx 0. + For TDD Cfg 0 both indices are used */ + U8 reTxIdx[2]; /*!< Retransmission Index corresponding to + the hqFdbkIdx */ +#ifdef LTEMAC_SPS + U8 spsUlRsrvIdx; /*!< Subframe to reserve UL SPS cfgd grant */ + U8 spsUlRsrvHqProcIdx;/*!< Proc for the cfgd UL SPS grant */ +#endif + CmLteTimingInfo schdTime; +#ifdef LTE_TDD + U8 numUlSubfrms; /*!< Number of UL subframes */ + RgSchUlSf *ulSfArr; /*!< no msg3 alloc info here */ +#else + RgSchUlSf ulSfArr[RG_SCH_CMN_UL_NUM_SF]; /*!< no msg3 alloc info here */ +#endif + Void *schSpfc; /*!< Scheduler Specific Cell UL dereferencing */ + RgSchCmnUlPwrCb ulPwrCb; /*!< Uplink power control block */ + U8 ulNumRePerRb; /*!< Number of REs per RB in UL */ + /* Added support for non-adaptive retransmission in uplink */ + U8 maxAllocPerUlSf; /*!< Max Allocations in a given SF */ +#ifdef RGR_V1 +/* Added a param to limit msg3 allocations */ + U8 maxMsg3PerUlSf; /*!< Max msg3 alocs in a given SF */ +#endif + +#ifdef LTEMAC_SPS + RgSchCmnUlCellSpsInfo ulSpsInfo; /*!< UL SPS info for the cell */ + U16 schdTti; /*< 0..1023, corresponding to scheduling time, + * can theoretically used for non-SPS + * purposes as well */ +#endif + U32 ncsgPrbCnt; /*!< Cumulative sum of PDSCH PRBs assigned to non-Csg UEs */ + U32 totPrbCnt; /*!< Cumulative sum of PDSCH PRBs assigned to all UEs */ + CmLListCp reTxLst; /*!< Retransmission List*/ +} RgSchCmnUlCell; + +/** + @brief ACK-NACK repetition related information per cell. */ +typedef struct rgSchCmnAckNakRepCb +{ +#ifdef LTE_TDD + CmLListCp ackNakRepQ[2*RGSCH_NUM_SUB_FRAMES]; /*!< ACK NACK repetition queue */ +#else + CmLListCp ackNakRepQ[RGSCH_NUM_SUB_FRAMES]; /*!< ACK NACK repetition queue */ +#endif +} RgSchCmnAckNakRepCb; + +/** + @brief Measurement Gap related information per cell. */ +typedef struct rgSchCmnMeasGapCb +{ + CmLListCp gapPrd40Q[RG_SCH_CMN_MEAS_GAPPRD40]; /*!< Measurement Gap queue + for UEs with 40 ms gap period */ + CmLListCp gapPrd80Q[RG_SCH_CMN_MEAS_GAPPRD80]; /*!< Measurement Gap queue + for UEs with 80 ms gap period */ +} RgSchCmnMeasGapCb; + +/** + * @brief + * common scheduler specific information for rapId to UE mapping. */ +typedef struct rgSchCmnRapIdMap +{ + U8 rapId; + CmLListCp assgndUes; /*!< List of UEs for which this rapId is + assigned. */ +} RgSchCmnRapIdMap; + +/** + * @brief + * common scheduler specific information for RACH Dedicated Preambles. */ +typedef struct rgSchCmnRachCfg +{ + U8 numDedPrm; /*!< number of configured dedicated prmbls */ + U8 dedPrmStart; /*!< starting rapId Number */ + U8 remDedPrm; /*!< remaining number of ded Prm available + for the "applFrm" */ + CmLteTimingInfo applFrm; /*!< Frame under consideration for dedPrm + distribution */ + U8 prachMskIndx;/*!< Prach Mask Idx corresponding to + applFrm*/ + RgSchCmnRapIdMap rapIdMap[RG_SCH_MAX_DED_PRMBLS]; /*!< mapping of RapId + * to assigned UEs */ + CmLListCp hoUeLst; /*!< List of UEs undergoing Handover */ + CmLListCp pdcchOdrLst; /*!< Pdcch Order Q, holds the UEs for which + PO has to be generated. */ +} RgSchCmnRachCfg; + +/** + @brief Uplink Power control related information per UE. */ +typedef struct rgSchCmnUeUlPwrCb +{ + Bool isAccumulated; /*!< Indicates if power is accumulative or not */ + Bool deltaMcsEnbld; /*!< Indicates if coding effeciency is + * considered or not for PUSCH power computation */ + U8 pucchIdx; /*!< Index for TPC-PUCCH-RNTI */ + U8 puschIdx; /*!< Index for TPC-PUSCH-RNTI */ + U8 isPhrAvail; /*!< Indicates if PHR is recieved */ + S8 phVal; /*!< Power headroom value in dB */ + S8 pwrPerRb; /*!< UL power computed per RB */ + S8 maxUePwr; /*!< Maximum power with which UE can transmit */ + U8 maxUlRbs; /*!< Maximum number of UL Rbs for UL scheduling */ + S8 delta; /*!< Delta corresponding to TPC, for PUSCH */ + U8 numRb; /*!< Number of RBs used in last allocation */ + S8 remPuschPwr; /*!< PUSCH power remaining to be adjusted + (in db) */ /* chk if needed */ + S8 remPucchPwr; /*!< PUCCH Power remaining to be adjusted (in db) */ + U8 pucchTpc; /*!< TPC to be used for PUCCH power control */ + U8 puschTpc; /*!< TPC to be used for PUSCH power control */ + U8 trgCqi; /*!< Target CQI */ + RgSchCmnTpcRntiCb *tpcPucchRntiCb; /*!< Pointer to tpcPucchRntiCb for the UE */ + CmLList pucchGrpLnk; /*!< To link together UEs in + * RgSchCmnTpcRntiCb */ + CmLList schdPucchGrpLnk; /*!< To link together scheduled + * UEs in RgSchCmnTpcRntiCb */ + RgSchCmnTpcRntiCb *tpcPuschRntiCb; /*!< Pointer to tpcPuschRntiCb for the UE */ + CmLList puschGrpLnk; /*!< To link together UEs in + * RgSchCmnTpcRntiCb */ + CmLList schdPuschGrpLnk; /*!< To link together scheduled + * UEs in RgSchCmnTpcRntiCb */ + S8 p0UePusch; /*!< P_0UE_PUSCH*/ + S8 p0UePucch; /*!< P_0_PUCCH*/ + S8 maxPwrPerRb; + S8 maxPwrDeltaByPhr; +} RgSchCmnUeUlPwrCb; + +/** + @brief Uplink RB allocation information. */ +struct rgSchCmnUeUlAlloc +{ + /* Request */ + U32 reqBytes; /*!< Requested bytes */ + + /* Allocation to be filled by UL RB allocator module */ + U32 allocdBytes; /*!< Allocated bytes */ + RgSchUlAlloc *alloc; /*!< Alloc assgnd by Allocator */ + CmLList reqLnk; /*!< To link UL Tx UEs */ + CmLList schdLstLnk; /*!< To link scheduled/non-scheduled UL UEs */ +}; + +typedef struct rgSchCmnAllocRecord +{ + U32 alloc; /* allocation amount */ + CmLteTimingInfo allocTime; /* Time at which allocation made */ + CmLList lnk; /* To link in ulAllocLst */ + U8 numRb; /* Number of RBs */ + U8 cqi; /* CQI assumed for allocation */ + U8 tpc; /* TPC */ +}RgSchCmnAllocRecord; + + +/** + * @brief + * Uplink Bler LA information for UE + */ +#ifdef UL_LA +typedef struct ueUlLaCb +{ + S32 deltaiTbs; + U32 iTbsUpperCap; + S32 cqiBasediTbs; + Bool lastiTbsIgnored; +} UeUlLaCb; +#endif + +/** + * @brief + * Uplink information for scheduler per UE + */ +typedef struct rgSchCmnUlUe +{ + U8 maxUlCqi; /*!< CQI for which no better Imcs can be granted */ + U8 crntUlCqi[RG_SCH_MAX_UL_TX_ANT]; /*!< Current CQI */ +/* Added changes of TFU_UPGRADE */ +#ifdef TFU_UPGRADE + U8 validUlCqi; +#endif + U8 lastCfi; /* last CFI, updated in case of SPS */ + CmLListCp ulAllocLst; /*!< To track the outstanding Allocations + * node type RgSchCmnAllocRecord */ + + + Void *schSpfc; /*!< scheduler specific UE DL Info */ + RgSchCmnUeUlPwrCb ulPwrCb; /*!< Uplink power control block */ + RgSchCmnUeUlAlloc alloc; /*!< Allocation info */ +#ifdef SCH_STATS + U32 schedOccns; /*!< Number of scheduling occassions in a refresh period */ + U32 schedRetxOccns; + U32 avgCqi; /*!< AvgCqi in a refresh period */ + U32 numCqiOccns; + U32 prbAlloc; +#endif +#ifdef UL_LA + UeUlLaCb ulLaCb; /*!< Uplink LA structure */ +#endif + RgUeUlHqCb hqEnt; /*!< Uplink HARQ information for the UE */ + U8 subbandShare; /*!< New variable added to store the number + * of subbands alowed for this UE */ + U32 subbandRequired; /*!< Number of subbands required to + * serve the total BO */ + CmLList ulSchedLnk; /*!< To link UE UL Cb to toBeSchedList */ +#ifdef EMTC_ENABLE + RgSchUlHqProcCb *tempProc; /*!< To identify UE is serverd for Retx */ +#endif +#ifdef RG_5GTF + U8 vrbgRequired; + U8 vrbgAllocated; +#endif +} RgSchCmnUlUe; + +/** + @brief Downlink RB allocation information for Msg4. */ +typedef struct rgSchCmnMsg4RbAlloc +{ + RgSchDlSf *msg4DlSf; /*!< DL sub-frame for which allocation is to + be done: filled in by RR/MAX C/I/PFS */ + CmLListCp msg4TxLst; /*!< List of RgSchDlRbAllocs for Msg4 Tx */ + CmLListCp msg4RetxLst; /*!< List of RgSchDlRbAllocs for Msg4 ReTx */ + CmLListCp schdMsg4TxLst; /*!< List of Msg4 Txs scheduled per TTI */ + CmLListCp schdMsg4RetxLst; /*!< List of Msg4 ReTxs scheduled in the TTI */ + CmLListCp nonSchdMsg4TxLst; /*!< List of transmitting MSG4 not scheduled in the TTI */ + CmLListCp nonSchdMsg4RetxLst; /*!< List of re-transmitting MSG4 not + scheduled in the TTI */ +} RgSchCmnMsg4RbAlloc; +#ifdef RGR_V1 +/* Changes for CR timer implementation*/ +typedef struct rgSchCmnCcchSduRbAlloc +{ + RgSchDlSf *ccchSduDlSf; /*!< DL sub-frame for which allocation is to + be done: filled in by RR/MAX C/I/PFS */ + CmLListCp ccchSduTxLst; /*!< List of RgSchDlRbAllocs for CcchSdu Tx */ + CmLListCp ccchSduRetxLst; /*!< List of RgSchDlRbAllocs for CcchSdu ReTx */ + CmLListCp schdCcchSduTxLst; /*!< List of CcchSdu Txs scheduled per TTI */ + CmLListCp schdCcchSduRetxLst; /*!< List of CcchSdu ReTxs scheduled in the TTI */ + CmLListCp nonSchdCcchSduTxLst; /*!< List of transmitting MSG4 not scheduled in the TTI */ + CmLListCp nonSchdCcchSduRetxLst; /*!< List of re-transmitting MSG4 not + scheduled in the TTI */ +} RgSchCmnCcchSduRbAlloc; +#endif + +/** + @brief Downlink RB allocation information for UEs. */ +typedef struct rgSchCmnUeRbAlloc +{ + RgSchDlSf *dedDlSf; /*!< DL sub-frame for which dedicated + allocation is to be done: filled in + by RR/MAX C/I/PFS */ + CmLListCp txHqPLst; /*!< List of HqPs to be scheduled for Tx per + TTI: RgSchUeCb list */ + CmLListCp retxHqPLst; /*!< List of HqPs scheduled for ReTx per + TTI: RgSchUeCb list */ + CmLListCp errIndTxHqPLst; /*!< LAA SCELL: List of transmitting LAA Err Ind Tx HqPs scheduled per TTI */ +#ifdef LTEMAC_SPS + CmLListCp retxSpsHqPLst; /*!< List of SPS HqPs scheduled for ReTx per + TTI: RgSchUeCb list */ + CmLListCp txSpsHqPLst; /*!< List of SPS HqPs scheduled for Tx per + TTI: RgSchUeCb list */ +#endif + CmLListCp txLaaHqPLst; /*!< List of LAA HqPs scheduled on PCell for Tx per +TTI*/ + CmLListCp schdTxHqPLst; /*!< List of transmitting HqPs scheduled per TTI */ + CmLListCp schdRetxHqPLst; /*!< List of re-transmitting HqPs scheduled per TTI */ + CmLListCp nonSchdTxHqPLst; /*!< List of transmitting HqPs not scheduled in the TTI */ + CmLListCp nonSchdRetxHqPLst;/*!< List of re-transmitting HqPs not scheduled in the TTI */ +/* Changes for MIMO feature addition */ + /* MIMO Tx+Retx hqProc scheduling handling */ + CmLListCp txRetxHqPLst; /*!< List of HqPs scheduled for tx and retx per + TTI(MIMO case): RgSchUeCb list */ + CmLListCp schdTxRetxHqPLst; /*!< List of TX&RETXing(MIMO case) HqPs scheduled per TTI */ + CmLListCp nonSchdTxRetxHqPLst; /*!< List of TX&RETXing(MIMO case) HqPs not scheduled in the TTI */ +#ifdef LTEMAC_SPS + CmLListCp schdRetxSpsHqPLst; /*!< List of re-transmitting SPS HqPs scheduled per TTI */ + CmLListCp nonSchdRetxSpsHqPLst;/*!< List of re-transmitting SPS HqPs + not scheduled in the TTI */ + CmLListCp schdTxSpsHqPLst; /*!< List of transmitting SPS HqPs scheduled per TTI */ + CmLListCp nonSchdTxSpsHqPLst; /*!< List of transmitting SPS HqPs not scheduled per TTI */ +#endif + CmLListCp schdTxLaaHqPLst; /*!< List of transmitting LAA TBs scheduled on PCell per TTI */ + CmLListCp nonSchdTxLaaHqPLst; /*!< List of transmitting LAA TBs not scheduled on PCell per TTI */ + CmLListCp schdErrIndTxHqPLst; /*!< List of transmitting LAA ErrInd TBs scheduled per TTI */ + CmLListCp nonSchdErrIndTxHqPLst; /*!< List of transmitting LAA ErrInd not scheduled per TTI */ +} RgSchCmnUeRbAlloc; + +/** + @brief Downlink RB allocation information. */ +struct rgSchCmnDlRbAllocInfo +{ + RgSchDlRbAlloc pcchAlloc; /*!< Allocation for PCCH */ + RgSchDlRbAlloc bcchAlloc; /*!< Allocation for BCCH on DLSCH */ + RgSchDlRbAlloc raRspAlloc[RG_SCH_CMN_MAX_CMN_PDCCH]; /*!< Allocation for RAR */ + RgSchCmnMsg4RbAlloc msg4Alloc; /*!< Alloction for Msg4 */ +#ifdef RGR_V1 + /* Changes for CR timer implementation*/ + RgSchCmnCcchSduRbAlloc ccchSduAlloc; /*!< Alloction for ccchSdu */ +#endif + RgSchCmnUeRbAlloc dedAlloc; /*!< Alloction information for UEs */ +}; + +/** + * @brief + * Cell specific common scheduler information for all Scheduler types. + */ +typedef struct rgSchCmnCell +{ + RgrCfiCfg cfiCfg; /*!< CFI for PDCCH */ + RgrUlTrgCqiCfg trgUlCqi; /*!< Target UL CQI */ + CmTqCp tmrTqCp; /*!< Refresh Timer Task Queue + * Control Point */ + CmTqType tmrTq[RG_SCH_CMN_NUM_REFRESH_Q]; /*!< Timer Task Queue */ + RgrDlCmnCodeRateCfg dlCmnCodeRate; /*!< Coding rate for common DL channels: + Expressed in multiples of 1024 */ + RgrPuschSubBandCfg puschSubBand; /*!< UL subband information */ + RgrUlCmnCodeRateCfg ulCmnCodeRate; /*!< Coding rate for common UL channels: + Expressed in multiples of 1024 */ + RgSchCmnRachCfg rachCfg; /*!< Rach configuration for schCmn */ + RgSchCmnUlCell ul; /*!< Scheduler UL info */ + RgSchCmnDlCell dl; /*!< Scheduler DL info */ + RgUlSchdApis *apisUl; /*!< Specific UL Scheduler APIs */ + RgDlSchdApis *apisDl; /*!< Specific DL Scheduler APIs */ + RgDlfsSchdApis *apisDlfs; /*!< APIs specific to DLFS scheduler */ +#ifdef EMTC_ENABLE + RgUlSchdApis *apisEmtcUl; /*!< Specific UL Scheduler APIs for EMTC*/ + RgDlEmtcSchdApis *apisEmtcDl; /*!< Specific DL Scheduler APIs for EMTC*/ +#endif + CmLteAggrLvl dciAggrLvl[RG_SCH_CMN_MAX_CQI][10]; + /*!< Aggr Level for each CQI for + * each DCI Format */ + RgSchCmnDlRbAllocInfo allocInfo; +}RgSchCmnCell; + + +/** + * @brief + * RACHO information for scheduler per UE. + */ +typedef struct rgSchCmnDlUeRachInfo +{ + CmLList inActUeLnk; /*!< Link UE to PO inactUeList */ + CmLList poLnk; /*!< To link UE to PDCCH Order Q */ + CmLList hoLnk; /*!< To link UE to HandOver UE lst */ + CmLList rapIdLnk; /*!< Link to the list assgndUes */ + CmLteTimingInfo asgnOppr; /*!< PRACH oppurtunity time assgined to UE */ + U8 hoRapId; /*!< RAPID assigned to UE for HandOver */ + U8 poRapId; /*!< RAPID assigned to UE for PdcchOrder */ +}RgSchCmnDlUeRachInfo; + + +/** + * @brief + * Downlink CodeWord information for scheduler per UE. + */ +typedef struct rgSchCmnDlUeCwInfo +{ + U8 cqi; /*!< CQI reported for this CW */ + U8 iTbs[2]; /*!< [0]ITBS for CW for 1 Layer, + corresponding to this CW's cqi. */ + /*!< [1]ITBS for CW for 2 Layer, + corresponding to this CW's cqi. */ + U32 eff[2]; /*!< [0]eff for CW for 1 Layer, + corresponding to this CW's cqi. */ + /*!< [1]eff for CW for 2 Layer, + corresponding to this CW's cqi. */ + U8 noLyr; /*!< No. of layers this CW shall be using + * for transmission */ + U16 dtxCnt; + U16 ackCnt; + U16 nackCnt; +}RgSchCmnDlUeCwInfo; +/** + * @brief UE cmn scheduler specific MIMO Info. + */ +typedef struct rgSchCmnUeMimoInfo +{ + RgSchCmnDlUeCwInfo cwInfo[RG_SCH_CMN_MAX_CW_PER_UE];/*!< Codeword related feddback Information */ + U8 ri; /*!< Maximum allowable number of TX layers for SM */ + U8 pmi; /*!< Precoding matrix indicator(if any) */ + U8 btrCwIdx; /*!< Index of a better(efficient) CW (0 or 1) */ + U8 forceTD; /*!< Flag to indicate transmission scheme as TD + * beyond any other consideration */ +}RgSchCmnUeMimoInfo; + +typedef struct ueLaCb { + S32 deltaiTbs; + U32 iTbsUpperCap; + S32 cqiBasediTbs; + Bool lastiTbsIgnored; + U8 notFirstCqi; + U8 numLastiTbsIgnored; +} UeLaCb; + +/** + * @brief + * Downlink information for scheduler per UE. + */ +typedef struct rgSchCmnDlUe +{ + U32 maxSbSz; /*!< Max soft channel bits per Hq proc per TTI */ + U32 maxTbSz; /*!< Max DLSCH TB bits per TB per TTI */ + U8 maxRb; /*!< updated based on SoftBuffer Limitation and MaxDlBwPerUE */ + U32 maxTbBits;/*!< Max Transport Block Bits this UE can receive per TTI*/ + RgSchCmnUeMimoInfo mimoInfo; /*!< UE cmn scheduler specific MIMO Info */ + RgSchDlHqProcCb *proc; /*!< Proc which is picked for Trans for this Subfrm,"dlSf" */ + Void *schSpfc; /*!< scheduler specific UE DL Info */ + Void *dlfsUe; /*!< DLFS Specific information */ + U32 outStndAlloc; /*!< UEs outstanding allocation, for a given TTI. + * valid for a single scheduling index */ + RgSchCmnDlUeRachInfo rachInfo; /*!< Ue specific RACH HO Info */ +#ifdef LTEMAC_SPS + RgSchCmnDlUeSpsInfo dlSpsInfo;/*!< DL SPS information for the UE */ +#endif +#if defined(SCH_STATS) || defined(TENB_STATS) + U32 schedOccns; + U32 currPdbLvl; + U32 prevOccnLvlUpd; + /* U32 schedRetxOccns; + U32 prbAlloc;*/ +#endif +#ifdef SCH_STATS + U32 schedRetxOccns; + U32 avgCqi; + U32 numCqiOccns; + U32 numRi1; + U32 numRi2; + U32 boReported; + U32 prbAlloc; + U32 remAmbrForStats; +#endif + UeLaCb laCb[RG_SCH_CMN_MAX_CW_PER_UE]; + U8 cqiFlag; + U8 lastCfi; +#ifdef RG_5GTF + U8 vrbgRequired; + U8 vrbgAllocated; +#endif +} RgSchCmnDlUe; + +/** + @brief Uplink RB allocation information. */ +struct rgSchCmnUlRbAllocInfo +{ +#ifdef EMTC_ENABLE + RgSchEmtcUlSf *ulsf; +#endif + RgSchUlSf *sf; /*!< Subframe to schedule for */ + CmLListCp contResLst; /*!< UEs to schedule for cnt resn */ + CmLListCp schdContResLst; /*!< Final UEs scheduled for cnt resn */ + CmLListCp nonSchdContResLst; /*!< UEs not scheduled for cnt resn*/ + CmLListCp ueLst; /*!< UEs to schedule for data */ + CmLListCp schdUeLst; /*!< Final UEs scheduled for data */ + CmLListCp nonSchdUeLst; /*!< Final UEs not scheduled for data */ +}; + +/** + * @brief + * Information common to DL and UL scheduler per UE. + */ +typedef struct rgSchCmnUeInfo +{ + U8 ueCat; /*!< UE category */ + CmTimer tmr; +} RgSchCmnUeInfo; +/** + * @brief + * Information for scheduler per UE. + */ +typedef struct rgSchCmnUe +{ + RgSchCmnUeInfo cmn; /*!< UE specific scheduler information common to + uplink and downlink */ + RgSchCmnUlUe ul; /*!< UE specific UL scheduler information */ + RgSchCmnDlUe dl; /*!< UE specific DL scheduler informaion */ +} RgSchCmnUe; + +typedef struct rgSchCmnLcg +{ + U32 bs; /*!< Effective Buffer Status */ + U32 cfgdGbr; /*!< Configured GBR */ + U32 effGbr; /*!< Effective GBR */ + U32 deltaMbr; /*!< Configured MBR in excess of configured GBR */ + U32 effDeltaMbr; /*!< Effective MBR */ + U32 reportedBs; /*!< Latest Buffer Status */ + Void *schSpfc; +}RgSchCmnLcg; + +#ifdef LTEMAC_SPS +/** + * @brief + * SPS information for DL service + */ +typedef struct rgSchCmnDlSvcSpsInfo +{ + CmLList toBeSchdSvcEnt; /*!< Linked list entity for toBeSchdSvcs lst */ + U16 zeroBoOcassionCnt; /*!< Number of contiguous SPS ocassions for + which BO=0 */ + U32 effSpsBo; /*!< Effective BO of the SPS service */ + U32 bytesReq; /*!< Bytes Requested for this SPS service */ + U8 hdrEst; /*!< Header estimate for SPS service */ + +} RgSchCmnDlSvcSpsInfo; +#endif + +typedef struct rgSchCmnDlSvc { + U8 qci; /*!< Prio computed against Qci */ + U8 prio; /*!< Prio computed against Qci */ + U32 gbr; /*!< scaled GBR as per Refresh time resolution */ + U32 mbr; /*!< scaled MBR as per Refresh time resolution */ + Void *schSpfc[CM_LTE_MAX_CELLS];/*!< Scheduler specific Info */ +#ifdef LTEMAC_SPS + RgSchCmnDlSvcSpsInfo dlSvcSpsInfo; /*!< SPS related information for DL + service */ +#endif +}RgSchCmnDlSvc; + +typedef struct rgSchCmnDlHqProc { + CmLList retxLnk; /*!< To link retransmitting HARQ processes in cell */ + U32 totBytes;/*!< This maintains total allocation */ +#ifdef LTEMAC_SPS + Bool isSpsSvcSchd;/*!< Indicates if this HARQ process is having SPS + service scheduled: TRUE for SPS and non-SPS + ocassions */ + Bool isSpsActv; /*!< Indicates if this HARQ proc + is in-use for SPS transmission: TRUE only for + SPS ocassions */ + U8 spsAction; /*!< SPS action associated with this HARQ proc: + activation/reactivation */ + CmLteTimingInfo maxRetxTime; /*!< Maximum retransmission time for SPS HARQ + proc */ +#endif + Void *schSpfc;/*!< Scheduler specific Info */ +}RgSchCmnDlHqProc; + +/*--------------------------* + * UL specific declarations END + *---------------------------*/ + +/* Inappropriate name of CQI to ITbs table for DL. */ +typedef U8 RgSchCmnCqiToTbs[16]; +/* The following data type is used to store computed efficiency */ +/* for each MCS and consequently, will be used to derive MCS */ +/* for a CQI. The last row is used for storing the average */ +typedef U32 RgSchCmnTbSzEff[RG_SCH_CMN_NUM_TBS]; + +/* Inappropriate name of CQI to ITbs table for DL. */ +/* Changes for MIMO feature addition */ +EXTERN RgSchCmnTbSzEff rgSchCmnNorCfi1Eff[RGSCH_MAX_NUM_LYR_PERCW], rgSchCmnNorCfi2Eff[RGSCH_MAX_NUM_LYR_PERCW]; +EXTERN RgSchCmnTbSzEff rgSchCmnNorCfi3Eff[RGSCH_MAX_NUM_LYR_PERCW], rgSchCmnNorCfi4Eff[RGSCH_MAX_NUM_LYR_PERCW]; +/* Added new variable for Ul eff */ +EXTERN RgSchCmnTbSzEff rgSchCmnNorUlEff[1],rgSchCmnExtUlEff[1]; +EXTERN RgSchCmnCqiToTbs rgSchCmnNorCfi1CqiToTbs[RGSCH_MAX_NUM_LYR_PERCW], rgSchCmnNorCfi2CqiToTbs[RGSCH_MAX_NUM_LYR_PERCW]; +EXTERN RgSchCmnCqiToTbs rgSchCmnNorCfi3CqiToTbs[RGSCH_MAX_NUM_LYR_PERCW], rgSchCmnNorCfi4CqiToTbs[RGSCH_MAX_NUM_LYR_PERCW]; +EXTERN RgSchCmnCqiToTbs *rgSchCmnCqiToTbs[RGSCH_MAX_NUM_LYR_PERCW][RG_SCH_CMN_MAX_CP][RG_SCH_CMN_MAX_CFI]; +EXTERN RgSchCmnTbSzEff rgSchCmnExtCfi1Eff[RGSCH_MAX_NUM_LYR_PERCW], rgSchCmnExtCfi2Eff[RGSCH_MAX_NUM_LYR_PERCW]; +EXTERN RgSchCmnTbSzEff rgSchCmnExtCfi3Eff[RGSCH_MAX_NUM_LYR_PERCW], rgSchCmnExtCfi4Eff[RGSCH_MAX_NUM_LYR_PERCW]; +EXTERN RgSchCmnCqiToTbs rgSchCmnExtCfi1CqiToTbs[RGSCH_MAX_NUM_LYR_PERCW], rgSchCmnExtCfi2CqiToTbs[RGSCH_MAX_NUM_LYR_PERCW]; +EXTERN RgSchCmnCqiToTbs rgSchCmnExtCfi3CqiToTbs[RGSCH_MAX_NUM_LYR_PERCW], rgSchCmnExtCfi4CqiToTbs[RGSCH_MAX_NUM_LYR_PERCW]; +/* Include CRS REs while calculating Efficiency */ +EXTERN RgSchCmnTbSzEff +*rgSchCmnEffTbl[RGSCH_MAX_NUM_LYR_PERCW][RG_SCH_CMN_MAX_CP][RG_SCH_CMN_MAX_ANT_CONF][RG_SCH_CMN_MAX_CFI]; +/* Added new variable for Ul eff */ +EXTERN RgSchCmnTbSzEff *rgSchCmnUlEffTbl[RG_SCH_CMN_MAX_CP]; + +EXTERN RgSchTbSzTbl rgTbSzTbl; + +EXTERN Void rgSCHCmnInit ARGS((Void +)); +EXTERN S16 rgSCHCmnRgrCellCfg ARGS(( +RgSchCellCb *cell, +RgrCellCfg *cellCfg, +RgSchErrInfo *err +)); +EXTERN S16 rgSCHCmnRgrCellRecfg ARGS(( +RgSchCellCb *cell, +RgrCellRecfg *recfg, +RgSchErrInfo *err +)); +EXTERN Void rgSCHCmnFreeDlLc ARGS(( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgSchDlLcCb *svc +)); +EXTERN Void rgSCHCmnCellDel ARGS(( +RgSchCellCb *cell +)); +EXTERN Void rgSCHCmnDlRlsSubFrm ARGS(( +RgSchCellCb *cell, +CmLteTimingInfo frm +)); +#ifdef LTE_ADV +EXTERN S16 rgSCHCmnRgrSCellUeCfg ARGS(( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgrUeSecCellCfg *sCellInfoCfg, +RgSchErrInfo *err +)); + +EXTERN Void rgSchFreeTpcIdxForSCell ARGS(( +RgSchUeCb *ue, +RgSchDlHqProcCb *proc, +RgSchDlSf *dlsf +)); + +EXTERN Bool rgSchIsN1PucchResAvail ARGS(( + CmLListCp *lst, + RgSchUeCb *ue, + U8 n1Idx, + U8 resCount +)); +EXTERN Bool rgSchIsN3PucchResAvail ARGS(( + CmLListCp *lst, + RgSchUeCb *ue, + U8 n1Idx +)); + +EXTERN S16 rgSchGetAvlTpcIdx ARGS(( + RgSchUeCb *ue, + U8 *tpcIdx, + RgSchDlSf *dlsf, + RgSchCellCb *cell +)); + +EXTERN Void rgSCHSCellDelUeSCell ARGS(( + RgSchCellCb *cellCb, + RgSchUeCb *ueCb, + U8 sCellIdx +)); + +EXTERN S16 rgSCHCmnRgrSCellUeDel ARGS(( + RgSchUeCellInfo *sCellInfo, + RgSchUeCb *ue +)); + +#endif /* LTE_ADV */ +EXTERN S16 rgSCHCmnRgrUeCfg ARGS(( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgrUeCfg *ueCfg, +RgSchErrInfo *err +)); +EXTERN S16 rgSCHCmnRgrUeRecfg ARGS(( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgrUeRecfg *ueRecfg, +RgSchErrInfo *err +)); +EXTERN Void rgSCHCmnUeDel ARGS(( +RgSchCellCb *cell, +RgSchUeCb *ue +)); +EXTERN Void rgSCHCmnUeReset ARGS(( +RgSchCellCb *cell, +RgSchUeCb *ue +)); +EXTERN S16 rgSCHCmnRgrLcgRecfg ARGS(( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgSchLcgCb *lcg, +RgrLcgRecfg *reCfg, +RgSchErrInfo *err +)); +EXTERN S16 rgSCHCmnRgrLcgCfg ARGS(( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgSchLcgCb *lcg, +RgrLcgCfg *lcgCfg, +RgSchErrInfo *err +)); +EXTERN S16 rgSCHCmnRgrLchCfg ARGS(( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgSchDlLcCb *dlLc, +RgrLchCfg *lcCfg, +RgSchErrInfo *err +)); +EXTERN S16 rgSCHCmnRgrLchDel ARGS(( +RgSchCellCb *cell, +RgSchUeCb *ue, +CmLteLcId lcId, +U8 lcgId +)); +EXTERN S16 rgSCHCmnRgrLchRecfg ARGS(( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgSchDlLcCb *dlLc, +RgrLchRecfg *lcRecfg, +RgSchErrInfo *err +)); +EXTERN Void rgSCHCmnLcgDel ARGS(( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgSchLcgCb *lcg +)); +EXTERN S16 rgSCHCmnUpdBsrShort ARGS(( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgSchLcgCb *ulLcg, +U8 bsr, +RgSchErrInfo *err +)); +EXTERN S16 rgSCHCmnUpdBsrTrunc ARGS(( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgSchLcgCb *ulLcg, +U8 bsr, +RgSchErrInfo *err +)); +EXTERN S16 rgSCHCmnUpdBsrLong ARGS(( +RgSchCellCb *cell, +RgSchUeCb *ue, +U8 bsArr[], +RgSchErrInfo *err +)); +EXTERN S16 rgSCHCmnDataRcvd ARGS(( +RgSchCellCb *cell, +RgSchUeCb *ue, +U8 numLc, +RgSchUlLcCb *lcArr[], +U16 bytesArr[], +RgSchErrInfo *err +)); +EXTERN Void rgSCHCmnUlCqiInd ARGS(( +RgSchCellCb *cell, +RgSchUeCb *ue, +TfuUlCqiRpt *ulCqiInfo +)); +EXTERN S16 rgSCHCmnUpdExtPhr ARGS(( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgInfExtPhrCEInfo *extPhr, +RgSchErrInfo *err +)); +EXTERN S16 rgSCHCmnUpdPhr ARGS(( +RgSchCellCb *cell, +RgSchUeCb *ue, +U8 phr, +RgSchErrInfo *err +)); +EXTERN S16 rgSCHCmnUpdUlHqProc ARGS(( +RgSchCellCb *cell, +RgSchUlHqProcCb *curProc, +RgSchUlHqProcCb *oldProc +)); +EXTERN S16 rgSCHCmnContResUlGrant ARGS(( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgSchErrInfo *err +)); +EXTERN Void rgSCHCmnActvtUlUe ARGS(( +RgSchCellCb *cell, +RgSchUeCb *ue +)); +EXTERN Void rgSCHCmnActvtDlUe ARGS(( +RgSchCellCb *cell, +RgSchUeCb *ue +)); +EXTERN Void rgSCHCmnHdlUlTransInd ARGS(( +RgSchCellCb *cell, +RgSchUeCb *ue, +CmLteTimingInfo timingInfo +)); +EXTERN S16 rgSCHCmnSrRcvd ARGS(( +RgSchCellCb *cell, +RgSchUeCb *ue, +CmLteTimingInfo frm, +RgSchErrInfo *err +)); +EXTERN Void rgSCHCmnUlRbAllocAddUeToLst ARGS(( +RgSchCellCb *cell, +RgSchUeCb *ue, +CmLListCp *lst +)); +EXTERN S16 rgSCHCmnTti ARGS(( +RgSchCellCb *cell, +RgSchErrInfo *err +)); +EXTERN Void rgSCHCmnUlHqProcForUe ARGS(( +RgSchCellCb *cell, +CmLteTimingInfo frm, +RgSchUeCb *ue, +RgSchUlHqProcCb **procRef +)); +EXTERN RgSchUlAlloc *rgSCHCmnFirstRcptnReq ARGS(( +RgSchCellCb *cell +)); +EXTERN RgSchUlAlloc *rgSCHCmnNextRcptnReq ARGS(( +RgSchCellCb *cell, +RgSchUlAlloc *alloc +)); +EXTERN RgSchUlAlloc *rgSCHCmnFirstHqFdbkAlloc ARGS(( +RgSchCellCb *cell, +U8 idx +)); +EXTERN RgSchUlAlloc *rgSCHCmnNextHqFdbkAlloc ARGS(( +RgSchCellCb *cell, +RgSchUlAlloc *alloc, +U8 idx +)); +EXTERN Void rgSCHCmnDlDedBoUpd ARGS(( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgSchDlLcCb *svc +)); +/* Fix: syed Remove the msg4Proc from cell + * msg4Retx Queue. I have used CMN scheduler function + * directly. Please define a new API and call this + * function through that. */ +EXTERN Void rgSCHCmnDlMsg4ProcRmvFrmRetx ARGS(( +RgSchCellCb *cell, +RgSchDlHqProcCb *hqP +)); +EXTERN Void rgSCHCmnDlProcAddToRetx ARGS(( +RgSchCellCb *cell, +RgSchDlHqProcCb *hqP +)); + +#ifdef EMTC_ENABLE +EXTERN Void rgSCHCmnEmtcUlProcAddToRetx ARGS(( +RgSchCellCb *cell, +RgSchUlHqProcCb *hqP +)); +#endif + +EXTERN Void rgSCHCmnDlCqiInd ARGS(( +RgSchCellCb *cell, +RgSchUeCb *ue, +Bool isPucchInfo, +Void *dlCqi, +CmLteTimingInfo timingInfo +)); +/* Added changes of TFU_UPGRADE */ +#ifdef TFU_UPGRADE +EXTERN Void rgSCHCmnRawCqiInd ARGS +(( +RgSchCellCb *cellCb, +RgSchUeCb *ueCb, +TfuRawCqiRpt *rawCqiRpt, +CmLteTimingInfo timingInfo +)); + +EXTERN Void rgSCHCmnSrsInd ARGS +(( +RgSchCellCb *cellCb, +RgSchUeCb *ueCb, +TfuSrsRpt *srsRpt, +CmLteTimingInfo timingInfo +)); +#endif /* TFU_UPGRADE */ + +EXTERN Void rgSCHCmnDlTARpt ARGS(( +RgSchCellCb *cell, +RgSchUeCb *ue +)); +EXTERN RgSchPdcch *rgSCHCmnCmnPdcchAlloc ARGS(( +RgSchCellCb *cell, +RgSchDlSf *subFrm +)); +EXTERN RgSchUlAlloc *rgSCHCmnUlSbAlloc ARGS(( +RgSchUlSf *sf, +U8 numSb, +RgSchUlHole *hole +)); +EXTERN Void rgSCHCmnRlsUlSf ARGS(( +RgSchCellCb *cell, +U8 idx +)); + +/* PHR handling for MSG3 */ +EXTERN Void rgSCHCmnUlRecMsg3Alloc ARGS(( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgSchRaCb *raCb +)); + +/* Added periodic BSR timer */ + +/*ccpu00117180 - ADD - Added Prototype in .x since the function access is now PUBLIC */ +PUBLIC Void rgSCHCmnUpdVars ARGS(( +RgSchCellCb *cell +)); + +#ifdef LTEMAC_SPS +EXTERN Void rgSCHCmnFillHqPTb ARGS(( +RgSchCellCb *cell, +RgSchDlRbAlloc *rbAllocInfo, +U8 tbAllocIdx, +RgSchPdcch *pdcch +)); + +EXTERN Void rgSCHCmnDlProcAck ARGS(( +RgSchCellCb *cell, +RgSchDlHqProcCb *hqP +)); +EXTERN Void rgSCHCmnHdlCrntiCE ARGS(( +RgSchCellCb *cell, +RgSchUeCb *ue +)); +EXTERN Void rgSCHCmnDlRelPdcchFbk ARGS(( +RgSchCellCb *cell, +RgSchUeCb *ue, +Bool isAck +)); +EXTERN Void rgSCHCmnDlGetRbgInfo ARGS(( +U8 dlTotalBw, +U8 dlSubsetBw, +U8 maxRaType1SubsetBw, +U8 rbgSize, +RgSchBwRbgInfo *rbgInfo +)); +EXTERN U8 rgSCHCmnDlRaType0Alloc ARGS(( +RgSchDlSfAllocInfo *allocedInfo, +U8 rbsReq, +RgSchBwRbgInfo *rbgInfo, +U8 *numAllocRbs, +RgSchDlSfAllocInfo *resAllocInfo, +Bool isPartialAlloc +)); +#ifdef RGSCH_SPS_UNUSED +EXTERN U8 rgSCHCmnDlRaType1Alloc ARGS(( +RgSchDlSfAllocInfo *allocedInfo, +U8 rbsReq, +RgSchBwRbgInfo *rbgInfo, +U8 startRbgSubset, +U8 *allocRbgSubset, +RgSchDlSfAllocInfo *resAllocInfo, +Bool isPartialAlloc +)); +#endif +EXTERN U8 rgSCHCmnDlRaType2Alloc ARGS(( +RgSchDlSfAllocInfo *allocedInfo, +U8 rbsReq, +RgSchBwRbgInfo *rbgInfo, +U8 *rbStart, +RgSchDlSfAllocInfo *resAllocInfo, +Bool isPartialAlloc +)); +EXTERN Bool rgSCHCmnAllocUeInSpsBw ARGS(( +RgSchDlSf *dlSf, +RgSchCellCb *cell, +RgSchUeCb *ue, +RgSchDlRbAlloc *rbAllocInfo, +Bool isPartialAlloc +)); +#endif +EXTERN Void rgSCHCmnDrxStrtInActvTmrInUl ARGS((RgSchCellCb *cell)); +EXTERN Void rgSCHCmnUpdUeDataIndLcg ARGS((RgSchCellCb *cell, RgSchUeCb *ue, RgInfUeDatInd *datInd)); +#ifdef LTE_TDD +EXTERN U8 rgSCHCmnGetPhichUlSfIdx ARGS((CmLteTimingInfo *timeInfo, RgSchCellCb *cell)); +EXTERN U8 rgSCHCmnGetUlSfIdx ARGS((CmLteTimingInfo *timeInfo, RgSchCellCb *cell)); +EXTERN U8 rgSCHCmnGetPValFrmCCE ARGS((RgSchCellCb *cell, U8 cce)); +#endif +EXTERN U8 rgSCHCmnGetUlHqProcIdx ARGS((CmLteTimingInfo *timeInfo, RgSchCellCb *cell)); + +EXTERN Void rgSchCmnSetCqiReqField ARGS(( + RgSchUeCellInfo *cellInfo, + RgSchUeCb *ue, + RgSchCqiReqField *cqiReq +)); + +/* APIs exposed by COMMON SCHEDULER to + * SPECIFIC SCHEDULER */ +/* UL_ALLOC_CHANGES */ +EXTERN Void rgSCHCmnUlFreeAlloc ARGS(( +RgSchCellCb *cell, +RgSchUlAlloc *alloc +)); +#ifndef EMTC_ENABLE +EXTERN Void rgSCHCmnUlFreeAllocation ARGS(( +RgSchCellCb *cell, +RgSchUlSf *sf, +RgSchUlAlloc *alloc +)); +#else +EXTERN Void rgSCHCmnUlFreeAllocation ARGS(( +RgSchCellCb *cell, +RgSchUlSf *sf, +RgSchUlAlloc *alloc, +Bool isEmtcUe +)); +#endif +/* APIs exposed by DL RB allocation module */ +EXTERN S16 rgSCHCmnAllocDlRb ARGS(( +RgSchCellCb *cell, +RgSchCmnDlRbAllocInfo *dlRbAllocInfo +)); + +/* APIs exposed by UL RB allocation module */ +EXTERN Void rgSCHCmnAllocUlRb ARGS(( +RgSchCellCb *cell, +RgSchCmnUlRbAllocInfo *ulRbAllocInfo +)); + +/* APIs Exposed to Specific Scheduler */ +EXTERN RgSchPdcch *rgSCHCmnPdcchAllocCrntSf ARGS(( +RgSchCellCb *cell, +RgSchUeCb *ue +)); +EXTERN Void rgSCHCmnPdcchRlsCrntSf ARGS(( +RgSchCellCb *cell, +RgSchPdcch *pdcch +)); +EXTERN Void rgSCHCmnUlFillPdcchWithAlloc ARGS(( +RgSchPdcch *pdcch, +RgSchUlAlloc *alloc, +RgSchUeCb *ue +)); +EXTERN Void rgSCHCmnUlAllocFillTpc ARGS(( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgSchUlAlloc *alloc +)); +EXTERN Void rgSCHCmnUlAllocFillNdmrs ARGS(( +RgSchCmnUlCell *cellUl, +RgSchUlAlloc *alloc +)); +EXTERN Void rgSCHCmnUlAllocLnkHqProc ARGS(( +RgSchUeCb *ue, +RgSchUlAlloc *alloc, +RgSchUlHqProcCb *proc, +Bool isReTx +)); +EXTERN RgSchPdcch *rgSCHCmnPdcchAlloc ARGS(( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgSchDlSf *subFrm, +U8 cqi, +TfuDciFormat dciFrmt, +Bool isDtx +)); +EXTERN Void rgSCHCmnRdcImcsTxTb ARGS(( +RgSchDlRbAlloc *allocInfo, +U8 tbInfoIdx, +U32 cnsmdBytes +)); +EXTERN Void rgSCHCmnFillPdcch ARGS(( +RgSchCellCb *cell, +RgSchPdcch *pdcch, +RgSchDlRbAlloc *rbAllocInfo +)); +EXTERN U8 rgSCHCmnUpdDai ARGS(( +RgSchUeCb *ue, +CmLteTimingInfo *fdbkTime, +U8 m, +Bool havePdcch, +RgSchDlHqProcCb *hqP, +U8 *ulDai + +)); +EXTERN Void rgSCHCmnFillHqPPdcch ARGS(( +RgSchCellCb *cell, +RgSchDlRbAlloc *rbAllocInfo, +RgSchDlHqProcCb *hqP +)); +EXTERN S16 rgSCHCmnDlChkResAvl ARGS(( +RgSchCellCb *cell, +RgSchDlSf *subFrm, +RgSchUeCb *ue, +RgSchDlHqProcCb *proc, +U32 *bo, +U8 *iTbs, +U32 *maxRb +)); +EXTERN S16 rgSCHCmnDlDedAlloc ARGS(( +RgSchCellCb *cell, +RgSchDlSf *subFrm, +RgSchUeCb *ue, +RgSchDlHqProcCb *proc, +U32 bo, +U8 iTbs, +U32 maxRb, +U32 *bytes +)); +EXTERN Void rgSCHCmnUlUeFillAllocInfo ARGS(( +RgSchCellCb *cell, +RgSchUeCb *ue +)); +/* Fixing incorrect Imcs derivation */ +EXTERN U8 rgSCHCmnUlGetITbsFrmIMcs ARGS(( +U8 iMcs +)); +/* Adding ueCtg to argument list */ +EXTERN U8 rgSCHCmnUlGetIMcsFrmITbs ARGS(( +U8 iTbs, +CmLteUeCategory ueCtg +)); +EXTERN U32 rgSCHCmnUlMinTbBitsForITbs ARGS(( +RgSchCmnUlCell *cellUl, +U8 iTbs +)); +EXTERN U8 rgSCHCmnUlGetITbs ARGS(( +RgSchCellCb *cell, +RgSchUeCb *ue, +Bool isEcp +)); +EXTERN Void rgSCHCmnUlAllocFillRbInfo ARGS(( +RgSchCellCb *cell, +RgSchUlSf *sf, +RgSchUlAlloc *alloc +)); +EXTERN Void rgSCHCmnDlUeResetTemp ARGS(( +RgSchUeCb *ue, +RgSchDlHqProcCb *hqP +)); +EXTERN Void rgSCHCmnUlUeResetTemp ARGS(( +RgSchCellCb *cell, +RgSchUeCb *ue +)); +/* proc is added for DTX support */ +/* DL per UE RB allocation API */ +EXTERN S16 rgSCHCmnDlAllocTxRb ARGS(( +RgSchCellCb *cell, +RgSchDlSf *subFrm, +RgSchUeCb *ue, +U32 bo, +U32 *effBo, +RgSchDlHqProcCb *proc, +RgSchCmnDlRbAllocInfo *cellWdAllocInfo +)); +EXTERN PUBLIC Bool rgSCHCmnIsDlCsgPrio ARGS(( +RgSchCellCb *cell +)); +EXTERN PUBLIC Bool rgSCHCmnIsUlCsgPrio ARGS(( +RgSchCellCb *cell +)); +EXTERN S16 rgSCHCmnDlAllocRetxRb ARGS(( +RgSchCellCb *cell, +RgSchDlSf *subFrm, +RgSchUeCb *ue, +U32 bo, +U32 *effBo, +RgSchDlHqProcCb *proc, +RgSchCmnDlRbAllocInfo *cellWdAllocInfo +)); +#ifdef LTEMAC_SPS +EXTERN Void rgSCHCmnClcRbAlloc ARGS(( +RgSchCellCb *cell, +U32 bo, +U8 cqi, +U8 *rb, +U32 *tbs, +U8 *mcs, +U8 *iTbs, +Bool isSpsBo, +RgSchDlSf *sf +)); +PUBLIC U32 rgSCHCmnCalcRiv ARGS(( +U8 bw, +U8 rbStart, +U8 numRb +)); +#endif /* LTEMAC_SPS */ + +/* end: Apis to add Ues in to DlRbAllocInfo Lists */ +/* start: Apis to add Ues in to UlRbAllocInfo Lists */ +EXTERN Void rgSCHCmnUlAdd2UeLst ARGS(( +RgSchCellCb *cell, +RgSchCmnUlRbAllocInfo *allocInfo, +RgSchUeCb *ue +)); +EXTERN Void rgSCHCmnUlAdd2CntResLst ARGS(( +RgSchCmnUlRbAllocInfo *allocInfo, +RgSchUeCb *ue +)); +EXTERN Void rgSCHCmnRmvFrmTaLst ARGS(( +RgSchCellCb *cell, +RgSchUeCb *ue +)); +/* end: Apis to add Ues in to UlRbAllocInfo Lists */ +EXTERN Void rgSCHCmnUlUpdOutStndAlloc ARGS(( +RgSchCellCb *cell, +RgSchUeCb *ue, +U32 alloc +)); + +EXTERN Void rgSCHCmnUlRecordUeAlloc ARGS(( +RgSchCellCb *cell, +RgSchUeCb *ue +)); + + + +/* APIs exposed by common power module */ +EXTERN Void rgSCHPwrInit ARGS(( + Void)); +EXTERN U8 rgSCHPwrPuschTpcForUe ARGS(( + RgSchCellCb *cell, + RgSchUeCb *ue)); +EXTERN U8 rgSCHPwrGetMaxUlRb ARGS(( + RgSchCellCb *cell, + RgSchUeCb *ue)); +EXTERN U8 rgSCHPwrPucchTpcForUe ARGS(( + RgSchCellCb *cell, + RgSchUeCb *ue)); +EXTERN Void rgSCHPwrGrpCntrlPucch ARGS(( + RgSchCellCb *cell, + RgSchDlSf *dlSf)); +EXTERN Void rgSCHPwrGrpCntrlPusch ARGS(( + RgSchCellCb *cell, + RgSchDlSf *dlSf, + RgSchUlSf *ulSf)); +EXTERN Void rgSCHPwrPucchDeltaInd ARGS(( + RgSchCellCb *cell, + RgSchUeCb *ue, + S8 pwrDelta)); +EXTERN Void rgSCHPwrUpdExtPhr ARGS(( + RgSchCellCb *cell, + RgSchUeCb *ue, + RgInfExtPhrCEInfo *extPhr, + RgSchCmnAllocRecord *allocInfo)); +EXTERN Void rgSCHPwrUpdPhr ARGS(( + RgSchCellCb *cell, + RgSchUeCb *ue, + U8 phr, + RgSchCmnAllocRecord *allocInfo, + S8 maxUePwr)); +EXTERN Void rgSCHPwrUlCqiInd ARGS(( + RgSchCellCb *cell, + RgSchUeCb *ue + )); +EXTERN Void rgSCHPwrRecordRbAlloc ARGS(( + RgSchCellCb *cell, + RgSchUeCb *ue, + U8 numRb + )); +EXTERN S16 rgSCHPwrCellCfg ARGS(( + RgSchCellCb *cell, + RgrCellCfg *cfg)); +EXTERN S16 rgSCHPwrCellRecfg ARGS(( + RgSchCellCb *cell, + RgrCellRecfg *recfg)); +EXTERN Void rgSCHPwrCellDel ARGS(( + RgSchCellCb *cell)); + +#ifdef LTE_ADV +EXTERN S16 rgSCHPwrUeSCellCfg ARGS(( + RgSchCellCb *cell, + RgSchUeCb *ue, + RgrUeSecCellCfg *sCellInfoCfg)); +#endif + +EXTERN S16 rgSCHPwrUeCfg ARGS(( + RgSchCellCb *cell, + RgSchUeCb *ue, + RgrUeCfg *cfg)); +EXTERN S16 rgSCHPwrUeRecfg ARGS(( + RgSchCellCb *cell, + RgSchUeCb *ue, + RgrUeRecfg *recfg)); +EXTERN Void rgSCHPwrUeDel ARGS(( + RgSchCellCb *cell, + RgSchUeCb *ue)); +EXTERN Void rgSCHPwrUeReset ARGS(( + RgSchCellCb *cell, + RgSchUeCb *ue)); + +#ifdef LTEMAC_SPS +EXTERN S16 rgSCHCmnSpsUlProcCrcInd ARGS(( +RgSchCellCb *cell, +RgSchUeCb *ue, +CmLteTimingInfo crcTime +)); +EXTERN Void rgSCHCmnSpsInit ARGS((Void)); + +EXTERN Void rgSCHCmnSpsRelDlSpsActHqP ARGS(( +RgSchCellCb *cell, +RgSchDlHqProcCb *hqP)); + +EXTERN S16 rgSCHCmnSpsCellCfg ARGS(( +RgSchCellCb *cell, +RgrCellCfg *cellCfg, +RgSchErrInfo *err)); +EXTERN Void rgSCHCmnSpsCellDel ARGS(( +RgSchCellCb *cell +)); +EXTERN S16 rgSCHCmnSpsUeCfg ARGS(( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgrUeCfg *ueCfg, +RgSchErrInfo *err +)); +EXTERN S16 rgSCHCmnSpsUeRecfg ARGS(( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgrUeRecfg *ueRecfg, +RgSchErrInfo *err +)); +EXTERN Void rgSCHCmnSpsUeDel ARGS(( +RgSchCellCb *cell, +RgSchUeCb *ue +)); +EXTERN S16 rgSCHCmnSpsDlLcRecfg ARGS(( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgSchDlLcCb *dlLc, +RgrLchRecfg *lcRecfg, +RgSchErrInfo *err +)); +EXTERN S16 rgSCHCmnSpsDlLcCfg ARGS(( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgSchDlLcCb *dlLc, +RgrLchCfg *lcCfg, +RgSchErrInfo *err +)); +EXTERN Void rgSCHCmnSpsDlLcDel ARGS(( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgSchDlLcCb *dlLc +)); +EXTERN Void rgSCHCmnSpsDlCqiIndHndlr ARGS(( +RgSchCellCb *cell, +RgSchUeCb *ue, +CmLteTimingInfo timingInfo +)); +EXTERN Void rgSCHCmnSpsDlDedBoUpd ARGS(( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgSchDlLcCb *dlLc +)); +EXTERN Void rgSCHCmnSpsDlUeReset ARGS(( +RgSchCellCb *cell, +RgSchUeCb *ue +)); +EXTERN Void rgSCHCmnSpsDlProcAddToRetx ARGS(( +RgSchCellCb *cell, +RgSchDlHqProcCb *hqP +)); +EXTERN Void rgSCHCmnSpsDlProcAck ARGS(( +RgSchCellCb *cell, +RgSchDlHqProcCb *hqP +)); + +EXTERN Void rgSCHCmnSpsDlRelPdcchFbk ARGS(( +RgSchCellCb *cell, +RgSchUeCb *ue, +Bool isAck +)); +EXTERN Void rgSCHCmnSpsDlSched ARGS(( +RgSchCellCb *cell, +RgSchCmnDlRbAllocInfo *allocInfo +)); +#ifdef RG_UNUSED +EXTERN S16 rgSCHCmnSpsGetDlActvUe ARGS(( +RgSchCellCb *cell, +CmLteTimingInfo *timingInfo, +CmLListCp *dlSpsActvUeLst +)); +#endif +EXTERN Void rgSCHCmnSpsDlAllocFnlz ARGS(( +RgSchCellCb *cell, +RgSchCmnDlRbAllocInfo *allocInfo +)); + +EXTERN Void rgSCHCmnSpsDlUpdDlSfAllocWithSps ARGS(( +RgSchCellCb *cell, +CmLteTimingInfo schdTime, +RgSchDlSf *dlSf +)); + + +/* APIs exposed by UL SPS */ +EXTERN Void rgSCHCmnSpsUlLcgDel ARGS(( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgSchLcgCb *lcg +)); +EXTERN Void rgSCHCmnSpsUlUeReset ARGS(( +RgSchCellCb *cell, +RgSchUeCb *ue +)); +EXTERN Void rgSCHCmnSpsUlProcRelInd ARGS(( +RgSchCellCb *cell, +RgSchUeCb *ue, +Bool isExplRel +)); + +EXTERN Void rgSCHCmnSpsUlProcActInd ARGS(( +RgSchCellCb *cell, +RgSchUeCb *ue, +U16 spsSduSize +)); +EXTERN Void rgSCHCmnSpsPhrInd ARGS(( +RgSchCellCb *cell, +RgSchUeCb *ue +)); + + +EXTERN S16 rgSCHCmnSpsBsrRpt ARGS(( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgSchLcgCb *ulLcg +)); + + +EXTERN S16 rgSCHCmnSpsUlCqiInd ARGS(( +RgSchCellCb *cell, +RgSchUeCb *ue +)); +EXTERN S16 rgSCHCmnSpsUlProcDtxInd ARGS(( +RgSchCellCb *cell, +RgSchUeCb *ue, +CmLteTimingInfo dtxTime +)); +EXTERN S16 rgSCHCmnSpsUlTti ARGS(( +RgSchCellCb *cell, +RgSchCmnUlRbAllocInfo *allocInfo +)); +#ifdef RG_UNUSED +EXTERN S16 rgSCHCmnSpsUlGetActvUeLst ARGS(( +RgSchCellCb *cell, +CmLteTimingInfo timingInfo, +CmLListCp *ulSpsActvUeLst +)); +#endif +EXTERN Void rgSCHCmnUlSpsRelInd ARGS(( +RgSchCellCb *cell, +RgSchUeCb *ue, +Bool isExplRel +)); + + +EXTERN Void rgSCHCmnUlSpsActInd ARGS(( +RgSchCellCb *cell, +RgSchUeCb *ue, +U16 spsSduSize +)); + +EXTERN Void rgSCHCmnUlCrcFailInd ARGS(( +RgSchCellCb *cell, +RgSchUeCb *ue, +CmLteTimingInfo crcTime +)); +EXTERN Void rgSCHCmnUlCrcInd ARGS(( +RgSchCellCb *cell, +RgSchUeCb *ue, +CmLteTimingInfo crcTime +)); + +/* Added handling to retrnasmit RelPDCCH in case no + feedback is received */ +EXTERN Void rgSCHCmnSpsDlReTxRelPdcch ARGS(( +RgSchCellCb *cell +)); +#endif + +EXTERN Void rgSCHCmnChkRetxAllowDtx +ARGS(( +RgSchCellCb *cell, +RgSchUeCb *ueCb, +RgSchDlHqProcCb *proc, +Bool *reTxAllwd +)); + +EXTERN S16 PtUiRgmBndCfm ARGS((Pst* pst, SuId suId, U8 status)); + +EXTERN S16 rgSCHCmnDlInitHqEnt +ARGS(( +RgSchCellCb *cell, +RgSchDlHqEnt *hqEnt +)); + +EXTERN PUBLIC Void rgSchCmnDlSfHqDel +ARGS(( +RgSchUeCb *ue, +RgSchCellCb *cell +)); + +EXTERN PUBLIC Void rgSCHCmnDlDeInitHqEnt +ARGS(( +RgSchCellCb *cell, +RgSchDlHqEnt *hqE +)); +EXTERN PUBLIC U8 rgSCHCmnUlGetCqi +ARGS (( +RgSchCellCb *cell, +RgSchUeCb *ue, +CmLteUeCategory ueCtgy +)); +#ifdef DL_LA +EXTERN S16 rgSCHDhmUpdBlerBasediTbsEff ARGS(( + RgSchCellCb *cell, + RgSchUeCb *ueCb, + U8 tbCnt + )); +#endif + +EXTERN Void rgSchCmnUpdCfiDb ARGS(( + RgSchCellCb *cell, + U8 delta + )); +EXTERN S16 RgUiRgmChangeTransModeInd ARGS(( + Pst *pst, + SuId suId, + RgmTransModeInd *transModeInd)); + +EXTERN Void rgSchCheckAndTriggerModeChange ARGS(( +RgSchCellCb *cell, +RgSchUeCb *ue, +U8 reportediTbs, +U8 previTbs, +U8 maxiTbs +)); +EXTERN Void rgSCHRrDlProcRmvFrmRetx ARGS(( +RgSchCellCb *cell, +RgSchDlHqProcCb *hqP +)); +EXTERN U8 rgSchUtlGetServCellIdx ARGS(( + Inst inst, + U16 cellId, + RgSchUeCb *ue + )); +EXTERN S16 rgSchUtlVldtCellId ARGS (( + Inst inst, + U16 cellId +)); +EXTERN Void rgSCHCmnInitUlRbAllocInfo ARGS(( +RgSchCmnUlRbAllocInfo *allocInfo +)); +EXTERN TfuDciFormat rgSCHCmnSlctPdcchFrmt ARGS(( +RgSchCellCb *cell, +RgSchUeCb *ue, +U8 *raType +)); + +EXTERN Void rgSCHCmnNonDlfsDedRbAlloc ARGS(( +RgSchCellCb *cell, +RgSchCmnUeRbAlloc *allocInfo, +CmLListCp *ueLst, +CmLListCp *schdUeLst, +CmLListCp *nonSchdUeLst +)); + +EXTERN Bool rgSCHCmnRetxAvoidTdd ARGS +(( +RgSchDlSf *curSf, +RgSchCellCb *cell, +RgSchDlHqProcCb *proc +)); + + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* __RGSCHCMNX__ */ + + +/********************************************************************** + End of file +**********************************************************************/ diff --git a/src/5gnrmac/rg_sch_dbm.c b/src/5gnrmac/rg_sch_dbm.c new file mode 100755 index 000000000..156638d7a --- /dev/null +++ b/src/5gnrmac/rg_sch_dbm.c @@ -0,0 +1,1994 @@ +/******************************************************************************* +################################################################################ +# Copyright (c) [2017-2019] [Radisys] # +# # +# 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. # +################################################################################ +*******************************************************************************/ + +/************************************************************************ + + Name: LTE-MAC layer + + Type: C source file + + Desc: C source code for Entry point fucntions + + File: rg_sch_dbm.c + +**********************************************************************/ + +/** @file rg_sch_dbm.c +@brief This file contains the APIs exposed for the database handling of the scheduler. +*/ +static const char* RLOG_MODULE_NAME="MAC"; +static int RLOG_FILE_ID=230; +static int RLOG_MODULE_ID=4096; +/* header include files -- defines (.h) */ +#include "envopt.h" /* environment options */ +#include "envdep.h" /* environment dependent */ +#include "envind.h" /* environment independent */ +#include "gen.h" /* general layer */ +#include "ssi.h" /* system service interface */ +#include "cm_hash.h" /* common hash list */ +#include "cm_mblk.h" /* common memory link list library */ +#include "cm_llist.h" /* common linked list library */ +#include "cm_err.h" /* common error */ +#include "cm_lte.h" /* common LTE */ +#include "lrg.h" +#include "rgr.h" +#include "tfu.h" +#include "rg_env.h" +#include "rg_sch_err.h" +#include "rg_sch_inf.h" +#include "rg_sch.h" +#include "rg_sch_cmn.h" + +/* header/extern include files (.x) */ +#include "gen.x" /* general layer */ +#include "ssi.x" /* system service interface */ +#include "cm5.x" /* common timers */ +#include "cm_lib.x" /* common library */ +#include "cm_hash.x" /* common hash list */ +#include "cm_mblk.x" /* common memory link list library */ +#include "cm_llist.x" /* common linked list library */ +#include "cm_tkns.x" /* common tokens */ +#include "cm_lte.x" /* common LTE */ +#include "lrg.x" +#include "rgr.x" +#include "tfu.x" +#include "rgm.x" /* layer management typedefs for MAC */ +#include "rg_sch_inf.x" +#include "rg_sch.x" +#include "rg_sch_cmn.x" +#include "rl_interface.h" +#include "rl_common.h" + + +/* local defines */ +PRIVATE S16 rgSCHDbmInitUeCbLst ARGS(( RgSchCellCb *cellCb, U16 numBins)); +#ifdef LTE_TDD +PRIVATE S16 rgSCHDbmInitUeTfuPendLst ARGS(( RgSchCellCb *cellCb, U16 numBins)); +#endif +PRIVATE Void rgSCHDbmInitDedLcLst ARGS((RgSchUeCb *ueCb)); +PRIVATE Void rgSCHDbmInitCmnLcLst ARGS((RgSchCellCb *cellCb)); +#ifdef LTEMAC_SPS +PRIVATE S16 rgSCHDbmInitSpsUeCbLst ARGS((RgSchCellCb *cellCb, + U16 numBins)); +#endif +PRIVATE Void rgSCHDbmInitRaCbLst ARGS(( RgSchCellCb *cellCb)); +#ifndef LTE_TDD +PRIVATE Void rgSCHDbmInitRaReqLst ARGS(( RgSchCellCb *cellCb)); +#endif +PRIVATE Void rgSCHDbmInitCrntRgrCfgLst ARGS(( RgSchCellCb *cellCb)); +PRIVATE Void rgSCHDbmInitPndngRgrCfgLst ARGS(( RgSchCellCb *cellCb)); + +#ifdef EMTC_ENABLE +PUBLIC S16 rgSCHDbmPutEmtcRnti ARGS((RgSchCellCb *cellCb,RgSchRntiLnk *rntiLnk)); +#endif + +/* local typedefs */ + +/* local externs */ + +/* forward references */ + +/** + * @brief Handler for Initializing the cell. + * + * @details + * + * Function : rgSCHDbmInitCell + * + * Initializes the lists belonging to the cell. + * + * + * @param[in] RgSchCellCb *cellCb + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 rgSCHDbmInitCell +( +RgSchCellCb *cellCb +) +#else +PUBLIC S16 rgSCHDbmInitCell(cellCb) +RgSchCellCb *cellCb; +#endif +{ + S16 ret; + + TRC2(rgSCHDbmInitCell); + + /* Initialize ue list */ + if ((ret = rgSCHDbmInitUeCbLst(cellCb, RGSCH_MAX_UE_BIN_PER_CELL)) != ROK) + RETVALUE(ret); +#ifdef LTE_TDD + if ((ret = rgSCHDbmInitUeTfuPendLst(cellCb, + RGSCH_MAX_UE_BIN_PER_CELL)) != ROK) + RETVALUE(ret); +#endif + +#ifdef LTEMAC_SPS + /* Initialize SPS Ue list */ + if ((ret = rgSCHDbmInitSpsUeCbLst(cellCb, RGSCH_MAX_UE_BIN_PER_CELL)) != ROK) + RETVALUE(ret); +#endif /* LTEMAC_SPS */ + + /* Initialize BCCH/PCCH logical channels */ + rgSCHDbmInitCmnLcLst(cellCb); + + /* Initialize configuration lists */ + rgSCHDbmInitCrntRgrCfgLst(cellCb); + rgSCHDbmInitPndngRgrCfgLst(cellCb); + +#ifndef LTE_TDD + /* Initialize raReq list */ + rgSCHDbmInitRaReqLst(cellCb); +#endif + + /* Initialize raCb list */ + rgSCHDbmInitRaCbLst(cellCb); + + /* Initialize l2mList */ +#ifdef LTE_L2_MEAS + cmLListInit(&cellCb->l2mList); +#endif /* LTE_L2_MEAS */ + + RETVALUE(ret); + +} /* rgSCHDbmInitCell */ + +/** + * @brief Handler for initializing the ueCbLst under the cellCb. + * + * @details + * + * Function : rgSCHDbmInitUeCbLst + * + * + * @param[in] *cellCb + * @param[in] numBins + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PRIVATE S16 rgSCHDbmInitUeCbLst +( +RgSchCellCb *cellCb, +U16 numBins +) +#else +PRIVATE S16 rgSCHDbmInitUeCbLst(cellCb, numBins) +RgSchCellCb *cellCb; +U16 numBins; +#endif +{ + RgSchUeCellInfo ueCellInfo; + TRC2(rgSCHDbmInitUeCbLst) + + /* Fix: syed It is better to compute offset dynamically + * rather than hardcoding it as 0 */ + RETVALUE(cmHashListInit(&cellCb->ueLst, numBins, (U16)((PTR)&(ueCellInfo.ueLstEnt) - (PTR)&ueCellInfo), FALSE, + CM_HASH_KEYTYPE_CONID, + rgSchCb[cellCb->instIdx].rgSchInit.region, + rgSchCb[cellCb->instIdx].rgSchInit.pool)); + +} /* rgSCHDbmInitUeCbLst */ + +/** + * @brief Handler for de-initializing the ueCbLst under the cellCb. + * + * @details + * + * Function : rgSCHDbmDeInitUeCbLst + * + * + * @param[in] *cellCb + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 rgSCHDbmDeInitUeCbLst +( +RgSchCellCb *cellCb +) +#else +PUBLIC S16 rgSCHDbmDeInitUeCbLst(cellCb) +RgSchCellCb *cellCb; +#endif +{ + TRC2(rgSCHDbmDeInitUeCbLst) + + RETVALUE(cmHashListDeinit(&cellCb->ueLst)); + +} /* rgSCHDbmDeInitUeCbLst */ + +#ifdef LTEMAC_SPS +/** + * @brief Handler for initializing the spsUeCbLst under the cellCb. + * + * @details + * + * Function : rgSCHDbmInitSpsUeCbLst + * + * + * @param[in] *cellCb + * @param[in] numBins + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PRIVATE S16 rgSCHDbmInitSpsUeCbLst +( +RgSchCellCb *cellCb, +U16 numBins +) +#else +PRIVATE S16 rgSCHDbmInitSpsUeCbLst(cellCb, numBins) +RgSchCellCb *cellCb; +U16 numBins; +#endif +{ + RgSchUeCb ue; + TRC2(rgSCHDbmInitSpsUeCbLst) + + RETVALUE(cmHashListInit(&cellCb->spsUeLst, numBins, (U16) ((PTR) &(ue.spsUeLstEnt) - (PTR) &ue), FALSE, + CM_HASH_KEYTYPE_CONID, + rgSchCb[cellCb->instIdx].rgSchInit.region, + rgSchCb[cellCb->instIdx].rgSchInit.pool)); + +} /* rgSCHDbmInitSpsUeCbLst */ + +/** + * @brief Handler for de-initializing the spsUeCbLst under the cellCb. + * + * @details + * + * Function : rgSCHDbmDeInitSpsUeCbLst + * + * + * @param[in] *cellCb + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 rgSCHDbmDeInitSpsUeCbLst +( +RgSchCellCb *cellCb +) +#else +PUBLIC S16 rgSCHDbmDeInitSpsUeCbLst(cellCb) +RgSchCellCb *cellCb; +#endif +{ + TRC2(rgSCHDbmDeInitSpsUeCbLst) + + RETVALUE(cmHashListDeinit(&cellCb->spsUeLst)); + +} /* rgSCHDbmDeInitSpsUeCbLst */ + +#endif /* LTEMAC_SPS */ + +/** + * @brief Handler for inserting the ueCb in to the ueCbLst under the cellCb. + * + * @details + * + * Function : rgSCHDbmInsUeCb + * + * + * @param[in] *cellCb + * @param[in] *ueCb + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 rgSCHDbmInsUeCb +( +RgSchCellCb *cellCb, +RgSchUeCb *ueCb +) +#else +PUBLIC S16 rgSCHDbmInsUeCb(cellCb, ueCb) +RgSchCellCb *cellCb; +RgSchUeCb *ueCb; +#endif +{ + RgSchUeCellInfo *ueCellInfo = NULLP; + TRC2(rgSCHDbmInsUeCb) + + ueCellInfo = ueCb->cellInfo[ueCb->cellIdToCellIdxMap[RG_SCH_CELLINDEX(cellCb)]]; + + RETVALUE(cmHashListInsert(&cellCb->ueLst, (PTR)ueCellInfo, + (U8 *)&ueCb->ueId, (U16)sizeof(ueCb->ueId))); + +} /* rgSCHDbmInsUeCb */ + +#ifdef LTEMAC_SPS +/** + * @brief Handler for inserting the ueCb in to the spsUeCbLst under the cellCb. + * + * @details + * + * Function : rgSCHDbmInsSpsUeCb + * + * + * @param[in] *cellCb + * @param[in] *ueCb + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 rgSCHDbmInsSpsUeCb +( +RgSchCellCb *cellCb, +RgSchUeCb *ueCb +) +#else +PUBLIC S16 rgSCHDbmInsSpsUeCb(cellCb, ueCb) +RgSchCellCb *cellCb; +RgSchUeCb *ueCb; +#endif +{ + TRC2(rgSCHDbmInsSpsUeCb) + + RETVALUE(cmHashListInsert(&cellCb->spsUeLst, (PTR)ueCb, + (U8 *)&ueCb->spsRnti, (U16)sizeof(ueCb->spsRnti))); + +} /* end of rgSCHDbmInsSpsUeCb */ + +#endif /* LTEMAC_SPS */ + +/** + * @brief Handler for accessing the existing ueCb identified by the key ueId + * in the ueCbLst under the cellCb. + * + * @details + * + * Function : rgSCHDbmGetUeCb + * + * + * @param[in] *cellCb + * @param[in] ueId + * @return RgSchUeCb* + **/ +#ifdef ANSI +PUBLIC RgSchUeCb* rgSCHDbmGetUeCb +( +RgSchCellCb *cellCb, +CmLteRnti ueId +) +#else +PUBLIC RgSchUeCb* rgSCHDbmGetUeCb(cellCb, ueId) +RgSchCellCb *cellCb; +CmLteRnti ueId; +#endif +{ + RgSchUeCellInfo *ueCellInfo = NULLP; + + TRC2(rgSCHDbmGetUeCb) + + cmHashListFind(&cellCb->ueLst, (U8 *)&ueId, + sizeof(ueId), 0, (PTR *)&ueCellInfo); + + RETVALUE(!ueCellInfo?NULLP:ueCellInfo->ue); +} /* rgSCHDbmGetUeCb */ + +#ifdef LTEMAC_SPS +/** + * @brief Handler for accessing the existing ueCb identified by the key + * spsRnti in the spsUeCbLst under the cellCb. + * + * @details + * + * Function : rgSCHDbmGetSpsUeCb + * + * + * @param[in] *cellCb + * @param[in] ueId + * @return RgSchUeCb* + **/ +#ifdef ANSI +PUBLIC RgSchUeCb* rgSCHDbmGetSpsUeCb +( +RgSchCellCb *cellCb, +CmLteRnti spsRnti +) +#else +PUBLIC RgSchUeCb* rgSCHDbmGetSpsUeCb(cellCb, spsRnti) +RgSchCellCb *cellCb; +CmLteRnti spsRnti; +#endif +{ + RgSchUeCb *ueCb = NULLP; + + TRC2(rgSCHDbmGetSpsUeCb) + + cmHashListFind(&cellCb->spsUeLst, (U8 *)&spsRnti, + sizeof(spsRnti), 0, (PTR *)&ueCb); + RETVALUE(ueCb); +} /* rgSCHDbmGetSpsUeCb */ +#endif + +/** + * @brief Handler for accessing the existing next ueCb in the ueCbLst under the + * cellCb. + * + * @details + * + * Function : rgSCHDbmGetNextUeCb + * + * + * @param[in] *cellCb + * @param[in] *ueCb + * @return RgSchUeCb* + **/ +#ifdef ANSI +PUBLIC RgSchUeCb* rgSCHDbmGetNextUeCb +( +RgSchCellCb *cellCb, +RgSchUeCb *ueCb +) +#else +PUBLIC RgSchUeCb* rgSCHDbmGetNextUeCb(cellCb, ueCb) +RgSchCellCb *cellCb; +RgSchUeCb *ueCb; +#endif +{ + RgSchUeCellInfo *ueCellInfo = NULLP; + RgSchUeCellInfo *nextUeCellInfo = NULLP; + + TRC2(rgSCHDbmGetNextUeCb) + + if (ueCb) + { + ueCellInfo = ueCb->cellInfo[ + ueCb->cellIdToCellIdxMap[RG_SCH_CELLINDEX(cellCb)]]; + } + + cmHashListGetNext(&cellCb->ueLst, (PTR) ueCellInfo, (PTR *)&nextUeCellInfo); + RETVALUE(!nextUeCellInfo?NULLP:nextUeCellInfo->ue); +} /* rgSCHDbmGetNextUeCb */ + +#ifdef LTEMAC_SPS +/** + * @brief Handler for accessing the existing next ueCb stored in the spsUeCbLst + * using SPS-Rnti under the cellCb. + * + * @details + * + * Function : rgSCHDbmGetNextSpsUeCb + * + * + * @param[in] *cellCb + * @param[in] *ueCb + * @return RgSchUeCb* + **/ +#ifdef ANSI +PUBLIC RgSchUeCb* rgSCHDbmGetNextSpsUeCb +( +RgSchCellCb *cellCb, +RgSchUeCb *ueCb +) +#else +PUBLIC RgSchUeCb* rgSCHDbmGetNextSpsUeCb(cellCb, ueCb) +RgSchCellCb *cellCb; +RgSchUeCb *ueCb; +#endif +{ + RgSchUeCb *nextUeCb = NULLP; + + TRC2(rgSCHDbmGetNextSpsUeCb) + + cmHashListGetNext(&cellCb->spsUeLst, (PTR) ueCb, (PTR *)&nextUeCb); + RETVALUE(nextUeCb); +} /* end of rgSCHDbmGetNextSpsUeCb */ + +#endif /* LTEMAC_SPS */ + +#ifdef LTE_L2_MEAS +/** + * @brief Handler for Cleaning up L2 Meas related Data in + * cellCb. + * + * @details + * + * Function : rgSCHDbmDelL2MUe + * + * + * @param[in] *cellCb + * @param[in] *ueCb + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 rgSCHDbmDelL2MUe +( +RgSchCellCb *cellCb, +RgSchUeCb *ueCb +) +#else +PUBLIC S16 rgSCHDbmDelL2MUe(cellCb, ueCb) +RgSchCellCb *cellCb; +RgSchUeCb *ueCb; +#endif +{ + U8 lcCnt = 0; + RgSchCmnUlUe *ueUl = RG_SCH_CMN_GET_UL_UE(ueCb, cellCb); + + TRC2(rgSCHDbmDelL2MUe) + + ueUl->hqEnt.numBusyHqProcs = 0; + /* Clean cell level UE Active Count */ + for (lcCnt =0; lcCnt < RGSCH_MAX_LC_PER_UE; lcCnt++) + { + if (ueCb->ul.lcCb[lcCnt].isValid) + { + if((ueCb->ul.lcCb[lcCnt].qciCb->ulUeCount) && + (ueCb->ulActiveLCs & + (1 << (ueCb->ul.lcCb[lcCnt].qciCb->qci -1)))) + { + ueCb->ul.lcCb[lcCnt].qciCb->ulUeCount--; + ueCb->ulActiveLCs &= ~(1 << + (ueCb->ul.lcCb[lcCnt].qciCb->qci -1)); + } + } + + if (ueCb->dl.lcCb[lcCnt]) + { + if (ueCb->qciActiveLCs[ueCb->dl.lcCb[lcCnt]->qciCb->qci]) + { + ueCb->dl.lcCb[lcCnt]->qciCb->dlUeCount--; + ueCb->qciActiveLCs[ueCb->dl.lcCb[lcCnt]->qciCb->qci] = 0; + } + } + } + + RETVALUE(ROK); +} /* rgSCHDbmDelL2MUe */ + +#endif + +/** + * @brief Handler for deleting the existing ueCb from the ueCbLst under the + * cellCb. + * + * @details + * + * Function : rgSCHDbmDelUeCb + * + * + * @param[in] *cellCb + * @param[in] *ueCb + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 rgSCHDbmDelUeCb +( +RgSchCellCb *cellCb, +RgSchUeCb *ueCb +) +#else +PUBLIC S16 rgSCHDbmDelUeCb(cellCb, ueCb) +RgSchCellCb *cellCb; +RgSchUeCb *ueCb; +#endif +{ + RgSchUeCellInfo *ueCellInfo = NULLP; + TRC2(rgSCHDbmDelUeCb) + + ueCellInfo = ueCb->cellInfo[ueCb->cellIdToCellIdxMap[RG_SCH_CELLINDEX(cellCb)]]; + + RETVALUE(cmHashListDelete(&cellCb->ueLst, (PTR)ueCellInfo)); +} /* rgSCHDbmDelUeCb */ + +#ifdef LTEMAC_SPS +/** + * @brief Handler for deleting the existing ueCb from the spsUeCbLst under the + * cellCb. + * + * @details + * + * Function : rgSCHDbmDelSpsUeCb + * + * + * @param[in] *cellCb + * @param[in] *ueCb + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 rgSCHDbmDelSpsUeCb +( +RgSchCellCb *cellCb, +RgSchUeCb *ueCb +) +#else +PUBLIC S16 rgSCHDbmDelSpsUeCb(cellCb, ueCb) +RgSchCellCb *cellCb; +RgSchUeCb *ueCb; +#endif +{ + TRC2(rgSCHDbmDelSpsUeCb) + + RETVALUE(cmHashListDelete(&cellCb->spsUeLst, (PTR)ueCb)); +} /* end of rgSCHDbmDelSpsUeCb */ + +#endif /* LTEMAC_SPS */ + +/** + * @brief Handler for Initializing the UE. + * + * @details + * + * Function : rgSCHDbmInitUe + * + * Initializes the lists belonging to the UE. + * + * + * @param[in] RgSchUeCb *ueCb + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 rgSCHDbmInitUe +( +RgSchUeCb *ueCb +) +#else +PUBLIC S16 rgSCHDbmInitUe(ueCb) +RgSchUeCb *ueCb; +#endif +{ + S16 ret = ROK; + + TRC2(rgSCHDbmInitUe); + + /* Initialize Dedicated logical channels */ + rgSCHDbmInitDedLcLst(ueCb); + + RETVALUE(ret); +} /* rgSCHDbmInitUe */ + +/** + * @brief Handler for Initializing the dedicated logical channels. + * + * @details + * + * Function : rgSCHDbmInitDedLcLst + * + * Initializes dedicated logical channels. + * + * @param[in] RgSchUeCb *ueCb + * @return Void + **/ +#ifdef ANSI +PRIVATE Void rgSCHDbmInitDedLcLst +( +RgSchUeCb *ueCb +) +#else +PRIVATE Void rgSCHDbmInitDedLcLst(ueCb) +RgSchUeCb *ueCb; +#endif +{ + U8 idx; + + TRC2(rgSCHDbmInitDedLcLst); + + for (idx = 0; idx < RGSCH_MAX_LC_PER_UE; ++idx) + { + /* Set Dedicated LCs as not configured */ + ueCb->ul.lcCb[idx].isValid = FALSE; + ueCb->dl.lcCb[idx] = NULLP; + } + + /* Stack Crash problems for TRACE5 Changes. Added the return below */ + RETVOID; + + +} /* rgSCHDbmInitDedLcLst */ + +/** + * @brief Handler for Initializing the common logical channel list of the cell. + * + * @details + * + * Function : rgSCHDbmInitCmnLcLst + * + * Initializes following common logical channels belonging to the cell. + * - BCCH on BCH + * - BCCH on DLSCH + * - PCCH + * + * @param[in] RgSchCellCb *cellCb + * @return Void + **/ +#ifdef ANSI +PRIVATE Void rgSCHDbmInitCmnLcLst +( +RgSchCellCb *cellCb +) +#else +PRIVATE Void rgSCHDbmInitCmnLcLst(cellCb) +RgSchCellCb *cellCb; +#endif +{ + U8 idx; + + TRC2(rgSCHDbmInitCmnLcLst); + + for (idx = 0; idx < RGSCH_MAX_CMN_LC_CB; idx++) + { + cellCb->cmnLcCb[idx].lcId = RGSCH_INVALID_LC_ID; + } + + /* Stack Crash problems for TRACE5 Changes. Added the return below */ + RETVOID; + +} /* rgSCHDbmInitCmnLcLst */ + +/** + * @brief Handler for inserting dedicated DL logical channel. + * + * @details + * + * Function : rgSCHDbmInsDlDedLcCb + * + * @param[in] RgSchUeCb *ueCb + * @param[in] RgSchDlLcCb* dlLcCb + * @return Void + **/ +#ifdef ANSI +PUBLIC Void rgSCHDbmInsDlDedLcCb +( +RgSchUeCb *ueCb, +RgSchDlLcCb *dlLcCb +) +#else +PUBLIC Void rgSCHDbmInsDlDedLcCb(ueCb, dlLcCb) +RgSchUeCb *ueCb; +RgSchDlLcCb *dlLcCb; +#endif +{ + TRC2(rgSCHDbmInsDlDedLcCb); + + ueCb->dl.lcCb[dlLcCb->lcId - 1] = dlLcCb; + +} /* rgSCHDbmInsDlDedLcCb */ + +/** + * @brief Handler for deleting dedicated DL logical channel. + * + * @details + * + * Function : rgSCHDbmDelDlDedLcCb + * + * @param[in] RgSchUeCb *ueCb + * @param[in] RgSchDlLcCb* dlLcCb + * @return Void + **/ +#ifdef ANSI +PUBLIC Void rgSCHDbmDelDlDedLcCb +( +RgSchUeCb *ueCb, +RgSchDlLcCb *dlLcCb +) +#else +PUBLIC Void rgSCHDbmDelDlDedLcCb(ueCb, dlLcCb) +RgSchUeCb *ueCb; +RgSchDlLcCb *dlLcCb; +#endif +{ + TRC2(rgSCHDbmDelDlDedLcCb); + +#ifdef LTE_L2_MEAS + /* Clean cell level UE Active Count */ + + if (ueCb->dl.lcCb[dlLcCb->lcId - 1]) + { + if ((dlLcCb->qciCb) + && (ueCb->qciActiveLCs[dlLcCb->qciCb->qci])) + { + ueCb->qciActiveLCs[dlLcCb->qciCb->qci]--; + if (!(ueCb->qciActiveLCs[dlLcCb->qciCb->qci])) + { + dlLcCb->qciCb->dlUeCount--; + } + } + } +#endif /* LTE_L2_MEAS */ + + ueCb->dl.lcCb[dlLcCb->lcId - 1] = NULLP; + + /* Stack Crash problems for TRACE5 Changes. Added the return below */ + RETVOID; + +} /* rgSCHDbmDelDlDedLcCb */ + +/** + * @brief Handler for accessing the existing dl dedicated lcCb at idx in the + * lcCbLst of the ueCb. + * + * @details + * + * Function : rgSCHDbmGetDlDedLcCb + * + * @param[in] *ueCb + * @param[in] idx + * @return RgSchDlLcCb* + **/ +#ifdef ANSI +PUBLIC RgSchDlLcCb* rgSCHDbmGetDlDedLcCb +( +RgSchUeCb *ueCb, +CmLteLcId idx +) +#else +PUBLIC RgSchDlLcCb* rgSCHDbmGetDlDedLcCb(ueCb, idx) +RgSchUeCb *ueCb; +CmLteLcId idx; +#endif +{ + TRC2(rgSCHDbmGetDlDedLcCb); + + if (idx < RGSCH_DEDLC_MIN_LCID || idx > RGSCH_DEDLC_MAX_LCID) + { + RETVALUE(NULLP); + } + RETVALUE(ueCb->dl.lcCb[idx-1]); + +} /* rgSCHDbmGetDlDedLcCb */ + +/** + * @brief Handler for accessing the existing first dl dedicated lcCb at idx + * in the lcCbLst of the ueCb. + * + * @details + * + * Function : rgSCHDbmGetFirstDlDedLcCb + * + * + * @param[in] *ueCb + * @return RgSchDlLcCb* + **/ +#ifdef ANSI +PUBLIC RgSchDlLcCb* rgSCHDbmGetFirstDlDedLcCb +( +RgSchUeCb *ueCb +) +#else +PUBLIC RgSchDlLcCb* rgSCHDbmGetFirstDlDedLcCb(ueCb) +RgSchUeCb *ueCb; +#endif +{ + U8 idx; + TRC2(rgSCHDbmGetFirstDlDedLcCb) + + for(idx = 0; idx < RGSCH_DEDLC_MAX_LCID; idx++) + { + if(ueCb->dl.lcCb[idx]) + { + RETVALUE(ueCb->dl.lcCb[idx]); + } + } + RETVALUE(NULLP); +} /* rgSCHDbmGetFirstDlDedLcCb */ +/** + * @brief Handler for accessing the existing next dl dedicated lcCb at idx + * in the lcCbLst of the ueCb. + * + * @details + * + * Function : rgSCHDbmGetNextDlDedLcCb + * + * + * @param[in] *ueCb + * @param[in] *lcCb + * @return RgSchDlLcCb* + **/ +#ifdef ANSI +PUBLIC RgSchDlLcCb* rgSCHDbmGetNextDlDedLcCb +( +RgSchUeCb *ueCb, +RgSchDlLcCb *lcCb +) +#else +PUBLIC RgSchDlLcCb* rgSCHDbmGetNextDlDedLcCb(ueCb, lcCb) +RgSchUeCb *ueCb; +RgSchDlLcCb *lcCb; +#endif +{ + U8 idx; + TRC2(rgSCHDbmGetNextDlDedLcCb); + + if (!lcCb) + { + RETVALUE(rgSCHDbmGetFirstDlDedLcCb(ueCb)); + } + + for(idx = lcCb->lcId; idx < RGSCH_DEDLC_MAX_LCID; idx++) + { + if(ueCb->dl.lcCb[idx]) + { + RETVALUE(ueCb->dl.lcCb[idx]); + } + } + RETVALUE(NULLP); +} /* rgSCHDbmGetNextDlDedLcCb */ + +/** + * @brief Handler for accessing the existing dl common lcCb identified by the key lcId + * in the lcCbLst of the ueCb. + * + * @details + * + * Function : rgSCHDbmGetCmnLcCb + * + * + * @param[in] *cellCb + * @param[in] lcId + * @return RgSchClcDlLcCb* + **/ +#ifdef ANSI +PUBLIC RgSchClcDlLcCb* rgSCHDbmGetCmnLcCb +( +RgSchCellCb *cellCb, +CmLteLcId lcId +) +#else +PUBLIC RgSchClcDlLcCb* rgSCHDbmGetCmnLcCb(cellCb, lcId) +RgSchCellCb *cellCb; +CmLteLcId lcId; +#endif +{ + U8 idx; + + TRC2(rgSCHDbmGetCmnLcCb) + + for(idx = 0; idx < RGSCH_MAX_CMN_LC_CB; idx++) + { + if(cellCb->cmnLcCb[idx].lcId == lcId) + { + RETVALUE(&(cellCb->cmnLcCb[idx])); + } + } + RETVALUE(NULLP); +} /* rgSCHDbmGetCmnLcCb */ + +/** + * @brief Handler for accessing the existing BCCH mapped on to BCH in the + * lcCbLst of the ueCb. + * + * @details + * + * Function : rgSCHDbmGetBcchOnBch + * + * + * @param[in] *cellCb + * @return RgSchClcDlLcCb* + **/ +#ifdef ANSI +PUBLIC RgSchClcDlLcCb* rgSCHDbmGetBcchOnBch +( +RgSchCellCb *cellCb +) +#else +PUBLIC RgSchClcDlLcCb* rgSCHDbmGetBcchOnBch(cellCb) +RgSchCellCb *cellCb; +#endif +{ + TRC2(rgSCHDbmGetBcchOnBch) + + if(cellCb->cmnLcCb[RGSCH_BCCH_BCH_IDX].lcId != RGSCH_INVALID_LC_ID) + { + RETVALUE(&(cellCb->cmnLcCb[RGSCH_BCCH_BCH_IDX])); + } + RETVALUE(NULLP); +} /* rgSCHDbmGetBcchOnBch */ + +/** + * @brief Handler for accessing the existing BCCH mapped on to DLSCH in the + * lcCbLst of the ueCb. + * + * @details + * + * Function : rgSCHDbmGetFirstBcchOnDlsch + * + * + * @param[in] *cellCb + * @return RgSchClcDlLcCb* + **/ +#ifdef ANSI +PUBLIC RgSchClcDlLcCb* rgSCHDbmGetFirstBcchOnDlsch +( +RgSchCellCb *cellCb +) +#else +PUBLIC RgSchClcDlLcCb* rgSCHDbmGetFirstBcchOnDlsch(cellCb) +RgSchCellCb *cellCb; +#endif +{ + TRC2(rgSCHDbmGetFirstBcchOnDlsch) + + if(cellCb->cmnLcCb[RGSCH_BCCH_DLSCH_IDX1].lcId != RGSCH_INVALID_LC_ID) + { + RETVALUE(&(cellCb->cmnLcCb[RGSCH_BCCH_DLSCH_IDX1])); + } + RETVALUE(NULLP); +} /* rgSCHDbmGetFirstBcchOnDlsch */ + +/** + * @brief Handler for accessing the existing BCCH mapped on to DLSCH in the + * lcCbLst of the ueCb. + * + * @details + * + * Function : rgSCHDbmGetSecondBcchOnDlsch + * + * + * @param[in] *cellCb + * @return RgSchClcDlLcCb* + **/ +#ifdef ANSI +PUBLIC RgSchClcDlLcCb* rgSCHDbmGetSecondBcchOnDlsch +( +RgSchCellCb *cellCb +) +#else +PUBLIC RgSchClcDlLcCb* rgSCHDbmGetSecondBcchOnDlsch(cellCb) +RgSchCellCb *cellCb; +#endif +{ + TRC2(rgSCHDbmGetSecondBcchOnDlsch) + + if(cellCb->cmnLcCb[RGSCH_BCCH_DLSCH_IDX2].lcId != RGSCH_INVALID_LC_ID) + { + RETVALUE(&(cellCb->cmnLcCb[RGSCH_BCCH_DLSCH_IDX2])); + } + RETVALUE(NULLP); +} /* rgSCHDbmGetSecondBcchOnDlsch */ + +/** + * @brief Handler for accessing the existing PCCH in the lcCbLst of the ueCb. + * + * @details + * + * Function : rgSCHDbmGetPcch + * + * + * @param[in] *cellCb + * @return RgSchClcDlLcCb* + **/ +#ifdef ANSI +PUBLIC RgSchClcDlLcCb* rgSCHDbmGetPcch +( +RgSchCellCb *cellCb +) +#else +PUBLIC RgSchClcDlLcCb* rgSCHDbmGetPcch(cellCb) +RgSchCellCb *cellCb; +#endif +{ + TRC2(rgSCHDbmGetPcch) + + if(cellCb->cmnLcCb[RGSCH_PCCH_IDX].lcId != RGSCH_INVALID_LC_ID) + { + RETVALUE(&(cellCb->cmnLcCb[RGSCH_PCCH_IDX])); + } + RETVALUE(NULLP); +} /* rgSCHDbmGetPcch */ + +/** + * @brief Handler for inserting the BCCH mapped on to BCH in the + * lcCbLst of the ueCb. + * + * @details + * + * Function : rgSCHDbmInsBcchOnBch + * + * + * @param[in] *cellCb + * @return Void + **/ +#ifdef ANSI +PUBLIC Void rgSCHDbmInsBcchOnBch +( +RgSchCellCb *cellCb, +RgSchClcDlLcCb *cmnDlLcCb +) +#else +PUBLIC Void rgSCHDbmInsBcchOnBch(cellCb, cmnDlLcCb) +RgSchCellCb *cellCb; +RgSchClcDlLcCb *cmnDlLcCb; +#endif +{ + TRC2(rgSCHDbmInsBcchOnBch) + + cellCb->cmnLcCb[RGSCH_BCCH_BCH_IDX].lcId = cmnDlLcCb->lcId; + cellCb->cmnLcCb[RGSCH_BCCH_BCH_IDX].boLst = cmnDlLcCb->boLst; + + /* Stack Crash problems for TRACE5 Changes. Added the return below */ + RETVOID; + +} /* rgSCHDbmInsBcchOnBch */ + +/** + * @brief Handler for inserting the BCCH mapped on to DLSCH in the + * lcCbLst of the ueCb. + * + * @details + * + * Function : rgSCHDbmInsBcchOnDlsch + * + * + * @param[in] *cellCb + * @return Void + **/ +#ifdef ANSI +PUBLIC Void rgSCHDbmInsBcchOnDlsch +( +RgSchCellCb *cellCb, +RgSchClcDlLcCb *cmnDlLcCb +) +#else +PUBLIC Void rgSCHDbmInsBcchOnDlsch(cellCb, cmnDlLcCb) +RgSchCellCb *cellCb; +RgSchClcDlLcCb *cmnDlLcCb; +#endif +{ + TRC2(rgSCHDbmInsBcchOnDlsch) + + if(cellCb->cmnLcCb[RGSCH_BCCH_DLSCH_IDX1].lcId == RGSCH_INVALID_LC_ID) + { + cellCb->cmnLcCb[RGSCH_BCCH_DLSCH_IDX1].lcId = cmnDlLcCb->lcId; + cellCb->cmnLcCb[RGSCH_BCCH_DLSCH_IDX1].boLst = cmnDlLcCb->boLst; + cellCb->cmnLcCb[RGSCH_BCCH_DLSCH_IDX1].si = FALSE; + } + else if(cellCb->cmnLcCb[RGSCH_BCCH_DLSCH_IDX2].lcId == RGSCH_INVALID_LC_ID) + { + cellCb->cmnLcCb[RGSCH_BCCH_DLSCH_IDX2].lcId = cmnDlLcCb->lcId; + cellCb->cmnLcCb[RGSCH_BCCH_DLSCH_IDX2].boLst = cmnDlLcCb->boLst; + cellCb->cmnLcCb[RGSCH_BCCH_DLSCH_IDX2].si = TRUE; + } + + /* Stack Crash problems for TRACE5 Changes. Added the return below */ + RETVOID; + +} /* rgSCHDbmInsBcchOnDlsch */ + + +/** + * @brief Handler for inserting the PCCH in the lcCbLst of the ueCb. + * + * @details + * + * Function : rgSCHDbmInsPcch + * + * + * @param[in] *cellCb + * @return Void + **/ +#ifdef ANSI +PUBLIC Void rgSCHDbmInsPcch +( +RgSchCellCb *cellCb, +RgSchClcDlLcCb *cmnDlLcCb +) +#else +PUBLIC Void rgSCHDbmInsPcch(cellCb, cmnDlLcCb) +RgSchCellCb *cellCb; +RgSchClcDlLcCb *cmnDlLcCb; +#endif +{ + TRC2(rgSCHDbmInsPcch) + + cellCb->cmnLcCb[RGSCH_PCCH_IDX].lcId = cmnDlLcCb->lcId; + cellCb->cmnLcCb[RGSCH_PCCH_IDX].boLst = cmnDlLcCb->boLst; + + /* Stack Crash problems for TRACE5 Changes. Added the return below */ + RETVOID; + +} /* rgSCHDbmInsPcch */ + +/** + * @brief Handler for initializing the boLst. + * + * @details + * + * Function : rgSCHDbmInitCmnLcBoLst + * + * + * @param[in] *cmnDlLcCb + * @return Void + **/ +#ifdef ANSI +PUBLIC Void rgSCHDbmInitCmnLcBoLst +( +RgSchClcDlLcCb *cmnDlLcCb +) +#else +PUBLIC Void rgSCHDbmInitCmnLcBoLst(cmnDlLcCb) +RgSchClcDlLcCb *cmnDlLcCb; +#endif +{ + TRC2(rgSCHDbmInitCmnLcBoLst) + + cmLListInit(&cmnDlLcCb->boLst); + RETVOID; +} /* rgSCHDbmInitCmnLcBoLst */ + +/** + * @brief Handler for inserting the bo report in to the boLst. + * + * @details + * + * Function : rgSCHDbmInsCmnLcBoRpt + * + * + * @param[in] *cmnDlLcCb + * @param[in] *boRpt + * @return Void + **/ +#ifdef ANSI +PUBLIC Void rgSCHDbmInsCmnLcBoRpt +( +RgSchClcDlLcCb *cmnDlLcCb, +RgSchClcBoRpt *cmnBoRpt +) +#else +PUBLIC Void rgSCHDbmInsCmnLcBoRpt(cmnDlLcCb, cmnBoRpt) +RgSchClcDlLcCb *cmnDlLcCb; +RgSchClcBoRpt *cmnBoRpt; +#endif +{ + TRC2(rgSCHDbmInsCmnLcBoRpt) + + cmnBoRpt->boLstEnt.next = NULLP; + cmnBoRpt->boLstEnt.prev = NULLP; + cmnBoRpt->boLstEnt.node = (PTR)cmnBoRpt; + cmLListAdd2Tail(&cmnDlLcCb->boLst, &cmnBoRpt->boLstEnt); + RETVOID; +} /* rgSCHDbmInsCmnLcBoRpt */ + + +/** + * @brief Handler for initializing the raCbLst. + * + * @details + * + * Function : rgSCHDbmInitRaCbLst + * + * + * @param[in] *cellCb + * @return Void + **/ +#ifdef ANSI +PRIVATE Void rgSCHDbmInitRaCbLst +( +RgSchCellCb *cellCb +) +#else +PRIVATE Void rgSCHDbmInitRaCbLst(cellCb) +RgSchCellCb *cellCb; +#endif +{ + TRC2(rgSCHDbmInitRaCbLst) + + cmLListInit(&cellCb->raInfo.raCbLst); + RETVOID; +} /* rgSCHDbmInitRaCbLst */ + + +/** + * @brief Handler for accessing the existing raCb in the raCbLst. + * + * @details + * + * Function : rgSCHDbmGetRaCb + * + * + * @param[in] *cellCb + * @param[in] key + * @return RgSchRaCb* + **/ +#ifdef ANSI +PUBLIC RgSchRaCb* rgSCHDbmGetRaCb +( +RgSchCellCb *cellCb, +CmLteRnti key +) +#else +PUBLIC RgSchRaCb* rgSCHDbmGetRaCb(cellCb, key) +RgSchCellCb *cellCb; +CmLteRnti key; +#endif +{ + CmLList *tmpNode; + + TRC2(rgSCHDbmGetRaCb) + + CM_LLIST_FIRST_NODE(&cellCb->raInfo.raCbLst,tmpNode); + while(tmpNode) + { + if(((RgSchRaCb *)tmpNode->node)->tmpCrnti == key) + { + RETVALUE((RgSchRaCb *)(tmpNode->node)); + } + CM_LLIST_NEXT_NODE(&cellCb->raInfo.raCbLst,tmpNode); + } + RETVALUE(NULLP); +} /* rgSCHDbmGetRaCb */ + +#ifndef LTE_TDD +/** + * @brief Handler for initializing the raReqLst. + g + * @details + * + * Function : rgSCHDbmInitRaReqLst + * + * + * @param[in] *cellCb + * @return Void + **/ +#ifdef ANSI +PRIVATE Void rgSCHDbmInitRaReqLst +( +RgSchCellCb *cellCb +) +#else +PRIVATE Void rgSCHDbmInitRaReqLst(cellCb) +RgSchCellCb *cellCb; +#endif +{ + U8 idx; + + TRC2(rgSCHDbmInitRaReqLst) + + /* ccpu00133557- Memory Leak Fix- initializing for the all nodes + * in RAREQ list*/ + for(idx = 0; idx < RGSCH_RAREQ_ARRAY_SIZE; idx++) + { + cmLListInit(&cellCb->raInfo.raReqLst[idx]); + } + RETVOID; +} /* rgSCHDbmInitRaReqLst */ +#endif + +/** + * @brief Handler for initializing the crnt rgr cfgLst. + * + * @details + * + * Function : rgSCHDbmInitCrntRgrCfgLst + * + * + * @param[in] *cellCb + * @return Void + **/ +#ifdef ANSI +PRIVATE Void rgSCHDbmInitCrntRgrCfgLst +( +RgSchCellCb *cellCb +) +#else +PRIVATE Void rgSCHDbmInitCrntRgrCfgLst(cellCb) +RgSchCellCb *cellCb; +#endif +{ + TRC2(rgSCHDbmInitCrntRgrCfgLst) + + cmLListInit(&cellCb->rgCfgInfo.crntRgrCfgLst); + RETVOID; +} /* rgSCHDbmInitCrntRgrCfgLst */ + +/** + * @brief Handler for initializing the pndng rgr cfgLst. + * + * @details + * + * Function : rgSCHDbmInitPndngRgrCfgLst + * + * + * @param[in] *cellCb + * @return Void + **/ +#ifdef ANSI +PRIVATE Void rgSCHDbmInitPndngRgrCfgLst +( +RgSchCellCb *cellCb +) +#else +PRIVATE Void rgSCHDbmInitPndngRgrCfgLst(cellCb) +RgSchCellCb *cellCb; +#endif +{ + TRC2(rgSCHDbmInitPndngRgrCfgLst) + + cmLListInit(&cellCb->rgCfgInfo.pndngRgrCfgLst); + RETVOID; +} /* rgSCHDbmInitPndngRgrCfgLst */ + +/** + * @brief Handler for inserting the cfgElem in to the crntRgrCfgLst. + * + * @details + * + * Function : rgSCHDbmInsCrntRgrCfgElem + * + * + * @param[in] *cellCb + * @param[in] *cfgElem + * @return Void + **/ +#ifdef ANSI +PUBLIC Void rgSCHDbmInsCrntRgrCfgElem +( +RgSchCellCb *cellCb, +RgSchCfgElem *cfgElem +) +#else +PUBLIC Void rgSCHDbmInsCrntRgrCfgElem(cellCb, cfgElem) +RgSchCellCb *cellCb; +RgSchCfgElem *cfgElem; +#endif +{ + TRC2(rgSCHDbmInsCrntRgrCfgElem) + + cfgElem->cfgReqLstEnt.next = NULLP; + cfgElem->cfgReqLstEnt.prev = NULLP; + cmLListAdd2Tail(&cellCb->rgCfgInfo.crntRgrCfgLst, &cfgElem->cfgReqLstEnt); + RETVOID; +} /* rgSCHDbmInsCrntRgrCfgElem */ + +/** + * @brief Handler for inserting the cfgElem in to the pndngRgrCfgLst. + * + * @details + * + * Function : rgSCHDbmInsPndngRgrCfgElem + * + * + * @param[in] *cellCb + * @param[in] *cfgElem + * @return Void + **/ +#ifdef ANSI +PUBLIC Void rgSCHDbmInsPndngRgrCfgElem +( +RgSchCellCb *cellCb, +RgSchCfgElem *cfgElem +) +#else +PUBLIC Void rgSCHDbmInsPndngRgrCfgElem(cellCb, cfgElem) +RgSchCellCb *cellCb; +RgSchCfgElem *cfgElem; +#endif +{ + TRC2(rgSCHDbmInsPndngRgrCfgElem) + + cfgElem->cfgReqLstEnt.next = NULLP; + cfgElem->cfgReqLstEnt.prev = NULLP; + cfgElem->cfgReqLstEnt.node = (PTR)cfgElem; + cmLListAdd2Tail(&cellCb->rgCfgInfo.pndngRgrCfgLst, &cfgElem->cfgReqLstEnt); + RETVOID; +} /* rgSCHDbmInsPndngRgrCfgElem */ + +/** + * @brief Handler for accessing the existing cfgElem in the crntRgrCfgLst. + * + * @details + * + * Function : rgSCHDbmGetNextCrntRgrCfgElem + * + * + * @param[in] *cellCb + * @param[in] *cfgElem + * @return RgSchCfgElem* + **/ +#ifdef ANSI +PUBLIC RgSchCfgElem* rgSCHDbmGetNextCrntRgrCfgElem +( +RgSchCellCb *cellCb, +RgSchCfgElem *cfgElem +) +#else +PUBLIC RgSchCfgElem* rgSCHDbmGetNextCrntRgrCfgElem(cellCb, cfgElem) +RgSchCellCb *cellCb; +RgSchCfgElem *cfgElem; +#endif +{ + TRC2(rgSCHDbmGetNextCrntRgrCfgElem) + + if(!cfgElem) + { + RETVALUE( cellCb->rgCfgInfo.crntRgrCfgLst.first ? + (RgSchCfgElem *)(cellCb->rgCfgInfo.crntRgrCfgLst.first->node) : NULLP ); + } + RETVALUE( cfgElem->cfgReqLstEnt.next ? + (RgSchCfgElem *)(cfgElem->cfgReqLstEnt.next->node) : NULLP ); +} /* rgSCHDbmGetNextCrntRgrCfgElem */ + +/** + * @brief Handler for accessing the existing cfgElem in the pndngRgrCfgLst. + * + * @details + * + * Function : rgSCHDbmGetNextPndngRgrCfgElem + * + * + * @param[in] *cellCb + * @param[in] *cfgElem + * @return RgSchCfgElem* + **/ +#ifdef ANSI +PUBLIC RgSchCfgElem* rgSCHDbmGetNextPndngRgrCfgElem +( +RgSchCellCb *cellCb, +RgSchCfgElem *cfgElem +) +#else +PUBLIC RgSchCfgElem* rgSCHDbmGetNextPndngRgrCfgElem(cellCb, cfgElem) +RgSchCellCb *cellCb; +RgSchCfgElem *cfgElem; +#endif +{ + TRC2(rgSCHDbmGetNextPndngRgrCfgElem) + + if(!cfgElem) + { + RETVALUE( cellCb->rgCfgInfo.pndngRgrCfgLst.first ? + (RgSchCfgElem *)(cellCb->rgCfgInfo.pndngRgrCfgLst.first->node) : NULLP ); + } + RETVALUE( cfgElem->cfgReqLstEnt.next ? + (RgSchCfgElem *)(cfgElem->cfgReqLstEnt.next->node) : NULLP ); +} /* rgSCHDbmGetNextPndngRgrCfgElem */ + +/** + * @brief Handler for extracting the existing cfgElem from the pndngRgrCfgLst. + * + * @details + * + * Function : rgSCHDbmGetPndngRgrCfgElemByKey + * + * + * @param[in] *cellCb + * @param[in] key + * @return RgSchCfgElem* + **/ +#ifdef ANSI +PUBLIC RgSchCfgElem* rgSCHDbmGetPndngRgrCfgElemByKey +( +RgSchCellCb *cellCb, +CmLteTimingInfo key +) +#else +PUBLIC RgSchCfgElem* rgSCHDbmGetPndngRgrCfgElemByKey(cellCb, key) +RgSchCellCb *cellCb; +CmLteTimingInfo key; +#endif +{ + CmLList *tmpNode; + + TRC2(rgSCHDbmGetPndngRgrCfgElemByKey) + + CM_LLIST_FIRST_NODE(&cellCb->rgCfgInfo.pndngRgrCfgLst,tmpNode); + while(tmpNode) + { + if((((RgSchCfgElem *)tmpNode->node)->actvTime.sfn == key.sfn) && + (((RgSchCfgElem *)tmpNode->node)->actvTime.subframe == key.subframe)) + { + RETVALUE((RgSchCfgElem *)(tmpNode->node)); + } + CM_LLIST_NEXT_NODE(&cellCb->rgCfgInfo.pndngRgrCfgLst,tmpNode); + } + RETVALUE(NULLP); +} /* rgSCHDbmGetPndngRgrCfgElemByKey */ + +/** + * @brief Handler for deleting the existing cfgElem from the crntRgrCfgLst. + * + * @details + * + * Function : rgSCHDbmDelCrntRgrCfgElem + * + * + * @param[in] *cellCb + * @param[in] *cfgElem + * @return RgSchCfgElem* + **/ +#ifdef ANSI +PUBLIC RgSchCfgElem* rgSCHDbmDelCrntRgrCfgElem +( +RgSchCellCb *cellCb, +RgSchCfgElem *cfgElem +) +#else +PUBLIC RgSchCfgElem* rgSCHDbmDelCrntRgrCfgElem(cellCb, cfgElem) +RgSchCellCb *cellCb; +RgSchCfgElem *cfgElem; +#endif +{ + TRC2(rgSCHDbmDelCrntRgrCfgElem) + + if(cmLListDelFrm(&cellCb->rgCfgInfo.crntRgrCfgLst,&cfgElem->cfgReqLstEnt)) + { + RETVALUE((RgSchCfgElem *)(cfgElem->cfgReqLstEnt.node)); + } + RETVALUE(NULLP); +} /* rgSCHDbmDelCrntRgrCfgElem */ + +/** + * @brief Handler for deleting the existing cfgElem from the pndngRgrCfgLst. + * + * @details + * + * Function : rgSCHDbmDelPndngRgrCfgElem + * + * + * @param[in] *cellCb + * @param[in] *cfgElem + * @return RgSchCfgElem* + **/ +#ifdef ANSI +PUBLIC RgSchCfgElem* rgSCHDbmDelPndngRgrCfgElem +( +RgSchCellCb *cellCb, +RgSchCfgElem *cfgElem +) +#else +PUBLIC RgSchCfgElem* rgSCHDbmDelPndngRgrCfgElem(cellCb, cfgElem) +RgSchCellCb *cellCb; +RgSchCfgElem *cfgElem; +#endif +{ + TRC2(rgSCHDbmDelPndngRgrCfgElem) + + if(cmLListDelFrm(&cellCb->rgCfgInfo.pndngRgrCfgLst,&cfgElem->cfgReqLstEnt)) + { + RETVALUE((RgSchCfgElem *)(cfgElem->cfgReqLstEnt.node)); + } + RETVALUE(NULLP); +} /* rgSCHDbmDelPndngRgrCfgElem */ + +/** + * @brief Handler for initializing the rntiDb. + * + * @details + * + * Function : rgSCHDbmRntiDbInit + * + * + * @param[in] *cellCb + * @param[in] rntiStart + * @param[in] maxRntis + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 rgSCHDbmRntiDbInit +( +RgSchCellCb *cellCb, +U16 rntiStart, +U16 maxRntis +) +#else +PUBLIC S16 rgSCHDbmRntiDbInit(cellCb, rntiStart, maxRntis) +RgSchCellCb *cellCb; +U16 rntiStart; +U16 maxRntis; +#endif +{ + U16 rnti; + RgSchRntiLnk *rntiPool; + + TRC2(rgSCHDbmRntiDbInit) + + /* Fix for Change Request ccpu00099150 */ + if(rgSCHUtlAllocSBuf(cellCb->instIdx, + (Data **)&cellCb->rntiDb.rntiPool,maxRntis*sizeof(RgSchRntiLnk)) != ROK) + { + RETVALUE(RFAILED); + } + cellCb->rntiDb.rntiStart = rntiStart; + cellCb->rntiDb.maxRntis = maxRntis; + + cellCb->rntiDb.count = maxRntis; + + rnti = rntiStart; + rntiPool = cellCb->rntiDb.rntiPool; + if (maxRntis == 1) + { + rntiPool[0].rnti = rnti; + rntiPool[0].prv = NULLP; + rntiPool[0].nxt = NULLP; + cellCb->rntiDb.lastRnti = &rntiPool[0]; + } + else + { + U16 idx; + rntiPool[0].rnti = rnti++; + rntiPool[0].prv = NULLP; + rntiPool[0].nxt = &rntiPool[1]; + for (idx = 1; idx < maxRntis - 1; ++idx) + { + rntiPool[idx].rnti = rnti++; + rntiPool[idx].prv = &rntiPool[idx-1]; + rntiPool[idx].nxt = &rntiPool[idx+1]; + } + rntiPool[idx].rnti = rnti++; + rntiPool[idx].prv = &rntiPool[idx-1]; + rntiPool[idx].nxt = NULLP; + cellCb->rntiDb.lastRnti = &rntiPool[idx]; + } + cellCb->rntiDb.freeRnti = &rntiPool[0]; + RETVALUE(ROK); +} /* rgSCHDbmRntiDbInit */ + +/** + * @brief Handler for de-initializing the rntiDb. + * + * @details + * + * Function : rgSCHDbmRntiDbDeInit + * + * + * @param[in] *cellCb + * @return Void + **/ +#ifdef ANSI +PUBLIC Void rgSCHDbmRntiDbDeInit +( +RgSchCellCb *cellCb +) +#else +PUBLIC Void rgSCHDbmRntiDbDeInit(cellCb) +RgSchCellCb *cellCb; +#endif +{ + TRC2(rgSCHDbmRntiDbDeInit) + + /* ccpu00117052 - MOD - Passing double pointer + for proper NULLP assignment*/ + rgSCHUtlFreeSBuf(cellCb->instIdx, (Data **)(&(cellCb->rntiDb.rntiPool)), + cellCb->rntiDb.maxRntis*sizeof(RgSchRntiLnk)); + cellCb->rntiDb.maxRntis = 0; + cellCb->rntiDb.freeRnti = NULLP; + cellCb->rntiDb.lastRnti = NULLP; + cmLListInit(&cellCb->rntiDb.rntiGuardPool); + + /* Stack Crash problems for TRACE5 Changes. Added the return below */ + RETVOID; + +} /* rgSCHDbmRntiDbDeInit */ + +/** + * @brief Handler for accessing the free RNTI. + * + * @details + * + * Function : rgSCHDbmGetRnti + * + * + * @param[in] *cellCb + * @return RgSchRntiLnk* + **/ +#ifdef ANSI +PUBLIC RgSchRntiLnk* rgSCHDbmGetRnti +( +RgSchCellCb *cellCb +) +#else +PUBLIC RgSchRntiLnk* rgSCHDbmGetRnti(cellCb) +RgSchCellCb *cellCb; +#endif +{ + RgSchRntiLnk *rntiLnk; + + TRC2(rgSCHDbmGetRnti) + + if (!(cellCb->rntiDb.freeRnti)) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cellCb->cellId,"RNTI exhausted count:%d", + cellCb->rntiDb.count); + RETVALUE(NULLP); + } + + rntiLnk = cellCb->rntiDb.freeRnti; + cellCb->rntiDb.freeRnti = rntiLnk->nxt; + + /* setting prv and nxt to NULLP may not be needed */ + rntiLnk->prv = NULLP; + rntiLnk->nxt = NULLP; + + if (cellCb->rntiDb.freeRnti != NULLP) + { + cellCb->rntiDb.freeRnti->prv = NULLP; + } + else + { + cellCb->rntiDb.lastRnti = NULLP; + } + + cellCb->rntiDb.count--; + + printf("rgSCHDbmGetRnti::rntiLnk->rnti %u\n",rntiLnk->rnti); + RETVALUE(rntiLnk); +} /* rgSCHDbmGetRnti */ + +/** + * @brief Handler for releasing the RNTI. + * + * @details + * + * Function : rgSCHDbmRlsRnti + * + * + * @param[in] *cellCb + * @param[in] rntiLnk + * @return Void + **/ +#ifdef ANSI +PUBLIC Void rgSCHDbmRlsRnti +( +RgSchCellCb *cellCb, +RgSchRntiLnk *rntiLnk +) +#else +PUBLIC Void rgSCHDbmRlsRnti(cellCb, rntiLnk) +RgSchCellCb *cellCb; +RgSchRntiLnk *rntiLnk; +#endif +{ + TRC2(rgSCHDbmRlsRnti) +#ifdef EMTC_ENABLE + if(ROK==rgSCHDbmPutEmtcRnti(cellCb,rntiLnk)) +{ +RETVOID; +} +#endif + rntiLnk->nxt = NULLP; + if (cellCb->rntiDb.lastRnti) + { + cellCb->rntiDb.lastRnti->nxt = rntiLnk; + rntiLnk->prv = cellCb->rntiDb.lastRnti; + } + else + { + rntiLnk->prv = NULLP; + cellCb->rntiDb.freeRnti = rntiLnk; + } + cellCb->rntiDb.lastRnti = rntiLnk; + + cellCb->rntiDb.count++; + + /* Stack Crash problems for TRACE5 Changes. Added the return below */ + RETVOID; + +} /* rgSCHDbmRlsRnti */ + +#ifdef LTE_TDD +/** + * @brief Handler for initializing the ueTfuPendLst under the cellCb. + * + * @details + * + * Function : rgSCHDbmInitUeTfuPendLst + * + * + * @param[in] *cellCb + * @param[in] numBins + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PRIVATE S16 rgSCHDbmInitUeTfuPendLst +( +RgSchCellCb *cellCb, +U16 numBins +) +#else +PRIVATE S16 rgSCHDbmInitUeTfuPendLst(cellCb, numBins) +RgSchCellCb *cellCb; +U16 numBins; +#endif +{ + RgSchUePucchRecpInfo pucchInfo; + TRC2(rgSCHDbmInitUeTfuPendLst) + + /* Fix: syed It is better to compute offset dynamically + * rather than hardcoding it as 0 */ + if(cmHashListInit(&cellCb->ueTfuPendLst, numBins, (U16)((PTR)&(pucchInfo.hashLstEnt) - (PTR)&pucchInfo), FALSE, + CM_HASH_KEYTYPE_CONID, + rgSchCb[cellCb->instIdx].rgSchInit.region, + rgSchCb[cellCb->instIdx].rgSchInit.pool) != ROK) + { + RETVALUE(RFAILED); + } + + RETVALUE(ROK); + +} /* rgSCHDbmInitUeTfuPendLst */ + +/** + * @brief Handler for de-initializing the ueTfuPendLst under the cellCb. + * + * @details + * + * Function : rgSCHDbmDeInitUeTfuPendLst + * + * + * @param[in] *cellCb + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 rgSCHDbmDeInitUeTfuPendLst +( +RgSchCellCb *cellCb +) +#else +PUBLIC S16 rgSCHDbmDeInitUeTfuPendLst(cellCb) +RgSchCellCb *cellCb; +#endif +{ + TRC2(rgSCHDbmDeInitUeTfuPendLst) + + cmHashListDeinit(&cellCb->ueTfuPendLst); + + RETVALUE(ROK); +} /* rgSCHDbmDeInitUeTfuPendLst */ +#endif + +/********************************************************************** + + End of file +**********************************************************************/ diff --git a/src/5gnrmac/rg_sch_dhm.c b/src/5gnrmac/rg_sch_dhm.c new file mode 100755 index 000000000..f6c8c59a7 --- /dev/null +++ b/src/5gnrmac/rg_sch_dhm.c @@ -0,0 +1,5251 @@ +/******************************************************************************* +################################################################################ +# Copyright (c) [2017-2019] [Radisys] # +# # +# 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. # +################################################################################ +*******************************************************************************/ + +/************************************************************************ + + Name: LTE-MAC layer + + Type: C source file + + Desc: C source code for Entry point fucntions + + File: rg_sch_dhm.c + +**********************************************************************/ + +/** @file rg_sch_dhm.c +@brief APIs related to Downlink HARQ for the scheduler. +*/ + +static const char* RLOG_MODULE_NAME="MAC"; +static int RLOG_FILE_ID=242; +static int RLOG_MODULE_ID=4096; + +/* header include files -- defines (.h) */ +#include "envopt.h" /* environment options */ +#include "envdep.h" /* environment dependent */ +#include "envind.h" /* environment independent */ +#include "gen.h" /* general layer */ +#include "ssi.h" /* system service interface */ +#include "cm5.h" /* common timers */ +#include "cm_hash.h" /* common hash list */ +#include "cm_mblk.h" /* common memory link list library */ +#include "cm_llist.h" /* common linked list library */ +#include "cm_err.h" /* common error */ +#include "cm_lte.h" /* common LTE */ +#include "lrg.h" +#include "rgr.h" +#include "rgm.h" +#include "tfu.h" +#include "rg_env.h" +#include "rg_sch_err.h" +#include "rg_sch_inf.h" /* typedefs for Scheduler */ +#include "rg_sch.h" +#include "rg_sch_cmn.h" +#include "rl_interface.h" +#include "rl_common.h" + +/* header/extern include files (.x) */ +#include "gen.x" /* general layer */ +#include "ssi.x" /* system service interface */ +#include "cm5.x" /* common timers */ +#include "cm_lib.x" /* common library */ +#include "cm_hash.x" /* common hash list */ +#include "cm_llist.x" /* common linked list library */ +#include "cm_mblk.x" /* memory management */ +#include "cm_tkns.x" /* common tokens */ +#include "cm_lte.x" /* common LTE */ +#include "lrg.x" +#include "rgr.x" +#include "rgm.x" +#include "tfu.x" +#include "rg_sch_inf.x" /* typedefs for Scheduler */ +#include "rg_sch.x" +#include "rg_sch_cmn.x" + +#ifdef RGSCH_SPS_STATS +extern U32 rgNumSPSSchedDropMaxRetx; +extern U32 rgNumActDtx; +#endif +PUBLIC U32 nackSf[10]; + + + +#ifdef MAC_SCH_STATS +PUBLIC RgSchNackAckStats hqFailStats; +PUBLIC RgSchHqRetxStats hqRetxStats; +#endif /* MAC_SCH_STATS */ +//Chandan Stats Collection +#ifdef DLHQ_STATS +U32 statsCnt; +RgSchDlHqStats dlHqStats[10000] = {{0,0,0}}; +#endif + +#ifdef TFU_TDD +/* For special bundling case: convert numOfAcks to ACK/NACK + * The below table derives the HARQ aknowledgement as ACK or NACK using the + * number of transmission done and the feedback value received + * The below table is based on Table 7.3-X from 36.213 and + * table 79 from FAPIv1.1 doc + */ +U8 rgSchNumOfAcksToAckNack[RG_SCH_MAX_NUM_EXPECTED_ACKS][RG_SCH_NUM_FDBK_VALUE] = { +{TFU_HQFDB_ACK, TFU_HQFDB_NACK, TFU_HQFDB_NACK}, +{TFU_HQFDB_NACK, TFU_HQFDB_ACK, TFU_HQFDB_NACK}, +{TFU_HQFDB_NACK, TFU_HQFDB_NACK, TFU_HQFDB_ACK}, +{TFU_HQFDB_ACK, TFU_HQFDB_NACK, TFU_HQFDB_NACK}, +{TFU_HQFDB_NACK, TFU_HQFDB_ACK, TFU_HQFDB_NACK}, +{TFU_HQFDB_NACK, TFU_HQFDB_NACK, TFU_HQFDB_ACK}, +{TFU_HQFDB_ACK, TFU_HQFDB_NACK, TFU_HQFDB_NACK}, +{TFU_HQFDB_NACK, TFU_HQFDB_ACK, TFU_HQFDB_NACK}, +{TFU_HQFDB_NACK, TFU_HQFDB_NACK, TFU_HQFDB_ACK} +}; +#endif + +/* local typedefs */ + +/* local externs */ + +PRIVATE Void rgSCHDhmFdbkIndHndlTa ARGS((RgSchDlHqProcCb *hqP, U8 tbIdx, U8 fdbk, + Bool maxHqRetxReached)); +PUBLIC void rgEmtcsetNullSubFrm ARGS((RgSchDlHqProcCb *hqP)); +#ifndef LTE_TDD +PRIVATE S16 rgSCHDhmProcHqFdbkAckNackRep ARGS(( +RgSchDlHqProcCb *hqP, +RgSchDlSf *sf, +U8 tbCnt, +U8 *isAck +)); +#endif +#ifdef DL_LA +PRIVATE S16 rgSCHDhmUpdateAckNackHistory ARGS(( + RgSchCellCb *cell, + RgSchUeCb *ueCb, + U8 hqfdbk, + U8 tbCnt + )); +#endif +#ifdef LTE_TDD +PRIVATE Void rgSCHDhmPrcSplBundlFdbk ARGS(( + RgSchCellCb *cell, + TfuHqInfo *fdbk, + U8 hqCnt + )); +#ifdef LTE_ADV +PRIVATE Void rgSchGetHqFdbkPosForM1 ARGS(( + RgSchUeCb *ue, + RgSchDlHqProcCb *hqP, + U8 *isAck, + RgTfuHqInfo *fdbk, + U8 tbIdx, + RgSchTddANInfo *anInfo + )); +PRIVATE Void rgSchGetHqFdbkPosForM234 ARGS(( + RgSchUeCb *ue, + RgSchDlHqProcCb *hqP, + U8 *isAck, + RgTfuHqInfo *fdbk, + U8 tbIdx, + RgSchTddANInfo *anInfo, + U8 M, + CmLteTimingInfo timeInfo + )); +#endif/*LTE_ADV*/ +#endif/*LTE_TDD*/ + +/* Freeing up the HARQ proc blocked for + * indefinite time in case of Retx */ +PUBLIC S16 rgSCHDhmDlRetxAllocFail ARGS(( +RgSchUeCb *ue, +RgSchDlHqProcCb *proc +)); + +#ifdef EMTC_ENABLE +EXTERN S16 rgSCHDhmEmtcRgrCellCfg ARGS(( +RgSchCellCb *cell +)); +#endif + +#ifdef CA_DBG +extern U32 gPCellTb1AckCount,gPCellTb2AckCount,gPCellTb1NackCount,gPCellTb2NackCount; +extern U32 gSCellSchedCount,gPrimarySchedCount; +extern U32 gSCellTb1AckCount,gSCellTb2AckCount,gSCellTb1NackCount,gSCellTb2NackCount; +extern U32 gPCellTb1DtxCount, gPCellTb2DtxCount, gSCellTb1DtxCount, gSCellTb2DtxCount; +extern U32 gHqFdbkCount; + +#endif +#ifdef EMTC_ENABLE +EXTERN Void rgSCHEmtcUtlDlHqPTbRmvFrmTx +( +RgSchEmtcDlSf *subFrm, +RgSchDlHqProcCb *hqP, +U8 tbIdx, +Bool isRepeting +); +EXTERN RgSchEmtcDlSf* rgSCHEmtcUtlSubFrmGet +( +RgSchCellCb *cell, +CmLteTimingInfo frm +); +EXTERN Void rgSCHEmtcHqInfoAlloc ARGS((RgSchCellCb *cell, RgSchDlHqProcCb *hqP)); +#endif +/* forward references */ + +/** + * @brief This function initializes the DL HARQ Entity of UE. + * + * @details + * + * Function: rgSCHDhmHqEntInit + * Purpose: This function initializes the DL HARQ entity of + * UE control block. This is performed at the time + * of creating UE control block. + * + * Invoked by: configuration module + * + * @param[in] RgSchCellCb* cell + * @return RgSchDlHqEnt * + * + **/ +/*MS_WORKAROUND for ccpu00122893*/ +#ifdef ANSI +PUBLIC Void rgSCHDhmHqEntReset +( + RgSchDlHqEnt *hqE +) +#else +PUBLIC Void rgSCHDhmHqEntReset(hqE) + RgSchDlHqEnt *hqE; +#endif +{ + RgSchDlHqProcCb *hqP; + U8 i; + TRC2(rgSCHDhmHqEntReset) + cmLListInit(&hqE->inUse); + cmLListInit(&hqE->free); + for (i=0; i < hqE->numHqPrcs; i++) + { + hqP = &hqE->procs[i]; + hqP->hqE = hqE; + hqP->procId = i; + /* Fix - reset numLch */ + hqP->tbInfo[0].numLch = 0; + hqP->tbInfo[1].numLch = 0; + hqP->tbInfo[0].txCntr = 0; + hqP->tbInfo[0].ndi = 0; /* Initialize the NDI to Zero */ + hqP->tbInfo[1].txCntr = 0; + hqP->tbInfo[1].ndi = 0; /* Initialize the NDI to Zero */ + hqP->tbInfo[0].tbIdx = 0; + hqP->tbInfo[1].tbIdx = 1; + hqP->tbInfo[0].hqP = hqP; + hqP->tbInfo[1].hqP = hqP; + hqP->tbInfo[0].state = HQ_TB_ACKED; + hqP->tbInfo[1].state = HQ_TB_ACKED; + hqP->tbInfo[0].contResCe = NOTPRSNT; + hqP->tbInfo[1].contResCe = NOTPRSNT; + hqP->lnk.node = (PTR)hqP; + //cmLListAdd2Tail(&hqE->free, &hqP->lnk); + hqP->hqPLst = NULLP; + rgSCHDhmHqPAdd2FreeLst(hqP); + hqP->tbInfo[0].lchSchdData = hqP->tbInfo[0].lchSchdDataArr; + hqP->tbInfo[1].lchSchdData = hqP->tbInfo[1].lchSchdDataArr; + hqP->drxCb.rttIndx = DRX_INVALID; + hqP->drxCb.reTxIndx = DRX_INVALID; + hqP->tbInfo[0].cntrRetxAllocFail = 0; + hqP->tbInfo[1].cntrRetxAllocFail = 0; + hqP->hasDcch = FALSE; + hqP->cwSwpEnabled = FALSE; + hqP->pdcch = NULLP; + hqP->subFrm = NULLP; + +#ifdef LTE_ADV + rgSCHLaaResetDlHqProcCb(hqP); +#endif + } + RETVOID; +} /* rgSCHDhmHqEntReset */ + +/** + * @brief This function assigns dlHqEnt of raCb to ueCb. + * + * @details + * + * Function: rgSCHDhmAssgnUeHqEntFrmRaCb + * Purpose: This function assigns dlHqEnt of raCb to ueCb. + * + * Invoked by: configuration module + * + * @param[in] RgSchUeCb *ue + * @param[in] RgSchRaCb *raCb + * @return Void + * + **/ +#ifdef ANSI +PUBLIC Void rgSCHDhmAssgnUeHqEntFrmRaCb +( +RgSchUeCb *ue, +RgSchRaCb *raCb +) +#else +PUBLIC Void rgSCHDhmAssgnUeHqEntFrmRaCb(ue, raCb) +RgSchUeCb *ue; +RgSchRaCb *raCb; +#endif +{ + TRC2(rgSCHDhmAssgnUeHqEntFrmRaCb) + + ue->cellInfo[0]->hqEnt = raCb->dlHqE; + ue->cellInfo[0]->hqEnt->ue = ue; + /* Update the DL Harq related information */ + ue->cellInfo[0]->hqEnt->maxHqTx = ue->cell->dlHqCfg.maxDlHqTx; + raCb->dlHqE = NULLP; + /* Fix : set UE active in DL as UE initialization completed */ + ue->dl.dlInactvMask &= ~(RG_HQENT_INACTIVE); + ue->ul.ulInactvMask &= ~(RG_HQENT_INACTIVE); + rgSCHCmnDlInitHqEnt(ue->cell, ue->cellInfo[0]->hqEnt); + + RETVOID; +} + +/** + * @brief This function deletes the dlHqEnt. + * + * @details + * + * Function: rgSCHDhmDelHqEnt + * Purpose: This function deletes the dlHqEnt. + * + * Invoked by: configuration module + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchDlHqEnt **hqE + * @return Void + * + **/ +#ifdef ANSI +PUBLIC Void rgSCHDhmDelHqEnt +( +RgSchCellCb *cell, +RgSchDlHqEnt **hqE +) +#else +PUBLIC Void rgSCHDhmDelHqEnt(cell, hqE) +RgSchCellCb *cell; +RgSchDlHqEnt **hqE; +#endif +{ + TRC2(rgSCHDhmDelHqEnt) + + if (!(*hqE)) + { + RETVOID; + } + + rgSCHCmnDlDeInitHqEnt(cell, *hqE); + + rgSCHUtlFreeSBuf(cell->instIdx, (Data **)hqE, + sizeof(RgSchDlHqEnt)); + + RETVOID; +} + +#ifdef ANSI +PUBLIC RgSchDlHqEnt *rgSCHDhmHqEntInit +( +RgSchCellCb *cell +) +#else +PUBLIC RgSchDlHqEnt *rgSCHDhmHqEntInit(cell) +RgSchCellCb *cell; +#endif +{ + RgSchDlHqEnt *hqE; + Inst inst = cell->instIdx; + + TRC2(rgSCHDhmHqEntInit) + + /* Init the HARQ data structure */ + if (rgSCHUtlAllocSBuf(inst, (Data **)&hqE, sizeof(RgSchDlHqEnt)) != ROK) + { + RLOG_ARG0(L_DEBUG,DBG_CELLID,cell->cellId, + "rgSCHDhmHqEntInit hqE alloc fail"); + RETVALUE(NULLP); + } +#ifdef LTE_TDD + /* Init the HARQ processes */ + hqE->numHqPrcs = rgSchTddDlNumHarqProcTbl[cell->ulDlCfgIdx]; + if (rgSCHUtlAllocSBuf(inst, (Data **)&hqE->procs, + hqE->numHqPrcs * sizeof(RgSchDlHqProcCb)) != ROK) + { + RLOG_ARG0(L_DEBUG,DBG_CELLID,cell->cellId, + "rgSCHDhmHqEntInit hqP alloc fail in hqE"); + RETVALUE(NULLP); + } +#else + hqE->numHqPrcs = RGSCH_NUM_DL_HQ_PROC; +#endif + +#ifdef LTE_ADV + rgSCHLaaInitDlHqProcCb (cell, hqE); +#endif + + /* Initialize maximum tranmission counter */ + hqE->maxHqTx = cell->dlHqCfg.maxDlHqTx; + + + /* MW_WORKAROUND for ccpu00122893 */ + rgSCHDhmHqEntReset(hqE); + /* CA Dev Start*/ + hqE->cell = cell; + /* CA Dev End*/ + + RETVALUE(hqE); +} /* rgSCHDhmHqEntInit */ + +/** + * @brief This function gets an available HARQ process. + * + * @details + * + * Function: rgSCHDhmGetAvlHqProc + * Purpose: This function returns an available HARQ process in + * the DL direction. All HARQ processes are maintained + * in queues of free and inuse. + * + * 1. Check if the free queue is empty. If yes, return + * RFAILED + * 2. If not empty, update the proc variable with the + * first process in the queue. Return ROK. + * + * Invoked by: scheduler + * + * @param[in] RgSchUeCb *ue + * @param[in] CmLteTimingInfo timingInfo + * @param[out] RgSchDlHqProc **hqP + * @return S16 + * -#ROK if successful + * -#RFAILED otherwise + * + **/ +#ifdef ANSI +PUBLIC S16 rgSCHDhmGetAvlHqProc +( +RgSchCellCb *cell, +RgSchUeCb *ue, +CmLteTimingInfo timingInfo, +RgSchDlHqProcCb **hqP +) +#else +PUBLIC S16 rgSCHDhmGetAvlHqProc (cell, ue, timingInfo, hqP) +RgSchCellCb *cell; +RgSchUeCb *ue; +CmLteTimingInfo timingInfo; +RgSchDlHqProcCb **hqP; +#endif +{ + RgSchDlHqEnt *hqE = NULLP; + RgSchDlHqProcCb *tmpHqProc; + CmLList *tmp; + TRC2(rgSCHDhmGetAvlHqProc); + + hqE = RG_SCH_CMN_GET_UE_HQE(ue, cell); + + if (hqE == NULLP) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId, "rgSCHDhmGetAvlHqProc hqE NULL ue %d" + , ue->ueId); + RETVALUE(RFAILED); + } + + + CM_LLIST_FIRST_NODE(&(hqE->free), tmp); + + if (NULLP == tmp) + { + RLOG_ARG3(L_ERROR,DBG_CELLID,cell->cellId, + "rgSCHDhmGetAvlHqProc free %ld inUse %ld ue %d" + , hqE->free.count, hqE->inUse.count, ue->ueId); + /* No Harq Process available in the free queue. */ + RETVALUE(RFAILED); + } + + tmpHqProc = (RgSchDlHqProcCb *)(tmp->node); + +#ifdef LTEMAC_SPS + /* If SPS HARQ procs are in use, do not use SPS harq procs for non-SPS + * transmissions */ + if (ue->dl.isSpsHqPInUse) + { + while (tmpHqProc->procId < ue->dl.dlSpsCfg.numSpsHqProc) + { + CM_LLIST_NEXT_NODE(&(hqE->free), tmp); + if (!tmp) + { + break; + } + tmpHqProc = (RgSchDlHqProcCb *)(tmp->node); + } + if (!tmp) + { + /* No Harq Process available in the free queue. */ + RETVALUE(RFAILED); + } + } +#endif + + + tmpHqProc->tbInfo[0].timingInfo = timingInfo; + tmpHqProc->tbInfo[1].timingInfo = timingInfo; + tmpHqProc->hasDcch = FALSE; + tmpHqProc->cwSwpEnabled = FALSE; + + /* Remove the element from the free Queue */ + //cmLListDelFrm(&hqE->free, tmp); + rgSCHDhmHqPDelFrmFreeLst(tmpHqProc); + + /* Add the element into the inUse Queue as well */ + //cmLListAdd2Tail(&hqE->inUse, &tmpHqProc->lnk); + rgSCHDhmHqPAdd2InUseLst(tmpHqProc); + + *hqP = tmpHqProc; + +#ifdef LTE_ADV + rgSCHLaaResetDlHqProcCb(tmpHqProc); +#endif + + /* LAA DBG Only */ + tmpHqProc->tbSizeAtEstimate[0] = 0; + tmpHqProc->tbSizeAtEstimate[1] = 0; + tmpHqProc->tbSizeAtFnlz[0] = 0; + tmpHqProc->tbSizeAtFnlz[1] = 0; + tmpHqProc->tbSizeOfMvdTb[0] = 0; + tmpHqProc->tbSizeOfMvdTb[1] = 0; + tmpHqProc->itbsAtEstimate[0] = 0; + tmpHqProc->itbsAtEstimate[1] = 0; + tmpHqProc->prbAtEstimate = 0; + + RETVALUE(ROK); +} /* rgSCHDhmGetAvlHqProc */ + + +/** + * @brief This function adds HARQ process for a given TB in to + * the inuse queue upon retx. + * + * @details + * + * Function: rgSCHDhmHqTbRetx + * Purpose: This function handles when a HARQ process is scheduled + * for retransmission. It adds the HARQ procss to inuse + * queue. + * 1. Check if this HqP is already added to the inUse + * queue as part of this function call for other + * TB's retransmission. + * 2. If already present in inUse Q then do not add. + * + * Invoked by: scheduler + * + * @param[in] RgSchDlHqEnt *hqE + * @param[in] CmLteTimingInfo timingInfo + * @param[out] RgDlHqProc *hqP + * @param[in] U8 tbIdx + * @return Void + * + **/ +#ifdef ANSI +PUBLIC Void rgSCHDhmHqTbRetx +( +RgSchDlHqEnt *hqE, +CmLteTimingInfo timingInfo, +RgSchDlHqProcCb *hqP, +U8 tbIdx +) +#else +PUBLIC Void rgSCHDhmHqTbRetx(hqE, timingInfo, hqP, tbIdx) +RgSchDlHqEnt *hqE; +CmLteTimingInfo timingInfo; +RgSchDlHqProcCb *hqP; +U8 tbIdx; +#endif +{ + U8 othrTbIdx = tbIdx ^ 1; + TRC2(rgSCHDhmHqTbRetx) + + hqP->tbInfo[tbIdx].timingInfo = timingInfo; + + if (hqE->msg4Proc == hqP) + { + RETVOID; + } + /* fix for ccpu00118633 No Hq proc Avl end*/ + + /* Extra:check if Harq process is already linked to in-use + Queue by means of other TB handling. */ + if (hqP->tbInfo[othrTbIdx].state != HQ_TB_WAITING) + { + /*Fix FIXME */ + if (hqE->msg4Proc != hqP) + { + //cmLListAdd2Tail(&hqE->inUse, &hqP->lnk); + rgSCHDhmHqPAdd2InUseLst(hqP); + } + } + + hqP->tbInfo[tbIdx].cntrRetxAllocFail = 0; + + RETVOID; +} /* rgSCHDhmHqTbRetx */ + +/** + * @brief This function returns last scheduled HARQ process for + * a UE's HARQ entity. + * + * @details + * + * Function: rgSCHDhmLastSchedHqProc + * Purpose: This function returns the last (most recent) + * process in the inUse list, which corresponds + * to the last scheduled process. Returns NULLP + * if list is empty. + * The reason for introducing this is to have + * an ability to check if UE was scheduled + * in the current subframe (scheduling would + * have caused a proc to be added to the end + * of the list, and checking time (only subframe + * number probably works) would confirm this. + * + * Invoked by: scheduler + * + * @param[in] RgSchDlHqEnt *hqE + * @return RgSchDlHqProcCb * + * + **/ +#ifdef ANSI +PUBLIC RgSchDlHqProcCb * rgSCHDhmLastSchedHqProc +( +RgSchDlHqEnt *hqE +) +#else +PUBLIC RgSchDlHqProcCb * rgSCHDhmLastSchedHqProc(hqE) +RgSchDlHqEnt *hqE; +#endif +{ + TRC2(rgSCHDhmLastSchedHqProc); + /* GRPPWR_CNTRL Fix: UE context will not hold a valid hqE, + * until RACH procedure is completed */ + if ((hqE == NULLP) || (hqE->inUse.last == NULLP)) + { + RETVALUE(NULLP); + } + RETVALUE((RgSchDlHqProcCb *)hqE->inUse.last->node); +} /* rgSCHDhmLastSchedHqProc */ + +#ifdef RGR_V1 +/** + * @brief This function gets an available HARQ process for MSG 4. + * + * @details + * + * Function: rgSCHDhmGetCcchSduHqProc + * Purpose: This function returns an available HARQ process in + * the DL direction. All HARQ processes are maintained + * in queues of free and inuse. + * + * 1. Check if the free queue is empty. If yes, return + * RFAILED. + * 2. If not empty, update the proc variable with the + * first process in the queue. Return ROK. + * + * Invoked by: scheduler + * + * @param[in] RgSchRaCb *raCb + * @param[in] CmLteTimingInfo timingInfo + * @param[out] RgSchDlHqProcCb **hqP + * @return S16 + * -#ROK if successful + * -#RFAILED otherwise + * + **/ +#ifdef ANSI +PUBLIC S16 rgSCHDhmGetCcchSduHqProc +( +RgSchUeCb *ueCb, +CmLteTimingInfo timingInfo, +RgSchDlHqProcCb **hqP +) +#else +PUBLIC S16 rgSCHDhmGetCcchSduHqProc (ueCb, timingInfo, hqP) +RgSchUeCb *ueCb; +CmLteTimingInfo timingInfo; +RgSchDlHqProcCb **hqP; +#endif +{ + RgSchDlHqProcCb *tmpHqProc; + CmLList *tmp; + RgSchDlHqEnt *hqE; + + TRC2(rgSCHDhmGetCcchSduHqProc) + + hqE = ueCb->cellInfo[0]->hqEnt; + CM_LLIST_FIRST_NODE(&(hqE->free), tmp); + if (NULLP == tmp) + { + /* No Harq Process available in the free queue. */ + RETVALUE(RFAILED); + } + + /* Remove the element from the free Queue and */ + /* set the MSG 4 HARQ proc pointer */ + //cmLListDelFrm(&hqE->free, tmp); + + tmpHqProc = (RgSchDlHqProcCb *)(tmp->node); + + rgSCHDhmHqPDelFrmFreeLst(tmpHqProc); + + tmpHqProc->tbInfo[0].timingInfo = timingInfo; + /* Fix : syed minor code reorg */ + *hqP = tmpHqProc; + /*Updating ccchSduProc to identify feedback for CCCH SDU sent without + * Cont Res CE*/ + hqE->ccchSduProc = tmpHqProc; + //cmLListAdd2Tail(&hqE->inUse, &tmpHqProc->lnk); + rgSCHDhmHqPAdd2InUseLst(tmpHqProc); + + RETVALUE(ROK); +} /* rgSCHDhmGetCcchSduHqProc */ +#endif + +/** + * @brief This function gets an available HARQ process for MSG 4. + * + * @details + * + * Function: rgSCHDhmGetMsg4HqProc + * Purpose: This function returns an available HARQ process in + * the DL direction. All HARQ processes are maintained + * in queues of free and inuse. + * + * 1. Check if the free queue is empty. If yes, return + * RFAILED. + * 2. If not empty, update the proc variable with the + * first process in the queue. Return ROK. + * + * Invoked by: scheduler + * + * @param[in] RgSchRaCb *raCb + * @param[in] CmLteTimingInfo timingInfo + * @param[out] RgDlHqProc **hqP + * @return S16 + * -#ROK if successful + * -#RFAILED otherwise + * + **/ +#ifdef ANSI +PUBLIC S16 rgSCHDhmGetMsg4HqProc +( +RgSchRaCb *raCb, +CmLteTimingInfo timingInfo +) +#else +PUBLIC S16 rgSCHDhmGetMsg4HqProc (raCb, timingInfo) +RgSchRaCb *raCb; +CmLteTimingInfo timingInfo; +#endif +{ + RgSchDlHqProcCb *tmpHqProc; + CmLList *tmp; + RgSchDlHqEnt *hqE; + + TRC2(rgSCHDhmGetMsg4HqProc) + + hqE = raCb->dlHqE; + CM_LLIST_FIRST_NODE(&(hqE->free), tmp); + if (NULLP == tmp) + { + /* No Harq Process available in the free queue. */ + RETVALUE(RFAILED); + } + + /* Remove the element from the free Queue and */ + /* set the MSG 4 HARQ proc pointer */ + //cmLListDelFrm(&hqE->free, tmp); + tmpHqProc = (RgSchDlHqProcCb *)(tmp->node); + rgSCHDhmHqPDelFrmFreeLst(tmpHqProc); + tmpHqProc->tbInfo[0].timingInfo = timingInfo; + hqE->msg4Proc = tmpHqProc; + + RETVALUE(ROK); +} /* rgSCHDhmGetMsg4HqProc */ + +/** + * @brief This function releases a HARQ process. + * + * @details + * + * Function: rgSCHDhmRlsHqpTb + * Purpose: This function resets the TB specific fields + * Based on the other TBs state, this HqProcess + * is returned to the HqEnt. + * + * 1. Add the HARQ process to the free queue. + * Invoked by: scheduler and HARQ processing + * + * @param[in] RgDlHqProc *hqP + * @param[in] U8 tbIdx + * @param[in] Bool togNdi + * @return Void + * + **/ +#ifdef ANSI +PUBLIC Void rgSCHDhmRlsHqpTb +( +RgSchDlHqProcCb *hqP, +U8 tbIdx, +Bool togNdi +) +#else +PUBLIC Void rgSCHDhmRlsHqpTb(hqP, tbIdx, togNdi) +RgSchDlHqProcCb *hqP; +U8 tbIdx; +Bool togNdi; +#endif +{ + RgSchDlHqEnt *hqE; + U8 othrTbIdx = tbIdx ^ 1; +#ifdef LTEMAC_SPS + RgSchCmnDlHqProc *cmnHqDl; +#endif + /* L2_COUNTERS */ +#ifdef LTE_L2_MEAS + RgSchDlLcCb* lcCb = NULLP; + U8 numLch = 0; +#endif + + TRC2(rgSCHDhmRlsHqpTb) + + /* Reset all tbInfo values */ + + hqE = hqP->hqE; + +#ifdef MAC_SCH_STATS + if (hqP->hqE->ue != NULLP) + { + RgSchUeCb *ueCb = hqP->hqE->ue; + RgSchCmnUe *cmnUe = (RgSchCmnUe*)ueCb->sch; + RgSchCmnDlUe *dlUe = RG_SCH_CMN_GET_DL_UE(ueCb,hqE->cell);/*CA dev*/ + U8 cqi = dlUe->mimoInfo.cwInfo[0].cqi; + /* to get retransmission, decreasing transmission counter */ + U16 numDlRetx = hqP->tbInfo[0].txCntr-1; + U8 tbs = dlUe->mimoInfo.cwInfo[0].iTbs[0]; + static U32 retxCnt1 = 0; + + RG_SCH_CMN_DL_TBS_TO_MCS(tbs, \ + hqRetxStats.dlCqiStat[(cqi - 1)].mcs); + + switch (numDlRetx) + { + case 1: + hqRetxStats.dlCqiStat[(cqi - 1)].numOfHQ_1++; + break; + case 2: + hqRetxStats.dlCqiStat[(cqi - 1)].numOfHQ_2++; + break; + case 3: + hqRetxStats.dlCqiStat[(cqi - 1)].numOfHQ_3++; + break; + case 4: + hqRetxStats.dlCqiStat[(cqi - 1)].numOfHQ_4++; + break; + } + hqRetxStats.dlCqiStat[(cqi - 1)].totalTx = \ + hqRetxStats.dlCqiStat[(cqi - 1)].numOfHQ_1 + \ + (hqRetxStats.dlCqiStat[(cqi - 1)].numOfHQ_2 * 2) + \ + (hqRetxStats.dlCqiStat[(cqi - 1)].numOfHQ_3 * 3) + \ + (hqRetxStats.dlCqiStat[(cqi - 1)].numOfHQ_4 * 4); + + retxCnt1 += numDlRetx; + } +#endif /* MAC_SCH_STATS */ + RGSCH_ARRAY_BOUND_CHECK(0, hqP->tbInfo, tbIdx); + /* Toggle ndi */ + if(togNdi == TRUE) + { + hqP->tbInfo[tbIdx].ndi ^= 1; + } + + /* L2_COUNTERS */ +#ifdef LTE_L2_MEAS + for (numLch =0; numLch < hqP->tbInfo[tbIdx].numLch; numLch++) + { + if (NULLP != (lcCb = rgSCHDbmGetDlDedLcCb( hqP->hqE->ue, + hqP->tbInfo[tbIdx].lchSchdDataArr[numLch].lcId))) + { + if (lcCb->lcType == CM_LTE_LCH_DTCH) + { + if (hqP->hqE->ue->qciActiveLCs[lcCb->qciCb->qci]) + { + hqP->hqE->ue->qciActiveLCs[lcCb->qciCb->qci]--; + } + + if (!(hqP->hqE->ue->qciActiveLCs[lcCb->qciCb->qci])) + { + lcCb->qciCb->dlUeCount--; + } + } + } + } +#endif + + /* Initialization */ + hqP->tbInfo[tbIdx].tbSz = 0; + hqP->tbInfo[tbIdx].numLch = 0; + hqP->tbInfo[tbIdx].txCntr = 0; + /* FOR ACK NACK REP */ + hqP->tbInfo[tbIdx].fbkRepCntr = 0; + hqP->tbInfo[tbIdx].fbkRecpRepCntr = 0; + hqP->tbInfo[tbIdx].ackCount = 0; + /* pdcch is moved from TbCb to HqCb. + This pdcch will be set to NULL when + HqCb will be pushed to free list*/ + hqP->tbInfo[tbIdx].state = HQ_TB_ACKED; + hqP->tbInfo[tbIdx].isAckNackDtx = 0; + hqP->tbInfo[tbIdx].nackCount = 0; + hqP->tbInfo[tbIdx].dtxCount = 0; + hqP->tbInfo[tbIdx].schdTa.pres = NOTPRSNT; + hqP->tbInfo[tbIdx].contResCe = NOTPRSNT; +#ifdef LTE_ADV + hqP->tbInfo[tbIdx].schdSCellActCe.pres = NOTPRSNT; +#endif + hqP->tbInfo[tbIdx].minRlcReordrTmr = 0; + /* Handling msg4 hqProc */ + if (hqE->msg4Proc == hqP) + { + hqE->msg4Proc = NULLP; + hqP->pdcch = NULLP; + hqP->subFrm = NULLP; + /* Add the proc to the free list */ + //cmLListAdd2Tail(&hqE->free, &hqP->lnk); + rgSCHDhmHqPAdd2FreeLst(hqP); + RETVOID; + } +#ifdef RGR_V1 + /* MS_WORKAROUND : syed The check (hqE->ccchSduProc != NULLP) + * is dangerous and it expects ccchSduProc is the first + * DL allocation for a UE, and considering a scenario + * of multiple UEs contending and 1 UE per TTI, this + * assumption can be wronged, leading to inUse list + * corruption. Hence altering this check. + * A better approach would be do avoid having this + * special handling for ccchSduProc, streamline + * it with the usual approach. */ + if (hqE->ccchSduProc == hqP) + { + hqE->ccchSduProc = NULLP; + /* ccpu00137582- If hqP is in reTxLst then it will be no more available + * in inUse list, Hence need not to delete from inUse list*/ + if(NULLP == hqP->tbInfo[tbIdx].ccchSchdInfo.retxLnk.node) + { + //cmLListDelFrm(&hqE->inUse, &hqP->lnk); + rgSCHDhmHqPDelFrmInUseLst(hqP); + } + else + { + hqP->tbInfo[tbIdx].ccchSchdInfo.retxLnk.node = NULLP; + } + hqP->pdcch = NULLP; + hqP->subFrm = NULLP; + /* Add the proc to the free list */ + //cmLListAdd2Tail(&hqE->free, &hqP->lnk); + rgSCHDhmHqPAdd2FreeLst(hqP); + RETVOID; + } +#endif + + /* extra:check if other TB is also free for allocation then + * add it to FREE List */ + switch(hqP->tbInfo[othrTbIdx].state) + { + case HQ_TB_ACKED: + /* Remove the element from the inUse Queue */ + /* Freeing up the HARQ proc blocked for + * indefinite time in case of Retx */ + if (hqP->tbInfo[tbIdx].cntrRetxAllocFail != RG_SCH_MAX_RETX_ALLOC_FAIL) + { + //cmLListDelFrm(&hqE->inUse, &hqP->lnk); + rgSCHDhmHqPDelFrmInUseLst(hqP); + } + hqP->pdcch = NULLP; + hqP->subFrm = NULLP; +#ifdef EMTC_ENABLE +rgEmtcsetNullSubFrm(hqP); +#endif + /* Add the proc to the free list */ + //cmLListAdd2Tail(&hqE->free, &hqP->lnk); + rgSCHDhmHqPAdd2FreeLst(hqP); +#ifdef LAA_DBG + if (hqE->free.count > 8) + { + int *p = NULL; + printf("Crashing invalid hq count after free \n"); + printf("Crashing %d \n", *p); + *p = 10; + } +#endif +#ifdef LTEMAC_SPS + cmnHqDl = RG_SCH_CMN_GET_DL_HQP(hqP); + if (cmnHqDl) + { + cmnHqDl->spsAction = 0; + cmnHqDl->isSpsActv = FALSE; + cmnHqDl->isSpsSvcSchd = FALSE; + } +#endif + break; + case HQ_TB_NACKED: + /* Remove the element from the inUse Queue */ + /* Freeing up the HARQ proc blocked for + * indefinite time in case of Retx */ + if (hqP->tbInfo[othrTbIdx].cntrRetxAllocFail == 0) + { + //cmLListDelFrm(&hqE->inUse, &hqP->lnk); + rgSCHDhmHqPDelFrmInUseLst(hqP); + } + break; + case HQ_TB_WAITING: + /* Do nothing */ + break; + } + + hqP->tbInfo[tbIdx].cntrRetxAllocFail = 0; + + RETVOID; +} /* rgSCHDhmRlsHqpTb */ + +/** + * @brief This function releases a HARQ process. + * + * @details + * + * Function: rgSCHDhmRlsHqProc + * Purpose: This function returns a HARQ process to HARQ Entity + * in the DL direction. + * + * 1. Add the HARQ process to the free queue. + * Invoked by: scheduler and HARQ processing + * + * @param[in] RgDlHqProc *hqP + * @return Void + * + **/ +#ifdef ANSI +PUBLIC Void rgSCHDhmRlsHqProc +( +RgSchDlHqProcCb *hqP +) +#else +PUBLIC Void rgSCHDhmRlsHqProc(hqP) +RgSchDlHqProcCb *hqP; +#endif +{ + + TRC2(rgSCHDhmRlsHqProc) + + +#ifdef MAC_SCH_STATS + /* THIS FUNCTION IS NOT CALLED */ + if (hqP->hqE->ue != NULLP) + { + RgSchUeCb *ueCb = hqP->hqE->ue; + RgSchCmnUe *cmnUe = (RgSchCmnUe*)ueCb->sch; + RgSchCmnDlUe *dlUe = RG_SCH_CMN_GET_DL_UE(ueCb,hqE->cell);/*CA dev*/ + U8 cqi = dlUe->mimoInfo.cwInfo[0].cqi; + /* to get retransmission, decreasing transmission counter */ + U16 numDlRetx = hqP->tbInfo[0].txCntr-1; + U8 tbs = dlUe->mimoInfo.cwInfo[0].iTbs[0]; + + RG_SCH_CMN_DL_TBS_TO_MCS(tbs, hqRetxStats.dlCqiStat[(cqi - 1)].mcs); + + switch (numDlRetx) + { + case 1: + hqRetxStats.dlCqiStat[(cqi - 1)].numOfHQ_1++; + break; + case 2: + hqRetxStats.dlCqiStat[(cqi - 1)].numOfHQ_2++; + break; + case 3: + hqRetxStats.dlCqiStat[(cqi - 1)].numOfHQ_3++; + break; + case 4: + hqRetxStats.dlCqiStat[(cqi - 1)].numOfHQ_4++; + break; + } + hqRetxStats.dlCqiStat[(cqi - 1)].totalTx = \ + hqRetxStats.dlCqiStat[(cqi - 1)].numOfHQ_1 + \ + (hqRetxStats.dlCqiStat[(cqi - 1)].numOfHQ_2 * 2) + \ + (hqRetxStats.dlCqiStat[(cqi - 1)].numOfHQ_3 * 3) + \ + (hqRetxStats.dlCqiStat[(cqi - 1)].numOfHQ_4 * 4); + } +#endif /* MAC_SCH_STATS */ + hqP->pdcch = NULLP; + hqP->subFrm = NULLP; +#ifdef EMTC_ENABLE +rgEmtcsetNullSubFrm(hqP); +#endif + rgSCHDhmHqPDelFrmInUseLst(hqP); + rgSCHDhmHqPAdd2FreeLst(hqP); +#ifdef TFU_UPGRADE + hqP->tbCnt = 0; +#endif + + RETVOID; +} /* rgSCHDhmRlsHqProc */ + +#ifdef LTEMAC_SPS +/** + * @brief This function gets HARQ process with the given ID. + * + * @details + * + * Function: rgSCHDhmGetHqProcFrmId + * Purpose: This function returns the HARQ process with the given ID. + * Invoked by: ROM + * + * @param[in] RgSchUeCb *ue + * @param[in] U8 idx + * @param[in] RgDlHqProc **hqP + * @return S16 + * -# ROK if successful + * -# RFAILED otherwise + * + **/ +#ifdef ANSI +PUBLIC S16 rgSCHDhmGetHqProcFrmId +( +RgSchCellCb *cell, +RgSchUeCb *ue, +U8 idx, +RgSchDlHqProcCb **hqP +) +#else +PUBLIC S16 rgSCHDhmGetHqProcFrmId(cell, ue, idx, hqP) +RgSchCellCb *cell; +RgSchUeCb *ue; +U8 idx; +RgSchDlHqProcCb **hqP; +#endif +{ + RgSchDlHqEnt *hqE; + TRC2(rgSCHDhmGetHqProcFrmId) + + hqE = RG_SCH_CMN_GET_UE_HQE(ue, cell); + /* Pick the proc based on the index provided */ + *hqP = &(hqE->procs[idx]); + + RETVALUE(ROK); +} /* rgSCHDhmGetHqProcFrmId */ + +/** + * @brief This function gets SPS HARQ process from the given time + * + * @details + * + * Function: rgSCHDhmSpsDlGetHqProc + * Purpose: This function returns the SPS HARQ process for the given time + * + * @param[in] RgSchUeCb *ue + * @param[in] CmLteTimingInfo timingInfo + * @return RgSchDlHqProcCb control block + * + **/ +#ifdef ANSI +PUBLIC RgSchDlHqProcCb* rgSCHDhmSpsDlGetHqProc +( +RgSchCellCb *cell, +RgSchUeCb *ue, +CmLteTimingInfo timingInfo +) +#else +PUBLIC RgSchDlHqProcCb* rgSCHDhmSpsDlGetHqProc(cell, ue, timingInfo) +RgSchCellCb *cell, +RgSchUeCb *ue; +CmLteTimingInfo timingInfo; +#endif +{ + RgSchDlHqEnt *hqE; + U8 idx; + RgSchDlHqProcCb *hqProc = NULLP; + CmLList *tmp = NULLP; + + TRC2(rgSCHDhmSpsDlGetHqProc); + + hqE = RG_SCH_CMN_GET_UE_HQE(ue, cell); + + CM_LLIST_FIRST_NODE(&(hqE->free), tmp); + + if (NULLP == tmp) + { + /* No Harq Process available in the free queue. */ + RETVALUE(NULLP); + } + + idx = ((timingInfo.sfn * RGSCH_NUM_SUB_FRAMES_5G + timingInfo.subframe)/ + ue->dl.dlSpsCfg.dlSpsPrdctyEnum) % ue->dl.dlSpsCfg.numSpsHqProc; + + + hqProc = (RgSchDlHqProcCb *)(tmp->node); + + /* If the HARQ process is in the free list, retrieve the process */ + while (hqProc->procId != idx) + { + CM_LLIST_NEXT_NODE(&(hqE->free), tmp); + if (!tmp) + { + break; + } + hqProc = (RgSchDlHqProcCb *)(tmp->node); + } + + if (!tmp) + { + /* No Harq Process available in the free queue. */ + RETVALUE(NULLP); + } + + hqProc->tbInfo[0].timingInfo = timingInfo; + hqProc->tbInfo[1].timingInfo = timingInfo; + + /* Remove the element from the free Queue */ + //cmLListDelFrm(&hqE->free, tmp); + rgSCHDhmHqPDelFrmFreeLst(hqProc); + + /* Add the element into the inUse Queue as well */ + //cmLListAdd2Tail(&hqE->inUse, &hqProc->lnk); + rgSCHDhmHqPAdd2InUseLst(hqProc); + +#ifdef LTE_ADV + rgSCHLaaResetDlHqProcCb(hqProc); +#endif + + RETVALUE(hqProc); +} /* rgSCHDhmSpsDlGetHqProc */ +#endif /* LTEMAC_SPS */ + + +/** * @brief Handler for handling TA. + * + * @details + * + * Function : rgSCHDhmFdbkIndHndlTa + * + * This function handles the TA state and values based on the + * feedback indication received. + * + * @param[in] RgSchDlHqProcCb *hqP + * @param[in] U8 tbIdx + * @param[in] U8 fdbk + * @return Void + * -# None. + **/ +#ifdef ANSI +PRIVATE Void rgSCHDhmFdbkIndHndlTa +( +RgSchDlHqProcCb *hqP, +U8 tbIdx, +U8 fdbk, +Bool maxHqRetxReached +) +#else +PRIVATE Void rgSCHDhmFdbkIndHndlTa(hqP, tbIdx, fdbk,maxHqRetxReached) +RgSchDlHqProcCb *hqP; +U8 tbIdx; +U8 fdbk; +Bool maxHqRetxReached; +#endif +{ + RgSchUeCb *ueCb; + RgSchCellCb *cell; + + TRC2(rgSCHDhmFdbkIndHndlTa) + + ueCb = hqP->hqE->ue; + cell = ueCb->cell; + switch(fdbk) + { + case TRUE: + /*ccpu00130018 -ADD - To prevent duplicate insert into the TA list*/ + hqP->tbInfo[tbIdx].taSnt = FALSE; + /* To prevent duplicate inserts of ueCb into TA list */ + if (ueCb->taLnk.node == NULLP) + { + ueCb->taLnk.node = (PTR)ueCb; + cmLListAdd2Tail(&cell->taUeLst, &ueCb->taLnk); + } + else + { +#ifdef DEBUGP + RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId, "Trying to add CRNTI:%d into TA" + "ACK List twice", ueCb->ueId); +#endif + } + break; + + case FALSE: + /* If Ta was sent and its the final NACK, then reset only the + * taState to IDLE and not the value */ + /* Changed handling in case maxhqretx is reached for TA */ + if(TRUE == maxHqRetxReached) + { + hqP->tbInfo[tbIdx].taSnt = FALSE; + hqP->hqE->ue->dl.taCb.state = RGSCH_TA_IDLE; + + rgSCHUtlReTxTa(cell, ueCb); + RLOG_ARG0(L_DEBUG,DBG_CELLID,cell->cellId, + "Nack Rcvd for TA. Max Tries Attempted"); + } + break; + case TFU_HQFDB_DTX: + /* If Ta was sent and its the final NACK, then reset only the + * taState to IDLE and not the value */ + if(TRUE == maxHqRetxReached) + { + hqP->tbInfo[tbIdx].taSnt = FALSE; + hqP->hqE->ue->dl.taCb.state = RGSCH_TA_IDLE; + + /*ccpu00131191 and ccpu00131317 - Fix for RRC Reconfig failure + * issue for VoLTE call */ + rgSCHUtlDlTARpt(cell, ueCb); + } + break; + + default: + break; + } + + RETVOID; +} /* rgSCHDhmFdbkIndHndlTa */ + +/* 3.1 MIMO: TA cmd details at TB level rather than Hq Level */ +/** * @brief Handler for scheduling TA. + * + * @details + * + * Function : rgSCHDhmShcdTa + * + * This function is called by scheduler when resource allocation + * for TA transmission is done. + * + * @param[in] RgSchUeCb *ue + * @param[out] RgSchDlHqTbCb *tbInfo + * @return Void + * -# None. + **/ +#ifdef ANSI +PUBLIC Void rgSCHDhmSchdTa +( +RgSchUeCb *ueCb, +RgSchDlHqTbCb *tbInfo +) +#else +PUBLIC Void rgSCHDhmSchdTa(ueCb, tbInfo) +RgSchUeCb *ueCb; +RgSchDlHqTbCb *tbInfo; +#endif +{ + + TRC2(rgSCHDhmSchdTa) + + ueCb->dl.taCb.state = RGSCH_TA_SCHEDULED; + ueCb->dl.taCb.numRemSf = 2; + tbInfo->schdTa.pres = PRSNT_NODEF; + tbInfo->schdTa.val = ueCb->dl.taCb.ta; + + RETVOID; +} /* rgSCHDhmSchdTa */ + +#ifdef LTE_TDD +/** * @brief Handler for fetching Harq Proc given the feeback information. + * + * @details + * + * Function : rgSCHDhmHqProcByFdbkTime + * + * This function shall fetch all the harq proc having the feedback + * timing information. + * + * @param[in] RgSchDlHqEnt *hqE + * @param[in] CmLteTimingInfo timeInfo + * @param[in] Bool *isMsg4 + * @param[out] RgSchDlHqProcCb **hqPrcs + * @param[out] U8 *numTbs + * @param[out] S8 *tbStrtIdx + * @param[out] U8 *cntHqPrcs + * @return S16 + **/ +#ifdef ANSI +PRIVATE S16 rgSCHDhmHqProcByFdbkTime +( +RgSchDlHqEnt *hqE, +CmLteTimingInfo timeInfo, +Bool *isMsg4, +RgSchDlHqProcCb **hqPrcs, +U8 *numTbs, +S8 *tbStrtIdx, +U8 *cntHqPrcs, +RgSchCellCb *cell +) +#else +PRIVATE S16 rgSCHDhmHqProcByFdbkTime(hqE, timeInfo, isMsg4, hqPrcs, + numTbs, tbStrtIdx, cntHqPrcs) +RgSchDlHqEnt *hqE; +CmLteTimingInfo timeInfo; +Bool *isMsg4; +RgSchDlHqProcCb **hqPrcs; +U8 *numTbs; +S8 *tbStrtIdx; +U8 *cntHqPrcs; +RgSchCellCb *cell; +#endif +{ + RgSchDlHqTbCb *tbCb; + RgSchDlHqProcCb *hqP; + CmLteTimingInfo schdSfTime; + RgSchTddDlAscSetIdxK ascIdx; + U8 noFdbks; + U8 i; + U8 idx; + U8 dlIdx; + CmLListCp *lnk; + CmLList *node; + + *cntHqPrcs = 0; + if (hqE->msg4Proc) + { + if (RGSCH_TIMEINFO_SAME(hqE->msg4Proc->tbInfo[0].fdbkTime, timeInfo)) + { + *isMsg4 = TRUE; + hqPrcs[*cntHqPrcs] = hqE->msg4Proc; + tbStrtIdx[*cntHqPrcs] = 0; + numTbs[*cntHqPrcs] = 1; + (*cntHqPrcs)++; + RETVALUE(ROK); + } + } + ascIdx = rgSchTddDlAscSetIdxKTbl[cell->ulDlCfgIdx][timeInfo.subframe]; + noFdbks = ascIdx.numFdbkSubfrms; + + for(idx=0; idxue->dl.dlSfHqInfo[dlIdx].hqPLst; + node = lnk->first; + while (node) + { + hqP = (RgSchDlHqProcCb*)node->node; + node = node->next; + + numTbs[*cntHqPrcs] = 0; + tbStrtIdx[*cntHqPrcs] = -1; + for (i = 0; i < 2; i++) + { + /* Extra:check which TB is waiting for feedback */ + if (hqP->tbInfo[i].state == HQ_TB_WAITING) + { + if (tbStrtIdx[*cntHqPrcs] == -1) + { + tbStrtIdx[*cntHqPrcs] = i; + } + numTbs[*cntHqPrcs]++; + } + } + if (numTbs[*cntHqPrcs] > 0) + { + hqPrcs[*cntHqPrcs] = hqP; + (*cntHqPrcs)++; + } + } + + /* AN REP Hq Procs */ + node = cell->subFrms[dlIdx]->ackNakRepQ.first; + while(node) + { + tbCb = (RgSchDlHqTbCb *)(node->node); + hqP = tbCb->hqP; + + numTbs[*cntHqPrcs] = 0; + tbStrtIdx[*cntHqPrcs] = -1; + for (i = 0; i < 2; i++) + { + /* Extra:check which TB is waiting for feedback */ + if (hqP->tbInfo[i].state == HQ_TB_WAITING) + { + if (tbStrtIdx[*cntHqPrcs] == -1) + { + tbStrtIdx[*cntHqPrcs] = i; + } + numTbs[*cntHqPrcs]++; + } + } + if (numTbs[*cntHqPrcs] == 2) + { + node = node->next; + } + if (numTbs[*cntHqPrcs] > 0) + { + hqPrcs[*cntHqPrcs] = hqP; + (*cntHqPrcs)++; + } + + node = node->next; + } + } + + + RETVALUE(ROK); +} +#else /* LTE_TDD */ +/** * @brief Handler for fetching Harq Proc given the timming information. + * + * @details + * + * Function : rgSCHDhmHqProcByTime + * + * This function shall fetch the harq proc using the timing information. + * + * @param[in] RgSchDlHqEnt *hqE + * @param[in] CmLteTimingInfo timeInfo + * @param[in] Bool *isMsg4 + * @param[out] U8 *numTbs + * @param[out] S8 *tbStrtIdx + * @return RgSchDlHqProcCb* + * -# RgSchDlHqProcCb* + * -# NULLP + **/ +#ifdef ANSI +PUBLIC RgSchDlHqProcCb *rgSCHDhmHqProcByTime +( +RgSchDlHqEnt *hqE, +CmLteTimingInfo timeInfo, +Bool *isMsg4, +RgSchDlSf *sf +) +#else +PUBLIC RgSchDlHqProcCb *rgSCHDhmHqProcByTime(hqE, timeInfo, + isMsg4,sf) +RgSchDlHqEnt *hqE; +CmLteTimingInfo timeInfo; +Bool *isMsg4; +RgSchDlSf *sf; +#endif +{ + if (hqE->msg4Proc) + { + if (RGSCH_TIMEINFO_SAME(hqE->msg4Proc->tbInfo[0].timingInfo, timeInfo)) + { + *isMsg4 = TRUE; + RETVALUE(hqE->msg4Proc); + } + } + + RETVALUE(NULLP); +} +#endif + +/** * @brief Handler for handling the harq transaction failure. + * + * @details + * + * Function : rgSCHDhmHqTbTrnsFail + * + * This function handled the harq TB transaction failure : + * - If retries have not reached maximum, add to the reTx Q. + * - else do error recovery. + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchDlHqProcCb *hqP + * @param[in] U8 tbCnt + * @param[out] Bool *isMaxRetx + * @return Void + * -#None. + * + **/ +#ifdef ANSI +PUBLIC Void rgSCHDhmHqTbTrnsFail +( +RgSchCellCb *cell, +RgSchDlHqProcCb *hqP, +U8 tbCnt, +Bool *isMaxRetx +) +#else +PUBLIC Void rgSCHDhmHqTbTrnsFail(cell, hqP, tbCnt, isMaxRetx) +RgSchCellCb *cell; +RgSchDlHqProcCb *hqP; +U8 tbCnt; +Bool *isMaxRetx; +#endif +{ + RgSchDlHqEnt *hqE; + U8 maxHqTx; + + TRC2(rgSCHDhmHqTbTrnsFail) + + hqE = hqP->hqE; + + /* Fetch the maximum number of harq transmissions */ + if (hqE->msg4Proc == hqP) + { +#ifdef RGR_V1 + if(hqP->hqE->raCb->expiryTime.sfn == RGSCH_CONTRES_EXP) + { + RLOG_ARG1(L_DEBUG,DBG_CELLID,cell->cellId, + "rgSCHDhmHqTbTrnsFail contRes exp(): tmpCRNTI = %u", + hqP->hqE->raCb->tmpCrnti); + rgSCHRamMsg4Done(cell, (RgSchRaCb *)hqP->hqE->raCb); + RETVOID; + } +#endif + maxHqTx = cell->dlHqCfg.maxMsg4HqTx; + } + else + { + maxHqTx = hqE->maxHqTx; + } + +#ifdef MAC_SCH_STATS + if (hqE->ue != NULLP) + { + RgSchUeCb *ueCb = hqE->ue; + RgSchCmnUe *cmnUe = (RgSchCmnUe*)ueCb->sch; + RgSchCmnDlUe *dlUe = RG_SCH_CMN_GET_DL_UE(ueCb,hqE->cell);/*CA dev*/ + U8 tbs = dlUe->mimoInfo.cwInfo[0].iTbs[0]; + static U32 retxCnt = 0; + + { + ++retxCnt; + hqFailStats.dlCqiStat[(dlUe->mimoInfo.cwInfo[0].cqi - 1)].numOfNacks++; + } + RG_SCH_CMN_DL_TBS_TO_MCS(tbs, + (hqFailStats.dlCqiStat[(dlUe->mimoInfo.cwInfo[0].cqi - 1)].mcs)); + } +#endif /* MAC_SCH_STATS */ + + RGSCH_ARRAY_BOUND_CHECK(cell->instIdx, hqP->tbInfo, tbCnt); + /* Reset the PDCCH reference */ + hqP->pdcch = NULL; + if (hqP->tbInfo[tbCnt].txCntr < maxHqTx) + { + hqP->tbInfo[tbCnt].state = HQ_TB_NACKED; + + if((hqE->ue != NULLP) && (hqE->ue->isDrxEnabled == TRUE)) + { + + /*If DRX is enabled for the UE, we need to start the HARQ RTT timer + * for the UE. Addtion to the retransmission queue will be done on + * HARQ RTT timer expiry.--*/ + switch(hqP->tbInfo[tbCnt ^ 1].state) + { + case HQ_TB_ACKED: + /*As the first TB is ACKED we have not started HARQ RTT for the + * HqP, so start it here.*/ + //cmLListDelFrm(&hqE->inUse, &hqP->lnk); + rgSCHDhmHqPDelFrmInUseLst(hqP); + /* CA Dev Start */ + rgSCHDrxStartHarqRTTTmr(hqP->hqE->ue->cell, hqP, tbCnt); + /* CA Dev End*/ +#ifdef LTEMAC_SPS + /* Integration fix */ + /* Setting cntrRetxAllocFail to MAX value here */ + /* Since the hqP entry is already deleted from inUse list of HqEntity + setting the value here will ensure the entry is not deleted + again during release harq proc */ + if ( (hqP->sch != (RgSchCmnDlHqProc *)NULLP) && + (RG_SCH_CMN_SPS_DL_IS_SPS_HQP(hqP))) + { + hqP->tbInfo[0].cntrRetxAllocFail = RG_SCH_MAX_RETX_ALLOC_FAIL; + if (hqP->tbInfo[1].txCntr) + { + hqP->tbInfo[1].cntrRetxAllocFail = RG_SCH_MAX_RETX_ALLOC_FAIL; + } + } +#endif + break; + case HQ_TB_NACKED: + /*As the first TB is NACKED we have already started HARQ RTT for the + * HqP, so dont start it here, just delete from in use queue.*/ + //cmLListDelFrm(&hqE->inUse, &hqP->lnk); + rgSCHDhmHqPDelFrmInUseLst(hqP); + break; + case HQ_TB_WAITING: + /*As this is the first TB to be fed back and is NACKED start + * the HARQ RTT here.*/ + /* CA Dev Start */ + rgSCHDrxStartHarqRTTTmr(hqP->hqE->ue->cell, hqP,tbCnt); + /* CA Dev End*/ + break; + } + RETVOID; + } + /* extra:check if already removed as part of other TB processing + * then donot remove from InUse Q */ + /* Check if other TB is not waiting for feedback. + * Makinf sure hqP is present in inUse Queue until + * it is fedback for all its TBs */ + switch(hqP->tbInfo[tbCnt ^ 1].state) + { + case HQ_TB_ACKED: + /*Fix for ccpu00113296 - Do not delete for Msg4 Harq Entities*/ + if(hqE->msg4Proc != hqP) + { + //cmLListDelFrm(&hqE->inUse, &hqP->lnk); + rgSCHDhmHqPDelFrmInUseLst(hqP); + } + /* Retransmission needs to be done. Add to the scheduler Q */ + rgSCHUtlDlProcAddToRetx(hqP->hqE->cell, hqP); + break; + case HQ_TB_NACKED: + /*Fix for ccpu00113296 - Do not delete for Msg4 Harq Entities*/ + if(hqE->msg4Proc != hqP) + { + //cmLListDelFrm(&hqE->inUse, &hqP->lnk); + rgSCHDhmHqPDelFrmInUseLst(hqP); + } + break; + case HQ_TB_WAITING: + /* Retransmission needs to be done. Add to the scheduler Q */ + /* CA Dev Start*/ + rgSCHUtlDlProcAddToRetx(hqP->hqE->cell, hqP); + /* CA Dev End*/ + break; + } + *isMaxRetx = FALSE; + } + else + { + /* Failure Notification */ + if (hqE->msg4Proc == hqP) + { + /* SR_RACH_STATS : MSG4 Max Retx Fail*/ + rgNumMsg4FailMaxRetx++; +#ifdef TENB_STATS + hqE->cell->tenbStats->sch.msg4Fail ++; +#endif + + /* Perform RAM MSG4 done processing */ + RLOG_ARG1(L_DEBUG,DBG_CELLID,cell->cellId, + "rgSCHDhmHqTbTrnsFail(): hq max retx fail: tmpCRNTI = %u", + hqP->hqE->raCb->tmpCrnti); + rgSCHRamMsg4Done(cell, (RgSchRaCb *)hqP->hqE->raCb); + } + else + { + /* Release the Harq Proc */ + rgSCHDhmRlsHqpTb(hqP, tbCnt, TRUE); + } + *isMaxRetx = TRUE; + } + + RETVOID; +} /* rgSCHDhmHqTbTrnsFail */ + +PUBLIC U32 rgHqRvStats[2][4][2] = {{{0, 0}, {0, 0}, {0, 0}, {0, 0}}, + {{0, 0}, {0, 0}, {0, 0}, {0, 0}}}; +#ifdef LTE_TDD +#ifdef LTE_ADV +/** * @brief Function to decode the position of HarqFb for M=1. + * + * @details + * + * Function : rgSchGetHqFdbkPosForM1 + * + * @param[in] RgSchUeCb *ue, + * @param[in] RgSchDlHqProcCb *hqP, + * @param[in] U8 *isAck, + * @param[in] RgTfuHqInfo *fdbk, + * @param[in] U8 tbIdx, + * @param[in] RgSchTddANInfo *anInfo; + * @return RETVOID + **/ +#ifdef ANSI +PRIVATE Void rgSchGetHqFdbkPosForM1 +( + RgSchUeCb *ue, + RgSchDlHqProcCb *hqP, + U8 *isAck, + RgTfuHqInfo *fdbk, + U8 tbIdx, + RgSchTddANInfo *anInfo + ) +#else +PRIVATE Void rgSchGetHqFdbkPosForM1(ue,hqP,isAck,fdbk,tbIdx,anInfo) + RgSchUeCb *ue; + RgSchDlHqProcCb *hqP; + U8 *isAck; + RgTfuHqInfo *fdbk; + U8 tbIdx; + RgSchTddANInfo *anInfo; +#endif +{ + if((ue != NULLP)) + { + /* handle pusch and pucch cases */ + /* PUSCH:: Fdbks are in the increasing order + * of servCellIdx as per 36.212 section 5.2.26*/ + switch(ue->f1bCsAVal) + { + case RG_SCH_A_VAL_2: + { + if(RG_SCH_IS_CELL_SEC(ue,hqP->hqE->cell)) + { + *isAck = fdbk->isAck[1];/*SCell*/ + } + else + { + *isAck = fdbk->isAck[0];/*PCell*/ + } + break; + } + case RG_SCH_A_VAL_3: + { + if(RG_SCH_IS_CELL_SEC(ue,hqP->hqE->cell)) + { + U8 cellIdx = rgSchUtlGetServCellIdx(hqP->hqE->cell->instIdx, + hqP->hqE->cell->cellId, + hqP->hqE->ue); + + if(rgSCHUtlGetMaxTbSupp(ue->cellInfo[cellIdx]->txMode.txModeEnum) > 1) + {/*SCell - mimo mode*/ + if(TRUE == fdbk->isPusch) + { + *isAck = fdbk->isAck[tbIdx + 1]; + } + else + { + *isAck = fdbk->isAck[tbIdx]; + } + } + else + {/*SCell - siso mode*/ + *isAck = fdbk->isAck[2]; + } + }else + { + if(rgSCHUtlGetMaxTbSupp(ue->mimoInfo.txMode) > 1) + {/*Primary Cell - mimo mode*/ + *isAck = fdbk->isAck[tbIdx]; + } + else + {/*Primary Cell - siso mode*/ + if((TRUE == fdbk->isPusch) && (FALSE == anInfo->isSpsOccasion)) + { + /* If fdbk is on PUSCH but its not an SPS occasion*/ + *isAck = fdbk->isAck[0]; + } + else + { + /* If fdbk is on PUCCH or its an SPS occasion*/ + *isAck = fdbk->isAck[2]; + } + } + } + break; + } + case RG_SCH_A_VAL_4: + { + if(RG_SCH_IS_CELL_SEC(ue,hqP->hqE->cell)) + { + *isAck = fdbk->isAck[tbIdx + 2]; + } + else + { + *isAck = fdbk->isAck[tbIdx]; + } + break; + } + default: + break; + } + } + RETVOID; +}/* End of rgSchGetHqFdbkPosForM1 */ + +/** * @brief Function to decode the position of HarqFb for M>=2 cases. + * + * @details + * + * Function : rgSchGetHqFdbkPosForM234 + * + * @param[in] RgSchUeCb *ue, + * @param[in] RgSchDlHqProcCb *hqP, + * @param[in] U8 *isAck, + * @param[in] RgTfuHqInfo *fdbk, + * @param[in] U8 tbIdx, + * @param[in] RgSchTddANInfo *anInfo; + * @param[in] CmLteTimingInfo timeInfo; + * @return RETVOID + **/ +#ifdef ANSI +PRIVATE Void rgSchGetHqFdbkPosForM234 +( + RgSchUeCb *ue, + RgSchDlHqProcCb *hqP, + U8 *isAck, + RgTfuHqInfo *fdbk, + U8 tbIdx, + RgSchTddANInfo *anInfo, + U8 M, + CmLteTimingInfo timeInfo + ) +#else +PRIVATE Void rgSchGetHqFdbkPosForM234(ue,hqP,isAck,fdbk,tbIdx,anInfo,M,timeInfo) + RgSchUeCb *ue; + RgSchDlHqProcCb *hqP; + U8 *isAck; + RgTfuHqInfo *fdbk; + U8 tbIdx; + RgSchTddANInfo *anInfo; + U8 M; + CmLteTimingInfo timeInfo; +#endif +{ + U8 fdbkIdx; + Bool isSCell; + RgSchTddANInfo *pCellAnInfo; + U8 incr = 0; + + if(NULLP != ue) + { + isSCell = RG_SCH_IS_CELL_SEC(ue,hqP->hqE->cell); + pCellAnInfo = rgSCHUtlGetUeANFdbkInfo(ue, &timeInfo, RGSCH_PCELL_INDEX); + + if(TRUE == fdbk->isPusch) + { + if(TRUE == isSCell) + {/*SCell*/ + if (anInfo->wUlDai == 3) + { + incr = anInfo->wUlDai; + } + else + { + incr = M; + } + if(1 == anInfo->ulDai) + { + fdbkIdx = (hqP->tbInfo[tbIdx].dai - 1) + + hqP->tbInfo[tbIdx].tbIdx + incr; + } + else + { + fdbkIdx = (hqP->tbInfo[tbIdx].dai - 1) + incr; + } + } + else + {/*PCell*/ + if(1 == anInfo->ulDai) + { + if(rgSCHUtlGetMaxTbSupp(ue->mimoInfo.txMode) > 1) + { + fdbkIdx = (hqP->tbInfo[tbIdx].dai - 1) + (hqP->tbInfo[tbIdx].tbIdx); + } + else + { + fdbkIdx = (hqP->tbInfo[tbIdx].dai) - 1; + } + } + else + { + fdbkIdx = (hqP->tbInfo[tbIdx].dai) - 1; + } + } + } + else + {/*PUCCH*/ + if(TRUE == isSCell) + { + /* pucchFdbkIdx is set to DAI hence -1 to get index */ + fdbkIdx = ((hqP->tbInfo[tbIdx].pucchFdbkIdx) + M -1); + } + else + { + if(M > 2) + { + /* SPS occasion feedback in case of M > 2 will + * be always present in the index 0*/ +#ifdef LTEMAC_SPS + if(hqP->spsN1PucchRes.pres == TRUE) + {/* SPS occasion hq proc */ + fdbkIdx = 0; + }else +#endif + if((NULLP != pCellAnInfo) && + (pCellAnInfo->dlDai != pCellAnInfo->ulDai)) + { + fdbkIdx = hqP->tbInfo[tbIdx].pucchFdbkIdx; + }else + {/* NO SPS occasion was present in the bundle*/ + fdbkIdx = hqP->tbInfo[tbIdx].pucchFdbkIdx - 1; + } + } + else + { + fdbkIdx = hqP->tbInfo[tbIdx].pucchFdbkIdx - 1; + } + } + } + *isAck = fdbk->isAck[fdbkIdx]; +#ifdef DLHQ_STATS + static RgSchDlHqProcCb *temp = NULLP; + if (temp != hqP->tbInfo[tbIdx].hqP) + { + statsCnt = statsCnt % 10000; + dlHqStats[statsCnt].cellId = hqP->hqE->cell->cellId; + dlHqStats[statsCnt].sfn = hqP->tbInfo[tbIdx].timingInfo.sfn; + dlHqStats[statsCnt].sf = hqP->tbInfo[tbIdx].timingInfo.subframe; + dlHqStats[statsCnt].ack = *isAck; + dlHqStats[statsCnt].fdbkIdx = fdbkIdx; + dlHqStats[statsCnt].ue = hqP->hqE->ue->ueId;; + if (anInfo) + dlHqStats[statsCnt].ulDai = incr; + if(TRUE == fdbk->isPusch) + { + dlHqStats[statsCnt].dlDai = hqP->tbInfo[tbIdx].dai; + } + else + { + dlHqStats[statsCnt].dlDai = hqP->tbInfo[tbIdx].pucchFdbkIdx; + } + if (*isAck != 1) + { + dlHqStats[statsCnt].ack0 = fdbk->isAck[0]; + dlHqStats[statsCnt].ack1 = fdbk->isAck[1]; + dlHqStats[statsCnt].ack2 = fdbk->isAck[2]; + dlHqStats[statsCnt].ack3 = fdbk->isAck[3]; + dlHqStats[statsCnt].ack4 = fdbk->isAck[4]; + dlHqStats[statsCnt].ack5 = fdbk->isAck[5]; + dlHqStats[statsCnt].ack6 = fdbk->isAck[6]; + dlHqStats[statsCnt].ack7 = fdbk->isAck[7]; + } + statsCnt++; + temp = hqP->tbInfo[tbIdx].hqP; + } +#endif + }/*ue*/ + RETVOID; +}/*rgSchGetHqFdbkPosForM234*/ +#endif/*LTE_ADV*/ + +/* + * @brief Handler for HARQ feedback received for DL transmission. + * + * @details + * + * Function : rgSCHDhmHqFdbkInd + * + * This function shall act on the feedback received from TOM for DL + * transmission. If the feedback for msg4 is final (after max transmissions + * or ACK) inform RAM that Msg4 transmission is done. + * + * + * @param[in] Void *cb + * @param[in] U8 cbType + * @param[in] RgSchCellCb cellCb + * @param[in] CmLteTimingInfo timeInfo + * @param[in] TfuHqInfo *fdbk + * @param[in] RgInfRlsHqInfo *rlsHqBufs + * @param[in] RgSchErrInfo *err + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 rgSCHDhmHqFdbkInd +( +Void *cb, +U8 cbType, +RgSchCellCb *cellCb, +CmLteTimingInfo timeInfo, +TfuHqInfo *fdbk, +RgInfRlsHqInfo *rlsHqBufs, +RgSchErrInfo *err +) +#else +PUBLIC S16 rgSCHDhmHqFdbkInd(cb, cbType, cellCb, timeInfo, fdbk, rlsHqBufs, err) +Void *cb; +U8 cbType; +RgSchCellCb *cellCb; +CmLteTimingInfo timeInfo; +TfuHqInfo *fdbk; +RgInfRlsHqInfo *rlsHqBufs; +RgSchErrInfo *err; +#endif +{ + RgSchCellCb *sCell = NULLP; + RgSchDlHqEnt *hqE; + /*ccpu00127339 - MOD - change to avoid the crash*/ + RgSchUeCb *ue = NULLP; + RgSchDlSf *sf; + Bool isMsg4 = FALSE; + RgSchRaCb *raCb = NULLP; + U16 rnti=0; + /* Maximum possible HARQ processes in UL-DL configuration 5 that is + * given feedback at a time */ + RgSchDlHqProcCb *hqPrcs[(RGSCH_NUM_SUB_FRAMES-1)*5]; /*MAX 5 Cells*/ + U8 numTb[(RGSCH_NUM_SUB_FRAMES-1)*5]; + S8 tbStrtIdx[(RGSCH_NUM_SUB_FRAMES-1)*5]; + U8 hqCnt; + U8 idx; + RgSchTddANInfo *anInfo = NULLP; + U8 isAck = 0; + U8 tbCnt; + RgrTddAckNackMode ackNackMode; + Bool hqRls = FALSE; + RgSchDlSf *nxtDlsf = NULLP; + /* U8 rcvCnt = 0; */ + CmLteTimingInfo nxtfrm = {0,0}; + Bool anUpd = FALSE; + Bool maxHqRetxReached; +#ifdef LTEMAC_SPS + Bool hasRelPdcch = FALSE; +#endif + +#if ((defined LTEMAC_SPS_AN_MUX) || (defined LTE_ADV)) + RgSchTddDlAscSetIdxK ascIdx; + U8 noFdbks; +#endif + +#ifdef LTEMAC_SPS_AN_MUX + Bool isPusch = FALSE; + U8 tmpIdx; + U8 hIdx; + /* Subframes in which transmissions are scheduled and whose feedback can come + * in this subframe. Used only for Multiplexing mode */ + CmLteTimingInfo schdSfTime[RGSCH_TDD_MAX_FDBK]; +#ifdef RGSCH_SPS_STATS + RgSchCmnDlHqProc *cmnHqDl; +#endif +#endif +#ifdef LTE_ADV + U8 sCellActCePres = 0; +#endif +/* LTEMAC_SPS_AN_MUX*/ + RgrSchFrmt1b3TypEnum uciFrmtTyp = RG_SCH_UCI_FORMAT1A_1B; + TRC2(rgSCHDhmHqFdbkInd) + + if (cbType == RGSCH_HQ_FDB_IND_CB_TYPE_RA_CB) + { + raCb = (RgSchRaCb *)(cb); + ackNackMode = RGR_TDD_ACKNACK_MODE_BUNDL; + hqE = raCb->dlHqE; + /* ccpu00139061 Fix */ + rnti = raCb->tmpCrnti; + } + else + { + ue = (RgSchUeCb *)(cb); + ackNackMode = ue->dl.ackNackMode; + hqE = RG_SCH_CMN_GET_UE_HQE(ue, cellCb); + rnti = ue->ueId; +#ifdef LTEMAC_SPS_AN_MUX + isPusch = fdbk->isPusch; +#endif + +#ifdef LTEMAC_SPS + if (RGSCH_TIMEINFO_SAME(timeInfo, ue->relPdcchFbkTiming)) + { + hasRelPdcch = TRUE; + } +#endif + } + +#if ((defined LTEMAC_SPS_AN_MUX) || (defined LTE_ADV)) + ascIdx = rgSchTddDlAscSetIdxKTbl[cellCb->ulDlCfgIdx][timeInfo.subframe]; + noFdbks = ascIdx.numFdbkSubfrms; +#endif +#ifdef LTEMAC_SPS_AN_MUX + /* Calculate the subframe time at which transmissions should have happened to + * receive feedback in this subframe */ + if (ackNackMode == RGR_TDD_ACKNACK_MODE_MULT) + { + for(idx=0; idxcell); + /* Fetch the harqProc from the inUse list */ +#ifdef LTEMAC_SPS + if ((FALSE == hasRelPdcch) && (hqCnt == 0)) +#endif + if(hqCnt == 0) + { + err->errType = RGSCHERR_DHM_FDBK_IND; + err->errCause = RGSCHERR_DHM_FDBK_IND_INVALID_CB; + RETVALUE(RFAILED); + } + + /* ccpu00147469 : This code is moved below as here this code always try to + * get the primary cell aninfo. it is due to hqE->cell->cellId as it is + * cellId of PCEll + */ + + if(fdbk->hqFdbkMode == TFU_ACK_NACK_SPECIAL_BUNDLING) + { + rgSCHDhmPrcSplBundlFdbk(cellCb, fdbk, hqCnt); + } + +#ifdef TFU_TDD +#endif + +#ifdef LTEMAC_SPS_AN_MUX + /* Check if feedback came on configured UL SPS grant in Muxing mode */ + if((ackNackMode == RGR_TDD_ACKNACK_MODE_MULT) && + (isPusch == TRUE) ) + { + hIdx = 0; + /* Pick the valid feedbacks out of M feedbacks */ + for(idx=0; idx\ + tbInfo[(S16)(tbStrtIdx[hIdx])].timingInfo,\ + schdSfTime[idx])) && + !RGSCH_TIMEINFO_SAME(ue->relPdcchTxTime, schdSfTime[idx])) + { + /* Discard the feedback which is corresponding to a subframe in + * which no DL transmission took place */ + tmpIdx = idx+1; + while(tmpIdx < noFdbks) + { + fdbk->isAck[tmpIdx-1] = fdbk->isAck[tmpIdx]; + fdbk->isAck[tmpIdx-1] = fdbk->isAck[tmpIdx]; + tmpIdx++; + } + rcvCnt--; + ++hIdx; + } + } /* end of for loop */ + } /* end of configured UL SPS grant check */ +#endif +#ifdef CA_DBG + { + if(ue) + { + gHqFdbkCount++; + } + } + +#endif + + for(idx=0;idx < hqCnt; idx++) + { + /* Fix for CR ccpu00147469: Get the anInfo for each harq proc */ + if(ue) + { +#ifdef LTE_ADV + U8 servCellIdx = rgSchUtlGetServCellIdx(hqPrcs[idx]->hqE->cell->instIdx, + hqPrcs[idx]->hqE->cell->cellId,ue); + + if(ue->cellInfo[servCellIdx]->sCellState != RG_SCH_SCELL_ACTIVE) + { + continue; + } + anInfo = rgSCHUtlGetUeANFdbkInfo(ue, &timeInfo,servCellIdx); +#else + anInfo = rgSCHUtlGetUeANFdbkInfo(ue, &timeInfo,RGSCH_PCELL_INDEX); +#endif + if(anInfo == NULLP) + { + RGSCHDBGINFO(cellCb->instIdx,(rgSchPBuf(cellCb->instIdx), + "Ack Rcvd. No Ack/Nack feedback available \n")); + RETVALUE(RFAILED); + } + } + + sCell = hqPrcs[idx]->hqE->cell; + rlsHqBufs = &(sCell->rlsHqArr[sCell->crntHqIdx]); + rlsHqBufs->ueHqInfo[rlsHqBufs->numUes].numOfTBs = 0; + for (tbCnt = tbStrtIdx[idx]; (tbCnt-tbStrtIdx[idx]) < numTb[idx]; tbCnt++) + { + /* Fix : syed MultiUe per TTI crash in TA List. */ + hqRls = FALSE; + maxHqRetxReached = FALSE; + /* Remove the harq process from the subframe */ + sf = rgSCHUtlSubFrmGet(cellCb, hqPrcs[idx]->tbInfo[tbCnt].timingInfo); + + if(NULLP != ue) + { + uciFrmtTyp = ue->dl.dlSfHqInfo[cellCb->cellId][sf->dlIdx].uciFrmtTyp; + } + + if(uciFrmtTyp != RG_SCH_UCI_FORMAT1B_CS) + { + if((fdbk->hqFdbkMode != TFU_ACK_NACK_SPECIAL_BUNDLING)&& + (RGR_TDD_ACKNACK_MODE_MULT == ackNackMode)) + { + isAck = fdbk->isAck[hqPrcs[idx]->tbInfo[tbCnt].m]; + } + else + { + /* TODO: review for TM4 and CA interaction */ + if((TRUE == hqPrcs[idx]->cwSwpEnabled) && (1 < numTb[idx])) + { + isAck = fdbk->isAck[!tbCnt]; + } + else + { + isAck = fdbk->isAck[tbCnt]; + } + } + } +#ifdef LTE_ADV + else + { + if(1 == noFdbks) + {/* M == 1 case */ + rgSchGetHqFdbkPosForM1(ue, hqPrcs[idx], &isAck, fdbk, tbCnt, anInfo); + } + else + { + rgSchGetHqFdbkPosForM234(ue, hqPrcs[idx], &isAck, fdbk, tbCnt, anInfo, noFdbks, timeInfo); + } + } +#endif + +#ifdef BRDCM + /* revanth tweakin AN PUSCH to ACK always */ + if (hqPrcs[idx]->isPuschFdbk) + { + isAck = 1; + } +#endif + + hqPrcs[idx]->tbInfo[tbCnt].isAckNackDtx = isAck; + if(cellCb->ulDlCfgIdx != 5) + { + rgSCHUtlGetNxtDlSfInfo(hqPrcs[idx]->tbInfo[tbCnt].timingInfo,\ + cellCb, sf, &nxtDlsf, &nxtfrm); + } + /* Keep a tab on how many ACKs or NACKs we have received */ + if (isAck == TFU_HQFDB_ACK) + { + hqPrcs[idx]->tbInfo[tbCnt].ackCount += 1; /* Ack counter */ + rgHqRvStats[tbCnt][hqPrcs[idx]->tbInfo[tbCnt].dlGrnt.rv][0]++; +#ifdef TENB_STATS + sCell->tenbStats->sch.dlAckNack[tbCnt]\ + [hqPrcs[idx]->tbInfo[tbCnt].dlGrnt.rv]++; +#endif + /* Do not update the Ul Trans Time in case of raCb */ + if (ue) + { + rgSCHUtlHdlUlTransInd(cellCb, ue, timeInfo); +#ifdef TENB_STATS + ue->tenbStats->stats.nonPersistent.sch[RG_SCH_CELLINDEX(sCell)].dlAckNackCnt[tbCnt] ++; +#endif + } + } + else if (isAck == TFU_HQFDB_NACK) + { + hqPrcs[idx]->tbInfo[tbCnt].nackCount += 1; /* Nack Counter */ + rgHqRvStats[tbCnt][hqPrcs[idx]->tbInfo[tbCnt].dlGrnt.rv][1]++; +#ifdef TENB_STATS + sCell->tenbStats->sch.dlNack[tbCnt]\ + [hqPrcs[idx]->tbInfo[tbCnt].dlGrnt.rv]++; + sCell->tenbStats->sch.dlAckNack[tbCnt]\ + [hqPrcs[idx]->tbInfo[tbCnt].dlGrnt.rv]++; +#endif + /* Do not update the Ul Trans Time in case of raCb */ + if (ue) + { + rgSCHUtlHdlUlTransInd(cellCb, ue, timeInfo); +#ifdef TENB_STATS + ue->tenbStats->stats.nonPersistent.sch[RG_SCH_CELLINDEX(sCell)].dlNackCnt[tbCnt] ++; + ue->tenbStats->stats.nonPersistent.sch[RG_SCH_CELLINDEX(sCell)].dlAckNackCnt[tbCnt] ++; +#endif + } +#ifdef LTE_L2_MEAS + if(hqPrcs[idx]->tbInfo[tbCnt].txCntr == 1) + { + cellCb->dlUlTbCnt.tbTransDlFaulty++; + } +#endif + } + else + { + hqPrcs[idx]->tbInfo[tbCnt].dtxCount += 1; /* DTX Counter*/ +#ifdef TENB_STATS + sCell->tenbStats->sch.dlDtx[tbCnt]\ + [hqPrcs[idx]->tbInfo[tbCnt].dlGrnt.rv]++; + if (ue) + { + ue->tenbStats->stats.nonPersistent.sch[RG_SCH_CELLINDEX(sCell)].dlDtxCnt[tbCnt] ++; + } +#endif +#ifdef LTE_L2_MEAS + if(hqPrcs[idx]->tbInfo[tbCnt].txCntr == 1) + { + cellCb->dlUlTbCnt.tbTransDlFaulty++; + } +#endif + } +#ifdef CA_DBG + if(ue && RG_SCH_IS_CELL_SEC(ue,hqPrcs[idx]->hqE->cell)) + { + if(isAck == TFU_HQFDB_ACK) + { + gSCellTb1AckCount++; + gSCellTb2AckCount++; + }else if(isAck == TFU_HQFDB_NACK) + { + gSCellTb1NackCount++; + gSCellTb2NackCount++; + }else + { + gSCellTb1DtxCount++; + gSCellTb2DtxCount++; + } + } + else + { + if(isAck == TFU_HQFDB_ACK) + { + gPCellTb1AckCount++; + gPCellTb2AckCount++; + }else if(isAck == TFU_HQFDB_NACK) + { + gPCellTb1NackCount++; + gPCellTb2NackCount++; + }else + { + gPCellTb1DtxCount++; + gPCellTb2DtxCount++; + } + } +#endif + /* Check if this is repeating UE */ + if (hqPrcs[idx]->tbInfo[tbCnt].fbkRepCntr != 0) + { + rgSCHUtlDlHqPTbRmvFrmTx(sf, hqPrcs[idx], tbCnt, TRUE); + /* Check if last repetition */ + if (--hqPrcs[idx]->tbInfo[tbCnt].fbkRepCntr) + { + RGSCH_NULL_CHECK(cellCb->instIdx, nxtDlsf); + /* Update feedback time for this hqP TB so that + * next subframe its picked up */ + RGSCH_UPD_HQAN_FDBKTIME(&hqPrcs[idx]->tbInfo[tbCnt],\ + nxtDlsf, nxtfrm); + RGSCH_NULL_CHECK(cellCb->instIdx, anInfo); + RGSCH_UPD_ANINFO_WITH_HQ(anInfo, &hqPrcs[idx]->tbInfo[tbCnt]); + anUpd = TRUE; + continue; + } + /* For a repeating UE take the decision here */ + /* For a repeating UE take the decision here */ + if (((hqPrcs[idx]->tbInfo[tbCnt].ackCount) > (hqPrcs[idx]->tbInfo[tbCnt].nackCount)) && + ((hqPrcs[idx]->tbInfo[tbCnt].ackCount) > (hqPrcs[idx]->tbInfo[tbCnt].dtxCount))) + { + isAck = TFU_HQFDB_ACK; + } + else if (((hqPrcs[idx]->tbInfo[tbCnt].dtxCount) > (hqPrcs[idx]->tbInfo[tbCnt].nackCount)) && + ((hqPrcs[idx]->tbInfo[tbCnt].dtxCount) > (hqPrcs[idx]->tbInfo[tbCnt].ackCount))) + { + isAck = TFU_HQFDB_DTX; + } + else + { + isAck = TFU_HQFDB_NACK; + } + hqPrcs[idx]->tbInfo[tbCnt].isAckNackDtx = isAck; + } + else + { + rgSCHUtlDlHqPTbRmvFrmTx(sf, hqPrcs[idx], tbCnt, FALSE); + } +#ifdef LTEMAC_SPS + if (((isAck == TFU_HQ_NACK) || (isAck == TFU_HQ_ACK)) && + ((hqPrcs[idx]->sch != (RgSchCmnDlHqProc *)NULLP) && + (RG_SCH_CMN_SPS_DL_IS_SPS_TX_HQP(hqPrcs[idx]))) + ) + { + /* ACK or NACK received for SPS ACTV PDCCH + * Hence consider SPS ACTVN PDCCH received successfully */ + rgSCHUtlDlProcAck(cellCb, hqPrcs[idx]); + } +#endif + if(TFU_HQFDB_ACK == isAck) + { + /* SPS_REVIEW */ + if (isMsg4 == TRUE) + { + if (raCb == NULLP) + { + raCb = rgSCHDbmGetRaCb(cellCb, rnti); + } + /* Inform Random Access Module regarding the ack received */ + if (raCb != NULLP) + { + /*RRC Connection Setup failure issue where RRC connection + * setup was not reaching UE due to message 4 HARQ failure */ +#ifdef XEON_SPECIFIC_CHANGES + CM_LOG_DEBUG(CM_LOG_ID_SCH, "Msg4 Harq SUCCESS for UE(%d)\n", rnti); +#endif + rgSCHRamMsg4Done(cellCb, raCb); + } + } + else /*ccpu00114124- HARQ Release for Msg4 */ + { +#ifdef DL_LA + /*Update feedback history for every Tx/Retx */ + rgSCHDhmUpdateAckNackHistory(sCell, ue, isAck, tbCnt); +#endif + RGSCH_NULL_CHECK(cellCb->instIdx, ue); + RG_UPD_ACQI_TRIG_WT(ue, sCell, isAck); +#ifdef LTE_ADV + /* Store activation CE presence as it is required later to start + *activation delay timer */ + sCellActCePres = hqPrcs[idx]->tbInfo[tbCnt].schdSCellActCe.pres; +#endif + rgSCHDhmRlsHqpTb(hqPrcs[idx], tbCnt, TRUE); + } + hqRls = TRUE; + } + else + { + /* If this Msg4 DTX, there will be + * no DlHqProc as it has its own HarqProc */ + /* SPS_REVIEW */ + { + rgSCHDhmHqTbTrnsFail(cellCb, hqPrcs[idx], tbCnt, &hqRls); + maxHqRetxReached = hqRls; +#ifdef DL_LA + if ((isMsg4 == FALSE)) + { + /*Update feedback history for every Tx/Retx */ + rgSCHDhmUpdateAckNackHistory(sCell, ue, isAck, tbCnt); + } +#endif + if (isMsg4 == FALSE) + { + RGSCH_NULL_CHECK(cellCb->instIdx, ue); + RG_UPD_ACQI_TRIG_WT(ue, sCell, isAck); + } + } + } + + if(TRUE == hqRls) + { + /* MS_WORKAROUND: to increase Harq Fail Counter . + The status field is required for tracking the number of harq faliures at MAC*/ + if (isAck) + { + rlsHqBufs->ueHqInfo[rlsHqBufs->numUes].status[\ + rlsHqBufs->ueHqInfo[rlsHqBufs->numUes].numOfTBs] = TRUE; + } + else + { + rlsHqBufs->ueHqInfo[rlsHqBufs->numUes].status[\ + rlsHqBufs->ueHqInfo[rlsHqBufs->numUes].numOfTBs] = FALSE; + } + rlsHqBufs->ueHqInfo[rlsHqBufs->numUes].tbId[\ + rlsHqBufs->ueHqInfo[rlsHqBufs->numUes].numOfTBs] = tbCnt + 1; + rlsHqBufs->ueHqInfo[rlsHqBufs->numUes].numOfTBs++; + } + + /* Handle the TA */ + if (hqPrcs[idx]->tbInfo[tbCnt].taSnt == TRUE) + { + rgSCHDhmFdbkIndHndlTa(hqPrcs[idx], tbCnt, isAck, maxHqRetxReached); + } +#ifdef LTE_ADV + /* Handle Scell activation */ + if (TRUE == sCellActCePres) + { + /* Primary Cellcb needs to be retrived + * if the feedback is coming on pusch of + * sec cell. THis needs to be considered + * while UL_CA*/ + rgSCHSCellHndlFdbkInd(hqPrcs[idx], tbCnt, isAck, maxHqRetxReached); + } +#endif + } + if (hqRls == FALSE) + { + hqPrcs[idx]->cwSwpEnabled = FALSE; + } + if(rlsHqBufs->ueHqInfo[rlsHqBufs->numUes].numOfTBs) + { + rlsHqBufs->ueHqInfo[rlsHqBufs->numUes].rnti = rnti; + rlsHqBufs->ueHqInfo[rlsHqBufs->numUes].hqProcId = + hqPrcs[idx]->procId; + rlsHqBufs->numUes++; + } +#ifdef BRDCM + hqPrcs[idx]->isPuschFdbk = 0; +#endif + } + +#ifdef LTEMAC_SPS + /*it is possible for some TDD configurations (like TDD cfg 5) + * to have multiple feedback for 13 subframes before. It is + * possible in such a case to have a release sent after data + * thus running into a situation where we are receiving feedback + * for both data and relese pdcch + */ +/* + if ( (hqCnt == 0) || + (hasRelPdcch && rcvCnt > hqCnt) + ) + */ + if (ue && hasRelPdcch) + { + /* Bool found = FALSE; */ + + sf = rgSCHUtlSubFrmGet(cellCb, ue->relPdcchTxTime); + + /* + if ( !sf->relPdcch) + { + found = FALSE; + } + */ + + +#if ((defined LTEMAC_SPS_AN_MUX) || (defined LTE_ADV)) + if(ackNackMode == RGR_TDD_ACKNACK_MODE_MULT) + { + CmLteTimingInfo txTime; + U8 ulDlCfgIdx = 0; + U8 maxFdbks = 0; + U8 itr = 0; + + ulDlCfgIdx = cellCb->ulDlCfgIdx; + + maxFdbks = rgSchTddDlAscSetIdxKTbl[ulDlCfgIdx] + [timeInfo.subframe]. + numFdbkSubfrms; + + for(itr=0; itr< maxFdbks; itr++) + { +#ifdef LTE_ADV + /* Handling the case of only SPS release pdcch + * and no other scheduling in both the serving cells + * */ + if(ue->uciFrmtTyp == RG_SCH_UCI_FORMAT1B_CS) + {/* Using the sorted K table */ + RGSCHDECRFRMCRNTTIME (timeInfo, txTime, + rgSchTddDlHqPucchResCalTbl[ulDlCfgIdx][timeInfo.subframe].subfrmNum[itr]); + }else +#endif + { + RGSCHDECRFRMCRNTTIME (timeInfo, txTime, + rgSchTddDlAscSetIdxKTbl[ulDlCfgIdx][timeInfo.subframe].subfrmNum[itr]); + } + + if (RGSCH_TIMEINFO_SAME (txTime, ue->relPdcchTxTime)) + { +#ifdef LTE_ADV + if((ue->uciFrmtTyp == RG_SCH_UCI_FORMAT1B_CS)&& + (maxFdbks == 1)) + {/* M == 1 case */ + if(rgSCHUtlGetMaxTbSupp(ue->mimoInfo.txMode) > 1) + { + isAck = fdbk->isAck[0]; + }else + { + isAck = fdbk->isAck[2]; + } + } + else + /* M > 1 same below logic apply. + If SPS occasion and rel pdcch is present + SPS occasion after SPS release cannot + happen in a bundle + */ +#endif + { + isAck = fdbk->isAck[itr]; + } + + rgSCHUtlDlRelPdcchFbk(cellCb, ue, isAck); + + RGSCH_NULL_CHECK(cellCb->instIdx, sf->relPdcch); + /* Remove release PDCCH from the subframe */ + rgSCHUtlPdcchPut(cellCb, &sf->pdcchInfo, sf->relPdcch); + sf->relPdcch = NULLP; + /* found = TRUE; */ + break; + } + + } + } + else +#endif + { + RGSCH_NULL_CHECK(cellCb->instIdx, sf->relPdcch); + /* Remove release PDCCH from the subframe */ + rgSCHUtlPdcchPut(cellCb, &sf->pdcchInfo, sf->relPdcch); + sf->relPdcch = NULLP; + /* found = TRUE; */ + rgSCHUtlDlRelPdcchFbk(cellCb, ue, fdbk->isAck[0]); + } + /* + if ( found == FALSE ) + { + RGSCH_NULL_CHECK(cellCb->instIdx, ue); + RLOG_ARG3(L_ERROR,DBG_CELLID,cellCb->cellId,"CRNTI:%d" + " NO HARQ proc available for feedback:timeInfo:snf %d,subframe %d", + ue->ueId,timeInfo.sfn, timeInfo.subframe); + err->errType = RGSCHERR_DHM_FDBK_IND; + err->errCause = RGSCHERR_DHM_FDBK_IND_INVALID_CB; + RETVALUE(RFAILED); + } + */ + }/*if(hqCnt==0)*/ +#endif /* LTEMAC_SPS */ + /* Initialise the Ack/Nack feedback */ + /* [ccpu00127651] - MOD For Msg4 Harq Proc, anInfo will not be filled while + scheduling. So added a condition !isMsg4 to avoid calling the function + rgSCHUtlInitUeANFdbkInfo*/ + if((ue) && (!anUpd) && (!isMsg4)) + { +#ifdef LTE_ADV + /* TODO:: Initi the anInfo all the serving cells */ + for(idx = 0; idx <= RG_SCH_MAX_SCELL; idx++) + { + if(ue->cellInfo[idx]) + { + anInfo = rgSCHUtlGetUeANFdbkInfo(ue, &timeInfo,idx); + /* Fix for CR ccpu00147693: If anInfo is there then initialize it + * else don't do anything. basically continue for next serving + * cell*/ + if(anInfo) + { + rgSCHUtlInitUeANFdbkInfo(anInfo); + } + } + } +#else + rgSCHUtlInitUeANFdbkInfo(anInfo); +#endif + } + + RETVALUE(ROK); +} +//#endif /* LTEMAC_SPS */ + +#else /* LTE_TDD */ +/** * @brief Handler for HARQ feedback received for DL transmission. + * + * @details + * + * Function : rgSCHDhmPrcFdbkForTb + * + * Process Hq Prc Fdbk for a TB + * + * @param[in] RgSchCellCb *cell + * @param[in] RgTfuHarqAckIndInfo *fdbk + * @param[in] RgSchErrInfo *err + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 rgSCHDhmPrcFdbkForTb +( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgSchDlHqProcCb *hqP, +RgSchDlSf *sf, +Bool isMsg4, +U16 rnti, +U8 tbCnt, +CmLteTimingInfo timingInfo, +U8 isAck, +RgInfRlsHqInfo *rlsHqBufs, +RgSchErrInfo *err +) +#else +PUBLIC S16 rgSCHDhmPrcFdbkForTb(cell, ue, hqP, sf, isMsg4, rnti, tbCnt, timingInfo, isAck, rlsHqBufs, err) +RgSchCellCb *cell; +RgSchUeCb *ue; +RgSchDlHqProcCb *hqP; +RgSchDlSf *sf; +Bool isMsg4; +U16 rnti; +U8 tbCnt; +CmLteTimingInfo timingInfo; +U8 isAck; +RgInfRlsHqInfo *rlsHqBufs; +RgSchErrInfo *err; +#endif +{ +#ifdef DEBUGP + Inst inst = cell->instIdx; +#endif +#ifdef RGSCH_SPS_STATS + RgSchCmnDlHqProc *cmnHqDl; +#endif + S16 ret = ROK; + RgSchRaCb *raCb = NULLP; + Bool hqRls=FALSE; + Bool hqFreed =FALSE; + Bool maxHqRetxReached = FALSE; + RgSchCmnDlUe *ueDl = NULLP; + RgSchCellCb *sCell = hqP->hqE->cell; +#ifdef EMTC_ENABLE + RgSchEmtcDlSf *emtcSf; + CmLteTimingInfo frm = timingInfo; +#endif + + TRC2(rgSCHDhmPrcFdbkForTb) + if (ue) + { + ueDl = RG_SCH_CMN_GET_DL_UE(ue,cell); + } + hqRls = FALSE; + /* Fix : syed MultiUe per TTI crash in TA List. */ + maxHqRetxReached = FALSE; + + /* Fix : syed Consider CW to TB mapping for Hq Feedback. + * TODO: Need to enhance this in case of TM4 testing, + * when cwSwap flag is considered. */ + + RGSCHDBGINFO(inst, (rgSchPBuf(inst), "rgSCHDhmHqFdbkInd():\ + tbCnt=%d , isAck=%d",tbCnt,isAck)); + if (isAck == TFU_HQFDB_ACK) + { + hqP->tbInfo[tbCnt].ackCount += 1; /* Ack counter */ + /*sanjay*/ + rgHqRvStats[tbCnt][hqP->tbInfo[tbCnt].dlGrnt.rv][0]++; + /* Do not update the Ul Trans Time in case of raCb */ + if (ue) + { + rgSCHUtlHdlUlTransInd(cell, ue, timingInfo); +#ifdef TENB_STATS + ue->tenbStats->stats.nonPersistent.sch[RG_SCH_CELLINDEX(sCell)].dlAckNackCnt[tbCnt]++; +#endif + + } + +#ifdef TENB_STATS + sCell->tenbStats->sch.dlAckNack[tbCnt]\ + [hqP->tbInfo[tbCnt].dlGrnt.rv]++; + +#endif + + } + else if (isAck == TFU_HQFDB_NACK) + { + hqP->tbInfo[tbCnt].nackCount += 1; /* Nack Counter */ + RGSCHDBGINFONEW(inst, (rgSchPBuf(inst), " HqP[%d:%d] NACKED " + "ue(%d)\n", hqP->procId, tbCnt, hqP->hqE->ue->ueId)); + rgHqRvStats[tbCnt][hqP->tbInfo[tbCnt].dlGrnt.rv][1]++; + /* Do not update the Ul Trans Time in case of raCb */ + +#ifdef TENB_STATS + sCell->tenbStats->sch.dlAckNack[tbCnt]\ + [hqP->tbInfo[tbCnt].dlGrnt.rv]++; + + sCell->tenbStats->sch.dlNack[tbCnt]\ + [hqP->tbInfo[tbCnt].dlGrnt.rv]++; + + +#endif + + if (ue) + { + rgSCHUtlHdlUlTransInd(cell, ue, timingInfo); +#ifdef TENB_STATS + ue->tenbStats->stats.nonPersistent.sch[RG_SCH_CELLINDEX(sCell)].dlAckNackCnt[tbCnt]++; + ue->tenbStats->stats.nonPersistent.sch[RG_SCH_CELLINDEX(sCell)].dlNackCnt[tbCnt] ++; +#endif + } + /* Added Dl TB count for NACKED data*/ +#ifdef LTE_L2_MEAS + if(hqP->tbInfo[tbCnt].txCntr == 1) + { + cell->dlUlTbCnt.tbTransDlFaulty++; + } +#endif + } + else + { + RGSCHDBGINFONEW(inst,(rgSchPBuf(inst)," HqP[%d:%d] DTXED UE(%d)\n", + hqP->procId, tbCnt,hqP->hqE->ue->ueId)); + hqP->tbInfo[tbCnt].dtxCount += 1; /* DTX Counter*/ + +#ifdef TENB_STATS + sCell->tenbStats->sch.dlDtx[tbCnt]\ + [hqP->tbInfo[tbCnt].dlGrnt.rv]++; + if (ue) + { + ue->tenbStats->stats.nonPersistent.sch[RG_SCH_CELLINDEX(sCell)].dlDtxCnt[tbCnt]++; + } +#endif + + + /* Added Dl TB count for DTXED data*/ +#ifdef LTE_L2_MEAS + if(hqP->tbInfo[tbCnt].txCntr == 1) + { + cell->dlUlTbCnt.tbTransDlFaulty++; + } +#endif + } + + /* Check if this is repeating UE */ + if (hqP->tbInfo[tbCnt].fbkRepCntr != 0) + { + if((rgSCHDhmProcHqFdbkAckNackRep(hqP,sf,tbCnt,&isAck)) != ROK) + { + RETVALUE(ret); + } + } + else + { + /* For a Normal UE take the decision here */ + hqP->tbInfo[tbCnt].isAckNackDtx = isAck; + { + rgSCHUtlDlHqPTbRmvFrmTx(sf, hqP, tbCnt, FALSE); + } + } + /* Process either the ACK received or max retries have occurred */ + /* Assuming for Repetition that 2 ACKs and 2 NACKs make an NACK */ + if (TFU_HQFDB_ACK == isAck) + { + if (isMsg4 == TRUE) + { + /* SR_RACH_STATS : MSG4 ACK*/ + rgNumMsg4Ack++; + + if (raCb == NULLP) + { + raCb = rgSCHDbmGetRaCb(cell, rnti); + } + RGSCHDBGINFO(cell->instIdx, + (rgSchPBuf(cell->instIdx), "Ack Rcvd. FdbkInd for Msg4Done\n")); + /* Inform Random Access Module regarding the ack received */ + if (raCb != NULLP) + { + /*RRC Connection Setup failure issue where RRC connection + * setup was not reaching UE due to message 4 HARQ failure */ + printf("\nMSG4 Ack ,calling rgSCHRamMsg4Done\n"); + ret = rgSCHRamMsg4Done(cell, raCb); + hqFreed = TRUE; + } + else + { + printf("\nraCb is NULLP\n"); + } + } + else /*ccpu00114124- HARQ Release for Msg4 */ + { + RGSCH_NULL_CHECK(cell->instIdx, ueDl); + /* Push this harq process back to the free queue */ + ueDl->mimoInfo.cwInfo[tbCnt].ackCnt++; +#ifdef DL_LA + if(hqP->tbInfo[tbCnt].txCntr == 1) + { + rgSCHDhmUpdateAckNackHistory(sCell, ue, isAck, tbCnt); + } +#endif + RGSCH_NULL_CHECK(cell->instIdx, ue); + RG_UPD_ACQI_TRIG_WT(ue, sCell,isAck); + rgSCHDhmRlsHqpTb(hqP, tbCnt, TRUE); + } + hqRls = TRUE; + } + else + { + { + if(!isMsg4) + { + RGSCH_NULL_CHECK(cell->instIdx, ueDl); + ueDl->mimoInfo.cwInfo[tbCnt].nackCnt++; +#ifdef DL_LA + if(hqP->tbInfo[tbCnt].txCntr == 1) + { + rgSCHDhmUpdateAckNackHistory(sCell, ue, isAck, tbCnt); + } +#endif + RGSCH_NULL_CHECK(cell->instIdx, ue); + RG_UPD_ACQI_TRIG_WT(ue, sCell, isAck); + } + else + { +#ifdef XEON_SPECIFIC_CHANGES + CM_LOG_DEBUG(CM_LOG_ID_SCH,"Msg4 Harq FAILURE for UE(%d)\n", rnti); +#endif + rgNumMsg4Nack++; + } + rgSCHDhmHqTbTrnsFail(cell, hqP, tbCnt, &hqRls); + maxHqRetxReached = hqRls; + } + } + + if(hqRls == TRUE) + { + /* MS_WORKAROUND: to increase Harq Fail Counter . + The status field is required for tracking the number of harq faliures at MAC*/ + if (isAck) + { + rlsHqBufs->ueHqInfo[rlsHqBufs->numUes].status[\ + rlsHqBufs->ueHqInfo[rlsHqBufs->numUes].numOfTBs] = TRUE; + } +#ifdef LTE_L2_MEAS + else if(maxHqRetxReached) + { + /* this is to differentiat the NACK with data loss used for UU loss L2 meas */ + rlsHqBufs->ueHqInfo[rlsHqBufs->numUes].status[\ + rlsHqBufs->ueHqInfo[rlsHqBufs->numUes].numOfTBs] = 0xFF; /* RGU_NACK_LOSS; */ + } +#endif + else + { + rlsHqBufs->ueHqInfo[rlsHqBufs->numUes].status[\ + rlsHqBufs->ueHqInfo[rlsHqBufs->numUes].numOfTBs] = FALSE; + } + rlsHqBufs->ueHqInfo[rlsHqBufs->numUes].tbId[\ + rlsHqBufs->ueHqInfo[rlsHqBufs->numUes].numOfTBs] = tbCnt + 1; + rlsHqBufs->ueHqInfo[rlsHqBufs->numUes].numOfTBs++; + } + + /* Handle the TA */ + if (hqFreed == FALSE && hqP->tbInfo[tbCnt].taSnt == TRUE) + { + rgSCHDhmFdbkIndHndlTa(hqP, tbCnt, isAck, maxHqRetxReached); + } + RETVALUE(ret); +} /* rgSCHDhmPrcFdbkForTb */ +/** * @brief Function to decode the position of HarqFb for eachCell. + * + * @details + * + * Function : rgSchGetHqFdbkPos + * + * @param[in] RgSchCellCb *cell, + * @param[in] RgSchUeCb *ue, + * @param[in] RgSchDlHqProcCb *hqP, + * @param[in] RgrSchFrmt1b3TypEnum uciFrmtTyp, + * @param[in] Bool *isAck, + * @param[in] RgTfuHqInfo *fdbk, + * @return RETVOID + **/ +#ifdef ANSI +PUBLIC Void rgSchGetHqFdbkPos +( + RgSchCellCb *cell, + RgSchUeCb *ue, + RgSchDlHqProcCb *hqP, + RgrSchFrmt1b3TypEnum uciFrmtTyp, + U8 *isAck, + RgTfuHqInfo *fdbk + ) +#else +PUBLIC Void rgSchGetHqFdbkPos(cell,ue,hqP,uciFrmtTyp,isAck,fdbk) + RgSchCellCb *cell; + RgSchUeCb *ue; + RgSchDlHqProcCb *hqP; + RgrSchFrmt1b3TypEnum uciFrmtTyp; + U8 *isAck; + RgTfuHqInfo *fdbk; +#endif +{ + if(uciFrmtTyp != RG_SCH_UCI_FORMAT1B_CS) + { + isAck[0] = fdbk->isAck[0]; + isAck[1] = fdbk->isAck[1]; + RETVOID; + } +#ifdef LTE_ADV + /* LAA Making all ack for LAA CELL */ + //if (hqP->hqE && rgSCHLaaSCellEnabled(hqP->hqE->cell)) + if (0) + { + isAck[0] = TRUE; + isAck[1] = TRUE; + RETVOID; + } + + if((ue != NULLP)) + { + /* PUSCH:: Fdbks are in the increasing order + * of servCellIdx as per 36.212 section 5.2.26*/ + switch(ue->f1bCsAVal) + {/* A Value */ + case RG_SCH_A_VAL_2: + { + if(RG_SCH_IS_CELL_SEC(ue,hqP->hqE->cell)) + { + isAck[0] = fdbk->isAck[1];/*SCell*/ + isAck[1] = fdbk->isAck[1];/*SCell*/ + } + else + { + isAck[0] = fdbk->isAck[0];/*PCell*/ + isAck[1] = fdbk->isAck[0];/*PCell*/ + } + break; + } + case RG_SCH_A_VAL_3: + { + if(RG_SCH_IS_CELL_SEC(ue,hqP->hqE->cell)) + { +#ifdef LTE_ADV + U8 servCellIdx = rgSchUtlGetServCellIdx(hqP->hqE->cell->instIdx, + hqP->hqE->cell->cellId, + ue); + + if(rgSCHUtlGetMaxTbSupp(ue->cellInfo[servCellIdx]->txMode.txModeEnum) > 1) +#else + if(rgSCHUtlGetMaxTbSupp(ue->cellInfo[RGSCH_PCELL_INDEX]->txMode.txModeEnum) > 1) +#endif + { /* Sec cell is in mimo mode */ + /* use 0 and 1 for sec in case of pucch + * and 1 and 2 in case of PUSCH as the primary cell is in + * siso case as A =3 */ + if(!fdbk->isPusch) + { + isAck[0] = fdbk->isAck[0]; + isAck[1] = fdbk->isAck[1]; + }else + {/* PUSCH as per 36.212 serction 5.2.26*/ + isAck[0] = fdbk->isAck[1]; + isAck[1] = fdbk->isAck[2]; + } + }else + {/* sec cell is in siso */ + isAck[0] = fdbk->isAck[2]; + } + }else + { + if(rgSCHUtlGetMaxTbSupp(ue->mimoInfo.txMode) > 1) + {/* primay cell is in mimo + use 0 and 1 */ + isAck[0] = fdbk->isAck[0]; + isAck[1] = fdbk->isAck[1]; + }else + { + if(!fdbk->isPusch) + { + isAck[0] = fdbk->isAck[2]; + }else + {/* PUSCH as per 36.212 serction 5.2.26*/ + isAck[0] = fdbk->isAck[0]; + } + } + } + break; + } + case RG_SCH_A_VAL_4: + { + if(RG_SCH_IS_CELL_SEC(ue,hqP->hqE->cell)) + { + isAck[0] = fdbk->isAck[2]; + isAck[1] = fdbk->isAck[3]; +#ifdef CA_DBG + { + if(isAck[0] == TFU_HQFDB_ACK) + { + gSCellTb1AckCount++; + }else if(isAck[0] == TFU_HQFDB_NACK) + { + gSCellTb1NackCount++; + }else + { + gSCellTb1DtxCount++; + } + + if(isAck[1] == TFU_HQFDB_ACK) + { + gSCellTb2AckCount++; + }else if(isAck[1] == TFU_HQFDB_NACK) + { + gSCellTb2NackCount++; + }else + { + gSCellTb2DtxCount++; + } + + } +#endif + } + else + { + isAck[0] = fdbk->isAck[0]; + isAck[1] = fdbk->isAck[1]; +#ifdef CA_DBG + { + if(isAck[0] == TFU_HQFDB_ACK) + { + gPCellTb1AckCount++; + }else if(isAck[0] == TFU_HQFDB_NACK) + { + gPCellTb1NackCount++; + }else + { + gPCellTb1DtxCount++; + } + + if(isAck[1] == TFU_HQFDB_ACK) + { + gPCellTb2AckCount++; + }else if(isAck[1] == TFU_HQFDB_NACK) + { + gPCellTb2NackCount++; + }else + { + gPCellTb2DtxCount++; + } + + } +#endif + + } + break; + } + default: + break; + } + } +#endif + RETVOID; +}/* End of rgSchGetHqFdbkPos */ +#ifdef LTE_ADV +#ifdef ANSI +PUBLIC Void rgSchGetHqFdbkPosFormat3 +( + RgSchDlHqProcCb *hqP, + U8 *isAck, + TfuHqFdbk *fdbk + ) +#else +PUBLIC Void rgSchGetHqFdbkPosFormat3(hqP,isAck,fdbk) + RgSchDlHqProcCb *hqP; + U8 *isAck; + TfuHqFdbk *fdbk; +#endif +{ + U8 cellIdx = RG_SCH_CMN_GET_CELL_IDX_FROM_HQP(hqP); + isAck[0] = (U8)fdbk[cellIdx]; + isAck[1] = (U8)fdbk[cellIdx + 1]; +} +#endif +/** * @brief Handler for HARQ feedback received for DL transmission. + * + * @details + * + * Function : rgSCHDhm5gtfHqFdbkInd + * + * This function shall act on the feedback received from TOM for DL + * transmission. If the feedback for msg4 is final (after max transmissions + * or ACK) inform RAM that Msg4 transmission is done. + * + * + * @param[in] Void *cb + * @param[in] U8 cbType + * @param[in] RgSchCellCb *cell + * @param[in] RgTfuHarqAckIndInfo *fdbk + * @param[in] RgInfRlsHqInfo *rlsHqBufs + * @param[in] RgSchErrInfo *err + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 rgSCHDhm5gtfHqFdbkInd +( +RgSchUeCb *ue, +RgSchCellCb *cell, +CmLteTimingInfo timingInfo, +TfuHqFdbk fdbk, +RgSchErrInfo *err +) +#else +PUBLIC S16 rgSCHDhm5gtfHqFdbkInd(ue, cell, timingInfo, fdbk, err) +RgSchUeCb *ue; +RgSchCellCb *cell; +CmLteTimingInfo timingInfo; +TfuHqFdbk fdbk; +RgSchErrInfo *err; +#endif +{ + RgSchDlHqProcCb *hqP = NULLP; + CmLList *node = NULLP; + CmLListCp *lnk; + S16 ret = ROK; + RgSchDlSf *sf; + Bool isMsg4 = FALSE; + U16 rnti=0; + U16 procId=0; + U8 hqPCount = 0; + RgInfRlsHqInfo *rlsHqBufs = NULLP; + + TRC2(rgSCHDhm5gtfHqFdbkInd) + + RGSCHDECRFRMCRNTTIME(timingInfo, timingInfo, 4); + + sf = rgSCHUtlSubFrmGet(cell, timingInfo); + + lnk = &ue->dl.dlSfHqInfo[cell->cellId][sf->dlIdx].hqPLst; + node = lnk->first; + hqPCount = lnk->count; + rnti = ue->ueId; + + while (hqPCount) + { + hqP = (RgSchDlHqProcCb *)node->node; + node = node->next; + rlsHqBufs = &(hqP->hqE->cell->rlsHqArr[hqP->hqE->cell->crntHqIdx]); + procId = hqP->procId; + + rlsHqBufs->ueHqInfo[rlsHqBufs->numUes].numOfTBs = 0; + + if (HQ_TB_WAITING == hqP->tbInfo[0].state) + { + rgSCHDhmPrcFdbkForTb(cell, ue, hqP, sf, isMsg4, rnti, 0, + timingInfo, fdbk, rlsHqBufs, err); + } + if(rlsHqBufs->ueHqInfo[rlsHqBufs->numUes].numOfTBs) + { + rlsHqBufs->ueHqInfo[rlsHqBufs->numUes].rnti = rnti; + rlsHqBufs->ueHqInfo[rlsHqBufs->numUes].hqProcId = + (U8)procId; + rlsHqBufs->numUes++; + } + hqPCount--; + } + + RETVALUE(ret); +} /* rgSCHDhm5gtfHqFdbkInd */ + +/** * @brief Handler for HARQ feedback received for DL transmission. + * + * @details + * + * Function : rgSCHDhmHqFdbkInd + * + * This function shall act on the feedback received from TOM for DL + * transmission. If the feedback for msg4 is final (after max transmissions + * or ACK) inform RAM that Msg4 transmission is done. + * + * + * @param[in] Void *cb + * @param[in] U8 cbType + * @param[in] RgSchCellCb *cell + * @param[in] RgTfuHarqAckIndInfo *fdbk + * @param[in] RgInfRlsHqInfo *rlsHqBufs + * @param[in] RgSchErrInfo *err + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 rgSCHDhmHqFdbkInd +( +Void *cb, +U8 cbType, +RgSchCellCb *cell, +CmLteTimingInfo timingInfo, +RgTfuHqInfo *fdbk, +RgInfRlsHqInfo *rlsHqBufs, +RgSchErrInfo *err +) +#else +PUBLIC S16 rgSCHDhmHqFdbkInd(cb, cbType, cell, timingInfo, fdbk, rlsHqBufs, err) +Void *cb; +U8 cbType; +RgSchCellCb *cell; +CmLteTimingInfo timingInfo; +RgTfuHqInfo *fdbk; +RgInfRlsHqInfo *rlsHqBufs; +RgSchErrInfo *err; +#endif +{ + RgSchDlHqTbCb *tbCb; + RgSchDlHqEnt *hqE = NULLP; + RgSchDlHqProcCb *hqP = NULLP; + CmLList *node = NULLP; + CmLListCp *lnk; + /* Create and Initialize Ue it so that Its not Deferenced Unnecessarily */ + RgSchUeCb *ue = NULLP; + + S16 ret = ROK; + RgSchDlSf *sf; + Bool isMsg4 = FALSE; + RgSchRaCb *raCb = NULLP; + U16 rnti=0; + /* Added Insure Fixes Of UR.Initialized procId */ + U16 procId=0; + /* DTX Change: Bool is converted into U8*/ + U8 isAck[2]={0}; /*Changed to Array of 2*/ + U8 tbCnt; + U8 hqPCount = 0; + +#ifdef LTEMAC_SPS + CmLteTimingInfo fdbkRcptTime = timingInfo; +#ifdef RGSCH_SPS_STATS + RgSchCmnDlHqProc *cmnHqDl; +#endif +#endif +#ifdef LTE_ADV + TfuHqFdbk format3Ack[CM_LTE_MAX_CELLS *2] = {0}; +#endif + RgrSchFrmt1b3TypEnum uciFrmtTyp = RG_SCH_UCI_FORMAT1A_1B; + + TRC2(rgSCHDhmHqFdbkInd) + + /* Get the subframe associated with the feedback */ + /* ccpu00133109: Removed RGSCHSUBFRMCRNTTIME as it is not giving proper output + * if diff is more than 10. Instead using RGSCHDECRFRMCRNTTIME() as it is + * serving the purpose */ + RGSCHDECRFRMCRNTTIME(timingInfo, timingInfo, 4); + + sf = rgSCHUtlSubFrmGet(cell, timingInfo); + if (cbType == RGSCH_HQ_FDB_IND_CB_TYPE_RA_CB) + { + raCb = (RgSchRaCb *)(cb); + hqE = raCb->dlHqE; + hqP = rgSCHDhmHqProcByTime(hqE, timingInfo, &isMsg4,\ + sf); + if(hqP) + { + hqPCount = 1; + } + rnti = raCb->tmpCrnti; + } + else + { + ue = (RgSchUeCb *)(cb); + hqE = RG_SCH_CMN_GET_UE_HQE(ue, cell); + { + lnk = &ue->dl.dlSfHqInfo[cell->cellId][sf->dlIdx].hqPLst; + } + node = lnk->first; + hqPCount = lnk->count; + rnti = ue->ueId; +#ifdef LTE_ADV + uciFrmtTyp = ue->dl.dlSfHqInfo[cell->cellId][sf->dlIdx].uciFrmtTyp; +#endif + } + /* + TO ADD STATS + from Harq Proc get ueCb = hqP->hqEnt->ueCb + from ueCb get cmnUecb = (RgSchCmnUe *)ueCb->sch; + from ueCb get dlUe = (RgSchCmnDlUe)cmnUeCb->dl + from get cmInfo "RgSchCmnDlUeCwInfo" dlUe->mimoInfo->cwInfo[0] + from get CQI from cmInfo->cqi + from cmInfo get iTbs cmInfo->iTbs[0] + call RG_SCH_CMN_DL_TBS_TO_MCS to map iTbs=>MCS + Update stats in cellCb + cellCb->hqFailStats[cmInfo->cqi].mcs = RG_SCH_CMN_DL_TBS_TO_MCS(cmInfo->iTbs[0]); + if (fdbk->isAck == TRUE) + cellCb->hqFailStats[cmInfo->cqi].numOfNacks += 1; + else + cellCb->hqFailStats[cmInfo->cqi].numOfAcks += 1; + DL Ack/Nack statistics + */ +#ifdef MAC_SCH_STATS + if (hqE->ue != NULLP) + { + RgSchUeCb *ueCb = hqE->ue; + RgSchCmnUe *cmnUe = (RgSchCmnUe*)ueCb->sch; + RgSchCmnDlUe *dlUe = RG_SCH_CMN_GET_DL_UE(ueCb,hqE->cell);/*CA dev*/ + U8 tbs = dlUe->mimoInfo.cwInfo[0].iTbs[0]; + static U32 retxCnt = 0; + + if (fdbk->isAck[0] == TFU_HQFDB_ACK) + { + hqFailStats.dlCqiStat[(dlUe->mimoInfo.cwInfo[0].cqi - 1)].numOfAcks++; + } + else + { + ++retxCnt; + hqFailStats.dlCqiStat[(dlUe->mimoInfo.cwInfo[0].cqi - 1)].numOfNacks++; + } + RG_SCH_CMN_DL_TBS_TO_MCS(tbs, + (hqFailStats.dlCqiStat[(dlUe->mimoInfo.cwInfo[0].cqi - 1)].mcs)); + } +#endif /* MAC_SCH_STATS */ + + /* Fetch the harqProc from the inUse list */ +#ifdef LTEMAC_SPS + /* Check if the feedback timing matches with ue->relPdcchFbkTiming*/ + /* Call Common module with the feedback information */ + if (ue && (ue->relPdcchFbkTiming.sfn != (RGSCH_MAX_SFN + 1))) + { + if (RGSCH_TIMEINFO_SAME(fdbkRcptTime, ue->relPdcchFbkTiming)) + { + sf = rgSCHUtlSubFrmGet(cell, timingInfo); + +#ifdef LTE_ADV + if(uciFrmtTyp == RG_SCH_UCI_FORMAT1B_CS) + {/* Feedback for SPS Release on PCell + If Pcell is in mimo, feedback index will be 0 + else 2 */ + if(rgSCHUtlGetMaxTbSupp(ue->mimoInfo.txMode) > 1) + { + isAck[0] = fdbk->isAck[0]; + }else + { + isAck[0] = fdbk->isAck[2]; + } + + /* Not releasing pdcch here + * as it is already done at the time of + * reception req */ + rgSCHUtlDlRelPdcchFbk(cell, ue, isAck[0]); + } + else +#endif + { + if (!sf->relPdcch) + { + RLOG_ARG3(L_ERROR,DBG_CELLID,cell->cellId, + "CRNTI:%d NO HARQ proc available for feedback: TimingInfo: " + "sfn %d subframe %d", ue->ueId, timingInfo.sfn, + timingInfo.subframe); + RETVALUE(RFAILED); + } + + isAck[0] = fdbk->isAck[0]; + /* Note: Since relPdcchFbkTimimg matches with the recieved + * feedback, assumed that feedback is for release PDCCH */ + rgSCHUtlDlRelPdcchFbk(cell, ue, isAck[0]); + + /* Remove release PDCCH from the subframe */ + rgSCHUtlPdcchPut(cell, &sf->pdcchInfo, sf->relPdcch); + sf->relPdcch = NULLP; + RETVALUE(ROK); + } + } + } +#endif /* LTEMAC_SPS */ + + /* Remove the harq process from the subframe */ + sf = rgSCHUtlSubFrmGet(cell, timingInfo); + RG_SCH_ADD_TO_CRNT_TIME(timingInfo, timingInfo, 1); + +#ifdef CA_DBG + { + if(ue) + { + gHqFdbkCount++; + } + } + +#endif + while (hqPCount) + { + if(cbType != RGSCH_HQ_FDB_IND_CB_TYPE_RA_CB) + { + hqP = (RgSchDlHqProcCb *)node->node; + node = node->next; + rlsHqBufs = &(hqP->hqE->cell->rlsHqArr[hqP->hqE->cell->crntHqIdx]); + } + procId = hqP->procId; + + rlsHqBufs->ueHqInfo[rlsHqBufs->numUes].numOfTBs = 0; + + /*Get the position of Ack/Nack from 2 bytes fdbkInfo. + * On the basis of f1bCsAVal find the position of iAck or Nack*/ +#ifdef LTE_ADV + if (uciFrmtTyp == RG_SCH_UCI_FORMAT3) + { + rgSchGetHqFdbkPosFormat3(hqP,isAck,format3Ack); + } + else +#endif + { + rgSchGetHqFdbkPos(cell,ue,hqP, uciFrmtTyp, isAck,fdbk); + } + for (tbCnt = 0; tbCnt < 2; tbCnt++) + { + if (HQ_TB_WAITING == hqP->tbInfo[tbCnt].state) + { + rgSCHDhmPrcFdbkForTb(cell, ue, hqP, sf, isMsg4, rnti, tbCnt, + timingInfo, isAck[tbCnt], rlsHqBufs, err); + } + } + if(rlsHqBufs->ueHqInfo[rlsHqBufs->numUes].numOfTBs) + { + rlsHqBufs->ueHqInfo[rlsHqBufs->numUes].rnti = rnti; + rlsHqBufs->ueHqInfo[rlsHqBufs->numUes].hqProcId = + (U8)procId; + rlsHqBufs->numUes++; + } + hqPCount--; + } + + node = sf->ackNakRepQ.first; + while (node) + { + tbCb = (RgSchDlHqTbCb *)(node->node); + hqP = tbCb->hqP; + + procId = hqP->procId; + rlsHqBufs = &(hqP->hqE->cell->rlsHqArr[hqP->hqE->cell->crntHqIdx]); + rlsHqBufs->ueHqInfo[rlsHqBufs->numUes].numOfTBs = 0; + if (HQ_TB_WAITING == tbCb->state) + { + isAck[0] = fdbk->isAck[tbCb->tbIdx]; + rgSCHDhmPrcFdbkForTb(cell, ue, hqP, sf, isMsg4, rnti, tbCb->tbIdx, + timingInfo, isAck[0], rlsHqBufs, err); + } + hqP->cwSwpEnabled = FALSE; + if(rlsHqBufs->ueHqInfo[rlsHqBufs->numUes].numOfTBs) + { + rlsHqBufs->ueHqInfo[rlsHqBufs->numUes].rnti = rnti; + rlsHqBufs->ueHqInfo[rlsHqBufs->numUes].hqProcId = + (U8)procId; + rlsHqBufs->numUes++; + } + hqPCount--; + node = node->next; + } + + RETVALUE(ret); +} /* rgSCHDhmHqFdbkInd */ +#endif /* LTE_FDD */ + + +/** + * @brief Handler for Harq related UE configuration. + * + * @details + * + * Function : rgSCHDhmRgrUeCfg + * + * This function shall fetch the harq related information into the + * respective ueCb from the UE configuration as provided by the + * upper layers. + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ueCb + * @param[in] RgrUeCfg *ueCfg + * @param[out] RgSchErrInfo *err + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC Void rgSCHDhmRgrUeCfg +( +RgSchCellCb *cell, +RgSchUeCb *ueCb, +RgrUeCfg *ueCfg, +RgSchErrInfo *err +) +#else +PUBLIC Void rgSCHDhmRgrUeCfg(cell, ueCb, ueCfg, err) +RgSchCellCb *cell; +RgSchUeCb *ueCb; +RgrUeCfg *ueCfg; +RgSchErrInfo *err; +#endif +{ + TRC2(rgSCHDhmRgrUeCfg) + + UNUSED(err); + + /* Initialize the TA Timer */ + cmInitTimers(&ueCb->taTmr, 1); + + /* Setting these values irrespective of taTmr value */ + ueCb->dl.taCb.state = RGSCH_TA_IDLE; + /* Corrected default value of TA as per 36.213, 4.2.3 */ + ueCb->dl.taCb.ta = RGSCH_NO_TA_RQD; + + /*[ccpu00121813]-ADD-Initializing outstanding TA value */ + ueCb->dl.taCb.outStndngTa = FALSE; + ueCb->dl.taCb.outStndngTaval = RGSCH_NO_TA_RQD; + + /* Start TA timer only if cfgd as FINITE value */ + if (ueCfg->ueTaTmrCfg.pres) + { + /* Configuring taTmr with 30 deficit, to enable eNodeB sending + * TA command before the expiry of TA at UE. Also considering for + * possible retx for this TA command */ + /*[ccpu00121813]-ADD-Added chk if tatmr val > 30 */ + if(ueCfg->ueTaTmrCfg.taTmr > 30) + { + ueCb->dl.taCb.cfgTaTmr = ueCfg->ueTaTmrCfg.taTmr - 30; + } + rgSCHTmrStartTmr (cell, ueCb, RG_SCH_TMR_TA, ueCb->dl.taCb.cfgTaTmr); + } + RETVOID; +} /* rgSCHDhmRgrUeCfg */ + + +/** + * @brief Handler for HARQ related UE Reconfiguration + * + * @details + * + * Function : rgSCHDhmRgrCellCfg + * + * This function shall fetch the HARQ related information into the + * respective ueCb from the UE configuration as provided by the + * upper layers. + * + * @param[in] RgSchCellCb *cell + * @param[in] RgrCellCfg *cellCfg + * @param[out] RgSchErrInfo *err + * + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC Void rgSCHDhmRgrCellCfg +( +RgSchCellCb *cell, +RgrCellCfg *cellCfg, +RgSchErrInfo *err +) +#else +PUBLIC Void rgSCHDhmRgrCellCfg(cell, cellCfg, err) +RgSchCellCb *cell; +RgrCellCfg *cellCfg; +RgSchErrInfo *err; +#endif +{ + RgSchDlHqEnt *hqE; + PTR pUeCb;/* previous UE Control block */ + PTR nUeCb;/* next UE control block */ + S16 ret; + U8 idx; + + TRC2(rgSCHDhmRgrCellCfg) + + UNUSED(err); + + pUeCb = NULLP; + + cell->dlHqCfg = cellCfg->dlHqCfg; + for (;;) + { + ret = cmHashListGetNext(&(cell->ueLst), pUeCb, &nUeCb); + if (ret != ROK) + { + break; + } + else + { + pUeCb = nUeCb; + /* Update the DL Harq related information */ + hqE = RG_SCH_CMN_GET_UE_HQE(((RgSchUeCb*)nUeCb), cell); + hqE->maxHqTx = cell->dlHqCfg.maxDlHqTx; + } + } + /* Initializing the list for ueCbs that would have ta */ + cmLListInit(&cell->taUeLst); +#ifdef RGR_V1 + cmLListInit(&cell->ccchSduUeLst); + cmLListInit(&cell->contResGrdTmrLst); + cmLListInit(&cell->contResTmrLst); +#ifdef EMTC_ENABLE + if(cell->emtcEnable) + { + rgSCHDhmEmtcRgrCellCfg(cell); + } +#endif +#endif + + /* Initializing the timer queue */ + cell->tqCp.nxtEnt = 0; + cell->tqCp.tmrLen = RGSCH_UE_TQ_SIZE; + + for (idx = 0; idx < RGSCH_UE_TQ_SIZE; idx++) + { + cell->tq[idx].first = NULLP; + cell->tq[idx].tail = NULLP; + } + RETVOID; +} /* rgSCHDhmRgrCellCfg */ + +/** + * @brief Handler for Updating HARQ Information from Cell Reconfiguration + * + * @details + * + * Function : rgSCHDhmRgrCellRecfg + * + * This function shall fetch the HARQ related information into the + * respective ueCb from the UE configuration as provided by the + * upper layers. + * + * @param[in] RgSchCellCb *cell + * @param[in] RgrCellRecfg *cellRecfg + * @param[out] RgSchErrInfo *err + * + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC Void rgSCHDhmRgrCellRecfg +( +RgSchCellCb *cell, +RgrCellRecfg *cellRecfg, +RgSchErrInfo *err +) +#else +PUBLIC Void rgSCHDhmRgrCellRecfg(cell, cellRecfg, err) +RgSchCellCb *cell; +RgrCellRecfg *cellRecfg; +RgSchErrInfo *err; +#endif +{ + RgSchDlHqEnt *hqE; + PTR pUeCb;/* previous UE Control block */ + PTR nUeCb;/* next UE control block */ + S16 ret; + + TRC2(rgSCHDhmRgrCellRecfg) + + UNUSED(err); + + pUeCb = NULLP; + + /* Update the cell with recieved configuration */ + if (cellRecfg->recfgTypes & RGR_CELL_DL_HARQ_RECFG) + { + cell->dlHqCfg = cellRecfg->dlHqRecfg; + + for (;;) + { + ret = cmHashListGetNext(&(cell->ueLst), pUeCb, &nUeCb); + if (ret != ROK) + { + break; + } + else + { + pUeCb = nUeCb; + /* Update the DL Harq related information */ + hqE = RG_SCH_CMN_GET_UE_HQE(((RgSchUeCb*)nUeCb), cell); + hqE->maxHqTx = cell->dlHqCfg.maxDlHqTx; + } + } + } + RETVOID; +} /* rgSCHDhmRgrCellRecfg */ + +/** + * @brief Handler for freeing up the HARQ related information from ueCb + * + * @details + * + * Function : rgSCHDhmFreeUe + * + * This function shall free up the HARQ specific information from ueCb. + * + * @param[in] RgSchUeCb *ueCb + * + * @return None. + * + **/ +#ifdef ANSI +PUBLIC Void rgSCHDhmFreeUe +( +RgSchUeCb *ueCb +) +#else +PUBLIC Void rgSCHDhmFreeUe(ueCb) +RgSchUeCb *ueCb; +#endif +{ + + TRC2(rgSCHDhmFreeUe) + + /* If TA Timer is running. Stop it */ + if (ueCb->taTmr.tmrEvnt != TMR_NONE) + { + rgSCHTmrStopTmr(ueCb->cell, ueCb->taTmr.tmrEvnt, ueCb); + } + + /* ccpu00118357 - ADD - stop the periodic BSR timer so it + * doesn't expire after UE is deleted */ +#ifdef RGR_V1 + if (ueCb->bsrTmr.tmrEvnt != TMR_NONE) + { + rgSCHTmrStopTmr(ueCb->cell, ueCb->bsrTmr.tmrEvnt, ueCb); + } +#endif /* ifdef RGR_V1*/ + + + if (RG_SCH_CMN_GET_UE_HQE(ueCb, ueCb->cell)) + { + rgSCHDhmDelHqEnt(ueCb->cell, &(RG_SCH_CMN_GET_UE_HQE(ueCb, ueCb->cell))); + } + + /* This UE needs to be removed from its entry into cell's taUeLst */ + /*Fix for ccpu00113622 - Delete Only when taLnk Node exists*/ + if(ueCb->taLnk.node) + { + cmLListDelFrm(&(ueCb->cell->taUeLst), &ueCb->taLnk); + ueCb->taLnk.node = NULLP; + } + + if (ueCb->dlTaLnk.node != NULLP) + { + /* Fix: syed Need to raise a CR for not calling CMN or specific scheduler + * function directly from other modules. APIs should be defined and/or used + * instead. Please check for other possible incorrect usage. */ + rgSCHCmnRmvFrmTaLst(ueCb->cell, ueCb); + } + + RETVOID; + +} /* rgSCHDhmFreeUe */ + +/** + * @brief Handler for updating the TA. + * + * @details + * + * Function : rgSCHDhmUpdTa + * + * This function shall update the TA received. + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ueCb + * @param[in] U8 ta + * + * @return None. + * + **/ +#ifdef ANSI +PUBLIC Void rgSCHDhmUpdTa +( +RgSchCellCb *cell, +RgSchUeCb *ueCb, +U8 ta +) +#else +PUBLIC Void rgSCHDhmUpdTa(cell, ueCb, ta) +RgSchCellCb *cell; +RgSchUeCb *ueCb; +U8 ta; +#endif +{ + TRC2(rgSCHDhmUpdTa) + + if (ueCb->dl.taCb.state == RGSCH_TA_IDLE) + { + ueCb->dl.taCb.state = RGSCH_TA_TOBE_SCHEDULED; + ueCb->dl.taCb.numRemSf = 2; + rgSCHUtlDlTARpt(cell, ueCb); + /* If TA Timer is running. Stop it */ + if (ueCb->taTmr.tmrEvnt != TMR_NONE) + { + rgSCHTmrStopTmr(cell, ueCb->taTmr.tmrEvnt, ueCb); + } + + /* SR_RACH_STATS : TA MODIFIED */ + if (ueCb->dl.taCb.ta != ta) + { + rgNumTAModified++; + } + ueCb->dl.taCb.ta = ta; + } + else + { + /* [ccpu00121813]-ADD-Updating outstanding values + * TA which gets transmitted at N gets applied at UE at N+6,once TA + * has been scheduled,further TA values get stored in outstndngTaval. + * Once TA gets applied at UE or when NACK/DTX is rcvd for maxhqretx times + * then schedule the outstanding TA val if present */ + ueCb->dl.taCb.outStndngTa = TRUE; + ueCb->dl.taCb.outStndngTaval = ta; + } + + RETVOID; +} /* rgSCHDhmUpdTa */ + + /** @brief This function handles the TA timer expiry. + * + * @details + * + * Function: This function handled the TA Expiry. + * + * Processing steps: + * - + * + * + * @param[in] RgSchUeCb *ueCb + * + * @return Void + * -#None. + */ +#ifdef ANSI +PUBLIC Void rgSCHDhmProcTAExp +( + RgSchUeCb *ueCb + ) +#else +PUBLIC Void rgSCHDhmProcTAExp (ueCb) + RgSchUeCb *ueCb; +#endif +{ + TRC2(rgSCHDhmProcTAExp); + + /* Ask scheduler to schedule this UE */ + ueCb->dl.taCb.state = RGSCH_TA_TOBE_SCHEDULED; + rgSCHUtlDlTARpt(ueCb->cell, ueCb); + RETVOID; +} /* end of rgSCHDhmProcTAExp */ + +/* 3.1 MIMO: LC details at TB level rather than Hq Level */ +/** + * @brief Handler for Adding scheduled logical channel data information + * to harqProc. + * + * @details + * + * Function : rgSCHDhmAddLcData + * + * This function shall add the scheduled logical channel data + * information to the HARQ process. + * + * @param[in] RgSchLchAllocInfo *lchData + * @param[in] RgSchDlHqTbCb *tbInfo + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 rgSCHDhmAddLcData +( +Inst inst, +RgSchLchAllocInfo *lchData, +RgSchDlHqTbCb *tbInfo +) +#else +PUBLIC S16 rgSCHDhmAddLcData(inst, lchData, tbInfo) +Inst inst; +RgSchLchAllocInfo *lchData; +RgSchDlHqTbCb *tbInfo; +#endif +{ + + TRC2(rgSCHDhmAddLcData) + + if(tbInfo->numLch >= RGSCH_MAX_NUM_DED_LC) + { + RETVALUE(RFAILED); + } + + tbInfo->lchSchdDataArr[tbInfo->numLch] = *lchData; + + tbInfo->numLch++; + + RETVALUE(ROK); + +} /* rgSCHDhmAddLcData */ + +#ifdef LTE_TDD +/* + * @brief Handler for releaseing the subframe allocation. + * + * @details + * + * Function : rgSCHDhmTddRlsSubFrm + * + * This function shall be invoked to release the DL Sf + * allocations for which HARQ feedback time has expired. + * + * @param[in] RgSchCellCb *cellCb + * @param[in] CmLteTimingInfo uciTimingInfo; + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 rgSCHDhmTddRlsSubFrm +( +RgSchCellCb *cellCb, +CmLteTimingInfo uciTimingInfo +) +#else +PUBLIC S16 rgSCHDhmTddRlsSubFrm(cellCb, uciTimingInfo) +RgSchCellCb *cellCb; +CmLteTimingInfo uciTimingInfo; +#endif +{ + CmLteTimingInfo dlSfTime; + RgSchTddDlAscSetIdxK ascIdx; + U8 noFdbks; + U8 i; + + TRC2(rgSCHDhmTddRlsSubFrm) + + ascIdx = + rgSchTddDlAscSetIdxKTbl[cellCb->ulDlCfgIdx][uciTimingInfo.subframe]; + noFdbks = ascIdx.numFdbkSubfrms; + for(i=0; i < noFdbks; i++) + { + /* Get the subframe and sfn for which HARQ Ack/Nack + * has to be sent */ + /* ccpu00132341-MOD- optimized getting DLSF time using macro*/ + /* ccpu00133109: Removed RGSCHSUBFRMCRNTTIME as it is not giving proper + * output if diff is more than 10. Instead using RGSCHDECRFRMCRNTTIME() + * as it is serving the purpose */ + RGSCHDECRFRMCRNTTIME(uciTimingInfo, dlSfTime, ascIdx.subfrmNum[i]); + rgSCHUtlDlRlsSubFrm(cellCb, dlSfTime); + } + RETVALUE(ROK); +}/* rgSCHDhmTddRlsSubFrm */ + +#ifdef TFU_TDD +U32 macDtx = 0; +#endif +/** + * @brief Handler for Removing the HARQ process from a dlsf. + * + * @details + * + * Function : rgSCHDhmRlsDlsfHqProc + * + * This function shall be invoked for every tti. It goes back to + * to the sixth last subframe to check whether it still exists. If + * that exists this function traverses through the entire harq + * proc list associated and frees up all of them. + * + * @param[in] RgSchCellCb *cellCb + * @param[in] CmLteTimingInfo timingInfo + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 rgSCHDhmRlsDlsfHqProc +( +RgSchCellCb *cellCb, +CmLteTimingInfo uciTimingInfo +) +#else +PUBLIC S16 rgSCHDhmRlsDlsfHqProc(cellCb, uciTimingInfo) +RgSchCellCb *cellCb; +CmLteTimingInfo uciTimingInfo; +#endif +{ + RgSchDlSf *dlSf; + CmLteTimingInfo dlSfTime; + CmLteTimingInfo nxtfrm = {0,0}; + RgSchDlHqProcCb *tmpHqProc; + RgSchTddDlAscSetIdxK ascIdx; + U8 noFdbks; + S16 i; + RgSchDlSf *nxtDlsf = NULLP; + CmLList *node; + CmLList *hqPNode; + U8 idx; + /*ccpu00130018 -MOD -Initiatizing with FALSE*/ + U8 maxRetx=FALSE; + RgSchTddANInfo *anInfo = NULLP; + RgSchDlHqTbCb *tbCb; + RgSchUeCb *ue = NULLP; + TRC2(rgSCHDhmRlsDlsfHqProc) + + ascIdx = + rgSchTddDlAscSetIdxKTbl[cellCb->ulDlCfgIdx][uciTimingInfo.subframe]; + noFdbks = ascIdx.numFdbkSubfrms; + for(i=0; i < noFdbks; i++) + { + /* Get the subframe and sfn for which HARQ Ack/Nack + * has to be sent */ + /* ccpu00132341-MOD- optimized getting DLSF time using macro*/ + /* ccpu00133109: Removed RGSCHSUBFRMCRNTTIME as it is not giving proper + * output if diff is more than 10. Instead using RGSCHDECRFRMCRNTTIME() + * as it is serving the purpose */ + RGSCHDECRFRMCRNTTIME(uciTimingInfo, dlSfTime, ascIdx.subfrmNum[i]); + + dlSf = rgSCHUtlSubFrmGet (cellCb, dlSfTime); + if(cellCb->ulDlCfgIdx != 5) + { + rgSCHUtlGetNxtDlSfInfo(dlSfTime, cellCb, dlSf, &nxtDlsf, &nxtfrm); + } + /* Subframe is present. Delete all the harq associations from + * this subframe. + */ + + /*Handling for Msg4*/ + node = dlSf->msg4HqPLst.first; + while (node) + { + tmpHqProc = (RgSchDlHqProcCb *)(node->node); + node = node->next; + tmpHqProc->cwSwpEnabled = FALSE; + if (HQ_TB_WAITING == tmpHqProc->tbInfo[0].state) + { + tbCb = &tmpHqProc->tbInfo[0]; + + /* Fix : syed MultiUe per TTI crash in TA List. */ + maxRetx = FALSE; + + tbCb->dtxCount++; + tbCb->isAckNackDtx = TFU_HQFDB_DTX; + + + rgSCHUtlDlHqPTbRmvFrmTx(dlSf, tmpHqProc, tbCb->tbIdx, FALSE); + + /* Delete the Harq Association. Release the Harq Process */ + rgSCHDhmHqTbTrnsFail(cellCb, tmpHqProc, tbCb->tbIdx, &maxRetx); + + if (tbCb->taSnt == TRUE) + { + /* [ccpu00127148] Correcting the check */ + if (TRUE == maxRetx) + { + tbCb->taSnt = FALSE; + RGSCH_NULL_CHECK(cellCb->instIdx, ue) + ue->dl.taCb.state = RGSCH_TA_IDLE; + + rgSCHUtlReTxTa(cellCb, ue); + } + } + } + } + + node = dlSf->ueLst.first; + while (node) + { +#ifdef TFU_TDD + macDtx++; +#endif + ue = (RgSchUeCb *)(node->node); + node = node->next; + if (NULLP != ue) + { + hqPNode = ue->dl.dlSfHqInfo[cellCb->cellId][dlSf->dlIdx].hqPLst.first; + while (hqPNode) + { + tmpHqProc = (RgSchDlHqProcCb *)hqPNode->node; + hqPNode = hqPNode->next; + for (idx = 0 ;idx < 2; idx++) + { + if (HQ_TB_WAITING == tmpHqProc->tbInfo[idx].state) + { + tbCb = &tmpHqProc->tbInfo[idx]; + + /* Fix : syed MultiUe per TTI crash in TA List. */ + maxRetx = FALSE; + + tbCb->dtxCount++; + tbCb->isAckNackDtx = TFU_HQFDB_DTX; + + + /* Update feedback time for this process so that + * next subframe its picked up */ +#ifdef LTE_ADV + U8 servCellIdx = rgSchUtlGetServCellIdx( + tmpHqProc->hqE->cell->instIdx, + tmpHqProc->hqE->cell->cellId, + ue); + anInfo = rgSCHUtlGetUeANFdbkInfo(ue, &tbCb->fdbkTime,servCellIdx); +#else + anInfo = rgSCHUtlGetUeANFdbkInfo(ue, &tbCb->fdbkTime,RGSCH_PCELL_INDEX); +#endif + if(anInfo == NULLP) + { + RGSCHDBGERR(cellCb->instIdx, (rgSchPBuf(cellCb->instIdx), + "Ack/Nack Info is NULL, Processing %dth feedback subframe for DTX" + "received on SFN [%d] and SF [%d]\n",i, uciTimingInfo.sfn, + uciTimingInfo.subframe)); + } + else if (tbCb->fbkRepCntr == 0) + { + /* Initialise the Ack/Nack feedback */ + anInfo->dlDai--; + if(!(anInfo->dlDai)) + { + rgSCHUtlInitUeANFdbkInfo(anInfo); + } + } + else + { + /* Update feedback time for this process so that + * * next subframe its picked up */ + RGSCH_NULL_CHECK(cellCb->instIdx, nxtDlsf); + RGSCH_UPD_HQAN_FDBKTIME(tbCb, nxtDlsf, nxtfrm); + RGSCH_UPD_ANINFO_WITH_HQ(anInfo, tbCb); + rgSCHUtlDlHqPTbRmvFrmTx(dlSf, tmpHqProc, tbCb->tbIdx, TRUE); + tbCb->fbkRepCntr--; + continue; + + } + rgSCHUtlDlHqPTbRmvFrmTx(dlSf, tmpHqProc, tbCb->tbIdx, FALSE); + /*ccpu000119494-ADD- for SPS, call SPS specific DTX handler */ + + { + /* Delete the Harq Association. Release the Harq Process */ + rgSCHDhmHqTbTrnsFail(cellCb, tmpHqProc, tbCb->tbIdx, &maxRetx); + } + if (tbCb->taSnt == TRUE) + { + /* [ccpu00127148] Correcting the check */ + if (TRUE == maxRetx) + { + tbCb->taSnt = FALSE; + RGSCH_NULL_CHECK(cellCb->instIdx, ue) + ue->dl.taCb.state = RGSCH_TA_IDLE; + + rgSCHUtlReTxTa(cellCb, ue); + + RLOG_ARG0(L_DEBUG,DBG_CELLID,cellCb->cellId, + "Nack/DTX Rcvd for TA. Max Tries Attempted"); + } + } + } + } + } + } + } + + node = dlSf->ackNakRepQ.first; + while (node) + { + tbCb = (RgSchDlHqTbCb *)(node->node); + tmpHqProc = tbCb->hqP; + /* [ccpu00121813]-ADD-Fetch ueCb */ + ue = tmpHqProc->hqE->ue; + /* Fix : syed MultiUe per TTI crash in TA List. */ + maxRetx = FALSE; + + tbCb->dtxCount++; +#ifdef TENB_STATS + tmpHqProc->hqE->cell->tenbStats->sch.dlDtx[tbCb->tbIdx][tbCb->dlGrnt.rv]++; + ue->tenbStats->stats.nonPersistent.sch[RG_SCH_CELLINDEX(tmpHqProc->hqE->cell)].dlDtxCnt[tbCb->tbIdx] ++; +#endif + + node = node->next; + /* If This is not the last repetition */ + if (tbCb->fbkRepCntr > 1) + { + /* Update feedback time for this process so that + * next subframe its picked up */ +#ifdef LTE_ADV + U8 servCellIdx = rgSchUtlGetServCellIdx( + tmpHqProc->hqE->cell->instIdx, + tmpHqProc->hqE->cell->cellId, + ue); + anInfo = rgSCHUtlGetUeANFdbkInfo(ue, &tbCb->fdbkTime,servCellIdx); +#else + anInfo = rgSCHUtlGetUeANFdbkInfo(ue, &tbCb->fdbkTime,0); +#endif + if(anInfo == NULLP) + { + RETVALUE(RFAILED); + } + RGSCH_NULL_CHECK(cellCb->instIdx, nxtDlsf); + RGSCH_UPD_HQAN_FDBKTIME(tbCb, nxtDlsf, nxtfrm); + RGSCH_UPD_ANINFO_WITH_HQ(anInfo, tbCb); + rgSCHUtlDlHqPTbRmvFrmTx(dlSf,tmpHqProc,tbCb->tbIdx, TRUE); + tbCb->fbkRepCntr--; + continue; + } + else + { + rgSCHUtlDlHqPTbRmvFrmTx(dlSf,tmpHqProc,tbCb->tbIdx, TRUE); + + if (((tbCb->nackCount + tbCb->dtxCount) >= tbCb->ackCount)) + { + /*even if one NACK, we consider the feedback + * on a whole as NACk */ + if ( tbCb->nackCount != 0 ) + { + tbCb->isAckNackDtx = TFU_HQFDB_NACK; + } + else + { + tbCb->isAckNackDtx = TFU_HQFDB_DTX; + } + + { + /* Delete the Harq Association. Release the Harq Process */ + rgSCHDhmHqTbTrnsFail(cellCb, tmpHqProc, tbCb->tbIdx, &maxRetx); + } + }/*if(((tbCb->nackCount+....*/ + }/*else....*/ + + if (tbCb->taSnt == TRUE) + { + /* [ccpu00127148] Correcting the check */ + if (TRUE == maxRetx) + { + tbCb->taSnt = FALSE; + ue->dl.taCb.state = RGSCH_TA_IDLE; + + rgSCHUtlReTxTa(cellCb, ue); + RLOG_ARG0(L_DEBUG,DBG_CELLID,cellCb->cellId, + "Nack/DTX Rcvd for TA. Max Tries Attempted"); + + } + } + } + } + RETVALUE(ROK); +}/* rgSCHDhmRlsDlsfHqProc */ +#else /* ifdef LTE_TDD */ +/** + * @brief Handler for Removing the HARQ process from a dlsf. + * + * @details + * + * Function : rgSCHDhmRlsDlsfHqProc + * + * This function shall be invoked for every tti. It goes back to + * to the sixth last subframe to check whether it still exists. If + * that exists this function traverses through the entire harq + * proc list associated and frees up all of them. + * + * @param[in] RgSchCellCb *cell + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 rgSCHDhmRlsDlsfHqProc +( +RgSchCellCb *cell, +CmLteTimingInfo timingInfo +) +#else +PUBLIC S16 rgSCHDhmRlsDlsfHqProc(cell, timingInfo) +RgSchCellCb *cell; +CmLteTimingInfo timingInfo; +#endif +{ + RgSchDlSf *sf; + CmLteTimingInfo frm; + RgSchDlHqProcCb *tmpHqProc; + Bool maxRetx; + CmLList *node; + CmLList *hqPNode; + U8 idx; + RgSchDlHqTbCb *tbCb; + RgSchUeCb *ue; + + TRC2(rgSCHDhmRlsDlsfHqProc) + + /* Fetch the current timing info. Modify it to Last sf to be rlsd.*/ + /* ccpu00133109: Removed RGSCHSUBFRMCRNTTIME as it is not giving proper + * output if diff is more than 10. Instead using RGSCHDECRFRMCRNTTIME() + * as it is serving the purpose */ + RGSCHDECRFRMCRNTTIME(timingInfo, frm, RG_SCH_CMN_HARQ_INTERVAL); + + + /* Get the required Last subframe */ + sf = rgSCHUtlSubFrmGet(cell, frm); + + /*CA Dev Start*/ + /*Handling for Msg4*/ + node = sf->msg4HqPLst.first; + while (node) + { + tmpHqProc = (RgSchDlHqProcCb *)(node->node); + if (HQ_TB_WAITING == tmpHqProc->tbInfo[0].state) + { + tbCb = &tmpHqProc->tbInfo[0]; + /* Fix : syed MultiUe per TTI crash in TA List. */ + maxRetx = FALSE; + + RGSCHDBGINFO(cell->instIdx, (rgSchPBuf(cell->instIdx),"\n rgSCHDhmRlsDlsfHqProc():\ + txCntr=%d tmpHqProc=%d",tbCb->txCntr,tmpHqProc->procId)); + + tbCb->dtxCount++; + if ((tmpHqProc->hqE->msg4Proc == tmpHqProc) || + (tmpHqProc->hqE->ccchSduProc == tmpHqProc)) + { + tbCb->isAckNackDtx = TFU_HQFDB_NACK; + rgNumMsg4Dtx++; + } + + node = node->next; + if (tbCb->fbkRepCntr != 0) + { + /* Update timingInfo for this hqP so that next subframe its picked up */ + RG_SCH_ADD_TO_CRNT_TIME(tbCb->timingInfo, tbCb->timingInfo, 1); + rgSCHUtlDlHqPTbRmvFrmTx(sf,tmpHqProc,tbCb->tbIdx, TRUE); + tbCb->fbkRepCntr--; + continue; + } + rgSCHUtlDlHqPTbRmvFrmTx(sf,tmpHqProc,tbCb->tbIdx, FALSE); + + /* Delete the Harq Association. Release the Harq Process */ + rgSCHDhmHqTbTrnsFail(cell, tmpHqProc, tbCb->tbIdx, &maxRetx); + + } + } + /* Subframe is present. Delete all the harq associations from + * this subframe. + */ + node = sf->ueLst.first; + while (node) + { + ue = (RgSchUeCb *)(node->node); + node = node->next; + if(ue != NULLP) + { + hqPNode = ue->dl.dlSfHqInfo[cell->cellId][sf->dlIdx].hqPLst.first; + + while (hqPNode) + { + tmpHqProc = (RgSchDlHqProcCb *)hqPNode->node; + tmpHqProc->cwSwpEnabled = FALSE; + hqPNode = hqPNode->next; + for (idx = 0 ;idx < 2; idx++) + { + if (HQ_TB_WAITING == tmpHqProc->tbInfo[idx].state) + { + tbCb = &tmpHqProc->tbInfo[idx]; + /* Fix : syed MultiUe per TTI crash in TA List. */ + maxRetx = FALSE; + + RGSCHDBGINFO(cell->instIdx, (rgSchPBuf(cell->instIdx),"\n rgSCHDhmRlsDlsfHqProc():\ + txCntr=%d tmpHqProc=%d",tbCb->txCntr,tmpHqProc->procId)); + + tbCb->dtxCount++; + if ((tmpHqProc->hqE->msg4Proc == tmpHqProc) || + (tmpHqProc->hqE->ccchSduProc == tmpHqProc)) + { + tbCb->isAckNackDtx = TFU_HQFDB_NACK; + rgNumMsg4Dtx++; + } + else + { + tbCb->isAckNackDtx = TFU_HQFDB_DTX; + } + + rgSCHUtlDlHqPTbRmvFrmTx(sf,tmpHqProc,idx, FALSE); + + { + /* Delete the Harq Association. Release the Harq Process */ + rgSCHDhmHqTbTrnsFail(cell, tmpHqProc, tbCb->tbIdx, &maxRetx); + } + if (tbCb->taSnt == TRUE) + { + /* [ccpu00127148] Correcting the check */ + if (TRUE == maxRetx) + { + tbCb->taSnt = FALSE; + ue->dl.taCb.state = RGSCH_TA_IDLE; + + rgSCHUtlReTxTa(cell, ue); + RGSCHDBGINFO(cell->instIdx, (rgSchPBuf(cell->instIdx), + "Nack/DTX Rcvd for TA. Max Tries Attempted\n")); + } + } + RgSchCmnDlUe *ueDl = RG_SCH_CMN_GET_DL_UE(ue,cell); + ueDl->mimoInfo.cwInfo[tbCb->tbIdx].dtxCnt++; + } + } + } + } + } + /*CA Dev End*/ + + RETVALUE(ROK); +} /* rgSCHDhmRlsDlsfHqProc */ +#endif +#ifdef LTEMAC_SPS +#ifdef RG_UNUSED +/** + * @brief This function marks the HARQ process with a given ID as SPS HARQ + * proc + * + * @details + * + * Function: rgSCHDhmMarkSpsHqProc + * Purpose: This function returns the HARQ process with the given ID. + * Invoked by: SPS Module + * Processing steps: + * - Get the HARQ process by index from the UE + * - Set isSpsHqProc = TRUE + * + * @param[in] RgSchUeCb *ue + * @param[in] U8 idx + * @return S16 + * -# ROK if successful + * -# RFAILED otherwise + * + **/ +#ifdef ANSI +PUBLIC S16 rgSCHDhmMarkSpsHqProc +( +RgSchUeCb *ue, +U8 idx +) +#else +PUBLIC S16 rgSCHDhmMarkSpsHqProc(ue, idx) +RgSchUeCb *ue; +U8 idx; +#endif +{ + RgSchDlHqProcCb *hqP; + TRC2(rgSCHDhmMarkSpsHqProc) + + /* Pick the proc based on the index provided */ + rgSCHDhmGetHqProcFrmId(ue->cell, ue, idx, &hqP); + + RETVALUE(ROK); +} /* rgSCHDhmMarkSpsHqProc */ +#endif /* RG_UNUSED */ +#endif /* LTEMAC_SPS */ + +#ifndef LTE_TDD +/** * @brief Handler for HARQ feedback received for DL AckNack rep enabled UE + * + * @details + * + * Function : rgSCHDhmProcHqFdbkAckNackRep + * + * This function shall act on the feedback received from TOM for DL + * transmission. + * + * + * @param[in] RgSchDlHqProcCb *hqP + * @param[in] RgSchDlSf *sf + * @param[in] U8 tbCnt + * @param[in] U8 *isAck + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PRIVATE S16 rgSCHDhmProcHqFdbkAckNackRep +( +RgSchDlHqProcCb *hqP, +RgSchDlSf *sf, +U8 tbCnt, +U8 *isAck +) +#else +PRIVATE S16 rgSCHDhmProcHqFdbkAckNackRep(hqP,sf,tbCnt,isAck) +RgSchDlHqProcCb *hqP; +RgSchDlSf *sf; +U8 tbCnt; +U8 *isAck; +#endif +{ + TRC2(rgSCHDhmProcHqFdbkAckNackRep) + /* Check if this is repeating UE */ + rgSCHUtlDlHqPTbRmvFrmTx(sf, hqP, tbCnt, TRUE); + /* Check if last repetition */ + if (--hqP->tbInfo[tbCnt].fbkRepCntr) + { + /* Update timingInfo for this hqP so that next subframe its picked up */ + RG_SCH_ADD_TO_CRNT_TIME(hqP->tbInfo[tbCnt].timingInfo, \ + hqP->tbInfo[tbCnt].timingInfo, 1); + RETVALUE(RFAILED); + } + + /* Take decision here based on the number + * of DTX's,NACK's and ACK's received + */ + if (((hqP->tbInfo[tbCnt].ackCount) > (hqP->tbInfo[tbCnt].nackCount) + + (hqP->tbInfo[tbCnt].dtxCount))) + { + *isAck = TFU_HQFDB_ACK; + } + /*even a single NACK indicates that UE received + * the transmission. + */ + else if ( hqP->tbInfo[tbCnt].nackCount != 0 ) + { + *isAck = TFU_HQFDB_NACK; + } + else + { + *isAck = TFU_HQFDB_DTX; + } + + + hqP->tbInfo[tbCnt].isAckNackDtx = *isAck; + RETVALUE(ROK); +} +#endif /* ifndef LTE_TDD */ + + +/* Freeing up the HARQ proc blocked for + * indefinite time in case of Retx */ +/** + * @brief This function handles the scenario in case Retx allocation is failed. + * + * @details + * + * Function: rgSCHDhmDlRetxAllocFail + * Purpose: + * + * @param[in] RgSchUeCb *ue + * @param[in] RgSchDlHqProcCb *hqP + * @return Void + * + **/ +#ifdef ANSI +PUBLIC S16 rgSCHDhmDlRetxAllocFail +( +RgSchUeCb *ue, +RgSchDlHqProcCb *hqP +) +#else +PUBLIC S16 rgSCHDhmDlRetxAllocFail(ue, hqP) +RgSchUeCb *ue; +RgSchDlHqProcCb *hqP; +#endif +{ + RgSchCellCb *cell; + RgInfRlsHqInfo *rlsHqInfo; + Pst pst; + Bool maxRetx = FALSE; + RgSchCmnCell *cellSch; + + TRC2(rgSCHDhmDlRetxAllocFail); + + cell = hqP->hqE->cell; + cellSch = RG_SCH_CMN_GET_CELL(cell); + rlsHqInfo = &(cell->rlsHqArr[cell->crntHqIdx]); + + /* If retx was attempted for 1st TB, increment its retx alloc fail counter */ + if (hqP->tbInfo[0].state == HQ_TB_NACKED) + { + hqP->tbInfo[0].cntrRetxAllocFail++; + } + + /* If retx was attempted for 2nd TB, increment its retx alloc fail counter */ + if (hqP->tbInfo[1].state == HQ_TB_NACKED) + { + hqP->tbInfo[1].cntrRetxAllocFail++; + } + + /* initialize MAC-SCH interface HARQ release info */ + rlsHqInfo->numUes = 0; + rlsHqInfo->ueHqInfo[rlsHqInfo->numUes].numOfTBs = 0; + + /* Release HARQ proc for TB1 if Retx alloc failure count has reached max */ + if (hqP->tbInfo[0].cntrRetxAllocFail == RG_SCH_MAX_RETX_ALLOC_FAIL) + { + if (hqP->hqE->msg4Proc == hqP) + { + hqP->tbInfo[0].txCntr = cell->dlHqCfg.maxMsg4HqTx; + } + else + { + hqP->tbInfo[0].txCntr = hqP->hqE->maxHqTx; + } + + rgSCHDhmHqTbTrnsFail(cell, hqP, hqP->tbInfo[0].tbIdx, &maxRetx); + +#ifdef LTE_L2_MEAS + if (maxRetx) + { + rlsHqInfo->ueHqInfo[rlsHqInfo->numUes].status[\ + rlsHqInfo->ueHqInfo[rlsHqInfo->numUes].numOfTBs] = 0xFF; /* RGU_NACK_LOSS */; + } + else + { + rlsHqInfo->ueHqInfo[rlsHqInfo->numUes].status[\ + rlsHqInfo->ueHqInfo[rlsHqInfo->numUes].numOfTBs] = FALSE; + } +#else + rlsHqInfo->ueHqInfo[rlsHqInfo->numUes].status[\ + rlsHqInfo->ueHqInfo[rlsHqInfo->numUes].numOfTBs] = FALSE; +#endif + + rlsHqInfo->ueHqInfo[rlsHqInfo->numUes].tbId[\ + rlsHqInfo->ueHqInfo[rlsHqInfo->numUes].numOfTBs] = 1; + rlsHqInfo->ueHqInfo[rlsHqInfo->numUes].numOfTBs++; + } + + /* Release HARQ proc for TB2 if Retx alloc failure count has reached max */ + if (hqP->tbInfo[1].cntrRetxAllocFail == RG_SCH_MAX_RETX_ALLOC_FAIL) + { + if (hqP->hqE->msg4Proc == hqP) + { + hqP->tbInfo[1].txCntr = cell->dlHqCfg.maxMsg4HqTx; + } + else + { + hqP->tbInfo[1].txCntr = hqP->hqE->maxHqTx; + } + + rgSCHDhmHqTbTrnsFail(cell, hqP, hqP->tbInfo[1].tbIdx, &maxRetx); + + rlsHqInfo->ueHqInfo[rlsHqInfo->numUes].status[\ + rlsHqInfo->ueHqInfo[rlsHqInfo->numUes].numOfTBs] = FALSE; + rlsHqInfo->ueHqInfo[rlsHqInfo->numUes].tbId[\ + rlsHqInfo->ueHqInfo[rlsHqInfo->numUes].numOfTBs] = 2; + rlsHqInfo->ueHqInfo[rlsHqInfo->numUes].numOfTBs++; + } + + /* MS_WORKAROUND for ccpu00122892 Temp fix for erroeneous RETX Harq release by rgSCHCmnDlAllocRetxRb */ + + if ((hqP->tbInfo[0].state != HQ_TB_NACKED) && + (hqP->tbInfo[1].state != HQ_TB_NACKED)) + { + cellSch->apisDl->rgSCHDlProcRmvFrmRetx(cell, ue, hqP); + } + + /* send HARQ release to MAC */ + if (rlsHqInfo->ueHqInfo[rlsHqInfo->numUes].numOfTBs > 0) + { + /* Fix : syed HO UE does not have a valid ue->rntiLnk */ + rlsHqInfo->ueHqInfo[rlsHqInfo->numUes].rnti = ue->ueId; + rlsHqInfo->ueHqInfo[rlsHqInfo->numUes].hqProcId = hqP->procId; + rlsHqInfo->numUes = 1; + + rgSCHUtlGetPstToLyr(&pst, &rgSchCb[cell->instIdx], cell->macInst); + RgSchMacRlsHq(&pst, rlsHqInfo); + } + + RETVALUE(ROK); +} + +#ifdef DL_LA +#ifdef ANSI +PRIVATE S16 rgSCHDhmUpdateAckNackHistory +( +RgSchCellCb *cell, +RgSchUeCb *ueCb, +U8 hqfdbk, +U8 tbCnt +) +#else +PRIVATE S16 rgSCHDhmUpdateAckNackHistory(cell, ueCb, hqfdbk, tbCnt) +( +RgSchCellCb *cell; +RgSchUeCb *ueCb; +U8 hqfdbk; +U8 tbCnt; +) +#endif +{ + RgSchCmnDlUe *ueDl; + + ueDl = RG_SCH_CMN_GET_DL_UE(ueCb,cell); + + /* + * If fdbk is ack update totalNoOfAck and ackNackHistory for + * current idx + */ + if (hqfdbk == TFU_HQFDB_ACK) + { + ueDl->laCb[tbCnt].deltaiTbs += DL_LA_STEPUP; + } + else + { + ueDl->laCb[tbCnt].deltaiTbs = ueDl->laCb[tbCnt].deltaiTbs - DL_LA_STEPDOWN; + } + /* + printf("deltaiTbs[%d] cqibasediTbs[%d] iTbs[%d] tbCnt[%d]\n", + ueDl->laCb[tbCnt].deltaiTbs, ueDl->laCb[tbCnt].cqiBasediTbs, + (ueDl->laCb[tbCnt].deltaiTbs + ueDl->laCb[tbCnt].cqiBasediTbs)/100, + tbCnt); + */ + rgSCHDhmUpdBlerBasediTbsEff(cell, ueCb, tbCnt); + + RETVALUE(ROK); +} + +#ifdef ANSI +PUBLIC S16 rgSCHDhmUpdBlerBasediTbsEff +( +RgSchCellCb *cell, +RgSchUeCb *ueCb, +U8 tbCnt +) +#else +PUBLIC S16 rgSCHDhmUpdBlerBasediTbsEff(cell, ueCb, tbCnt) +( +RgSchCellCb *cell; +RgSchUeCb *ueCb; +U8 tbCnt; +) +#endif +{ + S32 iTbs; + RgSchCmnDlUe *ueDl; + RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell); + U8 cfi = cellSch->dl.currCfi; + U8 maxiTbs = (*(RgSchCmnCqiToTbs *)(cellSch->dl.cqiToTbsTbl[0][cfi]))[RG_SCH_CMN_MAX_CQI - 1]; + maxiTbs = RG_SCH_DL_MAX_ITBS; + + ueDl = RG_SCH_CMN_GET_DL_UE(ueCb,cell); + iTbs = (ueDl->laCb[tbCnt].deltaiTbs + ueDl->laCb[tbCnt].cqiBasediTbs)/100; + + if (iTbs > maxiTbs) + { + ueDl->laCb[tbCnt].deltaiTbs = (maxiTbs * 100) - ueDl->laCb[tbCnt].cqiBasediTbs; + ueDl->mimoInfo.cwInfo[tbCnt].iTbs[0] = RGSCH_MIN(maxiTbs, ueCb->cell->thresholds.maxDlItbs); + } + else if (iTbs < 0) + { + ueDl->laCb[tbCnt].deltaiTbs = -(ueDl->laCb[tbCnt].cqiBasediTbs); + ueDl->mimoInfo.cwInfo[tbCnt].iTbs[0] = 0; + } + else + { + ueDl->mimoInfo.cwInfo[tbCnt].iTbs[0] = RGSCH_MIN(((ueDl->laCb[tbCnt].cqiBasediTbs +\ + ueDl->laCb[tbCnt].deltaiTbs)/100), + ueCb->cell->thresholds.maxDlItbs); + } +#ifdef RG_5GTF + ueCb->ue5gtfCb.mcs = ueDl->mimoInfo.cwInfo[tbCnt].iTbs[0]; +#endif + ueDl->mimoInfo.cwInfo[tbCnt].iTbs[1] = ueDl->mimoInfo.cwInfo[tbCnt].iTbs[0]; + + /* Eff for CW for 1 Layer Tx */ + ueDl->mimoInfo.cwInfo[tbCnt].eff[0] = + (*(RgSchCmnTbSzEff *)(cellSch->dl.cqiToEffTbl[0][cfi]))\ + [ueDl->mimoInfo.cwInfo[tbCnt].iTbs[0]]; + + /* Eff for CW for 2 Layer Tx */ + ueDl->mimoInfo.cwInfo[tbCnt].eff[1] = + (*(RgSchCmnTbSzEff *)(cellSch->dl.cqiToEffTbl[1][cfi]))\ + [ueDl->mimoInfo.cwInfo[tbCnt].iTbs[1]]; + + RETVALUE(ROK); +} +#endif + +#ifdef LTE_TDD +/** + * @brief This function Processes the Hq Fdbk in case of + * special Bundling in TDD (FAPIv1.1: Table 79) + * + * @details + * + * Function: rgSCHDhmPrcSplBundlFdbk + * Purpose: To Interpret the Harq Feedback according to + * table 7.3-1: 36.213 + * + * 0 = 0 or None (UE detect at least one DL is missed) + * 1 = 1 or 4 or 7 ACKs reported + * 2 = 2 or 5 or 8 ACKs reported + * 3 = 3 or 6 or 9 ACKs reported + * 4 = DTX (UE did not transmit anything) + * + * @param[in] TfuHqInfo *fdbk + * @param[in] U8 hqCnt + * @return Void + * + **/ +#ifdef ANSI +PRIVATE Void rgSCHDhmPrcSplBundlFdbk +( +RgSchCellCb *cell, +TfuHqInfo *fdbk, +U8 hqCnt +) +#else +PRIVATE Void rgSCHDhmPrcSplBundlFdbk(cell, fdbk, hqCnt) +( +RgSchCellCb *cell; +TfuHqInfo *fdbk; +U8 hqCnt; +) +#endif +{ + U8 numOfAcks; + + TRC2(rgSCHDhmPrcSplBundlFdbk); + + /* Num of ACKs reported by UE */ + numOfAcks = fdbk->isAck[0]; + + if(fdbk->isAck[0] == TFU_HQFDB_NACK || + fdbk->isAck[0] == TFU_HQFDB_DTX) + { + /* NACK/DTX CASE */ + } + else + { + RGSCH_ARRAY_BOUND_CHECK(cell->instIdx, + rgSchNumOfAcksToAckNack[(hqCnt-1)], (numOfAcks - 1)); + + fdbk->isAck[0] = rgSchNumOfAcksToAckNack[(hqCnt-1)] + [(numOfAcks-1)]; + } + /* The Hq Fdbk is a combined Ack/Nack for multiple Codewords within + the PDSCH trasnmission (spatial bundling). So we have + to assume same feedback for both codewords */ +#ifdef LTE_ADV + for(U8 idx = 1 ; idx < TFU_MAX_HARQ_FDBKS; idx++) + { + fdbk->isAck[idx] = fdbk->isAck[0]; + } +#else + fdbk->isAck[1] = fdbk->isAck[0]; +#endif + + RETVOID; +} +#endif + +/** + * @brief This function adds HARQ process to FREE list + * + * @details + * + * Function: rgSCHDhmHqPAdd2FreeLst + * Purpose: + * + * Invoked by: scheduler + * + * @param[out] RgDlHqProc *hqP + * @return Void + * + **/ +#ifdef ANSI +PUBLIC Void rgSCHDhmHqPAdd2FreeLst +( +RgSchDlHqProcCb *hqP +) +#else +PUBLIC Void rgSCHDhmHqPAdd2FreeLst(hqP) +RgSchDlHqProcCb *hqP; +#endif +{ + TRC2(rgSCHDhmHqPAdd2FreeLst) + +#ifdef LAA_DBG + if (hqP->hqPLst) + { + int *p = NULL; + printf("Crashing already part of free lst\n"); + printf("Crashing %d \n", *p); + *p = 10; + } +#endif + cmLListAdd2Tail(&hqP->hqE->free, &hqP->lnk); + hqP->hqPLst = &hqP->hqE->free; + + +#ifdef LAA_DBG + if (hqP->hqE->free.count > 8) + { + int *p = NULL; + printf("Crashing invalid hq count\n"); + printf("Crashing %d \n", *p); + *p = 10; + } +#endif + +#ifdef LTE_ADV + rgSCHLaaHndlHqProcFree(hqP); +#endif + + RETVOID; +} /* rgSCHDhmHqPAdd2FreeLst */ + + +/** + * @brief This function adds HARQ process to inUse list + * + * @details + * + * Function: rgSCHDhmHqPAdd2InUseLst + * Purpose: + * + * Invoked by: scheduler + * + * @param[out] RgDlHqProc *hqP + * @return Void + * + **/ +#ifdef ANSI +PUBLIC Void rgSCHDhmHqPAdd2InUseLst +( +RgSchDlHqProcCb *hqP +) +#else +PUBLIC Void rgSCHDhmHqPAdd2InUseLst(hqP) +RgSchDlHqProcCb *hqP; +#endif +{ + TRC2(rgSCHDhmHqPAdd2InUseLst) + +#ifdef LAA_DBG + if (hqP->hqPLst) + { + int *p = NULL; + printf("Crashing already part of inuse lst\n"); + printf("Crashing %d \n", *p); + *p = 10; + } +#endif + cmLListAdd2Tail(&hqP->hqE->inUse, &hqP->lnk); + hqP->hqPLst = &hqP->hqE->inUse; + + +#ifdef LAA_DBG + if (hqP->hqE->inUse.count > 8) + { + int *p = NULL; + printf("Crashing invalid hq count \n"); + printf("Crashing %d \n", *p); + *p = 10; + } +#endif + + RETVOID; +} /* rgSCHDhmHqPAdd2InUseLst */ + +/** + * @brief This function adds HARQ process to FREE list + * + * @details + * + * Function: rgSCHDhmHqPDelFrmFreeLst + * Purpose: + * + * Invoked by: scheduler + * + * @param[out] RgDlHqProc *hqP + * @return Void + * + **/ +#ifdef ANSI +PUBLIC Void rgSCHDhmHqPDelFrmFreeLst +( +RgSchDlHqProcCb *hqP +) +#else +PUBLIC Void rgSCHDhmHqPDelFrmFreeLst(hqP) +RgSchDlHqProcCb *hqP; +#endif +{ + TRC2(rgSCHDhmHqPDelFrmFreeLst) + +#ifdef LAA_DBG + if (!hqP->hqPLst) + { + int *p = NULL; + printf("Crashing not part of any lst\n"); + printf("Crashing %d \n", *p); + *p = 10; + } +#endif +#ifdef LAA_DBG + if (hqP->hqPLst != &hqP->hqE->free) + { + int *p = NULL; + printf("Crashing del from wrong lst\n"); + printf("Crashing %d \n", *p); + *p = 10; + } +#endif + + cmLListDelFrm(&hqP->hqE->free, &hqP->lnk); + hqP->hqPLst = NULLP; + +#ifdef LAA_DBG + if (hqP->hqE->free.count > 8) + { + int *p = NULL; + printf("Crashing invalid hq count\n"); + printf("Crashing %d \n", *p); + *p = 10; + } +#endif + + RETVOID; +} /* rgSCHDhmHqPDelFrmFreeLst */ + + + +/** + * @brief This function adds HARQ process to FREE list + * + * @details + * + * Function: rgSCHDhmHqPDelFrmInUseLst + * Purpose: + * + * Invoked by: scheduler + * + * @param[out] RgDlHqProc *hqP + * @return Void + * + **/ +#ifdef ANSI +PUBLIC Void rgSCHDhmHqPDelFrmInUseLst +( +RgSchDlHqProcCb *hqP +) +#else +PUBLIC Void rgSCHDhmHqPDelFrmInUseLst(hqP) +RgSchDlHqProcCb *hqP; +#endif +{ + TRC2(rgSCHDhmHqPDelFrmInUseLst) + +#ifdef LAA_DBG + if (!hqP->hqPLst) + { + int *p = NULL; + printf("Crashing not part of any lst\n"); + printf("Crashing %d \n", *p); + *p = 10; + + } +#endif +#ifdef LAA_DBG + if (hqP->hqPLst != &hqP->hqE->inUse) + { + int *p = NULL; + printf("Crashing del from wrong lst\n"); + printf("Crashing %d \n", *p); + *p = 10; + } +#endif + + cmLListDelFrm(&hqP->hqE->inUse, &hqP->lnk); + hqP->hqPLst = NULLP; + +#ifdef LAA_DBG + if (hqP->hqE->inUse.count > 8) + { + int *p = NULL; + printf("Crashing invalid hq count\n"); + printf("Crashing %d \n", *p); + *p = 10; + } +#endif + + RETVOID; +} /* rgSCHDhmHqPDelFrmInUseLst */ + + +/********************************************************************** + + End of file +**********************************************************************/ diff --git a/src/5gnrmac/rg_sch_drx.c b/src/5gnrmac/rg_sch_drx.c new file mode 100755 index 000000000..3b4058252 --- /dev/null +++ b/src/5gnrmac/rg_sch_drx.c @@ -0,0 +1,3249 @@ +/******************************************************************************* +################################################################################ +# Copyright (c) [2017-2019] [Radisys] # +# # +# 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. # +################################################################################ +*******************************************************************************/ + +/************************************************************************ + + Name: LTE-MAC layer + + Type: C source file + + Desc: C source code for DRX realted functions + + File: rg_sch_drx.c + +**********************************************************************/ + +/** @file rg_sch_drx.c +@brief This file implements the DRX processing . +*/ + +static const char* RLOG_MODULE_NAME="MAC"; +static int RLOG_MODULE_ID=4096; +static int RLOG_FILE_ID=163; + +/* header include files -- defines (.h) */ +#include "envopt.h" /* environment options */ +#include "envdep.h" /* environment dependent */ +#include "envind.h" /* environment independent */ +#include "gen.h" /* general layer */ +#include "ssi.h" /* system service interface */ +#include "cm_hash.h" /* common hash list */ +#include "cm_llist.h" /* common linked list library */ +#include "cm_err.h" /* common error */ +#include "cm_lte.h" /* common LTE */ +#include "lrg.h" +#include "rgr.h" +#include "rgm.h" +#include "tfu.h" +#include "rg_env.h" +#include "rg_sch_inf.h" +#ifdef LTEMAC_PH3_HDFDD +#include "rg_sch_hdfdd.h" +#endif /*LTEMAC_PH3_HDFDD*/ +#include "rg_sch.h" +#include "rg_sch_err.h" +#include "rg_sch_cmn.h" +#include "rl_interface.h" +#include "rl_common.h" + +/* header/extern include files (.x) */ +#include "gen.x" /* general layer typedefs */ +#include "ssi.x" /* system services typedefs */ +#include "cm5.x" /* common timers */ +#include "cm_hash.x" /* common hash list */ +#include "cm_lib.x" /* common library */ +#include "cm_llist.x" /* common linked list */ +#include "cm_mblk.x" /* memory management */ +#include "cm_tkns.x" /* common tokens */ +#include "cm_lte.x" /* common tokens */ +#include "tfu.x" /* TFU types */ +#include "lrg.x" /* layer management typedefs for MAC */ +#include "rgr.x" /* layer management typedefs for MAC */ +#include "rgm.x" /* layer management typedefs for MAC */ +#include "rg_sch_inf.x" /* typedefs for Scheduler */ +#ifdef LTEMAC_PH3_HDFDD +#include "rg_sch_hdfdd.x" +#endif /*LTEMAC_PH3_HDFDD*/ + +#include "rg_sch.x" /* typedefs for Scheduler */ +#include "rg_sch_cmn.x" + + /** + * @file rg_sch_drx.c This file gives the describes the design for DRX feature. + * + * DRX is Discontinuous Reception i.e. the UE in order to save some battery + * would not monitor (decode) PDCCHs at all times. Instead the UE is configured + * with a periodically occuring duration wherein it shall monitor PDCCHs. The UE + * can be called ACTIVE at this time, this time is a minimum of a configurable + * value - onDuration and a maximum of Infinity. + * + * ACTIVE time MIN (onDuration) MAX (infinity) + * + * A sample configuration is periodicity of 10 subframes (ms) and an offset + * value of 3. This can be represented as the diagram given below. The portion + * marked as ACTIVE is the onDuration and the UE monitors PDCCHs. + * + * @code + * + * <-ACTIVE-><---IN-ACTIVE------><-ACTIVE-><---IN-ACTIVE-- + * + * |__|__|__|--------|__|__|__|__|__|__|__|--------|__|__|__|__|__| + * 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 + * + * @endcode + */ +#ifdef LTE_TDD +/****************************************************************************** + * Structure definitions for TDD * + ******************************************************************************/ + +/** @brief : No of DL subframes in a particular TDD configuration + * + * @details : Special subframes in TDD can carry PDCCH if configured + * for DwPTS. For normal CP with subframe configruation (0-8) + * & extended CP with subframe configuration (0-6), Special + * Subframes can carry PDCCH and are represented in row 0. + * Extended CP with subframe configuraton (7-8), which do + * not carry PDCCH are represented in row 1. + * rgSchDrxDlSfTddCfg[1][2] represent number of DL subframes + * in TDD config 2 where DwPTS can carry PDCCH and + * rgSchDrxDlSfTddCfg[0][2] represent number of DL subframes + * in TDD config 2 where no DwPTS exits. + */ + +PRIVATE U8 rgSchDrxDlSfTddCfg[RGSCH_MAX_SFCFG][RGSCH_MAX_TDD_CFG] = +{ + {2,4,6,6,7,8,3}, + {4,6,8,7,8,9,5} +}; + +/** @brief : No of DL subframes till next SFN from a particular subframe + * + * @details :For a given Special subframe config + * (refer rgSchDrxDlSfTddCfg for an explanation) and given + * TDD config, how many DL subframes till Next SFN from this + * subframe onwards. + * + */ + +PRIVATE U8 rgSchDrxDLSfTillNxtSFN[RGSCH_MAX_SFCFG][RGSCH_MAX_TDD_CFG] + [RGSCH_NUM_SUB_FRAMES]= +{ + { + {2,1,1,1,1,1,0,0,0,0}, + {4,3,3,3,3,2,1,1,1,1}, + {6,5,5,5,4,3,2,2,2,1}, + {6,5,5,5,5,5,4,3,2,1}, + {7,6,6,6,6,5,4,3,2,1}, + {8,7,7,7,6,5,4,3,2,1}, + {3,2,2,2,2,2,1,1,1,1} + + }, + { + {4,3,2,2,2,2,1,0,0,0}, + {6,5,4,4,4,3,2,1,1,1}, + {8,7,6,6,5,4,3,2,1,1}, + {7,6,5,5,5,5,4,3,2,1}, + {8,7,6,6,6,5,4,3,2,1}, + {9,8,7,7,6,5,4,3,2,1}, + {5,4,3,3,3,3,2,1,1,1} + } +}; /*rgSchDrxDLSfTillNxtSFN*/ + + +/** @brief : Lookup table for DL subframe given the number of subframes + * + * @details :For a given Special subframe config + * (refer rgSchDrxDlSfTddCfg for an explanation) and given + * TDD config, the DL subframe index given the number of subframes + * + */ + +PRIVATE U8 rgSchDrxDLSftoDLSfIdx[RGSCH_MAX_SFCFG][RGSCH_MAX_TDD_CFG] + [RGSCH_NUM_SUB_FRAMES]= +{ + { + {5,0}, + {9,0,4,5}, + {9,0,3,4,5,8}, + {9,0,5,6,7,8}, + {9,0,4,5,6,7,8}, + {9,0,3,4,5,6,7,8}, + {9,0,5} + }, + { + {6,0,1,5}, + {9,0,1,4,5,6}, + {9,0,1,3,4,5,6,8}, + {9,0,1,5,6,7,8}, + {9,0,1,4,5,6,7,8}, + {9,0,1,3,4,5,6,7,8}, + {9,0,1,5,6} + } +};/* rgSchdrxDLSftoDLSfIdx*/ +/* ccpu00134196-[Add]-DRX retx timer changes */ +/* The k+4 th subframe in TDD at which HARQ RTT expires may be an Uplink SF. + In such case, the drx retx timer may start at the next pdcch sf instead + of at k+4 itself */ +U8 rgSchDrxHarqRetxFirstPsf[RGSCH_MAX_TDD_CFG][RGSCH_NUM_SUB_FRAMES] = { + {0, 0, 4, 0, 6, 0, 0, 4, 0, 6}, + {0, 0, 4, 6, 0, 0, 0, 4, 6, 0}, + {0, 0, 4, 0, 0, 0, 0, 4, 0, 0}, + {0, 0, 4, 4, 4, 0, 0, 0, 0, 0}, + {0, 0, 4, 4, 0, 0, 0, 0, 0, 0}, + {0, 0, 4, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 4, 6, 5, 0, 0, 4, 7, 0}, +}; +#endif /* LTE_TDD */ + +/****************************************************************************** + * Start of Function declarations * + ******************************************************************************/ +PRIVATE Void rgSCHDrxTtiHdlOnDurUl ARGS(( +RgSchCellCb *cell, +U16 ulIndex +)); +PRIVATE Void rgSCHDrxTtiHdlOnDurDl ARGS(( +RgSchCellCb *cell, +U16 dlIndex +)); +PRIVATE Void rgSCHDrxTtiHdlDlHarqRTT ARGS(( +RgSchCellCb *cell, +U16 dlIndex +)); +PRIVATE Void rgSCHDrxTtiHdlUlHarqRTT ARGS(( +RgSchCellCb *cell, +U16 ulIndex +)); + PRIVATE S16 rgSCHDrxTtiHdlOnDur ARGS((RgSchCellCb *cellCb, U16 dlIndex, + U16 ulIndex)); + PRIVATE S16 rgSCHDrxTtiHdlInActv ARGS((RgSchCellCb *cellCb, U16 dlIndex, + U16 ulIndex)); + PRIVATE S16 rgSCHDrxTtiHdlShortCycle ARGS((RgSchCellCb *cell, U16 dlIndex, + U16 ulIndex)); + PRIVATE S16 rgSCHDrxTtiHdlDlHarq ARGS((RgSchCellCb *cellCb, U16 dlIndex, + U16 ulIndex)); + PRIVATE S16 rgSCHDrxCpyUeCfg ARGS((RgSchDrxUeCb *drxCb, + RgrUeDrxCfg* ueDrxCfg)); + + PRIVATE S16 rgSCHDrxGetNxtOnDur ARGS((RgSchCellCb* cell,RgSchDrxUeCb* drxCb, + CmLteTimingInfo* nxtOnDur, + U8 delta)); + +PRIVATE Void rgSCHDrxMvToNxtOnDurOcc ARGS((RgSchCellCb* cell, + RgSchUeCb* ue, + U16 idx, + Bool calcFrmOffst)); +#ifdef LTE_TDD +PRIVATE Void rgSCHDrxCalcNxtTmrExpry ARGS((RgSchCellCb *cell, + RgSchUeCb *ue, + U16 delta, + U32 tmrLen, + S16 *distance, + U16 *idx + )); +PRIVATE S16 rgSCHDrxGetNxtTmrExpry ARGS((RgSchCellCb *cell,U16 curTime, + U32 duration, + CmLteTimingInfo* tmrExpryIdx)); +#endif /* LTE_TDD */ +#ifdef EMTC_ENABLE +EXTERN S16 rgSCHEmtcDrxCpyUeCfg +( + RgSchUeCb *ueCb, + RgrUeDrxCfg *drxCfg +); +EXTERN S16 rgSCHDrxTtiHdlUlHarq +( +RgSchCellCb *cell, +U16 dlIndex, +U16 ulIndex +); +EXTERN Void rgSCHDrxUeUlHqReset +( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgUeUlHqCb *hqE +); + +#endif + +/** @brief This function handles the per TTI handling of the DRX module. + * Invoked by rgSCHTti @sa rgSCHTti. + * + * @details This function goes through the drxQ and marks the UE as ACTIVE or + * INACTIVE based on the timers and thier status. + * + * Function: rgSCHDrxTtiInd + * + * Processing steps: + * - Processing is divided into respective timer handling. + * - Calculate the DL and UL indices as follows + * @code + * dlIndex = (cell->crntTime.sfn * 10 + cell->crntTime.subframe + + * RG_SCH_DRX_DL_DELTA) % RG_SCH_MAX_DRXQ_SIZE; + * + * ulIndex = (cell->crntTime.sfn * 10 + cell->crntTime.subframe + + * RG_SCH_DRX_UL_DELTA) % RG_SCH_MAX_DRXQ_SIZE; + * @endcode + * - Call rgSCHDrxTtiHdlOnDur to handle onDurationTimer handling + * - Call rgSCHDrxTtiHdlInActv to handle drx-InactivityTimer handling + * - Call rgSCHDrxTtiHdlShortCycle to handle Short cycle timer. + * - Call rgSCHDrxTtiHdlDlHarq to handle HARQ RTT and drx-retransmission + * timers. + * - Call rgSchDrxTtiHdlUlHarq to handle Uplink HARQ processing - + * related to ACTIVITY when a UE is expecting a grant for an uplink + * re-transmissions. + * - Post this processing the ueCb->dlInactvMask's DRX Bit shall be set + * or reset to denote ACTIVITY or INACTIVITY respectively. + * - Post this processing the ueCb->ulInactvMask's DRX Bit shall be set + * or reset to denote ACTIVITY or INACTIVITY respectively. + * - Add the UE to the list of Active/inactive UEs. + * + * @param RgSchCellCb *cell + * @param [out] CmLListCp *dlInactvLst List to which the DL in-active UEs are + * added* + * @return + */ +#ifdef ANSI +PUBLIC Void rgSCHDrxTtiInd +( +RgSchCellCb *cell +) +#else +PUBLIC Void rgSCHDrxTtiInd (cell) +RgSchCellCb *cell; +#endif +{ + U16 dlIndex; + U16 ulIndex; + + TRC2(rgSCHDrxTtiInd ); + + + dlIndex = (cell->crntTime.sfn * RGSCH_NUM_SUB_FRAMES_5G + cell->crntTime.subframe + + RG_SCH_DRX_DL_DELTA) % RG_SCH_MAX_DRXQ_SIZE; + + ulIndex = (cell->crntTime.sfn * RGSCH_NUM_SUB_FRAMES_5G + cell->crntTime.subframe + + RG_SCH_DRX_UL_DELTA) % RG_SCH_MAX_DRXQ_SIZE; + +#ifdef LTEMAC_R9 + rgSCHDrxTtiHdlDlHarq (cell, dlIndex, ulIndex); + /* checks the Ul-Retransmission timer */ +#ifdef EMTC_ENABLE + if(cell->emtcEnable) + { + rgSCHDrxTtiHdlUlHarq (cell, dlIndex, ulIndex); + } +#endif + rgSCHDrxTtiHdlInActv(cell, dlIndex, ulIndex); + + /*Process Short cycle expiry before On duration timer so that long cycles + * On Duration can be processed if timer has expired*/ + rgSCHDrxTtiHdlShortCycle (cell, dlIndex, ulIndex); + rgSCHDrxTtiHdlOnDur(cell, dlIndex, ulIndex); + +#else /*LTEMAC_R9*/ + rgSCHDrxTtiHdlOnDur(cell, dlIndex, ulIndex); + rgSCHDrxTtiHdlDlHarq (cell, dlIndex, ulIndex); + /* checks the Ul-Retransmission timer */ +#ifdef EMTC_ENABLE + if(cell->emtcEnable) + { + rgSCHDrxTtiHdlUlHarq (cell, dlIndex, ulIndex); + } +#endif + rgSCHDrxTtiHdlInActv(cell, dlIndex, ulIndex); + rgSCHDrxTtiHdlShortCycle (cell, dlIndex, ulIndex); + +#endif /*LTEMAC_R9*/ + + RETVOID; + +}/*rgSCHDrxTtiInd*/ + +/** @brief This function is called to handle onDurationTimer per TTI processing. + * + * @details + * Invoked by - rgSCHDrxTtiInd + * + * Function: rgSCHDrxTtiHdlOnDur + * + * Processing steps: + * + * - OnDurationTimer is handled using the drxQ @sa RgSchDrxQ + * + * - For Downlink we shall look at an index that is + * n + RG_SCH_DRX_DL_DELTA. + * + * + * - For Uplink we shall look at an index that is + * n + RG_SCH_DRX_UL_DELTA as + * we are concerned with the PDCCH and not the actual PUSCH. + * + * + * @param RgSchCellCb *cellCb + * @param U16 dlIndex + * @param U16 ulIndex + * @return ROK/RFAILED + */ + +#ifdef ANSI +PRIVATE S16 rgSCHDrxTtiHdlOnDur +( +RgSchCellCb* cell, +U16 dlIndex, +U16 ulIndex +) +#else +PRIVATE S16 rgSCHDrxTtiHdlOnDur(cell, dlIndex, ulIndex) +RgSchCellCb* cell; +U16 dlIndex; +U16 ulIndex; +#endif +{ + + TRC2(rgSCHDrxTtiHdlOnDur); + +#if ( ERRCLASS & ERRCLS_INT_PAR ) + if ( cell == (RgSchCellCb* )NULLP ) + { + RETVALUE(RFAILED); + } +#endif + + rgSCHDrxTtiHdlOnDurDl(cell,dlIndex); + + rgSCHDrxTtiHdlOnDurUl(cell, ulIndex); + + RETVALUE(ROK); + +}/*rgSCHDrxTtiHdlOnDur*/ + + +/** @brief This function handles the processing for drxInactityTimer per TTI + * + * @details + * Invoked by - rgSCHDrxTtiInd + * + * Function: rgSCHDrxTtiHdlInActv + * + * Processing steps: + * + * - For Downlink we shall look at an index that is + * n + RG_SCH_DRX_DL_DELTA of the drxQ. + * + * - MARK UE AS INACTIVE BASED ON DRX-INACTIVITY TIMER EXPIRY + * + * + * - For Uplink we shall look at an index that is + * n + RG_SCH_DRX_UL_DELTA as + * we are concerned with the PDCCH and not the actual PUSCH. + * + * + * @param RgSchCellCb *cellCb + * @param U16 dlIndex + * @param U16 ulIndex + * @return ROK/RFAILED + */ + +#ifdef ANSI +PUBLIC S16 rgSCHDrxTtiHdlInActv +( +RgSchCellCb *cell, +U16 dlIndex, +U16 ulIndex +) +#else +PUBLIC S16 rgSCHDrxTtiHdlInActv(cell, dlIndex, ulIndex) +RgSchCellCb *cell; +U16 dlIndex; +U16 ulIndex; +#endif +{ + CmLList *node; + RgSchDRXCellCb *drxCell=NULLP; + RgSchUeCb *ue=NULLP; + RgSchDrxUeCb *drxUe=NULLP; + U16 shrtCycleExpIndx; + CmLListCp dlInactvLst; /* list of UE's becoming DL-inactive */ + CmLListCp ulInactvLst; /* list of UE's becoming UL-inactive */ + RgSchCmnCell *cellSch = NULLP; + Bool delInUlScan = FALSE; + + TRC2(rgSCHDrxTtiHdlInActv); + +#if ( ERRCLASS & ERRCLS_INT_PAR ) + if ( cell == (RgSchCellCb* )NULLP) + { + RETVALUE(RFAILED); + } +#endif + + + drxCell = (cell->drxCb); + delInUlScan = drxCell->delInUlScan; + + + /*********************************************************** + * Scanning inActvitiyQ in DL + ***********************************************************/ + + /* The DL loop will scan for UE's whose inactivity timer has + * expired. It will switch the cycle to short or long based + * on the cycle configured. + * Furhter,if !delInUlScan, then will remove the UE from the + * inactivity q. + */ + + node = drxCell->drxQ[dlIndex].inActvTmrQ.first; + + /* Initialize DL inactive list */ + cmLListInit(&dlInactvLst); + + /* Initialize UL inactive list */ + cmLListInit(&ulInactvLst); + + while (node) + { + ue = (RgSchUeCb*)node->node; + node = node->next; + drxUe = RG_SCH_DRX_GET_UE(ue); + + if ( delInUlScan == TRUE) + { + drxUe->drxInactDistance--; + } + + if ( drxUe->drxInactDistance != DRX_TMR_EXPRD ) + { + continue; + } + + /* UE is inactive as inactivity timer has expired */ + drxUe->drxDlInactvMask |= RG_SCH_DRX_INACTVTMR_BITMASK; + + + /* update the ue mask only if no condition in drx + * is keeping ue active + */ + if ( !RG_SCH_DRX_DL_IS_UE_ACTIVE(drxUe)) + { + /* set the UE has DRX inactive */ + ue->dl.dlInactvMask |= RG_DRX_INACTIVE; + + /* Add to DL inactive list */ + cmLListAdd2Tail(&dlInactvLst,&(ue->dlDrxInactvLnk)); + ue->dlDrxInactvLnk.node = (PTR)ue; + } + + /*Remove from the queue if !delInUlScan */ + if( delInUlScan == FALSE ) + { + cmLListDelFrm(&(drxCell->drxQ[dlIndex].inActvTmrQ), + &(drxUe->inActvTmrEnt)); + + drxUe->drxInactvIndx = DRX_INVALID; + + }/* if (delInUlScan == FALSE) */ + + if (drxUe->isShortCycleCfgd) + { + /* add shorty cycle expirty */ + drxUe->isLongCycle = FALSE; + + shrtCycleExpIndx = (dlIndex + (drxUe->shortCycleTmrLen * + drxUe->shortDrxCycle)) % RG_SCH_MAX_DRXQ_SIZE; + + drxUe->drxShortCycleDistance = (drxUe->shortCycleTmrLen * + drxUe->shortDrxCycle) / RG_SCH_MAX_DRXQ_SIZE; + + /*Remove the UE from existing index*/ + if (drxUe->shortCycleIndx != DRX_INVALID) + { + cmLListDelFrm(&(drxCell->drxQ[drxUe->shortCycleIndx].shortCycleQ), + &(drxUe->shortCycleEnt)); + } + + cmLListAdd2Tail(&(drxCell->drxQ[shrtCycleExpIndx].shortCycleQ), + &(drxUe->shortCycleEnt)); + + drxUe->shortCycleEnt.node = (PTR)ue; + drxUe->shortCycleIndx = shrtCycleExpIndx; + + /*Calculate onDuration again & move the + * ueCb to the next Onduration occurence + */ + + /*we maybe at any position in the RF timeline, + * need to calculate onDuration from the starting + * offset + */ + rgSCHDrxMvToNxtOnDurOcc(cell,ue,RG_SCH_DRX_DL_DELTA,TRUE); + + }/*isShortCycleCfgd */ + else + { + /* use the long cycle */ + drxUe->isLongCycle = TRUE; + }/*isLongCycle*/ + }/*while(node) */ + + + + /*********************************************************** + * Scanning inActvitiyQ in UL + ***********************************************************/ + + /* The UL loop will scan for UE's whose inactivity timer has + * expired and mark the UE's UL inactive. + * Furhter,if delInUlScan, then will remove the UE from the + * inactivity q. + */ + + /* For Uplink we shall look at an index that is n + RG_SCH_DRX_UL_DELTA as + we are concerned with the PDCCH and not the actual PUSCH.*/ + + + + node = drxCell->drxQ[ulIndex].inActvTmrQ.first; + + + while (node) + { + ue = (RgSchUeCb*)node->node; + node = node->next; + drxUe = RG_SCH_DRX_GET_UE(ue); + + if ( delInUlScan == FALSE) + { + drxUe->drxInactDistance--; + } + + if ( drxUe->drxInactDistance != DRX_TMR_EXPRD ) + { + continue; + } + + /* Need to mark the UE as inactive due to expiry of + * DRX inactivity timer */ + + /* UE is inactive as inactivity timer has expired */ + drxUe->drxUlInactvMask |= RG_SCH_DRX_INACTVTMR_BITMASK; + + /* update the ue mask only if no other condition in + * drx is keeping ue active */ + + if (!RG_SCH_DRX_UL_IS_UE_ACTIVE(drxUe)) + { + /* set the inactivity bit */ + ue->ul.ulInactvMask |= RG_DRX_INACTIVE; + + /* Add to Ul inactive list */ + cmLListAdd2Tail(&ulInactvLst,&(ue->ulDrxInactvLnk)); + ue->ulDrxInactvLnk.node = (PTR)ue; + } + + if ( delInUlScan == TRUE) + { + /* remove from queue */ + cmLListDelFrm(&(drxCell->drxQ[ulIndex].inActvTmrQ), + &(drxUe->inActvTmrEnt)); + + drxUe->drxInactvIndx = DRX_INVALID; + + }/* if ( delInUlScan == TRUE) */ + }/*while(node) for uplink */ + + + /* Send the list to the scheduler to mark UE as inactive in UL*/ + cellSch = RG_SCH_CMN_GET_CELL(cell); + cellSch->apisUl->rgSCHUlInactvtUes(cell, &ulInactvLst); + + /* Send the DL inactive list to the scheduler to mark UE as inactive */ + cellSch = RG_SCH_CMN_GET_CELL(cell); + cellSch->apisDl->rgSCHDlInactvtUes(cell,&dlInactvLst); + + RETVALUE(ROK); +}/*rgSCHDrxTtiHdlInActv*/ + + /** @brief This function handles the per TTI processing for DRX short cycle + * timer. + * + * @details + * Invoked by - rgSCHDrxTtiInd + * + * Function: rgSCHDrxTtiHdlShortCycle + * + * Processing steps: + * - For downlink + * + * in addition we have to mark the ues based on drx short cycle + * expiry + * + * + * @param RgSchCellCb *cell + * @param U16 dlIndex + * @param U16 ulIndex + * @return ROK/RFAILED + */ + +#ifdef ANSI +PUBLIC S16 rgSCHDrxTtiHdlShortCycle +( +RgSchCellCb *cell, +U16 dlIndex, +U16 ulIndex +) +#else +PUBLIC S16 rgSCHDrxTtiHdlShortCycle (cell, dlIndex, ulIndex) +RgSchCellCb *cell; +U16 dlIndex; +U16 ulIndex; +#endif +{ + CmLList *node; + RgSchDRXCellCb *drxCell=NULLP; + RgSchUeCb *ue=NULLP; + RgSchDrxUeCb *drxUe=NULLP; + + TRC2(rgSCHDrxTtiHdlShortCycle ); + +#if ( ERRCLASS & ERRCLS_INT_PAR ) + if ( cell == (RgSchCellCb* )NULLP ) + { + RETVALUE(RFAILED); + } +#endif + + UNUSED(ulIndex); + + + drxCell = RG_SCH_DRX_GET_CELL(cell); + + node = drxCell->drxQ[dlIndex].shortCycleQ.first; + + while (node) + { + ue = (RgSchUeCb*)node->node; + node = node->next; + drxUe = RG_SCH_DRX_GET_UE(ue); + + if ( --drxUe->drxShortCycleDistance != DRX_TMR_EXPRD) + { + continue; + } + + /* mark the UE's current cycle to be long */ + drxUe->isLongCycle = TRUE; + + /* remove from the shortCycleQ */ + + cmLListDelFrm(&(drxCell->drxQ[dlIndex].shortCycleQ), + &(drxUe->shortCycleEnt)); + drxUe->shortCycleIndx = DRX_INVALID; + + /* Remove from onDuration queue inserted based on short cycle + * and calculate onDuration based on long cycle.*/ + rgSCHDrxMvToNxtOnDurOcc(cell,ue,RG_SCH_DRX_DL_DELTA,TRUE); + }/*while(node)...*/ + + RETVALUE(ROK); +}/*rgSCHDrxTtiHdlShortCycle*/ + + + /** @brief This function handles the HARQ timer's processing per TTI. + * + * @details + * Invoked by - rgSCHDrxTtiInd + * + * Function: rgSCHDrxTtiHdlDlHarq + * + * Processing steps: + * - In addition per TTI DRX module must look at Downlink HARQ queues + * maintained to track HARQ RTT timer and drx-RetransmissionTimer. + * Every TTI at the scheduling index we shall check these queues and + * process accordingly. + * + * + * - Though these timers are related to downlink HARQ processing, they + * have an impact on uplink scheduling. The reason is that the UE, + * if active for downlink scheduling implies that it is reading + * PDCCHs i.e. we can still send uplink allocations to the UE. Hence + * every TTI Uplink too would look at the harqRTTQ and harqRetxQ. + * + * + * + * @param RgSchCellCb *cellCb + * @param U16 dlIndex + * @param U16 ulIndex + * @return ROK/RFAILED + */ + +#ifdef ANSI +PRIVATE S16 rgSCHDrxTtiHdlDlHarq +( +RgSchCellCb *cell, +U16 dlIndex, +U16 ulIndex +) +#else /* ANSI */ +PRIVATE S16 rgSCHDrxTtiHdlDlHarq (cell, dlIndex, ulIndex) +RgSchCellCb *cell; +U16 dlIndex; +U16 ulIndex; +#endif /* ANSI */ +{ + +#if ( ERRCLASS & ERRCLS_INT_PAR) + if ( cell == (RgSchCellCb *)NULLP ) + { + RETVALUE(RFAILED); + } +#endif /*ERRCLASS & ERRCLS_INT_PAR*/ + + + TRC2(rgSCHDrxTtiHdlDlHarq ); + + rgSCHDrxTtiHdlDlHarqRTT(cell, dlIndex); + + rgSCHDrxTtiHdlUlHarqRTT(cell, ulIndex); + + RETVALUE(ROK); +} + + /** @brief This function is called by the common scheduler as part of + * finalization of allocations in downlink. + * + * @details + * Invoked by - + * + * Function: rgSchDrxStrtInActvTmr + * + * This function is responsible to starting drx-InactivityTimer + * + * Processing steps: + * + * + * @param RgSchCellCb *cell + * @param CmLListCp *ueUlLst + * @param U8 direction + * @return Void + */ + +#ifdef ANSI +PUBLIC Void rgSCHDrxStrtInActvTmr +( +RgSchCellCb *cell, +CmLListCp *ueLst, +U8 direction +) +#else +PUBLIC Void rgSCHDrxStrtInActvTmr(cell, ueLst, direction) +RgSchCellCb *cell; +CmLListCp *ueLst; +U8 direction; +#endif +{ + CmLList *node; + CmLList *delNode; + RgSchUeCb *ueCb; + RgSchDrxUeCb *ueDrxCb; +#ifndef LTE_TDD + U16 index1; +#endif + U16 inActvTmrExpIndx; +#ifndef LTE_TDD + U16 curTimeInSf; /* current time in number of subframes */ +#endif +#ifdef LTE_TDD + U16 delta; +#endif /*LTE_TDD*/ + CmLListCp dlInactvLst; /* list of UE's becoming DL-inactive */ + CmLListCp ulInactvLst; /* list of UE's becoming UL-inactive */ + RgSchCmnCell *cellSch = NULLP; + Bool delInUlScan = FALSE; + + + TRC2(rgSCHDrxStrtInActvTmr); + + + if ( direction == RG_SCH_DRX_UL) + { +#ifndef LTE_TDD + curTimeInSf = (cell->crntTime.sfn * RGSCH_NUM_SUB_FRAMES_5G) + + (cell->crntTime.subframe) +RG_SCH_DRX_UL_DELTA; +#endif + +#ifdef LTE_TDD + delta = RG_SCH_DRX_UL_DELTA; +#endif /*LTE_TDD */ + } + else + { +#ifndef LTE_TDD + curTimeInSf = (cell->crntTime.sfn * RGSCH_NUM_SUB_FRAMES_5G) + + (cell->crntTime.subframe) + RG_SCH_DRX_DL_DELTA; +#endif + +#ifdef LTE_TDD + delta = RG_SCH_DRX_DL_DELTA; +#endif /*LTE_TDD */ + } + + + /* Initialize DL inactive list */ + cmLListInit(&dlInactvLst); + + /* Initialize UL inactive list */ + cmLListInit(&ulInactvLst); + + delInUlScan = cell->drxCb->delInUlScan; + +#ifndef LTE_TDD + index1 = (curTimeInSf) % RG_SCH_MAX_DRXQ_SIZE; +#endif + + node = ueLst->first; + + while(node) + { + ueCb = (RgSchUeCb *)node->node; + ueDrxCb = ueCb->drxCb; + + /* Stop inactivity timer */ + if ( ueDrxCb->drxInactvIndx != DRX_INVALID ) + { + cmLListDelFrm(&(cell->drxCb->drxQ[ueDrxCb->drxInactvIndx].inActvTmrQ), + &(ueDrxCb->inActvTmrEnt)); + } +#ifdef LTE_TDD + + rgSCHDrxCalcNxtTmrExpry(cell, + ueCb, + delta, + ueDrxCb->inactvtyTmrLen, + &(ueDrxCb->drxInactDistance), + &inActvTmrExpIndx + ); + +#else /*LTE_TDD*/ + inActvTmrExpIndx = (index1 + ueDrxCb->inactvtyTmrLen) + % RG_SCH_MAX_DRXQ_SIZE; + + ueDrxCb->drxInactDistance = ueDrxCb->inactvtyTmrLen + / RG_SCH_MAX_DRXQ_SIZE; +#endif /*LTE_TDD*/ + + cmLListAdd2Tail(&(cell->drxCb->drxQ[inActvTmrExpIndx].inActvTmrQ), + &(ueDrxCb->inActvTmrEnt)); + + ueDrxCb->inActvTmrEnt.node = (PTR)ueCb; + + ueDrxCb->drxInactvIndx = inActvTmrExpIndx; + + /* Update DRX InActive both masks */ + ueDrxCb->drxUlInactvMask &= ~RG_SCH_DRX_INACTVTMR_BITMASK; + ueDrxCb->drxDlInactvMask &= ~RG_SCH_DRX_INACTVTMR_BITMASK; + + /* Update UE's Inactive masks */ + ueCb->ul.ulInactvMask &= ~RG_DRX_INACTIVE; + ueCb->dl.dlInactvMask &= ~RG_DRX_INACTIVE; + + if ( delInUlScan == TRUE) + { + if ( ueDrxCb->inactvtyTmrLen == RGR_DRX_PRD_1PSF) + { + ueDrxCb->drxInactDistance = DRX_TMR_EXPRD; + ueDrxCb->drxDlInactvMask |= RG_SCH_DRX_INACTVTMR_BITMASK; + + /* if no other condition is keeping ue inactive, + * inactivate ue + */ + if ( !RG_SCH_DRX_DL_IS_UE_ACTIVE(ueDrxCb) ) + { + ueCb->dl.dlInactvMask |= RG_DRX_INACTIVE; + + /* Add to DL inactive list */ + cmLListAdd2Tail(&dlInactvLst,&(ueCb->dlDrxInactvLnk)); + ueCb->dlDrxInactvLnk.node = (PTR)ueCb; + } + }/*if ( ueDrxCb->inactvyTmrLen...*/ + + }/*delInUlScan==TRUE*/ + else + { + if ( ueDrxCb->inactvtyTmrLen == RGR_DRX_PRD_1PSF ) + { + ueDrxCb->drxInactDistance = DRX_TMR_EXPRD; + ueDrxCb->drxUlInactvMask |= RG_SCH_DRX_INACTVTMR_BITMASK; + /* if no other condition is keeping ue inactive, + * inactivate ue + */ + if ( !RG_SCH_DRX_DL_IS_UE_ACTIVE(ueDrxCb) ) + { + ueCb->ul.ulInactvMask |= RG_DRX_INACTIVE; + + if ( !RG_SCH_CMN_UL_IS_UE_ACTIVE(ueCb)) + { + /* Add to UL inactive list */ + cmLListAdd2Tail(&ulInactvLst,&(ueCb->ulDrxInactvLnk)); + ueCb->ulDrxInactvLnk.node = (PTR)ueCb; + } + }/*if ( !RG_SCH_DRX....)*/ + }/*if (ueDrxCb->inactv...*/ + } + + /* move the link list forward */ + delNode = node; + node = node->next; + + cmLListDelFrm(ueLst, delNode); + delNode->node = NULLP; + + }/*node*/ + + /* Send the list to the scheduler to mark UE as inactive in UL*/ + cellSch = RG_SCH_CMN_GET_CELL(cell); + cellSch->apisUl->rgSCHUlInactvtUes(cell, &ulInactvLst); + + /* Send the DL inactive list to the scheduler to mark UE as inactive */ + cellSch = RG_SCH_CMN_GET_CELL(cell); + cellSch->apisDl->rgSCHDlInactvtUes(cell,&dlInactvLst); + + RETVOID; +}/*rgSCHDrxStrtInActvTmr*/ + + /** @brief This function is called by the downlink HARQ module on receiving a + * negative feedback from the UE for a PDSCH transmission. + * + * @details + * Invoked by - rgSCHDhmHqTrnsFail + * + * Function: rgSCHDrxStartHarqRTTTmr + * + * Processing steps: + * + * + * @param RgSchCellCb *cell + * @param RgSchDlHqProcCb *dlHq + * @param U8 tbCnt + * @return Void + */ +#ifdef ANSI +PUBLIC Void rgSCHDrxStartHarqRTTTmr +( +RgSchCellCb *cell, +RgSchDlHqProcCb *hqP, +U8 tbCnt +) +#else +PUBLIC Void rgSCHDrxStartHarqRTTTmr(cell, hqP, tbCnt) +RgSchCellCb *cell; +RgSchDlHqProcCb *hqP; +U8 tbCnt; +#endif +{ + RgSchDRXCellCb *drxCell =NULLP; + RgSchDrxDlHqProcCb *drxHq =NULLP; + U16 harqRTTExpIndx; + U8 fdbkDelta; +#ifdef LTE_TDD + U8 firstDlTxOcassion; + U8 drxRetxTmrStartSf; +#endif + TRC2(rgSCHDrxStartHarqRTTTmr); + + + drxCell = RG_SCH_DRX_GET_CELL(cell); + drxHq = RG_SCH_DRX_GET_DL_HQ(hqP); + +#ifdef LTE_TDD + /* ccpu00134196-[Add]-DRX retx timer changes */ + firstDlTxOcassion = rgSchDrxHarqRetxFirstPsf[cell->ulDlCfgIdx] + [hqP->tbInfo[tbCnt].fdbkTime.subframe]; + + harqRTTExpIndx = ((hqP->tbInfo[tbCnt].fdbkTime.sfn * 10) + + hqP->tbInfo[tbCnt].fdbkTime.subframe + firstDlTxOcassion) + % RG_SCH_MAX_DRXQ_SIZE; + + fdbkDelta = RGSCH_CALC_SF_DIFF(cell->crntTime, hqP->tbInfo[tbCnt].fdbkTime); +#else /*LTE_TDD*/ + + /* For FDD HARQ RTT expiry index is 8 subframes from the time + * corresponding PDSCH was scheduled. We are adding 1 subframe + * so that UE is scheduled for retransmission in the next subframe*/ + /* ccpu00134196-[Add]-DRX retx timer changes */ + harqRTTExpIndx = ((hqP->tbInfo[tbCnt].timingInfo.sfn * RGSCH_NUM_SUB_FRAMES_5G) + + hqP->tbInfo[tbCnt].timingInfo.subframe + RG_SCH_MIN_HARQ_RTT) + % RG_SCH_MAX_DRXQ_SIZE; + + fdbkDelta = RGSCH_CALC_SF_DIFF(cell->crntTime, hqP->tbInfo[tbCnt].timingInfo); +#endif /*LTE_TDD*/ + /* ccpu00134196-[Add]-DRX retx timer changes */ + /* ensure that the insertion into the queue happens at an index + greater than the dl index, ie, do +1 */ + /* Instead of depending on TTI details of current time and HARQ RTT Expire + * time, Handling this check with deltas, because with TTIs it is not possible + * to handle wrap-around condition*/ +#ifdef LTE_TDD + if(fdbkDelta + RG_SCH_DRX_DL_DELTA >= firstDlTxOcassion) + { + /* The retx timer length should be reduced. + This means based on the platforms delta between the DL HARQ + processing and DL scheduling, drx retx timer lengths of 1ms/2ms + may not be possible */ + drxRetxTmrStartSf = (hqP->tbInfo[tbCnt].fdbkTime.subframe + + firstDlTxOcassion) % RGSCH_NUM_SUB_FRAMES; + U8 i; + /* We are here because the Retx Timer start is moved by atleast one + position. Hence the timer will be reduced by minimum one */ + drxHq->retxTmrReduction = 1; + + /* Now check the consecutive subframes starting from the actual + starting position of the retx tmr till the new position. Reduce the + timer value only if the sf is a Pdcch sf */ + for(i = 1; i <= fdbkDelta + RG_SCH_DRX_DL_DELTA-firstDlTxOcassion+ 1; i++) + { + if (rgSchTddUlDlSubfrmTbl[cell->ulDlCfgIdx] + [(drxRetxTmrStartSf+i)%RGSCH_NUM_SUB_FRAMES] + != RG_SCH_TDD_UL_SUBFRAME) + { + drxHq->retxTmrReduction++; + } + } +#else + if(fdbkDelta + RG_SCH_DRX_DL_DELTA >= RG_SCH_MIN_HARQ_RTT) + { + drxHq->retxTmrReduction = + fdbkDelta + RG_SCH_DRX_DL_DELTA - RG_SCH_MIN_HARQ_RTT+ 1; +#endif + /* KW_FIX */ + harqRTTExpIndx = (harqRTTExpIndx + drxHq->retxTmrReduction) % + RG_SCH_MAX_DRXQ_SIZE; + } + else + { + drxHq->retxTmrReduction = 0; + } + cmLListAdd2Tail (&(drxCell->drxQ[harqRTTExpIndx].harqRTTQ), + &(drxHq->harqRTTEnt)); + + drxHq->harqRTTEnt.node = (PTR)hqP; + drxHq->rttIndx = harqRTTExpIndx; + + RETVOID; + +}/*rgSCHDrxStartHarqRTTTmr*/ + + +/** @brief This function is called by the Configuration module to give a + * trigger to DRX module for UE configuration. + * + * @details + * + * Function: rgSCHDrxUeCfg + * + * Processing steps: + * - Copy configuration information into drxUe structure. + * - Calculate the first occurance of onDuration based on values + * provided in the configuration structure. + * - Append the UE to the onDurationQ at that index. + * - The UE must be appened to the list based on the timing calculated + * above (nxtSfn, nxtSubframe). + * + * @param RgSchCellCb *cell Cell control block. + * @param RgSchUeCb *ue UE control block. + * @param RgrUeCfg *ueCfg RGR UE configuration information. + * @return + * -# ROK + * -# RFAILED + */ +#ifdef ANSI +PUBLIC S16 rgSCHDrxUeCfg +( + RgSchCellCb *cell, + RgSchUeCb *ue, + RgrUeCfg *ueCfg + ) +#else +PUBLIC S16 rgSCHDrxUeCfg (cell, ue, ueCfg) + RgSchCellCb *cell; + RgSchUeCb *ue; + RgrUeCfg *ueCfg; +#endif +{ + S16 ret = ROK; + RgSchDrxUeCb *ueDrxCb; + CmLteTimingInfo nxtOnDur; + U16 onDurIndx; + U16 nxtOnDurTime; + U16 curTime; + U8 cellIdx; + + + TRC2(rgSCHDrxUeCfg); + + +#if ( ERRCLASS & ERRCLS_INT_PAR ) + if ( cell == (RgSchCellCb* )NULLP) + { + RETVALUE(RFAILED); + } + + if ((ue == (RgSchUeCb* )NULLP) + || + (ueCfg == (RgrUeCfg* )NULLP)) + { + RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId, "rgSCHDrxUeCfg():" + "Invalid params.cell or ue or ueCfg is NULL "); + RETVALUE(RFAILED); + } +#endif + + + /* allocate and initialize drxCb */ + ret = rgSCHUtlAllocSBuf(cell->instIdx, (Data**)&ue->drxCb, + (sizeof(RgSchDrxUeCb))); + + if(ret != ROK) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId, + "Memory allocation FAILED for DRX UECB CRBTI:%d",ue->ueId); + RETVALUE(ret); + } + + ueDrxCb = ue->drxCb; + + /* initialize the masks */ + ueDrxCb->drxDlInactvMask = DRX_UE_INACTIVE; + ueDrxCb->drxUlInactvMask = DRX_UE_INACTIVE; + ue->dl.dlInactvMask |= RG_DRX_INACTIVE; + ue->ul.ulInactvMask |= RG_DRX_INACTIVE; + + for(cellIdx = 0; cellIdx < CM_LTE_MAX_CELLS; cellIdx++) + { + ue->drxCb->drxDlInactvMaskPerCell[cellIdx] = DRX_UE_INACTIVE; + ue->drxCb->drxUlInactvMaskPerCell[cellIdx] = DRX_UE_INACTIVE; + } + + /* Copy the configuration values into the UE's DRX CB. */ + rgSCHDrxCpyUeCfg (ueDrxCb, &ueCfg->ueDrxCfg); +#ifdef EMTC_ENABLE + if(ue->isEmtcUe) + { + rgSCHEmtcDrxCpyUeCfg(ue ,&ueCfg->ueDrxCfg); + } +#endif + + /* set all indexes to default values */ + ueDrxCb->onDurIndx = DRX_INVALID; + ueDrxCb->onDurExpIndx = DRX_INVALID; + ueDrxCb->drxInactvIndx = DRX_INVALID; + ueDrxCb->shortCycleIndx = DRX_INVALID; + + /* set all distances to timer expiry */ + ueDrxCb->onDurExpDistance = DRX_TMR_EXPRD; + ueDrxCb->drxInactDistance = DRX_TMR_EXPRD; + ueDrxCb->drxShortCycleDistance = DRX_TMR_EXPRD; + ueDrxCb->distance = DRX_TMR_EXPRD; + + /* Mark the UE in long/short cycle initially as per configuration*/ + if(FALSE == ueDrxCb->isShortCycleCfgd) + { + ueDrxCb->isLongCycle = TRUE; + } + else + { + ueDrxCb->isLongCycle = FALSE; + } + + /* Calculate the next occurance from this point */ + rgSCHDrxGetNxtOnDur (cell, ueDrxCb, &nxtOnDur,RG_SCH_NO_DELTA); + + + nxtOnDurTime = ((nxtOnDur.sfn * RGSCH_NUM_SUB_FRAMES_5G) + nxtOnDur.subframe); + curTime = ((cell->crntTime.sfn * RGSCH_NUM_SUB_FRAMES_5G) + + cell->crntTime.subframe); + + onDurIndx = nxtOnDurTime % RG_SCH_MAX_DRXQ_SIZE; + + ueDrxCb->distance = (nxtOnDurTime - curTime) / RG_SCH_MAX_DRXQ_SIZE; + if (ueDrxCb->distance < 0) + { + RLOG_ARG2(L_ERROR,DBG_CELLID,cell->cellId, "DRXUE. Invalid " + "value for distance, %d CRNTI:%d", ueDrxCb->distance,ue->ueId); + } + //printf("The onduartion index is: %d\n",(int)onDurIndx); + cmLListAdd2Tail(&(cell->drxCb->drxQ[onDurIndx].onDurationQ), + &(ueDrxCb->onDurationEnt)); + + ueDrxCb->onDurationEnt.node = (PTR)ue; + ueDrxCb->onDurIndx = onDurIndx; + + /* Starting Short Cycle Timer */ + if(TRUE == ueDrxCb->isShortCycleCfgd) + { + ueDrxCb->drxShortCycleDistance = (ueDrxCb->shortCycleTmrLen * + ueDrxCb->shortDrxCycle) / RG_SCH_MAX_DRXQ_SIZE; + ueDrxCb->shortCycleIndx = (curTime + (ueDrxCb->shortCycleTmrLen * + ueDrxCb->shortDrxCycle)) % RG_SCH_MAX_DRXQ_SIZE; + cmLListAdd2Tail(&(cell->drxCb->drxQ[ueDrxCb->shortCycleIndx].shortCycleQ), + &(ueDrxCb->shortCycleEnt)); + ueDrxCb->shortCycleEnt.node = (PTR)ue; + } + + RETVALUE(ret); +} /* end of rgSCHDrxUeCfg */ + +/** @brief This function gets the next occurance of onDurationTimer from the + * current time. + * + * @details rgSCHDrxGetNxtOnDur + * + * Function: rgSCHDrxGetNxtOnDur + * + * Processing steps: - + * Calculation of first occurance of onDuration is to be done as + * follows. + * Assume DRX configuration came at subframe (x, y) the periodicity is + * offset = (perd, offset). + * The (sfn, subframe) satisfying the following condition is the first + * occurance from this point. + * + * (sfn * 10 + subframe) mod perd = offset + * + - + * + * + * @param RgSchCellCb *cell + * @param RgSchDrxUeCb *drxCb + * @param CmLteTimingInfo *nxtOnDur + * @param U8 delta + * @return ROK/RFAILED + */ +#ifdef ANSI +PRIVATE S16 rgSCHDrxGetNxtOnDur +( + RgSchCellCb *cell, + RgSchDrxUeCb *drxCb, + CmLteTimingInfo *nxtOnDur, + U8 delta + ) +#else +PRIVATE S16 rgSCHDrxGetNxtOnDur (cell, drxCb, nxtOnDur, delta) + RgSchCellCb *cell; + RgSchDrxUeCb *drxCb; + CmLteTimingInfo *nxtOnDur; + U8 delta; +#endif +{ + U16 curTime; + U16 curDist; + U16 cycleLen; + U32 numOfCycles; + U32 nxtDist; + + TRC3(rgSCHDrxGetNxtOnDur); + +#if ( ERRCLASS & ERRCLS_INT_PAR ) + if ( cell == (RgSchCellCb* )NULLP ) + { + RETVALUE(RFAILED); + } + + if( (drxCb == (RgSchDrxUeCb* )NULLP) + || + (nxtOnDur == (CmLteTimingInfo* )NULLP) + ) + { + RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId, + "rgSCHDrxGetNxOnDur():Invalid params." + "cell/drxCb/nxtOnDur is NULL"); + RETVALUE(RFAILED); + } +#endif + + + if (TRUE == drxCb->isLongCycle) + { + cycleLen = drxCb->longDrxCycle; + } + else + { + cycleLen = drxCb->shortDrxCycle; + } + + curTime = ((cell->crntTime.sfn * RGSCH_NUM_SUB_FRAMES_5G) + cell->crntTime.subframe); + + curTime += delta; /*TODO: see if we need to take care of wrap arounds */ + + if ( curTime <= drxCb->drxStartOffset ) + { + /* offset is the nextOnDur */ + nxtOnDur->sfn = drxCb->drxStartOffset / RGSCH_NUM_SUB_FRAMES_5G; + nxtOnDur->subframe = (U8)(drxCb->drxStartOffset % RGSCH_NUM_SUB_FRAMES_5G); + nxtDist = ((nxtOnDur->sfn * RGSCH_NUM_SUB_FRAMES_5G) + nxtOnDur->subframe); + } + else + { + curDist = curTime - drxCb->drxStartOffset; + + numOfCycles = curDist / cycleLen; + + if (0 == (curDist % cycleLen)) + { + /* Perfect match pick up the current time */ + /*nxtOnDur should be set to equal to currentTime + DELTA */ + nxtOnDur->sfn = (U16)curTime / RGSCH_NUM_SUB_FRAMES_5G; + nxtOnDur->subframe = (U16)curTime % RGSCH_NUM_SUB_FRAMES_5G; + nxtDist = ((nxtOnDur->sfn * RGSCH_NUM_SUB_FRAMES_5G) + nxtOnDur->subframe); + + } + else + { + nxtDist = drxCb->drxStartOffset + (numOfCycles + 1) * + cycleLen; + nxtOnDur->sfn = (U16)nxtDist / RGSCH_NUM_SUB_FRAMES_5G; + nxtOnDur->subframe = (U16)nxtDist % RGSCH_NUM_SUB_FRAMES_5G; + + } + } + + /*If next On Duration is less than DL DELTA ahead, we will miss it and + * hence need to move to the On-Duration after that.*/ + if((nxtDist - (curTime - delta)) <= RG_SCH_DRX_MAX_DELTA) + { + nxtDist = nxtDist + cycleLen; + nxtOnDur->sfn = (U16)nxtDist / RGSCH_NUM_SUB_FRAMES_5G; + nxtOnDur->subframe = (U16)nxtDist % RGSCH_NUM_SUB_FRAMES_5G; + } + RETVALUE(ROK); +} /* end of rgSCHDrxGetNxtOnDur */ + +/** @brief This function is a utility function to copy the UE configuration from + * the RGR structure to the UE control block. + * + * @details + * -Invoked by rgSCHDrxUeCfg + * + * Function: rgSCHDrxCpyUeCfg + * + * Processing steps: + * - Copies configuration values + * + * @param RgSchDrxUeCb *ueCb + * @param RgrUeDrxCfg *drxCfg + * @return ROK/RFAILED + */ +#ifdef ANSI +PRIVATE S16 rgSCHDrxCpyUeCfg +( + RgSchDrxUeCb *ueCb, + RgrUeDrxCfg *drxCfg +) +#else +PRIVATE S16 rgSCHDrxCpyUeCfg (ueCb, drxCfg) + RgSchDrxUeCb *ueCb; + RgrUeDrxCfg *drxCfg; +#endif +{ + TRC3(rgSCHDrxCpyUeCfg); + +#if ( ERRCLASS & ERRCLS_INT_PAR ) + if ( (ueCb == (RgSchDrxUeCb* )NULLP ) + || + (drxCfg == (RgrUeDrxCfg* )NULLP) + ) + { + RETVALUE(RFAILED); + } +#endif + + + /* Copy all values to UE control block */ +#ifdef LTEMAC_R9 + ueCb->cqiMask = drxCfg->cqiMask; +#endif /*LTEMAC_R9*/ + ueCb->onDurTmrLen = drxCfg->drxOnDurTmr; + ueCb->inactvtyTmrLen = drxCfg->drxInactvTmr; + ueCb->drxRetransTmrLen = drxCfg->drxRetxTmr; + ueCb->longDrxCycle = drxCfg->drxLongCycleOffst.longDrxCycle; + ueCb->drxStartOffset = drxCfg->drxLongCycleOffst.drxStartOffst; + ueCb->isShortCycleCfgd = drxCfg->drxShortDrx.pres; + ueCb->shortDrxCycle = drxCfg->drxShortDrx.shortDrxCycle; + ueCb->shortCycleTmrLen = drxCfg->drxShortDrx.drxShortCycleTmr; + + RETVALUE(ROK); +} /* end of rgSCHDrxCpyUeCfg */ + +#ifdef RGR_V2 +/** @brief This function is called by the configuration module when a UE is + * reconfigured for DRX parameters. + * + * @details + * Invoked By - rgSCHCfgRgrUeCfg + * + * Function: rgSCHDrxUeReCfg + * As per MAC specifications the new values of timers shall be applied only once + * they are restarted, hence no processing is required for modified timer values. + * + * Processing steps: + * - if offset and/or drxCycleLenght changes then recalculate the next + * onDurationIndex + * - remove the UE from current index + * - add the UE to the new index. + * - if short cycle is enabled + * - set isShortCycleCfgd = TRUE + * + * @param RgSchCellCb *cell + * @param RgSchUeCb *ue + * @param RgrUeRecfg *ueReCfg + * @return ROK/RFAILED + */ +#ifdef ANSI +PUBLIC S16 rgSCHDrxUeReCfg +( + RgSchCellCb *cell, + RgSchUeCb *ue, + RgrUeRecfg *ueReCfg + ) +#else +PUBLIC S16 rgSCHDrxUeReCfg (cell, ue, ueReCfg) + RgSchCellCb *cell; + RgSchUeCb *ue; + RgrUeRecfg *ueReCfg; +#endif +{ + /* DRX_INFI_LOOP */ + RgSchCmnCell *cellSch = NULLP; + CmLListCp dlInactvLst; /* list of UE's becoming DL-inactive */ + + S16 ret = ROK; + Inst instIdx = cell->instIdx; + RgSchDrxUeCb *ueDrxCb; + CmLteTimingInfo nxtOnDur; + U16 nxtOnDurTime; + U16 onDurIndx; + U16 curTime; + U16 shrtCycleExpIndx; + U16 onDurExpTime; + U16 cycleLen; + U16 curIndx; + U8 cellIdx; + + TRC2(rgSCHDrxUeReCfg); + + + /* drx was disabled but now enabled for this ue */ + if ( (ue->isDrxEnabled == FALSE) + && + (ueReCfg->ueDrxRecfg.isDrxEnabled == TRUE) + ) + { + /* allocated and initialize drxCb */ + ret = rgSCHUtlAllocSBuf(instIdx, (Data**)&ue->drxCb, + (sizeof(RgSchDrxUeCb))); + + if ( ret != ROK ) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId, + "rgSCHdrxUeReCfg():""Memory allocation FAILED for DRX UE Cb CRNTI:%d", + ue->ueId); + RETVALUE(ret); + } + + ue->isDrxEnabled = TRUE; /* sachin */ + /* initialize the masks */ + ue->drxCb->drxDlInactvMask = DRX_UE_INACTIVE; + ue->drxCb->drxUlInactvMask = DRX_UE_INACTIVE; + ue->dl.dlInactvMask |= RG_DRX_INACTIVE; + ue->ul.ulInactvMask |= RG_DRX_INACTIVE; + + for(cellIdx = 0; cellIdx < CM_LTE_MAX_CELLS; cellIdx++) + { + ue->drxCb->drxDlInactvMaskPerCell[cellIdx] = DRX_UE_INACTIVE; + ue->drxCb->drxUlInactvMaskPerCell[cellIdx] = DRX_UE_INACTIVE; + } + + /* set all indexes to default values */ + ue->drxCb->onDurIndx = DRX_INVALID; + ue->drxCb->onDurExpIndx = DRX_INVALID; + ue->drxCb->drxInactvIndx = DRX_INVALID; + ue->drxCb->shortCycleIndx = DRX_INVALID; + + /* set all distances to timer expiry */ + ue->drxCb->onDurExpDistance = DRX_TMR_EXPRD; + ue->drxCb->drxInactDistance = DRX_TMR_EXPRD; + ue->drxCb->drxShortCycleDistance = DRX_TMR_EXPRD; + ue->drxCb->distance = DRX_TMR_EXPRD; + + } + if( ue->drxCb == NULLP ) + { + RETVALUE(RFAILED); + } + ueDrxCb = ue->drxCb; + + /*drx was enabled but now disabled for this UE */ + if ( (ue->isDrxEnabled == TRUE ) + && + (ueReCfg->ueDrxRecfg.isDrxEnabled == FALSE) + ) + { + /* remove UE from all DRX Queues */ + (Void)rgSCHDrxUeDel(cell,ue); + + /* free drxCb */ + /* ccpu00117052 - MOD - Passing double pointer + for proper NULLP assignment*/ + rgSCHUtlFreeSBuf(instIdx,(Data **)(&((ue->drxCb))), + sizeof(RgSchDrxUeCb)); + + /* Resetting the DRX Bit set in Inactv Mask */ + ue->dl.dlInactvMask &= ~RG_DRX_INACTIVE; + ue->ul.ulInactvMask &= ~RG_DRX_INACTIVE; + + ue->isDrxEnabled = FALSE; + + }/*isDrxEnabled == FALSE */ + else + { + /* If Application is updating DRX params */ + if (ueReCfg->ueRecfgTypes & RGR_UE_DRX_RECFG ) + { + rgSCHDrxCpyUeCfg (ueDrxCb, &ueReCfg->ueDrxRecfg); +#ifdef EMTC_ENABLE + if(ue->isEmtcUe) + { + rgSCHEmtcDrxCpyUeCfg(ue, &ueReCfg->ueDrxRecfg); + } +#endif + + } + + /* Removing the UE from existing index of shortcycle, if any*/ + if(ueDrxCb->shortCycleIndx != DRX_INVALID) + { + cmLListDelFrm(&(cell->drxCb->drxQ[ueDrxCb->shortCycleIndx].shortCycleQ), + &(ueDrxCb->shortCycleEnt)); + + ueDrxCb->shortCycleEnt.node = (PTR) NULLP; + ueDrxCb->shortCycleIndx = DRX_INVALID; + } + + /* Mark for intiating long/short cycle as per received config */ + if(FALSE == ue->drxCb->isShortCycleCfgd) + { + ue->drxCb->isLongCycle = TRUE; + } + else + { + ue->drxCb->isLongCycle = FALSE; + } + + /* Calculate the next occurance from this point */ + rgSCHDrxGetNxtOnDur (cell, ueDrxCb, &nxtOnDur,RG_SCH_NO_DELTA); + + /* remove the UE from the current onDuration Queue */ + if ( ueDrxCb->onDurIndx != DRX_INVALID ) + { + cmLListDelFrm(&(cell->drxCb->drxQ[ueDrxCb->onDurIndx].onDurationQ), + &(ueDrxCb->onDurationEnt)); + } + + + nxtOnDurTime = (nxtOnDur.sfn * RGSCH_NUM_SUB_FRAMES_5G) + nxtOnDur.subframe; + curTime = ((cell->crntTime.sfn * RGSCH_NUM_SUB_FRAMES_5G) + + cell->crntTime.subframe); + + /* If Onduration timer of old configuration is already running then waiting till it expires */ + if((ueDrxCb->onDurExpIndx != DRX_INVALID) && (ueDrxCb->onDurExpDistance != DRX_TMR_EXPRD)) + { + curIndx = (curTime + RG_SCH_DRX_DL_DELTA) % RG_SCH_MAX_DRXQ_SIZE; + RLOG_ARG3(L_DEBUG,DBG_CELLID,cell->cellId, + "OLD ONDUR RUNNING-EXPIRES at %d curIdx-%d nxtOnDurTime-%d", + ueDrxCb->onDurExpIndx, + curIndx, + nxtOnDurTime); + + /* Manipulating the time when old onDuration timer can expire */ + if(curIndx >= ueDrxCb->onDurExpIndx) + { + onDurExpTime = curTime + ((ueDrxCb->onDurExpDistance+1) * RG_SCH_MAX_DRXQ_SIZE)+ (ueDrxCb->onDurExpIndx - curIndx + RG_SCH_DRX_DL_DELTA); + } + else + { + onDurExpTime = curTime + (ueDrxCb->onDurExpDistance * RG_SCH_MAX_DRXQ_SIZE)+ (ueDrxCb->onDurExpIndx - curIndx + RG_SCH_DRX_DL_DELTA); + } + + if(nxtOnDurTime <= onDurExpTime) + { + if(ueDrxCb->isLongCycle) + { + cycleLen = ueDrxCb->longDrxCycle; + } + else + { + cycleLen = ueDrxCb->shortDrxCycle; + } + /* Moving to the possible occassion of onduration after current onduration expiry: + * If both are aligning then going for next cycle */ + nxtOnDurTime += ((onDurExpTime - nxtOnDurTime)/cycleLen + 1 ) *cycleLen ; + } + } + /* Add the UE to the index which corresponds to the next onduration start*/ + onDurIndx = nxtOnDurTime % RG_SCH_MAX_DRXQ_SIZE; + + ueDrxCb->distance = (nxtOnDurTime - curTime) / RG_SCH_MAX_DRXQ_SIZE; + if (ueDrxCb->distance < 0) + { + RLOG_ARG2(L_ERROR,DBG_CELLID,cell->cellId,"DRXUE. Invalid " + "value for distance, %d CRNTI:%d", ueDrxCb->distance,ue->ueId); + } + + cmLListAdd2Tail(&(cell->drxCb->drxQ[onDurIndx].onDurationQ), + &(ueDrxCb->onDurationEnt)); + + ueDrxCb->onDurationEnt.node = (PTR)ue; + ueDrxCb->onDurIndx = onDurIndx; + + /* DRX_INFI_LOOP */ + cmLListInit(&dlInactvLst); + /* Add to DL inactive list */ + cmLListAdd2Tail(&dlInactvLst,&(ue->dlDrxInactvLnk)); + ue->dlDrxInactvLnk.node = (PTR)ue; + /* Send the list to the scheduler to mark UE as inactive */ + cellSch = RG_SCH_CMN_GET_CELL(cell); + cellSch->apisDl->rgSCHDlInactvtUes(cell, &dlInactvLst); + /* DRX_INFI_LOOP */ + + /* Starting short cycle timer as per the existence of old onDuration timer */ + if(TRUE == ueDrxCb->isShortCycleCfgd) + { + /* Expiring short DRX cycle Tmr once the number of short DRX cycles done */ + ueDrxCb->drxShortCycleDistance = (nxtOnDurTime + ueDrxCb->onDurTmrLen + (ueDrxCb->shortCycleTmrLen -1 )* + ueDrxCb->shortDrxCycle) / RG_SCH_MAX_DRXQ_SIZE; + shrtCycleExpIndx = (nxtOnDurTime + ueDrxCb->onDurTmrLen + ((ueDrxCb->shortCycleTmrLen -1)* + ueDrxCb->shortDrxCycle)) % RG_SCH_MAX_DRXQ_SIZE; + cmLListAdd2Tail(&(cell->drxCb->drxQ[shrtCycleExpIndx].shortCycleQ), + &(ueDrxCb->shortCycleEnt)); + ueDrxCb->shortCycleEnt.node = (PTR)ue; + ueDrxCb->shortCycleIndx = shrtCycleExpIndx; + } + } + + RETVALUE(ROK); + +} /* end of rgSCHDrxUeReCfg */ +#endif + +/** @brief This function Loop through the list of HARQ processes for this + * UE and delete from the harqRTTQ and harqRetxQ + * + * Function: rgSCHDrxUeHqReset + * Invoked by rgSCHDrxUeDel + * + * Processing steps: + Loop through the list of HARQ processes for this UE and delete from + * the harqRTTQ and harqRetxQ. + * + * @param RgSchCellCb *cell + * @return ROK/RFAILED + */ +#ifdef ANSI +PUBLIC Void rgSCHDrxUeHqReset +( + RgSchCellCb *cell, + RgSchUeCb *ue, + RgSchDlHqEnt *hqE, + U8 cellIdx + ) +#else +PUBLIC Void rgSCHDrxUeHqReset(cell, ue, hqE, cellIdx) + RgSchCellCb *cell; + RgSchUeCb *ue; + RgSchDlHqEnt *hqE; + U8 cellIdx; +#endif +{ + RgSchDlHqProcCb *hqP; + RgSchDrxDlHqProcCb *drxHq =NULLP; + U8 i; + + TRC2(rgSCHDrxUeHqReset); + + for(i=0; i < hqE->numHqPrcs; i++) + { + hqP = &hqE->procs[i]; + drxHq = RG_SCH_DRX_GET_DL_HQ(hqP); + + if(drxHq->rttIndx != DRX_INVALID) + { + cmLListDelFrm (&(cell->drxCb->drxQ[drxHq->rttIndx].harqRTTQ), + &(drxHq->harqRTTEnt)); + + drxHq->rttIndx = DRX_INVALID; + } + + if(drxHq->reTxIndx != DRX_INVALID) + { + cmLListDelFrm (&(cell->drxCb->drxQ[drxHq->reTxIndx].harqRetxQ), + &(drxHq->harqRetxEnt)); + + drxHq->reTxIndx = DRX_INVALID; + } + } + + ue->drxCb->drxDlInactvMaskPerCell[cellIdx] = DRX_UE_INACTIVE; + ue->drxCb->drxUlInactvMaskPerCell[cellIdx] = DRX_UE_INACTIVE; +} + +/** @brief This function Deletes DRX specific context for a UE. + * + * @details This funciton is invoked by the Configuration module on RGR UE Deletion. + * This function removes the UE's context from all of the DRX Queues. + * In addition it deletes context of UE's HARQ Processes present in the harqRTTQ + * and harqRetxQ + * + * + * Function: rgSCHDrxUeDel + * Invoked by rgSCHCfgRgrUeDel + * + * Processing steps: + * - Remove the UE from the following queues + * - onDurationQ - using onDurIndx + * - onDurationExpQ - using onDurExpIndx + * - inActvTmrQ - using drxInactvIndx + * - shortCycleQ - using shortCycleIndx + * - Loop through the list of HARQ processes for this UE and delete from + * the harqRTTQ and harqRetxQ. + * + * @param RgSchCellCb *cell + * @param RgSchUeCb *ue + * @return ROK/RFAILED + */ +#ifdef ANSI +PUBLIC S16 rgSCHDrxUeDel +( + RgSchCellCb *cell, + RgSchUeCb *ue + ) +#else +PUBLIC S16 rgSCHDrxUeDel (cell, ue) + RgSchCellCb *cell; + RgSchUeCb *ue; +#endif +{ + RgSchDrxUeCb *ueDrxCb; + RgSchDlHqEnt *hqE = NULLP; + U8 cellIdx; + RgSchUeCellInfo *cellInfo = NULLP; +#ifdef EMTC_ENABLE + RgSchCmnUlUe *ueUl = RG_SCH_CMN_GET_UL_UE(ue, cell); +#endif + TRC2(rgSCHDrxUeDel); + + + /* ccpu00129899: Moved the drx-enabled check to the caller */ + ueDrxCb = ue->drxCb; + + /* Remove UE from all queues */ + if ( ueDrxCb->onDurIndx != DRX_INVALID ) + { + cmLListDelFrm(&(cell->drxCb->drxQ[ueDrxCb->onDurIndx].onDurationQ), + &(ueDrxCb->onDurationEnt)); + + ueDrxCb->onDurIndx = DRX_INVALID; + } + + if ( ueDrxCb->onDurExpIndx != DRX_INVALID ) + { + cmLListDelFrm(&(cell->drxCb->drxQ[ueDrxCb->onDurExpIndx].onDurationExpQ), + &(ueDrxCb->onDurationExpEnt)); + + ueDrxCb->onDurExpIndx = DRX_INVALID; + } + + if ( ueDrxCb->drxInactvIndx != DRX_INVALID ) + { + cmLListDelFrm(&(cell->drxCb->drxQ[ueDrxCb->drxInactvIndx].inActvTmrQ), + &(ueDrxCb->inActvTmrEnt)); + + ueDrxCb->drxInactvIndx = DRX_INVALID; + } + + if ( ueDrxCb->shortCycleIndx != DRX_INVALID ) + { + cmLListDelFrm(&(cell->drxCb->drxQ[ueDrxCb->shortCycleIndx].shortCycleQ), + &(ueDrxCb->shortCycleEnt)); + + ueDrxCb->shortCycleIndx = DRX_INVALID; + } + + for(cellIdx = 0; cellIdx < CM_LTE_MAX_CELLS; cellIdx++) + { + cellInfo = ue->cellInfo[cellIdx]; + + if(cellInfo) + { + hqE = cellInfo->hqEnt; + rgSCHDrxUeHqReset(cell, ue, hqE, cellIdx); + } + } +#ifdef EMTC_ENABLE + if(ue->isEmtcUe) + { + rgSCHDrxUeUlHqReset(cell, ue, &(ueUl->hqEnt)); + } +#endif + /* Resetting the DRX Bit set in Inactv Mask */ + ue->dl.dlInactvMask &= ~RG_DRX_INACTIVE; + ue->ul.ulInactvMask &= ~RG_DRX_INACTIVE; + ueDrxCb->drxDlInactvMask = DRX_UE_INACTIVE; + ueDrxCb->drxUlInactvMask = DRX_UE_INACTIVE; + + RETVALUE(ROK); +}/*rgSCHDrxUeDel*/ + +/** @brief This function is called at the time of RGR cell configuration. + * + * @details + * Invoked by - rgSCHCfgRgrCellCfg + * + * Function: rgSCHDrxCellCfg + * + * Processing steps: + * - Initializes the following drxQ (cmMemset would do). + * + * + * @param RgSchCellCb *cell + * @param RgrCellCfg *cellCfg + * @return ROK/RFAILED + */ +#ifdef ANSI +PUBLIC S16 rgSCHDrxCellCfg +( + RgSchCellCb *cell, + RgrCellCfg *cellCfg + ) +#else +PUBLIC S16 rgSCHDrxCellCfg (cell, cellCfg) + RgSchCellCb *cell; + RgrCellCfg *cellCfg; +#endif +{ + + S16 ret = ROK; + Inst instIdx = cell->instIdx; + + TRC2(rgSCHDrxCellCfg); + + +#if ( ERRCLASS & ERRCLS_INT_PAR ) + /*KWORK_FIX :Removed check for cell being NULL*/ + if( (cellCfg == (RgrCellCfg* )NULLP)) + { + RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId, + "rgSCHDrxCellCfg():Invalid Params. cell/cellCfg is NULL"); + RETVALUE(RFAILED); + } +#endif + + /* allocate and initialize drxCb */ + ret = rgSCHUtlAllocSBuf(instIdx, (Data**)&cell->drxCb, + (sizeof(RgSchDRXCellCb))); + + if(ret != ROK) + { + RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,"rgSCHDrxCellCfg():" + "Memory allocation FAILED for DRX cell Cb"); + RETVALUE(ret); + } + + /* delInUlScan determines which index scans the queue last. + * We look at onDurationQ both from ulIndex & dlIndex pov. + * Consider, onDuration starts at index 5, and current index is 2, + * while dlIndex is 2 & ulIndex is 3 i.e dl is looking 2 SF ahead + * and ul is looking 3 SF ahead. In this case, dl will scan the queue + * last and therefore DL will delete ueCb from onDuration q. + * The reverse is true for the other case.*/ + + if ( RG_SCH_DRX_UL_DELTA > RG_SCH_DRX_DL_DELTA ) + { + cell->drxCb->delInUlScan = FALSE; + } + else + { + cell->drxCb->delInUlScan = TRUE; + } + + RETVALUE(ret); +} /* end of rgSchDrxCellCfg */ + + + +/** @brief This function to delete DRX specific context in the cell control + * block. + * + * @details + * Invoked by - rgSCHCfgRgrCellDel + * + * Function: rgSCHDrxCellDel + * + * Processing steps: + * - De-Inits RgSchDRXCellCb (Nothing to be done) + * - Assumption: The API is invoked after deletion of UEs from the cell. + * + * @param RgSchCellCb *cell + * @return Void + */ +#ifdef ANSI +PUBLIC Void rgSCHDrxCellDel +( + RgSchCellCb *cell + ) +#else +PUBLIC Void rgSCHDrxCellDel (cell) + RgSchCellCb *cell; +#endif +{ + Inst instIdx = cell->instIdx; + + TRC2(rgSCHCfgRgrCellDel); + + + if (cell->drxCb) + { + /* ccpu00117052 - MOD - Passing double pointer + for proper NULLP assignment*/ + rgSCHUtlFreeSBuf(instIdx, (Data **)(&(cell->drxCb)), + sizeof(RgSchDRXCellCb)); + } + RETVOID; +} /* end of rgSchDrxCellDel */ + +/** @brief This function is called when an SR is received from the UE. In this + * case the UE should be marked as ACTIVE till we send a UL allocation to the + * UE. + * + * @details + * Invoked by - rgSCHCmnSrRcvd + * Must be called after calling the specific scheduler. + * + * Function: rgSCHDrxSrInd + * + * Processing steps: + * - Mark the UE as ACTIVE + * ueCb->drxUlInactvMask |= (DRX_SR_ACTIVE); + * - Optionally call schedulers to add this UE to their scheduling + * queues. + * - Set drxUe->srRcvd = TRUE + * + * Note : the specification state that the UE shall start be active + * listening for UL grant, this implies we could potentially exploit + * this to send DL transmissions as well. However we have currently + * chosen not to do so. + * + * @param RgSchCellCb *cell + * @param RgSchUeCb *ue + * @return ROK/RFAILED + */ +#ifdef ANSI +PUBLIC S16 rgSCHDrxSrInd +( + RgSchCellCb *cell, + RgSchUeCb *ue + ) +#else +PUBLIC S16 rgSCHDrxSrInd (cell, ue) + RgSchCellCb *cell; + RgSchUeCb *ue; +#endif +{ + RgSchDrxUeCb *drxCb; + + TRC2(rgSCHDrxSrInd); + + +#if ( ERRCLASS & ERRCLS_INT_PAR ) + if ( cell == (RgSchCellCb* )NULLP) + { + RETVALUE(ROK); + } + + if( (ue == (RgSchUeCb* )NULLP)) + { + RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId, + "rgSCHDrxSrInd():Invalid Params. cell/ue is NULL"); + RETVALUE(RFAILED); + } + #endif + /* KWork fix - shifted this down */ + + + drxCb = RG_SCH_DRX_GET_UE(ue); + + /* Mark the UE as active for UL only */ + drxCb->drxUlInactvMask &= ~RG_SCH_DRX_SR_BITMASK; + drxCb->srRcvd = TRUE; + /* Update UE's inactive mask and if required move UE to ACTIVE state */ + RG_SCH_CMN_UL_UPDT_INACTV_MASK( cell, ue, RG_DRX_INACTIVE); + + RETVALUE(ROK); +} /* rgSCHDrxSrInd */ + + +/** @brief This function handles ACTIVITY due to RACH using a dedicated preamble + * (PDCCH order) OR Handover. A UE shall remain marked as active from the time + * we successfully send out a RAR upto the time it receives a PDCCH indicating a + * new transmission. + * + * @details + * Invoked by - rgSCHCmnHdlHoPo + * + * Function: rgSCHDrxDedRa + * + * Processing steps: + * - MARK the UE as active + * - set the raRcvd = TRUE for this UE. + * + * @code + * ueCb->drxDlInactvMask |= (DRX_RA_ACTIVE); + * ueCb->drxUlInactvMask |= (DRX_RA_ACTIVE); + * ueCb->raRcvd = TRUE; + * @endcode + * + * @param RgSchCellCb *cellCb + * @param RgSchUeCb *ueCb + * @return Void + */ +#ifdef ANSI +PUBLIC Void rgSCHDrxDedRa +( +RgSchCellCb *cellCb, +RgSchUeCb *ueCb + ) +#else +PUBLIC Void rgSCHDrxDedRa (cellCb, ueCb) +RgSchCellCb *cellCb; +RgSchUeCb *ueCb; +#endif +{ + RgSchDrxUeCb *drxCb; + + TRC2(rgSCHDrxDedRa); + + + drxCb = RG_SCH_DRX_GET_UE(ueCb); + + /* Mark the UE as active for UL & DL */ + drxCb->drxUlInactvMask &= ~RG_SCH_DRX_RA_BITMASK; + /* Update UE's inactive mask and if required move UE to ACTIVE state */ + RG_SCH_CMN_UL_UPDT_INACTV_MASK(cellCb, ueCb, RG_DRX_INACTIVE); + + drxCb->drxDlInactvMask &= ~RG_SCH_DRX_RA_BITMASK; + /* Update UE's inactive mask and if required move UE to ACTIVE state */ + RG_SCH_CMN_DL_UPDT_INACTV_MASK(cellCb, ueCb, RG_DRX_INACTIVE); + + drxCb->raRcvd = TRUE; + + RETVOID; +} /* end of rgSCHDrxDedRa */ + + +/** @brief This function calculates the next onDuration Occurence + * and removes & queue it again in onDurationQ + * + * @details + * Invoked by - + * + * Function: rgSCHDrxMvToNxtOnDurOcc + * + * Processing steps: + * + * + * @param RgSchCellCb *cell + * @param RgSchUeCb *ueCb + * @param U16 idx - if calcFrmOffst is TRUE, + * idx is delta to be added + * @param Bool calcFrmOffst + * @return Void + */ +#ifdef ANSI +PRIVATE Void rgSCHDrxMvToNxtOnDurOcc +( +RgSchCellCb *cell, +RgSchUeCb *ueCb, +U16 idx, +Bool calcFrmOffst +) +#else +PRIVATE Void rgSCHDrxMvToNxtOnDurOcc (cell, ueCb, idx, calcFrmOffst) +RgSchCellCb *cell; +RgSchUeCb *ueCb; +U16 idx; +Bool calcFrmOffst; +#endif +{ + U16 nxtOnDurIndex; + U16 curTime; + RgSchDrxUeCb *drxUe; + RgSchDRXCellCb *drxCell; + CmLteTimingInfo nxtOnDur; /* to be used when calcFrmOffset is set */ + U16 nxtOnDurInSf; /* next On Duration in no of subframes */ + + drxCell = cell->drxCb; + drxUe = ueCb->drxCb; + + TRC2(rgSCHDrxMvToNxtOnDurOcc) + + if(calcFrmOffst == FALSE) + { + if (drxUe->isLongCycle) + { + nxtOnDurIndex = ((idx + drxUe->longDrxCycle) + % RG_SCH_MAX_DRXQ_SIZE ); + drxUe->distance = drxUe->longDrxCycle/RG_SCH_MAX_DRXQ_SIZE; + } + else + { + nxtOnDurIndex = ((idx + drxUe->shortDrxCycle)% RG_SCH_MAX_DRXQ_SIZE); + + drxUe->distance = drxUe->shortDrxCycle / RG_SCH_MAX_DRXQ_SIZE; + } + } + else + { + rgSCHDrxGetNxtOnDur(cell,drxUe,&nxtOnDur,(U8)idx); + + nxtOnDurInSf = ((nxtOnDur.sfn * RGSCH_NUM_SUB_FRAMES_5G) + + nxtOnDur.subframe); + + curTime = ((cell->crntTime.sfn * RGSCH_NUM_SUB_FRAMES_5G) + + cell->crntTime.subframe); + + nxtOnDurIndex = nxtOnDurInSf % RG_SCH_MAX_DRXQ_SIZE; + drxUe->distance = (nxtOnDurInSf-curTime) / RG_SCH_MAX_DRXQ_SIZE; + if (drxUe->distance < 0) + { + RLOG_ARG2(L_ERROR,DBG_CELLID,cell->cellId,"DRXUE. Invalid " + "value for distance, %d CRNTI:%d", drxUe->distance,ueCb->ueId); + } + } + + /* First remove from existing location */ + if ( drxUe->onDurIndx != DRX_INVALID ) + { + cmLListDelFrm(&(drxCell->drxQ[drxUe->onDurIndx].onDurationQ), + &(drxUe->onDurationEnt)); + } + + /* Add at new location */ + cmLListAdd2Tail(&(drxCell->drxQ[nxtOnDurIndex].onDurationQ), + &(drxUe->onDurationEnt)); + + drxUe->onDurationEnt.node = (PTR)ueCb; + drxUe->onDurIndx = nxtOnDurIndex; + + RETVOID; +}/*rgSCHDrxMvToNxtOnDurOcc*/ + +#ifdef LTE_TDD +/** @brief This function calculates the next SFN,subframe a given + * timer is going to expire. Works for all TDD configurations. + * + * @details + * + * Function: rgSCHDrxGetNxtTmrExpry + * We need to count only PDCCH frames in a given TDD + * configuration. This is true for onDuration, inActivity + * & drx-retransmission timers. + * + * Processing steps (assume timer starts at (12,2) and duration + * is 23 DL subframes): + * - based on TDD configuration, move to the next SFN and + * count the number of DL subframes consumed. In our example, + * moving to (12,9) will consume 6 DL subframes assuming TDD + * config of 2. + * - From this point on, determine how many exact Radio Frames + * will be consumed for the remaining DL subframes. In our + * example, remaining DL subframes are (23-6) are 17. + * For config 2, the following holds true + * 8 DLSF are in 1 RF + * 1 DLSF in 1/8 DLSF + * 17 DLSF in 17/8 i.e 2 RF + 1 subframe + * In order to consume 17 DLSF, we need to move forward + * 2 RFs + 1 subframe. Adding 2 RF's gives us (14,9) + * - For the remaining subframe, we need to figure out the next + * available DL subframe. For TDD_configuration, the first DL + * subframe is at index 0. So, the timer will run till (15,0) + * and will expire on (15,1) + * + * @param RgSchUeCb *ue Ue control block. + * @param U16 curTime current Time + * @param U32 duration Timer duration + * @param CmLteTimingInfo *tmrExpryIdx Timer expry (SFN,sf) + * @return ROK/RFAILED + */ +#ifdef ANSI +PRIVATE S16 rgSCHDrxGetNxtTmrExpry +( + RgSchCellCb *cell, + U16 curTime, + U32 duration, + CmLteTimingInfo *tmrExpryIdx +) +#else +PRIVATE S16 rgSCHDrxGetNxtTmrExpry (cell,curTime,duration,tmrExpryIdx) + RgSchCellCb *cell; + U16 curTime; + U32 duration; + CmLteTimingInfo *tmrExpryIdx; +#endif +{ + U32 dlSfTillNxtSFN; /*!< DL subframes till next SFN */ + U8 tddCfgMode; /*!< tdd config mode */ + Bool isDwPtsCnted; /*!< is DwPts counted as PDCCH sf */ + CmLteTimingInfo crntTime; /*!< current SFN & sf */ + + + TRC2(rgSCHDrxGetNxtTmrExpry); + +#if ( ERRCLASS & ERRCLS_INT_PAR ) + if ( (cell == (RgSchCellCb* )NULLP) + || + (tmrExpryIdx == (CmLteTimingInfo* )NULLP) + ) + { + RETVALUE(RFAILED); + } +#endif + + + isDwPtsCnted = cell->isDwPtsCnted ; + + tddCfgMode = cell->ulDlCfgIdx; + crntTime.sfn = curTime / RGSCH_NUM_SUB_FRAMES_5G; + crntTime.subframe = curTime % RGSCH_NUM_SUB_FRAMES_5G; + + + + /* First calculate the number of DL subframes till next SFN */ + + dlSfTillNxtSFN = rgSchDrxDLSfTillNxtSFN[isDwPtsCnted][tddCfgMode] + [(crntTime.subframe % RGSCH_NUM_SUB_FRAMES)]; + + + if ( dlSfTillNxtSFN >= duration ) + { + /* the timer would expire on the same RF */ + U32 diff = dlSfTillNxtSFN - duration; + + tmrExpryIdx->sfn = crntTime.sfn; + + if ( diff == 0 ) + { + tmrExpryIdx->subframe = rgSchDrxDLSftoDLSfIdx[isDwPtsCnted][tddCfgMode] + [0]; + } + else + { + U8 arrayIdx; + /* to know the DL sf index based on diff */ + arrayIdx = rgSchDrxDlSfTddCfg[isDwPtsCnted][tddCfgMode]; + + tmrExpryIdx->subframe = rgSchDrxDLSftoDLSfIdx[isDwPtsCnted][tddCfgMode] + [arrayIdx - diff]; + } + }/* if ( dlSfTillNxtSFN >= duration...*/ + else + { + U32 remSf; /*!< remaining subframes */ + U32 numRf; /*!< num of complete radio frames */ + U32 numRemSfs; /*!< num of remaining subframes */ + + remSf = duration - dlSfTillNxtSFN; + + /* move to (currSFN,9) having consued dlSfTillNxtSFN DL subframes */ + tmrExpryIdx->sfn = crntTime.sfn; + tmrExpryIdx->subframe = (U8)9; + + numRf = (1 * remSf)/rgSchDrxDlSfTddCfg[isDwPtsCnted][tddCfgMode]; + numRemSfs = (1 * remSf)%rgSchDrxDlSfTddCfg[isDwPtsCnted][tddCfgMode]; + + tmrExpryIdx->sfn = tmrExpryIdx->sfn + numRf; + + /* we are now at (X,9) having consumed dlSfTillNxtSFN + numRf * num of DL + * subframes in 1 RF */ + + if ( numRemSfs == 0 ) + { + /* we are at subframe 9 i.e. the timer is going to expire using exact + * radio frames. However, not all TDD_configurations have 9 as their + * last DL subframe. We might have passed the last DL subfrme. + * Therefore, move back */ + tmrExpryIdx->subframe = rgSchDrxDLSftoDLSfIdx[isDwPtsCnted][tddCfgMode] + [numRemSfs]; + } + else + { + /* a reminder implies we have to move past this SFN as we are at the + * last subframe on that SFN */ + tmrExpryIdx->sfn++; + tmrExpryIdx->subframe = rgSchDrxDLSftoDLSfIdx[isDwPtsCnted][tddCfgMode] + [numRemSfs]; + } + }/*else if diff > duration */ + + /* timer will expire 1 + tmrExpryIdx */ + + if ( ( tmrExpryIdx->subframe + 1) == 10 ) + { + tmrExpryIdx->sfn++; + tmrExpryIdx->subframe = 0; + } + else + { + tmrExpryIdx->subframe++; + } + + /* check to see if it sfn has crossed its max */ + if ( tmrExpryIdx->sfn > RG_SCH_CMN_MAX_SFN_NUM ) + { + tmrExpryIdx->sfn = tmrExpryIdx->sfn - (RG_SCH_CMN_MAX_SFN_NUM + 1); + } + + RETVALUE(ROK); +}/*rgSCHDrxGetNxtTmrExpry*/ + +/** @brief This function calculates the next onDuration Occurence + * for TDD + * @details + * Invoked by - + * + * Function: rgSCHDrxCalcNxtTmrExpry + * + * Processing steps: a wrapper function to call + * rgSCHDrxGetNxtTmrExpry + * + * @param RgSchCellCb *cell + * @param RgSchUeCb *ue + * @param U16 delta + * @param U32 tmrLen + * @param U16 *distance + * @param S16 *idx + * @return ROK/RFAILED + */ +#ifdef ANSI +PRIVATE Void rgSCHDrxCalcNxtTmrExpry +( + RgSchCellCb *cell, + RgSchUeCb *ue, + U16 delta, + U32 tmrLen, + S16 *distance, + U16 *idx +) +#else +PRIVATE Void rgSCHDrxCalcNxtTmrExpry (cell,ue,delta,tmrLen,distance,idx) + RgSchCellCb *cell; + RgSchUeCb *ue; + U16 delta; + U32 tmrLen; + S16 *distance; + U16 *idx; +#endif +{ + U16 curTimeInSf; /*current time in no of subframes*/ + CmLteTimingInfo tmrExpry; + U16 tmrExpryInSf; /*timer expry in no of subframes*/ + + TRC2(rgSCHDrxCalcNxtTmrExpry) + + curTimeInSf = cell->crntTime.sfn * RGSCH_NUM_SUB_FRAMES_5G + + cell->crntTime.subframe; + + /* add delta to curTime */ + curTimeInSf += delta; + + rgSCHDrxGetNxtTmrExpry(ue->cell,curTimeInSf,tmrLen,&tmrExpry); + + /* convert timre Expry in terms of subframes */ + tmrExpryInSf = tmrExpry.sfn * RGSCH_NUM_SUB_FRAMES_5G + + tmrExpry.subframe; + + + *idx = (tmrExpryInSf) % RG_SCH_MAX_DRXQ_SIZE; + + if ( distance != NULLP ) /* hqReTx don't use the concept of distance. + They can send NULLP for distance. + */ + { + if ( tmrExpryInSf > curTimeInSf ) + { + *distance = (tmrExpryInSf - curTimeInSf) / + RG_SCH_MAX_DRXQ_SIZE; + } + else + { + /* in case the RF is at its max and wraps around */ + + *distance = ((tmrExpryInSf + (RG_SCH_CMN_MAX_NUM_OF_SFN - 1)) + - + curTimeInSf) / RG_SCH_MAX_DRXQ_SIZE; + } + if (*distance < 0) + { + RLOG_ARG2(L_ERROR,DBG_CELLID,cell->cellId, "DRXUE. Invalid " + "value for distance, %d CRNTI:%d", *distance,ue->ueId); + } + } + + RETVOID; +}/*rgSCHDrxCalcNxtTmrExpry*/ + +/* ccpu00134670- Validating onduration timer versus DRX cycle*/ +/*********************************************************** + * + * Func : rgSCHCfgVldtTddDrxCycCfg + * + * + * Desc : Validates DRX Cycle Length configuration against received + * onDuration timer from RRC. + * + * Ret : S16 + * ROK - Success + * + * RFAILED - Failed + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PUBLIC S16 rgSCHCfgVldtTddDrxCycCfg +( +RgSchCellCb *cell, +U16 drxCycle, +U8 onDurTmr, +U16 offSet +) +#else +PUBLIC S16 rgSCHCfgVldtTddDrxCycCfg(cell, drxCycle, onDurTmr, offSet) +RgSchCellCb *cell; +U16 drxCycle; +U8 onDurTmr; +U16 offSet; +#endif +{ + U16 startTime; + U16 endTimeInSf; + CmLteTimingInfo endTime; + TRC2(rgSCHCfgVldtTddDrxCycCfg) + + startTime = offSet; + do + { + rgSCHDrxGetNxtTmrExpry(cell, startTime, onDurTmr, &endTime); + + endTimeInSf = (endTime.sfn* RGSCH_NUM_SUB_FRAMES)+endTime.subframe; + + if(((RGSCH_MAX_SUBFRM_5G + endTimeInSf- startTime) % RGSCH_MAX_SUBFRM_5G) >= + drxCycle) + { + RETVALUE(RFAILED); + } + + startTime = (startTime + drxCycle); + /* Going for next iteration if the DRX cycle is not multiple of 10. If it is + multiple of 10(Number of Subframes in a SFN) then subframe, at which + onduration timer can start, will be always same, Otherwise the possible + subframe numbers, where the onDuration timer can start, is 5. Hence 4 + more iterations are required. */ + }while((drxCycle % RGSCH_NUM_SUB_FRAMES) && + (startTime < (drxCycle * RGSCH_NUM_SUB_FRAMES/2))); + + RETVALUE(ROK); +} + +#endif /*LTE_TDD */ + +/** @brief This function is called to handle onDurationTimer per TTI processing. + * + * @details + * Invoked by - rgSCHDrxTtiInd + * + * Function: rgSCHDrxTtiHdlOnDurUl + * + * Processing steps: + * + * - OnDurationTimer is handled using the drxQ @sa RgSchDrxQ + * + * - For Uplink we shall look at an index that is + * n + RG_SCH_DRX_UL_DELTA as + * we are concerned with the PDCCH and not the actual PUSCH. + * + * + * @param RgSchCellCb *cellCb + * @param U16 ulIndex + * @return Void + */ + +#ifdef ANSI +PRIVATE Void rgSCHDrxTtiHdlOnDurUl +( +RgSchCellCb *cell, +U16 ulIndex +) +#else +PRIVATE Void rgSCHDrxTtiHdlOnDurUl(cell, ulIndex) +RgSchCellCb *cell; +U16 ulIndex; +#endif +{ + CmLList *node; + RgSchDRXCellCb *drxCell = NULLP; + RgSchUeCb *ue = NULLP; + RgSchDrxUeCb *drxUe = NULLP; + CmLListCp ulInactvLst; /* list of UE's becoming DL-inactive */ + RgSchCmnCell *cellSch = NULLP; + Bool delInUlScan = FALSE; + + TRC2(rgSCHDrxTtiHdlOnDurUl) + + drxCell = (cell->drxCb); + delInUlScan = drxCell->delInUlScan; + /*********************************************************** + * Scanning OnDurationQ in UL + ***********************************************************/ + + /* For Uplink we shall look at an index that is n + RG_SCH_DRX_UL_DELTA as + we are concerned with the PDCCH and not the actual PUSCH.*/ + + node = drxCell->drxQ[ulIndex].onDurationQ.first; + + while (node) + { + ue = (RgSchUeCb*)node->node; + node = node->next; + drxUe = RG_SCH_DRX_GET_UE(ue); + + + if ( delInUlScan == FALSE) + { + drxUe->distance--; + } + + if ( drxUe->distance != DRX_TMR_EXPRD ) + { + continue; + } + + /* reset the bit mask to indicate that onduration has started */ + drxUe->drxUlInactvMask &= ~RG_SCH_DRX_ONDUR_BITMASK; + + /* if no other condition is keeping UE as inactive, + * activate UE + */ + RG_SCH_CMN_UL_UPDT_INACTV_MASK(cell, ue, RG_DRX_INACTIVE); + + if ( delInUlScan == TRUE ) + { + /*calculate next on duration occurence + * and it to the onDuration Queue*/ + rgSCHDrxMvToNxtOnDurOcc(cell,ue,ulIndex,FALSE); + }/*delInUlScan == FALSE */ + }/*while(node)*/ + + /*********************************************************** + * Scanning OnDurationExpQ in UL + ***********************************************************/ + + node = drxCell->drxQ[ulIndex].onDurationExpQ.first; + + /* Initialize UL inactive list */ + cmLListInit(&ulInactvLst); + + while (node) + { + ue = (RgSchUeCb*)node->node; + node = node->next; + drxUe = RG_SCH_DRX_GET_UE(ue); + + if ( delInUlScan == FALSE ) + { + drxUe->onDurExpDistance--; + } + + if ( drxUe->onDurExpDistance != DRX_TMR_EXPRD ) + { + continue; + } + + /*UE is inactive as onduration has expired */ + drxUe->drxUlInactvMask |= RG_SCH_DRX_ONDUR_BITMASK; + + if( !RG_SCH_DRX_UL_IS_UE_ACTIVE(drxUe)) + { + /* set the inactive bit to indicate UE has now become inactive */ + ue->ul.ulInactvMask |= RG_DRX_INACTIVE; + + /* Add to DL inactive list */ + cmLListAdd2Tail(&ulInactvLst,&(ue->ulDrxInactvLnk)); + ue->ulDrxInactvLnk.node = (PTR)ue; + } + + if ( delInUlScan == TRUE) + { + /*Remove from DRX queue*/ + cmLListDelFrm(&(drxCell->drxQ[ulIndex].onDurationExpQ), + &(drxUe->onDurationExpEnt)); + + drxUe->onDurExpIndx = DRX_INVALID; + } + + }/*while(node)*/ + + /* Send the list to the scheduler to mark UE as inactive in UL*/ + cellSch = RG_SCH_CMN_GET_CELL(cell); + cellSch->apisUl->rgSCHUlInactvtUes(cell, &ulInactvLst); + + RETVOID; +} + +/** @brief This function is called to handle onDurationTimer per TTI processing. + * + * @details + * Invoked by - rgSCHDrxTtiInd + * + * Function: rgSCHDrxTtiHdlOnDurDl + * + * Processing steps: + * + * - OnDurationTimer is handled using the drxQ @sa RgSchDrxQ + * + * - For Downlink we shall look at an index that is + * n + RG_SCH_DRX_DL_DELTA. + * + * + * @param RgSchCellCb *cellCb + * @param U16 dlIndex + * @return Void + */ + +#ifdef ANSI +PRIVATE Void rgSCHDrxTtiHdlOnDurDl +( +RgSchCellCb *cell, +U16 dlIndex +) +#else +PRIVATE Void rgSCHDrxTtiHdlOnDurDl(cell, dlIndex) +RgSchCellCb *cell; +U16 dlIndex; +#endif +{ + CmLList *node; + RgSchDRXCellCb *drxCell = NULLP; + RgSchUeCb *ue = NULLP; + RgSchDrxUeCb *drxUe = NULLP; + RgSchCmnCell *cellSch = NULLP; + U16 expiryIndex; + CmLListCp dlInactvLst; /* list of UE's becoming DL-inactive */ + Bool delInUlScan = FALSE; + + /* The DL loop, if onDurationTimer has started, will add the UeCb + * in the onDurationTmrExprQ. If !delInUlScan, then calculate the next + * OnDuration occurence, q it there and remove it from the current location. + */ + TRC2(rgSCHDrxTtiHdlOnDurDl) + /*********************************************************** + * Scanning OnDurationQ in DL + ***********************************************************/ + drxCell = (cell->drxCb); + + delInUlScan = drxCell->delInUlScan; + //printf("CELL Timer [SFN : %d],[SF : %d]\n",cell->crntTime.sfn,cell->crntTime.subframe); + + node = drxCell->drxQ[dlIndex].onDurationQ.first; + + + while (node) + { + ue = (RgSchUeCb* )node->node; + + node = node->next; + + drxUe = RG_SCH_DRX_GET_UE(ue); + + if ( delInUlScan == TRUE) + { + drxUe->distance--; + } + + if ( drxUe->distance != DRX_TMR_EXPRD ) + { + continue; + } + + + /* UE is active as onduration is to start */ + drxUe->drxDlInactvMask &= ~RG_SCH_DRX_ONDUR_BITMASK; + + /* set the UE as DRX active*/ + + /* Update UE's inactive mask and if required move UE to ACTIVE state */ + RG_SCH_CMN_DL_UPDT_INACTV_MASK(cell, ue, RG_DRX_INACTIVE); + /*ACC-TDD */ + /* Temporary fix to delete stale entry */ + if (drxUe->onDurExpIndx != DRX_INVALID) + { + RLOG_ARG4(L_DEBUG,DBG_CELLID,cell->cellId, + "UEID:%d PreExisted[%d:%d]in onDurExpQ new[%d]", + ue->ueId, + drxUe->onDurExpIndx, + drxUe->onDurExpDistance, + dlIndex); + cmLListDelFrm(&(drxCell->drxQ[drxUe->onDurExpIndx].onDurationExpQ), + &(drxUe->onDurationExpEnt)); + + drxUe->onDurExpIndx = DRX_INVALID; + } + /*start the onduration expiry timer*/ +#ifdef LTE_TDD + rgSCHDrxCalcNxtTmrExpry(cell, + ue, + RG_DL_DELTA, + drxUe->onDurTmrLen, + &(drxUe->onDurExpDistance), + &(expiryIndex) + ); +#else /*LTE_TDD */ + expiryIndex = ((dlIndex + drxUe->onDurTmrLen) % + RG_SCH_MAX_DRXQ_SIZE); + drxUe->onDurExpDistance = (drxUe->onDurTmrLen)/ + RG_SCH_MAX_DRXQ_SIZE; +#endif /*LTE_TDD */ + + cmLListAdd2Tail(&(drxCell->drxQ[expiryIndex].onDurationExpQ), + &(drxUe->onDurationExpEnt)); + //printf("DRXOnDuration Timer Started at [SFN : %d],[SF : %d]\n",cell->crntTime.sfn,cell->crntTime.subframe); + drxUe->onDurationExpEnt.node = (PTR)ue; + drxUe->onDurExpIndx = expiryIndex; + + //printf("DRxOnDuration will Expire = [%d]\n",(cell->crntTime.sfn*10+cell->crntTime.subframe+drxUe->onDurTmrLen)); + + if ( delInUlScan == FALSE ) + { + /*calculate next on duration occurence + * and it to the onDuration Queue*/ + rgSCHDrxMvToNxtOnDurOcc(cell,ue,dlIndex,FALSE); + }/*delInUlScan == FALSE */ + + }/*while(node)*/ + + /*********************************************************** + * Scanning OnDurationExpQ in DL + ***********************************************************/ + + /* Mark UE as Inactive based on OnDuration Expiry */ + node = drxCell->drxQ[dlIndex].onDurationExpQ.first; + + /* Initialize DL inactive list */ + cmLListInit(&dlInactvLst); + + while (node) + { + ue = (RgSchUeCb*)node->node; + node = node->next; + drxUe = RG_SCH_DRX_GET_UE(ue); + + if ( delInUlScan == TRUE ) + { + drxUe->onDurExpDistance--; + } + + if ( drxUe->onDurExpDistance != DRX_TMR_EXPRD ) + { + continue; + } + + + /* UE is inactive as onduration has expired */ + drxUe->drxDlInactvMask |= (RG_SCH_DRX_ONDUR_BITMASK); + + if( !RG_SCH_DRX_DL_IS_UE_ACTIVE(drxUe)) + { + /* set the inactive bit to indicate UE has now become inactive */ + ue->dl.dlInactvMask |= RG_DRX_INACTIVE; + + /* Add to DL inactive list */ + cmLListAdd2Tail(&dlInactvLst,&(ue->dlDrxInactvLnk)); + ue->dlDrxInactvLnk.node = (PTR)ue; + } + + if ( delInUlScan == FALSE ) + { + /*Remove from DRX queue*/ + cmLListDelFrm(&(drxCell->drxQ[dlIndex].onDurationExpQ), + &(drxUe->onDurationExpEnt)); + + drxUe->onDurExpIndx = DRX_INVALID; + } + + } + + /* Send the list to the scheduler to mark UE as inactive */ + cellSch = RG_SCH_CMN_GET_CELL(cell); + cellSch->apisDl->rgSCHDlInactvtUes(cell, &dlInactvLst); + + RETVOID; +}/*rgSCHDrxTtiHdlOnDurDl*/ + + /** @brief This function handles the Dl HARQ timer's processing per TTI. + * + * @details + * Invoked by - rgSCHDrxTtiHdlDlHarq + * + * Function: rgSCHDrxTtiHdlDlHarqRTT + * + * Processing steps: + * - In addition per TTI DRX module must look at Downlink HARQ queues + * maintained to track HARQ RTT timer and drx-RetransmissionTimer. + * Every TTI at the scheduling index we shall check these queues and + * process accordingly. + * + * @param RgSchCellCb *cellCb + * @param U16 dlIndex + * @return Void + */ + +#ifdef ANSI +PRIVATE Void rgSCHDrxTtiHdlDlHarqRTT +( +RgSchCellCb *cell, +U16 dlIndex +) +#else /* ANSI */ +PRIVATE Void rgSCHDrxTtiHdlDlHarqRTT(cell, dlIndex) +RgSchCellCb *cell; +U16 dlIndex; +#endif /* ANSI */ +{ + CmLList *node; + RgSchDrxDlHqProcCb *drxHq; + RgSchDlHqProcCb *dlHq; + RgSchDRXCellCb *drxCell; + RgSchDrxUeCb *drxUe; + U16 reTxExpIndx; + Bool delInUlScan; + RgSchUeCb *ue; + CmLListCp dlInactvLst; /* list of UE's becoming DL-inactive */ + RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell); + U8 cellIdx; + U32 dlInactvMask; + + TRC2(rgSCHDrxTtiHdlDlHarqRTT); + + drxCell = cell->drxCb; + delInUlScan = drxCell->delInUlScan; + + /*********************************************************** + * Scanning harqRTTQ in DL + ***********************************************************/ + + cmLListInit(&dlInactvLst); + node = drxCell->drxQ[dlIndex].harqRTTQ.first; + + while (node) + { + dlHq = (RgSchDlHqProcCb*)node->node; + node = node->next; + ue = dlHq->hqE->ue; +#ifdef EMTC_ENABLE + if(TRUE == ue->isEmtcUe) + { + continue; + } +#endif + drxHq = RG_SCH_DRX_GET_DL_HQ(dlHq); + drxUe = RG_SCH_DRX_GET_UE(ue); + cellIdx = ue->cellIdToCellIdxMap[RG_SCH_CELLINDEX(dlHq->hqE->cell)]; + /* add the UE to the cell's retransmission queuee before starting + * reTx timer, because this will not depend on retx timer trigger*/ + rgSCHUtlDlProcAddToRetx(dlHq->hqE->cell, dlHq); + + if ( delInUlScan == FALSE) + { + cmLListDelFrm (&(drxCell->drxQ[dlIndex].harqRTTQ), + &(drxHq->harqRTTEnt)); + + drxHq->rttIndx = DRX_INVALID; + } + /* ccpu00134565: Starting retransmission timer only if timerLen is + * having non-zero value after reduction, Adding to Retx queue is + * independent of starting retransmission timer. Hence if part will + * take care of starting retx timer only*/ + if (drxUe->drxRetransTmrLen > drxHq->retxTmrReduction) + { + /* add the harq proc to the re-tx queue--*/ +#ifdef LTE_TDD + /* ccpu00134196-[Add]-DRX retx timer changes */ + rgSCHDrxCalcNxtTmrExpry(cell, + ue, + RG_DL_DELTA, + drxUe->drxRetransTmrLen-drxHq->retxTmrReduction, + NULLP, /*retransQ does not maintain distance*/ + &reTxExpIndx + ); + +#else /*LTE_TDD*/ + /* ccpu00134196-[Add]-DRX retx timer changes */ + reTxExpIndx = ((dlIndex + + drxUe->drxRetransTmrLen-drxHq->retxTmrReduction) % + RG_SCH_MAX_DRXQ_SIZE); +#endif /*LTE_TDD*/ + /* TODO. Workaround to avoid duplicate entry */ + if(drxHq->reTxIndx == DRX_INVALID) + { + cmLListAdd2Tail (&(drxCell->drxQ[reTxExpIndx].harqRetxQ), + &(drxHq->harqRetxEnt)); + + drxHq->harqRetxEnt.node = (PTR)dlHq; + drxHq->reTxIndx = reTxExpIndx; + } + else + { + RLOG_ARG4(L_ERROR,DBG_CELLID,cell->cellId,"CRNTI:%d " + "Adding Retx Node to expire at RetxIndx: %d at dlIndex %d " + "drxHq->reTxIndx %d", ue->ueId, reTxExpIndx, dlIndex, + drxHq->reTxIndx); + continue; + } + /*mark the ue as active for downlink--*/ + drxUe->drxDlInactvMask &= ~(RG_SCH_DRX_DLHQ_BITMASK << dlHq->procId); + drxUe->drxDlInactvMaskPerCell[cellIdx] &= ~(RG_SCH_DRX_DLHQ_BITMASK << dlHq->procId); + + /* Update UE's inactive mask and if required move UE to ACTIVE state */ + RG_SCH_CMN_DL_UPDT_INACTV_MASK(cell, ue, RG_DRX_INACTIVE); + } + }/*while(node)*/ + + /*********************************************************** + * Scanning harqRetxQ in DL + ***********************************************************/ + + node = drxCell->drxQ[dlIndex].harqRetxQ.first; + while (node) + { + dlHq = (RgSchDlHqProcCb*)node->node; + ue = dlHq->hqE->ue; + drxUe = RG_SCH_DRX_GET_UE(ue); + node = node->next; + drxHq = RG_SCH_DRX_GET_DL_HQ(dlHq); + cellIdx = ue->cellIdToCellIdxMap[RG_SCH_CELLINDEX(dlHq->hqE->cell)]; + + /*mark the ue as in-active for downlink*/ + drxUe->drxDlInactvMaskPerCell[cellIdx] |= (RG_SCH_DRX_DLHQ_BITMASK << dlHq->procId); + + dlInactvMask = RG_SCH_DRX_DLHQ_BITMASK << dlHq->procId; + + for(cellIdx = 0; cellIdx < CM_LTE_MAX_CELLS; cellIdx++) + { + dlInactvMask &= drxUe->drxDlInactvMaskPerCell[cellIdx]; + } + + drxUe->drxDlInactvMask |= dlInactvMask; + + /* if no other condition is keeping ue active, + * inactivate the Ue + */ + if ( !RG_SCH_DRX_DL_IS_UE_ACTIVE(drxUe)) + { + ue->dl.dlInactvMask |= (RG_DRX_INACTIVE); + + /* Add to DL inactive list */ + cmLListAdd2Tail(&dlInactvLst,&(ue->dlDrxInactvLnk)); + ue->dlDrxInactvLnk.node = (PTR)ue; + } + + /*remove the harq proc from this queue*/ + if ( delInUlScan == FALSE) + { + cmLListDelFrm (&(drxCell->drxQ[dlIndex].harqRetxQ), + &(drxHq->harqRetxEnt)); + drxHq->reTxIndx = DRX_INVALID; + } + } + /*Call schedulers to inactivate ue*/ + cellSch->apisDl->rgSCHDlInactvtUes(cell, &dlInactvLst); + + RETVOID; +} + + /** @brief This function handles the Ul HARQ timer's processing per TTI. + * + * @details + * Invoked by - rgSCHDrxTtiHdlDlHarq + * + * Function: rgSCHDrxTtiHdlUlHarqRTT + * + * Processing steps: + * - In addition per TTI DRX module must look at Downlink HARQ queues + * maintained to track HARQ RTT timer and drx-RetransmissionTimer. + * Every TTI at the scheduling index we shall check these queues and + * process accordingly. + * + * - Though these timers are related to downlink HARQ processing, they + * have an impact on uplink scheduling. The reason is that the UE, + * if active for downlink scheduling implies that it is reading + * PDCCHs i.e. we can still send uplink allocations to the UE. Hence + * every TTI Uplink too would look at the harqRTTQ and harqRetxQ. + * + * + * + * @param RgSchCellCb *cellCb + * @param U16 ulIndex + * @return Void + */ + +#ifdef ANSI +PRIVATE Void rgSCHDrxTtiHdlUlHarqRTT +( +RgSchCellCb *cell, +U16 ulIndex +) +#else /* ANSI */ +PRIVATE Void rgSCHDrxTtiHdlUlHarqRTT(cell, ulIndex) +RgSchCellCb *cell; +U16 ulIndex; +#endif /* ANSI */ +{ + CmLList *node; + RgSchDrxDlHqProcCb *drxHq; + RgSchDlHqProcCb *dlHq; + RgSchDRXCellCb *drxCell; + RgSchDrxUeCb *drxUe; + Bool delInUlScan; + RgSchUeCb *ue; + CmLListCp ulInactvLst; /* list of UE's becoming DL-inactive */ + RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell); + U8 cellIdx; + U32 ulInactvMask; + + + TRC2(rgSCHDrxTtiHdlUlHarqRTT); + + drxCell = cell->drxCb; + delInUlScan = drxCell->delInUlScan; + + cmLListInit(&ulInactvLst); + + /*********************************************************** + * Scanning harqRTTQ in UL + ***********************************************************/ + + /* + Though these timers are related to downlink HARQ processing, they + have an impact on uplink scheduling. The reason is that the UE, + if active for downlink scheduling implies that it is reading + PDCCHs i.e. we can still send uplink allocations to the UE. Hence + every TTI Uplink too would look at the harqRTTQ and harqRetxQ. + */ + + node = drxCell->drxQ[ulIndex].harqRTTQ.first; + while (node) + { + dlHq = (RgSchDlHqProcCb*)node->node; + ue = dlHq->hqE->ue; + drxUe = RG_SCH_DRX_GET_UE(ue); + node = node->next; + drxHq = RG_SCH_DRX_GET_DL_HQ(dlHq); + cellIdx = ue->cellIdToCellIdxMap[RG_SCH_CELLINDEX(dlHq->hqE->cell)]; + + if ( delInUlScan == TRUE ) + { + /* remove the harq proc from this queue--*/ + cmLListDelFrm (&(drxCell->drxQ[ulIndex].harqRTTQ), + &(drxHq->harqRTTEnt)); + + drxHq->rttIndx = DRX_INVALID; + } + + /* mark the ue as active for uplink--*/ + drxUe->drxUlInactvMask &= ~(RG_SCH_DRX_DLHQ_BITMASK << dlHq->procId); + drxUe->drxUlInactvMaskPerCell[cellIdx] &= ~(RG_SCH_DRX_DLHQ_BITMASK << dlHq->procId); + + /* Update UE's inactive mask and if required move UE to ACTIVE state */ + RG_SCH_CMN_UL_UPDT_INACTV_MASK( cell, ue, RG_DRX_INACTIVE); + } + + /*********************************************************** + * Scanning harqRetxQ in UL + ***********************************************************/ + node = drxCell->drxQ[ulIndex].harqRetxQ.first; + while (node) + { + dlHq = (RgSchDlHqProcCb*)node->node; + ue = dlHq->hqE->ue; + drxUe = RG_SCH_DRX_GET_UE(ue); + drxHq = RG_SCH_DRX_GET_DL_HQ(dlHq); + cellIdx = ue->cellIdToCellIdxMap[RG_SCH_CELLINDEX(dlHq->hqE->cell)]; + + /*mark the ue as in-active for uplink*/ + + drxUe->drxUlInactvMaskPerCell[cellIdx] |= (RG_SCH_DRX_DLHQ_BITMASK << dlHq->procId); + + ulInactvMask = RG_SCH_DRX_DLHQ_BITMASK << dlHq->procId; + + for(cellIdx = 0; cellIdx < CM_LTE_MAX_CELLS; cellIdx++) + { + ulInactvMask &= drxUe->drxUlInactvMaskPerCell[cellIdx]; + } + + drxUe->drxUlInactvMask |= ulInactvMask; + + if(!RG_SCH_DRX_UL_IS_UE_ACTIVE(drxUe)) + { + ue->ul.ulInactvMask |= (RG_DRX_INACTIVE); + + cmLListAdd2Tail(&ulInactvLst,&(ue->ulDrxInactvLnk)); + ue->ulDrxInactvLnk.node = (PTR)ue; + } + + /* remove the harq proc from this queue*/ + if ( delInUlScan == TRUE) + { + cmLListDelFrm (&(drxCell->drxQ[ulIndex].harqRetxQ), + &(drxHq->harqRetxEnt)); + drxHq->reTxIndx = DRX_INVALID; + } + + node = node->next; + } + cellSch->apisUl->rgSCHUlInactvtUes(cell, &ulInactvLst); + + RETVOID; + +} + +/********************************************************************** + + End of file +**********************************************************************/ diff --git a/src/5gnrmac/rg_sch_err.h b/src/5gnrmac/rg_sch_err.h new file mode 100755 index 000000000..744f0a4bd --- /dev/null +++ b/src/5gnrmac/rg_sch_err.h @@ -0,0 +1,229 @@ +/******************************************************************************* +################################################################################ +# Copyright (c) [2017-2019] [Radisys] # +# # +# 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. # +################################################################################ +*******************************************************************************/ + +/********************************************************************** + + Name: LTEMAC - Error File + + Type: C include file + + Desc: Error defines required by LTEMAC layer + + File: rg_sch_err.h + +*********************************************************************21*/ +/* +* The defines declared in this file correspond to those +* used by LTEMAC Layer +* +*/ + +#ifndef __RGSCHERRH__ +#define __RGSCHERRH__ + +/* defines */ + + +/* Macro definitions */ +#define RGSCHLOGERROR(_inst, errCls, errCode, errVal, errDesc) \ + SLogError(rgSchCb[_inst].rgSchInit.ent, rgSchCb[_inst].rgSchInit.inst,\ + rgSchCb[_inst].rgSchInit.procId, \ + (Txt *) __FILE__, \ + (S32) __LINE__, \ + (ErrCls) (errCls), \ + (ErrCode) (errCode), \ + (ErrVal) (errVal), \ + (Txt *) errDesc) + +#ifdef LTE_L2_MEAS +#define RGSCHFILLERR(_err, _errType, _errCause) \ + _err.errType = _errType; \ + _err.errCause = _errCause; +#endif +/* error codes */ +#define ERGBASE 0 + +#define ERGXXX (ERGBASE + 0) /* reserved */ +#define ERRRG (ERGBASE + 0) /* reserved */ + +#define RGSCHERR_NONE ERGBASE + +#define ERG001 (ERRRG + 1) /* gk_sch.c: 535 */ +#define ERG002 (ERRRG + 2) /* gk_sch.c: 548 */ +#define ERG003 (ERRRG + 3) /* gk_sch.c: 606 */ +#define ERG004 (ERRRG + 4) /* gk_sch.c: 616 */ +#define ERG005 (ERRRG + 5) /* gk_sch.c: 691 */ +#define ERG006 (ERRRG + 6) /* gk_sch.c: 704 */ +#define ERG007 (ERRRG + 7) /* gk_sch.c: 792 */ +#define ERG008 (ERRRG + 8) /* gk_sch.c: 805 */ +#define ERG009 (ERRRG + 9) /* gk_sch.c: 879 */ +#define ERG010 (ERRRG + 10) /* gk_sch.c: 956 */ + +#define ERG011 (ERRRG + 11) /* gk_sch_cmn.c:24144 */ + +#define ERG012 (ERRRG + 12) /* gk_sch_sps.c:9181 */ + +#define ERG013 (ERRRG + 13) /* gk_sch_tom.c: 608 */ +#define ERG014 (ERRRG + 14) /* gk_sch_tom.c: 684 */ + +#define ERG015 (ERRRG + 15) /* gk_sch_utl.c:4209 */ +#define ERG016 (ERRRG + 16) /* gk_sch_utl.c:4285 */ +#define ERG017 (ERRRG + 17) /* gk_sch_utl.c:5027 */ +#define ERG018 (ERRRG + 18) /* gk_sch_utl.c:5084 */ +#define ERG019 (ERRRG + 19) /* gk_sch_utl.c:5112 */ +#define ERG020 (ERRRG + 20) /* gk_sch_utl.c:5257 */ +#define ERG021 (ERRRG + 21) /* gk_sch_utl.c:5266 */ +#define ERG022 (ERRRG + 22) /* gk_sch_utl.c:5897 */ +#define ERG023 (ERRRG + 23) /* gk_sch.c:902 */ +#define ERG024 (ERRRG + 24) /* gk_sch.c:915 */ +#define ERG025 (ERRRG + 25) /* gk_sch.c:988 */ +#define ERG026 (ERRRG + 26) /* gk_sch.c:998 */ + + +/* *********************************************************** + * Error Type + *************************************************************/ +#define RGSCHERR_TYPE_BASE 0 +#define RGSCHERR_CAUSE_BASE 0 + +/* ErrType defines for DHM */ +#define RG_DHM_ERRTYPE_BASE (RGSCHERR_CAUSE_BASE + 1) +#define RGSCHERR_DHM_SND_DAT_REQ RG_DHM_ERRTYPE_BASE +#define RGSCHERR_DHM_FDBK_IND (RG_DHM_ERRTYPE_BASE + 1) +#define RGSCHERR_DHM_SND_STA_IND (RG_DHM_ERRTYPE_BASE + 2) +#define RGSCHERR_DHM_FDBK_IND_INVALID_CB (RGSCHERR_DHM_SND_STA_IND + 3) +#define RGSCHERR_DHM_SND_HQ_FDB_REQ (RG_DHM_ERRTYPE_BASE + 4) +/* ErrType defines for TOM */ +#define RG_TOM_ERRTYPE_BASE (RGSCHERR_DHM_SND_HQ_FDB_REQ + 1) +#define RGSCHERR_TOM_RAREQIND RG_TOM_ERRTYPE_BASE +#define RGSCHERR_TOM_HARQACKIND (RG_TOM_ERRTYPE_BASE + 1) +#define RGSCHERR_TOM_SRIND (RG_TOM_ERRTYPE_BASE + 2) +#define RGSCHERR_TOM_DLCQIIND (RG_TOM_ERRTYPE_BASE + 3) +#define RGSCHERR_TOM_DATIND (RG_TOM_ERRTYPE_BASE + 4) +#define RGSCHERR_TOM_DECFAILIND (RG_TOM_ERRTYPE_BASE + 5) +#define RGSCHERR_TOM_TAIND (RG_TOM_ERRTYPE_BASE + 6) +#define RGSCHERR_TOM_TTIIND (RG_TOM_ERRTYPE_BASE + 7) +/* Changes for MIMO feature addition */ +#define RGSCHERR_TOM_DOAIND (RG_TOM_ERRTYPE_BASE + 8) +/* Added changes of TFU_UPGRADE */ +#ifdef TFU_UPGRADE +#define RGSCHERR_TOM_RAWCQIIND (RG_TOM_ERRTYPE_BASE + 9) +#define RGSCHERR_TOM_SRSIND (RG_TOM_ERRTYPE_BASE + 10) +#endif +/* GOM Module related error MACROs for error type */ +#define RG_GOM_ERRTYPE_BASE (RGSCHERR_TOM_TTIIND + 1) +#define RGSCHERR_GOM_CFG_REQ (RG_GOM_ERRTYPE_BASE) +#define RGSCHERR_GOM_RECFG_REQ (RG_GOM_ERRTYPE_BASE + 1) +#define RGSCHERR_GOM_DEL_REQ (RG_GOM_ERRTYPE_BASE + 2) +#define RGSCHERR_GOM_RESET_REQ (RG_GOM_ERRTYPE_BASE + 3) +#ifdef LTE_ADV +#define RGSCHERR_GOM_SCELL_REQ (RG_GOM_ERRTYPE_BASE + 4) +#endif /* LTE_ADV */ +/* L2 Measurement Module related error MACROs for error type */ +#ifdef LTE_L2_MEAS +#define RG_L2M_ERRTYPE_BASE (RGSCHERR_GOM_RESET_REQ + 1) +#define RGSCHERR_L2M_MEASREQ (RG_L2M_ERRTYPE_BASE) +#endif +/* *********************************************************** + * Error Cause + *************************************************************/ +/* Errcause defines for DHM */ +#define RG_DHM_ERRCAUSE_BASE (RGSCHERR_GOM_DEL_REQ + 1) +#define RG_DHM_MEM_ALLOC_FAIL (RG_DHM_ERRCAUSE_BASE ) +/* Errcause defines for RAM */ +#define RG_RAM_ERRCAUSE_BASE (RG_DHM_MEM_ALLOC_FAIL + 1) +#define RGSCHERR_RAM_MEM_EXHAUST (RG_RAM_ERRCAUSE_BASE ) +#define RGSCHERR_RAM_NO_MSG3_RCVD (RG_RAM_ERRCAUSE_BASE + 1) +#define RGSCHERR_RAM_RNTI_EXHAUST (RG_RAM_ERRCAUSE_BASE + 2) +/* Errcause defines for RAM */ +#define RG_TOM_ERRCAUSE_BASE (RGSCHERR_RAM_RNTI_EXHAUST + 1) +#define RGSCHERR_TOM_INV_CELL_ID (RG_TOM_ERRCAUSE_BASE ) +#define RGSCHERR_TOM_MEM_EXHAUST (RG_TOM_ERRCAUSE_BASE + 1) +/* CFG Module related error MACROs for error cause */ +#define RG_CFG_ERRCAUSE_BASE (RGSCHERR_TOM_MEM_EXHAUST + 1) +#define RGSCHERR_CFG_INVALID_RGR_CELL_CFG (RG_CFG_ERRCAUSE_BASE) +#define RGSCHERR_CFG_INVALID_RGR_UE_CFG (RG_CFG_ERRCAUSE_BASE + 1) +#define RGSCHERR_CFG_INVALID_RGR_DED_LC_CFG (RG_CFG_ERRCAUSE_BASE + 2) +#define RGSCHERR_CFG_INVALID_RGR_DED_LCG_CFG (RG_CFG_ERRCAUSE_BASE + 2) +#define RGSCHERR_CFG_INVALID_RGR_CMN_LC_CFG (RG_CFG_ERRCAUSE_BASE + 3) +#define RGSCHERR_CFG_INVALID_RGR_CELL_RECFG (RG_CFG_ERRCAUSE_BASE + 4) +#define RGSCHERR_CFG_INVALID_RGR_UE_RECFG (RG_CFG_ERRCAUSE_BASE + 5) +#define RGSCHERR_CFG_INVALID_RGR_LC_RECFG (RG_CFG_ERRCAUSE_BASE + 6) +#define RGSCHERR_CFG_INVALID_RGR_LCG_RECFG (RG_CFG_ERRCAUSE_BASE + 6) +#define RGSCHERR_CFG_RGR_CELL_CFG (RG_CFG_ERRCAUSE_BASE + 7) +#define RGSCHERR_CFG_RGR_UE_CFG (RG_CFG_ERRCAUSE_BASE + 8) +#define RGSCHERR_CFG_RGR_DED_LC_CFG (RG_CFG_ERRCAUSE_BASE + 9) +#define RGSCHERR_CFG_RGR_DED_LCG_CFG (RG_CFG_ERRCAUSE_BASE + 9) +#define RGSCHERR_CFG_RGR_CMN_LC_CFG (RG_CFG_ERRCAUSE_BASE + 10) +#define RGSCHERR_CFG_RGR_CELL_RECFG (RG_CFG_ERRCAUSE_BASE + 11) +#define RGSCHERR_CFG_RGR_UE_RECFG (RG_CFG_ERRCAUSE_BASE + 12) +#define RGSCHERR_CFG_RGR_LC_RECFG (RG_CFG_ERRCAUSE_BASE + 13) +#define RGSCHERR_CFG_RGR_LCG_RECFG (RG_CFG_ERRCAUSE_BASE + 13) +#define RGSCHERR_CFG_RGR_CELL_DEL (RG_CFG_ERRCAUSE_BASE + 14) +#define RGSCHERR_CFG_RGR_UE_DEL (RG_CFG_ERRCAUSE_BASE + 15) +#define RGSCHERR_CFG_RGR_LC_DEL (RG_CFG_ERRCAUSE_BASE + 16) +#define RGSCHERR_CFG_RGR_LCG_DEL (RG_CFG_ERRCAUSE_BASE + 16) +#define RGSCHERR_CFG_INVALID_RGR_UE_RESET (RG_CFG_ERRCAUSE_BASE + 17) +#define RGSCHERR_CFG_RGR_UE_RESET (RG_CFG_ERRCAUSE_BASE + 18) +/* Added for SI Enhancement*/ +#ifdef RGR_SI_SCH +#define RGSCHERR_CFG_INVALID_RGR_SI_CFG (RG_CFG_ERRCAUSE_BASE + 19) +#endif/*RGR_SI_SCH*/ +#ifdef LTEMAC_HDFDD +#define RGSCHERR_HDFDD_SPSCFGRD (RG_CFG_ERRCAUSE_BASE + 20) +#endif +/* ccpu00117452 - MOD - Changed macro name from + RGR_RRM_DLPWR_CNTRL to RGR_CQI_REPT */ +#ifdef RGR_CQI_REPT +#define RGSCHERR_CQIREPT (RG_CFG_ERRCAUSE_BASE + 21) +#endif + +/* LTE_ADV_FLAG_REMOVED_START */ +#define RGSCHERR_CFG_INVALID_RGR_LOAD_INF (RG_CFG_ERRCAUSE_BASE + 22) +/* LTE_ADV_FLAG_REMOVED_END */ + +#ifdef LTE_ADV +#define RGSCHERR_CFG_INVALID_RGR_UE_SCELL_RECFG (RG_CFG_ERRCAUSE_BASE + 23) +#define RGSCHERR_CFG_INVALID_RGR_UE_SCELL_PUCCH_RECFG (RG_CFG_ERRCAUSE_BASE + 24) +#endif +#define RGSCHERR_CFG_INVALID_RGR_ENB_CFG (RG_CFG_ERRCAUSE_BASE + 25) + +/* Scheduler related error causes */ +#define RG_SCH_ERRCAUSE_BASE (RGSCHERR_CFG_RGR_LC_DEL + 1) +#define RGSCHERR_SCH_CFG RG_SCH_ERRCAUSE_BASE +#define RGSCHERR_SCH_LCG_NOT_CFGD (RG_SCH_ERRCAUSE_BASE + 1) +#define RGSCHERR_SCH_NO_LCG_CFGD (RG_SCH_ERRCAUSE_BASE + 2) +#ifdef LTE_L2_MEAS /* TODO: Values? */ +#define RG_L2MEAS_ERRTYPE_BASE (RGSCHERR_SCH_NO_LCG_CFGD + 1) +#define RGSCHERR_SCH_L2MEAS (RG_L2MEAS_ERRTYPE_BASE + 2) +#define RGSCHERR_SCH_INVALID_MEAS_TYPE (RG_L2MEAS_ERRTYPE_BASE + 3) +#define RGSCHERR_SCH_INVALID_PARAM_RANGE (RG_L2MEAS_ERRTYPE_BASE + 4) +#define RGSCHERR_SCH_INVALID_CELLID (RG_L2MEAS_ERRTYPE_BASE + 5) +#define RGSCHERR_SCH_INVALID_MEASTYPE (RG_L2MEAS_ERRTYPE_BASE + 6) +#define RGSCHERR_SCH_DUP_TRANSID (RG_L2MEAS_ERRTYPE_BASE + 7) +#define RGSCHERR_SCH_L2MEAS_FAILED (RG_L2MEAS_ERRTYPE_BASE + 8) +#define RGSCHERR_SCH_ALLOC_FAILED (RG_L2MEAS_ERRTYPE_BASE + 9) +#define RGSCHERR_SCH_INVALID_QCI_VAL (RG_L2MEAS_ERRTYPE_BASE + 10) +#endif /* LTE_L2_MEAS */ + + +#endif /* __RGSCHERRH__ */ +/********************************************************************** + + End of file +**********************************************************************/ diff --git a/src/5gnrmac/rg_sch_ex_ms.c b/src/5gnrmac/rg_sch_ex_ms.c new file mode 100755 index 000000000..b75e33960 --- /dev/null +++ b/src/5gnrmac/rg_sch_ex_ms.c @@ -0,0 +1,303 @@ +/******************************************************************************* +################################################################################ +# Copyright (c) [2017-2019] [Radisys] # +# # +# 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. # +################################################################################ +*******************************************************************************/ + +/************************************************************************ + + Name: LTE-MAC layer + + Type: C source file + + Desc: C source code SSI Interface Implementation + + File: rg_sch_ex_ms.c + +**********************************************************************/ + +/** @file rg_ex_ms.c +@brief This file contains the implementation of callback functions +registered with SSI during the LTE MAC Task initialization. +*/ +/* header include files -- defines (.h) */ +#include "envopt.h" /* environment options */ +#include "envdep.h" /* environment dependent */ +#include "envind.h" /* environment independent */ +#include "gen.h" /* general layer */ +#include "ssi.h" /* system services */ +#include "cm5.h" /* common timers defines */ +#include "cm_hash.h" /* common hash list defines */ +#include "cm_llist.h" /* common linked list defines */ +#include "cm_mblk.h" /* memory management */ +#include "cm_tkns.h" /* common tokens */ +#include "cm_lte.h" /* common tokens */ +#include "tfu.h" /* RGU defines */ +#include "lrg.h" /* layer management defines for LTE-MAC */ +#include "rgr.h" /* layer management defines for LTE-MAC */ +#include "rgm.h" /* layer management defines for LTE-MAC */ +#include "rg_env.h" /* customisable defines and macros for LTE-MAC */ +#include "rg_sch_err.h" /* defines and macros for Scheduler */ +#include "rg_sch_inf.h" /* defines and macros for Scheduler */ +#include "rg_sch.h" /* defines and macros for Scheduler */ + + +/* header/extern include files (.x) */ +#include "gen.x" /* general layer typedefs */ +#include "ssi.x" /* system services typedefs */ +#include "cm5.x" /* common timers */ +#include "cm_hash.x" /* common hash list */ +#include "cm_lib.x" /* common library */ +#include "cm_llist.x" /* common linked list */ +#include "cm_mblk.x" /* memory management */ +#include "cm_tkns.x" /* common tokens */ +#include "cm_lte.x" /* common tokens */ +#include "tfu.x" /* RGU types */ +#include "lrg.x" /* layer management typedefs for MAC */ +#include "rgr.x" /* layer management typedefs for MAC */ +#include "rgm.x" /* layer management typedefs for MAC */ +#include "rg_sch_inf.x" /* typedefs for Scheduler */ +#include "rg_sch.x" /* typedefs for Scheduler */ + + + + +/** + * @brief Task Activation callback function. + * + * @details + * + * Function : schActvTsk + * + * Primitives invoked by MAC's users/providers through + * a loosely coupled interface arrive here by means of + * SSI's message handling. This API is registered with + * SSI during the Task Registration of MAC. + * + * @param[in] Pst *pst, post structure of the Primitive. + * @param[in] Buffer *mBuf, Packed primitive parameters in the buffer. + * @param[in] Reason reason. + * @return S16 + * -# ROK + **/ +#ifdef ANSI +PUBLIC S16 schActvTsk +( +Pst *pst, /* post structure */ +Buffer *mBuf /* message buffer */ +) +#else +PUBLIC S16 schActvTsk(pst, mBuf) +Pst *pst; /* post structure */ +Buffer *mBuf; /* message buffer */ +#endif +{ + TRC2(schActvTsk) + + switch(pst->srcEnt) + { + /* The originator of this message is the stack manager, + * unpack and go to the respective primitive processing function */ + case ENTSM: + switch(pst->event) + { +#ifdef LCRGMILRG + case EVTLRGSCHCFGREQ: + /* Process a config. request */ + cmUnpkLrgSchCfgReq(RgMiLrgSchCfgReq, pst, mBuf); + break; + case EVTLRGSCHCNTRLREQ: + /* Process a control request */ + cmUnpkLrgSchCntrlReq(RgMiLrgSchCntrlReq, pst, mBuf); + break; + case EVTLRGSCHSTAIND: + /* Process a control request */ + cmUnpkLrgSchStaInd(RgMiLrgSchStaInd, pst, mBuf); + break; +#ifdef LTE_L2_MEAS + case EVTLRGSCHL2MEASREQ: + /* Process L2 Measurement request */ + cmUnpkLrgSchL2MeasReq(RgMiLrgSchL2MeasReq, pst, mBuf); + break; + case EVTLRGSCHL2MEASSTOPREQ: + /* Process L2 Measurement Stop request */ + cmUnpkLrgSchL2MeasStopReq(RgMiLrgSchL2MeasStopReq, pst, mBuf); + break; + case EVTLRGSCHL2MEASSENDREQ: + /* Process L2 Measurement Send request */ + cmUnpkLrgSchL2MeasSendReq(RgMiLrgSchL2MeasSendReq, pst, mBuf); + break; +#endif +#endif /* LCRGMILRG */ + default: + RGSCH_FREE_MSG(mBuf); + break; + } + break; + case ENTNX: + switch(pst->event) + { +#ifdef LCRGUIRGR + case EVTRGRBNDREQ: + cmUnpkRgrBndReq(RgUiRgrBndReq, pst, mBuf); + break; + case EVTRGRUBNDREQ: + cmUnpkRgrUbndReq(RgUiRgrUbndReq, pst, mBuf); + break; + case EVTRGRCFGREQ: + cmUnpkRgrCfgReq(RgUiRgrCfgReq, pst, mBuf); + break; +#ifdef RGR_SI_SCH + case EVTRGRSICFGREQ: + cmUnpkRgrSiCfgReq(RgUiRgrSiCfgReq, pst, mBuf); + break; + case EVTRGRWARNINGSICFGREQ: + cmUnpkRgrWarningSiCfgReq(RgUiRgrWarningSiCfgReq, pst, mBuf); + break; + + case EVTRGRWARNINGSISTOPREQ: + cmUnpkRgrWarningSiStopReq(RgUiRgrWarningSiStopReq, pst, mBuf); + break; +#endif/*RGR_SI_SCH */ + /* LTE_ADV_FLAG_REMOVED_START */ + case EVTRGRLOADINFREQ: + cmUnpkRgrLoadInfReq(RgUiRgrLoadInfReq, pst, mBuf); + break; + /* LTE_ADV_FLAG_REMOVED_END */ +#endif + default: + RGSCH_FREE_MSG(mBuf); + break; + } + break; + case ENTTF: + switch(pst->event) + { +/*#ifdef LCRGLITFU L2Split */ +#if (defined(LCRGLITFU) || defined(LWLCRGLITFU)) + case EVTTFUSCHBNDCFM: + cmUnpkTfuBndCfm(RgLiTfuSchBndCfm, pst, mBuf); + break; + case EVTTFURAREQIND: + cmUnpkTfuRaReqInd(RgLiTfuRaReqInd, pst, mBuf); + break; + case EVTTFUULCQIIND: + cmUnpkTfuUlCqiInd(RgLiTfuUlCqiInd, pst, mBuf); + break; + case EVTTFUHQIND: + cmUnpkTfuHqInd(RgLiTfuHqInd, pst, mBuf); + break; + case EVTTFUSRIND: + cmUnpkTfuSrInd(RgLiTfuSrInd, pst, mBuf); + break; + case EVTTFUDLCQIIND: + cmUnpkTfuDlCqiInd(RgLiTfuDlCqiInd, pst, mBuf); + break; + case EVTTFUCRCIND: + /*cmUnpkTfuCrcIndInfo(RgLiTfuCrcInd, pst, mBuf); */ + cmUnpkTfuCrcInd(RgLiTfuCrcInd, pst, mBuf); + break; + case EVTTFUTIMINGADVIND: + cmUnpkTfuTimingAdvInd(RgLiTfuTimingAdvInd, pst, mBuf); + break; + case EVTTFUSCHTTIIND: + cmUnpkTfuSchTtiInd(RgLiTfuSchTtiInd, pst, mBuf); + break; + case EVTTFUPUCCHDELPWR: + cmUnpkTfuPucchDeltaPwr(RgLiTfuPucchDeltaPwrInd, pst, mBuf); + break; + case EVTTFUDOAIND: + cmUnpkTfuDoaInd(RgLiTfuDoaInd, pst, mBuf); + break; +#ifdef TFU_UPGRADE + case EVTTFURAWCQIIND: + cmUnpkTfuRawCqiInd(RgLiTfuRawCqiInd, pst, mBuf); + break; + case EVTTFUSRSIND: + cmUnpkTfuSrsInd(RgLiTfuSrsInd, pst, mBuf); + break; +#endif + /*LAA: Error Indication on SCell*/ + case EVTTFUERRIND: + cmUnpkTfuErrInd(RgLiTfuErrInd, pst, mBuf); + break; +#endif + default: + RGSCH_FREE_MSG(mBuf); + break; + } + break; + case ENTRG: /* When MAC sends a msg to Scheduler instance */ + switch(pst->event) + { +#ifdef LCSCH + case EVTINFDEDBOUPDTREQ: + cmUnpkMacSchDedBoUpdtReq(RgMacSchDedBoUpdtReq, pst, mBuf); + break; + case EVTINFCMNBOUPDTREQ: + cmUnpkMacSchCmnBoUpdtReq(RgMacSchCmnBoUpdtReq, pst, mBuf); + break; + case EVTINFSFRECPIND: + cmUnpkMacSchSfRecpInd(RgMacSchSfRecpInd, pst, mBuf); + break; + /*Fix: start: Inform UE delete to scheduler*/ + case EVTINFUEDELIND: + cmUnpkMacSchUeDelInd(RgMacSchUeDelInd, pst, mBuf); + break; + /*Fix: end: Inform UE delete to scheduler*/ +#ifdef LTE_L2_MEAS + case EVTINFL2MEASCFM: + cmUnpkMacSchL2MeasCfm(RgMacSchL2MeasCfm, pst, mBuf); + break; + case EVTINFL2MEASSTOPCFM: + cmUnpkMacSchL2MeasCfm(RgMacSchL2MeasStopCfm, pst, mBuf); + break; +#endif +#endif + default: + RGSCH_FREE_MSG(mBuf); + break; + } + break; + case ENTRM: /* When RRM sends msg to scheduler */ + switch(pst->event) + { + case EVTRGMBNDREQ: + cmUnpkRgmBndReq(RgUiRgmBndReq, pst, mBuf); + break; + case EVTRGMUBNDREQ: + cmUnpkRgmUbndReq(RgUiRgmUbndReq, pst, mBuf); + break; + case EVTRGMCFGPRBRPRT: + cmUnpkRgmCfgPrbRprt(RgUiRgmCfgPrbRprt, pst, mBuf); + break; + default: + RGSCH_FREE_MSG(mBuf); + break; + } + break; + default: + RGSCH_FREE_MSG(mBuf); + break; + } + SExitTsk(); + RETVALUE(ROK); +}/* end of schActvTsk */ + + +/********************************************************************** + + End of file +**********************************************************************/ diff --git a/src/5gnrmac/rg_sch_gom.c b/src/5gnrmac/rg_sch_gom.c new file mode 100755 index 000000000..d754c50d9 --- /dev/null +++ b/src/5gnrmac/rg_sch_gom.c @@ -0,0 +1,1871 @@ +/******************************************************************************* +################################################################################ +# Copyright (c) [2017-2019] [Radisys] # +# # +# 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. # +################################################################################ +*******************************************************************************/ + +/************************************************************************ + + Name: LTE-MAC layer + + Type: C source file + + Desc: C source code for Entry point fucntions + + File: rg_sch_gom.c + +**********************************************************************/ + +/** @file rg_sch_gom.c +@brief This module does processing related to handling of upper interface APIs +invoked by RRM towards MAC. +*/ + +static const char* RLOG_MODULE_NAME="MAC"; +static int RLOG_MODULE_ID=4096; +static int RLOG_FILE_ID=164; + +/* header include files -- defines (.h) */ +#include "envopt.h" /* environment options */ +#include "envdep.h" /* environment dependent */ +#include "envind.h" /* environment independent */ +#include "gen.h" /* general layer */ +#include "ssi.h" /* system service interface */ +#include "cm_hash.h" /* common hash list */ +#include "cm_mblk.h" /* common memory link list library */ +#include "cm_llist.h" /* common linked list library */ +#include "cm_err.h" /* common error */ +#include "cm_lte.h" /* common LTE */ +#include "lrg.h" +#include "rgr.h" +#include "tfu.h" +#include "rg_env.h" +#include "rg_sch_inf.h" +#include "rg_sch.h" +#include "rg_sch_err.h" +#include "rl_interface.h" +#include "rl_common.h" + +/* header/extern include files (.x) */ +#include "gen.x" /* general layer */ +#include "ssi.x" /* system service interface */ +#include "cm5.x" /* common timers */ +#include "cm_lib.x" /* common library */ +#include "cm_hash.x" /* common hash list */ +#include "cm_llist.x" /* common linked list library */ +#include "cm_mblk.x" /* memory management */ +#include "cm_tkns.x" /* common tokens */ +#include "cm_lte.x" /* common LTE */ +#include "lrg.x" +#include "rgr.x" +#include "tfu.x" +#include "rg_sch_inf.x" +#include "rg_sch.x" + +/* local defines */ +PRIVATE S16 rgSCHGomHndlCfgReq ARGS((RgSchCb *instCb, SpId spId, + RgrCfg *cfg, RgSchErrInfo *errInfo)); +PRIVATE S16 rgSCHGomHndlRecfgReq ARGS((RgSchCb *instCb, SpId spId, + RgrRecfg *recfg, RgSchErrInfo *errInfo)); +PRIVATE S16 rgSCHGomHndlResetReq ARGS((RgSchCb *instCb,SpId spId,RgrRst *reset, + RgSchErrInfo *errInfo)); +PRIVATE S16 rgSCHGomGetCellIdFrmCfgReq ARGS((RgrCfgReqInfo *rgrCfgReq, + CmLteCellId *cellId)); +PRIVATE S16 rgSCHGomCfgReq ARGS((Region reg, Pool pool, RgSchCb *instCb, + SpId spId, RgrCfgTransId transId, RgrCfgReqInfo *cfgReqInfo)); +PRIVATE S16 rgSCHGomEnqCfgReq ARGS((Region reg, Pool pool, RgSchCellCb *cell, + RgrCfgTransId transId, RgrCfgReqInfo *rgrCfgReq)); +PRIVATE S16 rgSCHGomHndlDelReq ARGS((RgSchCb *instCb,SpId spId, + RgrDel *del,RgSchErrInfo *errInfo)); +#ifdef LTE_ADV +PRIVATE S16 rgSCHGomHndlSCellActDeactReq ARGS((RgSchCb *instCb, SpId spId, + RgrSCellActDeactEvnt *sCellActDeactEvnt, RgSchErrInfo *errInfo, U8 action)); +#endif /* LTE_ADV */ +#ifdef EMTC_ENABLE +EXTERN S16 rgSchEmtcGetSiWinPerd ARGS(( +RgSchCellCb *cell, +U16 *siWinSize, +U16 *minPeriod +)); +extern S16 rgSCHEmtcUtlCalMcsAndNPrb +( + RgSchCellCb *cell, + U8 cfgType, + MsgLen msgLen, + U8 siId + ); + +EXTERN S32 rgSCHEmtcUtlGetAllwdCchTbSzForSI ARGS( +( +U32 bo +)); + +EXTERN Void rgSCHEmtcWarningSiCfg ARGS( +( +RgSchCellCb *cell, +RgrWarningSiCfgReqInfo *warningSiCfgReqInfo, +U16 idx +)); +#endif + + +/* local typedefs */ + +/* local externs */ + +/* forward references */ + + + +/** + * @brief Handler for config request from RRM to Schedular. + * + * @details + * + * Function: rgSCHGomHndlCfg + * + * This API is called from schedulers UIM and it handles config request + * from RRM to Scheduler. + * + * Processing Steps: + * - If the request is for the inactive cell, + * - Handle request.Call rgSCHGomCfgReq. + * - Else, + * - Enqueue the request. Call rgSCHGomEnqCfgReq. + * + * @param[in] Region reg + * @param[in] Poll pool + * @param[in] RgSchCb *instCb + * @param[in] SpId spId + * @param[in] RgrCfgTransId transId + * @param[in] RgrCfgReqInfo *cfgReqInfo + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 rgSCHGomHndlCfg +( +Region reg, +Pool pool, +RgSchCb *instCb, +SpId spId, +RgrCfgTransId transId, +RgrCfgReqInfo *cfgReqInfo +) +#else +PUBLIC S16 rgSCHGomHndlCfg(reg, pool, instCb, spId, transId, cfgReqInfo) +Region reg; +Pool pool; +RgSchCb *instCb; +SpId spId; +RgrCfgTransId transId; +RgrCfgReqInfo *cfgReqInfo; +#endif +{ + S16 ret; + CmLteCellId cellId; + RgSchCellCb *cell = NULLP; + U8 cfmStatus = RGR_CFG_CFM_NOK; +#ifdef DEBUGP + Inst inst = (instCb->rgSchInit.inst ); +#endif + + TRC2(rgSCHGomHndlCfg); + /* Apply the configuration for Cell Configuration or Delete */ + if (cfgReqInfo->action != RGR_RECONFIG) + { + ret = rgSCHGomCfgReq (reg, pool, instCb, spId, transId, cfgReqInfo); + RETVALUE(ret); + } + + /* Fetch the cell Id for the recieved request */ + if((rgSCHGomGetCellIdFrmCfgReq(cfgReqInfo, &cellId)) != ROK) + { + RLOG_ARG0(L_ERROR,DBG_INSTID,inst, "Action.Config Type Error"); + + SPutSBuf(reg, pool, (Data *)cfgReqInfo, (Size)sizeof(*cfgReqInfo)); + cfgReqInfo = NULLP; + rgSCHUtlRgrCfgCfm(instCb->rgSchInit.inst, spId, transId, cfmStatus); + RETVALUE(RFAILED); + } + /* Extract the cell and Enquee Config Request */ + if(NULLP != instCb->rgrSap[spId].cell) + { + if(cellId != instCb->rgrSap[spId].cell->cellId) + { + RLOG_ARG2(L_ERROR,DBG_CELLID,cellId, "Cell with Id %d already exists " + "on sap %d", instCb->rgrSap[spId].cell->cellId, spId); + + SPutSBuf(reg, pool, (Data *)cfgReqInfo, (Size)sizeof(*cfgReqInfo)); + cfgReqInfo = NULLP; + rgSCHUtlRgrCfgCfm(instCb->rgSchInit.inst, spId, transId, cfmStatus); + RETVALUE(RFAILED); + } + cell = instCb->rgrSap[spId].cell; + + /* Enqueue the configuration */ + ret = rgSCHGomEnqCfgReq(reg, pool, cell, transId, cfgReqInfo); + if (ret != ROK) + { + RLOG_ARG0(L_ERROR,DBG_CELLID,cellId, "rgSCHGomHndlCfg: Enqueuing CfgReq " + "Failed "); + + SPutSBuf(reg, pool, (Data *)cfgReqInfo, (Size)sizeof(*cfgReqInfo)); + cfgReqInfo = NULLP; + rgSCHUtlRgrCfgCfm(instCb->rgSchInit.inst, spId, transId, cfmStatus); + RETVALUE(RFAILED); + } + + RETVALUE(ROK); + } + SPutSBuf(reg, pool, (Data *)cfgReqInfo, (Size)sizeof(*cfgReqInfo)); + cfgReqInfo = NULLP; + rgSCHUtlRgrCfgCfm(instCb->rgSchInit.inst, spId, transId, cfmStatus); + RETVALUE(RFAILED); + +}/* rgSCHGomHndlCfg */ + + +/** + * @brief Handler to handle config request from RRM to Scheduler. + * + * @details + * + * Function: rgSCHGomCfgReq + * + * This API handles processing for config request from RRM to Scheduler. + * + * Processing Steps: + * - If Configuration request, call rgSCHGomHndlCfgReq. + * - Else if Reconfiguration request, call rgSCHGomHndlRecfgReq. + * - If successful, send configuration confirm to RRM. + * Call rgSCHUtlRgrCfgCfm else FAIL. + * + * @param[in] Region reg + * @param[in] Poll pool + * @param[in] RgSchCb *instCb + * @param[in] SpId spId + * @param[in] RgrCfgTransId transId + * @param[in] RgrCfgReqInfo *cfgReqInfo + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PRIVATE S16 rgSCHGomCfgReq +( +Region reg, +Pool pool, +RgSchCb *instCb, +SpId spId, +RgrCfgTransId transId, +RgrCfgReqInfo *cfgReqInfo +) +#else +PRIVATE S16 rgSCHGomCfgReq(reg, pool, instCb, spId, transId, cfgReqInfo) +Region reg; +Pool pool; +RgSchCb *instCb; +SpId spId; +RgrCfgTransId transId; +RgrCfgReqInfo *cfgReqInfo; +#endif +{ + U8 cfmStatus = RGR_CFG_CFM_OK; + S16 ret; + RgSchErrInfo errInfo; +#ifdef DEBUGP + Inst inst = (instCb->rgSchInit.inst ); +#endif + TRC2(rgSCHGomCfgReq); +#ifdef EMTC_ENABLE +printf("\n AT MAC rgSCHGomCfgReq \n"); +#endif + + /* Process Config/Reconfig/Delete request from RRM */ + switch (cfgReqInfo->action) + { + case RGR_CONFIG: + { + ret = rgSCHGomHndlCfgReq(instCb, spId, + &cfgReqInfo->u.cfgInfo, &errInfo); + break; + } + case RGR_RECONFIG: + { + ret = rgSCHGomHndlRecfgReq(instCb, spId, + &cfgReqInfo->u.recfgInfo, &errInfo); + break; + } + case RGR_RESET: + { + ret = rgSCHGomHndlResetReq(instCb, spId, + &cfgReqInfo->u.rstInfo, &errInfo); + break; + } + case RGR_DELETE: + { + ret = rgSCHGomHndlDelReq(instCb, spId, + &cfgReqInfo->u.delInfo, &errInfo); + break; + } +#ifdef LTE_ADV + case RGR_SCELL_ACT: + case RGR_SCELL_DEACT: + case RGR_SCELL_READY: + { + ret = rgSCHGomHndlSCellActDeactReq(instCb, spId, + &cfgReqInfo->u.sCellActDeactEvnt, &errInfo, cfgReqInfo->action); + break; + } +#endif /* LTE_ADV */ + default: + { + RLOG_ARG1(L_ERROR,DBG_INSTID,inst, "Invalid configuration " + "action %d", cfgReqInfo->action); + ret = RFAILED; + } + } /* End of switch */ + + if (ret != ROK) + { + cfmStatus = RGR_CFG_CFM_NOK; + } + + SPutSBuf(reg, pool, (Data *)cfgReqInfo, (Size)sizeof(*cfgReqInfo)); + cfgReqInfo = NULLP; +#ifdef EMTC_ENABLE +printf("\n AT MAC sending RGR cfg cfm \n"); +#endif + + /* Send back confirmation status to RRM */ + rgSCHUtlRgrCfgCfm(instCb->rgSchInit.inst, spId, transId, cfmStatus); +#ifdef EMTC_ENABLE +printf("\n AT MAC RGR cfg cfm sent\n"); +#endif + + RETVALUE(ret); +} /* rgSCHGomCfgReq */ + + +/** + * @brief Handler to enqueuing config request from RRM to Scheduler. + * + * @details + * + * Function: rgSCHGomEnqCfgReq + * + * This API enqueues config request from RRM to MAC. + * + * Processing Steps: + * - Allocate the configuration request element. + * - Copy the contents of the recieved configuration to config request + * element and free the recieved configuration pointer. + * - If the configuration is without activation time, + * - Enqueue the request in crntRgrCfgLst of the cell at the end of + * the list. + * - Else + * - Enqueue the request in pndngRgrCfgLst of the cell. + * + * @param[in] Region reg, + * @param[in] Pool pool + * @param[in] RgSchCellCb *cell + * @param[in] RgrCfgTransId transId + * @param[in] RgrCfgReqInfo *rgrCfgReq + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PRIVATE S16 rgSCHGomEnqCfgReq +( +Region reg, +Pool pool, +RgSchCellCb *cell, +RgrCfgTransId transId, +RgrCfgReqInfo *rgrCfgReq +) +#else +PRIVATE S16 rgSCHGomEnqCfgReq(reg, pool, cell, transId, rgrCfgReq) +Region reg; +Pool pool; +RgSchCellCb *cell; +RgrCfgTransId transId; +RgrCfgReqInfo *rgrCfgReq; +#endif +{ + S16 ret; + U32 sfDiff; + RgSchCfgElem *rgrCfgElem = NULLP; + CmLteTimingInfo actvTime; + Inst inst = cell->instIdx; + + TRC2(rgSCHGomEnqCfgReq); + + /* Allocate memory for config Element */ + ret = rgSCHUtlAllocSBuf(inst, (Data **)&rgrCfgElem, sizeof(RgSchCfgElem)); + if ((ret != ROK) || ((U8 *)rgrCfgElem == NULLP)) + { + RETVALUE(RFAILED); + } + + /* Initialize the configuration element */ + cmMemcpy((U8*)rgrCfgElem->rgrCfg.transId.trans,(U8*)transId.trans, + sizeof(transId.trans)); + rgrCfgElem->rgrCfg.reg = reg; + rgrCfgElem->rgrCfg.pool = pool; + rgrCfgElem->rgrCfg.rgrCfgReq = rgrCfgReq; + rgrCfgElem->cfgReqLstEnt.prev = NULLP; + rgrCfgElem->cfgReqLstEnt.next = NULLP; + rgrCfgElem->cfgReqLstEnt.node = (PTR )rgrCfgElem; + + /* Add configuration element to current/pending cfgLst */ + if (((rgrCfgReq->action == RGR_RECONFIG) && + (rgrCfgReq->u.recfgInfo.recfgType == RGR_CELL_CFG) && + (rgrCfgReq->u.recfgInfo.u.cellRecfg.recfgActvTime.pres == TRUE))) + + { + actvTime = + rgrCfgReq->u.recfgInfo.u.cellRecfg.recfgActvTime.actvTime; + + /* Check if the activation time is valid */ + if (actvTime.sfn >= RGSCH_MAX_SFN + || actvTime.subframe >= RGSCH_NUM_SUB_FRAMES_5G) + { + RLOG_ARG4(L_ERROR,DBG_CELLID,cell->cellId, "Invalid activation time for RGR " + "config request: activation sfn %d activation subframe %d current " + "sfn %d current subframe %d", actvTime.sfn, actvTime.subframe, + cell->crntTime.sfn, cell->crntTime.subframe); + /* ccpu00117052 - MOD - Passing double pointer + for proper NULLP assignment*/ + rgSCHUtlFreeSBuf(inst, (Data **)&rgrCfgElem, sizeof(*rgrCfgElem)); + RETVALUE(RFAILED); + } + + sfDiff = RGSCH_CALC_SF_DIFF(actvTime, cell->crntTime); + + if (sfDiff > (RGR_ACTV_WIN_SIZE * RGSCH_NUM_SUB_FRAMES_5G)) + { + RLOG_ARG4(L_ERROR,DBG_CELLID,cell->cellId,"Invalid activation time for RGR" + " config request: activation sfn %d activation subframe %d " + "current sfn %d current subframe %d", actvTime.sfn, + actvTime.subframe, cell->crntTime.sfn, cell->crntTime.subframe); + /* ccpu00117052 - MOD - Passing double pointer + for proper NULLP assignment*/ + rgSCHUtlFreeSBuf(inst, (Data **)&rgrCfgElem, sizeof(*rgrCfgElem)); + RETVALUE(RFAILED); + } + + if (sfDiff) + { + /* Add to pending cfgReqLst */ + rgrCfgElem->actvTime = actvTime; + rgSCHDbmInsPndngRgrCfgElem(cell, rgrCfgElem); + /* Cfm to be sent only after applying request */ + RETVALUE(ROK); + } + } + + /* Add to current cfgReq list */ + rgSCHDbmInsCrntRgrCfgElem(cell, rgrCfgElem); + /* Cfm to be sent only after applying request */ + RETVALUE(ROK); +} /* rgSCHGomEnqCfgReq */ + + +/** + * @brief Handler for TTI processing for configurations recieved from RRM. + * + * @details + * + * Function: rgSCHGomTtiHndlr + * + * This API does TTI processing for configurations recieved from RRM. + * + * Processing Steps: + * - It dequeues config request from the current configuration list. + * For each config request in the list: + * - Processes the request. Call rgSCHGomCfgReq. + * - It dequeues config request for the current tti from the pending + * configuration list. For each config request in the list: + * - Processes the request. Call rgSCHGomCfgReq. + * + * @param[in] RgSchCellCb *cell + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 rgSCHGomTtiHndlr +( +RgSchCellCb *cell, +SpId spId +) +#else +PUBLIC S16 rgSCHGomTtiHndlr(cell, spId) +RgSchCellCb *cell; +SpId spId; +#endif +{ + RgSchCfgElem *cfgElem; + Inst inst= cell->instIdx; + TRC2(rgSCHGomTtiHndlr); + + /* Dequeue from current config list */ + while ((cfgElem = rgSCHDbmGetNextCrntRgrCfgElem(cell, NULLP)) != NULLP) + { + rgSCHDbmDelCrntRgrCfgElem(cell, cfgElem); + rgSCHGomCfgReq(cfgElem->rgrCfg.reg,cfgElem->rgrCfg.pool, + &rgSchCb[inst], spId, cfgElem->rgrCfg.transId, + cfgElem->rgrCfg.rgrCfgReq); + /* ccpu00117052 - MOD - Passing double pointer + for proper NULLP assignment*/ + rgSCHUtlFreeSBuf(inst, (Data **)&cfgElem, sizeof(*cfgElem)); + } + + /* Handle config requests from pending config list */ + while((cfgElem = rgSCHDbmGetPndngRgrCfgElemByKey(cell, cell->crntTime)) != NULLP) + { + rgSCHDbmDelPndngRgrCfgElem(cell, cfgElem); + rgSCHGomCfgReq(cfgElem->rgrCfg.reg, cfgElem->rgrCfg.pool, + &rgSchCb[inst], spId, cfgElem->rgrCfg.transId, + cfgElem->rgrCfg.rgrCfgReq); + /* ccpu00117052 - MOD - Passing double pointer + for proper NULLP assignment*/ + rgSCHUtlFreeSBuf(inst, (Data **)&cfgElem, sizeof(*cfgElem)); + } + + RETVALUE(ROK); +} + + +/** + * @brief Handler to handle configuration request from RRM to MAC. + * + * @details + * + * Function: rgSCHGomHndlCfgReq + * + * This API handles processing for configuration request from RRM to MAC. + * + * - Processing Steps: + * - Validate configuration request parameters at CFG module. + * Call rgSCHCfgVldtRgrCellCfg for cell configuration. + * - If validated successfully, send configuration request to CFG. + * Call rgSCHCfgRgrCellCfg else FAIL. + * + * @param[in] RgSchCb *instCb + * @param[in] SpId spId + * @param[in] RgrCfg *cfg + * @param[out] RgSchErrInfo *errInfo + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PRIVATE S16 rgSCHGomHndlCfgReq +( +RgSchCb *instCb, +SpId spId, +RgrCfg *cfg, +RgSchErrInfo *errInfo +) +#else +PRIVATE S16 rgSCHGomHndlCfgReq(instCb, spId, cfg, errInfo) +RgSchCb *instCb; +SpId spId; +RgrCfg *cfg; +RgSchErrInfo *errInfo; +#endif +{ + S16 ret; + RgSchCellCb *cell = instCb->rgrSap[spId].cell; + Inst inst = (instCb->rgSchInit.inst ); + RgSchUeCb *ue; + + TRC2(rgSCHGomHndlCfgReq); + + errInfo->errType = RGSCHERR_GOM_CFG_REQ; + + /* Validate and process the configuration request */ + switch (cfg->cfgType) + { + case RGR_CELL_CFG: + { + ret = rgSCHCfgVldtRgrCellCfg(inst, &cfg->u.cellCfg, cell, errInfo); + if (ret != ROK) + { + RLOG1(L_ERROR,"Rgr Cell configuration " + "validation FAILED: Cell %d", cfg->u.cellCfg.cellId); + RETVALUE(RFAILED); + } + ret = rgSCHCfgRgrCellCfg(instCb, spId, &cfg->u.cellCfg, errInfo); + break; + } + case RGR_UE_CFG: + case RGR_SCELL_UE_CFG: + { + ret = rgSCHCfgVldtRgrUeCfg(inst, &cfg->u.ueCfg, &cell, errInfo); + if (ret != ROK) + { + RLOG1(L_ERROR,"Ue configuration validation" + " FAILED: CRNTI:%d", cfg->u.ueCfg.crnti); + RETVALUE(RFAILED); + } + ret = rgSCHCfgRgrUeCfg(cell, &cfg->u.ueCfg, errInfo); + break; + } + case RGR_LCH_CFG: + { + ret = rgSCHCfgVldtRgrLcCfg(inst, &cfg->u.lchCfg, &cell, &ue, errInfo); + if (ret != ROK) + { + RLOG1(L_ERROR,"LC configuration validation " + "FAILED: LCID:%d", cfg->u.lchCfg.lcId); + RETVALUE(RFAILED); + } + ret = rgSCHCfgRgrLchCfg(cell, ue, &cfg->u.lchCfg, errInfo); + break; + } + case RGR_LCG_CFG: + { + ret = rgSCHCfgVldtRgrLcgCfg(inst, &cfg->u.lcgCfg, &cell, &ue, errInfo); + if (ret != ROK) + { + RLOG1(L_ERROR,"LCG configuration validation " + "FAILED: LCGID:%d", cfg->u.lcgCfg.ulInfo.lcgId); + RETVALUE(RFAILED); + } + ret = rgSCHCfgRgrLcgCfg(cell, ue, &cfg->u.lcgCfg, errInfo); + break; + } + case RGR_ENB_CFG: + { + ret = rgSCHCfgVldtRgrSchedEnbCfg(inst, &cfg->u.schedEnbCfg, errInfo); + if (ret != ROK) + { + RGSCHDBGERR(inst,(rgSchPBuf(inst), "SCH ENB configuration validation " + "FAILED: \n" )); + RETVALUE(RFAILED); + } + ret = rgSCHCfgRgrSchedEnbCfg(inst, spId, &cfg->u.schedEnbCfg, errInfo); + break; + } + default: + { +#if(ERRCLASS & ERRCLS_INT_PAR) + RLOG1(L_ERROR,"Should never come here: " + "cfgType %d", cfg->cfgType); +#endif + RETVALUE(RFAILED); + } + } + + RETVALUE(ret); +} /* rgSCHGomHndlCfgReq */ + +#ifdef LTE_ADV +/** + * @brief Handler to handle re-configuration request from RRM to MAC. + * + * @details + * + * Function: rgSCHGomHndlSCellActDeactReq + * + * This API handles processing for SCell Activation Request from RRM to SCH. + * + * - Processing Steps: + * - Validate sCell Actication request parameters at CFG module. + * - If validated successfully, send configuration request to CFG. + * - call activation function for each SCells configured + * + * @param[in] RgSchCb *instCb + * @param[in] SpId spId + * @param[in] RgrSCellActDeactEvnt *sCellActDeactEvnt + * @param[in] U8 action + * @param[out] RgSchErrInfo *errInfo + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PRIVATE S16 rgSCHGomHndlSCellActDeactReq +( +RgSchCb *instCb, +SpId spId, +RgrSCellActDeactEvnt *sCellActDeactEvnt, +RgSchErrInfo *errInfo, +U8 action +) +#else +PRIVATE S16 rgSCHGomHndlSCellActDeactReq(instCb, spId, sCellActDeactEvnt, errInfo, action) +RgSchCb *instCb; +SpId spId; +RgrSCellActDeactEvnt *sCellActDeactEvnt; +RgSchErrInfo *errInfo; +U8 action; +#endif +{ + RgSchUeCb *ue = NULLP; + U16 idx = 0; + U16 sCellIdx = 0; + RgSchCellCb *cell = instCb->rgrSap[spId].cell; + Inst inst = (instCb->rgSchInit.inst); + + TRC2(rgSCHGomHndlSCellActDeactReq); + RGSCHDBGPRM(inst,(rgSchPBuf(inst), "Processing RGR SCell Actication request:" + "%d\n", sCellActDeactEvnt->crnti)); + + errInfo->errType = RGSCHERR_GOM_SCELL_REQ; + + /* Fetch the Ue */ + if ((ue = rgSCHDbmGetUeCb(cell, sCellActDeactEvnt->crnti)) == NULLP) + { + RGSCHDBGERRNEW(inst, (rgSchPBuf(inst), "[%d]UE: does not exist\n", + sCellActDeactEvnt->crnti)); + RETVALUE(RFAILED); + } + + for(idx = 0; idx < sCellActDeactEvnt->numOfSCells; idx++) + { + sCellIdx = sCellActDeactEvnt->sCellActDeactInfo[idx].sCellIdx; + + if (ROK != (rgSCHSCellTrigActDeact(cell, ue, sCellIdx, action))) + { + RGSCHDBGERR(inst,(rgSchPBuf(inst), "SCell Actication failed" + "for UE [%d] with SCellIdx [%d]\n", + sCellActDeactEvnt->crnti, idx)); + RETVALUE(RFAILED); + + } + + } + RGSCHDBGINFO(inst,(rgSchPBuf(inst), "RGR Reconfiguration processed\n")); + RETVALUE(ROK); +} /* rgSCHGomHndlSCellActDeactReq */ + +#endif /* LTE_ADV */ +/** + * @brief Handler to handle re-configuration request from RRM to MAC. + * + * @details + * + * Function: rgSCHGomHndlRecfgReq + * + * This API handles processing for re-configuration request from RRM to MAC. + * + * - Processing Steps: + * - Validate re-configuration request parameters at CFG module. + * Call rgSCHCfgVldtRgrCellRecfg for cell re-configuration. + * - If validated successfully, send configuration request to CFG. + * Call rgSCHCfgRgrCellRecfg else FAIL. + * + * @param[in] RgSchCb *instCb + * @param[in] SpId spId + * @param[in] RgrRecfg *recfg + * @param[out] RgSchErrInfo *errInfo + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PRIVATE S16 rgSCHGomHndlRecfgReq +( +RgSchCb *instCb, +SpId spId, +RgrRecfg *recfg, +RgSchErrInfo *errInfo +) +#else +PRIVATE S16 rgSCHGomHndlRecfgReq(instCb, spId, recfg, errInfo) +RgSchCb *instCb; +SpId spId; +RgrRecfg *recfg; +RgSchErrInfo *errInfo; +#endif +{ + RgSchUeCb *ue = NULLP; + RgSchDlLcCb *dlLc = NULLP; /* PURIFY_FIX:UMR */ + S16 ret; + RgSchCellCb *cell = instCb->rgrSap[spId].cell; + Inst inst = (instCb->rgSchInit.inst ); + + TRC2(rgSCHGomHndlRecfgReq); + + errInfo->errType = RGSCHERR_GOM_RECFG_REQ; + + /* Validate and process the re-configuration request */ + switch (recfg->recfgType) + { + case RGR_CELL_CFG: + { + ret = rgSCHCfgVldtRgrCellRecfg(inst, &recfg->u.cellRecfg, &cell, + errInfo); + if (ret != ROK) + { + RLOG_ARG0(L_ERROR,DBG_CELLID,recfg->u.cellRecfg.cellId,"Rgr Cell Recfg Validation " + "FAILED"); + RETVALUE(RFAILED); + } + ret = rgSCHCfgRgrCellRecfg(cell, &recfg->u.cellRecfg, errInfo); + break; + } + case RGR_UE_CFG: + case RGR_SCELL_UE_CFG: + { + ret = rgSCHCfgVldtRgrUeRecfg(inst, &recfg->u.ueRecfg, &cell, &ue, errInfo); + if ( ret != ROK) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,recfg->u.ueRecfg.cellId,"Ue Recfg Validation FAILED" + "OLD CRNTI:%d",recfg->u.ueRecfg.oldCrnti); + RETVALUE(RFAILED); + } + ret = rgSCHCfgRgrUeRecfg(cell, ue, &recfg->u.ueRecfg, errInfo); + break; + } + case RGR_LCH_CFG: + { + ret = rgSCHCfgVldtRgrLchRecfg(inst, &recfg->u.lchRecfg, &cell, &ue, + &dlLc, errInfo); + if (ret != ROK) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,recfg->u.lchRecfg.cellId,"Lc Recfg Validation FAILED" + "LCID:%d",recfg->u.lchRecfg.lcId); + RETVALUE(RFAILED); + } + ret = rgSCHCfgRgrLchRecfg(cell, ue, dlLc, &recfg->u.lchRecfg, errInfo); + break; + } + case RGR_LCG_CFG: + { + ret = rgSCHCfgVldtRgrLcgRecfg(inst, &recfg->u.lcgRecfg, cell, &ue, + errInfo); + if (ret != ROK) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,recfg->u.lcgRecfg.cellId, "Lcg Recfg Validation FAILED" + "LCGID:%d",recfg->u.lcgRecfg.ulRecfg.lcgId); + RETVALUE(RFAILED); + } + ret = rgSCHCfgRgrLcgRecfg(cell, ue, &recfg->u.lcgRecfg, errInfo); + break; + } + default: + { +#if(ERRCLASS & ERRCLS_INT_PAR) + RLOG1(L_ERROR,"Should never come here: recfgType %d", recfg->recfgType); +#endif + RETVALUE(RFAILED); + } + } + + RETVALUE(ret); +} /* rgSCHGomHndlRecfgReq */ + +/** + * @brief Handler to handle UE reset request from RRM to Scheduler. + * + * @details + * + * Function: rgSCHGomHndlResetReq + * + * This API handles processing for UE reset request from RRM to Scheduler. + * + * - Processing Steps: + * - Validate UE reset request parameters at CFG module. + * Call rgSCHCfgVldtRgrUeReset for UE reset. + * - If validated successfully, send UE reset request to CFG. + * Call rgSCHCfgRgrUeReset else FAIL. + * + * @param[in] RgrRst *rstInfo + * @param[out] RgSchErrInfo *errInfo + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PRIVATE S16 rgSCHGomHndlResetReq +( +RgSchCb *instCb, +SpId spId, +RgrRst *reset, +RgSchErrInfo *errInfo +) +#else +PRIVATE S16 rgSCHGomHndlResetReq(instCb, spId, reset, errInfo) +RgSchCb *instCb; +SpId spId; +RgrRst *reset; +RgSchErrInfo *errInfo; +#endif +{ + S16 ret; + RgSchCellCb *cell= instCb->rgrSap[spId].cell; + Inst inst = (instCb->rgSchInit.inst ); + RgSchUeCb *ue = NULLP; + + TRC2(rgSCHGomHndlResetReq); + + + errInfo->errType = RGSCHERR_GOM_RESET_REQ; + + /* Validate and process the UE reset request */ + ret = rgSCHCfgVldtRgrUeReset(inst, reset, cell, &ue, errInfo); + if (ret != ROK) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,reset->cellId,"Rgr UE Reset Validation FAILED" + "CRNTI:%d",reset->crnti); + RETVALUE(RFAILED); + } + + ret = rgSCHCfgRgrUeReset(cell, ue, reset, errInfo); + if (ret != ROK) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,reset->cellId,"Rgr UE Reset FAILED" + "CRNTI:%d",reset->crnti); + RETVALUE(RFAILED); + } + + RETVALUE(ret); +} /* rgSCHGomHndlResetReq */ + + +/** + * @brief Handler for processing Cell/Ue/Logical channel delete request + * recieved from RRM. + * + * @details + * + * Function: rgSCHGomHndlDelReq + * + * This API handles processing of delete request from RRM to MAC. + * + * Processing Steps: + * - Fetch corresponding control block and pass it to CFG module. + * - If control block does not exist, FAIL. + * + * @param[in] RgSchCb *instCb + * @param[in] SpId spId + * @param[in] RgrDel *del + * @param[out] RgSchErrInfo *errInfo + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PRIVATE S16 rgSCHGomHndlDelReq +( +RgSchCb *instCb, +SpId spId, +RgrDel *del, +RgSchErrInfo *errInfo +) +#else +PRIVATE S16 rgSCHGomHndlDelReq(instCb, spId, del, errInfo) +RgSchCb *instCb; +SpId spId; +RgrDel *del; +RgSchErrInfo *errInfo; +#endif +{ + + S16 ret; +#ifdef DEBUGP + Inst inst = (instCb->rgSchInit.inst); +#endif + VOLATILE U32 startTime=0; + + TRC2(rgSCHGomHndlDelReq); + + errInfo->errType = RGSCHERR_GOM_DEL_REQ; + + if(instCb->rgrSap[spId].cell == NULLP) + { + RLOG_ARG0(L_ERROR,DBG_INSTID,inst,"Cell doesnt exist"); + RETVALUE(RFAILED); + } + + /* Process the delete request */ + switch (del->delType) + { + case RGR_CELL_CFG: + { + ret = rgSCHCfgRgrCellDel(instCb->rgrSap[spId].cell, del, errInfo); + if(ret == ROK) + { + /* TODO::Needs to be revisited after tti flow CaDev Start */ + U8 idx = (U8)((instCb->rgrSap[spId].cell->cellId - instCb->genCfg.startCellId)&(CM_LTE_MAX_CELLS-1)); + instCb->cells[idx] = NULLP; + /* CaDev End */ + instCb->rgrSap[spId].cell = NULLP; + instCb->tfuSap[spId].cell = NULLP; + } + break; + } + case RGR_UE_CFG: + case RGR_SCELL_UE_CFG: + { + + /*starting Task*/ + SStartTask(&startTime, PID_SCH_UE_DEL); + + ret = rgSCHCfgRgrUeDel(instCb->rgrSap[spId].cell, del, errInfo); + + /*stoping Task*/ + SStopTask(startTime, PID_SCH_UE_DEL); + + break; + } + case RGR_LCH_CFG: + { + ret = rgSCHCfgRgrLcDel(instCb->rgrSap[spId].cell, del, errInfo); + break; + } + case RGR_LCG_CFG: + { + ret = rgSCHCfgRgrLcgDel(instCb->rgrSap[spId].cell, del, errInfo); + break; + } + default: + { +#if(ERRCLASS & ERRCLS_INT_PAR) + RLOG1(L_ERROR,"Should never come here: delType %d", del->delType); +#endif + RETVALUE(RFAILED); + } + } + + RETVALUE(ret); +} /* rgSCHGomHndlDelReq */ + + + + +/*********************************************************** + * + * Func : rgSCHGomGetCellIdFrmCfgReq + * + * + * Desc : + * - Processing Steps: + * - Retrieves the cell Id for a config request. + * + * @param[in] RgrCfgReqInfo *rgrCfgReq + * @param[out] CmLteCellId *cellId + * Ret : ROK on fetching cellId + * RFAILED on failure + * + * Notes: + * + * File : rg_sch_gom.c + * + **********************************************************/ +#ifdef ANSI +PRIVATE S16 rgSCHGomGetCellIdFrmCfgReq +( +RgrCfgReqInfo *rgrCfgReq, +CmLteCellId *cellId +) +#else +PRIVATE S16 rgSCHGomGetCellIdFrmCfgReq(rgrCfgReq, cellId) +RgrCfgReqInfo *rgrCfgReq; +CmLteCellId *cellId; +#endif +{ + + TRC2(rgSCHGomGetCellIdFrmCfgReq); + + + /* Extract CellId depending on the action and Config Type in the Request + * As of now this function is called for only re configuration so removed + * othe CASES below if needed we can add them*/ + switch (rgrCfgReq->action) + { + case RGR_RECONFIG: + { + if (rgrCfgReq->u.recfgInfo.recfgType ==RGR_CELL_CFG) + { + *cellId = rgrCfgReq->u.recfgInfo.u.cellRecfg.cellId; + } + else if ((rgrCfgReq->u.recfgInfo.recfgType == RGR_SCELL_UE_CFG) || + (rgrCfgReq->u.recfgInfo.recfgType == RGR_UE_CFG)) + { + *cellId = rgrCfgReq->u.recfgInfo.u.ueRecfg.cellId; + } + else if (rgrCfgReq->u.recfgInfo.recfgType == RGR_LCH_CFG) + { + *cellId = rgrCfgReq->u.recfgInfo.u.lchRecfg.cellId; + } + else if (rgrCfgReq->u.recfgInfo.recfgType == RGR_LCG_CFG) + { + *cellId = rgrCfgReq->u.recfgInfo.u.lcgRecfg.cellId; + } + else + { + RETVALUE(RFAILED); + } + break; + } + default: + { + RETVALUE(RFAILED); + } + } /* End of Switch */ + + RETVALUE(ROK); +} /* rgSCHGomGetCellIdFrmCfgReq */ + +#ifdef RGR_SI_SCH +/** + * @brief Handler to handle SI configuration request from RRM to MAC. + * + * @details + * + * Function: rgSCHGomHndlSiCfg + * + * This API handles processing for SI configuration request from RRM to MAC. + * + * - Processing Steps: + * - Validate SI configuration request parameters at CFG module. + * Call rgSCHCfgVldtSiCfg for SI configuration. + * - If validated successfully, send configuration request to CFG. + * Call rgSCHCfgRgrCellCfg else FAIL. + * + * @param[in] Region reg + * @param[in] Pool pool + * @param[in] RgSchCb *instCb + * @param[in] SpId spId + * @param[in] RgrCfgTransId transId + * @param[in] RgrSiCfgReqInfo *cfgReqInfo + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 rgSCHGomHndlSiCfg +( +Region reg, +Pool pool, +RgSchCb *instCb, +SpId spId, +RgrCfgTransId transId, +RgrSiCfgReqInfo *cfgReqInfo +) +#else +PUBLIC S16 rgSCHGomHndlSiCfg(reg, pool, instCb, spId, transId, cfgReqInfo) +Region reg; +Pool pool; +RgSchCb *instCb; +SpId spId; +RgrCfgTransId transId; +RgrSiCfgReqInfo *cfgReqInfo; +#endif +{ + S16 ret; + RgSchCellCb *cell = instCb->rgrSap[spId].cell; + Inst inst = (instCb->rgSchInit.inst ); + RgSchErrInfo errInfo; + U8 cfmStatus = RGR_CFG_CFM_NOK; + MsgLen msgLen = 0, pduLen; + S32 tbSz = 0; + U8 nPrb = 0; + U8 mcs = 0; + + TRC2(rgSCHGomHndlSiCfg); + + + /* check if cell does not exists */ + if (((U8 *)cell == NULLP) || (cell->cellId != cfgReqInfo->cellId)) + { + RLOG_ARG0(L_ERROR,DBG_CELLID,cfgReqInfo->cellId,"Cell Control block does not exist" + ); + RGSCH_FREE_MSG(cfgReqInfo->pdu); + SPutSBuf(reg, pool, (Data *)cfgReqInfo, (Size)sizeof(*cfgReqInfo)); + cfgReqInfo = NULLP; + rgSCHUtlRgrSiCfgCfm(instCb->rgSchInit.inst, spId, transId, cfmStatus); + RETVALUE(RFAILED); + } + + /*Validate the received SI configuration */ + ret = rgSCHCfgVldtRgrSiCfg(inst, cfgReqInfo, cell, &errInfo); + if (ret != ROK) + { + RLOG_ARG0(L_ERROR,DBG_CELLID,cfgReqInfo->cellId,"Rgr SI configuration " + "validation FAILED"); + RGSCH_FREE_MSG(cfgReqInfo->pdu); + SPutSBuf(reg, pool, (Data *)cfgReqInfo, (Size)sizeof(*cfgReqInfo)); + cfgReqInfo = NULLP; + rgSCHUtlRgrSiCfgCfm(instCb->rgSchInit.inst, spId, transId, cfmStatus); + RETVALUE(RFAILED); + } + /*ccpu00140789: Stopping SI scheduling*/ + if(RGR_SI_STOP == cfgReqInfo->cfgType) + { + if((cell->siCb.crntSiInfo.siInfo[cfgReqInfo->siId-1].si != NULLP)&& + (cell->siCb.siArray[cfgReqInfo->siId-1].si != NULLP)) + { + cell->siCb.crntSiInfo.siInfo[cfgReqInfo->siId-1].si = NULLP; + RGSCH_FREE_MSG(cell->siCb.siArray[cfgReqInfo->siId-1].si); + cell->siCb.siArray[cfgReqInfo->siId-1].si = NULLP; + if(cell->siCb.newSiInfo.siInfo[cfgReqInfo->siId-1].si != NULLP) + { + RGSCH_FREE_MSG(cell->siCb.newSiInfo.siInfo[cfgReqInfo->siId-1].si); + cell->siCb.newSiInfo.siInfo[cfgReqInfo->siId-1].si = NULLP; + } + SPutSBuf(reg, pool, (Data *)cfgReqInfo, (Size)sizeof(*cfgReqInfo)); + cfgReqInfo = NULLP; + cfmStatus = RGR_CFG_CFM_OK; + rgSCHUtlRgrSiCfgCfm(instCb->rgSchInit.inst, spId, transId, cfmStatus); + RETVALUE(ROK); + } + else + { + SPutSBuf(reg, pool, (Data *)cfgReqInfo, (Size)sizeof(*cfgReqInfo)); + cfgReqInfo = NULLP; + rgSCHUtlRgrSiCfgCfm(instCb->rgSchInit.inst, spId, transId, cfmStatus); + RETVALUE(RFAILED); + } + } + + /* Check if the pdu sent from application + * matches a transport block size. if not, + * add padding bytes. This is usually done + * by RRC but since we are bypassing RRC, + * MAC is taking over that responsibility + */ + if ( RGR_SI_CFG_TYPE_MIB != cfgReqInfo->cfgType ) + { + SFndLenMsg(cfgReqInfo->pdu, &msgLen); + + /* check if the application pdu matches a tb size */ + tbSz = rgSCHUtlGetAllwdCchTbSz(msgLen*8, &nPrb, &mcs); + + if ( tbSz != (msgLen*8) ) + { + MsgLen nmPadBytes = 0; + Data* padding = NULLP; + + /* need to add padding bytes */ + nmPadBytes = (tbSz - (msgLen*8))/8; + + if ( SGetSBuf(reg,pool,&padding,nmPadBytes) != ROK) + { + RLOG_ARG0(L_ERROR,DBG_CELLID,cfgReqInfo->cellId,"Rgr SI configuration " + "SGetSBuf failed for padding failed"); + SPutSBuf(reg, pool, (Data *)cfgReqInfo, (Size)sizeof(*cfgReqInfo)); + cfgReqInfo = NULLP; + rgSCHUtlRgrSiCfgCfm(instCb->rgSchInit.inst, spId, transId, + cfmStatus); + RETVALUE(RFAILED); + } + + cmMemset((U8*)padding,(U8)0,nmPadBytes); + +#ifdef MS_MBUF_CORRUPTION + MS_BUF_ADD_ALLOC_CALLER(); +#endif + if ( SAddPstMsgMult((Data*)padding,nmPadBytes,cfgReqInfo->pdu) != ROK) + { + RLOG_ARG0(L_ERROR,DBG_CELLID,cfgReqInfo->cellId,"Rgr SI configuration " + "Failed to add padding bytes"); + SPutSBuf(reg, pool, (Data *)cfgReqInfo, (Size)sizeof(*cfgReqInfo)); + cfgReqInfo = NULLP; + SPutSBuf(reg, pool, (Data* )padding,(Size)nmPadBytes); + padding = NULLP; + rgSCHUtlRgrSiCfgCfm(instCb->rgSchInit.inst, spId, transId, + cfmStatus); + RETVALUE(RFAILED); + } + SPutSBuf(reg, pool, (Data* )padding,(Size)nmPadBytes); + padding = NULLP; + }/* if (tbSz != ...*/ + }/* if (RGR_SI_CFG_TYPE_SI...*/ + + /*Set the received pdu at the appropriate place */ + switch(cfgReqInfo->cfgType) + { + case RGR_SI_CFG_TYPE_MIB: /* SI CFG Type MIB */ + RGSCHCHKNUPDSIPDU(cell->siCb.crntSiInfo.mib, + cell->siCb.newSiInfo.mib, + cfgReqInfo->pdu, cell->siCb.siBitMask, + RGSCH_SI_MIB_UPD); + break; + + case RGR_SI_CFG_TYPE_SIB1_PWS: + { + SFndLenMsg(cfgReqInfo->pdu, &pduLen); + ret = rgSCHUtlCalMcsAndNPrb(cell, cfgReqInfo->cfgType, pduLen,0); + if (ret != ROK) + { + RLOG_ARG0(L_ERROR,DBG_CELLID,cfgReqInfo->cellId,"Failed to get MCS and NPRB" + "value"); + RGSCH_FREE_MSG(cfgReqInfo->pdu); + SPutSBuf(reg, pool, (Data *)cfgReqInfo, (Size)sizeof(*cfgReqInfo)); + cfgReqInfo = NULLP; + rgSCHUtlRgrSiCfgCfm(instCb->rgSchInit.inst, spId, transId, + cfmStatus); + RETVALUE(RFAILED); + } + + RGSCHCHKNUPDSIPDU(cell->siCb.crntSiInfo.sib1Info.sib1, + cell->siCb.newSiInfo.sib1Info.sib1, + cfgReqInfo->pdu, cell->siCb.siBitMask, + RGSCH_SI_SIB1_PWS_UPD); + } + break; + + case RGR_SI_CFG_TYPE_SIB1: + SFndLenMsg(cfgReqInfo->pdu, &pduLen); + ret = rgSCHUtlCalMcsAndNPrb(cell, cfgReqInfo->cfgType, pduLen,0); + if (ret != ROK) + { + RLOG_ARG0(L_ERROR,DBG_CELLID,cfgReqInfo->cellId,"Failed to get MCS and NPRB" + "value"); + RGSCH_FREE_MSG(cfgReqInfo->pdu); + SPutSBuf(reg, pool, (Data *)cfgReqInfo, (Size)sizeof(*cfgReqInfo)); + cfgReqInfo = NULLP; + rgSCHUtlRgrSiCfgCfm(instCb->rgSchInit.inst, spId, transId, + cfmStatus); + RETVALUE(RFAILED); + } + RGSCHCHKNUPDSIPDU(cell->siCb.crntSiInfo.sib1Info.sib1, + cell->siCb.newSiInfo.sib1Info.sib1, + cfgReqInfo->pdu, cell->siCb.siBitMask, + RGSCH_SI_SIB1_UPD); + break; + + case RGR_SI_CFG_TYPE_SI: /* SI CFG TYPE SI */ + SFndLenMsg(cfgReqInfo->pdu, &pduLen); + ret = rgSCHUtlCalMcsAndNPrb(cell, cfgReqInfo->cfgType, pduLen, + cfgReqInfo->siId); + if (ret != ROK) + { + RLOG_ARG0(L_ERROR,DBG_CELLID,cfgReqInfo->cellId,"Failed to get MCS and NPRB" + "value"); + RGSCH_FREE_MSG(cfgReqInfo->pdu); + SPutSBuf(reg, pool, (Data *)cfgReqInfo, (Size)sizeof(*cfgReqInfo)); + cfgReqInfo = NULLP; + rgSCHUtlRgrSiCfgCfm(instCb->rgSchInit.inst, spId, transId, + cfmStatus); + RETVALUE(RFAILED); + } + /* Si recfg, where numSi changes */ + if (cell->siCb.siBitMask & RGSCH_SI_SICFG_UPD) + { + Buffer **newSiPdu = &cell->siCb.newSiInfo.siInfo[cfgReqInfo->siId-1].si; + if(*newSiPdu != NULLP) + { + RGSCH_FREE_MSG(*newSiPdu); + } + *newSiPdu = (Buffer *)cfgReqInfo->pdu; + cell->siCb.siBitMask |= RGSCH_SI_SI_UPD; + } + else /* Initial Si cfg or si recfg where numSi did not change */ + { + U8 bitMask; + /* Initial Si cfg */ + if (cell->siCb.crntSiInfo.siInfo[cfgReqInfo->siId-1].si == NULLP) + { + cell->siCb.siArray[cfgReqInfo->siId-1].si = cfgReqInfo->pdu; + cell->siCb.siArray[cfgReqInfo->siId-1].isWarningSi = FALSE; + bitMask = RGSCH_SI_DFLT; + } + else + { + bitMask = RGSCH_SI_SI_UPD; + } + + RGSCHCHKNUPDSIPDU(cell->siCb.crntSiInfo.siInfo[cfgReqInfo->siId-1].si, + cell->siCb.newSiInfo.siInfo[cfgReqInfo->siId-1].si, + cfgReqInfo->pdu, + cell->siCb.siBitMask, bitMask); + } + break; + + case RGR_SI_CFG_TYPE_SIB8_CDMA: /* SI CFG TYPE SIB 8 CDMA */ + SFndLenMsg(cfgReqInfo->pdu, &pduLen); + ret = rgSCHUtlCalMcsAndNPrb(cell, cfgReqInfo->cfgType, pduLen, + cfgReqInfo->siId); + if (ret != ROK) + { + RLOG_ARG0(L_ERROR,DBG_CELLID,cfgReqInfo->cellId,"Failed to get MCS and NPRB" + "value"); + RGSCH_FREE_MSG(cfgReqInfo->pdu); + SPutSBuf(reg, pool, (Data *)cfgReqInfo, (Size)sizeof(*cfgReqInfo)); + cfgReqInfo = NULLP; + rgSCHUtlRgrSiCfgCfm(instCb->rgSchInit.inst, spId, transId, + cfmStatus); + RETVALUE(RFAILED); + } + /* No need to wait for Modification period boundary */ + cell->siCb.siArray[cfgReqInfo->siId-1].si = cfgReqInfo->pdu; + RGSCH_SET_SI_INFO(cell->siCb.crntSiInfo.siInfo[cfgReqInfo->siId-1].si, + cfgReqInfo->pdu); + cell->siCb.siArray[cfgReqInfo->siId-1].isWarningSi = FALSE; + break; + default: + RLOG_ARG0(L_ERROR,DBG_CELLID,cfgReqInfo->cellId,"Invalid cfgType " + "parameter value"); + RGSCH_FREE_MSG(cfgReqInfo->pdu); + SPutSBuf(reg, pool, (Data *)cfgReqInfo, + (Size)sizeof(*cfgReqInfo)); + cfgReqInfo = NULLP; + rgSCHUtlRgrSiCfgCfm(instCb->rgSchInit.inst, spId, transId, + cfmStatus); + RETVALUE(RFAILED); + } + + SPutSBuf(reg, pool, (Data *)cfgReqInfo, (Size)sizeof(*cfgReqInfo)); + cfgReqInfo = NULLP; + cfmStatus = RGR_CFG_CFM_OK; + rgSCHUtlRgrSiCfgCfm(instCb->rgSchInit.inst, spId, transId, cfmStatus); + + + RETVALUE(ROK); +} /* rgSCHGomHndlSiCfg */ + + +/** + * @brief Handler to handle Warning SI configuration request from RRM to MAC. + * + * @details + * + * Function: rgSCHGomHndlWarningSiCfg + * + * This API handles processing for Warning SI configuration request from + * RRM to MAC. + * + * + * @param[in] Region reg + * @param[in] Pool pool + * @param[in] RgSchCb *instCb + * @param[in] SpId spId + * @param[in] RgrWarningSiCfgReqInfo *warningSiCfgReqInfo + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 rgSCHGomHndlWarningSiCfg +( +Region reg, +Pool pool, +RgSchCb *instCb, +SpId spId, +RgrCfgTransId transId, +RgrWarningSiCfgReqInfo *warningSiCfgReqInfo +) +#else +PUBLIC S16 rgSCHGomHndlWarningSiCfg(reg, pool, instCb, spId, transId, +warningSiCfgReqInfo) +Region reg; +Pool pool; +RgSchCb *instCb; +SpId spId; +RgrCfgTransId transId; +RgrWarningSiCfgReqInfo *warningSiCfgReqInfo; +#endif +{ + RgSchCellCb *cell = instCb->rgrSap[spId].cell; + U8 cfmStatus = RGR_CFG_CFM_NOK; + U16 idx; + U8 siId = warningSiCfgReqInfo->siId; + U8 j, mcs=0, nPrb=0; + RgSchWarningSiSeg *warningSiMsg; + RgSchWarningSiPdu *pduNode; + CmLList *node; + MsgLen msgLen = 0; + Bool freeNodeFound = FALSE; + U16 siWinSize = 0; + U16 minPeriod = 0; +#ifdef EMTC_ENABLE + U8 isEmtc = warningSiCfgReqInfo->emtcEnable; +#endif + + TRC2(rgSCHGomHndlWarningSiCfg); + +#ifdef EMTC_ENABLE + if(TRUE == isEmtc) + { + rgSchEmtcGetSiWinPerd(cell, &siWinSize, &minPeriod); + } + else +#endif + { + siWinSize = cell->siCfg.siWinSize; + minPeriod = cell->siCfg.minPeriodicity; + } + /* check if cell does not exists */ + if (((U8 *)cell == NULLP) || + (cell->cellId != warningSiCfgReqInfo->cellId) || + (warningSiCfgReqInfo->siId > + ((minPeriod * 10)/siWinSize))) + { + RLOG_ARG2(L_ERROR,DBG_CELLID,warningSiCfgReqInfo->cellId,"Warning SI Cfg Failed for siId = %d" + "warning cellID:%d",warningSiCfgReqInfo->siId,warningSiCfgReqInfo->cellId); + rgSCHUtlFreeWarningSiSeg(reg, pool, &warningSiCfgReqInfo->siPduLst); + SPutSBuf(reg, pool, (Data *)warningSiCfgReqInfo, + sizeof(RgrWarningSiCfgReqInfo)); + warningSiCfgReqInfo = NULLP; + rgSCHUtlRgrWarningSiCfgCfm(instCb->rgSchInit.inst, spId, siId, transId, + cfmStatus); + RETVALUE(RFAILED); + } + + /* Search for free index in WarningSi */ + for(idx = 0; idx < RGR_MAX_NUM_WARNING_SI; idx++) + { + if((cell->siCb.warningSi[idx].siId == 0 || + cell->siCb.warningSi[idx].siId == warningSiCfgReqInfo->siId)) + { + warningSiMsg = (RgSchWarningSiSeg *)&cell->siCb.warningSi[idx].warningSiMsg; + + /* Search for free SI node */ + /* ccpu00136659: CMAS ETWS design changes */ + if (warningSiMsg->segLstCp.first == NULLP) /* Free SI Node */ + { + warningSiMsg->transId = transId; + pduNode = (RgSchWarningSiPdu *)&cell->siCb.warningSi[idx]. + warningSiMsg.pduNode; + CM_LLIST_FIRST_NODE(&warningSiCfgReqInfo->siPduLst, node); + j = 0; + + /* Get the PDUs one by one from the received pduLst of warning + * message and calculate the MCS and nPrb of each pdu once. + * Store the pdu in warningSiMsg pduLst, which will be scheduled + * later while sending warning message as part of SIB11/SIB12 + */ + while((node != NULLP) && (j < RGR_MAX_WARNING_SI_SEG)) + + { + pduNode[j].pdu = (Buffer *)node->node; + if(pduNode[j].pdu != NULLP) + { + SFndLenMsg(pduNode[j].pdu, &msgLen); + /*Get the nPrb and mcs parametr values */ +#ifdef EMTC_ENABLE + if (rgSCHEmtcUtlGetAllwdCchTbSzForSI(msgLen*8) != (msgLen*8)) +#else + if (rgSCHUtlGetAllwdCchTbSz(msgLen*8, &nPrb, &mcs) != (msgLen*8)) +#endif + + { + RGSCHLOGERROR(cell->instIdx,ERRCLS_INT_PAR,ERG011, + (ErrVal)msgLen, + "rgSCHGomHndlWarningSiCfg():msgLen does not match\ + any valid TB Size."); + RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,"Warning SI Cfg Failed" + "for siId = %d", warningSiCfgReqInfo->siId); + rgSCHUtlFreeWarningSiSeg(reg, pool, + &warningSiCfgReqInfo->siPduLst); + SPutSBuf(reg, pool, (Data *)warningSiCfgReqInfo, + sizeof(RgrWarningSiCfgReqInfo)); + warningSiCfgReqInfo = NULLP; + rgSCHUtlRgrWarningSiCfgCfm(instCb->rgSchInit.inst, spId, + siId, transId,cfmStatus); + RETVALUE(RFAILED); + + } + } + pduNode[j].mcs = mcs; + pduNode[j].nPrb = nPrb; + pduNode[j].msgLen = msgLen; + /* ccpu00136659: CMAS ETWS design changes */ + cmLListAdd2Tail(&warningSiMsg->segLstCp, &pduNode[j].lnk); + pduNode[j].lnk.node = (PTR)&pduNode[j]; + j++; + node = node->next; + } + + /* ccpu00132385- nodes in received SI config linked list should + * be freed after processing the config.*/ + while(warningSiCfgReqInfo->siPduLst.first != NULLP) + { + node = warningSiCfgReqInfo->siPduLst.first; + cmLListDelFrm(&(warningSiCfgReqInfo->siPduLst), node); + SPutSBuf(reg, pool, (Data *)node,sizeof(CmLList)); + node = NULLP; + } + + cell->siCb.warningSi[idx].siId = warningSiCfgReqInfo->siId; + cell->siCb.warningSi[idx].idx = idx; +#ifdef EMTC_ENABLE + if(TRUE == isEmtc) + { + rgSCHEmtcWarningSiCfg(cell,warningSiCfgReqInfo,idx); + } + else +#endif + { + cell->siCb.siArray[warningSiCfgReqInfo->siId-1].si = + &cell->siCb.warningSi[idx]; + cell->siCb.siArray[warningSiCfgReqInfo->siId-1].isWarningSi = + TRUE; + } + freeNodeFound = TRUE; + break; + } + } + } + + if (freeNodeFound == FALSE) + { + RLOG_ARG0(L_DEBUG,DBG_CELLID,cell->cellId,"No SI Index is free"); + rgSCHUtlFreeWarningSiSeg(reg, pool, &warningSiCfgReqInfo->siPduLst); + SPutSBuf(reg, pool, (Data *)warningSiCfgReqInfo, + sizeof(RgrWarningSiCfgReqInfo)); + warningSiCfgReqInfo = NULLP; + rgSCHUtlRgrWarningSiCfgCfm(instCb->rgSchInit.inst, spId, siId, transId, + cfmStatus); + RETVALUE(RFAILED); + } + + SPutSBuf(reg, pool, (Data *)warningSiCfgReqInfo, + sizeof(RgrWarningSiCfgReqInfo)); + warningSiCfgReqInfo = NULLP; + RETVALUE(ROK); +} + + +/** + * @brief Handler to handle SI Stop request from RRM to MAC. + * + * @details + * + * Function: rgSCHGomHndlWarningSiStopReq + * + * This API handles processing for SI stop request from RRM to MAC. + * + * @param[in] Region reg + * @param[in] Pool pool + * @param[in] RgSchCb *instCb + * @param[in] SpId siId + * @return void + **/ +#ifdef ANSI +PUBLIC Void rgSCHGomHndlWarningSiStopReq +( +Region reg, +Pool pool, +RgSchCb *instCb, +U8 siId, +RgrCfgTransId transId, +SpId spId +) +#else +PUBLIC Void rgSCHGomHndlWarningSiStopReq(reg, pool, instCb, siId, transId, spId) +Region reg; +Pool pool; +RgSchCb *instCb; +U8 siId; +RgrCfgTransId transId; +SpId spId; +#endif +{ + RgSchCellCb *cell = instCb->rgrSap[spId].cell; + U16 idx; + CmLList *node; + RgSchWarningSiPdu *warningSiPdu; + Buffer *pdu; + + TRC3(rgSCHGomHndlWarningSiStopReq) + + for(idx = 0; idx < RGR_MAX_NUM_WARNING_SI; idx++) + { + if(cell->siCb.warningSi[idx].siId == siId) + { + if ((cmMemcmp ((U8 *)&cell->siCb.warningSi[idx].warningSiMsg.transId, + (U8 *)&transId, sizeof(RgrCfgTransId))) == 0) + { + /* ccpu00136659: CMAS ETWS design changes */ + CM_LLIST_FIRST_NODE(&cell->siCb.warningSi[idx].warningSiMsg.segLstCp, node); + while(node != NULLP) + { + /* On receiving the warning stop message, remove one by one + * each PDU from the warning SI list + */ + /* ccpu00136659: CMAS ETWS design changes */ + node = (CmLList *)&cell->siCb.warningSi[idx].warningSiMsg.segLstCp.first; + warningSiPdu = (RgSchWarningSiPdu *)node->node; + pdu = warningSiPdu->pdu; + cmLListDelFrm(&cell->siCb.warningSi[idx].warningSiMsg.segLstCp, node); + RGSCH_FREE_MSG(pdu); + node = node->next; + } + } + } + } + RETVOID; +} + +#endif/*RGR_SI_SCH */ + +/* LTE_ADV_FLAG_REMOVED_START */ + +/** + * @brief This function sets the Phigh range for CC users corresponding to the CC Pool + * @details + * + * Function: rgSchUpdtRNTPInfo + * + * Invoked by: rgSCHGomHndlLoadInf + * + * @param[in] RgSchCellCb* cell + * @param[in] RgSubFrm* subFrm + * @param[in] RgrLoadInfReqInfo *loadInfReq + * @return S16 + * + **/ +#ifdef ANSI +PUBLIC S16 rgSchUpdtRNTPInfo +( + RgSchCellCb *cell, + RgSchDlSf *sf, + RgrLoadInfReqInfo *loadInfReq + ) +#else +PRIVATE Void rgSchUpdtRNTPInfo(cell, sf) + RgSchCellCb *cell; + RgSchDlSf *sf; + RgrLoadInfReqInfo *loadInfReq; + +#endif +{ + /* Initialise the variables */ + RgSchSFRPoolInfo *sfrCCPool; + CmLListCp *l; + CmLList *n; + S16 ret = RFAILED; + + TRC2(rgSchUpdtRNTPInfo); + + l = &sf->sfrTotalPoolInfo.ccPool; + + /*Get the first node from the CC Pool*/ + n = cmLListFirst(l); + while(n) + { + sfrCCPool = (RgSchSFRPoolInfo*)n->node; + if (sfrCCPool->poolendRB == loadInfReq->rgrCcPHighEndRb) + { + sfrCCPool->pwrHiCCRange.endRb = loadInfReq->rgrCcPHighEndRb; + sfrCCPool->pwrHiCCRange.startRb = loadInfReq->rgrCcPHighStartRb; + RETVALUE(ROK); + } + else + { + n = cmLListNext(l); + } + } + RETVALUE(ret); +} +/** + * @brief Handler to handle LOAD INF request from RRM to MAC. + * + * @details + * + * Function: rgSCHGomHndlLoadInf + * + * This API handles processing for LOAD INF request from RRM to MAC. + * + * - Processing Steps: + * - Validate LOAD INF request parameters at CFG module. + * Call rgSCHCfgVldtRgrLoadInf for SI configuration. + * - If validated successfully, send configuration request. + * + * @param[in] Region reg + * @param[in] Pool pool + * @param[in] RgSchCb *instCb + * @param[in] SpId spId + * @param[in] RgrCfgTransId transId + * @param[in] RgrLoadInfReqInfo *loadInfReq + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 rgSCHGomHndlLoadInf +( + Region reg, + Pool pool, + RgSchCb *instCb, + SpId spId, + RgrCfgTransId transId, + RgrLoadInfReqInfo *loadInfReq + ) +#else +PUBLIC S16 rgSCHGomHndlLoadInf(reg, pool, instCb, spId, transId, loadInfReq) + Region reg; + Pool pool; + RgSchCb *instCb; + SpId spId; + RgrCfgTransId transId; + RgrLoadInfReqInfo *loadInfReq; +#endif +{ + S16 ret; + RgSchCellCb *cell = instCb->rgrSap[spId].cell; + Inst inst = (instCb->rgSchInit.inst ); + RgSchErrInfo errInfo; + U16 i; + + TRC2(rgSCHGomHndlLoadInf); + + + /* check if cell does not exists */ + if (((U8 *)cell == NULLP) || (cell->cellId != loadInfReq->cellId)) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,loadInfReq->cellId,"Cell Control block does not exist" + "for load cellId:%d",loadInfReq->cellId); + SPutSBuf(reg, pool, (Data *)loadInfReq, (Size)sizeof(*loadInfReq)); + RETVALUE(RFAILED); + } + + if (cell->lteAdvCb.dsfrCfg.status == RGR_DISABLE) + { + RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId, "rgSCHGomHndlLoadInf(): DSFR Feature not enabled"); + SPutSBuf(reg, pool, (Data *)loadInfReq, (Size)sizeof(*loadInfReq)); + RETVALUE(RFAILED); + } + /* Validate the received LOAD INF Configuration */ + ret = rgSCHCfgVldtRgrLoadInf(inst, loadInfReq, cell, &errInfo); + if (ret != ROK) + { + RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,"Rgr LOAD INF Configuration " + "validation FAILED"); + SPutSBuf(reg, pool, (Data *)loadInfReq, (Size)sizeof(*loadInfReq)); + RETVALUE(RFAILED); + } + /* Update the RNTP info rcvd in the respective cell centre pool so that Phigh can be + sent for the UEs scheduled in that particular RB range*/ + for(i = 0; i < RGSCH_NUM_DL_SUBFRAMES; i++) + { + if((rgSchUpdtRNTPInfo(cell, cell->subFrms[i], loadInfReq) != ROK)) + { + RETVALUE(RFAILED); + } + } + + SPutSBuf(reg, pool, (Data *)loadInfReq, (Size)sizeof(*loadInfReq)); + + + RETVALUE(ROK); +} /* rgSCHGomHndlLoadInf */ +/* LTE_ADV_FLAG_REMOVED_END */ + +/********************************************************************** + + End of file +**********************************************************************/ diff --git a/src/5gnrmac/rg_sch_hdfdd.c b/src/5gnrmac/rg_sch_hdfdd.c new file mode 100755 index 000000000..df02c21ab --- /dev/null +++ b/src/5gnrmac/rg_sch_hdfdd.c @@ -0,0 +1,1018 @@ +/******************************************************************************* +################################################################################ +# Copyright (c) [2017-2019] [Radisys] # +# # +# 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. # +################################################################################ +*******************************************************************************/ + +/************************************************************************ + + Name: LTE-MAC layer + + Type: C source file + + Desc: C source code for HD-FDD functions + + File: rg_sch_hdfdd.c + +**********************************************************************/ + +/** @file rg_sch_hdfdd.c +@brief This module handles the Periodic CQI/PMI/RI, SRS, SR and Half Duplex + functionality +*/ +#ifdef LTEMAC_HDFDD +static const char* RLOG_MODULE_NAME="MAC"; +static int RLOG_MODULE_ID=4096; +static int RLOG_FILE_ID=165; +#endif + +/* header include files -- defines (.h) */ +#include "envopt.h" /* environment options */ +#include "envdep.h" /* environment dependent */ +#include "envind.h" /* environment independent */ +#include "gen.h" /* general layer */ +#include "ssi.h" /* system service interface */ +#include "cm_hash.h" /* common hash list */ +#include "cm_llist.h" /* common linked list library */ +#include "cm_err.h" /* common error */ +#include "cm_lte.h" /* common LTE */ +#include "lrg.h" +#include "rgr.h" +#include "tfu.h" +#include "rg_env.h" +#include "rg_sch_inf.h" +#include "rg_sch_err.h" +#include "rgr.h" +#include "rgm.h" +#include "rg_sch.h" +#include "rg_sch_cmn.h" +#include "rl_interface.h" +#include "rl_common.h" + +/* header/extern include files (.x) */ +#include "gen.x" /* general layer typedefs */ +#include "ssi.x" /* system services typedefs */ +#include "cm5.x" /* common timers */ +#include "cm_hash.x" /* common hash list */ +#include "cm_lib.x" /* common library */ +#include "cm_llist.x" /* common linked list */ +#include "cm_mblk.x" /* memory management */ +#include "cm_tkns.x" /* common tokens */ +#include "cm_lte.x" /* common tokens */ +#include "tfu.x" /* RGU types */ +#include "lrg.x" /* layer management typedefs for MAC */ +#include "rgr.x" /* layer management typedefs for MAC */ +#include "rgm.x" /* layer management typedefs for MAC */ +#include "rg_sch_inf.x" /* typedefs for Scheduler */ +#include "rg_sch.x" /* typedefs for Scheduler */ +#include "rg_sch_cmn.x" + + +#ifdef LTEMAC_HDFDD +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + +/* @details + * + * Function : rgSCHHdFddUeCfg + * + * Invoking Module Processing: + * - This shall be invoked by SCH_GOM at UE Re/configuration. + * + * Processing Steps: + * - For UE-specific Half Duplex + * - Allocate the memory and place the UE in cellCb->hdUeLstCp + * - Update subframes information state to defualt + * - Update subframes information sfn to defualt + * - Return ROK + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ue + * @param[in] Bool *hdFddEnbl + * + * @RETVALUE S16 + * -# ROK + * -# RFAILED +*/ + +#ifdef ANSI +PUBLIC S16 rgSCHHdFddUeCfg +( +RgSchCellCb *cellCb, +RgSchUeCb *ueCb, +Bool hdFddEnbl +) +#else /* ANSI */ +PUBLIC S16 rgSCHHdFddUeCfg (cellCb, ueCb, hdFddEnbl) +RgSchCellCb *cellCb; +RgSchUeCb *ueCb; +Bool hdFddEnbl; +#endif /* ANSI */ +{ + U8 sfi; + TRC3(rgSCHHdFddUeCfg) + + RLOG_ARG2(L_DEBUG,DBG_CELLID,cellCb->cellId, + "rgSCHHdFddUeCfg(): UeId =%d hdFddEnbl=%d", + ueCb->ueId, hdFddEnbl); + if(ueCb->hdFddEnbld == TRUE) + { + if (hdFddEnbl == FALSE) + { + /* Do not allow switch from HD-FDD to FD-FDD configuration */ + RLOG_ARG1(L_ERROR,DBG_CELLID,cellCb->cellId, + "rgSCHHdFddUeCfg(): HD-FDD to FD-FDD Configuration is not allowed" + "CRNTI:%d",ueCb->ueId); + } + else + { + /* If already enabled then it can be second reconfiguration */ + RLOG_ARG1(L_ERROR,DBG_CELLID,cellCb->cellId, + "rgSCHHdFddUeCfg(): HD-FDD already enabled for this UE" + "CRNTI:%d",ueCb->ueId); + } + RETVALUE(RFAILED); + } + +#ifdef LTEMAC_SPS + /* Check is SPS enabled for this UE */ + if(hdFddEnbl == TRUE && + (ueCb->ul.ulSpsCfg.isUlSpsEnabled == TRUE || + ueCb->dl.dlSpsCfg.isDlSpsEnabled == TRUE)) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cellCb->cellId, + "rgSCHHdFddUeCfg(): Could'nt do HDFDD cfg, SPS already configured" + "CRNTI:%d",ueCb->ueId); + RETVALUE(RFAILED); + } +#endif + + ueCb->hdFddEnbld = hdFddEnbl; + if( hdFddEnbl == TRUE) + { + rgSCHUtlAllocSBuf(cellCb->instIdx,(Data **) &ueCb->hdFddCb, + sizeof(RgSchUeHdFddCb)); + if (ueCb->hdFddCb != NULLP) + { + for (sfi = 0; sfi < RG_SCH_HDFDD_NUMSFINFO; sfi++) + { + ueCb->hdFddCb->subfrm[sfi].subFrmDir = RG_SCH_HDFDD_NOSCHD; + ueCb->hdFddCb->subfrm[sfi].sfn = RG_SCH_HDFDD_INVSFN; + } + /* Add this UE to list maintained in CellCb */ + /* cmLListAdd2Tail(&cellCb->hdFddLst,&ueCb->hdFddCb->hdFddLstEnt); */ + } + else + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cellCb->cellId, + "rgSCHHdFddUeCfg(): Could not allocate memory for hd-fdd ueCb" + "CRNTI:%d",ueCb->ueId); + RETVALUE(RFAILED); + } + } + RETVALUE(ROK); +}/*rgSCHHdFddUeCfg*/ + + +/* @brief Frees Half Duplex related data structures + * + * @details + * + * Function : rgSCHHdFddUeDel + * + * Invoking Module Processing: + * - This shall be invoked by SCH_GOM at Ue deletion. + * + * Processing Steps: + * - if Half Duplex is enabled + * - if (ueCb->hdFddCb != NULL) + * - Remove ue from cellCb->hdUeLstCp; + * - Dellocate memory + * - else + * - Nothing to do + * - Return ROK + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ue + * + * @RETVALUE( S16 + * -# ROK +* +*/ +#ifdef ANSI +PUBLIC S16 rgSCHHdFddUeDel +( +RgSchCellCb *cellCb, +RgSchUeCb *ueCb +) +#else /* ANSI */ +PUBLIC S16 rgSCHHdFddUeDel(cellCb, ueCb) +RgSchCellCb *cellCb; +RgSchUeCb *ueCb; +#endif /* ANSI */ +{ + TRC3(rgSCHHdFddUeDel) + + RLOG_ARG2(L_DEBUG,DBG_CELLID,cellCb->cellId, + " rgSCHHdFddUeDel(): UeId =%d hdFdd=%x", + ueCb->ueId, ueCb->hdFddEnbld); + + + if (ueCb->hdFddCb) + { + /* ccpu00117052 - MOD - Passing double pointer + for proper NULLP assignment*/ + rgSCHUtlFreeSBuf(cellCb->instIdx, (Data **)(&(ueCb->hdFddCb)), + sizeof(RgSchUeHdFddCb)); + ueCb->hdFddEnbld = FALSE; + } + + RETVALUE(ROK); +} /* rgSCHHdFddUeDel */ + + + +#ifdef TFU_UPGRADE +/* @brief Mark the subframes as uplink for HD FDD if CQI/RI or SRS or RI is + * expecting . + * + * @details + * + * Function: rgSCHCmnHdFddPtUlMrk + * Purpose: Updation of Periodic CQI/PMI, SRS and SR tranmission + * instance updates + * for HD FDD UEs + * @param[in] RgSchCellCb *cell + * @RETVALUE None + */ + +#ifdef ANSI +PUBLIC Void rgSCHCmnHdFddPtUlMrk +( +RgSchCellCb *cellCb +) +#else /* ANSI */ +PUBLIC Void rgSCHCmnHdFddPtUlMrk (cellCb) +RgSchCellCb *cellCb; +#endif /* ANSI */ +{ + U16 sfn; /* System Frame Number */ + U32 pti; /* Index into Periodic table */ + U16 sfi; /* Index into HDFDD state table */ + CmLListCp *cqiLst; + CmLListCp *srsLst; + CmLListCp *srLst; + CmLListCp *riLst; + CmLList *cqiNode; + CmLList *srsNode; + CmLList *srNode; + CmLList *riNode; + CmLteTimingInfo timeInfo; + RgSchUePCqiCb *cqiCb = NULLP; + RgSchUePCqiCb *riCb = NULLP; + + TRC3(rgSCHCmnHdFddPtUlMrk) + + timeInfo = cellCb->crntTime; + + /* Determine indexes */ + pti = RG_SCH_HDFDD_GETPTI(timeInfo); + RG_SCH_HDFDD_GETSFN(sfn, timeInfo, RG_SCH_HDFDD_DELTA); + RG_SCH_HDFDD_GETSFI(sfi, timeInfo, RG_SCH_HDFDD_DELTA); + + /* Get PT entries for */ + cqiLst = &cellCb->pCqiSrsSrLst[pti].cqiLst; + srsLst = &cellCb->pCqiSrsSrLst[pti].srsLst; + srLst = &cellCb->pCqiSrsSrLst[pti].srLst; + riLst = &cellCb->pCqiSrsSrLst[pti].riLst; + + /* Get first node in each list */ + CM_LLIST_FIRST_NODE(cqiLst, cqiNode); + CM_LLIST_FIRST_NODE(srsLst, srsNode); + CM_LLIST_FIRST_NODE(riLst, riNode); + CM_LLIST_FIRST_NODE(srLst, srNode); + + /* Mark corresponding the subframe as uplink control */ + while ((NULLP != cqiNode ) && + (NULLP != srsNode ) && + (NULLP != srNode ) && + (NULLP != riNode )) + { + cqiCb = (RgSchUePCqiCb *)(cqiNode->node); + RG_SCH_HDFDD_VLDTANDMARK((RgSchUeCb*)(cqiCb->servCellInfo->ue), + RG_SCH_HDFDD_UL, sfn, sfi); + /* SRS Transmission instances */ + RG_SCH_HDFDD_VLDTANDMARK((RgSchUeCb*)srsNode->node, + RG_SCH_HDFDD_UL, sfn, sfi); + /* SR Transmission instances */ + RG_SCH_HDFDD_VLDTANDMARK((RgSchUeCb*)srNode->node, + RG_SCH_HDFDD_UL, sfn, sfi); + /* RI Transmission instances */ + riCb = (RgSchUePCqiCb *)(riNode->node); + RG_SCH_HDFDD_VLDTANDMARK((RgSchUeCb*)riCb->servCellInfo->ue, + RG_SCH_HDFDD_UL, sfn, sfi); + + /* Get next UeCb for all lists */ + CM_LLIST_NEXT_NODE(cqiLst, cqiNode); + CM_LLIST_NEXT_NODE(srsLst, srsNode); + CM_LLIST_NEXT_NODE(srLst, srNode); + CM_LLIST_NEXT_NODE(riLst, riNode); + } + + while ( NULLP != cqiNode) + { + /* CQI/PMI Transmission instances */ + cqiCb = (RgSchUePCqiCb *)(cqiNode->node); + RG_SCH_HDFDD_VLDTANDMARK((RgSchUeCb*)(cqiCb->servCellInfo->ue), + RG_SCH_HDFDD_UL, sfn, sfi); + CM_LLIST_NEXT_NODE(cqiLst, cqiNode); + } + while( NULLP != srsNode) + { + /* SRS Transmission instances */ + RG_SCH_HDFDD_VLDTANDMARK(((RgSchUeCb*)srsNode->node), + RG_SCH_HDFDD_UL, sfn, sfi); + CM_LLIST_NEXT_NODE(srsLst, srsNode); + } + while( NULLP != srNode) + { + /* SR Transmission instances */ + RG_SCH_HDFDD_VLDTANDMARK(((RgSchUeCb*)srNode->node), + RG_SCH_HDFDD_UL, sfn, sfi); + CM_LLIST_NEXT_NODE(srLst, srNode); + } + while( NULLP != riNode) + { + /* RI Transmission instances */ + riCb = (RgSchUePCqiCb *)(riNode->node); + RG_SCH_HDFDD_VLDTANDMARK((RgSchUeCb*)riCb->servCellInfo->ue, + RG_SCH_HDFDD_UL, sfn, sfi); + CM_LLIST_NEXT_NODE(riLst, riNode); + } + + RETVOID; +} /* rgSCHCmnHdFddPtUlMrk */ +#endif /* ifdef TFU_UPGRADE */ + + + +/* @brief Decides whether UE can be allowed for DL in given subframe + * + * @details + * + * Function : rgSCHCmnHdFddChkUlAllow + * + * Invoking Module Processing: + * - This shall be invoked by schedulars before allocating UL grants . + * + * Processing Steps: + * - if Half Duplex is enabled + * - If ue->sf[reqsf].state is "DONWLINK" + * set alloweUlSch=FALSE + * - else + * set alloweUlSch=TRUE + * This function Marking for BCCH/PCCH occasions is also done + * - Return ROK + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ue + * + * @RETVALUE None + * + */ +#ifdef ANSI +PUBLIC Void rgSCHCmnHdFddChkUlAllow +( + RgSchCellCb *cellCb, + RgSchUeCb *ueCb, + U8 *allow +) +#else /* ANSI */ +PUBLIC Void rgSCHCmnHdFddChkUlAllow ( cellCb, ueCb, allow) +RgSchCellCb *cellCb; +RgSchUeCb *ueCb; +U8 *allow; +#endif /* ANSI */ +{ + U16 sfn; + U16 sfi; + CmLteTimingInfo timeInfo; + RgSchDlSf *sf = NULLP; /* Dl subframe info */ + U8 ulOffset + + TRC3(rgSCHCmnHdFddChkUlAllow) + + RLOG_ARG1(L_DEBUG,DBG_CELLID,cellCb->cellId, + " rgSCHCmnHdFddChkUlAllow: ueId=%d ", ueCb->ueId); + + *allow = FALSE; + + timeInfo = cellCb->crntTime; + + ulOffset = RGSCH_PDCCH_PUSCH_DELTA - + TFU_CRCIND_ULDELTA + RGSCH_PDCCH_PUSCH_DELTA; + RG_SCH_ADD_TO_CRNT_TIME(cellCb->crntTime, timeInfo, ulOffset); + + /* Set default value */ + *allow = FALSE; + + /* Validate condition 1 */ + /* For (curretn time + DL_DELTA)th sf */ + + /* Also get subframe pointer to fetch Common Ch allocation */ + sf = rgSCHUtlSubFrmGet(cellCb, timeInfo); + + sfn = timeInfo.sfn; + RG_SCH_HDFDD_GETSFI(sfi, timeInfo, 0); + + /* Validate condition 2 */ + if (RG_SCH_HDFDD_ISCMN_SCHED(sf)) + { + /* Common channel scheduled */ + /* Mark the BCCH/PCCH occasion */ + RG_SCH_HDFDD_MARKSTATE(ueCb, RG_SCH_HDFDD_DLDATA, sfn, sfi); + RLOG_ARG1(L_DEBUG,DBG_CELLID,cellCb->cellId, + "rgSCHCmnHdFddChkUlAllow: Already marked for Cmn DL, ueId = %d ", + ueCb->ueId); + } + if ((ueCb->hdFddCb->subfrm[sfi].sfn == sfn) && + (ueCb->hdFddCb->subfrm[sfi].subFrmDir == RG_SCH_HDFDD_DLDATA || + ueCb->hdFddCb->subfrm[sfi].subFrmDir == RG_SCH_HDFDD_DLCNTRL)) + { + /* Downlink scheduled */ + *allow = FALSE; + RLOG_ARG1(L_DEBUG,DBG_CELLID,cellCb->cellId, + "rgSCHCmnHdFddChkUlAllow: Already marked for DL, ueId = %d ", + ueCb->ueId); + RETVOID; + } + + /* Validate condition 3 */ + /* For (curretn time + DL_DELTA + HRQ_DELTA)th sf + - i.e. next HARQ Feedback occasion */ + RG_SCH_HDFDD_GETSFN(sfn, timeInfo, RG_SCH_CMN_HARQ_INTERVAL); + RG_SCH_HDFDD_GETSFI(sfi, timeInfo, RG_SCH_CMN_HARQ_INTERVAL); + if (ueCb->hdFddCb->subfrm[sfi].sfn == sfn && + ueCb->hdFddCb->subfrm[sfi].subFrmDir == RG_SCH_HDFDD_UL) + { + /* No place for HARQ feedback */ + *allow = FALSE; + RLOG_ARG1(L_DEBUG,DBG_CELLID,cellCb->cellId, + "rgSCHCmnHdFddChkUlAllow: No Place for HARQ, ueId = %d ", + ueCb->ueId); + RETVOID; + + } + /* Validate condition 4 */ + /* For (curretn time + DL_DELTA - HRQ_DELTA)th sf + - i.e. previous HARQ Feedback occasion */ + RG_SCH_HDFDD_GETSFN(sfn, timeInfo, (-RG_SCH_CMN_HARQ_INTERVAL)); + RG_SCH_HDFDD_GETSFI(sfi, timeInfo, (-RG_SCH_CMN_HARQ_INTERVAL)); + if (ueCb->hdFddCb->subfrm[sfi].sfn == sfn && + ueCb->hdFddCb->subfrm[sfi].subFrmDir == RG_SCH_HDFDD_UL) + { + *allow = FALSE; + RLOG_ARG1(L_DEBUG,DBG_CELLID,cellCb->cellId, + " rgSCHCmnHdFddChkUlAllow: No Place for UL grant, ueId = %d ", + ueCb->ueId); + RETVOID; + + } + /* Validate condition 5 */ + /* For (curretn time + DL_DELTA - 1)th sf -i.e. Guard time */ + RG_SCH_HDFDD_GETSFN(sfn, timeInfo, (-RG_SCH_HDFDD_GRDTIM_DUR)); + RG_SCH_HDFDD_GETSFI(sfi, timeInfo, (-RG_SCH_HDFDD_GRDTIM_DUR)); + if (ueCb->hdFddCb->subfrm[sfi].sfn == sfn && + (ueCb->hdFddCb->subfrm[sfi].subFrmDir == RG_SCH_HDFDD_DLDATA)) + { + /* This subframe may be a switching gaurd time */ + *allow = FALSE; + RLOG_ARG1(L_DEBUG,DBG_CELLID,cellCb->cellId, + " rgSCHCmnHdFddChkUlAllow: No Place for Guard time, ueId = %d ", + ueCb->ueId); + RETVOID; + + } + /* Adition guard time rule check: Above check is only for PDSCH, lets check + is there is any BCCH/PCCH data scheduled */ + RG_SCH_ADD_TO_CRNT_TIME(cellCb->crntTime, timeInfo, + (ulOffset - RG_SCH_HDFDD_GRDTIM_DUR)); + /* Also get subframe pointer to fetch Common Ch allocation */ + sf = rgSCHUtlSubFrmGet(cellCb, timeInfo); + if (RG_SCH_HDFDD_ISCMN_SCHED(sf)) + { + /* Common channel scheduled */ + /* Mark the BCCH/PCCH occasion */ + RG_SCH_HDFDD_MARKSTATE(ueCb, RG_SCH_HDFDD_DLDATA, timeInfo.sfn, sfi); + *allow = FALSE; + RLOG_ARG1(L_DEBUG,DBG_CELLID,cellCb->cellId, + "rgSCHCmnHdFddChkUlAllow: Already marked for Cmn DL, ueId = %d ", + ueCb->ueId); + RETVOID; + + } + + /* All validation done. Safe to for UL */ + *allow = TRUE; + RETVOID; +} /* rgSCHCmnHdFddChkUlAllow */ + + + /* @brief Decides whether UE can be allowed for UL in given subframe + * + * @details + * + * Function : rgSCHCmnHdFddChkDlAllow + * + * Invoking Module Processing: + * - This shall be invoked by schedulars before allocating for DL. + * + * Processing Steps: + * Condition 1: subframe n + DL_DELTA should not be uplink + * Condition 2: subframe n+ DL_DELTA + 1 should meet guard time + * creation rule. For more + * information refer to section "2.25.7.1 Guard time + * creation rule" + * Condition 3: subframe n + DL_DELTA + HRQ_DELTA should not be + * downlink so that downlink data (HARQ Feedback) + * can be received in next 4 subframe. {n + 7} Above + * conditions have to + * be validated by taking SFN number into consideration. + * if all conditions are met then *allow is set to TRUE or lese to + * FALSE. + * if hd-fdd is not anabled for this UE, then *allow is always TRUE. + * + * Returns None + * @param[in] RgSchCellCb *cellCb + * @param[in] RgSchUeCb *ueCb + * @param[in] CmLteTimingInfo *timeInfo + * @param[out] U8 *allow -- TRUE is allowed or FALSE if no allowedi. + * Valdity of this pointer is not done in this function + * + */ +#ifdef ANSI +PUBLIC Void rgSCHCmnHdFddChkDlAllow +( +RgSchCellCb *cellCb, +RgSchUeCb *ueCb, +Bool *allow /* Valdity of this pointer is not done in this function */ +) +#else /* ANSI */ +PUBLIC Void rgSCHCmnHdFddChkDlAllow ( cellCb, ueCb, allow) +RgSchCellCb *cellCb; +RgSchUeCb *ueCb; +Bool *allow; /* Valdity of this pointer is not done in this function */ +#endif /* ANSI */ +{ + U16 sfn; + U16 sfi; + RgSchDlSf *sf = NULLP; /* Dl subframe info */ + CmLteTimingInfo timeInfo; + CmLteTimingInfo tempTimeInfo; + + TRC3(rgSCHCmnHdFddChkDlAllow) + + *allow = FALSE; + + timeInfo = cellCb->crntTime; + RGSCH_INCR_SUB_FRAME(timeInfo, RG_SCH_CMN_DL_DELTA); + + RLOG_ARG1(L_DEBUG,DBG_CELLID,cellCb->cellId, + "rgSCHCmnHdFddDlSchAll (): ueId=%d ", ueCb->ueId); + + /* Also get subframe pointer to fetch Common Ch allocation */ + sf = rgSCHUtlSubFrmGet(cellCb, timeInfo); + + /* Validate condition 1 */ + /* For (curretn time + DL_DELTA)th sf */ + sfn = timeInfo.sfn; + RG_SCH_HDFDD_GETSFI(sfi, timeInfo, 0); + + if ((ueCb->hdFddCb->subfrm[sfi].sfn == sfn) && + (ueCb->hdFddCb->subfrm[sfi].subFrmDir == RG_SCH_HDFDD_UL)) + { + /* Uplink scheduled */ + RLOG_ARG1(L_DEBUG,DBG_CELLID,cellCb->cellId, + "rgSCHCmnHdFddChkDlAllow: sf is UL, ueId=%d ", ueCb->ueId); + *allow = FALSE; + RETVOID; + } + + /* It is not validation, but BCCH/PCCH marking is done here */ + if (RG_SCH_HDFDD_ISCMN_SCHED(sf)) + { + /* Common channel scheduled */ + RG_SCH_HDFDD_MARKSTATE(ueCb, RG_SCH_HDFDD_DLDATA, sfn, sfi); /* NOT_HIT */ + } + + /* Validate condition 2 */ + /* For (curretn time + DL_DELTA + 1)th sf -i.e. Guard time */ + RG_SCH_HDFDD_GETSFN(sfn, timeInfo, RG_SCH_HDFDD_GRDTIM_DUR); + RG_SCH_HDFDD_GETSFI(sfi, timeInfo, RG_SCH_HDFDD_GRDTIM_DUR); + if (ueCb->hdFddCb->subfrm[sfi].sfn == sfn && + (ueCb->hdFddCb->subfrm[sfi].subFrmDir == RG_SCH_HDFDD_UL)) + { + /* This subframe may be a switching guard time */ + RLOG_ARG1(L_DEBUG,DBG_CELLID,cellCb->cellId, + " rgSCHCmnHdFddChkDlAllow: Guard time rule not met, ueId=%d ", + ueCb->ueId); + *allow = FALSE; + RETVOID; + } + + /* Validate condition 3 */ + /* For (curretn time + DL_DELTA + HRQ_DELTA)th sf - i.e. next HARQ + Feedback occasion */ + + RG_SCH_HDFDD_GETSFN(sfn, timeInfo, RG_SCH_CMN_HARQ_INTERVAL); + RG_SCH_HDFDD_GETSFI(sfi, timeInfo, RG_SCH_CMN_HARQ_INTERVAL); + + /* First check for any Common channel info is scheduled */ + RG_SCH_ADD_TO_CRNT_TIME(timeInfo, tempTimeInfo, RG_SCH_CMN_HARQ_INTERVAL) + /* Also get subframe pointer to fetch Common Ch allocation */ + sf = rgSCHUtlSubFrmGet(cellCb, tempTimeInfo); + if (RG_SCH_HDFDD_ISCMN_SCHED(sf)) + { + /* Common channel scheduled */ + /* Do the marking for this subframe */ + RG_SCH_HDFDD_MARKSTATE(ueCb, RG_SCH_HDFDD_DLDATA, tempTimeInfo.sfn, sfi); + RLOG_ARG1(L_DEBUG,DBG_CELLID,cellCb->cellId, + "rgSCHCmnHdFddChkDlAllow: Possible systemInfo, ueId=%d ", + ueCb->ueId); + } + + /* Check for actual validation condition 3 */ + if (ueCb->hdFddCb->subfrm[sfi].sfn == sfn && + ueCb->hdFddCb->subfrm[sfi].subFrmDir != RG_SCH_HDFDD_UL) + { + /* No place for HARQ feedback */ + RLOG_ARG1(L_DEBUG,DBG_CELLID,cellCb->cellId, + "rgSCHCmnHdFddChkDlAllow: No place for HARQ feedback, ueId=%d ", + ueCb->ueId); + *allow = FALSE; + + /* Mark this sf as DLCNTRL */ + ueCb->hdFddCb->subfrm[sfi].subFrmDir =RG_SCH_HDFDD_DLCNTRL; + RETVOID; + } + + + /* If we are here then, subframe at HARQth location can be UL. + But check if Guard violation is done */ + RG_SCH_HDFDD_GETSFN(sfn, timeInfo, RG_SCH_CMN_HARQ_INTERVAL-1); + RG_SCH_HDFDD_GETSFI(sfi, timeInfo, RG_SCH_CMN_HARQ_INTERVAL-1); + /* check for any Common channel info is scheduled */ + RG_SCH_ADD_TO_CRNT_TIME(timeInfo, tempTimeInfo, (RG_SCH_CMN_HARQ_INTERVAL-1)) + /* Also get subframe pointer to fetch Common Ch allocation */ + sf = rgSCHUtlSubFrmGet(cellCb, tempTimeInfo); + if (RG_SCH_HDFDD_ISCMN_SCHED(sf)) + { + /* Common channel scheduled */ + /* Do the marking for this subframe */ + RG_SCH_HDFDD_MARKSTATE(ueCb, RG_SCH_HDFDD_DLDATA, tempTimeInfo.sfn, sfi); + RLOG_ARG1(L_DEBUG,DBG_CELLID,cellCb->cellId, + "rgSCHCmnHdFddChkDlAllow: (GT) Possible systemInfo, ueId=%d ", + ueCb->ueId); + } + + if (ueCb->hdFddCb->subfrm[sfi].sfn == sfn && + ueCb->hdFddCb->subfrm[sfi].subFrmDir == RG_SCH_HDFDD_DLDATA) + { + /* No place for HARQ feedback */ + RLOG_ARG1(L_DEBUG,DBG_CELLID,cellCb->cellId, + "rgSCHCmnHdFddChkDlAllow: (GT) No place for HARQ feedback," + "ueId=%d ",ueCb->ueId); + + *allow = FALSE; + RETVOID; + } + /* First check for any Common channel info is scheduled */ + + *allow = TRUE; + /* All validation done. Safe to for DL */ + RETVOID; +} /* rgSCHCmnHdFddChkDlAllow */ + + + +/* @brief Decides whether NACK can be sent in a given subrame + * + * @details + * + * Function : rgSCHCmnHdFddChkNackAllow + * + * Invoking Module Processing: + * - This shall be invoked by schedulars. + * + * @param[in] RgSchUeCb *ue + * + * @RETVALUE None + * + */ + +#ifdef ANSI +PUBLIC Void rgSCHCmnHdFddChkNackAllow +( +RgSchCellCb *cellCb, +RgSchUeCb *ueCb, +CmLteTimingInfo timeInfo, +Bool *sndNACK +) +#else /* ANSI */ +PUBLIC Void rgSCHCmnHdFddChkNackAllow(cellCb, ueCb, timeInfo, sndNACK) +RgSchCellCb *cellCb; +RgSchUeCb *ueCb; +CmLteTimingInfo timeInfo; +Bool *sndNACK; +#endif /* ANSI */ +{ + RgSchDlSf *sf; + CmLteTimingInfo tempTimeInfo; + + TRC3(rgSCHCmnHdFddChkNackAllow) + + /* Information in timeInfo contains (n+DL_DELTA) th subframe info*/ + + *sndNACK = FALSE; + + /* Determine SFN and sf index for current subframe. + Note: Round function used as example */ + tempTimeInfo = timeInfo; + RGSCH_INCR_SUB_FRAME(tempTimeInfo, RG_SCH_CMN_HARQ_INTERVAL); + + /* Also get subframe pointer to fetch Common Ch allocation */ + sf = rgSCHUtlSubFrmGet(cellCb, tempTimeInfo); + + /* Check is this subframe has any Common Channel info scheduled */ + if(RG_SCH_HDFDD_ISCMN_SCHED(sf)) + { + /* Yes, Cannot send NACK */ + RLOG_ARG1(L_DEBUG,DBG_CELLID,cellCb->cellId, + "rgSCHCmnHdFddChkNackAllow: Cannot send NACK, ueId = %d ", + ueCb->ueId); + *sndNACK = FALSE; + } + else + { + /* safe, Send NACK */ + RLOG_ARG1(L_DEBUG,DBG_CELLID,cellCb->cellId, + "rgSCHCmnHdFddChkNackAllow: NACk can be sent, ueId = %d ", + ueCb->ueId); + *sndNACK = TRUE; + } + + RETVOID; +} /* rgSCHCmnHdFddChkNackAllow */ + + + + + /* @brief makes final marking for HD-FDD UL allocations + * + * @details + * + * Function : rgSCHCmnHdFddUpdULMark + * + * Invoking Module Processing: + * - This shall be invoked by schedulars at the time of UL allocation + * finalization. + * + * Processing Steps: + * + * @param[in] RgSchCellCb *cellCb + * @param[in] RgSchUeCb *ueCb + * @param[in] CmLteTimingInfo *timeInfo + * @param[out] U8 *allow -- TRUE is allowed or FALSE if no allowedi. + * Valdity of this pointer is not done in this function. + * + * @RETVALUE None + */ +#ifdef ANSI +PUBLIC Void rgSCHCmnHdFddUpdULMark +( +RgSchCellCb *cellCb, +RgSchUeCb *ueCb +) +#else /* ANSI */ +PUBLIC Void rgSCHCmnHdFddUpdULMark ( cellCb, ueCb) +RgSchCellCb *cellCb; +RgSchUeCb *ueCb; +#endif /* ANSI */ +{ + + U16 sfn; + U16 sfi; + CmLteTimingInfo timeInfo; + U8 ulOffset; + + TRC3(rgSCHCmnHdFddUpdULMark) + + + ulOffset = RGSCH_PDCCH_PUSCH_DELTA - + TFU_CRCIND_ULDELTA + RGSCH_PDCCH_PUSCH_DELTA; + RG_SCH_ADD_TO_CRNT_TIME(cellCb->crntTime, timeInfo, ulOffset) + + + /* Mark (n + UL_DELTA)th subframe as UL */ + sfn = timeInfo.sfn; + RG_SCH_HDFDD_GETSFI(sfi, timeInfo, 0); + + RG_SCH_HDFDD_MARKSTATE(ueCb, RG_SCH_HDFDD_UL, sfn, sfi); + + /* Mark (n + UL_DELTA + HARQ_DELTA)th subframe as DL */ + RG_SCH_HDFDD_GETSFN(sfn, timeInfo, RG_SCH_CMN_HARQ_INTERVAL); + RG_SCH_HDFDD_GETSFI(sfi, timeInfo, RG_SCH_CMN_HARQ_INTERVAL); + RG_SCH_HDFDD_MARKSTATE(ueCb, RG_SCH_HDFDD_DLCNTRL, sfn, sfi); + + /* Mark (n + UL_DELTA - HARQ_DELTA)th subframe as DL */ + RG_SCH_HDFDD_GETSFN(sfn, timeInfo, (0-RG_SCH_CMN_HARQ_INTERVAL)); + RG_SCH_HDFDD_GETSFI(sfi, timeInfo, (0-RG_SCH_CMN_HARQ_INTERVAL)); + if (ueCb->hdFddCb->subfrm[sfi].subFrmDir != RG_SCH_HDFDD_DLDATA) + { + RG_SCH_HDFDD_MARKSTATE(ueCb, RG_SCH_HDFDD_DLCNTRL, sfn, sfi); + } + + /* Mark (n + UL_DELTA - 1)th subframe as DL_CNTRL */ + RG_SCH_HDFDD_GETSFN(sfn, timeInfo, -RG_SCH_HDFDD_GRDTIM_DUR); + RG_SCH_HDFDD_GETSFI(sfi, timeInfo, -RG_SCH_HDFDD_GRDTIM_DUR); + RG_SCH_HDFDD_MARKSTATE(ueCb, RG_SCH_HDFDD_DLCNTRL, sfn, sfi); + + /* Remove marking for older subframes */ + + RG_SCH_HDFDD_GETSFN(sfn, timeInfo, (S16)(ulOffset * -1)); + RG_SCH_HDFDD_GETSFI(sfi, timeInfo, (ulOffset * -1)); + RG_SCH_HDFDD_MARKSTATE(ueCb, RG_SCH_HDFDD_NOSCHD, RG_SCH_HDFDD_INVSFN, sfi); + + RETVOID; +} /* rgSCHCmnHdFddUpdULMark */ + + + + + /* @brief makes final marking for HD-FDD DL allocations + * + * @details + * + * Function : rgSCHCmnHdFddUpdDLMark + * + * Invoking Module Processing: + * - This shall be invoked by schedulars at the time of DL allocation + * finalization. + * + * Processing Steps: + * + * @param[in] RgSchCellCb *cellCb + * @param[in] RgSchUeCb *ueCb + * @param[in] CmLteTimingInfo *timeInfo + * @param[out] U8 *allow -- TRUE is allowed or FALSE if no allowed. + * Valdity of this pointer is not done in this function + * + * @RETVALUE None + */ + +#ifdef ANSI +PUBLIC Void rgSCHCmnHdFddUpdDLMark +( +RgSchCellCb *cellCb, +RgSchUeCb *ueCb +) +#else /* ANSI */ +PUBLIC Void rgSCHCmnHdFddUpdDLMark (cellCb, ueCb) +RgSchCellCb *cellCb; +RgSchUeCb *ueCb; +#endif /* ANSI */ +{ + + U16 sfn; + U16 sfi; + CmLteTimingInfo timeInfo; + + TRC3(rgSCHCmnHdFddUpdDLMark) + + timeInfo = cellCb->crntTime; + RGSCH_INCR_SUB_FRAME(timeInfo, RG_SCH_CMN_DL_DELTA); + + /* Mark (n + DL_DELTA)th subframe as DL */ + sfn = timeInfo.sfn; + RG_SCH_HDFDD_GETSFI(sfi, timeInfo, 0); + + RG_SCH_HDFDD_MARKSTATE(ueCb, RG_SCH_HDFDD_DLDATA, sfn, sfi); + + /* Mark (n + 1)th subframe as DL_CNTRL */ + RG_SCH_HDFDD_GETSFN(sfn, timeInfo, RG_SCH_HDFDD_GRDTIM_DUR); + RG_SCH_HDFDD_GETSFI(sfi, timeInfo, RG_SCH_HDFDD_GRDTIM_DUR); + RG_SCH_HDFDD_MARKSTATE(ueCb, RG_SCH_HDFDD_DLCNTRL, sfn, sfi); + + /* Mark (n + DL_DELTA + HARQ_DELTA )th subframe as UL */ + RG_SCH_HDFDD_GETSFN(sfn, timeInfo, RG_SCH_CMN_HARQ_INTERVAL); + RG_SCH_HDFDD_GETSFI(sfi, timeInfo, RG_SCH_CMN_HARQ_INTERVAL); + RG_SCH_HDFDD_MARKSTATE(ueCb, RG_SCH_HDFDD_UL, sfn, sfi); + + /* Mark (n + DL_DELTA + HARQ_DELTA - 1)th subframe + as DL control for Guard period */ + RG_SCH_HDFDD_GETSFN(sfn, timeInfo, + (RG_SCH_CMN_HARQ_INTERVAL - RG_SCH_HDFDD_GRDTIM_DUR)); + RG_SCH_HDFDD_GETSFI(sfi, timeInfo, + (RG_SCH_CMN_HARQ_INTERVAL - RG_SCH_HDFDD_GRDTIM_DUR)); + if (ueCb->hdFddCb->subfrm[sfi].subFrmDir != RG_SCH_HDFDD_UL) + { + RG_SCH_HDFDD_MARKSTATE(ueCb, RG_SCH_HDFDD_DLCNTRL, sfn, sfi); + } + + RETVOID; +} /* rgSCHCmnHdFddUpdDLMark */ + + + /* @brief determines effective SFN + * + * @details + * + * Function : rgSCHHdFddGetSfn + * + * Invoking Module Processing: + * Any HD-FDD module can invoke this function. + * + * Processing Steps: + * + * @param[out] *sfn U32 + * @param[in] timeInfo timing information subframe of interest + * @param[in] offsest Offest with w.r.t which SFN has to be determined + * + * @RETVALUE None + */ + +#ifdef ANSI +PUBLIC Void rgSCHHdFddGetSfn +( + U16 *sfn, + CmLteTimingInfo timeInfo, + S16 offset +) +#else /* ANSI */ +PUBLIC Void rgSCHHdFddGetSfn (sfn, timeInfo, offset) + U16 *sfn; + CmLteTimingInfo timeInfo; + S16 offset; +#endif /* ANSI */ +{ + U16 tempSfn; + S16 tempSfCount; + + TRC3(rgSCHHdFddGetSfn) + if(((S16)(timeInfo.subframe) + offset) >= RGSCH_NUM_SUB_FRAMES) + { + /* Increament to number of times of SFNs that can be possible + with this offset */ + tempSfn = (timeInfo.sfn + + ((timeInfo.subframe + offset) / RGSCH_NUM_SUB_FRAMES)) + & (RGSCH_MAX_SFN -1); /* Mod with MAX SFN supported */ + } + else + { + if(((S16)(timeInfo.subframe) + offset) < 0) + { + /* If negative, then definitely at least previous SFN */ + tempSfn = (timeInfo.sfn - 1) & (RGSCH_MAX_SFN -1); + + /* Now find how many more times we need to decreament */ + tempSfCount = timeInfo.subframe + offset; + RG_SCH_HDFDD_ROLLSFN(tempSfCount, tempSfn); + } + else + { + /* No change in sfn */ + tempSfn = timeInfo.sfn; + } + } + *sfn = tempSfn; + + RETVOID; +} /* End of rgSCHHdFddGetSfn */ + + +#ifdef __cplusplus +} + /* extern C */ +#endif /* __cplusplus */ + +#endif /* LTEMAC_HDFDD */ + + + + +/********************************************************************** + + End of file +**********************************************************************/ diff --git a/src/5gnrmac/rg_sch_hdfdd.h b/src/5gnrmac/rg_sch_hdfdd.h new file mode 100755 index 000000000..5957cc153 --- /dev/null +++ b/src/5gnrmac/rg_sch_hdfdd.h @@ -0,0 +1,62 @@ +/******************************************************************************* +################################################################################ +# Copyright (c) [2017-2019] [Radisys] # +# # +# 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. # +################################################################################ +*******************************************************************************/ + +/********************************************************************** + Name: LTE MAC HD-FDD + + Type: C header file + + Desc: Defines required by HD-FDD + + File: rg_sch_hdfdd.h + +*********************************************************************21*/ + + +#ifndef __RGSCHHDFDDH__ +#define __RGSCHHDFDDH__ +#ifdef __cplusplus +extern "C" { +#endif + +/* Half Duplex Specific defines */ +/* Maximum Number of subframes information managed */ +#define RG_SCH_HDFDD_MAXSUB_INFO 20 + +/* Subframe States */ +#define RG_SCH_SF_DFLT_STATE 0x00 +#define RG_SCH_SF_DLDATA_STATE 0x01 +#define RG_SCH_SF_DLCNTRL_STATE 0x02 +#define RG_SCH_SF_ULDATA_CNTRL_STATE 0x04 + +/* To get the BCH is present or not at subframe */ +#define RG_SCH_BCCH_TRUE_FALSE( _time, _bchTrue)\ +{\ + _bchTrue = FALSE;\ + /* Call the API is provided by SI module */ \ +} + +#ifdef __cplusplus +} +#endif +#endif /* __RGSCHCMNH__ */ + +/********************************************************************30** + + End of file +**********************************************************************/ diff --git a/src/5gnrmac/rg_sch_hdfdd.x b/src/5gnrmac/rg_sch_hdfdd.x new file mode 100755 index 000000000..5f93a5ed5 --- /dev/null +++ b/src/5gnrmac/rg_sch_hdfdd.x @@ -0,0 +1,101 @@ +/******************************************************************************* +################################################################################ +# Copyright (c) [2017-2019] [Radisys] # +# # +# 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. # +################################################################################ +*******************************************************************************/ + +/********************************************************************** + + Name: LTE MAC HD-FDD + + Type: C include file + + Desc: Defines required by HD-FDD + + File: rg_sch_hdfdd.x + +**********************************************************************/ +/** + * @file rg_sch_hdfdd.x This file gives the describes the design for Half + * Duplex FDD feature. + * + * Half duplex FDD operation is one in which the UE cannot receive and + * transmit at the same time. This is more of a UE limitation, chosen to + * reduce the complexity of the UE's hardware. In LTE the half duplex FDD + * is implemented such that the eNodeB schedules such that the UE doesn't + * transmit and receive in the same subframe. The UE unless informed that a + * subframe is for Uplink transmission continues to look at the PDCCH. + + * Due to the delay in switching from downlink to uplink, UE is unable to + * receive the last few symbols of the subframe preceding the subframe + * assigned for uplink transmissions.Half duplex FDD is a UE specific + * configuration. +*/ + + +#ifndef __RGHDFDDX__ +#define __RGHDFDDX__ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + + + +/****************************************************************************** + * Start of Data declarations * + ******************************************************************************/ + +/** + @brief Half Duplex subframtion information stored per ue. */ + +typedef struct rgSchUeHdFddSfInfo +{ + U16 sfn; /*!< Store the sfn for updated state + Default Value= 0xffff + */ + U8 state; + /*!< 0x00= DFLT + 0x01= DL DATA +(OPT:CNTRL INFO) + 0x02= DL CNTRL + 0x04= UL DATA+(OPT: CTNRL INFO) + */ + +}RgSchUeHdFddSfInfo; + +/** + @brief Half Duplex control related information per ue. */ + +typedef struct rgSchUeHdFddCb +{ + RgSchUeHdFddSfInfo sf[RG_SCH_HDFDD_MAXSUB_INFO]; + + CmLList hdFddLstEnt; /*!< Linked list entity for HD-FDD List */ + +}RgSchUeHdFddCb; + + + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* __RGHDFDD__ */ + + +/********************************************************************** + End of file +**********************************************************************/ diff --git a/src/5gnrmac/rg_sch_inf.c b/src/5gnrmac/rg_sch_inf.c new file mode 100755 index 000000000..282fa62a6 --- /dev/null +++ b/src/5gnrmac/rg_sch_inf.c @@ -0,0 +1,1687 @@ +/******************************************************************************* +################################################################################ +# Copyright (c) [2017-2019] [Radisys] # +# # +# 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. # +################################################################################ +*******************************************************************************/ + +/************************************************************************ + + Name: LTE-MAC layer + + Type: C source file + + Desc: C source code for packing/unpacking of INF interface + primitives. + + File: rg_sch_inf.c + +**********************************************************************/ + +/* header include files (.h) */ +#include "envopt.h" /* environment options */ +#include "envdep.h" /* environment dependent */ +#include "envind.h" /* environment independent */ +#include "gen.h" /* general */ +#include "ssi.h" /* system services */ +#include "cm_tkns.h" /* Common Token Defines */ +#include "cm_llist.h" /* Common Link List Defines */ +#include "cm_hash.h" /* Common Hash List Defines */ +#include "cm_mblk.h" /* memory management */ +#include "cm_lte.h" /* Common LTE Defines */ +#include "tfu.h" /* RGU defines */ +#ifdef LTE_L2_MEAS +#include "lrg.h" +#endif +#include "rg_sch_inf.h" /* RGU Interface defines */ + +/* header/extern include files (.x) */ +#include "gen.x" /* general */ +#include "ssi.x" /* system services */ +#include "cm_tkns.x" /* Common Token Definitions */ +#include "cm_llist.x" /* Common Link List Definitions */ +#include "cm_lib.x" /* Common Library Definitions */ +#include "cm_hash.x" /* Common Hash List Definitions */ +#include "cm_mblk.x" /* memory management */ +#include "cm_lte.x" /* Common LTE Defines */ +#include "tfu.x" /* RGU defines */ +#ifdef LTE_L2_MEAS +#include "lrg.x" +#endif +#include "rg_sch_inf.x" /* RGU Interface includes */ + +#ifdef LCSCH +/*Fix: start: Inform UE delete to scheduler*/ +/** +* @brief This primitive is used to indicate to scheduler +* that UE has been deleted at MAC. +* +* @details +* +* Function : cmPkMacSchUeDelInd +* +* @param[in] Pst* pst +* @param[in] RgInfUeDelInd* ueDelInd +* @return S16 +* -# ROK +**/ +#ifdef ANSI +PUBLIC S16 cmPkMacSchUeDelInd +( +Pst* pst, +RgInfUeDelInd* ueDelInd +) +#else +PUBLIC S16 cmPkMacSchUeDelInd(pst, ueDelInd) +Pst* pst; +RgInfUeDelInd* ueDelInd; +#endif +{ + Buffer *mBuf = NULLP; + TRC2(cmPkMacSchUeDelInd) + + if (SGetMsg(pst->region, pst->pool, &mBuf) != ROK) + { + RETVALUE(RFAILED); + } + +#ifdef MS_MBUF_CORRUPTION + MS_BUF_ADD_ALLOC_CALLER(); +#endif + if(SAddPstMsgMult((Data *)ueDelInd, sizeof(RgInfUeDelInd), mBuf) != ROK) + { + RGSCHINF_FREE_MSG(mBuf); + RETVALUE(RFAILED); + } + + pst->event = (Event) EVTINFUEDELIND; + RETVALUE(SPstTsk(pst,mBuf)); +} + +/** +* @brief This primitive is used to indicate to scheduler +* that UE has been deleted at MAC. +* +* +* @details +* +* Function : cmUnpkMacSchUeDelInd +* +* @param[in] Pst* pst +* @param[in] SpId spId +* @param[in] RguDDatReqInfo * datReq +* @return S16 +* -# ROK +**/ +#ifdef ANSI +PUBLIC S16 cmUnpkMacSchUeDelInd +( +UeDelInd func, +Pst *pst, +Buffer *mBuf +) +#else +PUBLIC S16 cmUnpkMacSchUeDelInd(func, pst, mBuf) +UeDelInd func; +Pst *pst; +Buffer *mBuf; +#endif +{ + RgInfUeDelInd ueDelInd; + + TRC2(cmUnpkMacSchUeDelInd) + + if(SRemPreMsgMult((Data *)&ueDelInd, sizeof(RgInfUeDelInd), mBuf) != ROK) + { + RGSCHINF_FREE_MSG(mBuf); + RETVALUE(RFAILED); + } + + RGSCHINF_FREE_MSG(mBuf); + + RETVALUE((*func)(pst, &ueDelInd)); +} +/*Fix: end: Inform UE delete to scheduler*/ + +/** +* @brief Request from RLC to MAC for forwarding SDUs on + * dedicated channel for transmission. +* +* @details +* +* Function : cmPkMacSchDedBoUpdtReq +* +* @param[in] Pst* pst +* @param[in] SpId spId +* @param[in] RguDDatReqInfo * datReq +* @return S16 +* -# ROK +**/ +#ifdef ANSI +PUBLIC S16 cmPkMacSchDedBoUpdtReq +( +Pst* pst, +RgInfDedBoRpt* boRpt +) +#else +PUBLIC S16 cmPkMacSchDedBoUpdtReq(pst, boRpt) +Pst* pst; +RgInfDedBoRpt* boRpt; +#endif +{ + Buffer *mBuf = NULLP; + TRC2(cmPkMacSchDedBoUpdtReq) + + if (SGetMsg(pst->region, pst->pool, &mBuf) != ROK) { + RETVALUE(RFAILED); + } + +#ifdef MS_MBUF_CORRUPTION + MS_BUF_ADD_ALLOC_CALLER(); +#endif + if(SAddPstMsgMult((Data *)boRpt, sizeof(RgInfDedBoRpt), mBuf) != ROK) + { + RGSCHINF_FREE_MSG(mBuf); + RETVALUE(RFAILED); + } + + pst->event = (Event) EVTINFDEDBOUPDTREQ; + RETVALUE(SPstTsk(pst,mBuf)); +} + + +/** +* @brief Request from RLC to MAC for forwarding SDUs on + * dedicated channel for transmission. +* +* @details +* +* Function : cmUnpkMacSchDedBoUpdtReq +* +* @param[in] Pst* pst +* @param[in] SpId spId +* @param[in] RguDDatReqInfo * datReq +* @return S16 +* -# ROK +**/ +#ifdef ANSI +PUBLIC S16 cmUnpkMacSchDedBoUpdtReq +( +DedBoUpdtReq func, +Pst *pst, +Buffer *mBuf +) +#else +PUBLIC S16 cmUnpkMacSchDedBoUpdtReq(func, pst, mBuf) +DedBoUpdtReq func; +Pst *pst; +Buffer *mBuf; +#endif +{ + RgInfDedBoRpt boRpt; + + TRC2(cmUnpkMacSchDedBoUpdtReq) + + if(SRemPreMsgMult((Data *)&boRpt, sizeof(RgInfDedBoRpt), mBuf) != ROK) + { + RGSCHINF_FREE_MSG(mBuf); + RETVALUE(RFAILED); + } + + RGSCHINF_FREE_MSG(mBuf); + RETVALUE((*func)(pst, &boRpt)); +} +/** +* @brief Request from RLC to MAC for forwarding SDUs on + * dedicated channel for transmission. +* +* @details +* +* Function : cmPkMacSchCmnBoUpdtReq +* +* @param[in] Pst* pst +* @param[in] SpId spId +* @param[in] RguDDatReqInfo * datReq +* @return S16 +* -# ROK +**/ +#ifdef ANSI +PUBLIC S16 cmPkMacSchCmnBoUpdtReq +( +Pst* pst, +RgInfCmnBoRpt* boRpt +) +#else +PUBLIC S16 cmPkMacSchCmnBoUpdtReq(pst, boRpt) +Pst* pst; +RgInfCmnBoRpt* boRpt; +#endif +{ + Buffer *mBuf = NULLP; + TRC2(cmPkMacSchCmnBoUpdtReq) + + if (SGetMsg(pst->region, pst->pool, &mBuf) != ROK) { + RETVALUE(RFAILED); + } + +#ifdef MS_MBUF_CORRUPTION + MS_BUF_ADD_ALLOC_CALLER(); +#endif + if(SAddPstMsgMult((Data *)boRpt, sizeof(RgInfCmnBoRpt), mBuf) != ROK) + { + RGSCHINF_FREE_MSG(mBuf); + RETVALUE(RFAILED); + } + + pst->event = (Event) EVTINFCMNBOUPDTREQ; + RETVALUE(SPstTsk(pst,mBuf)); +} + + +/** +* @brief Request from RLC to MAC for forwarding SDUs on + * dedicated channel for transmission. +* +* @details +* +* Function : cmUnpkMacSchCmnBoUpdtReq +* +* @param[in] Pst* pst +* @param[in] SpId spId +* @param[in] RguDDatReqInfo * datReq +* @return S16 +* -# ROK +**/ +#ifdef ANSI +PUBLIC S16 cmUnpkMacSchCmnBoUpdtReq +( +CmnBoUpdtReq func, +Pst *pst, +Buffer *mBuf +) +#else +PUBLIC S16 cmUnpkMacSchCmnBoUpdtReq(func, pst, mBuf) +CmnBoUpdtReq func; +Pst *pst; +Buffer *mBuf; +#endif +{ + RgInfCmnBoRpt boRpt; + + TRC2(cmUnpkMacSchCmnBoUpdtReq) + + if(SRemPreMsgMult((Data *)&boRpt, sizeof(RgInfCmnBoRpt), mBuf) != ROK) + { + RGSCHINF_FREE_MSG(mBuf); + RETVALUE(RFAILED); + } + + RGSCHINF_FREE_MSG(mBuf); + RETVALUE((*func)(pst, &boRpt)); +} +/** +* @brief Request from RLC to MAC for forwarding SDUs on + * dedicated channel for transmission. +* +* @details +* +* Function : cmPkMacSchSfRecpInd +* +* @param[in] Pst* pst +* @param[in] SpId spId +* @param[in] RguDDatReqInfo * datReq +* @return S16 +* -# ROK +**/ +#ifdef ANSI +PUBLIC S16 cmPkMacSchSfRecpInd +( +Pst* pst, +RgInfSfDatInd* datInd +) +#else +PUBLIC S16 cmPkMacSchSfRecpInd(pst, datInd) +Pst* pst; +RgInfSfDatInd* datInd; +#endif +{ + Buffer *mBuf = NULLP; + TRC2(cmPkMacSchSfRecpInd) + + if (SGetMsg(pst->region, pst->pool, &mBuf) != ROK) { + RETVALUE(RFAILED); + } + + if(cmPkPtr((PTR)datInd, mBuf) != ROK) + { + RGSCHINF_FREE_MSG(mBuf); + RETVALUE(RFAILED); + } + + pst->event = (Event) EVTINFSFRECPIND; + RETVALUE(SPstTsk(pst,mBuf)); +} + + +/** +* @brief Request from RLC to MAC for forwarding SDUs on + * dedicated channel for transmission. +* +* @details +* +* Function : cmUnpkMacSchSfRecpInd +* +* @param[in] Pst* pst +* @param[in] SpId spId +* @param[in] RguDDatReqInfo * datReq +* @return S16 +* -# ROK +**/ +#ifdef ANSI +PUBLIC S16 cmUnpkMacSchSfRecpInd +( +SfRecpInd func, +Pst *pst, +Buffer *mBuf +) +#else +PUBLIC S16 cmUnpkMacSchSfRecpInd(func, pst, mBuf) +SfRecpInd func; +Pst *pst; +Buffer *mBuf; +#endif +{ + RgInfSfDatInd* datInd; + + TRC2(cmUnpkMacSchCmnBoUpdtReq) + + if(cmUnpkPtr((PTR *)&datInd, mBuf) != ROK) + { + RGSCHINF_FREE_MSG(mBuf); + RETVALUE(RFAILED); + } + + RGSCHINF_FREE_MSG(mBuf); + /* Call cmFreeMem(datInd) in scheduler */ + RETVALUE((*func)(pst, datInd)); +} + +#ifdef LTEMAC_SPS +/** +* @brief Primitive from MAC to SCH to indicate release of UL SPS for a UE +* +* @details +* +* Function : cmPkMacSchSpsRelInd +* +* @param[in] Pst* pst +* @param[in] RgInfSpsRelInfo* relInfo +* @return S16 +* -# ROK +**/ +#ifdef ANSI +PUBLIC S16 cmPkMacSchSpsRelInd +( +Pst* pst, +RgInfSpsRelInfo* relInfo +) +#else +PUBLIC S16 cmPkMacSchSpsRelInd(pst, relInfo) +Pst* pst; +RgInfSpsRelInfo* relInfo; +#endif +{ + Buffer *mBuf = NULLP; + + TRC2(cmPkMacSchSpsRelInd) + + if (SGetMsg(pst->region, pst->pool, &mBuf) != ROK) { + RETVALUE(RFAILED); + } + + if(cmPkPtr((PTR)relInfo, mBuf) != ROK) + { + RGSCHINF_FREE_MSG(mBuf); + RETVALUE(RFAILED); + } + + pst->event = (Event) EVTINFSPSRELIND; + RETVALUE(SPstTsk(pst,mBuf)); +} /* end of cmPkMacSchSpsRelInd */ + +/** +* @brief Primitive from MAC to SCH to indicate release of UL SPS for a UE +* +* @details +* +* Function : cmUnpkMacSchSpsRelInd +* +* @param[in] SpsRelInd func +* @param[in] Pst* pst +* @param[in] Buffer *mBuf +* @return S16 +* -# ROK +**/ +#ifdef ANSI +PUBLIC S16 cmUnpkMacSchSpsRelInd +( +SpsRelInd func, +Pst *pst, +Buffer *mBuf +) +#else +PUBLIC S16 cmUnpkMacSchSpsRelInd(func, pst, mBuf) +SpsRelInd func; +Pst *pst; +Buffer *mBuf; +#endif +{ + RgInfSpsRelInfo *relInfo; + + TRC2(cmUnpkMacSchSpsRelInd) + + if(cmUnpkPtr((PTR *)&relInfo, mBuf) != ROK) + { + RGSCHINF_FREE_MSG(mBuf); + RETVALUE(RFAILED); + } + + RGSCHINF_FREE_MSG(mBuf); + RETVALUE((*func)(pst, relInfo)); +} /* end of cmUnpkMacSchSpsRelInd */ +#endif /* LTEMAC_SPS */ + +#endif +#ifdef LCRG +/** +* @brief Request from RLC to MAC for forwarding SDUs on + * dedicated channel for transmission. +* +* @details +* +* Function : cmPkSchMacSfAllocReq +* +* @param[in] Pst* pst +* @param[in] SpId spId +* @param[in] RguDDatReqInfo * datReq +* @return S16 +* -# ROK +**/ +#ifdef ANSI +PUBLIC S16 cmPkSchMacSfAllocReq +( +Pst* pst, +RgInfSfAlloc* resAllocReq +) +#else +PUBLIC S16 cmPkSchMacSfAllocReq(pst, resAllocReq) +Pst* pst; +RgInfSfAlloc* resAllocReq; +#endif +{ + Buffer *mBuf = NULLP; + TRC2(cmPkSchMacSfAllocReq) + + if (SGetMsg(pst->region, pst->pool, &mBuf) != ROK) { + RETVALUE(RFAILED); + } + + if(cmPkPtr((PTR)resAllocReq, mBuf) != ROK) + { + RGSCHINF_FREE_MSG(mBuf); + RETVALUE(RFAILED); + } + + pst->event = (Event) EVTINFSFALLOCREQ; + RETVALUE(SPstTsk(pst,mBuf)); +} + + +/** +* @brief Request from RLC to MAC for forwarding SDUs on + * dedicated channel for transmission. +* +* @details +* +* Function : cmUnpkSchMacSfAllocReq +* +* @param[in] Pst* pst +* @param[in] SpId spId +* @param[in] RguDDatReqInfo * datReq +* @return S16 +* -# ROK +**/ +#ifdef ANSI +PUBLIC S16 cmUnpkSchMacSfAllocReq +( +SfAllocReq func, +Pst *pst, +Buffer *mBuf +) +#else +PUBLIC S16 cmUnpkSchMacSfAllocReq(func, pst, mBuf) +SfAllocReq func; +Pst *pst; +Buffer *mBuf; +#endif +{ + RgInfSfAlloc* resAllocReq; + + TRC2(cmUnpkSchMacSfAllocReq) + + if(cmUnpkPtr((PTR *)&resAllocReq, mBuf) != ROK) + { + RGSCHINF_FREE_MSG(mBuf); + RETVALUE(RFAILED); + } + + RGSCHINF_FREE_MSG(mBuf); + RETVALUE((*func)(pst, resAllocReq)); +} +/** +* @brief Request from SCH To MAC for harq entity reset +* +* @details +* +* Function : cmPkSchMacRstHqEntReq +* +* @param[in] Pst* pst +* @param[in] RgInfResetHqEnt *hqEntInfo +* @return S16 +* -# ROK +**/ +#ifdef ANSI +PUBLIC S16 cmPkSchMacRstHqEntReq +( +Pst* pst, +RgInfResetHqEnt* hqEntInfo +) +#else +PUBLIC S16 cmPkSchMacRstHqEntReq(pst, sfHqInfo) +Pst* pst, +RgInfResetHqEnt* hqEntInfo +#endif +{ + Buffer *mBuf = NULLP; + TRC2(cmPkSchMacRstHqEntReq) + + if (SGetMsg(pst->region, pst->pool, &mBuf) != ROK) { + RETVALUE(RFAILED); + } + + if(cmPkPtr((PTR)hqEntInfo, mBuf) != ROK) + { + RGSCHINF_FREE_MSG(mBuf); + RETVALUE(RFAILED); + } + + pst->event = (Event) EVTINFHQENTRESET; + RETVALUE(SPstTsk(pst,mBuf)); +} + +/** +* @brief Request from SCH to MAC for resetting the harqentity +* +* @details +* +* Function : cmUnpkSchMacRstHqEntReq +* +* @param[in] Pst* pst +* @param[in] RgInfResetHqEnt *hqEntInfo +* @return S16 +* -# ROK +**/ +#ifdef ANSI +PUBLIC S16 cmUnpkSchMacRstHqEntReq +( +RstHqEntReq func, +Pst *pst, +Buffer *mBuf +) +#else +PUBLIC S16 cmUnpkSchMacRstHqEntReq(func, pst, mBuf) +RstHqEntReq func, +Pst *pst, +Buffer *mBuf +#endif +{ + RgInfResetHqEnt* hqEntRstInfo; + + TRC2(cmUnpkSchMacRstHqEntReq) + + if(cmUnpkPtr((PTR *)&hqEntRstInfo, mBuf) != ROK) + { + RGSCHINF_FREE_MSG(mBuf); + RETVALUE(RFAILED); + } + + RGSCHINF_FREE_MSG(mBuf); + RETVALUE((*func)(pst, hqEntRstInfo)); +} + +/** +* @brief Request from RLC to MAC for forwarding SDUs on + * dedicated channel for transmission. +* +* @details +* +* Function : cmPkSchMacRlsHqReq +* +* @param[in] Pst* pst +* @param[in] SpId spId +* @param[in] RguDDatReqInfo * datReq +* @return S16 +* -# ROK +**/ +#ifdef ANSI +PUBLIC S16 cmPkSchMacRlsHqReq +( +Pst* pst, +RgInfRlsHqInfo* sfHqInfo +) +#else +PUBLIC S16 cmPkSchMacRlsHqReq(pst, sfHqInfo) +Pst* pst; +RgInfRlsHqInfo* sfHqInfo; +#endif +{ + Buffer *mBuf = NULLP; + TRC2(cmPkSchMacRlsHqReq) + + if (SGetMsg(pst->region, pst->pool, &mBuf) != ROK) { + RETVALUE(RFAILED); + } + + if(cmPkPtr((PTR)sfHqInfo, mBuf) != ROK) + { + RGSCHINF_FREE_MSG(mBuf); + RETVALUE(RFAILED); + } + + pst->event = (Event) EVTINFRLSHQREQ; + RETVALUE(SPstTsk(pst,mBuf)); +} + +/** +* @brief Request from RLC to MAC for forwarding SDUs on + * dedicated channel for transmission. +* +* @details +* +* Function : cmUnpkSchMacRlsHqReq +* +* @param[in] Pst* pst +* @param[in] SpId spId +* @param[in] RguDDatReqInfo * datReq +* @return S16 +* -# ROK +**/ +#ifdef ANSI +PUBLIC S16 cmUnpkSchMacRlsHqReq +( +RlsHqReq func, +Pst *pst, +Buffer *mBuf +) +#else +PUBLIC S16 cmUnpkSchMacRlsHqReq(func, pst, mBuf) +RlsHqReq func; +Pst *pst; +Buffer *mBuf; +#endif +{ + RgInfRlsHqInfo* sfHqInfo; + + TRC2(cmUnpkSchMacRlsHqReq) + + if(cmUnpkPtr((PTR *)&sfHqInfo, mBuf) != ROK) + { + RGSCHINF_FREE_MSG(mBuf); + RETVALUE(RFAILED); + } + + RGSCHINF_FREE_MSG(mBuf); + RETVALUE((*func)(pst, sfHqInfo)); +} +/** +* @brief Request from RLC to MAC for forwarding SDUs on + * dedicated channel for transmission. +* +* @details +* +* Function : cmPkSchMacRlsRntiReq +* +* @param[in] Pst* pst +* @param[in] SpId spId +* @param[in] RguDDatReqInfo * datReq +* @return S16 +* -# ROK +**/ +#ifdef ANSI +PUBLIC S16 cmPkSchMacRlsRntiReq +( +Pst* pst, +RgInfRlsRnti* rlsRnti +) +#else +PUBLIC S16 cmPkSchMacRlsRntiReq(pst, rlsRnti) +Pst* pst; +RgInfRlsRnti* rlsRnti; +#endif +{ + Buffer *mBuf = NULLP; + TRC2(cmPkSchMacRlsRntiReq) + + if (SGetMsg(pst->region, pst->pool, &mBuf) != ROK) { + RETVALUE(RFAILED); + } + +#ifdef MS_MBUF_CORRUPTION + MS_BUF_ADD_ALLOC_CALLER(); +#endif + if(SAddPstMsgMult((Data *)rlsRnti, sizeof(RgInfRlsRnti), mBuf) != ROK) + { + RGSCHINF_FREE_MSG(mBuf); + RETVALUE(RFAILED); + } + + pst->event = (Event) EVTINFRLSRNTIREQ; + RETVALUE(SPstTsk(pst,mBuf)); +} + +/** +* @brief Request from RLC to MAC for forwarding SDUs on + * dedicated channel for transmission. +* +* @details +* +* Function : cmUnpkSchMacRlsRntiReq +* +* @param[in] Pst* pst +* @param[in] SpId spId +* @param[in] RguDDatReqInfo * datReq +* @return S16 +* -# ROK +**/ +#ifdef ANSI +PUBLIC S16 cmUnpkSchMacRlsRntiReq +( +RlsRntiReq func, +Pst *pst, +Buffer *mBuf +) +#else +PUBLIC S16 cmUnpkSchMacRlsRntiReq(func, pst, mBuf) +RlsRntiReq func; +Pst *pst; +Buffer *mBuf; +#endif +{ + RgInfRlsRnti rlsRnti; + + TRC2(cmUnpkSchMacRlsRntiReq) + + if(SRemPreMsgMult((Data *)&rlsRnti, sizeof(RgInfRlsRnti), mBuf) != ROK) + { + RGSCHINF_FREE_MSG(mBuf); + RETVALUE(RFAILED); + } + + RGSCHINF_FREE_MSG(mBuf); + RETVALUE((*func)(pst, &rlsRnti)); +} + +/** +* @brief Request from RLC to MAC for forwarding SDUs on + * dedicated channel for transmission. +* +* @details +* +* Function : cmPkSchMacCellRegReq +* +* @param[in] Pst* pst +* @param[in] SpId spId +* @param[in] RguDDatReqInfo * datReq +* @return S16 +* -# ROK +**/ +#ifdef ANSI +PUBLIC S16 cmPkSchMacCellRegReq +( +Pst* pst, +RgInfCellReg* regReq +) +#else +PUBLIC S16 cmPkSchMacCellRegReq(pst, regReq) +Pst* pst; +RgInfCellReg* regReq; +#endif +{ + Buffer *mBuf = NULLP; + TRC2(cmPkSchMacCellRegReq) + + if (SGetMsg(pst->region, pst->pool, &mBuf) != ROK) { + RETVALUE(RFAILED); + } + +#ifdef MS_MBUF_CORRUPTION + MS_BUF_ADD_ALLOC_CALLER(); +#endif + if(SAddPstMsgMult((Data *)regReq, sizeof(RgInfCellReg), mBuf) != ROK) + { + RGSCHINF_FREE_MSG(mBuf); + RETVALUE(RFAILED); + } + + pst->event = (Event) EVTINFCELLREGREQ; + RETVALUE(SPstTsk(pst,mBuf)); +} + +/** +* @brief Request from RLC to MAC for forwarding SDUs on + * dedicated channel for transmission. +* +* @details +* +* Function : cmUnpkSchMacCellRegReq +* +* @param[in] Pst* pst +* @param[in] SpId spId +* @param[in] RguDDatReqInfo * datReq +* @return S16 +* -# ROK +**/ +#ifdef ANSI +PUBLIC S16 cmUnpkSchMacCellRegReq +( +CellRegReq func, +Pst *pst, +Buffer *mBuf +) +#else +PUBLIC S16 cmUnpkSchMacCellRegReq(func, pst, mBuf) +CellRegReq func; +Pst *pst; +Buffer *mBuf; +#endif +{ + RgInfCellReg regReq; + + TRC2(cmUnpkSchMacCellRegReq) + + if(SRemPreMsgMult((Data *)®Req, sizeof(RgInfCellReg), mBuf) != ROK) + { + RGSCHINF_FREE_MSG(mBuf); + RETVALUE(RFAILED); + } + + RGSCHINF_FREE_MSG(mBuf); + RETVALUE((*func)(pst, ®Req)); +} + +/** +* @brief Primitive from SCH to MAC to register GBR LCG per UE +* +* @details +* +* Function : cmPkSchMacLcgRegReq +* +* @param[in] Pst* pst +* @param[in] RgInfLcgRegReq *lcgRegReq +* @return S16 +* -# ROK +**/ +#ifdef ANSI +PUBLIC S16 cmPkSchMacLcgRegReq +( +Pst* pst, +RgInfLcgRegReq *lcgRegReq +) +#else +PUBLIC S16 cmPkSchMacLcgRegReq(pst, lcgRegReq) +Pst* pst; +RgInfLcgRegReq *lcgRegReq; +#endif +{ + Buffer *mBuf = NULLP; + + TRC2(cmPkSchMacLcgRegReq) + + if (SGetMsg(pst->region, pst->pool, &mBuf) != ROK) { + RETVALUE(RFAILED); + } + + if(SAddPstMsgMult((Data *)lcgRegReq, sizeof(RgInfLcgRegReq), mBuf) != ROK) + { + RGSCHINF_FREE_MSG(mBuf); + RETVALUE(RFAILED); + } + + pst->event = (Event) EVTINFLCGREG; + RETVALUE(SPstTsk(pst,mBuf)); +} /* end of cmPkSchMacLcgRegReq */ + +/** +* @brief Primitive from SCH to MAC to register GBR LCG +* +* @details +* +* Function : cmUnpkSchMacLcgRegReq +* +* @param[in] LcgReg func +* @param[in] Pst* pst +* @param[in] Buffer *mBuf +* @return S16 +* -# ROK +**/ +#ifdef ANSI +PUBLIC S16 cmUnpkSchMacLcgRegReq +( +LcgReg func, +Pst *pst, +Buffer *mBuf +) +#else +PUBLIC S16 cmUnpkSchMacLcgRegReq(func, pst, mBuf) +LcgReg func; +Pst *pst; +Buffer *mBuf; +#endif +{ + RgInfLcgRegReq *lcgRegReq; + + TRC2(cmUnpkSchMacLcgRegReq) + + if(cmUnpkPtr((PTR *)&lcgRegReq, mBuf) != ROK) + { + RGSCHINF_FREE_MSG(mBuf); + RETVALUE(RFAILED); + } + + RGSCHINF_FREE_MSG(mBuf); + RETVALUE((*func)(pst, lcgRegReq)); +} /* end of cmUnpkSchMacLcgRegReq */ + +#ifdef LTEMAC_SPS + +/** +* @brief Primitive from SCH to MAC to register the set of SPS LCs per UE +* +* @details +* +* Function : cmPkSchMacSpsLcRegReq +* +* @param[in] Pst* pst +* @param[in] RgInfSpsLcInfo *lcInfo +* @return S16 +* -# ROK +**/ +#ifdef ANSI +PUBLIC S16 cmPkSchMacSpsLcRegReq +( +Pst* pst, +RgInfSpsLcInfo *lcInfo +) +#else +PUBLIC S16 cmPkSchMacSpsLcRegReq(pst, lcInfo) +Pst* pst; +RgInfSpsLcInfo *lcInfo; +#endif +{ + Buffer *mBuf = NULLP; + + TRC2(cmPkSchMacSpsLcRegReq) + + if (SGetMsg(pst->region, pst->pool, &mBuf) != ROK) { + RETVALUE(RFAILED); + } + + if(cmPkPtr((PTR)lcInfo, mBuf) != ROK) + { + RGSCHINF_FREE_MSG(mBuf); + RETVALUE(RFAILED); + } + + pst->event = (Event) EVTINFSPSLCREG; + RETVALUE(SPstTsk(pst,mBuf)); +} /* end of cmPkSchMacSpsLcRegReq */ + +/** +* @brief Primitive from SCH to MAC to reset SPS Params for the UE +* +* @details +* +* Function : cmPkSchMacUlSpsResetReq +* +* @param[in] Pst* pst +* @param[in] RgInfUlSpsReset *ulSpsResetInfo +* @return S16 +* -# ROK +**/ +#ifdef ANSI +PUBLIC S16 cmPkSchMacUlSpsResetReq +( +Pst* pst, +RgInfUlSpsReset *ulSpsResetInfo +) +#else +PUBLIC S16 cmPkSchMacUlSpsResetReq(pst, ulSpsResetInfo) +Pst* pst; +RgInfUlSpsReset *ulSpsResetInfo; +#endif +{ + Buffer *mBuf = NULLP; + + TRC2(cmPkSchMacUlSpsResetReq) + + if (SGetMsg(pst->region, pst->pool, &mBuf) != ROK) { + RETVALUE(RFAILED); + } + + if(cmPkPtr((PTR)ulSpsResetInfo, mBuf) != ROK) + { + RGSCHINF_FREE_MSG(mBuf); + RETVALUE(RFAILED); + } + + pst->event = (Event) EVTINFSPSRESET; + RETVALUE(SPstTsk(pst,mBuf)); +} /* end of cmPkSchMacUlSpsResetReq */ + +/** +* @brief Primitive from SCH to MAC to register the set of SPS LCs per UE +* +* @details +* +* Function : cmUnpkSchMacSpsLcRegReq +* +* @param[in] SpsLcReg func +* @param[in] Pst* pst +* @param[in] Buffer *mBuf +* @return S16 +* -# ROK +**/ +#ifdef ANSI +PUBLIC S16 cmUnpkSchMacSpsLcRegReq +( +SpsLcReg func, +Pst *pst, +Buffer *mBuf +) +#else +PUBLIC S16 cmUnpkSchMacSpsLcRegReq(func, pst, mBuf) +SpsLcReg func; +Pst *pst; +Buffer *mBuf; +#endif +{ + RgInfSpsLcInfo *lcInfo; + + TRC2(cmUnpkSchMacSpsLcRegReq) + + if(cmUnpkPtr((PTR *)&lcInfo, mBuf) != ROK) + { + RGSCHINF_FREE_MSG(mBuf); + RETVALUE(RFAILED); + } + + RGSCHINF_FREE_MSG(mBuf); + RETVALUE((*func)(pst, lcInfo)); +} /* end of cmUnpkSchMacSpsLcRegReq */ + + + +/** +* @brief Primitive from SCH to MAC to reset UL SPS params +* +* @details +* +* Function : cmUnpkSchMacUlSpsResetReq +* +* @param[in] UlSpsReset func +* @param[in] Pst* pst +* @param[in] Buffer *mBuf +* @return S16 +* -# ROK +**/ +#ifdef ANSI +PUBLIC S16 cmUnpkSchMacUlSpsResetReq +( +UlSpsReset func, +Pst *pst, +Buffer *mBuf +) +#else +PUBLIC S16 cmUnpkSchMacUlSpsResetReq(func, pst, mBuf) +UlSpsReset func; +Pst *pst; +Buffer *mBuf; +#endif +{ + RgInfUlSpsReset *ulSpsResetInfo; + + TRC2(cmUnpkSchMacUlSpsResetReq) + + if(cmUnpkPtr((PTR *)&ulSpsResetInfo, mBuf) != ROK) + { + RGSCHINF_FREE_MSG(mBuf); + RETVALUE(RFAILED); + } + + RGSCHINF_FREE_MSG(mBuf); + RETVALUE((*func)(pst, ulSpsResetInfo)); +} /* end of cmUnpkSchMacUlSpsResetReq */ + + + +/** +* @brief Primitive from SCH to MAC to deregister the set of SPS LCs per UE +* +* @details +* +* Function : cmPkSchMacSpsLcDeregReq +* +* @param[in] Pst* pst +* @param[in] CmLteCellId cellId, +* @param[in] CmLteRnti crnti +* @return S16 +* -# ROK +**/ +#ifdef ANSI +PUBLIC S16 cmPkSchMacSpsLcDeregReq +( +Pst* pst, +CmLteCellId cellId, +CmLteRnti crnti +) +#else +PUBLIC S16 cmPkSchMacSpsLcDeregReq(pst, cellId, crnti) +Pst* pst; +CmLteCellId cellId; +CmLteRnti crnti; +#endif +{ + Buffer *mBuf = NULLP; + + TRC2(cmPkSchMacSpsLcDeregReq) + + if (SGetMsg(pst->region, pst->pool, &mBuf) != ROK) { + RETVALUE(RFAILED); + } + + CMCHKPK(cmPkLteCellId, cellId, mBuf); + CMCHKPK(cmPkLteRnti, crnti, mBuf); + + pst->event = (Event) EVTINFSPSLCDEREG; + RETVALUE(SPstTsk(pst,mBuf)); +} /* end of cmPkSchMacSpsLcDeregReq */ + +/** +* @brief Primitive from SCH to MAC to deregister the set of SPS LCs per UE +* +* @details +* +* Function : cmUnpkSchMacSpsLcDeregReq +* +* @param[in] SpsLcDereg func +* @param[in] Pst* pst +* @param[in] Buffer *mBuf +* @return S16 +* -# ROK +**/ +#ifdef ANSI +PUBLIC S16 cmUnpkSchMacSpsLcDeregReq +( +SpsLcDereg func, +Pst *pst, +Buffer *mBuf +) +#else +PUBLIC S16 cmUnpkSchMacSpsLcDeregReq(func, pst, mBuf) +SpsLcDereg func; +Pst *pst; +Buffer *mBuf; +#endif +{ + CmLteCellId cellId; + CmLteRnti crnti; + + TRC2(cmUnpkSchMacSpsLcDeregReq) + + CMCHKUNPK(cmUnpkLteRnti, &crnti, mBuf); + CMCHKUNPK(cmUnpkLteCellId, &cellId, mBuf); + + RGSCHINF_FREE_MSG(mBuf); + RETVALUE((*func)(pst, cellId, crnti)); +} /* end of cmUnpkSchMacSpsLcDeregReq */ + +#endif /* LTEMAC_SPS */ +#ifdef LTE_L2_MEAS + +/** +* @brief Primitive from SCH to MAC for L2 Measurement +* +* @details +* +* Function : cmPkSchMacL2MeasReq +* +* @param[in] Pst* pst +* @param[in] RgInfSpsLcInfo *lcInfo +* @return S16 +* -# ROK +**/ +#ifdef ANSI +PUBLIC S16 cmPkSchMacL2MeasReq +( +Pst* pst, +RgInfL2MeasReq *measInfo +) +#else +PUBLIC S16 cmPkSchMacL2MeasReq(pst, measInfo) +Pst* pst; +RgInfL2MeasReq *measInfo; +#endif +{ + Buffer *mBuf = NULLP; + + TRC2(cmPkSchMacL2MeasReq) + + if (SGetMsg(pst->region, pst->pool, &mBuf) != ROK) { + RETVALUE(RFAILED); + } + if(SAddPstMsgMult((Data *)measInfo, sizeof(RgInfL2MeasReq), mBuf) != ROK) + { + RGSCHINF_FREE_MSG(mBuf); + RETVALUE(RFAILED); + } + + pst->event = (Event) EVTINFL2MEASREQ; + RETVALUE(SPstTsk(pst,mBuf)); +} /* end of cmPkSchMacL2MeasReq */ + +/** +* @brief Primitive from SCH to MAC for L2 Stop Measurement +* +* @details +* +* Function : cmPkSchMacL2MeasStopReq +* +* @param[in] Pst* pst +* @param[in] RgInfSpsLcInfo *lcInfo +* @return S16 +* -# ROK +**/ +#ifdef ANSI +PUBLIC S16 cmPkSchMacL2MeasStopReq +( +Pst* pst, +RgInfL2MeasStopReq *measInfo +) +#else +PUBLIC S16 cmPkSchMacL2MeasStopReq(pst, measInfo) +Pst* pst; +RgInfL2MeasStopReq *measInfo; +#endif +{ + Buffer *mBuf = NULLP; + + TRC2(cmPkSchMacL2MeasStopReq) + + if (SGetMsg(pst->region, pst->pool, &mBuf) != ROK) { + RETVALUE(RFAILED); + } + if(SAddPstMsgMult((Data *)measInfo, sizeof(RgInfL2MeasStopReq), mBuf) != ROK) + { + SPutMsg(mBuf); + RETVALUE(RFAILED); + } + + pst->event = (Event) EVTINFL2MEASSTOPREQ; + RETVALUE(SPstTsk(pst,mBuf)); +} /* end of cmPkSchMacL2MeasStopReq */ +/** +* @brief Primitive from SCH to MAC for L2 Measurement +* Send Request +* @details +* +* Function : cmPkSchMacL2MeasSendReq +* +* @param[in] Pst* pst +* @param[in] RgInfSpsLcInfo *lcInfo +* @return S16 +* -# ROK +**/ +#ifdef ANSI +PUBLIC S16 cmPkSchMacL2MeasSendReq +( +Pst* pst, +RgInfL2MeasSndReq *measInfo +) +#else +PUBLIC S16 cmPkSchMacL2MeasSendReq(pst, measInfo) +Pst* pst; +RgInfL2MeasSndReq *measInfo; +#endif +{ + Buffer *mBuf = NULLP; + + TRC2(cmPkSchMacL2MeasSendReq) + if (SGetMsg(pst->region, pst->pool, &mBuf) != ROK) { + RETVALUE(RFAILED); + } + + if(SAddPstMsgMult((Data *)measInfo, sizeof(RgInfL2MeasSndReq), mBuf) != ROK) + { + SPutMsg(mBuf); + RETVALUE(RFAILED); + } + + pst->event = (Event) EVTINFL2MEASSENDREQ; + RETVALUE(SPstTsk(pst,mBuf)); +} /* end of cmPkSchMacL2MeasSendReq */ + +/** +* @brief Primitive from SCH to MAC for L2 Measurement request +* +* @details +* +* Function : cmUnpkSchMacL2MeasReq +* +* @param[in] L2MeasReg func +* @param[in] Pst* pst +* @param[in] Buffer *mBuf +* @return S16 +* -# ROK +**/ +#ifdef ANSI +PUBLIC S16 cmUnpkSchMacL2MeasReq +( +L2MeasReq func, +Pst *pst, +Buffer *mBuf +) +#else +PUBLIC S16 cmUnpkSchMacL2MeasReq(func, pst, mBuf) +L2MeasReq func; +Pst *pst; +Buffer *mBuf; +#endif +{ + RgInfL2MeasReq measInfo; + + TRC2(cmUnpkSchMacL2MeasReq) + + if(SRemPreMsgMult((Data *)&measInfo, sizeof(RgInfL2MeasReq), mBuf) != ROK) + { + RGSCHINF_FREE_MSG(mBuf); + RETVALUE(RFAILED); + } + + RGSCHINF_FREE_MSG(mBuf); + RETVALUE((*func)(pst, &measInfo)); +} /* end of cmUnpkSchMacL2MeasReq */ + +/** +* @brief Primitive from SCH to MAC for L2 Measurement Stop request +* +* @details +* +* Function : cmUnpkSchMacL2MeasStopReq +* +* @param[in] L2MeasReg func +* @param[in] Pst* pst +* @param[in] Buffer *mBuf +* @return S16 +* -# ROK +**/ +#ifdef ANSI +PUBLIC S16 cmUnpkSchMacL2MeasStopReq +( +L2MeasStopReq func, +Pst *pst, +Buffer *mBuf +) +#else +PUBLIC S16 cmUnpkSchMacL2MeasStopReq(func, pst, mBuf) +L2MeasStopReq func; +Pst *pst; +Buffer *mBuf; +#endif +{ + RgInfL2MeasStopReq measInfo; + + TRC2(cmUnpkSchMacL2MeasStopReq) + if(SRemPreMsgMult((Data *)&measInfo, sizeof(RgInfL2MeasStopReq), mBuf) != ROK) + { + SPutMsg(mBuf); + RETVALUE(RFAILED); + } + + SPutMsg(mBuf); + RETVALUE((*func)(pst, &measInfo)); +} /* end of cmUnpkSchMacL2MeasReq */ +/** +* @brief Primitive from SCH to MAC for L2 Measurement request +* +* @details +* +* Function : cmUnpkSchMacL2MeasReq +* +* @param[in] L2MeasReg func +* @param[in] Pst* pst +* @param[in] Buffer *mBuf +* @return S16 +* -# ROK +**/ +#ifdef ANSI +PUBLIC S16 cmUnpkSchMacL2MeasSendReq +( +L2MeasSendReq func, +Pst *pst, +Buffer *mBuf +) +#else +PUBLIC S16 cmUnpkSchMacL2MeasSendReq(func, pst, mBuf) +L2MeasSendReq func; +Pst *pst; +Buffer *mBuf; +#endif +{ + RgInfL2MeasSndReq measInfo; + + TRC2(cmUnpkSchMacL2MeasSendReq) + if(SRemPreMsgMult((Data *)&measInfo, sizeof(RgInfL2MeasSndReq), mBuf) != ROK) + { + SPutMsg(mBuf); + RETVALUE(RFAILED); + } + + SPutMsg(mBuf); + RETVALUE((*func)(pst, &measInfo)); +} /* end of cmUnpkSchMacL2MeasSendReq*/ + +/** +* @brief Primitive from MAC to SCH for L2 Measurement +* +* @details +* +* Function : cmPkMacSchL2MeasCfm +* +* @param[in] Pst* pst +* @param[in] RgInfL2MeasCfm *measInfo +* @return S16 +* -# ROK +**/ +#ifdef ANSI +PUBLIC S16 cmPkMacSchL2MeasCfm +( +Pst* pst, +RgInfL2MeasCfm *measCfm +) +#else +PUBLIC S16 cmPkMacSchL2MeasCfm(pst, measCfm) +Pst* pst; +RgInfL2MeasCfm *measCfm; +#endif +{ + Buffer *mBuf = NULLP; + + TRC2(cmPkMacSchL2MeasCfm) + + if (SGetMsg(pst->region, pst->pool, &mBuf) != ROK) { + RETVALUE(RFAILED); + } + + if(SAddPstMsgMult((Data *)measCfm, sizeof(RgInfL2MeasCfm), mBuf) != ROK) + { + RGSCHINF_FREE_MSG(mBuf); + RETVALUE(RFAILED); + } + + pst->event = (Event) EVTINFL2MEASCFM; + RETVALUE(SPstTsk(pst,mBuf)); +} /* end of cmPkMacSchL2MeasCfm */ + + +/** +* @brief Primitive from MAC to SCH for L2 Measurement +* stop cfm +* @details +* +* Function : cmPkMacSchL2MeasStopCfm +* +* @param[in] Pst* pst +* @param[in] RgInfL2MeasCfm *measInfo +* @return S16 +* -# ROK +**/ +#ifdef ANSI +PUBLIC S16 cmPkMacSchL2MeasStopCfm +( +Pst* pst, +RgInfL2MeasCfm *measCfm +) +#else +PUBLIC S16 cmPkMacSchL2MeasStopCfm(pst, measCfm) +Pst* pst; +RgInfL2MeasCfm *measCfm; +#endif +{ + Buffer *mBuf = NULLP; + + TRC2(cmPkMacSchL2MeasStopCfm) + if (SGetMsg(pst->region, pst->pool, &mBuf) != ROK) { + RETVALUE(RFAILED); + } + + if(SAddPstMsgMult((Data *)measCfm, sizeof(RgInfL2MeasCfm), mBuf) != ROK) + { + SPutMsg(mBuf); + RETVALUE(RFAILED); + } + + pst->event = (Event) EVTINFL2MEASSTOPCFM; + RETVALUE(SPstTsk(pst,mBuf)); +}/*cmPkMacSchL2MeasStopCfm*/ +/** +* @brief Primitive from MAC to SCH for L2 Measurement Cfm +* +* @details +* +* Function : cmUnpkSchMacL2MeasReq +* +* @param[in] L2MeasCfm func +* @param[in] Pst* pst +* @param[in] Buffer *mBuf +* @return S16 +* -# ROK +**/ +#ifdef ANSI +PUBLIC S16 cmUnpkMacSchL2MeasCfm +( +L2MeasCfm func, +Pst *pst, +Buffer *mBuf +) +#else +PUBLIC S16 cmUnpkMacSchL2MeasCfm(func, pst, mBuf) +L2MeasCfm func; +Pst *pst; +Buffer *mBuf; +#endif +{ + RgInfL2MeasCfm measCfm; + + TRC2(cmUnpkMacSchL2MeasCfm) + + if(SRemPreMsgMult((Data *)&measCfm, sizeof(RgInfL2MeasCfm), mBuf) != ROK) + { + RGSCHINF_FREE_MSG(mBuf); + RETVALUE(RFAILED); + } + + RGSCHINF_FREE_MSG(mBuf); + RETVALUE((*func)(pst, &measCfm)); +} /* end of cmUnpkMacSchL2MeasCfm */ + +/** +* @brief Primitive from MAC to SCH for L2 Measurement Stop Cfm +* +* @details +* +* Function : cmUnpkMacSchL2MeasStopCfm +* +* @param[in] L2MeasCfm func +* @param[in] Pst* pst +* @param[in] Buffer *mBuf +* @return S16 +* -# ROK +**/ +#ifdef ANSI +PUBLIC S16 cmUnpkMacSchL2MeasStopCfm +( +L2MeasCfm func, +Pst *pst, +Buffer *mBuf +) +#else +PUBLIC S16 cmUnpkMacSchL2MeasStopCfm(func, pst, mBuf) +L2MeasCfm func; +Pst *pst; +Buffer *mBuf; +#endif +{ +RgInfL2MeasCfm measCfm; + + TRC2(cmUnpkMacSchL2MeasStopCfm) + + if(SRemPreMsgMult((Data *)&measCfm, sizeof(RgInfL2MeasCfm), mBuf) != ROK) + { + SPutMsg(mBuf); + RETVALUE(RFAILED); + } + + SPutMsg(mBuf); + RETVALUE((*func)(pst, &measCfm)); +} /* end of cmUnpkMacSchL2MeasStopCfm */ + +#endif/* LTE_L2_MEAS */ + +#endif + + +/********************************************************************** + + End of file +**********************************************************************/ diff --git a/src/5gnrmac/rg_sch_inf.h b/src/5gnrmac/rg_sch_inf.h new file mode 100755 index 000000000..8c3d7d2cb --- /dev/null +++ b/src/5gnrmac/rg_sch_inf.h @@ -0,0 +1,102 @@ +/******************************************************************************* +################################################################################ +# Copyright (c) [2017-2019] [Radisys] # +# # +# 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. # +################################################################################ +*******************************************************************************/ + +/********************************************************************** + Name: Scheduler interface - RG_SCH_INF + + Type: C header file + + Desc: Constants needed for interface + + File: rg_sch_inf.h + +*********************************************************************21*/ + +#ifndef __GKSCH_H__ +#define __GKSCH_H__ + +/* Operation type for Harq Rls Req */ + +#define RGINF_RLS_HQ_NO_ACTION 0x00 +#define RGINF_RLS_HQ_SAVE_TB 0x01 +#define RGINF_RLS_HQ_DEL_TB 0x02 + +/*5g_NR RGU_MAX_LC has been reduced to 10 to 4*/ +#define RGINF_MAX_NUM_DED_LC 4 +#define RGINF_MAX_TB_PER_UE 2 +#define RGINF_MAX_NUM_UE_PER_TTI 1 +#define RGINF_MAX_LCG_PER_UE 4 +/* RRM_SP1_START */ +#define RGINF_MAX_GBR_QCI_REPORTS 4 +/* RRM_SP1_END */ +#define RGINF_BCH_INFO (1<<0) +#define RGINF_BCCH_INFO (1<<1) +#define RGINF_PCCH_INFO (1<<2) +#ifdef EMTC_ENABLE +#define RGINF_EMTC_BCCH_INFO (1<<3) +#define RGINF_EMTC_PCCH_INFO (1<<4) +#endif +/* Event corresponding to each primitive at this interface */ +/* SCH interface events values startes from 1 and max up to 49 because 50 + onwards is used between MAC-MAC interface*/ +#define EVTINFCELLREGREQ 1 +#define EVTINFSFALLOCREQ 2 +#define EVTINFRLSHQREQ 3 +#define EVTINFRLSRNTIREQ 4 +#define EVTINFDEDBOUPDTREQ 5 +#define EVTINFCMNBOUPDTREQ 6 +#define EVTINFSFRECPIND 7 +/* Added support for SPS*/ +#ifdef LTEMAC_SPS +#define EVTINFSPSLCREG 8 +#define EVTINFSPSLCDEREG 9 +#define EVTINFSPSRELIND 10 +#define EVTINFSPSRESET 18 +#endif /* LTEMAC_SPS */ + +#ifdef LTE_L2_MEAS +#define EVTINFL2MEASREQ 11 +#define EVTINFL2MEASCFM 12 +/*Added for radisys oam*/ +#define EVTINFL2MEASSENDREQ 14 +#define EVTINFL2MEASSTOPREQ 15 +#define EVTINFL2MEASSTOPCFM 16 +#endif +/*Fix: Inform UE delete to scheduler*/ +#define EVTINFUEDELIND 13 + +#define EVTINFLCGREG 17 + +#ifdef LTE_ADV +#define EVTINFHQENTRESET 19 +#endif + +#define RGSCHINF_FREE_MSG(_buf)\ +{\ + if (NULLP != (_buf)) \ + { \ + SPutMsg((_buf)); \ + _buf = NULLP; \ + } \ +} +#endif /* __GKSCH_H__ */ + +/********************************************************************30** + + End of file +**********************************************************************/ diff --git a/src/5gnrmac/rg_sch_inf.x b/src/5gnrmac/rg_sch_inf.x new file mode 100755 index 000000000..b64067ac1 --- /dev/null +++ b/src/5gnrmac/rg_sch_inf.x @@ -0,0 +1,1450 @@ +/******************************************************************************* +################################################################################ +# Copyright (c) [2017-2019] [Radisys] # +# # +# 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. # +################################################################################ +*******************************************************************************/ + +/********************************************************************** + + Name: LTE-MAC layer + + Type: C Include File + + Desc: Structures, variables, and typedefs required by the interface between + MAC and Scheduler. + + File: rg_sch_inf.x + +**********************************************************************/ +/** + @file rg_sch_inf.x + @brief Structure declarations and definitions for MAC-SCH interface. + */ + +#ifndef __GKSCH_X__ +#define __GKSCH_X__ + +#ifdef __cplusplus +extern "C" { +#endif +#ifdef EMTC_ENABLE +/** + * @brief This structure contains the uplink grant information that is sent in + response to the random access request from the UE for CEmodeA. + */ +typedef struct rgInfEmtcCEmodeARarUlGrt +{ + U8 msg3PUSCHNbIdx; /*!< Indicates the Msg3 PUSCH narrowband index. */ + U8 rbStart; /*!< Start Resource block of allocation. */ + U8 numRb; /*!< Number of resource blocks allocated. */ + U8 msg3PUSCHNumRep; /*!< Number of repetitions for Msg3 PUSCH. */ + U8 iMcsCrnt; /*!< Current MCS index of the grant. */ + U8 tpc; /*!< TPC command for the uplink grant. */ + U8 cqiBit; /*!< Indicates the CQI is enabled or not. */ + U8 delayBit; /*!< Indicates the Delay bit. */ + U8 msg34MPDCCHNbIdx; /*!< Indicates Msg3/4 MPDCCH narrowband index. */ +} RgInfEmtcCEmodeARarUlGrnt; + +/** + * @brief This structure contains the uplink grant information that is sent in + response to the random access request from the UE for CEmodeB. + */ +typedef struct rgInfEmtcCEmodeBRarUlGrnt +{ + U8 msg3PUSCHNbIdx; /*!< Indicates the Msg3 PUSCH narrowband index. */ + U8 rbStart; /*!< Start Resource block of allocation. */ + U8 numRb; /*!< Number of resource blocks allocated. */ + U8 msg3PUSCHNumRep; /*!< Number of repetitions for Msg3 PUSCH. */ + U8 iTbsCrnt; /*!< Current TBS index of the grant. */ + U8 msg34MPDCCHNbIdx; /*!< Indicates Msg3/4 MPDCCH narrowband index. */ +}RgInfEmtcCEmodeBRarUlGrnt; + +typedef enum rgEmtcCEmodeType +{ + RG_EMTC_CEMODE_A, + RG_EMTC_CEMODE_B, + RG_EMTC_CEMODE_INV +}RgEmtcCEmodeType; + +/** + * @brief This structure contains the uplink grant information that is sent in + response to the random access request from the UE for EMTC. + */ +typedef struct rgInfEmtcRarUlGrnt +{ + U8 rgEmtcCEmodeType; + union + { + RgInfEmtcCEmodeARarUlGrnt emtcCEmodeARarUlGrnt; + RgInfEmtcCEmodeBRarUlGrnt emtcCEmodeBRarUlGrnt; + }u; +}RgInfEmtcRarUlGrnt; + +#endif /* EMTC_ENABLE */ +/** + * @brief This structure contains common channel buffer occupancy report information. + */ +typedef struct rgInfCmnBoRpt +{ + S16 cellSapId; + CmLteCellId cellId; /*!< Identifies the cell. CellId value must be within the set of configured cell IDs. */ + CmLteLcId lcId; /*!< Identifies the logical channel. lcId value range is defined in + Section 6.2.1 in 36.321 specification. */ + CmLteLcType lcType; /*!< Identifies the Logical channel type.lcType can take the following values: + CM_LTE_LCH_BCCH + CM_LTE_LCH_PCCH + CM_LTE_LCH_CCCH + CM_LTE_LCH_DCCH + CM_LTE_LCH_DTCH */ + S32 bo; /*!< Buffer occupancy reported by RLC in bytes. */ +#ifdef EMTC_ENABLE + U8 emtcDIReason; /*!< Reason for DI message to send. */ + U8 pnb; /*!< Pagging narrowBand on which Ue perfom paging reception*/ +#endif + union /*!< lcType in the primitive is the union selector. */ + { + CmLteTimingInfo timeToTx; /*!< Timing info for the BO, applicable for BCCH and PCCH. */ + CmLteRnti rnti; /*!< Temporary C-RNTI, only for CCCH. RNTI range is specified + in Section 7.1 in 36.321 specification. */ + } u; +} RgInfCmnBoRpt; +/** + * @brief This structure contains dedicated channel buffer occupancy report + * information. + */ +typedef struct rgInfDedBoRpt +{ + S16 cellSapId; /*!< Identifies the cell SAP. cellSapId value must be within the set of configured cell SAP IDs. */ + CmLteCellId cellId; /*!< Identifies the cell. CellId value must be within the set of configured cellIds. */ + CmLteRnti rnti; /*!< Identifies the UE. RNTI value range is specified in Section 7.1 in 25.321 specification. */ + CmLteLcId lcId; /*!< Identifies the logical channel. lcId value range is defined in Section 6.2.1 in 36.321 specification. */ + S32 bo; /*!< Number of bytes reported as Buffer occupancy by RLC. */ +#ifdef CCPU_OPT + Bool staPduPrsnt; /*!< Is status PDU present reported by RLC. */ + U16 estRlcHdrSz;/*!< Estimated hader size reported by RLC */ +#endif + U32 staPduBo; /*!< Number of bytes reported as Buffer occupancy for status PDU by RLC. + This is already included in BO.*/ + U32 oldestSduArrTime; /*!< Oldest SDU Arrival Time from Upper Layer */ + Bool setMaxUlPrio; /*!< set when Pollbit is set from RLC in PDU */ + Bool setMaxDlPrio; /*!< Set when there is a status PDU in the DL*/ +} RgInfDedBoRpt; + +/*Fix: start: Indicate UE deletion from MAC to Scheduler*/ +/** + * @brief This structure contains the RNTI which is deleted at MAC + * information. + */ +typedef struct rgInfUeDelInd +{ + S16 cellSapId; /*!< Identifies the cell SAP. cellSapId value must be within the set of configured cell SAP IDs. */ + CmLteCellId cellId; /*!< Identifies the cell. CellId value must be within the set of configured cellIds. */ + CmLteRnti rnti; /*!< Identifies the UE. RNTI value range is specified in Section 7.1 in 25.321 specification. */ +} RgInfUeDelInd; + +/*Fix: end: Indicate UE deletion from MAC to Scheduler*/ + + + +/** + * @brief This structure contains the uplink grant information that is sent in + response to the random access request from the UE. + */ +typedef struct rgInfRarUlGrnt +{ +#ifndef MAC_5GTF_UPDATE + U8 hop; /*!< Indicates the hopping flag. */ +#else + U8 xPuschRange; /*!< xPUSCH range */ +#endif + U8 rbStart; /*!< Start Resource block of allocation. */ + U8 numRb; /*!< Number of resource blocks allocated. */ + U8 tpc; /*!< TPC command for the uplink grant. */ + U8 iMcsCrnt; /*!< Current MCS index of the grant. */ + U8 delayBit; /*!< Indicates the Delay bit. */ +#ifndef MAC_5GTF_UPDATE + U8 cqiBit; /*!< Indicates the CQI is enabled or not. */ +#else + U8 numBsiRep; /*!< Number of BSI reports. */ + U8 bsiBetaOffIdx; /*!< Index of BSI beta offset used in Msg3 */ + U8 pcrs; /*!< UL dual PCRS */ +#endif +} RgInfRarUlGrnt; + +/** + * @brief This structure carries timing adjustment, uplink grant information for the specific temporary C-RNTI. + */ +typedef struct rgInfCrntiInfo +{ + CmLteRnti tmpCrnti; /*!< Temporary C-RNTI. RNTI range is specified in Section 7.1 in 36.321 specification. */ + U8 rapId; /*!< rapId identifies the index of the Random Access Preamble. rapId ranges from 0 to 63.*/ + TknU16 ta; /*!< Timing Adjustment. Timing Adjustment Value range is defined in Section 6.1.3.5 in 36.321 specification. */ + RgInfRarUlGrnt grnt; /*!< Uplink Grant to go in RAR. */ + Bool isContFree; /*!< Indicates whether the procedure is contention-free or not. */ +#ifdef EMTC_ENABLE + RgInfEmtcRarUlGrnt emtcGrnt; /*!< Uplink grant for EMTC UE to go in RAR. */ +#endif +}RgInfCrntiInfo; + +/** + * @brief This structure carries information about downlink control format, scheduled TB size, + backoff indicator value, and the set of Random Access Responses within this RA-RNTI. +*/ +typedef struct rgInfRaRntiInfo +{ + U16 raRnti; /*!< RA-RNTI. RNTI range is specified in Section 7.1 in 36.321 specification. */ + TfuPdschDciInfo dciInfo; /*!< PDCCH allocated for RA-RNTI. For more information + refer to TFU Interface Service Definition (p/n 1100091). */ + U32 schdTbSz; /*!< Scheduled TB size. schdTbSz value range is defined in Section 7.1.7.2.1 in 36.213 + specification. */ + TknU8 backOffInd; /*!< Indicates the Backoff Indicator value. backOffInd value range + is defined in Section 7.2 in 36.321 specification. */ + U8 numCrnti; /*!< Number of valid RARs in the array. */ + RgInfCrntiInfo *crntiInfo; /*!< RAR information. */ +}RgInfRaRntiInfo; + +/** + * @brief This structure contains information about the RA-RNTIs for which + * random access responses are generated. + */ +typedef struct rgInfRarInfo +{ + U8 numRaRntis; /*!< Indicates the number of valid RA-RNTIs present. */ + RgInfRaRntiInfo *raRntiInfo; /*!< Contains allocation information per RA-RNTI. */ + U16 txPwrOffset; /*!< PDSCH tx power offset for RAR transmission */ +}RgInfRarInfo; + +/** + * @brief Logical channel allocation information. + */ +typedef struct rgInfLcDatInfo +{ + CmLList lchLstEnt; /*!< Is not used when part of resource allocation. */ + U8 lcId; /*!< Identifies the logical channel. lcId value range is defined + in Section 6.2.1 in 36.321 specification. */ + U32 numBytes; /*!< Number of bytes allocated/received to logical channel. */ +} RgInfLcDatInfo; + +/** + * @brief This structure contains control element information received from a + * particular UE.Extended PHR information + */ +typedef struct rgInfExtPhrSCellInfo +{ + U8 sCellIdx; /*!< SCELL index for which PHR is reported */ + U8 phr; /*!< PHR value. PHR value is defined in Section 6.1.3.6a in 36.321 specification. */ + U8 pCmax; /*!< PCMAX value. PCMAX value is defined in Table 6.1.3.6a-1 in 36.321 specification. */ + U8 pBackOff; /*!< If UE applied back off due to P-MPRc in 36.321 specification. */ +}RgInfExtPhrSCellInfo; +typedef struct rgInfExtPhrCEInfo +{ + U8 type2Phr; /*!< PHR value. PHR value is defined in Section 6.1.3.6a in 36.321 specification. */ + U8 type2PCMax; /*!< PCMAX value. PCMAX value is defined in Table 6.1.3.6a-1 in 36.321 specification. */ + U8 numServCells; /*!< Number of serving cells for which PHR is reported */ + RgInfExtPhrSCellInfo servCellPhr[CM_LTE_MAX_CELLS]; +}RgInfExtPhrCEInfo; /*!< EXT PHR value. EXT PHR value is defined in Section 6.1.3.6a in 36.321 R10 specification. */ + +/** + * @brief This structure contains control element information received from a + * particular UE. + */ +typedef struct rgInfCeInfo +{ + U16 bitMask; /*!< Bitmask for the MAC Control elements present. */ + struct + { + U16 cRnti; /*!< C-RNTI value. RNTI range is specified in Section 7.1 in 36.321 specification. */ + U8 phr; /*!< PHR value. PHR value is defined in Section 6.1.3.6 in 36.321 specification. */ + union + { + U8 truncBsr; /*!< Truncated BSR value. BSR value is defined in + Section 6.1.3.1 in 36.321 specification. */ + U8 shortBsr; /*!< Short BSR value.BSR value is defined in + Section 6.1.3.1 in 36.321 specification. */ + struct + { + U8 bs1; /*!< Buffer size 1 of long BSR. */ + U8 bs2; /*!< Buffer size 2 of long BSR. */ + U8 bs3; /*!< Buffer size 3 of long BSR. */ + U8 bs4; /*!< Buffer size 4 of long BSR. */ + }longBsr; /*!< BSR value is defined in Section 6.1.3.1 in 36.321 specification. */ + }bsr; + RgInfExtPhrCEInfo extPhr; /*!< EXT PHR value. EXT PHR value is defined in Section 6.1.3.6a in 36.321 R10 specification. */ +#ifdef MAC_5GTF_UPDATE + struct + { + U8 bar; /*!< Beam Adjusment Request */ + U8 numBsiFields; /*!< Number of BSI fields UE sent in BSI Feedback */ + struct + { + U16 bi; /*!< BSI Feedback : 9 bits Beam Index */ + U8 brsrp; /*!< BSI Feedback :7 bits BRSRP */ + }bsiFdbk[4]; + }beam; +#endif + } ces; + /* L2_COUNTERS */ +#ifdef LTE_L2_MEAS + U8 ulActLCs[RGINF_MAX_NUM_DED_LC]; + /*!< List of LCs for which Data is received in UL */ +#endif + + +#ifdef LTEMAC_SPS + U16 spsSduSize; +#endif + +} RgInfCeInfo; + +typedef struct rgInfLcgInfo +{ + U8 lcgId; /*!< LCGID. GBR DRB LCG */ + U32 bytesRcvd; /*!< Contains bytes received for LCG */ +}RgInfLcgInfo; + +/** + * @brief This structure contains control element information received from a + * particular UE identified by the RNTI. + */ +typedef struct rgInfUeDatInd +{ + CmLteRnti rnti; /*!< RNTI. RNTI range is specified in Section 7.1 in 36.321 specification. */ + CmLList ueLstEnt; /*!< UE linked list entry. */ + RgInfCeInfo ceInfo; /*!< Contains the control elements received from the UE. */ + RgInfLcgInfo lcgInfo[RGINF_MAX_LCG_PER_UE - 1]; /*!< Contains the bytes received per DRB LCG. */ +}RgInfUeDatInd; + +/** + * @brief This structure carries the control element information received for a + set of UEs along with timing information. + */ +typedef struct rgInfSfDatInd +{ + CmMemListCp memCp; /*!< Memory control point. */ + CmLListCp ueLst; /*!< Pointer to the UE linked list. */ + /* RRM_SP1_START */ + U32 qcisUlPrbCnt[RGINF_MAX_GBR_QCI_REPORTS];/*!< UL gbr LC's PRB count*/ + /* RRM_SP1_END */ + S16 cellSapId; /*!< Cell SAP Identifier. CellSAP ID value must be within the set of configured cell SAP IDs. */ + CmLteCellId cellId; /*!< Identifies the cell. CellId must be within the set of configured cell IDs. */ + CmLteTimingInfo timingInfo; /*!< Contains information about SFN and subframe. SFN ranges from 0 to 1023 whereas subframe ranges from 0 to 9. */ +}RgInfSfDatInd; + +/** + * @brief This structure carries the information about scheduled logical + * channels within this transport block along with timing adjustment + * information. + */ +typedef struct rgInfUeTbInfo +{ + Bool disTb; /*!< Currently, not used, but is + applicable in MIMO case. */ + Bool isReTx; /*!< Indicates the TB transmission type. */ + TknU8 ta; /*!< Timing Adjustment. */ +#ifdef LTE_ADV + TknU8 sCellActCe; /* !< SCell Act values and whether + scheduled or not */ +#endif + + /* Changed as a result of CR timer implementation*/ + U8 contResCe; /*!< Indicating presence of Contention Resolution CE across MAC-SCH + interface to + * identify CCCH SDU transmissions which need to + * be done without the + * contention resolution CE.*/ + + U8 numSchLch; /*!< Indicates the number of logical + channels scheduled. */ + U32 schdTbSz; + RgInfLcDatInfo schdDat[RGINF_MAX_NUM_DED_LC]; /*!< Contains + information about scheduled logical + channel. */ +} RgInfUeTbInfo; + +/** + @brief This structure carries the information reagarding secondary MAC like its + instance Id and HARQ process's Id + */ +typedef struct rgLaaTbReqInfo +{ + U8 sMacInstId; + U8 sCellHqPId; + U8 tbId; + U16 hqPStamp; +}RgLaaTbReqInfo; + +/** + * @brief This structure carries the UE-specific Resource allocation + * information like RNTI, downlink control format, HARQ process Identifier, + * scheduled TB size, and Transport Block information. + */ +typedef struct rgInfUeAlloc +{ + CmLteRnti rnti; /*!< RNTI. RNTI range is specified in Section 7.1 in 36.321 specification. */ + +/* Added support for SPS*/ +#ifdef LTEMAC_SPS + CmLteRnti pdcchRnti; /*!< RNTI used for PDCCH scrambling */ +#endif + + + + TfuPdschDciInfo dciInfo; /*!< Contains Downlink Control Information. For more information, + refer to TFU Interface Service Definition (p/n 1100091). */ + U8 hqProcId; /*!< HARQ process Identifier. hqProcId ranges between 1 and 8 for FDD mode and 1 and 15 for TDD mode */ + S8 tbStrtIdx; + TknU32 doa; + TfuTxMode txMode; + Bool puschRptUsd;/*!< True, if Precoding Information in PDCCH has to be + in-accordance with the latest PUSCH report */ + TfuDlCqiPuschInfo puschPmiInfo;/*!< PUSCH report details for explicit PMI + * information to PHY during a PDSCH */ + + + U8 nmbOfTBs; /*!< Indicates the number of TBs. Currently this is set to 1. */ + RgInfUeTbInfo tbInfo[RGINF_MAX_TB_PER_UE]; /*!< Contains TB identifier. */ + /* LTE_ADV_FLAG_REMOVED_START */ +#ifdef TFU_UPGRADE + U8 pa; /*!< DL Power control paramter P_A + configured by higher layers + Ref: RRC 36.331, 6.3.2, PDSCH-Config */ +#endif + U8 isEnbSFR; /*To check if SFR is enabled*/ + /* LTE_ADV_FLAG_REMOVED_END */ +#ifdef LTE_ADV + Bool fillCtrlPdu; /*!< Based upon this flag RLC will fill RLC Control PDU + In a tti if P-cell is present then control PDU + should be kept in P-cell otherwise S-cell*/ +#endif + RgLaaTbReqInfo tbReqInfo; /*!< LAA: TB information for the TBs which + need to be fetched from the SCell*/ +}RgInfUeAlloc; + +/** + * @brief This structure carries the Resource allocation information for the + * set of scheduled UEs. + */ +typedef struct rgInfUeInfo +{ + U8 numUes; /*!< Number of UEs allocated. */ + RgInfUeAlloc *allocInfo; /*!< Allocation information per UE. */ +}RgInfUeInfo; + +/** + * @brief This structure contains the RNTI and downlink control format + * information for the scheduled BCCH logical channel. + */ +typedef struct rgInfBcchInfo +{ + CmLteRnti rnti; /*!< RNTI range is specified in Section 7.1 in 36.321 specification. */ + TfuPdschDciInfo dciInfo; /*!< Downlink Control Information. For more information, + refer to TFU Interface Service Definition (p/n 1100091).*/ +/* Modified for SI Enhancement*/ +#ifndef RGR_SI_SCH + CmLteLcId lcId; /*!< Logical Channel Identifier.lcId value range is defined in + Section 6.2.1 in 36.321 specification. */ + Bool sndStatInd; /*!< Currently this is set to 1 for fresh transmission of BCCH data. */ +#else + Buffer *pdu; /*!< PDU being specified for BCCH. */ +#endif + U16 txPwrOffset; /*!< PDSCH tx power offset for BCCH + transmission */ +}RgInfBcchInfo; + +/** + * @brief This structure contains the RNTI and the downlink control information for the scheduled PCCH logical channel. + */ +typedef struct rgInfPcchInfo +{ + CmLteRnti rnti; /*!< RNTI range is specified in Section 7.1 in 36.321 specification. */ + TfuPdschDciInfo dciInfo; /*!< Downlink Control Information. + For more information, refer to TFU Interface Service Definition (p/n 1100091). */ + CmLteLcId lcId; /*!< Logical Channel Identifier. lcId value range is defined in + Section 6.2.1 in 36.321 specification. */ + + U16 txPwrOffset; /*!< PDSCH tx power offset for PCCH + transmission */ +}RgInfPcchInfo; + +/** + * @brief This structure contains the scheduled logical channel information + * mapped onto the BCH transport channel. + */ +typedef struct rgInfBchInfo +{ +/* Modified for SI Enhancement*/ +#ifndef RGR_SI_SCH + CmLteLcId lcId; /*!< Logical Channel Identifier. lcId value range is defined in Section 6.2.1 in 36.321 specification. */ +#else + Buffer *pdu; /*!< PDU being specified for BCH */ +#endif +}RgInfBchInfo; + +/** + * @brief This structure contains the scheduling information of BCH, PCCH, and + * BCCH channel information. + */ +typedef struct rgInfCmnLcInfo +{ + U16 bitMask; /*!< Bitmask representing all the common channels present. */ + RgInfBchInfo bchInfo; /*!< BCH channel Information. */ + RgInfPcchInfo pcchInfo; /*!< Paging Logical Channel Information. */ + RgInfBcchInfo bcchInfo; /*!< Broadcast Logical Channel Information. */ +}RgInfCmnLcInfo; + +#ifdef EMTC_ENABLE +/** + * @brief This structure contains the scheduled logical channel information + * mapped onto the BCH transport channel. + */ +typedef struct rgInfEmtcBcchInfo +{ + CmLteRnti rnti; /*!< RNTI range is specified in Section 7.1 in 36.321 specification. */ + TfuPdschDciInfo dciInfo; /*!< Downlink Control Information. For more information */ + Buffer *pdu; /*!< PDU being specified for BCH */ +}RgInfEmtcBcchInfo; + +/** + * @brief This structure contains the scheduling information of BCH, PCCH, and + * BCCH channel information. + */ +typedef struct rgInfEmtcCmnLcInfo +{ + U16 bitMask; /*!< Bitmask representing all the common channels present. */ + RgInfBchInfo bchInfo; /*!< BCH channel Information. */ + RgInfPcchInfo pcchInfo; /*!< Paging Logical Channel Information. */ + RgInfEmtcBcchInfo emtcBcchInfo; /*!< Broadcast Logical Channel Information. */ +}RgInfEmtcCmnLcInfo; +#endif + +#ifdef LTE_L2_MEAS +/** + * @brief UE-specific allocation information needed for measurements. + * */ +typedef struct rgInfUeUlAlloc +{ + CmLteRnti rnti; /*!< UE ID */ + U8 numPrb; /*!< Number of total PRB's allocated for this UE */ +} RgInfUeUlAlloc; + +/** + * @brief Allocation information of all UEs in this subframe. + * */ +typedef struct rgInfUlUeInfo +{ + U8 numUes; /*!< Number of UE's*/ + CmLteTimingInfo timingInfo; /*!< Uplink timing information */ + RgInfUeUlAlloc *ulAllocInfo;/*!< Uplink Allocations information */ +}RgInfUlUeInfo; +#endif /*LTE_L2_MEAS */ + +/** +*@brief this structure contains the lcId on which flow control need to be performed and the number of packets allowed for admission */ +typedef struct rgInfLcInfo +{ + CmLteLcId lcId; /*!< lcId for flow control*/ + U32 pktAdmitCnt; /*! NOK and reason -> INVALID */ + union { + RgInfPrbCfm prbCfm; /*!< Avgerage PRB usage per QCI*/ + } u; +} RgInfL2MeasCfm; + +/** + * @brief This API is invoked from l2 Measurements module at scheduler. + * When Scheduler receives a measurement request from stack manager for Average + * PRB usage Per QCI in Uplink, Scheduler invokes this API towards LTE MAC + * for the calculations. LTE MAC utilizes the uplink allocations information provided + * by scheduler for every subframe and data indications received for this calculation. + * This API carries a transId to uniquely identify the confirm received for + * this request from LTEMAC. + * */ +EXTERN S16 RgSchMacL2MeasReq ARGS(( + Pst* pst, + RgInfL2MeasReq* l2MeasReq +)); +/** + * @brief This API is invoked from l2 Measurements module at scheduler. + * When Scheduler receives a measurement send request from stack manager, + * it sends L2 measurement to layer manager. + * */ + +EXTERN S16 RgSchMacL2MeasSendReq ARGS(( + Pst* pst, + RgInfL2MeasSndReq* l2MeasReq +)); +/** + * @brief This API is invoked from l2 Measurements module at scheduler. + * When Scheduler receives a measurement stop request from stack manager, + * it stops L2 Measurement + */ +EXTERN S16 RgSchMacL2MeasStopReq ARGS(( + Pst* pst, + RgInfL2MeasStopReq* l2MeasReq +)); + +/** + * @brief This API is invoked from L2 Measurement module at LTE MAC. When LTE MAC + * completes calculation of Avergae PRB usage per QCI in Uplink for a given time + * period, It invokes this API to indicate result back to scheduler. LTE + * MAC sends the same transId received in measurement request from Scheduler. + * */ +EXTERN S16 RgMacSchL2MeasCfm ARGS(( + Pst* pst, + RgInfL2MeasCfm* l2MeasCfm +)); +/** + * @brief This API is invoked from L2 Measurement module at LTE MAC. When LTE MAC + * stops L2 measurement, it sends L2 measurement cfm. + * */ + +EXTERN S16 RgMacSchL2MeasStopCfm ARGS(( + Pst* pst, + RgInfL2MeasCfm* l2MeasCfm +)); + +EXTERN S16 RgMacSchL2MeasStop ARGS +(( +Pst* pst, +RgInfL2MeasCfm *measInfo +)); +#endif /* LTE_L2_MEAS */ + +typedef struct rgInfLcgRegReq +{ + CmLteCellId cellId; /*!< Cell Identifier */ + CmLteRnti crnti; /*!< RNTI which uniquely identifies the UE + RNTI range is specified in Section + 7.1 in 25.321 Specification. */ + U8 lcgId; + Bool isGbr; /* Indicate if the LCG is Gbr */ +} RgInfLcgRegReq; + + +/* Added support for SPS*/ +#ifdef LTEMAC_SPS +/** + * @brief This structure contains the logical channel information related to + * uplink SPS for a particular UE identified by the CRNTI. + */ +typedef struct rgInfSpsLcInfo +{ + CmLteCellId cellId; /*!< Cell Identifier */ + CmLteRnti crnti; /*!< RNTI which uniquely identifies the UE + RNTI range is specified in Section + 7.1 in 25.321 Specification. */ + CmLteRnti spsRnti; /*!< SPS RNTI. RNTI range is specified in + Section 7.1 in 25.321 Specification. */ + U8 spsLcCnt; /*!< identifies the number of SPS + configured logical channels */ + U8 spsLcId[RGINF_MAX_NUM_DED_LC]; /*!< Logical Channel + Identifier. lcId value range is + defined in Section 6.2.1 + in 36.321 Specification. */ + U8 implRelCnt; /*!< "implicitRelAfter" vallue */ + U16 spsPrd; /*!< SPS periodicity of the UE */ +} RgInfSpsLcInfo; + +/** + * @brief This structure contains UL SPS param Reset related to + * uplink SPS for a particular UE identified by the CRNTI. + */ +typedef struct rgInfUlSpsReset +{ + CmLteCellId cellId; /*!< Cell Identifier */ + CmLteRnti crnti; /*!< RNTI which uniquely identifies the UE + RNTI range is specified in Section + 7.1 in 25.321 Specification. */ +} RgInfUlSpsReset; + + +/** + * @brief This structure contains the information to release UL SPS for a UE */ +typedef struct rgInfSpsRelInfo +{ + S16 cellSapId; /*!< identifies the cell SAP. Value range + should be within the set of + configured cell SAP(s).*/ + CmLteRnti cRnti; /*!< RNTI of the UE */ + Bool isExplRel; /*!< TRUE if explicit release needs to be + sent to UE */ +} RgInfSpsRelInfo; +#endif /* LTEMAC_SPS */ + +/* + * Function Prototypes + */ +/** + * @brief Request from Scheduler to MAC to register a cell. + * @details This primitive is used for light-weight loose coupling. + */ +EXTERN S16 cmPkSchMacCellRegReq ARGS(( + Pst* pst, + RgInfCellReg* regReq +)); + +typedef S16 (*CellRegReq) ARGS(( + Pst* pst, + RgInfCellReg* regReq +)); + +/** + * @brief Request from Scheduler to MAC to register a cell. + * @details The scheduler invokes this primitive after the scheduler cell + * configuration is completed. Before calling this primitive, the scheduler + * creates a mapping of the cell which is uniquely idetified by cell ID and + * scheduler instance that is serving the cell. + */ +EXTERN S16 RgSchMacCellRegReq ARGS(( + Pst* pst, + RgInfCellReg* regReq +)); +/** + * @brief Request from Scheduler to MAC to register a cell. + * @details This primitive is used for light-weight loose coupling. + */ +EXTERN S16 cmUnpkSchMacCellRegReq ARGS(( + CellRegReq func, + Pst* pst, + Buffer *mBuf +)); +/** + * @brief Request from MAC to scheduler to update dedicated BO. + * @details This primitive is used for light-weight loose coupling. + */ +EXTERN S16 cmPkMacSchDedBoUpdtReq ARGS(( + Pst* pst, + RgInfDedBoRpt* boRpt +)); + +typedef S16 (*DedBoUpdtReq) ARGS(( + Pst* pst, + RgInfDedBoRpt* boRpt +)); + +/** + * @brief Request from MAC to scheduler to update dedicated BO. + * @details MAC layer invokes this primitive towards scheduler when it + * receives status response from the RLC for dedicated channels. Scheduler + * takes the buffer occupancy information into consideration while taking + * scheduling decisons. + */ +EXTERN S16 RgMacSchDedBoUpdtReq ARGS(( + Pst* pst, + RgInfDedBoRpt* boRpt +)); +/** + * @brief Request from MAC to scheduler to update dedicated BO. + * @details This primitive is used for light-weight loose coupling. + */ +EXTERN S16 cmUnpkMacSchDedBoUpdtReq ARGS(( + DedBoUpdtReq func, + Pst* pst, + Buffer *mBuf +)); +/** + * @brief Request from MAC to scheduler to update common channel BO. + * @details This primitive is used for light-weight loose coupling. + */ +EXTERN S16 cmPkMacSchCmnBoUpdtReq ARGS(( + Pst* pst, + RgInfCmnBoRpt* boRpt +)); + +typedef S16 (*CmnBoUpdtReq) ARGS(( + Pst* pst, + RgInfCmnBoRpt* boRpt +)); + +/** + * @brief Request from MAC to scheduler to update common channel BO. + * @details MAC layer invokes this primitive towards scheduler when it + * receives status response from the RLC for common channels. Scheduler + * takes the buffer occupancy information into consideration while taking + * scheduling decisons. + */ +EXTERN S16 RgMacSchCmnBoUpdtReq ARGS(( + Pst* pst, + RgInfCmnBoRpt* boRpt +)); +/** + * @brief Request from MAC to scheduler to update common channel BO. + * @details This primitive is used for light-weight loose coupling. + */ +EXTERN S16 cmUnpkMacSchCmnBoUpdtReq ARGS(( + CmnBoUpdtReq func, + Pst* pst, + Buffer *mBuf +)); + +/*Fix: start:Indicate UE deletion at MAC to scheduler*/ +/** + * @brief UE delete indication from MAC to scheduler. + * @details This primitive is used for light-weight loose coupling. + */ +EXTERN S16 cmPkMacSchUeDelInd ARGS(( + Pst* pst, + RgInfUeDelInd* ueDelInd +)); + +typedef S16 (*UeDelInd) ARGS(( + Pst* pst, + RgInfUeDelInd* ueDelInd +)); + +/** + * @brief UE deletion indication from MAC to scheduler. + * @details MAC layer invokes this primitive towards scheduler when it + * receives UE delete Request. As the UE is now deleted at MAC, it should + * not be scheduled. + */ +EXTERN S16 RgMacSchUeDelInd ARGS(( + Pst* pst, + RgInfUeDelInd* ueDelInd +)); +/** + * @brief UE delete Indication Request from MAC to scheduler. + * @details This primitive is used for light-weight loose coupling. + */ +EXTERN S16 cmUnpkMacSchUeDelInd ARGS(( + UeDelInd func, + Pst* pst, + Buffer *mBuf +)); +/*Fix: end:Indicate UE deletion at MAC to scheduler*/ +/** + * @brief Data Indication Request from MAC to scheduler. + * @details This primitive is used for light-weight loose coupling. + */ +EXTERN S16 cmPkMacSchSfRecpInd ARGS(( + Pst* pst, + RgInfSfDatInd* datInd +)); + +typedef S16 (*SfRecpInd) ARGS(( + Pst* pst, + RgInfSfDatInd* datInd +)); + +/** + * @brief Data Indication Request from MAC to scheduler. + * @details MAC layer invokes this primitive towards scheduler when it + * receives MAC Control Elements from the data received from the UE. Scheduler + * takes these control elements into consideration while taking scheduling + * decisons for the uplink. + */ +EXTERN S16 RgMacSchSfRecpInd ARGS(( + Pst* pst, + RgInfSfDatInd* datInd +)); +/** + * @brief Data Indication Request from MAC to scheduler. + * @details This primitive is used for light-weight loose coupling. + */ +EXTERN S16 cmUnpkMacSchSfRecpInd ARGS(( + SfRecpInd func, + Pst* pst, + Buffer *mBuf +)); +/** + * @brief Resource Allocation Request from Scheduler to MAC. + * @details This primitive is used for light-weight loose coupling. + */ +EXTERN S16 cmPkSchMacSfAllocReq ARGS(( + Pst* pst, + RgInfSfAlloc* resAllocReq +)); + +typedef S16 (*SfAllocReq) ARGS(( + Pst* pst, + RgInfSfAlloc* resAllocReq +)); + +/** + * @brief Resource Allocation Request from Scheduler to MAC. + * @details Scheduler invokes this primitive for every TTI towards MAC to + * inform the scheduling decisions taken for uplink grants, common channels + * and list of UEs to be scheduling during this TTI. + */ +EXTERN S16 RgSchMacSfAllocReq ARGS(( + Pst* pst, + RgInfSfAlloc* resAllocReq +)); +/** + * @brief Resource Allocation Request from Scheduler to MAC. + * @details This primitive is used for light-weight loose coupling. + */ +EXTERN S16 cmUnpkSchMacSfAllocReq ARGS(( + SfAllocReq func, + Pst* pst, + Buffer *mBuf +)); +/** + * @brief Request from Scheduler to release HARQ processes at MAC. + * @details This primitive is used for light-weight loose coupling. + */ +EXTERN S16 cmPkSchMacRlsHqReq ARGS(( + Pst* pst, + RgInfRlsHqInfo* sfHqInfo +)); + +typedef S16 (*RlsHqReq) ARGS(( + Pst* pst, + RgInfRlsHqInfo* sfHqInfo +)); + +/** + * @brief Request from Scheduler to release HARQ processes at MAC. + * @details Scheduler calls this primitive to send the list of UEs for + * which the HARQ buffers are released to MAC. The Scheduler invokes this + * primitive when a positive acknowledgement is received for the TB transmitted + * or a TB is retransmitted for the allowed maximum number of retransmissions. + */ +EXTERN S16 RgSchMacRlsHqReq ARGS(( + Pst* pst, + RgInfRlsHqInfo* sfHqInfo +)); +/** + * @brief Request from Scheduler to release HARQ processes at MAC. + * @details This primitive is used for light-weight loose coupling. + */ + +EXTERN S16 cmUnpkSchMacRlsHqReq ARGS(( + RlsHqReq func, + Pst* pst, + Buffer *mBuf +)); + +/** + * @brief Request from Scheduler to reset HARQ Entity at MAC. + * @details This primitive is used for light-weight loose coupling. + */ +EXTERN S16 cmPkSchMacRstHqEntReq ARGS(( + Pst* pst, + RgInfResetHqEnt* hqEntInfo +)); + +typedef S16 (*RstHqEntReq) ARGS(( + Pst* pst, + RgInfResetHqEnt* hqEntInfo +)); + +/** + * @brief Request from Scheduler to reset HARQ entity at MAC for a scell of an ue. + * This is triggered upon deactivation of a scell + */ +EXTERN S16 RgSchMacRstHqEntReq ARGS(( + Pst* pst, + RgInfResetHqEnt* hqEntInfo +)); +/** + * @brief Request from Scheduler to release HARQ processes at MAC. + * @details This primitive is used for light-weight loose coupling. + */ + +EXTERN S16 cmUnpkSchMacRstHqEntReq ARGS(( + RstHqEntReq func, + Pst* pst, + Buffer *mBuf +)); +/** + * @brief Request from Scheduler to release RNTI at MAC. + * @details This primitive is used for light-weight loose coupling. + */ +EXTERN S16 cmPkSchMacRlsRntiReq ARGS(( + Pst* pst, + RgInfRlsRnti* rlsRnti +)); + +typedef S16 (*RlsRntiReq) ARGS(( + Pst* pst, + RgInfRlsRnti* rlsRnti +)); + +/** + * @brief Request from Scheduler to release RNTI at MAC. + * @details The Scheduler calls this primitive to send the list of RNTIs for + * which the RRC Connection is being rejected. + */ +EXTERN S16 RgSchMacRlsRntiReq ARGS(( + Pst* pst, + RgInfRlsRnti* rlsRnt +)); +/** + * @brief Request from Scheduler to release RNTI at MAC. + * @details This primitive is used for light-weight loose coupling. + */ +EXTERN S16 cmUnpkSchMacRlsRntiReq ARGS(( + RlsRntiReq func, + Pst* pst, + Buffer *mBuf +)); +/* Added support for SPS*/ + +typedef S16 (*LcgReg) ARGS(( + Pst* pst, + RgInfLcgRegReq *lcgRegReq +)); + +EXTERN S16 cmPkSchMacLcgRegReq ARGS(( + Pst* pst, + RgInfLcgRegReq *lcgRegReq +)); + +EXTERN S16 RgSchMacLcgRegReq ARGS((Pst *pst, RgInfLcgRegReq *lcgRegReq)); + +EXTERN S16 cmUnpkSchMacLcgRegReq ARGS(( + LcgReg func, + Pst *pst, + Buffer *mBuf +)); + +EXTERN S16 RgSchMacLcgReg ARGS((Pst* pst, RgInfLcgRegReq *lcgRegReq)); + +#ifdef LTEMAC_SPS +/** + * @brief Primitive from Scheduler to MAC to register the logical channels of + * a SPS UE + * @details This primitive is used for light-weight loose coupling. + */ +EXTERN S16 cmPkSchMacSpsLcRegReq ARGS(( + Pst* pst, + RgInfSpsLcInfo *lcInfo +)); + +typedef S16 (*SpsLcReg) ARGS(( + Pst* pst, + RgInfSpsLcInfo *lcInfo +)); + +/** + * @brief Request from Scheduler to register the SPS related logical channels. + * @details Scheduler calls this primitive to send the list of logical channels + * that belong to the SPS logical channel group. + */ +EXTERN S16 RgSchMacSpsLcRegReq ARGS((Pst *pst, RgInfSpsLcInfo *lcInfo)); + +EXTERN S16 cmUnpkSchMacSpsLcRegReq ARGS(( + SpsLcReg func, + Pst *pst, + Buffer *mBuf +)); + + +/** + * @brief Primitive from Scheduler to MAC to Reset UL SPS related Params + * @details This primitive is used for light-weight loose coupling. + */ +EXTERN S16 cmPkSchMacUlSpsResetReq ARGS(( + Pst* pst, + RgInfUlSpsReset *ulSpsResetInfo +)); + +typedef S16 (*UlSpsReset) ARGS(( + Pst* pst, + RgInfUlSpsReset *ulSpsResetInfo +)); + +/** + * @brief Request from Scheduler to reset UL SPS Params + * @details Scheduler calls this primitive to reset implicit and explicit + * release counters for the UE + */ +EXTERN S16 RgSchMacUlSpsResetReq ARGS((Pst *pst, RgInfUlSpsReset *ulSpsResetInfo)); + +EXTERN S16 cmUnpkSchMacUlSpsResetReq ARGS(( + UlSpsReset func, + Pst *pst, + Buffer *mBuf +)); + + + +/** + * @brief Primitive from Scheduler to MAC to deregister the logical channels of + * a SPS UE + * @details This primitive is used for light-weight loose coupling. + */ +EXTERN S16 cmPkSchMacSpsLcDeregReq ARGS(( + Pst* pst, + CmLteCellId cellId, + CmLteRnti crnti +)); + +typedef S16 (*SpsLcDereg) ARGS(( + Pst* pst, + CmLteCellId cellId, + CmLteRnti crnti +)); + +/** + * @brief Request from Scheduler to deregister the SPS related logical channels. + * @details Scheduler calls this primitive to send the deregistration request + * for a UE once SPS is released for it + */ +EXTERN S16 RgSchMacSpsLcDeregReq ARGS((Pst *pst, CmLteCellId cellId, CmLteRnti + crnti)); + +EXTERN S16 cmUnpkSchMacSpsLcDeregReq ARGS(( + SpsLcDereg func, + Pst* pst, + Buffer *mBuf +)); + +/** + * @brief Primitive from MAC to Scheduler to indicate release of UL SPS for a UE + * @details This primitive is used for light-weight loose coupling. + */ +EXTERN S16 cmPkMacSchSpsRelInd ARGS(( + Pst* pst, + RgInfSpsRelInfo* relInfo +)); + +typedef S16 (*SpsRelInd) ARGS(( + Pst* pst, + RgInfSpsRelInfo* relInfo +)); + +/** + * @brief Indication from MAC to Scheduler to release UL SPS for a UE + * @details MAC calls this primitive to inform the scheduler that UL SPS needs + * to be released for a UE + */ +EXTERN S16 RgMacSchSpsRelInd ARGS((Pst *pst, RgInfSpsRelInfo *relInfo)); + +EXTERN S16 cmUnpkMacSchSpsRelInd ARGS(( + SpsRelInd func, + Pst* pst, + Buffer *mBuf +)); + +#endif +#ifdef LTE_L2_MEAS +EXTERN S16 cmPkMacSchL2MeasCfm ARGS(( +Pst* pst, +RgInfL2MeasCfm *measCfm +)); + +EXTERN S16 cmPkMacSchL2MeasStopCfm ARGS(( +Pst* pst, +RgInfL2MeasCfm *measCfm +)); + + +EXTERN S16 cmPkSchMacL2MeasReq ARGS(( + Pst* pst, + RgInfL2MeasReq *measInfo +)); + +EXTERN S16 cmPkSchMacL2MeasStopReq ARGS(( + Pst* pst, + RgInfL2MeasStopReq *measInfo +)); + +EXTERN S16 cmPkSchMacL2MeasSendReq ARGS(( + Pst* pst, + RgInfL2MeasSndReq *measInfo +)); +typedef S16 (*L2MeasReq) ARGS(( + Pst* pst, + RgInfL2MeasReq *measInfo +)); + +typedef S16 (*L2MeasStopReq) ARGS(( + Pst* pst, + RgInfL2MeasStopReq *measInfo +)); + +typedef S16 (*L2MeasSendReq) ARGS(( + Pst* pst, + RgInfL2MeasSndReq *measInfo +)); +typedef S16 (*L2MeasStopCfm) ARGS(( + Pst *pst, + RgInfL2MeasCfm *measCfm +)); + +typedef S16 (*L2MeasCfm) ARGS(( + Pst *pst, + RgInfL2MeasCfm *measCfm +)); +EXTERN S16 cmUnpkMacSchL2MeasCfm ARGS +(( +L2MeasCfm func, +Pst *pst, +Buffer *mBuf +)); +EXTERN S16 cmUnpkSchMacL2MeasReq ARGS(( + L2MeasReq func, + Pst *pst, + Buffer *mBuf +)); +EXTERN S16 cmUnpkSchMacL2MeasSendReq ARGS(( + L2MeasSendReq func, + Pst *pst, + Buffer *mBuf +)); +EXTERN S16 cmUnpkSchMacL2MeasStopReq ARGS(( + L2MeasStopReq func, + Pst *pst, + Buffer *mBuf +)); + +EXTERN S16 cmUnpkMacSchL2MeasStopCfm ARGS(( + L2MeasCfm func, + Pst *pst, + Buffer *mBuf +)); +#endif +EXTERN S16 RgSchMacRlsRnti ARGS((Pst* pst, RgInfRlsRnti* rlsRnti)); +EXTERN S16 RgSchMacRlsHq ARGS((Pst* pst, RgInfRlsHqInfo* sfHqInfo)); +EXTERN S16 RgSchMacSfAlloc ARGS((Pst* pst, RgInfSfAlloc* resAllocReq)); +EXTERN S16 RgSchMacRstHqEnt ARGS((Pst* pst, RgInfResetHqEnt* hqEntInfo)); +EXTERN S16 RgMacSchSfRecp ARGS((Pst* pst, RgInfSfDatInd* datInd)); +EXTERN S16 RgMacSchCmnBoUpdt ARGS(( Pst* pst, RgInfCmnBoRpt* boRpt)); +EXTERN S16 RgMacSchDedBoUpdt ARGS(( Pst* pst, RgInfDedBoRpt* boRpt)); +EXTERN S16 RgSchMacCellReg ARGS((Pst* pst,RgInfCellReg* regReq)); +#ifdef LTE_L2_MEAS +EXTERN S16 RgSchMacL2Meas ARGS((Pst* pst, RgInfL2MeasReq* l2MeasReq)); +EXTERN S16 RgMacSchL2Meas ARGS((Pst* pst, RgInfL2MeasCfm* l2MeasCfm)); +EXTERN S16 RgSchMacL2MeasStop ARGS((Pst* pst, RgInfL2MeasStopReq *measInfo)); +EXTERN S16 RgSchMacL2MeasSend ARGS((Pst* pst, RgInfL2MeasSndReq *measInfo)); +#endif /* LTE_L2_MEAS */ +/* Added support for SPS*/ +#ifdef LTEMAC_SPS +EXTERN S16 RgSchMacSpsLcReg ARGS((Pst *pst, RgInfSpsLcInfo *lcInfo)); +EXTERN S16 RgSchMacUlSpsReset ARGS((Pst *pst, RgInfUlSpsReset *lcInfo)); +EXTERN S16 RgSchMacSpsLcDereg ARGS((Pst *pst, CmLteCellId cellId, CmLteRnti + crnti)); +EXTERN S16 RgMacSchSpsRel ARGS((Pst *pst, RgInfSpsRelInfo* relInfo)); +#endif +EXTERN S16 RgMacSchUeDel ARGS((Pst* pst, RgInfUeDelInd* ueDelInd)); + +#ifdef __cplusplus +} +#endif +#endif /* __GKSCH_X__*/ + +/********************************************************************** + + End of file +**********************************************************************/ diff --git a/src/5gnrmac/rg_sch_l2m.c b/src/5gnrmac/rg_sch_l2m.c new file mode 100755 index 000000000..6e632dc89 --- /dev/null +++ b/src/5gnrmac/rg_sch_l2m.c @@ -0,0 +1,934 @@ +/******************************************************************************* +################################################################################ +# Copyright (c) [2017-2019] [Radisys] # +# # +# 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. # +################################################################################ +******************************************************************************* + +/************************************************************************ + + Name: LTE-MAC layer + + Type: C source file + + Desc: C source code for L2 Measurement fucntions + + File: rg_sch_l2m.c + +**********************************************************************/ + +/** @file rg_sch_l2m.c +@brief This file implements the L2 Measurement feature code. +*/ + +/* header include files -- defines (.h) */ +#include "envopt.h" /* environment options */ +#include "envdep.h" /* environment dependent */ +#include "envind.h" /* environment independent */ +#include "gen.h" /* general layer */ +#include "ssi.h" /* system service interface */ +#include "cm_hash.h" /* common hash list */ +#include "cm_llist.h" /* common linked list library */ +#include "cm_err.h" /* common error */ +#include "cm_lte.h" /* common LTE */ +#include "lrg.h" +#include "rgr.h" +#include "rgm.h" +#include "tfu.h" +#include "rg_env.h" +#include "rg_sch.h" +#include "rg_sch_cmn.h" +#include "rg_sch_inf.h" /* typedefs for Scheduler */ +#include "rg_sch_err.h" +#include "rl_interface.h" +#include "rl_common.h" + +/* header/extern include files (.x) */ +#include "gen.x" /* general layer typedefs */ +#include "ssi.x" /* system services typedefs */ +#include "cm5.x" /* common timers */ +#include "cm_hash.x" /* common hash list */ +#include "cm_lib.x" /* common library */ +#include "cm_llist.x" /* common linked list */ +#include "cm_mblk.x" /* memory management */ +#include "cm_tkns.x" /* common tokens */ +#include "cm_lte.x" /* common tokens */ +#include "tfu.x" /* TFU types */ +#include "lrg.x" /* layer management typedefs for MAC */ +#include "rgr.x" /* layer management typedefs for MAC */ +#include "rgm.x" /* layer management typedefs for MAC */ +#include "rg_sch_inf.x" /* typedefs for Scheduler */ +#include "rg_sch.x" /* typedefs for Scheduler */ +#include "rg_sch_cmn.x" /* typedefs for Scheduler */ +/* local defines */ +U32 dlPrbCnt; +#ifdef LTE_L2_MEAS + +static const char* RLOG_MODULE_NAME="MAC"; +static int RLOG_MODULE_ID=4096; +static int RLOG_FILE_ID=166; + +PRIVATE S16 rgSchL2mInsertMeasCb ARGS(( + RgSchCellCb *cell, + RgSchL2MeasCb *measCb, + LrgSchMeasReqInfo *measInfo )); + +PRIVATE RgSchL2MeasCb * rgSchL2mAllocMeasCb ARGS(( + RgSchCellCb *cell, + LrgSchMeasReqInfo *measInfo, + RgSchErrInfo err)); + +/* Function definitions */ + +/** @brief This function fills the L2 measurement confirm structure + * + * @details + * + * Function: rgSchFillL2MeasCfm + * + * @param [in] RgSchCellCb *cell + * @param [in] RgSchL2MeasCb *measCb + * @param [out] LrgSchMeasCfmInfo *measCfm + * @param [in] measTime + * @return Void + */ +#ifdef ANSI +PUBLIC S16 rgSchFillL2MeasCfm +( +RgSchCellCb *cell, +RgSchL2MeasCb *measCb, +LrgSchMeasCfmInfo *cfm, +U32 measTime +) +#else +PUBLIC S16 rgSchFillL2MeasCfm(cell, measCb, cfm, measTime) +RgSchCellCb *cell; +RgSchL2MeasCb *measCb; +LrgSchMeasCfmInfo *cfm; +U32 measTime; +#endif +{ + U8 idx; + LrgSchMeasReqInfo *measInfo; + U8 qciVal = 0; + U32 sampOc = 0; + + TRC3(rgSchFillL2MeasCfm) + + measInfo = &measCb->measReq; + + cfm->hdr.transId = measInfo->hdr.transId; + cfm->measType = measInfo->measType; + cfm->cellId = measInfo->cellId; + cfm->cfm.status = LCM_PRIM_OK; + if((measCb->measReq.measType & LRG_L2MEAS_AVG_PRB_DL) && + (measCb->dlTotalBw)) + { + cfm->avgPrbDl.prbPerc = ((cell->avgPrbDl.prbCount * 100) / + measCb->dlTotalBw); + /* Resetting the prbCount to 0, fix for ccpu00125002 */ + cell->avgPrbDl.prbCount = 0; + } + if((measCb->measReq.measType & LRG_L2MEAS_AVG_PRB_UL) && + (measCb->ulTotalBw)) + { + cfm->avgPrbUl.prbPerc = ((cell->avgPrbUl.prbCount * 100) / + measCb->ulTotalBw); + /* Resetting the prbCount to 0, fix for ccpu00125002 */ + cell->avgPrbUl.prbCount = 0; + } + if((measCb->measReq.measType & LRG_L2MEAS_AVG_PRB_PER_QCI_DL) && + (measCb->dlTotalBw)) + { + cfm->avgPrbQciDlCfm.numQci = measCb->measReq.avgPrbQciDl.numQci; + for(idx = 0; idx < measCb->measReq.avgPrbQciDl.numQci; idx++) + { + qciVal = measCb->measReq.avgPrbQciDl.qci[idx]; + cfm->avgPrbQciDlCfm.prbPercQci[idx].prbPercQci = + ((cell->qciArray[qciVal].dlPrbCount * 100) / + measCb->dlTotalBw); + cfm->avgPrbQciDlCfm.prbPercQci[idx].qciValue = qciVal; + cell->qciArray[qciVal].dlPrbCount = 0; + } + } + if((measCb->measReq.measType & LRG_L2MEAS_AVG_PRB_PER_QCI_UL) && + (measCb->ulTotalBw)) + { + cfm->avgPrbQciUlCfm.numQci = measCb->measReq.avgPrbQciUl.numQci; + for(idx = 0; idx < measCb->measReq.avgPrbQciUl.numQci; idx++) + { + cfm->avgPrbQciUlCfm.prbPercQci[idx].qciValue = + measCb->avgPrbQciUl.prbUsage[idx].qciValue; + + if(measCb->avgPrbQciUl.prbUsage[idx].prbUsage > measCb->ulTotalBw) + { + measCb->avgPrbQciUl.prbUsage[idx].prbUsage = measCb->ulTotalBw; + } + + cfm->avgPrbQciUlCfm.prbPercQci[idx].prbPercQci = + ((measCb->avgPrbQciUl.prbUsage[idx].prbUsage * 100) / + measCb->ulTotalBw); + } + } + if(measCb->measReq.measType & LRG_L2MEAS_RA_PREAMBLE) + { + cfm->raPrmbsCfm.dedPreambles = cell->raPrmbs.dedPream; + cfm->raPrmbsCfm.randSelPreLowRange = cell->raPrmbs.preamGrpA; + cfm->raPrmbsCfm.randSelPreHighRange = cell->raPrmbs.preamGrpB; + cell->raPrmbs.dedPream = 0; + cell->raPrmbs.preamGrpA = 0; + cell->raPrmbs.preamGrpB = 0; + } + if(measCb->measReq.measType & LRG_L2MEAS_NMB_ACTV_UE_PER_QCI_DL) + { + cfm->numUeQciDlCfm.numQci = measInfo->nmbActvUeQciDl.numQci; + sampOc = (measTime / measInfo->nmbActvUeQciDl.sampPrd); + + if(sampOc) + { + if (measCb->measReq.nmbActvUeQciDl.numQci) + { + for(idx = 0; idx < measCb->measReq.nmbActvUeQciDl.numQci; idx++) + { + qciVal = measCb->measReq.nmbActvUeQciDl.qci[idx]; + /* L2_COUNTERS */ + cell->qciArray[qciVal].dlTotal_UeCount += + cell->qciArray[qciVal].dlUeCount; + cfm->numUeQciDlCfm.numActvUeQci[idx].numActvUeQci = + cell->qciArray[qciVal].dlTotal_UeCount / sampOc; + cfm->numUeQciDlCfm.numActvUeQci[idx].qciValue = qciVal; + + RLOG_ARG3(L_DEBUG,DBG_CELLID,cell->cellId, + "L2_MEAS:CFM DL QCI %u TOTAL Count %lu Active UE %d ", + qciVal,cell->qciArray[qciVal].dlTotal_UeCount, + cfm->numUeQciDlCfm.numActvUeQci[idx].numActvUeQci); + + cell->qciArray[qciVal].dlTotal_UeCount = 0; + } + } + else + { + idx = 0; + for(qciVal = 1; qciVal < LRG_MAX_QCI_PER_REQ; qciVal++) + { + /* L2_COUNTERS */ + cell->qciArray[qciVal].dlTotal_UeCount += + cell->qciArray[qciVal].dlUeCount; + if (cell->qciArray[qciVal].dlTotal_UeCount) + { + cfm->numUeQciDlCfm.numActvUeQci[idx].numActvUeQci = + cell->qciArray[qciVal].dlTotal_UeCount / sampOc; + cfm->numUeQciDlCfm.numActvUeQci[idx].qciValue = qciVal; + + RLOG_ARG3(L_DEBUG,DBG_CELLID,cell->cellId, + "L2_MEAS:CFM DL QCI %u TOTAL Count %lu Active UE %d ", + qciVal,cell->qciArray[qciVal].dlTotal_UeCount, + cfm->numUeQciDlCfm.numActvUeQci[idx].numActvUeQci); + + cell->qciArray[qciVal].dlTotal_UeCount = 0; + idx++; + } + } + cfm->numUeQciDlCfm.numQci = idx; + } + } + } + if(measCb->measReq.measType & LRG_L2MEAS_NMB_ACTV_UE_PER_QCI_UL) + { + cfm->numUeQciUlCfm.numQci = measInfo->nmbActvUeQciUl.numQci; + sampOc = (measTime / measInfo->nmbActvUeQciUl.sampPrd); + + + if(sampOc) + { + if (measCb->measReq.nmbActvUeQciUl.numQci) + { + for(idx = 0; idx < measCb->measReq.nmbActvUeQciUl.numQci; idx++) + { + cell->qciArray[qciVal].ulTotal_UeCount += + cell->qciArray[qciVal].ulUeCount; + qciVal = measCb->measReq.nmbActvUeQciUl.qci[idx]; + cfm->numUeQciUlCfm.numActvUeQci[idx].numActvUeQci = + cell->qciArray[qciVal].ulTotal_UeCount/ sampOc; + cfm->numUeQciUlCfm.numActvUeQci[idx].qciValue = qciVal; + + RLOG_ARG3(L_DEBUG,DBG_CELLID,cell->cellId, + "L2_MEAS:CFM UL QCI %d TOTAL Count %lu Active UE %d ", + qciVal,cell->qciArray[qciVal].ulTotal_UeCount, + cfm->numUeQciUlCfm.numActvUeQci[idx].numActvUeQci); + + cell->qciArray[qciVal].ulTotal_UeCount = 0; + } + } + else + { + idx = 0; + for(qciVal = 1; qciVal < LRG_MAX_QCI_PER_REQ; qciVal++) + { + cell->qciArray[qciVal].ulTotal_UeCount += + cell->qciArray[qciVal].ulUeCount; + if (cell->qciArray[qciVal].ulTotal_UeCount) + { + cfm->numUeQciUlCfm.numActvUeQci[idx].numActvUeQci = + cell->qciArray[qciVal].ulTotal_UeCount/ sampOc; + cfm->numUeQciUlCfm.numActvUeQci[idx].qciValue = qciVal; + + RLOG_ARG3(L_DEBUG,DBG_CELLID,cell->cellId, + "L2_MEAS:CFM UL QCI %d TOTAL Count %lu Active UE %d ", + qciVal,cell->qciArray[qciVal].ulTotal_UeCount, + cfm->numUeQciUlCfm.numActvUeQci[idx].numActvUeQci); + + cell->qciArray[qciVal].ulTotal_UeCount = 0; + idx++; + } + } + cfm->numUeQciUlCfm.numQci = idx; + } + } + } + if(measCb->measReq.measType & LRG_L2MEAS_TB_TRANS_DL_COUNT) + { + cfm->tbTransDlTotalCnt = cell->dlUlTbCnt.tbTransDlTotalCnt; + cell->dlUlTbCnt.tbTransDlTotalCnt = 0; + } + if(measCb->measReq.measType & LRG_L2MEAS_TB_TRANS_DL_FAULTY_COUNT) + { + cfm->tbTransDlFaulty = cell->dlUlTbCnt.tbTransDlFaulty; + cell->dlUlTbCnt.tbTransDlFaulty = 0; + } + if(measCb->measReq.measType & LRG_L2MEAS_TB_TRANS_UL_COUNT) + { + cfm->tbTransUlTotalCnt = cell->dlUlTbCnt.tbTransUlTotalCnt; + cell->dlUlTbCnt.tbTransUlTotalCnt = 0; + } + if(measCb->measReq.measType & LRG_L2MEAS_TB_TRANS_UL_FAULTY_COUNT) + { + cfm->tbTransUlFaulty = cell->dlUlTbCnt.tbTransUlFaulty; + cell->dlUlTbCnt.tbTransUlFaulty = 0; + } + + measCb->dlTotalBw = 0; + measCb->ulTotalBw = 0; + + RETVALUE(ROK); +} /* rgSchFillL2MeasCfm */ + +/** @brief This function sends the L2 measurement confirm to LM + * from Shceduler + * + * @details + * + * Function: rgSchL2mSndCfm + * + * @param [in] Pst *pst + * @param [in] RgSchL2MeasCb *measCb + * @param [in] Bool isErr + * @return Void + */ +#ifdef ANSI +PUBLIC S16 rgSchL2mSndCfm +( +Pst *pst, +RgSchL2MeasCb *measCb, +LrgSchMeasReqInfo *measInfo, +Bool isErr +) +#else +PUBLIC S16 rgSchL2mSndCfm(pst, measCb, measInfo, isErr) +Pst *pst; +RgSchL2MeasCb *measCb; +LrgSchMeasReqInfo *measInfo; +Bool isErr; +#endif +{ + LrgSchMeasCfmInfo cfm; + + TRC3(rgSchL2mSndCfm) + + cmMemset((U8 *)&cfm, (U8)0, sizeof(LrgSchMeasCfmInfo)); + cfm.hdr.transId = measInfo->hdr.transId; + cfm.measType = measInfo->measType; + cfm.cellId = measInfo->cellId; + cfm.cfm.status = LCM_PRIM_OK; + if(isErr == TRUE) + { + cfm.cfm.status = LCM_PRIM_NOK; + cfm.cfm.reason = LCM_REASON_INVALID_PAR_VAL; + RgMiLrgSchL2MeasCfm(pst, &cfm); + RETVALUE(ROK); + } + RETVALUE(ROK); +} /* rgSchL2mSndCfm */ + +/** @brief This function fills the LM confirmation pst structure + * + * @details + * + * Function: rgSchL2mFillCfmPst + * + * @param [in] Pst *pst + * @param [out] Pst *cfmPst + * @param [in] LrgSchMeasReqInfo *measInfo + * @return Void + */ +#ifdef ANSI +PUBLIC Void rgSchL2mFillCfmPst +( +Pst *pst, +Pst *cfmPst, +LrgSchMeasReqInfo *measInfo +) +#else +PUBLIC Void rgSchL2mFillCfmPst(pst, cfmPst, measInfo) +Pst *pst; +Pst *cfmPst; +LrgSchMeasReqInfo *measInfo; +#endif +{ + + + TRC3(rgSchL2mFillCfmPst) + + + cfmPst->srcEnt = pst->dstEnt; + cfmPst->srcInst = pst->dstInst; + cfmPst->srcProcId = pst->dstProcId; + cfmPst->dstEnt = pst->srcEnt; + cfmPst->dstInst = pst->srcInst; + cfmPst->dstProcId = pst->srcProcId; + + cfmPst->selector = measInfo->hdr.response.selector; + cfmPst->prior = measInfo->hdr.response.prior; + cfmPst->route = measInfo->hdr.response.route; + cfmPst->region = measInfo->hdr.response.mem.region; + cfmPst->pool = measInfo->hdr.response.mem.pool; + + RETVOID; +} /* rgSchL2mFillCfmPst */ + +/** @brief This function inserts the MeasCb in to data base + * + * @details + * + * Function: rgSchL2mInsertMeasCb + * + * @param [in] RgSchCellCb *cell + * @param [in] RgSchL2MeasCb *measCb + * @param [in] LrgSchMeasReqInfo *measInfo + * @return S16 + * -# ROK + * -# RFAILED + */ +#ifdef ANSI +PRIVATE S16 rgSchL2mInsertMeasCb +( +RgSchCellCb *cell, +RgSchL2MeasCb *measCb, +LrgSchMeasReqInfo *measInfo +) +#else +PRIVATE S16 rgSchL2mInsertMeasCb(cell, measCb, measInfo) +RgSchCellCb *cell; +RgSchL2MeasCb *measCb; +LrgSchMeasReqInfo *measInfo; +#endif +{ + CmLList *lnk, *node; + RgSchL2MeasCb *oldMeasCb; + U32 diffTime; + + TRC3(rgSchL2mInsertMeasCb) + /* + * 1. Check if l2mList has any entries. + * 2. If yes + * 1. Take the first entrie's time period and find the diff with + * cell->crntTime. + * 2. If the diff is > measInfo->timePeriod then insert before this + * entry. + * 3. Else take the next entry in list + * 4. If reached without adding to list . Append at the end of list. + * 3. If no entries in l2mList add at the first. + */ + lnk = cell->l2mList.first; + node = &measCb->measLnk; + node->node = (PTR)measCb; + while(lnk != NULLP ) + { + oldMeasCb = (RgSchL2MeasCb *)lnk->node; + diffTime = (oldMeasCb->measReq.timePrd - + (RGSCH_CALC_SF_DIFF(cell->crntTime, oldMeasCb->startTime))); + if (diffTime > measInfo->timePrd) + { + cell->l2mList.crnt = lnk; + cmLListInsCrnt(&(cell->l2mList), node); + RETVALUE(ROK); + } + else + { + lnk = lnk->next; + } + } /* End of While */ + cmLListAdd2Tail(&(cell->l2mList), node); + RETVALUE(ROK); +} /* rgSchL2mInsertMeasCb */ + +/** @brief This function calculates the Down link prb count + * for a DlSf + * + * @details + * + * Function: rgSchL2CalDlPrbCount + * + * @param [in] RgSchCellCb *cell + */ +#ifdef ANSI +PRIVATE Void rgSchL2CalDlPrbCount +( +RgSchCellCb *cell +) +#else +PRIVATE Void rgSchL2CalDlPrbCount(cell) +RgSchCellCb *cell; +#endif +{ + CmLteTimingInfo frm; + RgSchDlSf *sf = NULLP; +#ifdef LTE_TDD + U8 idx; +#endif + + TRC3(rgSchL2CalDlPrbCount) + + frm = cell->crntTime; + RGSCH_INCR_SUB_FRAME(frm, RG_SCH_CMN_DL_DELTA); + sf = rgSCHUtlSubFrmGet(cell, frm); +#ifdef LTE_TDD + idx = (cell->crntTime.subframe + RG_SCH_CMN_DL_DELTA) % + RGSCH_NUM_SUB_FRAMES; + if(RG_SCH_CMN_CHK_DL_DATA_ALLOWED(cell, idx)) + { + cell->avgPrbDl.prbCount += sf->bwAssigned; + dlPrbCnt += sf->bwAssigned; + } +#else + cell->avgPrbDl.prbCount += sf->bwAssigned; +#endif + RETVOID; +} + +/** @brief This function calculates the up link prb count + * for a UlSf + * + * @details + * + * Function: rgSchL2CalUlPrbCount + * + * @param [in] RgSchCellCb *cell + */ +#ifdef ANSI +PRIVATE Void rgSchL2CalUlPrbCount +( +RgSchCellCb *cell +) +#else +PRIVATE Void rgSchL2CalUlPrbCount(cell) +RgSchCellCb *cell; +#endif +{ + RgSchUlSf *sf = NULLP; + RgSchCmnUlCell *cellUl = RG_SCH_CMN_GET_UL_CELL(cell); +#ifdef LTE_TDD + U8 idx; +#endif + + TRC3(rgSchL2CalUlPrbCount) + +#ifdef LTE_TDD + idx = cellUl->schdIdx; + if(idx < cellUl->numUlSubfrms) + { + sf = &cellUl->ulSfArr[idx]; + cell->avgPrbUl.prbCount += sf->totPrb; + } +#else + sf = &cellUl->ulSfArr[cellUl->schdIdx]; + cell->avgPrbUl.prbCount += sf->totPrb; +#endif + RETVOID; +} +/** @brief This function allocates memory from the heap + * + * @details + * + * Function: rgSchL2mAllocMeasCb + * + * @param [in] RgSchCellCb *cell + * @param [in] RgSchL2MeasCb *measInfo + * @param [out] RgSchErrInfo *err + * @return RgSchL2MeasCb * + */ +#ifdef ANSI +PRIVATE RgSchL2MeasCb * rgSchL2mAllocMeasCb +( +RgSchCellCb *cell, +LrgSchMeasReqInfo *measInfo, +RgSchErrInfo err +) +#else +PRIVATE RgSchL2MeasCb * rgSchL2mAllocMeasCb(cell, measInfo, err) +RgSchCellCb *cell; +LrgSchMeasReqInfo *measInfo; +RgSchErrInfo err; +#endif +{ + RgSchL2MeasCb *measCb = NULLP; + Inst inst = cell->instIdx; + UNUSED(err); + TRC3(rgSchL2mAllocMeasCb) + + if((rgSCHUtlAllocSBuf(inst, (Data **)&measCb, + sizeof(RgSchL2MeasCb))) == RFAILED) + { + RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,"rgSchL2mAllocMeasCb():" + "Allocation of RgSchL2MeasCb failed"); + RETVALUE(NULLP); + } + cmMemcpy((U8 *)&measCb->measReq, (U8 *)measInfo, sizeof(LrgSchMeasReqInfo)); + RGSCHCPYTIMEINFO(cell->crntTime, measCb->startTime); + + measCb->dlTotalBw = 0; + measCb->ulTotalBw = 0; + + RETVALUE(measCb); +} /* rgSchL2mAllocMeasCb */ + +/** + * @brief Layer Manager Measurement request handler. + * + * @details + * + * Function : rgSchL2mMeasReq + * + * This function handles measurement request received at scheduler instance + * from the Layer Manager. + * -# Measurement request will be stored in the list in ascending order of + * their time period. + * + * @param[in] Pst *pst, the post structure + * @param[in] LrgSchMeasReqInfo *measInfo, the measurement request structure + * @param[out] RgSchErrInfo *err, error information + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 rgSchL2mMeasReq +( +RgSchCellCb *cell, +LrgSchMeasReqInfo *measInfo, +RgSchErrInfo err +) +#else +PUBLIC S16 rgSchL2mMeasReq(cell, measInfo, err) +RgSchCellCb *cell; +LrgSchMeasReqInfo *measInfo; +RgSchErrInfo err; +#endif +{ + RgSchL2MeasCb *measCb; + U8 idx; + U8 qciVal; + + TRC3(rgSchL2mMeasReq) + + qciVal = 0; + if ((measCb = rgSchL2mAllocMeasCb(cell, measInfo, err)) == NULLP) + { + RGSCHFILLERR(err, RGSCHERR_L2M_MEASREQ, + RGSCHERR_SCH_ALLOC_FAILED); + RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId, "rgSchL2mMeasReq():" + "Allocation of RgSchL2MeasCb failed"); + RETVALUE(RFAILED); + } + /*cmMemcpy((U8 *)&measCb->measReq, (CONSTANT U8 *)measInfo,\ + sizeof(LrgSchMeasReqInfo));*/ + rgSchL2mInsertMeasCb(cell, measCb, measInfo); + + if (measInfo->timePrd == 0) + { + cell->sndL2Meas = FALSE; + if (measInfo->measType & LRG_L2MEAS_AVG_PRB_PER_QCI_DL) + { + for (idx = 0; idx < measInfo->avgPrbQciDl.numQci; idx++) + { + qciVal = measInfo->avgPrbQciDl.qci[idx]; + cell->qciArray[qciVal].qci = qciVal; + } + } + if (measInfo->measType & LRG_L2MEAS_NMB_ACTV_UE_PER_QCI_DL) + { + for (idx = 0; idx < measInfo->nmbActvUeQciDl.numQci; idx++) + { + qciVal = measInfo->nmbActvUeQciDl.qci[idx]; + cell->qciArray[qciVal].qci = qciVal; + } + } + if (measInfo->measType & LRG_L2MEAS_NMB_ACTV_UE_PER_QCI_UL) + { + for (idx = 0; idx < measInfo->nmbActvUeQciUl.numQci; idx++) + { + qciVal = measInfo->nmbActvUeQciUl.qci[idx]; + cell->qciArray[qciVal].qci = qciVal; + } + } + } + /* Here post the message to MAC */ + if(measInfo->measType & LRG_L2MEAS_AVG_PRB_PER_QCI_UL) + { + RgInfL2MeasReq measReq; + Pst pst; + cmMemset((U8 *)&measReq, 0, sizeof(RgInfL2MeasReq)); + measReq.transId = measInfo->hdr.transId; + measReq.measType = measInfo->measType; + measReq.timePrd = measInfo->timePrd; + measReq.cellId = measInfo->cellId; + measReq.t.prbReq.numQci = measInfo->avgPrbQciUl.numQci; + for (idx = 0; idx < measInfo->avgPrbQciUl.numQci; idx++) + { + measReq.t.prbReq.qci[idx] = measInfo->avgPrbQciUl.qci[idx]; + } + /* Send measReq to MAC */ + rgSCHUtlGetPstToLyr(&pst, &rgSchCb[cell->instIdx], cell->macInst); + RgSchMacL2Meas(&pst, &measReq); + } + RETVALUE(ROK); +} /* rgSchL2mMeasReq */ + +/** + * @brief This function calculates the measurement for differnt measurement type + * and send the end result to the layer manager + * + * @details + * + * Function : rgSCHL2Meas + * + * @param[in] RgSchCellCb *cell + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 rgSCHL2Meas +( +RgSchCellCb *cell, +U8 isCalrCrcInd +) +#else +PUBLIC S16 rgschL2Meas(cell,isCalrCrcInd) +RgSchCellCb *cell; +U8 isCalrCrcInd +#endif +{ + CmLList *node = NULLP; + RgSchL2MeasCb *measCb = NULLP; + U8 idx; + LrgSchMeasCfmInfo measCfm; + U8 qciVal = 0; + U32 sfDiff; + U32 meas; +#ifdef LTE_TDD + U8 sfIdx; + Bool isDlDataAllowed; + U8 rem; + U32 numDlSf; + U32 numUlSf; +#endif + TRC3(rgSCHL2Meas) + + node = cell->l2mList.first; + cmMemset((U8 *)&measCfm, 0, sizeof(LrgSchMeasCfmInfo)); + while(node != NULLP) + { + measCb = (RgSchL2MeasCb *)node->node; + node = node->next; + if(cell->crntTime.sfn == 1023 && cell->crntTime.subframe == 9) + { + /*calculates diff between crnt time and start time*/ + meas = RGSCH_CALC_SFN_SF_DIFF(cell->crntTime, + measCb->sfnCycle, measCb->startTime); + measCb->sfnCycle++; + } + else + { + /*calculates diff between crnt time and start time*/ + meas = RGSCH_CALC_SFN_SF_DIFF(cell->crntTime, + measCb->sfnCycle, measCb->startTime); + } + + if (cell->sndL2Meas || meas == measCb->measReq.timePrd) + { +#ifdef LTE_TDD + rem = meas % RGSCH_NUM_SUB_FRAMES; + /* Get the total number of DL and UL subframes within the reporting period*/ + numDlSf = (meas / RGSCH_NUM_SUB_FRAMES) * rgSchTddNumDlSubfrmTbl[cell->ulDlCfgIdx][RGSCH_NUM_SUB_FRAMES-1]; + numUlSf = (meas / RGSCH_NUM_SUB_FRAMES) * rgSchTddNumUlSubfrmTbl[cell->ulDlCfgIdx][RGSCH_NUM_SUB_FRAMES-1]; + + sfIdx = (measCb->startTime.subframe + 1) % RGSCH_NUM_SUB_FRAMES; + + while(rem) + { + isDlDataAllowed = RG_SCH_CMN_CHK_DL_DATA_ALLOWED(cell, sfIdx); + if(isDlDataAllowed) + { + numDlSf++; + } + else if(rgSchTddUlDlSubfrmTbl[cell->ulDlCfgIdx][sfIdx] == + RG_SCH_TDD_UL_SUBFRAME) + { + numUlSf++; + } + sfIdx = (sfIdx + 1) % RGSCH_NUM_SUB_FRAMES; + rem--; + } + + measCb->dlTotalBw = numDlSf * cell->bwCfg.dlTotalBw; + measCb->ulTotalBw = numUlSf * cell->bwCfg.ulTotalBw; + +#else + measCb->dlTotalBw = meas * cell->bwCfg.dlTotalBw; + measCb->ulTotalBw = meas * cell->bwCfg.ulTotalBw; +#endif + if((measCb->measReq.measType & LRG_L2MEAS_AVG_PRB_PER_QCI_UL)) + { + if(measCb->cfmRcvd) + { + rgSchFillL2MeasCfm(cell, measCb, &measCfm, meas); + } + else + { + continue; + } + } + else + { + rgSchFillL2MeasCfm(cell, measCb, &measCfm, meas); + } + RgMiLrgSchL2MeasCfm(&(rgSchCb[cell->instIdx].rgSchInit.lmPst), + &measCfm); + cmMemset((U8 *)&measCfm, 0, sizeof(LrgSchMeasCfmInfo)); + + /* Delete this measCb from the list */ + if(measCb->measReq.timePrd > 0) + { + cmLListDelFrm(&cell->l2mList, &measCb->measLnk); + rgSCHUtlFreeSBuf(cell->instIdx, (Data **)&measCb, + sizeof(RgSchL2MeasCb)); + } + else/*do not delete measCb, will use for next measurement*/ + { + measCb->startTime = cell->crntTime; + measCb->sfnCycle = 0; + measCb->cfmRcvd = FALSE; + cmMemset((U8 *)&measCb->avgPrbQciUl, 0, sizeof(LrgAvgPrbQCICfm)); + cell->sndL2Meas = FALSE; + } + /* ccpu00117052 - MOD - Passing double pointer + for proper NULLP assignment*/ + } + else + { + /* Just update the AVERAGE UL PRB counter here and return + * if the caller is CRCIndication() and the UL scheduling happens + * as a part of it*/ +#ifdef RG_ULSCHED_AT_CRC + if(isCalrCrcInd) + { + if(measCb->measReq.measType & LRG_L2MEAS_AVG_PRB_UL) + { + rgSchL2CalUlPrbCount(cell); + } + continue; + } +#else + /* UL PRB counter gets updated as a part of CRC indication + * if the UL scheduling happens there */ + if((measCb->measReq.measType & LRG_L2MEAS_AVG_PRB_UL)) + { + rgSchL2CalUlPrbCount(cell); + } +#endif + if((measCb->measReq.measType & LRG_L2MEAS_AVG_PRB_DL)) + { + rgSchL2CalDlPrbCount(cell); + } + if(measCb->measReq.measType & LRG_L2MEAS_NMB_ACTV_UE_PER_QCI_DL) + { + sfDiff = RGSCH_CALC_SF_DIFF(cell->crntTime, measCb->startTime); + + if((sfDiff % measCb->measReq.nmbActvUeQciDl.sampPrd) == 0) + { + if (measCb->measReq.nmbActvUeQciDl.numQci) + { + for (idx = 0; idx < measCb->measReq.nmbActvUeQciDl.numQci; + idx++) + { + qciVal = measCb->measReq.nmbActvUeQciDl.qci[idx]; + cell->qciArray[qciVal].dlTotal_UeCount += + cell->qciArray[qciVal].dlUeCount; + } + } + else + { + for (qciVal = 1; qciVal < LRG_MAX_QCI_PER_REQ; qciVal++) + { + cell->qciArray[qciVal].dlTotal_UeCount += + cell->qciArray[qciVal].dlUeCount; + } + } + } + } + if(measCb->measReq.measType & LRG_L2MEAS_NMB_ACTV_UE_PER_QCI_UL) + { + sfDiff = RGSCH_CALC_SF_DIFF(cell->crntTime , measCb->startTime); + if((sfDiff % measCb->measReq.nmbActvUeQciUl.sampPrd) == 0) + { + if (measCb->measReq.nmbActvUeQciUl.numQci) + { + for (idx = 0; idx < measCb->measReq.nmbActvUeQciUl.numQci; + idx++) + { + qciVal = measCb->measReq.nmbActvUeQciUl.qci[idx]; + cell->qciArray[qciVal].ulTotal_UeCount += + cell->qciArray[qciVal].ulUeCount; + } + } + else + { + for (qciVal = 1; qciVal < LRG_MAX_QCI_PER_REQ; qciVal++) + { + cell->qciArray[qciVal].ulTotal_UeCount += + cell->qciArray[qciVal].ulUeCount; + } + } + } + } + } + }/* end of while */ + RETVALUE(ROK); +} /* rgSCHL2MEas */ +#endif /* LTE_L2_MEAS */ +/********************************************************************** + + End of file +**********************************************************************/ diff --git a/src/5gnrmac/rg_sch_lmm.c b/src/5gnrmac/rg_sch_lmm.c new file mode 100755 index 000000000..f451a1e9d --- /dev/null +++ b/src/5gnrmac/rg_sch_lmm.c @@ -0,0 +1,1458 @@ +/******************************************************************************* +################################################################################ +# Copyright (c) [2017-2019] [Radisys] # +# # +# 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. # +################################################################################ +*******************************************************************************/ + +/************************************************************************ + + Name: LTE-MAC layer + + Type: C source file + + Desc: C source code for Layer Manager Interface Module + + File: rg_sch_lmm.c + +**********************************************************************/ + +/** @file rg_sch_lmm.c +@brief This file contains the Layer Management interface module implementation for scheduler. + The functions for the configuration, control, status and statistics + request primitives are defined here. +*/ + +static const char* RLOG_MODULE_NAME="MAC"; +static int RLOG_MODULE_ID=4096; +static int RLOG_FILE_ID=167; + +/* header include files (.h) */ +#include "envopt.h" /* environment options */ +#include "envdep.h" /* environment dependent */ +#include "envind.h" /* environment independent */ +#include "gen.h" /* general */ +#include "ssi.h" /* system services */ +#include "cm_tkns.h" /* Common Token Defines */ +#include "cm_llist.h" /* Common Link List Defines */ +#include "cm_hash.h" /* Common Hash List Defines */ +#include "cm_mblk.h" /* common memory link list library */ +#include "cm_lte.h" /* Common LTE Defines */ +#include "rg_env.h" /* MAC Environment Defines */ +#include "rgr.h" /* RGR Interface defines */ +#include "tfu.h" /* RGU Interface defines */ +#include "lrg.h" /* LRG Interface defines */ +#include "rgm.h" /* RGM Interface defines */ +#include "rg_sch.h" /* Scheduler defines */ +#include "rg_sch_inf.h" /* Scheduler defines */ +#include "rg_sch_err.h" /* MAC error defines */ +#ifdef LTE_L2_MEAS +#include "rg_sch_cmn.h" /* typedefs for Scheduler */ +#endif +#include "rl_interface.h" +#include "rl_common.h" + +/* header/extern include files (.x) */ +#include "gen.x" /* general */ +#include "ssi.x" /* system services */ +#include "cm5.x" /* system services */ +#include "cm_tkns.x" /* Common Token Definitions */ +#include "cm_llist.x" /* Common Link List Definitions */ +#include "cm_lib.x" /* Common Library Definitions */ +#include "cm_hash.x" /* Common Hash List Definitions */ +#include "cm_mblk.x" /* common memory link list library */ +#include "cm_lte.x" /* Common LTE Defines */ +#include "rgr.x" /* RGR Interface includes */ +#include "rgm.x" /* RGM Interface includes */ +#include "tfu.x" /* RGU Interface includes */ +#include "lrg.x" /* LRG Interface includes */ +#include "rg_sch_inf.x" /* Scheduler defines */ +#include "rg_sch.x" /* Scheduler includes */ +#ifdef LTE_L2_MEAS +#include "rg_sch_cmn.x" /* typedefs for Scheduler */ +#endif +#ifndef LTE_L2_MEAS +PUBLIC Void rgSCHCmnInit ARGS((Void)); +#endif +/* forward references */ + + +PRIVATE U16 rgSCHLmmSapCfg ARGS(( + Inst inst, + RgCfg *cfg, + U8 sapIdx, + Elmnt sapType +)); + +PRIVATE Void rgSCHLmmShutdown ARGS(( + Inst inst +)); + + +PUBLIC void printSchCellInfo(void) +{ + U8 idx=0; + U8 inst=0; + for (idx = 0; idx < rgSchCb[inst].numSaps; idx++) + { + /* Unbind all the TFU SAP */ + /* Free the memory held by the cell associated + * with this SAP */ + if (rgSchCb[inst].tfuSap[idx].cell != NULLP) + { + RLOG1(L_INFO,"CELL %d\n", idx); + RLOG1(L_INFO,"NUM UEs :%d\n",rgSchCb[inst].tfuSap[idx].cell->ueLst.nmbEnt); + } + } +} + + +/** + * @brief Task Initiation callback function. + * + * @details + * + * Function : schActvInit + * + * This function is supplied as one of parameters during MAC's + * task registration. SSI will invoke this function once, after + * it creates and attaches this TAPA Task to a system task. + * + * @param[in] Ent Entity, the entity ID of this task. + * @param[in] Inst Inst, the instance ID of this task. + * @param[in] Region Region, the region ID registered for memory + * usage of this task. + * @param[in] Reason Reason. + * @return S16 + * -# ROK + **/ +#ifdef ANSI +PUBLIC S16 schActvInit +( +Ent entity, /* entity */ +Inst instId, /* instance */ +Region region, /* region */ +Reason reason /* reason */ +) +#else +PUBLIC S16 schActvInit(entity, instId, region, reason) +Ent entity; /* entity */ +Inst instId; /* instance */ +Region region; /* region */ +Reason reason; /* reason */ +#endif +{ + Inst inst = (instId - RGSCH_INST_START); + + TRC2(schActvInit); + + /* Initialize the MAC TskInit structure to zero */ + cmMemset ((U8 *)&rgSchCb[inst], 0, sizeof(RgSchCb)); + + /* Initialize the MAC TskInit with received values */ + rgSchCb[inst].rgSchInit.ent = entity; + rgSchCb[inst].rgSchInit.inst = inst; + rgSchCb[inst].rgSchInit.region = region; + rgSchCb[inst].rgSchInit.pool = 0; + rgSchCb[inst].rgSchInit.reason = reason; + rgSchCb[inst].rgSchInit.cfgDone = FALSE; + rgSchCb[inst].rgSchInit.acnt = FALSE; + rgSchCb[inst].rgSchInit.usta = FALSE; + rgSchCb[inst].rgSchInit.trc = FALSE; +#ifdef DEBUGP +#ifdef RG_DEBUG + /* disabling debugs by default */ + /* rgSchCb[inst].rgSchInit.dbgMask = 0xffffffff; */ +#endif +#endif /* DEBUGP */ + rgSchCb[inst].rgSchInit.procId = SFndProcId(); + + rgSchCb[inst].rgrSap = NULLP; + rgSchCb[inst].tfuSap = NULLP; + rgSchCb[inst].rgmSap = NULLP; + rgSCHCmnInit(); + + RETVALUE(ROK); +} /* schActvInit */ + + +/** + * @brief SAP Configuration Handler. + * + * @details + * + * Function : rgSCHLmmSapCfg + * + * This function in called by RgMiLrgSchCfgReq(). It handles the + * interface SAP configuration of the scheduler instance. It + * initializes the sapState to LRG_UNBND. Returns + * reason for success/failure of this function. + * + * @param[in] RgCfg *cfg, the Configuaration information + * @return U16 + * -# LCM_REASON_GENCFG_NOT_DONE + * -# LCM_REASON_INVALID_SAP + * -# LCM_REASON_NOT_APPL + **/ +#ifdef ANSI +PRIVATE U16 rgSCHLmmSapCfg +( +Inst dInst, +RgCfg *cfg, /* Configuaration information */ +U8 sapIdx, /* SAP index */ +Elmnt sapType /* SAP Type */ +) +#else +PRIVATE U16 rgSCHLmmSapCfg(dInst, cfg, sapIdx, sapType) +Inst dInst; +RgCfg *cfg; /* Configuaration information */ +U8 sapIdx; /* SAP index */ +Elmnt sapType; /* SAP Type */ +#endif +{ + U16 ret = LCM_REASON_NOT_APPL; + RgSchLowSapCfgInfo *lowSapCfg = NULLP; + RgSchUpSapCfgInfo *upSapCfg = NULLP; + Inst inst = (dInst - RGSCH_INST_START); + + TRC2(rgSCHLmmSapCfg) + + /* Check if Gen Config has been done */ + + switch(sapType) + { + case STRGRSAP: +#ifndef CL_MAC_LWLC + if ((cfg->s.schInstCfg.rgrSap[sapIdx].selector != RGR_SEL_TC) && + (cfg->s.schInstCfg.rgrSap[sapIdx].selector != RGR_SEL_LC)) + { + ret = LCM_REASON_INVALID_PAR_VAL; + RLOG_ARG0(L_ERROR,DBG_INSTID,inst, "rgSCHLmmSapCfg(): unsupported" + " Selector value for RGR."); + break; + } +#endif + if(rgSchCb[inst].rgrSap[sapIdx].sapSta.sapState == LRG_NOT_CFG) + { + rgSchCb[inst].rgrSap[sapIdx].sapSta.sapState = LRG_UNBND; + } + upSapCfg = &rgSchCb[inst].rgrSap[sapIdx].sapCfg; + + upSapCfg->sapPst.dstEnt = cfg->s.schInstCfg.rgrSap[sapIdx].ent; + upSapCfg->sapPst.dstInst = cfg->s.schInstCfg.rgrSap[sapIdx].inst; + upSapCfg->sapPst.dstProcId = cfg->s.schInstCfg.rgrSap[sapIdx].procId; + upSapCfg->sapPst.srcEnt = rgSchCb[inst].rgSchInit.ent; + upSapCfg->sapPst.srcInst = rgSchCb[inst].rgSchInit.inst + + RGSCH_INST_START; + upSapCfg->sapPst.srcProcId = rgSchCb[inst].rgSchInit.procId; + upSapCfg->sapPst.region = cfg->s.schInstCfg.rgrSap[sapIdx].mem.region; + upSapCfg->sapPst.pool = cfg->s.schInstCfg.rgrSap[sapIdx].mem.pool; + upSapCfg->sapPst.selector = cfg->s.schInstCfg.rgrSap[sapIdx].selector; + upSapCfg->sapPst.route = cfg->s.schInstCfg.rgrSap[sapIdx].route; + upSapCfg->sapPst.intfVer = 0; + upSapCfg->sapPst.event = 0; + upSapCfg->sapPst.prior = cfg->s.schInstCfg.rgrSap[sapIdx].prior; + upSapCfg->suId = cfg->s.schInstCfg.rgrSap[sapIdx].suId; + upSapCfg->spId = cfg->s.schInstCfg.rgrSap[sapIdx].spId; + break; + case STTFUSAP: +#ifndef CL_MAC_LWLC + if ((cfg->s.schInstCfg.tfuSap[sapIdx].selector != TFU_SEL_TC) && + (cfg->s.schInstCfg.tfuSap[sapIdx].selector != TFU_SEL_LC)) + { + ret = LCM_REASON_INVALID_PAR_VAL; + RLOG_ARG0(L_ERROR,DBG_INSTID,inst, "rgSCHLmmSapCfg(): unsupported" + " Selector value for TFU."); + break; + } +#endif + if (rgSchCb[inst].tfuSap[sapIdx].sapSta.sapState == LRG_NOT_CFG) + { + rgSchCb[inst].tfuSap[sapIdx].sapSta.sapState = LRG_UNBND; + } + /* Initialize the sap timer */ + cmInitTimers(&(rgSchCb[inst].tfuSap[sapIdx].tmrBlk), 1); + lowSapCfg = &rgSchCb[inst].tfuSap[sapIdx].sapCfg; + + lowSapCfg->sapPst.dstEnt = cfg->s.schInstCfg.tfuSap[sapIdx].ent; + lowSapCfg->sapPst.dstInst = cfg->s.schInstCfg.tfuSap[sapIdx].inst; + lowSapCfg->sapPst.dstProcId = cfg->s.schInstCfg.tfuSap[sapIdx].procId; + lowSapCfg->sapPst.srcEnt = rgSchCb[inst].rgSchInit.ent; + lowSapCfg->sapPst.srcInst = rgSchCb[inst].rgSchInit.inst + + RGSCH_INST_START; + lowSapCfg->sapPst.srcProcId = rgSchCb[inst].rgSchInit.procId; + lowSapCfg->sapPst.region = cfg->s.schInstCfg.tfuSap[sapIdx].mem.region; + lowSapCfg->sapPst.pool = cfg->s.schInstCfg.tfuSap[sapIdx].mem.pool; + lowSapCfg->sapPst.selector = cfg->s.schInstCfg.tfuSap[sapIdx].selector; + lowSapCfg->sapPst.route = cfg->s.schInstCfg.tfuSap[sapIdx].route; + lowSapCfg->sapPst.intfVer = 0; + lowSapCfg->sapPst.event = 0; + lowSapCfg->sapPst.prior = cfg->s.schInstCfg.tfuSap[sapIdx].prior; + lowSapCfg->suId = cfg->s.schInstCfg.tfuSap[sapIdx].suId; + lowSapCfg->spId = cfg->s.schInstCfg.tfuSap[sapIdx].spId; + cmMemcpy((U8 *)&lowSapCfg->bndTmr, + (U8 *)&cfg->s.schInstCfg.tfuSap[sapIdx].bndTmr, + sizeof(TmrCfg)); + break; + case STRGMSAP: +#ifndef RGM_LWLC + if ((cfg->s.schInstCfg.rgmSap[sapIdx].selector != RGM_SEL_LWLC) && + (cfg->s.schInstCfg.rgmSap[sapIdx].selector != RGM_SEL_LC) && + (cfg->s.schInstCfg.rgmSap[sapIdx].selector != RGM_SEL_TC)) + { + ret = LCM_REASON_INVALID_PAR_VAL; + RLOG_ARG0(L_ERROR,DBG_INSTID,inst, "rgSCHLmmSapCfg(): unsupported" + " Selector value for RGM."); + break; + } +#endif + if (rgSchCb[inst].rgmSap[sapIdx].sapSta.sapState == LRG_NOT_CFG) + { + rgSchCb[inst].rgmSap[sapIdx].sapSta.sapState = LRG_UNBND; + } + upSapCfg = &rgSchCb[inst].rgmSap[sapIdx].sapCfg; + upSapCfg->sapPst.dstEnt = cfg->s.schInstCfg.rgmSap[sapIdx].ent; + upSapCfg->sapPst.dstInst = cfg->s.schInstCfg.rgmSap[sapIdx].inst; + upSapCfg->sapPst.dstProcId = cfg->s.schInstCfg.rgmSap[sapIdx].procId; + upSapCfg->sapPst.srcEnt = rgSchCb[inst].rgSchInit.ent; + upSapCfg->sapPst.srcInst = rgSchCb[inst].rgSchInit.inst + + RGSCH_INST_START; + upSapCfg->sapPst.srcProcId = rgSchCb[inst].rgSchInit.procId; + upSapCfg->sapPst.region = cfg->s.schInstCfg.rgmSap[sapIdx].mem.region; + upSapCfg->sapPst.pool = cfg->s.schInstCfg.rgmSap[sapIdx].mem.pool; + upSapCfg->sapPst.selector = cfg->s.schInstCfg.rgmSap[sapIdx].selector; + upSapCfg->sapPst.route = cfg->s.schInstCfg.rgmSap[sapIdx].route; + upSapCfg->sapPst.intfVer = 0; + upSapCfg->sapPst.event = 0; + upSapCfg->sapPst.prior = cfg->s.schInstCfg.rgmSap[sapIdx].prior; + upSapCfg->suId = cfg->s.schInstCfg.rgmSap[sapIdx].suId; + upSapCfg->spId = cfg->s.schInstCfg.rgmSap[sapIdx].spId; + + break; + default: + /* would never reach here */ + break; + } + RETVALUE(ret); +} + + +/** + * @brief Scheduler instance Configuration Handler. + * + * @details + * + * Function : rgSCHLmmInstCfg + * + * This function in called by RgMiLrgSchCfgReq(). It handles the + * general and SAP configurations of the scheduler instance. It initializes + * the hash lists of rgSchCb. Returns + * reason for success/failure of this function. + * + * @param[in] RgCfg *cfg, the Configuaration information + * @return U16 + * -# LCM_REASON_NOT_APPL + * -# LCM_REASON_INVALID_MSGTYPE + * -# LCM_REASON_MEM_NOAVAIL + **/ +#ifdef ANSI +PUBLIC U16 rgSCHLmmInstCfg +( +RgCfg *cfg, /* Configuaration information */ +Inst dInst +) +#else +PUBLIC U16 rgSCHLmmInstCfg(cfg,dInst) +RgCfg *cfg; /* Configuaration information */ +Inst dInst; +#endif +{ + U16 ret = LCM_REASON_NOT_APPL; + Inst inst = (dInst - RGSCH_INST_START); + U8 idx; + + TRC2(rgSCHLmmInstCfg) + + /* Check if Instance Configuration is done already */ + if (rgSchCb[inst].rgSchInit.cfgDone == TRUE) + { + RETVALUE(LCM_REASON_INVALID_MSGTYPE); + } + if ((cfg->s.schInstCfg.genCfg.lmPst.selector != LRG_SEL_TC) && + (cfg->s.schInstCfg.genCfg.lmPst.selector != LRG_SEL_LC)) + { + RLOG_ARG0(L_ERROR,DBG_INSTID,inst, "rgSCHLmmInstCfg(): unsupported " + "Selector value for lmPst."); + RETVALUE(LCM_REASON_INVALID_PAR_VAL); + } + /* Update the Pst structure for LM interface */ + cmMemcpy((U8 *)&rgSchCb[inst].rgSchInit.lmPst, + (U8 *)&cfg->s.schInstCfg.genCfg.lmPst, + sizeof(Pst)); + + rgSchCb[inst].rgSchInit.inst = inst; + rgSchCb[inst].rgSchInit.lmPst.srcProcId = rgSchCb[inst].rgSchInit.procId; + rgSchCb[inst].rgSchInit.lmPst.srcEnt = rgSchCb[inst].rgSchInit.ent; + rgSchCb[inst].rgSchInit.lmPst.srcInst = rgSchCb[inst].rgSchInit.inst + + RGSCH_INST_START; + rgSchCb[inst].rgSchInit.lmPst.event = EVTNONE; + + rgSchCb[inst].rgSchInit.region = cfg->s.schInstCfg.genCfg.mem.region; + rgSchCb[inst].rgSchInit.pool = cfg->s.schInstCfg.genCfg.mem.pool; + rgSchCb[inst].genCfg.tmrRes = cfg->s.schInstCfg.genCfg.tmrRes; +#ifdef LTE_ADV + rgSchCb[inst].genCfg.forceCntrlSrbBoOnPCel = cfg->s.schInstCfg.genCfg.forceCntrlSrbBoOnPCel; + rgSchCb[inst].genCfg.isSCellActDeactAlgoEnable = cfg->s.schInstCfg.genCfg.isSCellActDeactAlgoEnable; +#endif + rgSchCb[inst].genCfg.startCellId = cfg->s.schInstCfg.genCfg.startCellId; + + /* allocate RGR saps */ + if (SGetSBuf(rgSchCb[inst].rgSchInit.region, + rgSchCb[inst].rgSchInit.pool, + (Data **)&rgSchCb[inst].rgrSap, + (sizeof(RgSchUpSapCb) * cfg->s.schInstCfg.numSaps)) != ROK) + { + RLOG_ARG0(L_ERROR,DBG_INSTID,inst, "rgSCHLmmInstCfg: SGetSBuf for " + "RGR saps failed"); + RETVALUE(RFAILED); + } + /* allocate RGM saps */ + if (SGetSBuf(rgSchCb[inst].rgSchInit.region, + rgSchCb[inst].rgSchInit.pool, + (Data **)&rgSchCb[inst].rgmSap, + (sizeof(RgSchUpSapCb) * cfg->s.schInstCfg.numSaps)) != ROK) + { + RLOG_ARG0(L_ERROR,DBG_INSTID,inst, "rgSCHLmmInstCfg: SGetSBuf for " + "RGM saps failed"); + RETVALUE(RFAILED); + } + + + /* allocate TFU saps */ + if (SGetSBuf(rgSchCb[inst].rgSchInit.region, + rgSchCb[inst].rgSchInit.pool, + (Data **)&rgSchCb[inst].tfuSap, + (sizeof(RgSchLowSapCb) * cfg->s.schInstCfg.numSaps)) != ROK) + { + RLOG_ARG0(L_ERROR,DBG_INSTID,inst, "rgSCHLmmInstCfg: SGetSBuf for TFU " + "saps failed"); + RETVALUE(RFAILED); + } + + /* allocate for bndCfmResponses */ + if (SGetSBuf(rgSchCb[inst].rgSchInit.region, + rgSchCb[inst].rgSchInit.pool, + (Data **)&rgSchCb[inst].genCfg.bndCfmResp, + (sizeof(RgSchLmResponse) * cfg->s.schInstCfg.numSaps)) != ROK) + { + RLOG_ARG0(L_ERROR,DBG_INSTID,inst, "rgSCHLmmInstCfg: SGetSBuf for bind" + " confirm responses failed"); + RETVALUE(RFAILED); + } + +#ifdef LTE_ADV + rgSCHLaaInitEnbCb(&rgSchCb[inst]); +#endif + + rgSchCb[inst].numSaps = cfg->s.schInstCfg.numSaps; + for (idx = 0; idx < cfg->s.schInstCfg.numSaps; idx++) + { + /* Initialize SAP State and configure SAP */ + rgSchCb[inst].rgrSap[idx].sapSta.sapState = LRG_NOT_CFG; + rgSchCb[inst].rgrSap[idx].cell = NULLP; + rgSCHLmmSapCfg(dInst, cfg, idx, STRGRSAP); + + rgSchCb[inst].rgmSap[idx].sapSta.sapState = LRG_NOT_CFG; + rgSchCb[inst].rgmSap[idx].cell = NULLP; + rgSCHLmmSapCfg(dInst, cfg, idx, STRGMSAP); + + rgSchCb[inst].tfuSap[idx].sapSta.sapState = LRG_NOT_CFG; + rgSchCb[inst].tfuSap[idx].cell = NULLP; + rgSCHLmmSapCfg(dInst, cfg, idx, STTFUSAP); + rgSchCb[inst].tfuSap[idx].numBndRetries = 0; + } + /* Initialzie the timer queue */ + cmMemset((U8 *)&rgSchCb[inst].tmrTq, 0, sizeof(CmTqType)*RGSCH_TQ_SIZE); + /* Initialize the timer control point */ + cmMemset((U8 *)&rgSchCb[inst].tmrTqCp, 0, sizeof(CmTqCp)); + rgSchCb[inst].tmrTqCp.tmrLen = RGSCH_TQ_SIZE; + + /* SS_MT_TMR needs to be enabled as schActvTmr needs instance information */ + /* Timer Registration request to SSI */ + if (SRegTmrMt(rgSchCb[inst].rgSchInit.ent, dInst, + (S16)rgSchCb[inst].genCfg.tmrRes, schActvTmr) != ROK) + { + RLOG_ARG0(L_ERROR,DBG_INSTID,inst, "rgSCHLmmInstCfg(): Failed to " + "register timer."); + RETVALUE(LCM_REASON_MEM_NOAVAIL); + } + + /* Set Config done in TskInit */ + rgSchCb[inst].rgSchInit.cfgDone = TRUE; + + RETVALUE(ret); +} + + +/*********************************************************** + * + * Func : rgSCHLmmShutdown + * + * + * Desc : Handles the scheduler instance shutdown request. Calls + * rgSCHCfgFreeCellCb(RgSchCellCb*) to handle each cellCb deallocation. + * + * + * Ret : Void + * + * Notes: + * + * File : rg_sch_lmm.c + * + **********************************************************/ +#ifdef ANSI +PRIVATE Void rgSCHLmmShutdown +( +Inst inst +) +#else +PRIVATE Void rgSCHLmmShutdown(inst) +Inst inst; +#endif +{ + Inst dInst = inst + RGSCH_INST_START; + U8 idx; +#ifdef LTE_L2_MEAS + CmLList *lnk = NULLP; + RgSchCb *instCb = &rgSchCb[inst]; + RgSchCellCb *cell = NULLP; + RgSchL2MeasCb *measCb; + U8 ulAllocIdx; + RgSchCmnUlCell *cellUl; + RgSchClcBoRpt *bo = NULL; +#endif + + TRC2(rgSCHLmmShutdown) + +#ifdef LTE_L2_MEAS + for (idx = 0; idx < instCb->numSaps; idx++) + { + /* got the cell break the loop */ + cell = instCb->rgrSap[idx].cell; + if(cell != NULLP) + { + /* Free the memory held up by ulAllocInfo */ + cellUl = RG_SCH_CMN_GET_UL_CELL(cell); +#ifdef LTE_TDD + for(ulAllocIdx = 0; ulAllocIdx < RGSCH_SF_ALLOC_SIZE; ulAllocIdx++) +#else + for(ulAllocIdx = 0; ulAllocIdx < RGSCH_NUM_SUB_FRAMES; ulAllocIdx++) +#endif + { + if(cell->sfAllocArr[ulAllocIdx].ulUeInfo.ulAllocInfo != NULLP) + { + /* ccpu00117052 - MOD - Passing double pointer + for proper NULLP assignment*/ + rgSCHUtlFreeSBuf(cell->instIdx, + (Data **)(&(cell->sfAllocArr[ulAllocIdx].ulUeInfo.\ + ulAllocInfo)), + cellUl->maxAllocPerUlSf * sizeof(RgInfUeUlAlloc)); + } + } + /* Free the memory allocated to measCb */ + lnk = cell->l2mList.first; + while(lnk != NULLP) + { + measCb = (RgSchL2MeasCb *)lnk->node; + cmLListDelFrm(&cell->l2mList, lnk); + lnk = lnk->next; + /* ccpu00117052 - MOD - Passing double pointer + for proper NULLP assignment*/ + rgSCHUtlFreeSBuf(cell->instIdx, (Data **)&measCb,\ + sizeof(RgSchL2MeasCb)); + } + + /* Free mem if any present for boLst for common channels */ + for(idx = 0; idx < RGSCH_MAX_CMN_LC_CB; idx++) + { + lnk = (CmLList *)cell->cmnLcCb[idx].boLst.first; + while (lnk) + { + bo = (RgSchClcBoRpt *)(lnk->node); + lnk = lnk->next; + cmLListDelFrm(&cell->cmnLcCb[idx].boLst, &bo->boLstEnt); + rgSCHUtlFreeSBuf(cell->instIdx, (Data **)&bo, sizeof(RgSchClcBoRpt)); + } + } + } + } +#endif + +#ifdef LTE_ADV + rgSCHLaaDeInitEnbCb(&rgSchCb[inst]); +#endif + for (idx = 0; idx < rgSchCb[inst].numSaps; idx++) + { + /* Unbind all the TFU SAP */ + if(rgSchCb[inst].tfuSap[idx].sapSta.sapState == LRG_WAIT_BNDCFM) + { + rgSCHUtlTfuUBndReq(inst, rgSchCb[inst].tfuSap[idx].sapCfg, LRG_UNBND); + if (rgSchCb[inst].tfuSap[idx].sapCfg.bndTmr.enb == TRUE) + { + rgSCHLmmStopTmr(inst, RGSCH_BNDREQ_TMR, (PTR)&rgSchCb[inst].tfuSap[idx]); + } + rgSchCb[inst].tfuSap[idx].sapSta.sapState = LRG_UNBND; + } + if(rgSchCb[inst].tfuSap[idx].sapSta.sapState == LRG_BND) + { + rgSCHUtlTfuUBndReq(inst, rgSchCb[inst].tfuSap[idx].sapCfg, LRG_UNBND); + rgSchCb[inst].tfuSap[idx].sapSta.sapState = LRG_UNBND; + } + /* Free the memory held by the cell associated with this SAP */ + if (rgSchCb[inst].tfuSap[idx].cell != NULLP) + rgSCHCfgFreeCellCb(rgSchCb[inst].tfuSap[idx].cell); + rgSchCb[inst].tfuSap[idx].cell = NULLP; + } + /* Free the memory held by the scheduler instance */ + /* Deallocate RGR saps */ + SPutSBuf(rgSchCb[inst].rgSchInit.region, + rgSchCb[inst].rgSchInit.pool, + (Data *)rgSchCb[inst].rgrSap, + (sizeof(RgSchUpSapCb) * rgSchCb[inst].numSaps)); + rgSchCb[inst].rgrSap = NULLP; + /* Deallocate RGM saps */ + SPutSBuf(rgSchCb[inst].rgSchInit.region, + rgSchCb[inst].rgSchInit.pool, + (Data *)rgSchCb[inst].rgmSap, + (sizeof(RgSchUpSapCb) * rgSchCb[inst].numSaps)); + rgSchCb[inst].rgmSap = NULLP; + + /* Deallocate TFU saps */ + SPutSBuf(rgSchCb[inst].rgSchInit.region, + rgSchCb[inst].rgSchInit.pool, + (Data *)rgSchCb[inst].tfuSap, + (sizeof(RgSchLowSapCb) * rgSchCb[inst].numSaps)); + rgSchCb[inst].tfuSap = NULLP; + + /* Deallocate bndCfmResponses */ + SPutSBuf(rgSchCb[inst].rgSchInit.region, + rgSchCb[inst].rgSchInit.pool, + (Data *)rgSchCb[inst].genCfg.bndCfmResp, + (sizeof(RgSchLmResponse) * rgSchCb[inst].numSaps)); + rgSchCb[inst].genCfg.bndCfmResp = NULLP; + /* De-register the Timer Service */ + (Void) SDeregTmrMt(rgSchCb[inst].rgSchInit.ent, dInst, + (S16)rgSchCb[inst].genCfg.tmrRes, schActvTmr); + + /* call back the task initialization function to intialize + * the global rgSchCb[inst] Struct */ + schActvInit(rgSchCb[inst].rgSchInit.ent, dInst, rgSchCb[inst].rgSchInit.region, + rgSchCb[inst].rgSchInit.reason); + + /* Set Config done in TskInit */ + rgSchCb[inst].rgSchInit.cfgDone = FALSE; + + RETVOID; +} + + +/*********************************************************** + * + * Func : rgSCHLmmGenCntrl + * + * + * Desc : Processes the LM control request for STGEN elmnt. + * + * + * Ret : Void + * + * Notes: + * + * File : rg_sch_lmm.c + * + **********************************************************/ +#ifdef ANSI +PUBLIC Void rgSCHLmmGenCntrl +( +RgMngmt *cntrl, +RgMngmt *cfm, +Pst *cfmPst +) +#else +PUBLIC Void rgSCHLmmGenCntrl(cntrl, cfm, cfmPst) +RgMngmt *cntrl; +RgMngmt *cfm; +Pst *cfmPst; +#endif +{ + Inst inst = (cfmPst->srcInst - RGSCH_INST_START); /* Scheduler instance ID */ + TRC2(rgSCHLmmGenCntrl) + + cfm->cfm.status = LCM_PRIM_OK; + cfm->cfm.reason = LCM_REASON_NOT_APPL; + + + switch(cntrl->t.cntrl.action) + { + case AENA: + /* Action is Enable */ + switch(cntrl->t.cntrl.subAction) + { + case SAUSTA: + /* Enable Unsolicited Status (alarms) */ + rgSchCb[inst].rgSchInit.usta = TRUE; + /*Store the response and TransId for sending the Alarms */ + cmMemcpy((U8 *)&rgSchCb[inst].genCfg.ustaResp.response, + (U8 *)&cntrl->hdr.response, sizeof(Resp)); + rgSchCb[inst].genCfg.ustaResp.transId = cntrl->hdr.transId; + break; + case SADBG: + /* Enable Debug Printing */ +#ifdef DEBUGP + rgSchCb[inst].rgSchInit.dbgMask |= cntrl->t.cntrl.s.rgDbgCntrl.dbgMask; +#endif + break; +#ifdef PHY_ERROR_LOGING + case SAELMNT: + { + rgSchUlAllocCntr.mcs = cntrl->t.cntrl.s.rgSchUlAllocCntrl.mcs; + rgSchUlAllocCntr.numOfRb = cntrl->t.cntrl.s.rgSchUlAllocCntrl.numOfRb; + rgSchUlAllocCntr.rbStart = cntrl->t.cntrl.s.rgSchUlAllocCntrl.rbStart; + rgSchUlAllocCntr.testStart = cntrl->t.cntrl.s.rgSchUlAllocCntrl.testStart; + rgSchUlAllocCntr.enaLog = cntrl->t.cntrl.s.rgSchUlAllocCntrl.enaLog; + rgSchUlAllocCntr.logTime = cntrl->t.cntrl.s.rgSchUlAllocCntrl.logTime; + rgSchUlAllocCntr.crcOk = 0; + rgSchUlAllocCntr.crcErr = 0; + rgSchUlAllocCntr.numUlPackets = 0; + rgSchUlAllocCntr.numPrach = 0; + rgSchUlAllocCntr.taZero = 0; +#ifdef MAC_SCH_STATS + /* Reset + * L2 + * statistics + * */ + cmMemset((U8 *)&hqRetxStats, 0, sizeof(RgSchHqRetxStats)); + cmMemset((U8 *)&hqFailStats, 0, sizeof(RgSchNackAckStats)); +#endif + break; + } +#endif + default: + cfm->cfm.status = LCM_PRIM_NOK; + cfm->cfm.reason = LCM_REASON_INVALID_PAR_VAL; + RLOG_ARG1(L_ERROR,DBG_INSTID,inst, "rgSCHLmmGenCntrl(): " + "invalid subaction=%d", cntrl->t.cntrl.subAction); + break; + } + break; + case ADISIMM: + /* Action is Diable immidiately */ + switch(cntrl->t.cntrl.subAction) + { + case SAUSTA: + /* Disable Unsolicited Status (alarms) */ + rgSchCb[inst].rgSchInit.usta = FALSE; + break; + case SADBG: + /* Disable Debug Printing */ +#ifdef DEBUGP + rgSchCb[inst].rgSchInit.dbgMask &=\ + ~cntrl->t.cntrl.s.rgDbgCntrl.dbgMask; +#endif + break; + + default: + cfm->cfm.status = LCM_PRIM_NOK; + cfm->cfm.reason = LCM_REASON_INVALID_PAR_VAL; + RLOG_ARG1(L_ERROR,DBG_INSTID,inst, "rgSCHLmmGenCntrl():" + " invalid subaction=%d", cntrl->t.cntrl.subAction); + break; + } + break; + case ASHUTDOWN: + /* Free all the memory dynamically allocated by MAC */ + rgSCHLmmShutdown(inst); + break; + default: + cfm->cfm.status = LCM_PRIM_NOK; + cfm->cfm.reason = LCM_REASON_INVALID_PAR_VAL; + RLOG_ARG1(L_ERROR,DBG_INSTID,inst, "rgSCHLmmGenCntrl(): invalid" + " action=%d", cntrl->t.cntrl.action); + break; + } + RgMiLrgSchCntrlCfm(cfmPst, cfm); + RETVOID; +} + + +/*********************************************************** + * + * Func : rgSCHLmmSapCntrl + * + * + * Desc : Processes the LM control request for STxxxSAP elmnt. + * + * + * Ret : Void + * + * Notes: + * + * File : rg_sch_lmm.c + * + **********************************************************/ +#ifdef ANSI +PUBLIC Void rgSCHLmmSapCntrl +( +RgMngmt *cntrl, +RgMngmt *cfm, +Pst *cfmPst +) +#else +PUBLIC Void rgSCHLmmSapCntrl(cntrl, cfm, cfmPst) +RgMngmt *cntrl; +RgMngmt *cfm; +Pst *cfmPst; +#endif +{ + U8 idx; + + /* TODO Pass InstId instead of using InstId from cfmPst */ + Inst inst = (cfmPst->srcInst - RGSCH_INST_START); /* Scheduler instance Id */ + TRC2(rgSCHLmmSapCntrl) + + /* Only TFU SAP can be controlled by LM */ + switch(cntrl->hdr.elmId.elmnt) + { + case STTFUSAP: + idx = (U8)cntrl->t.cntrl.s.rgSapCntrl.suId; + if (idx > LRG_MAX_SAPS_PER_INST) + { + cfm->cfm.status = LCM_PRIM_NOK; + cfm->cfm.reason = LCM_REASON_INVALID_SAP; + } + switch(cntrl->t.cntrl.action) + { + case ABND: + /* Bind Enable Request */ + if ((rgSchCb[inst].tfuSap[idx].sapSta.sapState == LRG_NOT_CFG) || + (rgSchCb[inst].tfuSap[idx].sapSta.sapState == LRG_BND)) + { + cfm->cfm.status = LCM_PRIM_NOK; + cfm->cfm.reason = LCM_REASON_INVALID_SAP; + } + else + { + if (rgSchCb[inst].tfuSap[idx].sapCfg.bndTmr.enb == TRUE) + { + rgSCHLmmStartTmr(inst, RGSCH_BNDREQ_TMR, + rgSchCb[inst].tfuSap[idx].sapCfg.bndTmr.val, + (PTR)&rgSchCb[inst].tfuSap[idx]); + } + /* Change SAP state */ + rgSchCb[inst].tfuSap[idx].sapSta.sapState = LRG_WAIT_BNDCFM; + rgSchCb[inst].tfuSap[idx].numBndRetries++; + /* Store the response and TransId for sending + * the Control confirm */ + cmMemcpy((U8 *)&rgSchCb[inst].genCfg.bndCfmResp[idx].response, + (U8 *)&cntrl->hdr.response, sizeof(Resp)); + rgSchCb[inst].genCfg.bndCfmResp[idx].transId = + cntrl->hdr.transId; + + cfm->cfm.status = LCM_PRIM_OK_NDONE; + cfm->cfm.reason = LCM_REASON_NOT_APPL; + + /* Sending Control Confirm before sending Bind + * Request to TFU */ + RgMiLrgSchCntrlCfm(cfmPst, cfm); + + rgSCHUtlTfuBndReq(inst, rgSchCb[inst].tfuSap[idx].sapCfg.suId, + rgSchCb[inst].tfuSap[idx].sapCfg.spId); + RETVOID; + } + break; + case AUBND: + /* Unbind request */ + + /* Check if the SAP is configured */ + if( (rgSchCb[inst].tfuSap[idx].sapSta.sapState == LRG_NOT_CFG) || + (rgSchCb[inst].tfuSap[idx].sapSta.sapState == LRG_UNBND)) + { + cfm->cfm.status = LCM_PRIM_NOK; + cfm->cfm.reason = LCM_REASON_INVALID_MSGTYPE; + } + else + { + rgSCHUtlTfuUBndReq(inst, rgSchCb[inst].tfuSap[idx].sapCfg, + TFU_UBNDREQ_MNGMT); + if (rgSchCb[inst].tfuSap[idx].sapCfg.bndTmr.enb == TRUE) + { + rgSCHLmmStopTmr(inst, RGSCH_BNDREQ_TMR, + (PTR)&rgSchCb[inst].tfuSap[idx]); + } + /* Change SAP state */ + rgSchCb[inst].tfuSap[idx].sapSta.sapState = LRG_UNBND; + cfm->cfm.status = LCM_PRIM_OK; + cfm->cfm.reason = LCM_REASON_NOT_APPL; + } + break; + case ADEL: + /* Delete SAP, does initialization of SAP */ + if ((rgSchCb[inst].tfuSap[idx].sapSta.sapState == LRG_WAIT_BNDCFM) || + (rgSchCb[inst].tfuSap[idx].sapSta.sapState == LRG_BND)) + { + rgSCHUtlTfuUBndReq(inst, rgSchCb[inst].tfuSap[idx].sapCfg, + TFU_UBNDREQ_MNGMT); + if (rgSchCb[inst].tfuSap[idx].sapCfg.bndTmr.enb == TRUE) + { + rgSCHLmmStopTmr(inst, RGSCH_BNDREQ_TMR, + (PTR)&rgSchCb[inst].tfuSap[idx]); + } + } + cmMemset((U8 *)&rgSchCb[inst].tfuSap[idx], 0, sizeof(RgSchLowSapCb)); + rgSchCb[inst].tfuSap[idx].sapSta.sapState = LRG_NOT_CFG; + cfm->cfm.status = LCM_PRIM_OK; + cfm->cfm.reason = LCM_REASON_NOT_APPL; + break; + default: + cfm->cfm.status = LCM_PRIM_NOK; + cfm->cfm.reason = LCM_REASON_INVALID_PAR_VAL; + RLOG_ARG1(L_ERROR,DBG_INSTID,inst, "rgSCHLmmSapCntrl(): " + "invalid action=%d", cntrl->t.cntrl.action); + break; + } + break; + case STRGRSAP: + idx = (U8)cntrl->t.cntrl.s.rgSapCntrl.spId; + if (idx > LRG_MAX_SAPS_PER_INST) + { + cfm->cfm.status = LCM_PRIM_NOK; + cfm->cfm.reason = LCM_REASON_INVALID_SAP; + } + switch(cntrl->t.cntrl.action) + { + case ADEL: + cmMemset((U8 *)&rgSchCb[inst].rgrSap[idx], 0, sizeof(RgSchUpSapCb)); + rgSchCb[inst].rgrSap[idx].sapSta.sapState = LRG_NOT_CFG; + cfm->cfm.status = LCM_PRIM_OK; + cfm->cfm.reason = LCM_REASON_NOT_APPL; + break; + default: + cfm->cfm.status = LCM_PRIM_NOK; + cfm->cfm.reason = LCM_REASON_INVALID_PAR_VAL; + RLOG_ARG1(L_ERROR,DBG_INSTID,inst, "rgSCHLmmSapCntrl(): " + "invalid action=%d", cntrl->t.cntrl.action); + break; + } + break; + case STRGMSAP: + idx = (U8)cntrl->t.cntrl.s.rgSapCntrl.spId; + if (idx > LRG_MAX_SAPS_PER_INST) + { + cfm->cfm.status = LCM_PRIM_NOK; + cfm->cfm.reason = LCM_REASON_INVALID_SAP; + } + switch(cntrl->t.cntrl.action) + { + case ADEL: + cmMemset((U8 *)&rgSchCb[inst].rgmSap[idx], 0, sizeof(RgSchUpSapCb)); + rgSchCb[inst].rgmSap[idx].sapSta.sapState = LRG_NOT_CFG; + cfm->cfm.status = LCM_PRIM_OK; + cfm->cfm.reason = LCM_REASON_NOT_APPL; + break; + default: + cfm->cfm.status = LCM_PRIM_NOK; + cfm->cfm.reason = LCM_REASON_INVALID_PAR_VAL; + RLOG_ARG1(L_ERROR,DBG_INSTID,inst, "rgSCHLmmSapCntrl(): " + "invalid action=%d", cntrl->t.cntrl.action); + break; + } + break; + + default: + /* Would never come here. */ + RETVOID; + } + RgMiLrgSchCntrlCfm(cfmPst, cfm); + RETVOID; +} + + +/*********************************************************** + * + * Func : rgSCHLmmFillCfmPst + * + * + * Desc : Fills the Confirmation Post Structure cfmPst using the reqPst + * and the cfm->hdr.response. + * + * + * Ret : Void + * + * Notes: + * + * File : rg_sch_lmm.c + * + **********************************************************/ +#ifdef ANSI +PUBLIC Void rgSCHLmmFillCfmPst +( +Pst *reqPst, +Pst *cfmPst, +RgMngmt *cfm +) +#else +PUBLIC Void rgSCHLmmFillCfmPst(reqPst, cfmPst, cfm) +Pst *reqPst; +Pst *cfmPst; +RgMngmt *cfm; +#endif +{ + Inst inst; + + TRC2(rgSCHLmmFillCfmPst) + + inst = (reqPst->dstInst - RGSCH_INST_START); + + cfmPst->srcEnt = rgSchCb[inst].rgSchInit.ent; + cfmPst->srcInst = rgSchCb[inst].rgSchInit.inst + RGSCH_INST_START; + cfmPst->srcProcId = rgSchCb[inst].rgSchInit.procId; + cfmPst->dstEnt = reqPst->srcEnt; + cfmPst->dstInst = reqPst->srcInst; + cfmPst->dstProcId = reqPst->srcProcId; + + cfmPst->selector = cfm->hdr.response.selector; + cfmPst->prior = cfm->hdr.response.prior; + cfmPst->route = cfm->hdr.response.route; + cfmPst->region = cfm->hdr.response.mem.region; + cfmPst->pool = cfm->hdr.response.mem.pool; + + RETVOID; +} + + +/** + * @brief Timer start handler. + * + * @details + * + * Function : rgSCHLmmStartTmr + * + * This function based on the input parameters starts the timer for + * "tmrVal" duration. As of now scheduler instance uses the timer + * functionality for BndReq only. Hence there is no conditional + * code based on "tmrEvnt". + * + * @param[in] S16 tmrEvnt, the Timer Event + * @param[in] U32 tmrVal, the Wait Time + * @param[in] PTR cb, Entry for which Timer expired + * @return S16 + * -# ROK + **/ +#ifdef ANSI +PUBLIC S16 rgSCHLmmStartTmr +( +Inst inst, +S16 tmrEvnt, /* Timer Event */ +U32 tmrVal, /* Wait Time */ +PTR cb /* Entry for which Timer Expired */ +) +#else +PUBLIC S16 rgSCHLmmStartTmr(inst, tmrEvnt, tmrVal, cb) +Inst inst; /* scheduler instance ID */ +S16 tmrEvnt; /* Timer Event */ +U32 tmrVal; /* Wait Time */ +PTR cb; /* Entry for which Timer Expired */ +#endif +{ + CmTmrArg arg; +/* Inst dInst = inst + RGSCH_INST_START; */ + + TRC2(rgSCHLmmStartTmr) + + UNUSED(tmrEvnt); + + /* Initialize the arg structure */ + cmMemset((U8 *)&arg, 0, sizeof(CmTmrArg)); + + arg.tqCp = &rgSchCb[inst].tmrTqCp; + arg.tq = rgSchCb[inst].tmrTq; + arg.timers = &((RgSchLowSapCb *)cb)->tmrBlk; + arg.cb = cb; + arg.tNum = 0; + arg.max = RGSCH_MAX_TIMER; + arg.evnt = RGSCH_BNDREQ_TMR; + arg.wait = tmrVal; + cmPlcCbTq(&arg); + + RETVALUE(ROK); +} + + +/** + * @brief Timer stop handler. + * + * @details + * + * Function : rgSCHLmmStopTmr + * + * This function based on the input parameters stops the timer for + * "tmrEvnt". As of now Scheduler instance uses the timer functionality for + * BndReq only. Hence there is no conditional code based on "tmrEvnt". + * Once the bind happens and this timer is stopped, the timer functionality + * is deregistered with SSI. As there is no further use of timer processing. + * + * @param[in] S16 tmrEvnt, the Timer Event + * @param[in] PTR cb, Entry for which Timer expired + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 rgSCHLmmStopTmr +( +Inst inst, /* Scheduler instance */ +S16 tmrEvnt, /* Timer Event */ +PTR cb /* Entry for which Timer Expired */ +) +#else +PUBLIC S16 rgSCHLmmStopTmr(inst, tmrEvnt, cb) +Inst inst; /* Scheduler instance */ +S16 tmrEvnt; /* Timer Event */ +PTR cb; /* Entry for which Timer Expired */ +#endif +{ + CmTmrArg arg; + U8 i; + S16 ret; + + TRC2(rgSCHLmmStopTmr) + + ret = RFAILED; + + for(i=0;itmrBlk.tmrEvnt == tmrEvnt) + { + /* Initialize the arg structure */ + cmMemset((U8 *)&arg, 0, sizeof(CmTmrArg)); + + arg.tqCp = &rgSchCb[inst].tmrTqCp; + arg.tq = rgSchCb[inst].tmrTq; + arg.timers = &(((RgSchLowSapCb *)cb)->tmrBlk); + arg.cb = cb; + arg.max = RGSCH_MAX_TIMER; + arg.evnt = tmrEvnt; + + arg.tNum = i; + cmRmvCbTq(&arg); + ret = ROK; + break; + } + + } + + + RETVALUE(ret); +} + + +/** + * @brief Timer Expiry handler. + * + * @details + * + * Function : rgSCHLmmTmrExpiry + * + * This is a callback function used as an input parameter to cmPrcTmr() + * to check expiry of any timer. In this function, we are only concerned + * about tmrEvnt=Bind timer. + * + * @param[in] PTR cb, Entry for which Timer expired + * @param[in] S16 tmrEvnt, the Timer Event + * @return S16 + * -# ROK + **/ +#ifdef ANSI +PUBLIC S16 rgSCHLmmTmrExpiry +( +PTR cb, /* Pointer to timer control block */ +S16 tmrEvnt /* Timer Event */ +) +#else +PUBLIC S16 rgSCHLmmTmrExpiry(cb,tmrEvnt) +PTR cb; /* Pointer to timer control block */ +S16 tmrEvnt; /* Timer Event */ +#endif +{ + S16 ret = ROK; + RgSchLowSapCb *tfuSap = (RgSchLowSapCb *)cb; +#ifdef DEBUGP + Inst inst = tfuSap->cell->instIdx; +#endif + TRC2(rgSCHLmmTmrExpiry) + + + switch(tmrEvnt) + { + case RGSCH_BNDREQ_TMR: + tfuSap->numBndRetries++; + if(tfuSap->numBndRetries > RGSCH_MAX_BNDRETRY) + { + rgSCHLmmStaInd((U8)(tfuSap->sapCfg.sapPst.srcInst - RGSCH_INST_START), + (U16)LCM_CATEGORY_INTERFACE, (U16)LCM_EVENT_BND_FAIL, + (U16)LCM_CAUSE_TMR_EXPIRED, (RgUstaDgn *)NULLP); + } + else + { + /* Restart the bind timer */ + if (tfuSap->sapCfg.bndTmr.enb == TRUE) + { + ret = rgSCHLmmStartTmr((U8)(tfuSap->sapCfg.sapPst.srcInst - RGSCH_INST_START), + RGSCH_BNDREQ_TMR, + (U32)tfuSap->sapCfg.bndTmr.val, cb); + } + + /* Send bind request */ + rgSCHUtlTfuBndReq((U8)(tfuSap->sapCfg.sapPst.srcInst - RGSCH_INST_START), + tfuSap->sapCfg.suId, tfuSap->sapCfg.spId); + } + break; + default: + RLOG_ARG1(L_ERROR,DBG_INSTID,inst, "rgSCHLmmTmrExpiry(): Invalid" + " tmrEvnt=%d", tmrEvnt); + ret = RFAILED; + break; + } + RETVALUE(ret); +} + + +/** + * @brief Layer Manager Control Confirm generation handler + * for Bind Confirm reception at TFU interface. + * RgLiTfuBndCfm() forwards the confirmation to this + * function. All SAP state related handling is restricted + * to LMM modules, hence the cfm forwarding. + * + * @details + * + * Function : rgSCHLmmBndCfm + * + * This API is used by the LIM module of MAC to forward + * the Bind Confirm it receives over the TFU interface. + * + * @param[in] Pst *pst, Post Structure + * @param[in] SuId suId, Service user ID + * @param[in] U8 status, Status + * @return S16 + * -# ROK + **/ +#ifdef ANSI +PUBLIC S16 rgSCHLmmBndCfm +( +Pst *pst, /* Post Structure */ +SuId suId, /* Service user ID */ +U8 status /* Status */ +) +#else +PUBLIC S16 rgSCHLmmBndCfm(pst,suId,status) +Pst *pst; /* Post Structure */ +SuId suId; /* Service user Id */ +U8 status; /* Status */ +#endif +{ + S16 ret = ROK; + RgMngmt cntrlCfm; + Pst cfmPst; + Inst inst = (pst->dstInst - RGSCH_INST_START); /* scheduler instance */ + + TRC2(rgSCHLmmBndCfm) + + + /* check the SAP State */ + switch(rgSchCb[inst].tfuSap[suId].sapSta.sapState) + { + case LRG_WAIT_BNDCFM: + break; + case LRG_BND: + /* SAP is already bound */ + RETVALUE(ROK); + default: + RETVALUE(RFAILED); + } + + cfmPst = rgSchCb[inst].rgSchInit.lmPst; + cfmPst.selector = rgSchCb[inst].genCfg.bndCfmResp[suId].response.selector; + cfmPst.prior = rgSchCb[inst].genCfg.bndCfmResp[suId].response.prior; + cfmPst.route = rgSchCb[inst].genCfg.bndCfmResp[suId].response.route; + cfmPst.region = rgSchCb[inst].genCfg.bndCfmResp[suId].response.mem.region; + cfmPst.pool = rgSchCb[inst].genCfg.bndCfmResp[suId].response.mem.pool; + + cmMemset((U8 *)&cntrlCfm, 0, sizeof(RgMngmt)); + + switch(status) + { + case CM_BND_OK: /* status is OK */ + /* Change SAP state to Bound */ + rgSchCb[inst].tfuSap[suId].sapSta.sapState = LRG_BND; + if (rgSchCb[inst].tfuSap[suId].sapCfg.bndTmr.enb == TRUE) + { + ret = rgSCHLmmStopTmr(inst, RGSCH_BNDREQ_TMR, (PTR)&rgSchCb[inst].tfuSap[suId]); + } + /* Send Control Confirm with status as OK to Layer Manager */ + cntrlCfm.cfm.status = LCM_PRIM_OK; + cntrlCfm.cfm.reason = LCM_REASON_NOT_APPL; + /* Sending Status Indication to Layer Manager */ + rgSCHLmmStaInd((U8)(rgSchCb[inst].tfuSap->sapCfg.sapPst.srcInst - RGSCH_INST_START), + LCM_CATEGORY_INTERFACE, LCM_EVENT_BND_OK, + LCM_CAUSE_LYR_SPECIFIC, (RgUstaDgn *)NULLP); + break; + + default: + /* Change SAP state to UnBound */ + rgSchCb[inst].tfuSap[suId].sapSta.sapState = LRG_UNBND; + if (rgSchCb[inst].tfuSap[suId].sapCfg.bndTmr.enb == TRUE) + { + ret = rgSCHLmmStopTmr(inst, RGSCH_BNDREQ_TMR, (PTR)&rgSchCb[inst].tfuSap[suId]); + } + /* Send Control Confirm with status as NOK to Layer Manager */ + cntrlCfm.cfm.status = LCM_PRIM_NOK; + cntrlCfm.cfm.reason = LCM_REASON_NEG_CFM; + break; + } + rgSchCb[inst].tfuSap[suId].numBndRetries = 0; + cntrlCfm.hdr.elmId.elmnt = STTFUSAP; + cntrlCfm.hdr.transId = rgSchCb[inst].genCfg.bndCfmResp[suId].transId; + + ret = RgMiLrgSchCntrlCfm(&cfmPst, &cntrlCfm); + + RETVALUE(ret); +} + +/** + * @brief Layer Manager Unsolicited Status Indication generation. + * + * @details + * + * Function : rgSCHLmmStaInd + * + * This API is used by the other modules of MAC to send a unsolicited + * status indication to the Layer Manager. + * + * @param[in] U16 category, the Alarm category + * @param[in] U16 event, the Alarm event + * @param[in] U16 cause, the cause of the Alarm + * @param[in] RgUstaDgn *dgn, Alarm Diagonostics + * @return S16 + * -# ROK + **/ +#ifdef ANSI +PUBLIC S16 rgSCHLmmStaInd +( +Inst inst, +U16 category, +U16 event, +U16 cause, +RgUstaDgn *dgn +) +#else +PUBLIC S16 rgSCHLmmStaInd(inst, category, event, cause, dgn) +Inst inst; +U16 category; +U16 event; +U16 cause; +RgUstaDgn *dgn; +#endif +{ + RgMngmt usta; + + TRC2(rgSCHLmmStaInd) + + if(rgSchCb[inst].rgSchInit.usta == FALSE) + { + RETVALUE(ROK); + } + + cmMemset((U8 *)&usta, 0, sizeof(RgMngmt)); + + SGetDateTime(&usta.t.usta.cmAlarm.dt); + usta.t.usta.cmAlarm.category = category; + usta.t.usta.cmAlarm.event = event; + usta.t.usta.cmAlarm.cause = cause; + if (dgn != NULLP) + { + cmMemcpy((U8 *)&usta.t.usta.dgn, (U8 *)dgn, sizeof(RgUstaDgn)); + } + + rgSchCb[inst].rgSchInit.lmPst.selector = + rgSchCb[inst].genCfg.ustaResp.response.selector; + rgSchCb[inst].rgSchInit.lmPst.prior = + rgSchCb[inst].genCfg.ustaResp.response.prior; + rgSchCb[inst].rgSchInit.lmPst.route = + rgSchCb[inst].genCfg.ustaResp.response.route; + rgSchCb[inst].rgSchInit.lmPst.region = + rgSchCb[inst].genCfg.ustaResp.response.mem.region; + rgSchCb[inst].rgSchInit.lmPst.pool = + rgSchCb[inst].genCfg.ustaResp.response.mem.pool; + usta.hdr.transId = rgSchCb[inst].genCfg.ustaResp.transId; + + RETVALUE(RgMiLrgSchStaInd(&rgSchCb[inst].rgSchInit.lmPst, &usta)); +} + + +/** + * @brief Scheduler instance timer call back function registered with SSI. + * + * @details + * + * Function : schActvTmr + * + * This function is invoked by SSI for every timer activation + * period expiry. Note that SS_MT_TMR flag needs to be enabled for this + * as isntId is needed.As part of SRegTmr call for scheduler instance + * SS_MT_TMR flag needs to be enabled and schActvTmr needs to be given as + * callback function + * + * @return S16 + * -# ROK + **/ +#ifdef ANSI +PUBLIC S16 schActvTmr +( +Ent ent, +Inst inst +) +#else +PUBLIC S16 schActvTmr(ent, inst) +Ent ent; +Inst inst; +#endif +{ + Inst schInst = (inst - RGSCH_INST_START); + TRC2(schActvTmr) + + /* Check if any timer in the scheduler instance has expired */ + cmPrcTmr(&rgSchCb[schInst].tmrTqCp, + rgSchCb[schInst].tmrTq, (PFV) rgSCHLmmTmrExpiry); + + RETVALUE(ROK); + +} /* end of schActvTmr */ + + +/********************************************************************** + + End of file +**********************************************************************/ diff --git a/src/5gnrmac/rg_sch_mga.c b/src/5gnrmac/rg_sch_mga.c new file mode 100755 index 000000000..33dcf2dc3 --- /dev/null +++ b/src/5gnrmac/rg_sch_mga.c @@ -0,0 +1,1597 @@ +/******************************************************************************* +################################################################################ +# Copyright (c) [2017-2019] [Radisys] # +# # +# 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. # +################################################################################ +*******************************************************************************/ + +/************************************************************************ + + Name: LTE-MAC layer + + Type: C source file + + Desc: C source code for Scheduler common functions + + File: rg_sch_mga.c + +**********************************************************************/ + +/** @file rg_sch_mga.c +@brief This module handles schedulers' measurement gap and ack-nack repetiton functionality */ + +static const char* RLOG_MODULE_NAME="MAC"; +static int RLOG_MODULE_ID=4096; +static int RLOG_FILE_ID=169; + +/* header include files -- defines (.h) */ +#include "envopt.h" /* environment options */ +#include "envdep.h" /* environment dependent */ +#include "envind.h" /* environment independent */ +#include "gen.h" /* general layer */ +#include "ssi.h" /* system service interface */ +#include "cm_hash.h" /* common hash list */ +#include "cm_llist.h" /* common linked list library */ +#include "cm_err.h" /* common error */ +#include "cm_lte.h" /* common LTE */ +#include "lrg.h" +#include "rgr.h" +#include "tfu.h" +#include "rg_env.h" +#include "rg_sch_inf.h" +#include "rg_sch_err.h" +#include "rg_sch.h" +#include "rg_sch_cmn.h" +#include "rl_interface.h" +#include "rl_common.h" + +/* header/extern include files (.x) */ +#include "gen.x" /* general layer typedefs */ +#include "ssi.x" /* system services typedefs */ +#include "cm5.x" /* common timers */ +#include "cm_hash.x" /* common hash list */ +#include "cm_lib.x" /* common library */ +#include "cm_llist.x" /* common linked list */ +#include "cm_mblk.x" /* memory management */ +#include "cm_tkns.x" /* common tokens */ +#include "cm_lte.x" /* common tokens */ +#include "tfu.x" /* RGU types */ +#include "lrg.x" /* layer management typedefs for MAC */ +#include "rgr.x" /* layer management typedefs for MAC */ +#include "rg_sch_inf.x" /* typedefs for Scheduler */ +#include "rg_sch.x" /* typedefs for Scheduler */ + +/* local defines */ +PRIVATE S16 rgSCHMeasGapANRepUtlAddUe ARGS(( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgrUeMeasGapCfg *cfg)); + +PRIVATE S16 rgSCHMeasGapANRepUtlRmvUe ARGS(( +RgSchCellCb *cell, +RgSchUeCb *ue)); + +PRIVATE S16 rgSchAckNackRepUtlRmvUe ARGS(( + RgSchCellCb *cell, + RgSchUeCb *ue)); + +PRIVATE Void rgSchAckNackRepUtlHdlTti ARGS(( +RgSchCellCb *cell, +CmLListCp *ackNackRepQ)); + +PRIVATE Void rgSCHMeasGapANRepUtlHdlTti ARGS(( +RgSchCellCb *cell, +CmLListCp *measGapQ)); +#ifdef LTE_TDD +PRIVATE U8 rgSCHAckNakRepFindUlDuration ARGS(( +RgSchCellCb *cell, +RgSchDlSf *dlSf, +CmLteTimingInfo repTime, +U8 repCnt)); +PRIVATE Void rgSCHAckNakRepGetUlOffsetFrmDl ARGS(( +RgSchDlSf *dlSf, +CmLteTimingInfo crntDlTime, +U8 *noSubfrms)); +#endif + +/** + * @brief Handles Measurement gap and ack-nack repetition related + * configuration for a UE. + * + * @details + * + * Function : rgSCHMeasGapANRepUeCfg + * + * Invoking Module Processing: + * - This shall be invoked by SCH_GOM at UE configuration. It shall do the + * validations for the spec-defined values. + * + * Processing Steps: + * - For UE-specific measurement gap related configuration, + * - If measurementGap is configured, + * - Update UE with the configured values. + * - Add Ue to cell->measGapCb->gapPrdQ depending on the gap period + * configuration at index = the configured gap offset. + * - measGapOffst = the configured gap offset + * - Initialize timers. + * - else + * - measGapOffst = RG_INVALID_MEASGAPQ_ID + * - For UE-specific ACK-NACK repetition related configuration, + * - Update the configured value. Set 'cfgRepCnt' variable value. + * - repCntr = cfgRepCnt. + * - qOffst = RG_INVALID_ACKNACKREPQ_ID + * - Return ROK + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ue + * @param[in] RgrUeCfg *ueCfg + * + * @return S16 + * -# ROK + **/ + +#ifdef ANSI +PUBLIC S16 rgSCHMeasGapANRepUeCfg +( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgrUeCfg *ueCfg +) +#else +PUBLIC S16 rgSCHMeasGapANRepUeCfg(cell, ue, ueCfg) +RgSchCellCb *cell; +RgSchUeCb *ue; +RgrUeCfg *ueCfg; +#endif +{ + + TRC2(rgSCHMeasGapANRepUeCfg); + + + ue->measGapCb.isMesGapEnabled = ueCfg->ueMesGapCfg.isMesGapEnabled; + + if (ueCfg->ueMesGapCfg.isMesGapEnabled) + { + ue->measGapCb.gapPrd = ueCfg->ueMesGapCfg.gapPrd; + ue->measGapCb.gapOffst = ueCfg->ueMesGapCfg.gapOffst; + rgSCHMeasGapANRepUtlAddUe (cell, ue, &(ueCfg->ueMesGapCfg)); + cmInitTimers (&ue->measGapCb.measGapTmr, 1); + cmInitTimers (&ue->measGapCb.measGapUlInactvTmr, 1); + cmInitTimers (&ue->measGapCb.measGapDlInactvTmr, 1); + } + + /* ACK NACK repetition part */ + if (ueCfg->ueAckNackCfg.isAckNackEnabled) + { + ue->ackNakRepCb.cfgRepCnt = ueCfg->ueAckNackCfg.ackNackRepFactor; + ue->ackNakRepCb.repCntr = ue->ackNakRepCb.cfgRepCnt; + ue->ackNakRepCb.isAckNackEnabled = TRUE; + ue->ackNakRepCb.pucchRes = ueCfg->ueAckNackCfg.pucchAckNackRep; + cmInitTimers (&ue->ackNakRepCb.ackNakRepUlInactvTmr, 1); + cmInitTimers (&ue->ackNakRepCb.ackNakRepDlInactvTmr, 1); + cmInitTimers (&ue->ackNakRepCb.ackNakRepTmr, 1); + } + RETVALUE(ROK); +} + +/** + * @brief Handles Measurement gap and ack-nack repetition related + * re-configuration for a UE. + * + * @details + * + * Function : rgSCHMeasGapANRepUeRecfg + * + * Invoking Module Processing: + * - This shall be invoked by SCH_GOM at UE re-configuration. It shall do the + * validations for the spec-defined values. + * + * Processing Steps: + * - For measurement gap, + * - If measurement gap period or offset is re-configured, remove UE from + * the previous list, if any and add it to the new list. + * - Update configured values appropriately. + * - For ACK-NACK repetition, + * - Update the configured value. Set 'cfgRepCnt' variable value. + * - If (repCntr == 0) + * - repCntr = cfgRepCnt. + * - qOffst = RG_INVALID_ACKNACKREPQ_ID + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ue + * @param[in] RgrUeRecfg *ueRecfg + * + * @return S16 + * -# ROK + * -# RFAILED + **/ + +#ifdef ANSI +PUBLIC S16 rgSCHMeasGapANRepUeRecfg +( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgrUeRecfg *ueRecfg +) +#else +PUBLIC S16 rgSCHMeasGapANRepUeRecfg(cell, ue, ueRecfg) +RgSchCellCb *cell; +RgSchUeCb *ue; +RgrUeRecfg *ueRecfg; +#endif +{ + RgrUeMeasGapCfg *reCfg; + RgSchUeMeasGapCb *ueMeasCb; + RgrUeAckNackRepCfg *ackNackReCfg = &(ueRecfg->ueAckNackRecfg); + RgSchUeAckNakRepCb *ackNakRepCb = &(ue->ackNakRepCb); + + TRC2(rgSCHMeasGapANRepUeRecfg); + + + reCfg = &(ueRecfg->ueMeasGapRecfg); + ueMeasCb = &(ue->measGapCb); + + /* Removed extra comments + * Check this once again Check to see if anything changed or not */ + if ((reCfg->isMesGapEnabled == TRUE) && + (ueMeasCb->isMesGapEnabled == TRUE) && + (reCfg->gapPrd == ueMeasCb->gapPrd) && + (reCfg->gapOffst == ueMeasCb->gapOffst)) + { + /* Nothing changed hence nothing to do */ + } + else + { + if (reCfg->isMesGapEnabled) + { + if (ueMeasCb->isMesGapEnabled) + { + rgSCHMeasGapANRepUtlRmvUe (cell, ue); + } + else + { + cmInitTimers (&ueMeasCb->measGapTmr, 1); + cmInitTimers (&ueMeasCb->measGapUlInactvTmr, 1); + cmInitTimers (&ueMeasCb->measGapDlInactvTmr, 1); + } + + /* Add to the correct Measurement gap queue */ + rgSCHMeasGapANRepUtlAddUe (cell, ue, reCfg); + + ueMeasCb->gapPrd = reCfg->gapPrd; + ueMeasCb->gapOffst = reCfg->gapOffst; + ueMeasCb->isMesGapEnabled = TRUE; + } /* if new config has Measurement gap enabled */ + else + { + if (ueMeasCb->isMesGapEnabled) + { + /* check if return value needed or not */ + rgSCHMeasGapANRepUtlRmvUe (cell, ue); + ueMeasCb->isMesGapEnabled = FALSE; + } + } /* if new config has Measurement gap disabled */ + } /* For MeasGap configuration */ + + if (ackNackReCfg->isAckNackEnabled) + { + if (!ackNakRepCb->isAckNackEnabled) + { + ackNakRepCb->isAckNackEnabled = TRUE; + /* Timers need to be init immediately after config*/ + cmInitTimers (&ue->ackNakRepCb.ackNakRepUlInactvTmr, 1); + cmInitTimers (&ue->ackNakRepCb.ackNakRepDlInactvTmr, 1); + cmInitTimers (&ue->ackNakRepCb.ackNakRepTmr, 1); + } /* repetition was disabled */ + ackNakRepCb->pucchRes = ackNackReCfg->pucchAckNackRep; + ackNakRepCb->cfgRepCnt = ackNackReCfg->ackNackRepFactor; + if (ackNakRepCb->repCntr == 0) + { + ackNakRepCb->repCntr = ackNackReCfg->ackNackRepFactor; + } + } /* repetition enabled in re configuration */ + else + { + ackNakRepCb->isAckNackEnabled = FALSE; + } /* repetition disabled in re configuration */ + + RETVALUE(ROK); +} + + /** @brief This function is a utility to add the UE to the correct Measurement + * queue present in the cellCb. + * + * @details + * + * Function: + * + * Processing steps: + * - + * + * + * @param + * @param + * @return + */ +#ifdef ANSI +PRIVATE S16 rgSCHMeasGapANRepUtlAddUe +( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgrUeMeasGapCfg *cfg +) +#else +PRIVATE S16 rgSCHMeasGapANRepUtlAddUe (cell, ue, cfg) +RgSchCellCb *cell; +RgSchUeCb *ue; +RgrUeMeasGapCfg *cfg; +#endif +{ + + TRC2(rgSCHMeasGapANRepUtlAddUe); + + switch (cfg->gapPrd) + { + case RG_MEAS_GAPPRD_40: + /* Insert the UE into the linked list based on the gap Offset */ + ue->measGapCb.measQLnk.node = (PTR)ue; + cmLListAdd2Tail (&(cell->measGapCb.gapPrd40Q[cfg->gapOffst]), + &(ue->measGapCb.measQLnk)); + break; + case RG_MEAS_GAPPRD_80: + ue->measGapCb.measQLnk.node = (PTR)ue; + cmLListAdd2Tail (&(cell->measGapCb.gapPrd80Q[cfg->gapOffst]), + &(ue->measGapCb.measQLnk)); + break; + default: + RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId, + "rgSCHMeasGapANRepUeRecfg() Incorrect GAP Period" + "CRNTI:%d",ue->ueId); + RETVALUE(RFAILED); + } + RETVALUE(ROK); +} /* end of rgSCHMeasGapANRepUtlAddUe */ + + + /** @brief This function is a utility function to remove the ue from the measQ + * preset in tthe cell Cb. + * + * @details + * + * Function: + * + * Processing steps: + * - + * + * @param + * @param + * @return + */ +#ifdef ANSI +PRIVATE S16 rgSCHMeasGapANRepUtlRmvUe +( +RgSchCellCb *cell, +RgSchUeCb *ue +) +#else +PRIVATE S16 rgSCHMeasGapANRepUtlRmvUe (cell, ue) +RgSchCellCb *cell; +RgSchUeCb *ue; +#endif +{ + + TRC2(rgSCHMeasGapANRepUtlRmvUe); + + switch (ue->measGapCb.gapPrd) + { + case RG_MEAS_GAPPRD_40: + /* Remove from the existing list */ + cmLListDelFrm (&(cell->measGapCb.gapPrd40Q[ue->measGapCb.gapOffst]), + &(ue->measGapCb.measQLnk)); + ue->measGapCb.measQLnk.node = NULLP; + break; + case RG_MEAS_GAPPRD_80: + /* Remove from the existing list */ + cmLListDelFrm (&(cell->measGapCb.gapPrd80Q[ue->measGapCb.gapOffst]), + &(ue->measGapCb.measQLnk)); + ue->measGapCb.measQLnk.node = NULLP; + break; + } + RETVALUE(ROK); +} /* end of rgSCHMeasGapANRepUtlRmvUe */ + +/** + * @brief Frees Measurement gap and ack-nack repetition related data structures in UE + * + * @details + * + * Function : rgSCHMeasGapANRepUeDel + * + * Invoking Module Processing: + * - This shall be invoked by SCH_GOM at Ue deletion. + * + * Processing Steps: + * - For measurement gap, + * - if (measGapOffst != RG_INVALID_MEASGAPQ_ID) + * - Remove from the measurement queue depending on the measGapPrd + * value. + * - Delete all timers + * - For ACK-NACK repetition, + * - if (qOffst != RG_INVALID_ACKNACKREPQ_ID) + * - Remove from the ackNakRepQ queue + * - Delete all timers + * - Return ROK + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ue + * + * @return S16 + * -# ROK + **/ + +#ifdef ANSI +PUBLIC Void rgSCHMeasGapANRepUeDel +( +RgSchCellCb *cell, +RgSchUeCb *ue, +Bool isUeDel +) +#else +PUBLIC Void rgSCHMeasGapANRepUeDel(cell, ue, isUeDel) +RgSchCellCb *cell; +RgSchUeCb *ue; +Bool isUeDel; +#endif +{ + + + TRC2(rgSCHMeasGapANRepUeDel); + + if (ue->measGapCb.isMesGapEnabled) + { + rgSCHMeasGapANRepUtlRmvUe (cell, ue); + /* Must stop the timer if its running */ + if (ue->measGapCb.isMeasuring) + { + rgSCHTmrStopTmr (cell, RG_SCH_TMR_MEASGAP, ue); + } + + ue->measGapCb.isMesGapEnabled = FALSE; + } + + /* Stop timers if running */ + if (ue->dl.dlInactvMask) + { + if (ue->dl.dlInactvMask & RG_MEASGAP_INACTIVE) + { + rgSCHTmrStopTmr (cell, RG_SCH_TMR_DL_MEASGAP, ue); + } + if (ue->dl.dlInactvMask & RG_ACKNAKREP_INACTIVE) + { + rgSCHTmrStopTmr (cell, RG_SCH_TMR_DL_ACKNACK, ue); + } + ue->dl.dlInactvLnk.node = NULLP; + } + if (ue->ul.ulInactvMask) + { + if (ue->ul.ulInactvMask & RG_MEASGAP_INACTIVE) + { + rgSCHTmrStopTmr (cell, RG_SCH_TMR_UL_MEASGAP, ue); + } + if (ue->ul.ulInactvMask & RG_ACKNAKREP_INACTIVE) + { + rgSCHTmrStopTmr (cell, RG_SCH_TMR_UL_ACKNACK, ue); + } + ue->ul.ulInactvLnk.node = NULLP; + } + + /* ccpu00133470- Releasing ACKNACK Rep UE Deleted */ + if (isUeDel & ue->ackNakRepCb.isAckNakRep) + { + rgSCHTmrStopTmr (cell, RG_SCH_TMR_ACKNACK_REP, ue); + rgSchAckNackRepUtlRmvUe (cell, ue); + } + RETVOID; +} + + /** @brief This function deletes the UEs information related to ACK NACK + * repetition. + * + * @details + * + * Function: + * + * Processing steps: + * - Mainly we need to remove the UEs hqProcs from the ackNackQ(s) + * present in the subframes. + * + * + * @param + * @param + * @return + */ +#ifdef ANSI +PRIVATE S16 rgSchAckNackRepUtlRmvUe +( + RgSchCellCb *cell, + RgSchUeCb *ue + ) +#else +PRIVATE S16 rgSchAckNackRepUtlRmvUe (cell, ue) + RgSchCellCb *cell; + RgSchUeCb *ue; +#endif +{ + + + U8 hqIdx; + U8 repIdx; + RgSchDlHqProcCb *hqP; + U8 tbCnt; + + RgSchDlHqEnt *hqEnt = RG_SCH_CMN_GET_UE_HQE(ue, cell); + + TRC3(rgSchAckNackRepUtlRmvUe); + + for (hqIdx = 0; hqIdx < hqEnt->numHqPrcs; hqIdx++) + { + hqP = &hqEnt->procs[hqIdx]; + /* Starting from index 1 as index 0 isn't used */ + for (repIdx = 1; repIdx < ue->ackNakRepCb.cfgRepCnt; repIdx++) + { + for (tbCnt = 0; tbCnt < 2; tbCnt++) + { + if ((hqP->tbInfo[tbCnt].crntSubfrm[repIdx] != NULLP) && + (hqP->tbInfo[tbCnt].anRepLnk[repIdx].node != NULLP)) + { + cmLListDelFrm(&((hqP->tbInfo[tbCnt].crntSubfrm[repIdx])->\ + ackNakRepQ), &hqP->tbInfo[tbCnt].anRepLnk[repIdx]); + hqP->tbInfo[tbCnt].anRepLnk[repIdx].node = NULLP; + hqP->tbInfo[tbCnt].crntSubfrm[repIdx] = NULLP; + } + } + } + } + + RETVALUE(ROK); +} /* end of */ + + +/** + * @brief Per TTI processing for measurement gap and ack nack repetition + * handling. + * + * @details + * + * Function : rgSCHMeasGapANRepTtiHndl + * + * Invoking Module Processing: + * - This shall be invoked by SCH_TOM on recieving TTI indication from PHY + * . SCH_TOM shall update the cell->crntTime before invoking this API. + * + * Processing Steps: + * - Compute qOffset for 40ms queue as = + * ((cell->crntTime->sfn * 10)+cell->crntTime->subframe)%RG_MEAS_GAPPRD_40. + * - Mark all the UEs at computed offset for performing measurement. Set + * isMeasuring = TRUE. + * - Start measGapTmr for each UE: + * - length = RG_MEAS_GAP_LEN. + * - event = RG_MEASGAP_ON + * - handler = rgSCHMeasGapANRepTmrExpry + * - Reinitalize the list at the offset. + * - Compute qOffset for 80ms queue as = + * ((cell->crntTime->sfn * 10)+cell->crntTime->subframe)%RG_MEAS_GAPPRD_80. + * - Mark all the UEs at computed offset for performing measurement. Set + * isMeasuring = TRUE. + * - Start measGapTmr for each UE: + * - length = RG_MEAS_GAP_LEN. + * - event = RG_MEASGAP_ON + * - handler = rgSCHMeasGapANRepTmrExpry + * - Reinitalize the list at the offset. + * - Compute qOffset for ACK NACK repetition queue as = + * ((cell->crntTime->sfn * 10)+cell->crntTime->subframe)%RG_MAX_NUM_DLSF. + * - Mark all the UEs at computed offset for performing ack-nack repetition. Set + * isAckNakRep = TRUE. + * - Start ackNakRepTmr for each UE: + * - length = repCntr. + * - event = RG_ACKNAKREP_ON + * - handler = rgSchAckNakRepTmrExpry + * - Reinitalize the list at the offset. + * - 'isMeasuring' bool value shall be cheked + * - While sending dataRecpReq to PHY for non-adaptive uplink re-tx + * and if 'TRUE', no dataRecpReq shall be sent. + * - While sending NACK as feedback to UE and if 'TRUE' no PHICH shall + * be sent and shall mark the UE for adaptive re-tx. + * - While sending HqFbkRecpReq for a UE (applicable only if ACK NACK + * repetition coincides) and if 'TRUE', + * - The request shall not be sent. + * - Decrement repCntr + * - if (repCntr == 0) + * - Delete UE from the list. + * - Move the Ue to next subframe's list of ACK-NACK repeating UEs. + * - 'isAckNakRep' bool value shall be cheked + * - While sending dataRecpReq to PHY for non-adaptive uplink re-tx + * and if 'TRUE', no dataRecpReq shall be sent. + * - Check if any refresh for these cell-specific queues is needed + * anywhere else as well. + * - Check if TTI miss needs some trigger to the module. + * - Return ROK + * + * @param[in] RgSchCellCb *cell + * + * @return S16 + * -# ROK + **/ + +#ifdef ANSI +PUBLIC S16 rgSCHMeasGapANRepTtiHndl +( +RgSchCellCb *cell +) +#else +PUBLIC S16 rgSCHMeasGapANRepTtiHndl(cell) +RgSchCellCb *cell; +#endif +{ + U8 offset; + CmLListCp *queue; + RgSchDlSf *dlSf; + CmLteTimingInfo repTime; + + TRC2(rgSCHMeasGapANRepTtiHndl); + + /* Measurement GAP Starts at offSet - however at MAC we are concerned at + * subframe + TFU_DELTA. + */ + /* 40ms offset */ + /* Introduced timing delta for DL control in FDD */ +#ifdef LTE_TDD + offset = (cell->crntTime.sfn * RGSCH_NUM_SUB_FRAMES_5G + cell->crntTime.subframe + TFU_DELTA) % + RG_MEAS_GAPPRD_40; +#else + offset = (cell->crntTime.sfn * RGSCH_NUM_SUB_FRAMES_5G + cell->crntTime.subframe + TFU_DLCNTRL_DLDELTA) % + RG_MEAS_GAPPRD_40; +#endif + queue = &(cell->measGapCb.gapPrd40Q[offset]); + rgSCHMeasGapANRepUtlHdlTti (cell, queue); + /* 80ms offset */ + /* Introduced timing delta for DL control in FDD */ +#ifdef LTE_TDD + offset = (cell->crntTime.sfn * RGSCH_NUM_SUB_FRAMES_5G + cell->crntTime.subframe + TFU_DELTA) % + RG_MEAS_GAPPRD_80; +#else + offset = (cell->crntTime.sfn * RGSCH_NUM_SUB_FRAMES_5G + cell->crntTime.subframe + TFU_DLCNTRL_DLDELTA) % + RG_MEAS_GAPPRD_80; +#endif + queue = &(cell->measGapCb.gapPrd80Q[offset]); + rgSCHMeasGapANRepUtlHdlTti (cell, queue); + + /* for ACK NACK repetition starts at offset - however at MAC we are + * concerned with subframe - TFU_DELTA */ + /* offset = ((cell->crntTime.sfn * 10) + cell->crntTime.subframe) % + * RG_MAX_NUM_DLSF; */ + /* We wish to get the subframe whose HARQ Reception request would go out in + * this subframe. HARQ_RTT - TFU_DELTA + */ + /* Introduced timing delta for reception req */ +#ifdef LTE_TDD + /* ACC_TDD */ + //RGSCHSUBFRMCRNTTIME(cell->crntTime, repTime, (4 - TFU_DELTA)); + RGSCHDECRFRMCRNTTIME(cell->crntTime, repTime, (RG_SCH_CMN_HARQ_INTERVAL - TFU_RECPREQ_DLDELTA)); +#else + RGSCHDECRFRMCRNTTIME(cell->crntTime, repTime, (RG_SCH_CMN_HARQ_INTERVAL - TFU_RECPREQ_DLDELTA)); +#endif + dlSf = rgSCHUtlSubFrmGet (cell, repTime); + queue = &(dlSf->ueLst); + rgSchAckNackRepUtlHdlTti (cell, queue); + + RETVALUE(ROK); +} + + /** @brief This function Marks the UE as ackNakRep so that Reception request + * isnt sent for any other thing than HARQ. + * + * @details + * + * Function: + * + * Processing steps: + * - Loop through HARQ procs of the DlSf. + * - If the UE is a repeating one + * - Mark as ackNakRep = TRUE + * - Start the timer + * + * @param RgSchCellCb *cell + * @param CmLListCp *ackNakRepQ + * @return Void + */ +#ifdef ANSI +PRIVATE Void rgSchAckNackRepUtlHdlTti +( +RgSchCellCb *cell, +CmLListCp *ackNackRepQ +) +#else +PRIVATE Void rgSchAckNackRepUtlHdlTti (cell, ackNackRepQ) +RgSchCellCb *cell; +CmLListCp *ackNackRepQ; +#endif +{ + CmLList *node; + RgSchUeCb *ue; + + TRC2(rgSchAckNackRepUtlHdlTti); + + node = ackNackRepQ->first; + while (node) + { + ue = (RgSchUeCb *)(node->node); + if ((NULLP != ue) && (ue->ackNakRepCb.isAckNackEnabled)) + { + ue->ackNakRepCb.isAckNakRep = TRUE; + rgSCHTmrStartTmr (cell, ue, RG_SCH_TMR_ACKNACK_REP, + ue->ackNakRepCb.repCntr); + } + node = node->next; + } /* end of while */ + RETVOID; +} /* end of */ + + + /** @brief This function + * + * @details + * + * Function: + * + * Processing steps: + * - + * + * + * @param + * @param + * @return + */ +#ifdef ANSI +PRIVATE Void rgSCHMeasGapANRepUtlHdlTti +( +RgSchCellCb *cell, +CmLListCp *measGapQ +) +#else +PRIVATE Void rgSCHMeasGapANRepUtlHdlTti (cell, measGapQ) +RgSchCellCb *cell; +CmLListCp *measGapQ; +#endif +{ + CmLList *node; + RgSchUeCb *ue; + + TRC2(rgSCHMeasGapANRepUtlHdlTti); + + node = measGapQ->first; + while (node) + { + ue = (RgSchUeCb*)node->node; + ue->measGapCb.isMeasuring = TRUE; + rgSCHTmrStartTmr (cell, ue, RG_SCH_TMR_MEASGAP, RG_SCH_MEAS_GAP_LEN); + node = node->next; + } /* end of while */ + RETVOID; +} /* end of */ + + +/** + * @brief Determines the list of UEs inactive for DL scheduling due to + * measurement gap and ack nack repetitions + * + * @details + * + * Function : rgSCHMeasGapANRepGetDlInactvUe + * + * Invoking Module Processing: + * - This API shall be invoked to get list of inactive UEs for downlink + * scheduling due to measurement gaps and ACK NACK repetitions. + * + * Processing Steps: + * - Compute qOffset for 40ms or 80ms queue as = + * ((cell->crntTime->sfn * 10)+cell->crntTime->subframe + DL_DELTA + + * RG_SCH_CMN_HARQ_INTERVAL) + * % RG_MEAS_GAPPRD_40 or RG_MEAS_GAPPRD_80. + * - Add all the UEs at computed offset to dlInactvUeLst since the + * DL transmission or feedback transmission from UE for DL + * transmissions shall collide with measurement gap. + * - Mark each UE. Set dlInactvMask |= RG_MEASGAP_INACTIVE + * - Start measGapDlInactvTmr timer for each UE, + * - length = RG_MEAS_GAP_LEN + RG_SCH_CMN_HARQ_INTERVAL + * - event = RG_MEASGAP_DLINACTV + * - handler = rgSCHMeasGapANRepDlInactvTmrExpry + * - Compute qOffset for ACK NACK repetition queue as = + * ((cell->crntTime->sfn * 10)+cell->crntTime->subframe + DL_DELTA + + * RG_SCH_CMN_HARQ_INTERVAL -1) + * % RG_MAX_NUM_DLSF. + * - Add all the UEs at computed offset to dlInactvUeLst since the + * feedback transmission from UE for DL transmissions shall + * collide with ACK NACK repetition of the UE. + * - Mark each UE. Set dlInactvMask |= RG_ACKNAKREP_INACTIVE + * - Start ackNakRepDlInactvTmr timer for each UE, + * - length = repCntr - 1 + * - event = RG_ACKNAKREP_DLINACTV + * - handler = rgSCHMeasGapANRepDlInactvTmrExpry + * - Verify the above computations before coding + * + * - Return ROK + * + * @param[in] RgSchCellCb *cell + * @param[out] CmLListCp *dlInactvUeLst + * @return S16 + * -# ROK + **/ +#ifdef ANSI +PUBLIC S16 rgSCHMeasGapANRepGetDlInactvUe +( +RgSchCellCb *cell, +CmLListCp *dlInactvUeLst +) +#else +PUBLIC S16 rgSCHMeasGapANRepGetDlInactvUe(cell, dlInactvUeLst) +RgSchCellCb *cell; +CmLListCp *dlInactvUeLst; +#endif +{ + U8 offset; + CmLList *node; + CmLList *hqNode; + CmLListCp *queue; + RgSchUeCb *ue; + RgSchDlSf *dlSf; + CmLteTimingInfo ackNakTime; + U16 schedTime; + U8 harqFdbkOffset; +#ifdef LTE_TDD + U8 repCntr; +#endif + RgSchDlHqProcCb *hqP; + RgSchDlHqTbCb *tbCb; + U32 i; + + TRC2(rgSCHMeasGapANRepGetDlInactvUe); + + schedTime = cell->crntTime.sfn * RGSCH_NUM_SUB_FRAMES_5G + cell->crntTime.subframe + RG_DL_DELTA; + +#ifdef LTE_TDD + RG_SCH_ADD_TO_CRNT_TIME(cell->crntTime, ackNakTime, RG_DL_DELTA); + if(rgSchTddUlDlSubfrmTbl[cell->ulDlCfgIdx][ackNakTime.subframe] != + RG_SCH_TDD_DL_SUBFRAME) + { + RETVALUE(ROK); + } + + dlSf = rgSCHUtlSubFrmGet (cell, ackNakTime); + if(dlSf->dlFdbkInfo.sfnOffset > 0) + { + harqFdbkOffset = + (dlSf->dlFdbkInfo.sfnOffset - 1) * RGSCH_NUM_SUB_FRAMES+ \ + RGSCH_NUM_SUB_FRAMES - ackNakTime.subframe + \ + dlSf->dlFdbkInfo.subframe; + } + else + { + harqFdbkOffset = dlSf->dlFdbkInfo.subframe - ackNakTime.subframe; + } +#else + harqFdbkOffset = RG_SCH_CMN_HARQ_INTERVAL; +#endif + /* Calc offset for Measurement gap 40 */ + offset = (schedTime + harqFdbkOffset) % RG_MEAS_GAPPRD_40; + queue = &(cell->measGapCb.gapPrd40Q[offset]); + + node = queue->first; + while (node) + { + ue = (RgSchUeCb*)node->node; + ue->dl.dlInactvMask |= RG_MEASGAP_INACTIVE; + /* Add to the inactv list */ + ue->dl.dlInactvLnk.node = (PTR)ue; + cmLListAdd2Tail (dlInactvUeLst, &(ue->dl.dlInactvLnk)); + /* Start timer */ + rgSCHTmrStartTmr (cell, ue, RG_SCH_TMR_DL_MEASGAP, + (RG_SCH_MEAS_GAP_LEN + harqFdbkOffset)); + node = node->next; + } + + /* Calc offset for Measurement gap 80 */ + offset = (schedTime + harqFdbkOffset) % RG_MEAS_GAPPRD_80; + queue = &(cell->measGapCb.gapPrd80Q[offset]); + + node = queue->first; + while (node) + { + ue = (RgSchUeCb*)node->node; + ue->dl.dlInactvMask |= RG_MEASGAP_INACTIVE; + /* Add to the inactv list */ + ue->dl.dlInactvLnk.node = (PTR)ue; + cmLListAdd2Tail (dlInactvUeLst, &(ue->dl.dlInactvLnk)); + /* Start timer */ + rgSCHTmrStartTmr (cell, ue, RG_SCH_TMR_DL_MEASGAP, + (RG_SCH_MEAS_GAP_LEN + harqFdbkOffset)); + node = node->next; + } + + /* Calc offset for ACK NACK repetition */ + /*offset = (cell->crntTime.sfn * 10 + + cell->crntTime.subframe + RG_DL_DELTA + RG_SCH_CMN_HARQ_INTERVAL - 1) + % RG_MAX_NUM_DLSF;*/ + /* The ackNakRepQ resides in each dlSf corresponding to the repStart */ + /* Must pick up the subframe that was scheduled in the last TTI */ +#ifdef LTE_TDD + if(cell->ulDlCfgIdx == 5) + { + RETVALUE(ROK); + } + rgSCHUtlGetPrevDlSfInfo(cell, ackNakTime, &ackNakTime, &repCntr); + dlSf = rgSCHUtlSubFrmGet (cell, ackNakTime); + /* crnt DL subframe */ + RG_SCH_ADD_TO_CRNT_TIME(cell->crntTime, ackNakTime, RG_DL_DELTA); +#else + if(0 == RG_DL_DELTA) + { + /* Go to the subframe being scheduled */ + RG_SCH_ADD_TO_CRNT_TIME(cell->crntTime, ackNakTime, RG_DL_DELTA); + /* Go to the previous subframe */ + RGSCHDECRFRMCRNTTIME(ackNakTime, ackNakTime, 1); + } + else + { + RG_SCH_ADD_TO_CRNT_TIME(cell->crntTime, ackNakTime, + (RG_DL_DELTA - 1)); + } + dlSf = rgSCHUtlSubFrmGet (cell, ackNakTime); +#endif + queue = &(dlSf->ueLst); + + node = queue->first; + while (node) + { + ue = (RgSchUeCb *)(node->node); + node = node->next; + hqNode = ue->dl.dlSfHqInfo[cell->cellId][dlSf->dlIdx].hqPLst.first; + while (hqNode) + { + hqP = (RgSchDlHqProcCb *)hqNode->node; + hqNode = hqNode->next; + for (i = 0;(i<2) && (hqP->tbInfo[i].state == HQ_TB_WAITING);i++) + { + tbCb = &hqP->tbInfo[i]; + if (tbCb->fbkRepCntr > 0) + { + ue->dl.dlInactvMask |= RG_ACKNAKREP_INACTIVE; + /* Check if already added to the list */ + if (!(ue->dl.dlInactvMask & RG_MEASGAP_INACTIVE)) + { + /* Add to the inactv list */ + ue->dl.dlInactvLnk.node = (PTR)ue; + cmLListAdd2Tail (dlInactvUeLst, &(ue->dl.dlInactvLnk)); + } + /* Start timer */ +#ifdef LTE_TDD + repCntr = rgSCHAckNakRepFindUlDuration(cell, dlSf, ackNakTime, + (U8)(ue->ackNakRepCb.repCntr - 1)); + rgSCHTmrStartTmr (cell, ue, RG_SCH_TMR_DL_ACKNACK, repCntr); +#else + rgSCHTmrStartTmr (cell, ue, RG_SCH_TMR_DL_ACKNACK, + (ue->ackNakRepCb.repCntr - 1)); +#endif + } + } + } + } + RETVALUE(ROK); +} + +/** + * @brief Determines the list of UEs inactive for UL scheduling due to + * measurement gap and ack nack repetitions + * + * @details + * + * Function : rgSCHMeasGapANRepGetUlInactvUe + * + * Invoking Module Processing: + * - This API shall be invoked to get list of inactive UEs for uplink + * scheduling due to measurement gaps and ACK NACK repetitions. + * + * Processing Steps: + * - Compute qOffset for 40ms or 80ms queue as = + * ((cell->crntTime->sfn * 10)+cell->crntTime->subframe + TFU_DELTA + + * RG_SCH_CMN_HARQ_INTERVAL) + * % RG_MEAS_GAPPRD_40 or RG_MEAS_GAPPRD_80. + * - Add all the UEs at computed offset to ulInactvUeLst since the UL + * transmissions shall collide with measurement gap. + * - Mark each UE. Set ulInactvMask |= RG_MEASGAP_INACTIVE + * - Start measGapUlInactvTmr timer for each UE + * - length = RG_MEAS_GAP_LEN + * - event = RG_MEASGAP_ULINACTV + * - handler = rgSCHMeasGapANRepUlInactvTmrExpry + * - Compute qOffset for ACK NACK repetition queue as = + * ((cell->crntTime->sfn * 10)+cell->crntTime->subframe + TFU_DELTA + + * RG_SCH_CMN_HARQ_INTERVAL) + * % RG_MAX_NUM_DLSF. + * - Add all the UEs at computed offset to ulInactvUeLst since the + * feedback transmission from UE for DL transmissions shall + * collide with repeating ACK ACK-NACKs. + * - Mark each UE. Set ulInactvMask |= RG_ACKNAKREP_INACTIVE + * - Start ackNakRepUlInactv timer for each UE + * - length = repCntr + * - event = RG_ACKNAKREP_ULINACTV + * - handler = rgSCHMeasGapANRepUlInactvTmrExpry + * - Verify the above computations before coding + * - Return ROK + * + * @param[in] RgSchCellCb *cell + * @param[out] CmLListCp *ulInactvUeLst + * @return S16 + * -# ROK + **/ + +#ifdef ANSI +PUBLIC S16 rgSCHMeasGapANRepGetUlInactvUe +( +RgSchCellCb *cell, +CmLListCp *ulInactvUeLst +) +#else +PUBLIC S16 rgSCHMeasGapANRepGetUlInactvUe(cell, ulInactvUeLst) +RgSchCellCb *cell; +CmLListCp *ulInactvUeLst; +#endif +{ + + U8 offset; + CmLList *node; + CmLList *hqNode; + CmLListCp *queue; + RgSchUeCb *ue; + CmLteTimingInfo ackNakTime; + RgSchDlSf *dlSf; + U16 schedTime; + U8 pdcchToPuschGap; + U8 idx=0; +#ifdef LTE_TDD + U8 repCntr; +#endif + RgSchDlHqProcCb *hqP; + RgSchDlHqTbCb *tbCb; + U32 i; + + TRC2(rgSCHMeasGapANRepGetUlInactvUe); + + /*ccpu00139481- Meas Gap should be monitored in UL with TFU_ULCNTRL_DLDELTA*/ + schedTime = cell->crntTime.sfn * RGSCH_NUM_SUB_FRAMES_5G + cell->crntTime.subframe + \ + TFU_ULCNTRL_DLDELTA; +#ifndef LTE_TDD + pdcchToPuschGap = RGSCH_PDCCH_PUSCH_DELTA; +#else + RG_SCH_ADD_TO_CRNT_TIME(cell->crntTime, ackNakTime, TFU_ULCNTRL_DLDELTA); + pdcchToPuschGap = rgSchTddPuschTxKTbl[cell->ulDlCfgIdx][ackNakTime.subframe]; + for(idx=0; pdcchToPuschGap && (idx< (pdcchToPuschGap+RG_SCH_MEAS_GAP_LEN)) ; idx++) +#endif + { + /* Calc offset for Measurement gap 40 */ + offset = (schedTime + pdcchToPuschGap -idx + RG_MEAS_GAPPRD_40) % RG_MEAS_GAPPRD_40; + queue = &(cell->measGapCb.gapPrd40Q[offset]); + node = queue->first; + while (node) + { + ue = (RgSchUeCb*)node->node; + if(!(ue->ul.ulInactvMask & RG_MEASGAP_INACTIVE)) + { + ue->ul.ulInactvMask |= RG_MEASGAP_INACTIVE; + /* Add to the inactv list */ + ue->ul.ulInactvLnk.node = (PTR)ue; + cmLListAdd2Tail (ulInactvUeLst, &(ue->ul.ulInactvLnk)); + /* Start timer Note the timer is started for a value GAP_LEN + + * RG_SCH_CMN_HARQ_INTERVAL. The "4" + * is added because for UE to transmit, the PDCCH must be sent 4 subframes + * ahead - UE cant read PDCCH format0 if it is in measurement gap. */ + rgSCHTmrStartTmr (cell, ue, RG_SCH_TMR_UL_MEASGAP, + (RG_SCH_MEAS_GAP_LEN + pdcchToPuschGap - idx)); + //printf("Starting Meas Gap 40 @ DL TTI- (%d:%d) K-%d offset-%d Len %d \n", ackNakTime.sfn, ackNakTime.subframe, harqFdbkOffset, offset, RG_SCH_MEAS_GAP_LEN + harqFdbkOffset-idx); + } + node = node->next; + } + + /* Calc offset for Measurement gap 80 */ + offset = (schedTime + pdcchToPuschGap - idx + RG_MEAS_GAPPRD_80) % RG_MEAS_GAPPRD_80; + queue = &(cell->measGapCb.gapPrd80Q[offset]); + + node = queue->first; + while (node) + { + ue = (RgSchUeCb*)node->node; + if(!(ue->ul.ulInactvMask & RG_MEASGAP_INACTIVE)) + { + ue->ul.ulInactvMask |= RG_MEASGAP_INACTIVE; + /* Add to the inactv list */ + ue->ul.ulInactvLnk.node = (PTR)ue; + cmLListAdd2Tail (ulInactvUeLst, &(ue->ul.ulInactvLnk)); + /* Start timer */ + rgSCHTmrStartTmr (cell, ue, RG_SCH_TMR_UL_MEASGAP, + (RG_SCH_MEAS_GAP_LEN + pdcchToPuschGap - idx)); + //printf("Starting Meas Gap 80 @ DL TTI- (%d:%d) K-%d offset-%d Len %d \n", ackNakTime.sfn, ackNakTime.subframe, harqFdbkOffset, offset, RG_SCH_MEAS_GAP_LEN + harqFdbkOffset-idx); + } + node = node->next; + } + } + /* Calc offset for ACK NACK repetition */ + /*offset = (cell->crntTime.sfn * 10 + + cell->crntTime.subframe + RG_UL_SCHED_DELTA + + RG_SCH_CMN_HARQ_INTERVAL ) % RG_MAX_NUM_DLSF;*/ + + /* Must get the DLSF that is scheduled at TFU_DELTA Away */ +#ifdef LTE_TDD + if(cell->ulDlCfgIdx == 5) + { + RETVALUE(ROK); + } + RG_SCH_ADD_TO_CRNT_TIME(cell->crntTime, ackNakTime, TFU_DELTA); + if(rgSchTddUlDlSubfrmTbl[cell->ulDlCfgIdx][ackNakTime.subframe] != + RG_SCH_TDD_DL_SUBFRAME) + { + RETVALUE(ROK); + } +#else + /* Introduced timing delta for DL control in FDD */ + RG_SCH_ADD_TO_CRNT_TIME(cell->crntTime, ackNakTime, TFU_DLCNTRL_DLDELTA); +#endif + dlSf = rgSCHUtlSubFrmGet (cell, ackNakTime); + queue = &(dlSf->ueLst); + + node = queue->first; + while (node) + { + ue = (RgSchUeCb *)(node->node); + node = node->next; + hqNode = ue->dl.dlSfHqInfo[cell->cellId][dlSf->dlIdx].hqPLst.first; + while (hqNode) + { + hqP = (RgSchDlHqProcCb *)hqNode->node; + hqNode = hqNode->next; + for (i = 0;(i<2) && (hqP->tbInfo[i].state == HQ_TB_WAITING);i++) + { + tbCb = &hqP->tbInfo[i]; + if (tbCb->fbkRepCntr > 0) + { + ue->ul.ulInactvMask |= RG_ACKNAKREP_INACTIVE; + /* Check if already added to the list */ + if (!(ue->ul.ulInactvMask & RG_MEASGAP_INACTIVE)) + { + /* Add to the inactv list */ + ue->ul.ulInactvLnk.node = (PTR)ue; + cmLListAdd2Tail (ulInactvUeLst, &(ue->ul.ulInactvLnk)); + } + /* Start timer */ +#ifdef LTE_TDD + repCntr = rgSCHAckNakRepFindUlDuration(cell, dlSf, ackNakTime, + ue->ackNakRepCb.repCntr); + rgSCHTmrStartTmr (cell, ue, RG_SCH_TMR_UL_ACKNACK, repCntr); +#else + rgSCHTmrStartTmr (cell, ue, RG_SCH_TMR_UL_ACKNACK, + (ue->ackNakRepCb.repCntr)); +#endif + } + } + } + } + RETVALUE(ROK); +} + +/** + * @brief Handles processing of DL Inactive timer expiry at the end of + * measurement gap or ack nack repetition for a UE + * + * @details + * + * Function : rgSCHMeasGapANRepDlInactvTmrExpry + * + * Invoking Module Processing: + * - This API shall be invoked to process DL inactive timer expiry + * + * Processing Steps: + * - If timer event is RG_MEASGAP_DLINACTV, + * - dlInactvMask &= ~RG_MEASGAP_INACTIVE + * - If timer event is RG_ACKNAKREP_DLINACTV, + * - dlInactvMask &= ~RG_ACKNAKREP_INACTIVE + * - if (!dlInactvMask) + * - Invoke DL scheduler to put the UE back into the scheduling queues. + * - Re-initialize timer. + * - Return ROK + * + * @param[in] RgSchUeCb *ue + * @param[in] Check if some timer related parameter needs to be passed + * @return S16 + * -# ROK + **/ + +#ifdef ANSI +PUBLIC Void rgSCHMeasGapANRepDlInactvTmrExpry +( +RgSchUeCb *ue, +U8 tmrEvnt +) +#else +PUBLIC Void rgSCHMeasGapANRepDlInactvTmrExpry(ue, tmrEvnt) +RgSchUeCb *ue; +U8 tmrEvnt; +#endif +{ + + RgSchCellCb *cell = ue->cell; + TRC2(rgSCHMeasGapANRepDlInactvTmrExpry); + + switch (tmrEvnt) + { + case RG_SCH_TMR_DL_MEASGAP: + RG_SCH_CMN_DL_UPDT_INACTV_MASK ( cell, ue, RG_MEASGAP_INACTIVE); + break; + case RG_SCH_TMR_DL_ACKNACK: + RG_SCH_CMN_DL_UPDT_INACTV_MASK ( cell, ue, RG_ACKNAKREP_INACTIVE); + break; + } + if (!ue->dl.dlInactvMask) + { + cmInitTimers (&ue->measGapCb.measGapDlInactvTmr, 1); + cmInitTimers (&ue->ackNakRepCb.ackNakRepDlInactvTmr, 1); + } + RETVOID; +} + +/** + * @brief Handles processing of UL Inactive timer expiry at the end of + * measurement gap or ack nack repetition for a UE + * + * @details + * + * Function : rgSCHMeasGapANRepUlInactvTmrExpry + * + * Invoking Module Processing: + * - This API shall be invoked to process UL inactive timer expiry + * + * Processing Steps: + * - If timer event is RG_MEASGAP_ULINACTV, + * - ulInactvMask &= ~RG_MEASGAP_INACTIVE + * - If timer event is RG_ACKNAKREP_ULINACTV, + * - ulInactvMask &= ~RG_ACKNAKREP_INACTIVE + * - if (!ulInactvMask) + * - Invoke UL scheduler to put the UE back into the scheduling queues. + * - Re-initialize timer. + * - Return ROK + * + * @param[in] RgSchUeCb *ue + * @param[in] Check if some timer related parameter needs to be passed + * @return S16 + * -# ROK + **/ + +#ifdef ANSI +PUBLIC Void rgSCHMeasGapANRepUlInactvTmrExpry +( +RgSchUeCb *ue, +U8 tmrEvnt +) +#else +PUBLIC Void rgSCHMeasGapANRepUlInactvTmrExpry(ue, tmrEvnt) +RgSchUeCb *ue; +U8 tmrEvnt; +#endif +{ + RgSchCellCb *cell = ue->cell; + TRC2(rgSCHMeasGapANRepUlInactvTmrExpry); + + switch (tmrEvnt) + { + case RG_SCH_TMR_UL_MEASGAP: + RG_SCH_CMN_UL_UPDT_INACTV_MASK ( cell, ue, RG_MEASGAP_INACTIVE); + break; + case RG_SCH_TMR_UL_ACKNACK: + RG_SCH_CMN_UL_UPDT_INACTV_MASK ( cell, ue, RG_ACKNAKREP_INACTIVE); + break; + } + if (!ue->ul.ulInactvMask) + { + cmInitTimers (&ue->measGapCb.measGapUlInactvTmr, 1); + cmInitTimers (&ue->ackNakRepCb.ackNakRepUlInactvTmr, 1); + } + RETVOID; +} + +/** + * @brief Handles processing of measurement gap timer expiry at the end of + * measurement gap + * + * @details + * + * Function : rgSCHMeasGapANRepTmrExpry + * + * Invoking Module Processing: + * - This API shall be invoked to process measurement gap timer expiry + * + * Processing Steps: + * - Set ue->isMeasuring = FALSE + * - Re-initialize timer. + * - Return ROK + * + * @param[in] RgSchUeCb *ue + * @param[in] Check if some timer related parameter needs to be passed + * @return S16 + * -# ROK + **/ + +#ifdef ANSI +PUBLIC Void rgSCHMeasGapANRepTmrExpry +( +RgSchUeCb *ue +) +#else +PUBLIC Void rgSCHMeasGapANRepTmrExpry(ue) +RgSchUeCb *ue; +#endif +{ + + TRC2(rgSCHMeasGapANRepTmrExpry); + + ue->measGapCb.isMeasuring = FALSE; + cmInitTimers (&ue->measGapCb.measGapTmr, 1); + + RETVOID; +} + +/** + * @brief Handles processing of ACK-NACK repetition timer expiry at the end of + * ACK-NACK repetition. + * + * @details + * + * Function : rgSchAckNakRepTmrExpry + * + * Invoking Module Processing: + * - This API shall be invoked to process ACK-NACK repetition timer expiry + * + * Processing Steps: + * - Set ue->isAckNakRep = FALSE + * - Re-initialize timer. + * - Return ROK + * + * @param[in] RgSchUeCb *ue + * @param[in] Check if some timer related parameter needs to be passed + * @return S16 + * -# ROK + **/ + +#ifdef ANSI +PUBLIC Void rgSCHAckNakRepTmrExpry +( +RgSchUeCb *ue +) +#else +PUBLIC Void rgSCHAckNakRepTmrExpry(ue) +RgSchUeCb *ue; +#endif +{ + + TRC2(rgSCHAckNakRepTmrExpry); + + ue->ackNakRepCb.isAckNakRep = FALSE; + cmInitTimers (&ue->ackNakRepCb.ackNakRepTmr, 1); + + RETVOID; +} + + +/** + * @brief Adds ACK-NACK repeating UEs to the ackNakRepQ + * + * @details + * + * Function : rgSchAckNakRepAddToQ + * + * Invoking Module Processing: + * - This API shall be invoked for adding list of UEs to the ACK-NACK + * repeating queue at appropriate poistion. Invoking module shall invoke + * with the list of ACK-NACK repeating UEs for a sub-frame and timing info + * at which ACK NACK repetition shall start for the UEs. + * + * Processing Steps: + * - Determine the qOffset depending on the timing info as + * - qOffset = (repStartTime->sfn *10 + repStartTime->subframe) % RG_MAX_NUM_DLSF + * - Initialize the list at the qOffset. + * - For each UE in the list, + * - Add the UE to ackNakRepQ to the list at the determined qOffset. + * - Set ue->qOffset = qOffset + * - Initialize timers. + * - Return ROK + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchDlSf *crntDlSf + * @param[in] CmLteTimingInfo repStartTime + * + * @return S16 + * -# ROK + **/ + +#ifdef ANSI +PUBLIC Void rgSCHAckNakRepAddToQ +( +RgSchCellCb *cell, +RgSchDlSf *crntDlSf +) +#else +PUBLIC Void rgSCHAckNakRepAddToQ(cell, crntDlSf) +RgSchCellCb *cell; +RgSchDlSf *crntDlSf; +#endif +{ + RgSchUeCb *ue; + CmLList *node; + CmLList *hqNode; + RgSchDlHqProcCb *hqP; + RgSchDlHqTbCb *tbCb; + U32 i; + + TRC2(rgSCHAckNakRepAddToQ); + + node = crntDlSf->ueLst.first; + while (node) + { + ue = (RgSchUeCb *)(node->node); + node = node->next; + hqNode = ue->dl.dlSfHqInfo[cell->cellId][crntDlSf->dlIdx].hqPLst.first; + while (hqNode) + { + hqP = (RgSchDlHqProcCb *)hqNode->node; + hqNode = hqNode->next; + for (i = 0;(i<2) && (hqP->tbInfo[i].state == HQ_TB_WAITING);i++) + { + tbCb = &hqP->tbInfo[i]; + /* Add UEs that have enabled ACK NACK repetition */ + if (ue->ackNakRepCb.isAckNackEnabled) + { + tbCb->fbkRepCntr = ue->ackNakRepCb.cfgRepCnt; + tbCb->fbkRecpRepCntr = ue->ackNakRepCb.cfgRepCnt; + /* Removed init of timers as the init will be happening during + * config or timer expiry*/ + } + } + } + } + RETVOID; +} + + +#ifdef LTE_TDD +/** + * @brief Finds the number of subframes used for ACK-NACK cycle + * + * @details + * + * Function : rgSCHAckNakRepFindUlDuration + * + * This function finds the number of subframes required + * for ACK-NACK repetition cycle based on UL subframes. + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchDlSf *dlSf + * @param[in] CmLteTimingInfo repTime + * @param[in] U8 repCnt + * + * @return U8 + * + **/ + +#ifdef ANSI +PRIVATE U8 rgSCHAckNakRepFindUlDuration +( +RgSchCellCb *cell, +RgSchDlSf *dlSf, +CmLteTimingInfo repTime, +U8 repCnt +) +#else +PRIVATE U8 rgSCHAckNakRepFindUlDuration(cell, dlSf, repTime, repCnt) +RgSchCellCb *cell; +RgSchDlSf *dlSf; +CmLteTimingInfo repTime; +U8 repCnt; +#endif +{ + CmLteTimingInfo ulfrm; + U8 noSubfrms = 0; + U16 ulDlCfgIdx = cell->ulDlCfgIdx; + S16 rem = 0; + S16 idx; + S8 diff; + + TRC2(rgSCHAckNakRepFindUlDuration) + rgSCHAckNakRepGetUlOffsetFrmDl(dlSf, repTime, &noSubfrms); + RG_SCH_ADD_TO_CRNT_TIME(repTime, ulfrm, noSubfrms); + diff = repCnt-1; + idx = ulfrm.subframe; + while(diff) + { + idx = (idx + 1) % RGSCH_NUM_SUB_FRAMES; + if(rgSchTddUlDlSubfrmTbl[ulDlCfgIdx][idx] == + RG_SCH_TDD_UL_SUBFRAME) + { + diff--; + } + rem++; + } + noSubfrms += rem; + + RETVALUE(noSubfrms); + } + +/** + * @brief Finds the number of subframes used for ACK-NACK cycle + * + * @details + * + * Function : rgSCHAckNakRepGetUlOffsetFrmDl + * + * This function finds the number of subframes after + * which UL subframes are present for the gicen DL + * subframe. + * + * @param[in] RgSchDlSf *dlSf + * @param[in] CmLteTimingInfo crntDlTime + * @param[in] U8 *noSubfrms + * + * @return U8 + * + **/ + +#ifdef ANSI +PRIVATE Void rgSCHAckNakRepGetUlOffsetFrmDl +( +RgSchDlSf *dlSf, +CmLteTimingInfo crntDlTime, +U8 *noSubfrms +) +#else +PRIVATE Void rgSCHAckNakRepGetUlOffsetFrmDl(dlSf, crntDlTime, noSubfrms) +RgSchDlSf *dlSf; +CmLteTimingInfo crntDlTime; +U8 *noSubfrms; +#endif + { + TRC2(rgSCHAckNakRepGetUlOffsetFrmDl) + + if(dlSf->dlFdbkInfo.sfnOffset != 0) + { + *noSubfrms = (dlSf->dlFdbkInfo.sfnOffset - 1) * RGSCH_NUM_SUB_FRAMES; + *noSubfrms = *noSubfrms + RGSCH_NUM_SUB_FRAMES - crntDlTime.subframe; + *noSubfrms = *noSubfrms + dlSf->dlFdbkInfo.subframe; + } + else + { + *noSubfrms = dlSf->dlFdbkInfo.subframe - crntDlTime.subframe; + } + RETVOID; +} +#endif + +/********************************************************************** + + End of file +**********************************************************************/ diff --git a/src/5gnrmac/rg_sch_pt.c b/src/5gnrmac/rg_sch_pt.c new file mode 100755 index 000000000..13bee92a4 --- /dev/null +++ b/src/5gnrmac/rg_sch_pt.c @@ -0,0 +1,852 @@ +/******************************************************************************* +################################################################################ +# Copyright (c) [2017-2019] [Radisys] # +# # +# 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. # +################################################################################ +*******************************************************************************/ + +/************************************************************************ + + Name: LTE-MAC layer + + Type: C source file + + Desc: C source code for INF Interface Module + + File: rg_sch_pt.c + +**********************************************************************/ + +/** @file rg_sch_pt.c +@brief This file contains the definitions for Upper Interface(RGR/CRG/RGU) + primitives that are invoked from MAC to its service users. + Portable functions corresponding to these primitives are also defined. +*/ +/* header include files (.h) */ +#include "envopt.h" /* environment options */ +#include "envdep.h" /* environment dependent */ +#include "envind.h" /* environment independent */ +#include "gen.h" /* general */ +#include "ssi.h" /* system services */ +#include "cm_tkns.h" /* Common Token Defines */ +#include "cm_llist.h" /* Common Link List Defines */ +#include "cm_hash.h" /* Common Hash List Defines */ +#include "cm_lte.h" /* Common LTE Defines */ +#include "rg_env.h" /* MAC Environment Defines */ +#include "crg.h" /* CRG Interface defines */ +#include "rgr.h" /* RGR Interface defines */ +#include "rgu.h" /* RGU Interface defines */ +#include "cm_mblk.h" /* memory management */ +#include "cm_lte.h" /* Common LTE Defines */ +#include "tfu.h" /* RGU Interface defines */ +#ifdef LTE_L2_MEAS +#include "lrg.h" +#endif +#include "rg_sch_inf.h" /* RGU Interface defines */ + +/* header/extern include files (.x) */ +#include "gen.x" /* general */ +#include "ssi.x" /* system services */ +#include "cm_tkns.x" /* Common Token Definitions */ +#include "cm_llist.x" /* Common Link List Definitions */ +#include "cm_lib.x" /* Common Library Definitions */ +#include "cm_hash.x" /* Common Hash List Definitions */ +#include "cm_lte.x" /* Common LTE Defines */ +#include "crg.x" /* CRG Interface includes */ +#include "rgr.x" /* RGR Interface includes */ +#include "rgu.x" /* RGU Interface includes */ +#include "cm_mblk.x" /* memory management */ +#include "cm_lte.x" /* Common LTE Defines */ +#include "tfu.x" /* RGU Interface includes */ +#ifdef LTE_L2_MEAS +#include "lrg.x" +#endif +#include "rg_sch_inf.x" /* RGU Interface includes */ + +#define RG_MAX_SCH 1 + +PRIVATE CONSTANT CellRegReq RgSchMacCellRegReqMt[RG_MAX_SCH] = +{ +#ifdef LCSCH + cmPkSchMacCellRegReq, +#else + RgSchMacCellRegReq +#endif +}; + +PRIVATE CONSTANT DedBoUpdtReq RgMacSchDedBoUpdtReqMt[RG_MAX_SCH] = +{ +#ifdef LCSCH + cmPkMacSchDedBoUpdtReq, +#else + RgMacSchDedBoUpdtReq +#endif +}; + +PRIVATE CONSTANT CmnBoUpdtReq RgMacSchCmnBoUpdtReqMt[RG_MAX_SCH] = +{ +#ifdef LCSCH + cmPkMacSchCmnBoUpdtReq, +#else + RgMacSchCmnBoUpdtReq +#endif +}; + +PRIVATE CONSTANT SfRecpInd RgMacSchSfRecpIndMt[RG_MAX_SCH] = +{ +#ifdef LCSCH + cmPkMacSchSfRecpInd +#else + RgMacSchSfRecpInd, +#endif +}; +/*Fix: start: Inform UE delete to scheduler*/ +PRIVATE CONSTANT UeDelInd RgMacSchUeDelIndMt[RG_MAX_SCH] = +{ +#ifdef LCSCH + cmPkMacSchUeDelInd +#else + RgMacSchUeDelInd, +#endif +}; +/*Fix: end: Inform UE delete to scheduler*/ +PRIVATE CONSTANT SfAllocReq RgSchMacSfAllocReqMt[RG_MAX_SCH] = +{ +#ifdef LCSCH + cmPkSchMacSfAllocReq, +#else + RgSchMacSfAllocReq +#endif +}; + +PRIVATE CONSTANT RstHqEntReq RgSchMacRstHqEntReqMt[RG_MAX_SCH] = +{ +#ifdef LCSCH + cmPkSchMacRstHqEntReq, +#else + RgSchMacRstHqEntReq +#endif +}; +PRIVATE CONSTANT RlsHqReq RgSchMacRlsHqReqMt[RG_MAX_SCH] = +{ +#ifdef LCSCH + cmPkSchMacRlsHqReq, +#else + RgSchMacRlsHqReq +#endif +}; + +PRIVATE CONSTANT RlsRntiReq RgSchMacRlsRntiReqMt[RG_MAX_SCH] = +{ +#ifdef LCSCH + cmPkSchMacRlsRntiReq, +#else + RgSchMacRlsRntiReq +#endif +}; + +PRIVATE CONSTANT LcgReg RgSchMacLcgRegReqMt[RG_MAX_SCH] = +{ +#ifdef LCSCH + cmPkSchMacLcgRegReq, +#else + RgSchMacLcgRegReq +#endif +}; + +#ifdef LTEMAC_SPS +PRIVATE CONSTANT SpsLcReg RgSchMacSpsLcRegReqMt[RG_MAX_SCH] = +{ +#ifdef LCSCH + cmPkSchMacSpsLcRegReq, +#else + RgSchMacSpsLcRegReq +#endif +}; + +PRIVATE CONSTANT UlSpsReset RgSchMacUlSpsResetMt[RG_MAX_SCH] = +{ +#ifdef LCSCH + cmPkSchMacUlSpsReset, +#else + RgSchMacUlSpsResetReq +#endif +}; + + + +PRIVATE CONSTANT SpsLcDereg RgSchMacSpsLcDeregReqMt[RG_MAX_SCH] = +{ +#ifdef LCSCH + cmPkSchMacSpsLcDeregReq, +#else + RgSchMacSpsLcDeregReq +#endif +}; + +PRIVATE CONSTANT SpsRelInd RgMacSchSpsRelIndMt[RG_MAX_SCH] = +{ +#ifdef LCSCH + cmPkMacSchSpsRelInd, +#else + RgMacSchSpsRelInd +#endif +}; + +#endif /* LTEMAC_SPS */ + +#ifdef LTE_L2_MEAS +PRIVATE CONSTANT L2MeasReq RgSchMacL2MeasReqMt[RG_MAX_SCH] = +{ +#ifdef LCSCH + cmPkSchMacL2MeasReq +#else + RgSchMacL2MeasReq +#endif +}; +/*Added for Rsys oam*/ +PRIVATE CONSTANT L2MeasStopReq RgSchMacL2MeasStopReqMt[RG_MAX_SCH] = +{ +#ifdef LCSCH + cmPkSchMacL2MeasStopReq +#else + RgSchMacL2MeasStopReq +#endif +}; + +PRIVATE CONSTANT L2MeasSendReq RgSchMacL2MeasSendReqMt[RG_MAX_SCH] = +{ +#ifdef LCSCH + cmPkSchMacL2MeasSendReq +#else + RgSchMacL2MeasSendReq +#endif +}; + +PRIVATE CONSTANT L2MeasCfm RgMacSchL2MeasCfmMt[RG_MAX_SCH] = +{ +#ifdef LCSCH + cmPkMacSchL2MeasCfm +#else + RgMacSchL2MeasCfm +#endif +}; +PRIVATE CONSTANT L2MeasStopCfm RgMacSchL2MeasStopCfmMt[RG_MAX_SCH] = +{ +#ifdef LCSCH + cmPkMacSchL2MeasStopCfm +#else + RgMacSchL2MeasStopCfm +#endif +}; +#endif/*LTE_L2_MEAS*/ +/** +* @brief Data Indication from MAC to RLC to + * forward the data received for dedicated channels +* +* @details +* +* Function : RgSchMacCellReg +* +* @param[in] Pst* pst +* @param[in] SuId suId +* @param[in] RguDDatIndInfo * datInd +* @return S16 +* -# ROK +**/ +#ifdef ANSI +PUBLIC S16 RgSchMacCellReg +( +Pst* pst, +RgInfCellReg* regReq +) +#else +PUBLIC S16 RgSchMacCellReg(pst, regReq) +Pst* pst; +RgInfCellReg* regReq; +#endif +{ + + TRC3(RgSchMacCellReg); + + RETVALUE((*RgSchMacCellRegReqMt[0])(pst, regReq)); +} + +/** +* @brief Data Indication from MAC to RLC to + * forward the data received for dedicated channels +* +* @details +* +* Function : RgMacSchDedBoUpdt +* +* @param[in] Pst* pst +* @param[in] SuId suId +* @param[in] RguDDatIndInfo * datInd +* @return S16 +* -# ROK +**/ +#ifdef ANSI +PUBLIC S16 RgMacSchDedBoUpdt +( +Pst* pst, +RgInfDedBoRpt* boRpt +) +#else +PUBLIC S16 RgMacSchDedBoUpdt(pst, boRpt) +Pst* pst; +RgInfDedBoRpt* boRpt; +#endif +{ + + TRC3(RgMacSchDedBoUpdt); + + RETVALUE((*RgMacSchDedBoUpdtReqMt[0])(pst, boRpt)); +} + +/** +* @brief Data Indication from MAC to RLC to + * forward the data received for dedicated channels +* +* @details +* +* Function : RgMacSchCmnBoUpdt +* +* @param[in] Pst* pst +* @param[in] SuId suId +* @param[in] RguDDatIndInfo * datInd +* @return S16 +* -# ROK +**/ +#ifdef ANSI +PUBLIC S16 RgMacSchCmnBoUpdt +( +Pst* pst, +RgInfCmnBoRpt* boRpt +) +#else +PUBLIC S16 RgMacSchCmnBoUpdt(pst, boRpt) +Pst* pst; +RgInfCmnBoRpt* boRpt; +#endif +{ + + TRC3(RgMacSchCmnBoUpdt); + + RETVALUE((*RgMacSchCmnBoUpdtReqMt[0])(pst, boRpt)); +} + +/*Fix: start: Inform UE delete to scheduler*/ +/** +* @brief This primitive is used to indicate deletion of UE +* at MAC to scheduler. +* +* @details +* +* Function : RgMacSchUeDel +* +* @param[in] Pst* pst +* @param[in] RgInfSfDatInd* ueDelInd +* @return S16 +* -# ROK +**/ +#ifdef ANSI +PUBLIC S16 RgMacSchUeDel +( +Pst* pst, +RgInfUeDelInd* ueDelInd +) +#else +PUBLIC S16 RgMacSchUeDel(pst, datInd) +Pst* pst; +RgInfUeDelInd* ueDelInd; +#endif +{ + + TRC3(RgMacSchUeDel); + + RETVALUE((*RgMacSchUeDelIndMt[0])(pst, ueDelInd)); +} +/*Fix: end: Inform UE delete to scheduler*/ +/** +* @brief Data Indication from MAC to RLC to + * forward the data received for dedicated channels +* +* @details +* +* Function : RgMacSchSfRecp +* +* @param[in] Pst* pst +* @param[in] SuId suId +* @param[in] RguDDatIndInfo * datInd +* @return S16 +* -# ROK +**/ +#ifdef ANSI +PUBLIC S16 RgMacSchSfRecp +( +Pst* pst, +RgInfSfDatInd* datInd +) +#else +PUBLIC S16 RgMacSchSfRecp(pst, datInd) +Pst* pst; +RgInfSfDatInd* datInd; +#endif +{ + + TRC3(RgMacSchSfRecp); + + RETVALUE((*RgMacSchSfRecpIndMt[0])(pst, datInd)); +} + +/** +* @brief Data Indication from MAC to RLC to + * forward the data received for dedicated channels +* +* @details +* +* Function : RgSchMacSfAlloc +* +* @param[in] Pst* pst +* @param[in] SuId suId +* @param[in] RguDDatIndInfo * datInd +* @return S16 +* -# ROK +**/ +#ifdef ANSI +PUBLIC S16 RgSchMacSfAlloc +( +Pst* pst, +RgInfSfAlloc* resAllocReq +) +#else +PUBLIC S16 RgSchMacSfAlloc(pst, resAllocReq) +Pst* pst; +RgInfSfAlloc* resAllocReq; +#endif +{ + + TRC3(RgSchMacSfAlloc); + + RETVALUE((*RgSchMacSfAllocReqMt[0])(pst, resAllocReq)); +} + +/** +* @brief Trigger for resetting Harq Entity at MAC +* +* @details +* +* Function : RgSchMacRstHqEnt +* +* @param[in] Pst* pst +* @param[in] RgInfResetHqEnt *hqEntRstReq +* @return S16 +* -# ROK +**/ +#ifdef ANSI +PUBLIC S16 RgSchMacRstHqEnt +( +Pst* pst, +RgInfResetHqEnt* hqEntInfo +) +#else +PUBLIC S16 RgSchMacRstHqEnt(pst, hqEntInfo) +Pst* pst; +RgInfResetHqEnt* hqEntInfo; +#endif +{ + + TRC3(RgSchMacRstHqEnt) + + RETVALUE((*RgSchMacRstHqEntReqMt[0])(pst, hqEntInfo)); +} + +/** +* @brief Data Indication from MAC to RLC to + * forward the data received for dedicated channels +* +* @details +* +* Function : RgSchMacRlsHq +* +* @param[in] Pst* pst +* @param[in] SuId suId +* @param[in] RguDDatIndInfo * datInd +* @return S16 +* -# ROK +**/ +#ifdef ANSI +PUBLIC S16 RgSchMacRlsHq +( +Pst* pst, +RgInfRlsHqInfo* sfHqInfo +) +#else +PUBLIC S16 RgSchMacRlsHq(pst, sfHqInfo) +Pst* pst; +RgInfRlsHqInfo* sfHqInfo; +#endif +{ + + TRC3(RgSchMacRlsHq); + + RETVALUE((*RgSchMacRlsHqReqMt[0])(pst, sfHqInfo)); +} + +/** +* @brief Data Indication from MAC to RLC to + * forward the data received for dedicated channels +* +* @details +* +* Function : RgSchMacRlsRnti +* +* @param[in] Pst* pst +* @param[in] SuId suId +* @param[in] RguDDatIndInfo * datInd +* @return S16 +* -# ROK +**/ +#ifdef ANSI +PUBLIC S16 RgSchMacRlsRnti +( +Pst* pst, +RgInfRlsRnti* rlsRnti +) +#else +PUBLIC S16 RgSchMacRlsRnti(pst, rlsRnti) +Pst* pst; +RgInfRlsRnti* rlsRnti; +#endif +{ + + TRC3(RgSchMacRlsRnti); + + RETVALUE((*RgSchMacRlsRntiReqMt[0])(pst, rlsRnti)); +} + +/** +* @brief Request from SCH to MAC to register the GBR LCG of a UE +* +* @details +* +* Function : RgSchMacLcgReg +* +* @param[in] Pst* pst +* @param[in] RgInfLcgRegReq *lcgRegReq +* @return S16 +* -# ROK +**/ +#ifdef ANSI +PUBLIC S16 RgSchMacLcgReg +( +Pst* pst, +RgInfLcgRegReq *lcgRegReq +) +#else +PUBLIC S16 RgSchMacLcgReg(pst, lcgRegReq) +Pst* pst; +RgInfLcgRegReq *lcgRegReq; +#endif +{ + + TRC3(RgSchMacLcgReg); + + RETVALUE((*RgSchMacLcgRegReqMt[0])(pst, lcgRegReq)); +} /* end of RgSchMacLcgReg */ + +#ifdef LTEMAC_SPS +/** +* @brief Data Indication from MAC to SCH to + * indicate the arrival of the data on SPS logical channels +* +* @details +* +* Function : RgMacSchSpsRel +* +* @param[in] Pst* pst +* @param[in] RgInfSpsRelInfo* relInfo +* @return S16 +* -# ROK +**/ +#ifdef ANSI +PUBLIC S16 RgMacSchSpsRel +( +Pst* pst, +RgInfSpsRelInfo* relInfo +) +#else +PUBLIC S16 RgMacSchSpsRel(pst, relInfo) +Pst* pst; +RgInfSpsRelInfo* relInfo; +#endif +{ + + TRC3(RgMacSchS); + + RETVALUE((*RgMacSchSpsRelIndMt[0])(pst, relInfo)); +} /* end of RgMacSchSpsRel */ + +/** +* @brief Request from SCH to MAC to register the SPS logical channels of a UE +* +* @details +* +* Function : RgSchMacSpsLcReg +* +* @param[in] Pst* pst +* @param[in] RgInfSpsLcInfo *lcInfo +* @return S16 +* -# ROK +**/ +#ifdef ANSI +PUBLIC S16 RgSchMacSpsLcReg +( +Pst* pst, +RgInfSpsLcInfo *lcInfo +) +#else +PUBLIC S16 RgSchMacSpsLcReg(pst, lcInfo) +Pst* pst; +RgInfSpsLcInfo *lcInfo; +#endif +{ + + TRC3(RgSchMacSpsLcReg); + + RETVALUE((*RgSchMacSpsLcRegReqMt[0])(pst, lcInfo)); +} /* end of RgSchMacSpsLcReg */ + + + +/** +* @brief Request from SCH to MAC to reset UL SPS params +* +* @details +* +* Function : RgSchMacUlSpsReset +* +* @param[in] Pst* pst +* @param[in] RgInfUlSpsReset *lcInfo +* @return S16 +* -# ROK +**/ +#ifdef ANSI +PUBLIC S16 RgSchMacUlSpsReset +( +Pst* pst, +RgInfUlSpsReset *ulSpsResetInfo +) +#else +PUBLIC S16 RgSchMacUlSpsReset(pst, ulSpsResetInfo) +Pst* pst; +RgInfUlSpsReset *ulSpsResetInfo; +#endif +{ + + TRC3(RgSchMacUlSpsReset); + + RETVALUE((*RgSchMacUlSpsResetMt[0])(pst, ulSpsResetInfo)); +} /* end of RgSchMacUlSpsReset */ + + + +/** +* @brief Request from SCH to MAC to deregister the SPS logical channels of a UE +* +* @details +* +* Function : RgSchMacSpsLcDereg +* +* @param[in] Pst* pst +* @param[in] RgInfSpsLcInfo *lcInfo +* @return S16 +* -# ROK +**/ +#ifdef ANSI +PUBLIC S16 RgSchMacSpsLcDereg +( +Pst* pst, +CmLteCellId cellId, +CmLteRnti crnti +) +#else +PUBLIC S16 RgSchMacSpsLcDereg(pst, cellId, crnti) +Pst* pst; +CmLteCellId cellId; +CmLteRnti crnti; +#endif +{ + + TRC3(RgSchMacSpsLcDereg); + + RETVALUE((*RgSchMacSpsLcDeregReqMt[0])(pst, cellId, crnti)); +} /* end of RgSchMacSpsLcDereg */ + +#endif /* LTEMAC_SPS */ +#ifdef LTE_L2_MEAS +/** +* @brief Request from SCH to MAC for L2 Measurement +* +* @details +* +* Function : RgSchMacL2Meas +* +* @param[in] Pst* pst +* @param[in] RgInfL2MeasReq *measInfo +* @return S16 +* -# ROK +**/ +#ifdef ANSI +PUBLIC S16 RgSchMacL2Meas +( +Pst* pst, +RgInfL2MeasReq *measInfo +) +#else +PUBLIC S16 RgSchMacL2Meas(pst, measInfo) +Pst* pst; +RgInfL2MeasReq *measInfo; +#endif +{ + + TRC3(RgSchMacL2Meas); + + RETVALUE((*RgSchMacL2MeasReqMt[0])(pst, measInfo)); +} /* end of RgSchMacL2Meas */ + +/** +* @brief Request from SCH to MAC for Stopping L2 Measurement +* +* @details +* +* Function : RgSchMacL2MeasStop +* +* @param[in] Pst* pst +* @param[in] RgInfL2MeasReq *measInfo +* @return S16 +* -# ROK +**/ +#ifdef ANSI +PUBLIC S16 RgSchMacL2MeasStop +( +Pst* pst, +RgInfL2MeasStopReq *measInfo +) +#else +PUBLIC S16 RgSchMacL2MeasStop(pst, measInfo) +Pst* pst; +RgInfL2MeasStopReq *measInfo; +#endif +{ + + TRC3(RgSchMacL2MeasStop); + + RETVALUE((*RgSchMacL2MeasStopReqMt[0])(pst, measInfo)); +} /* end of RgSchMacL2Meas */ + +/** +* @brief Request from SCH to MAC for Sending L2 Measurement +* +* @details +* +* Function : RgSchMacL2MeasSend +* +* @param[in] Pst* pst +* @param[in] RgInfL2MeasReq *measInfo +* @return S16 +* -# ROK +**/ +#ifdef ANSI +PUBLIC S16 RgSchMacL2MeasSend +( +Pst* pst, +RgInfL2MeasSndReq *measInfo +) +#else +PUBLIC S16 RgSchMacL2MeasSend(pst, measInfo) +Pst* pst; +RgInfL2MeasSndReq *measInfo; +#endif +{ + + TRC3(RgSchMacL2MeasSend); + + RETVALUE((*RgSchMacL2MeasSendReqMt[0])(pst, measInfo)); +} /* end of RgSchMacL2MeasSend */ + +/** +* @brief Request from MAC to SCH for L2 Measurement +* +* @details +* +* Function : RgMacSchL2Meas +* +* @param[in] Pst* pst +* @param[in] RgInfL2MeasCfm *measInfo +* @return S16 +* -# ROK +**/ +#ifdef ANSI +PUBLIC S16 RgMacSchL2Meas +( +Pst* pst, +RgInfL2MeasCfm *measInfo +) +#else +PUBLIC S16 RgMacSchL2Meas(pst, measInfo) +Pst* pst; +RgInfL2MeasCfm *measInfo; +#endif +{ + + TRC3(RgMacSchL2Meas); + + RETVALUE((*RgMacSchL2MeasCfmMt[0])(pst, measInfo)); +} /* end of RgSchMacL2Meas */ +/** +* @brief Request from MAC to SCH for L2 Measurement +* +* @details +* +* Function : RgMacSchL2MeasStop +* +* @param[in] Pst* pst +* @param[in] RgInfL2MeasCfm *measInfo +* @return S16 +* -# ROK +**/ +#ifdef ANSI +PUBLIC S16 RgMacSchL2MeasStop +( +Pst* pst, +RgInfL2MeasCfm *measInfo +) +#else +PUBLIC S16 RgMacSchL2MeasStop(pst, measInfo) +Pst* pst; +RgInfL2MeasCfm *measInfo; +#endif +{ + + TRC3(RgMacSchL2MeasStop); + + RETVALUE((*RgMacSchL2MeasStopCfmMt[0])(pst, measInfo)); +} /* end of RgSchMacL2MeasStop*/ +#endif/*LTE_L2_MEAS*/ +/********************************************************************** + + End of file +**********************************************************************/ diff --git a/src/5gnrmac/rg_sch_pwr.c b/src/5gnrmac/rg_sch_pwr.c new file mode 100755 index 000000000..497f7500a --- /dev/null +++ b/src/5gnrmac/rg_sch_pwr.c @@ -0,0 +1,4229 @@ +/******************************************************************************* +################################################################################ +# Copyright (c) [2017-2019] [Radisys] # +# # +# 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. # +################################################################################ +*******************************************************************************/ + +/************************************************************************ + + Name: LTE-MAC layer + + Type: C source file + + Desc: C source code for power control functionality + + File: rg_sch_pwr.c + +**********************************************************************/ + +/** @file rg_sch_pwr.c +@brief This module handles schedulers' power control functionality +*/ + +static const char* RLOG_MODULE_NAME="MAC"; +static int RLOG_MODULE_ID=4096; +static int RLOG_FILE_ID=188; +/* header include files -- defines (.h) */ +#include "envopt.h" /* environment options */ +#include "envdep.h" /* environment dependent */ +#include "envind.h" /* environment independent */ +#include "gen.h" /* general layer */ +#include "ssi.h" /* system service interface */ +#include "cm_hash.h" /* common hash list */ +#include "cm_llist.h" /* common linked list library */ +#include "cm_err.h" /* common error */ +#include "cm_lte.h" /* common LTE */ +#include "cm_math.h" /* common MATH functions */ +#include "lrg.h" +#include "rgr.h" +#include "rgm.h" +#include "tfu.h" +#include "rg_env.h" +#include "rg_sch_inf.h" +#include "rg_sch_err.h" +#include "rg_sch.h" +#include "rg_sch_cmn.h" + +/* header/extern include files (.x) */ +#include "gen.x" /* general layer typedefs */ +#include "ssi.x" /* system services typedefs */ +#include "cm5.x" /* common timers */ +#include "cm_hash.x" /* common hash list */ +#include "cm_lib.x" /* common library */ +#include "cm_llist.x" /* common linked list */ +#include "cm_mblk.x" /* memory management */ +#include "cm_tkns.x" /* common tokens */ +#include "cm_lte.x" /* common tokens */ +#include "cm_math.x" /* common MATH functions */ +#include "tfu.x" /* RGU types */ +#include "lrg.x" /* layer management typedefs for MAC */ +#include "rgr.x" /* layer management typedefs for MAC */ +#include "rgm.x" /* layer management typedefs for MAC */ +#include "rg_sch_inf.x" /* typedefs for Scheduler */ +#include "rg_sch.x" /* typedefs for Scheduler */ +#include "rg_sch_cmn.x" +#include "rl_interface.h" +#include "rl_common.h" + + +/* Current specs have 23 dBm as max tx power capability for UEs */ +#define RG_SCH_PWR_UE_MAX_PWR 23 + +#define RG_SCH_REF_PCMAX 0xFF + +#define RG_SCH_CMN_GET_UL_UE(_ue,_cell) (&(((RgSchCmnUe *)((_ue->cellInfo[_ue->cellIdToCellIdxMap\ + [RG_SCH_CELLINDEX(_cell)]])->sch))->ul)) +#define RG_SCH_PWR_GETUEPWR(_ue, _cell) &(((RgSchCmnUe *)((_ue->cellInfo[_ue->cellIdToCellIdxMap\ + [RG_SCH_CELLINDEX(_cell)]])->sch))->ul.ulPwrCb) +#define RG_SCH_PWR_GETCELLPWR(cell) &((RgSchCmnCell *)((cell)->sc.sch))->ul.ulPwrCb + + +typedef S8 RgSchCmnUlPwrCqiToPwrTbl[RG_SCH_CMN_UL_NUM_CQI]; + +PRIVATE RgSchCmnUlPwrCqiToPwrTbl rgSchPwrCqiToPwrTbl; + +/* This table maps a given number of RBs (given by array index) + * to the power in dB that these many RBs map to. */ +CONSTANT U8 rgSchPwrRbToPwrTbl[111] = { 0, /* First entry is dummy */ + 0, 3, 4, 6, 7, 7, 8, 9, 9, 10, + 10, 10, 11, 11, 11, 12, 12, 12, 12, 13, + 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, + 15, 15, 15, 15, 15, 15, 15, 15, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20 +}; + + +/* This table maps power (in dB) to number of RBs */ +/* The array size comes from max power in rgSchPwrRbToPwrTbl */ +CONSTANT U8 rgSchPwrToRbTbl[20+1] = { + 1, 1, 2, 2, 3, 4, 5, 6, 7, 9, 11, + 13, 17, 21, 26, 33, 41, 52, 65, 82, 103 +}; + + + +PRIVATE S8 rgSCHPwrGetCqiPwr ARGS(( + U8 cqi + )); +PRIVATE S8 rgSCHPwrGetCqiPwrForUe ARGS(( + RgSchCellCb *cell, + RgSchUeCb *ue, + U8 cqi + )); +PRIVATE S8 rgSCHPwrCalcEfficncyPwr ARGS(( + U32 eff + )); +PRIVATE S8 rgSCHPwrGetDelta2FrmCqi ARGS(( + U8 crntCqi, + U8 trgCqi, + RgSchUeCb *ue, + RgSchCellCb *cell + )); +PRIVATE Void rgSCHPwrGetPuschTpc ARGS(( + U8 isAcc, + S8 delta, + S8 availPwr, + U8 *tpc, + S8 *tpcDelta + )); +PRIVATE U8 rgSCHPwrGetMaxRb ARGS(( + RgSchCellCb *cell, + S8 pwr + )); +PRIVATE U8 rgSCHPwrRbToPwr ARGS(( + RgSchCellCb *cell, + U8 numRb + )); +PRIVATE Void rgSCHPwrSchedPucchRnti ARGS(( + RgSchCellCb *cell, + RgSchCmnTpcRntiCb *cb, + RgSchPdcch *pdcch, + RgSchDlSf *dlSf, + Bool *sched + )); +PRIVATE Void rgSCHPwrPuschCntrl ARGS(( + RgSchCellCb *cell, + RgSchUeCb *ue + )); +PRIVATE Void rgSCHPwrPucchCntrl ARGS(( + RgSchCellCb *cell, + RgSchUeCb *ue + )); +PRIVATE Void rgSCHPwrSchedPuschRnti ARGS(( + RgSchCellCb *cell, + RgSchCmnTpcRntiCb *cb, + RgSchPdcch *pdcch, + RgSchUlSf *ulSf, + Bool *sched + )); +PRIVATE Void rgSCHPwrGetPucchFmt3TpcForUe ARGS(( + RgSchUeCb *ue, + U8 *tpc, + S8 *delta + )); +PRIVATE Void rgSCHPwrGetPucchFmt3aTpcForUe ARGS(( + RgSchUeCb *ue, + U8 *tpc, + S8 *delta + )); +PRIVATE Void rgSCHPwrGetPuschFmt3TpcForUe ARGS(( + RgSchUeCb *ue, + U8 *tpc, + S8 *delta + )); +PRIVATE Void rgSCHPwrGetPuschFmt3aTpcForUe ARGS(( + RgSchUeCb *ue, + U8 *tpc, + S8 *delta + )); +PRIVATE Void rgSCHPwrGetAcc1bitTpc ARGS(( + S8 remPwr, + U8 *tpc, + S8 *delta + )); +PRIVATE Void rgSCHPwrGetAcc2bitTpc ARGS(( + S8 remPwr, + U8 *tpc, + S8 *delta + )); +PRIVATE Void rgSCHPwrGetAbsTpc ARGS(( + S8 remPwr, + U8 *tpc, + S8 *delta + )); +PRIVATE Void rgSCHPwrOnPucchGrpPwrForUe ARGS(( + RgSchCellCb *cell, + RgSchUeCb *ue, + S8 delta + )); +PRIVATE Void rgSCHPwrOnPuschGrpPwrForUe ARGS(( + RgSchCellCb *cell, + RgSchUeCb *ue, + S8 delta + )); +PRIVATE Bool rgSCHPwrIsDlUeSched ARGS(( + RgSchCellCb *cell, + RgSchUeCb *ue, + RgSchDlSf *sf + )); +PRIVATE Bool rgSCHPwrIsUlUeSched ARGS(( + RgSchCellCb *cell, + RgSchUeCb *ue, + RgSchUlSf *sf + )); +PRIVATE Void rgSCHPwrOnSchedPucchTpc ARGS(( + RgSchCellCb *cell, + RgSchUeCb *ue, + S8 delta + )); +PRIVATE Void rgSCHPwrOnSchedPuschTpc ARGS(( + RgSchCellCb *cell, + RgSchUeCb *ue + )); +PRIVATE S16 rgSCHPwrApplyUePwrCfg ARGS(( + RgSchCellCb *cell, + RgSchUeCb *ue, + RgrUeUlPwrCfg *pwrCfg + )); +PRIVATE Void rgSCHPwrUeResetPucch ARGS(( + RgSchCellCb *cell, + RgSchUeCb *ue + )); +PRIVATE Void rgSCHPwrUeResetPusch ARGS(( + RgSchCellCb *cell, + RgSchUeCb *ue + )); +PRIVATE Void rgSCHPwrOnPuschPwrUpd ARGS(( + RgSchCellCb *cell, + RgSchUeCb *ue + )); +PRIVATE Void rgSCHPwrAddRntiToPucchRntiLst ARGS(( + RgSchCellCb *cell, + CmLteRnti rnti, + Bool isFmt3a + )); +PRIVATE Void rgSCHPwrAddRntiToPuschRntiLst ARGS(( + RgSchCellCb *cell, + CmLteRnti rnti, + Bool isFmt3a + )); +PRIVATE Void rgSCHPwrInitTpcRntiCb ARGS(( + RgSchCmnTpcRntiCb *cb, + CmLteRnti rnti, + Bool isFmt3a + )); +PRIVATE RgSchCmnTpcRntiCb* rgSCHPwrGetPucchRntiCb ARGS(( + RgSchCellCb *cell, + CmLteRnti tpcRnti + )); +PRIVATE RgSchCmnTpcRntiCb* rgSCHPwrGetPuschRntiCb ARGS(( + RgSchCellCb *cell, + CmLteRnti tpcRnti + )); +PRIVATE Void rgSCHPwrAddUeToPucchTpcRntiCb ARGS(( + RgSchCellCb *cell, + RgSchCmnTpcRntiCb *cb, + RgSchUeCb *ue + )); +PRIVATE Void rgSCHPwrDelUeFrmPucchTpcRntiCb ARGS(( + RgSchCellCb *cell, + RgSchCmnTpcRntiCb *cb, + RgSchUeCb *ue + )); +PRIVATE Void rgSCHPwrRmvSchdUeFrmPucchTpcRntiCb ARGS(( + RgSchCellCb *cell, + RgSchCmnTpcRntiCb *cb, + RgSchUeCb *ue + )); +PRIVATE Void rgSCHPwrRmvSchdUeOnlyFrmPucchTpcRntiCb ARGS(( + RgSchCellCb *cell, + RgSchCmnTpcRntiCb *cb, + RgSchUeCb *ue + )); +PRIVATE Void rgSCHPwrRmvSchdPucchTpcRntiCb ARGS(( + RgSchCellCb *cell, + RgSchCmnTpcRntiCb *cb + )); +PRIVATE Void rgSCHPwrAddSchdUeToPucchTpcRntiCb ARGS(( + RgSchCellCb *cell, + RgSchCmnTpcRntiCb *cb, + RgSchUeCb *ue + )); +PRIVATE Void rgSCHPwrAddSchdPucchTpcRntiCb ARGS(( + RgSchCellCb *cell, + RgSchCmnTpcRntiCb *cb + )); +PRIVATE Void rgSCHPwrAddUeToPuschTpcRntiCb ARGS(( + RgSchCmnTpcRntiCb *cb, + RgSchUeCb *ue + )); +PRIVATE Void rgSCHPwrAddSchdUeToPuschTpcRntiCb ARGS(( + RgSchCellCb *cell, + RgSchCmnTpcRntiCb *cb, + RgSchUeCb *ue + )); +PRIVATE Void rgSCHPwrDelUeFrmPuschTpcRntiCb ARGS(( + RgSchCellCb *cell, + RgSchCmnTpcRntiCb *cb, + RgSchUeCb *ue + )); +PRIVATE Void rgSCHPwrRmvSchdUeFrmPuschTpcRntiCb ARGS(( + RgSchCellCb *cell, + RgSchCmnTpcRntiCb *cb, + RgSchUeCb *ue + )); +PRIVATE Void rgSCHPwrRmvSchdUeOnlyFrmPuschTpcRntiCb ARGS(( + RgSchCellCb *cell, + RgSchCmnTpcRntiCb *cb, + RgSchUeCb *ue + )); +PRIVATE Void rgSCHPwrAddSchdPuschTpcRntiCb ARGS(( + RgSchCellCb *cell, + RgSchCmnTpcRntiCb *cb + )); +PRIVATE Void rgSCHPwrRmvSchdPuschTpcRntiCb ARGS(( + RgSchCellCb *cell, + RgSchCmnTpcRntiCb *cb + )); +PRIVATE S16 rgSCHPwrChkPucchTpcRntiIdx ARGS(( + RgSchCmnTpcRntiCb *cb, + U8 idx + )); +PRIVATE S16 rgSCHPwrChkPuschTpcRntiIdx ARGS(( + RgSchCmnTpcRntiCb *cb, + U8 idx + )); +PRIVATE S16 rgSCHPwrChkUniqPucchTpcRntiIdx ARGS(( + RgSchCmnTpcRntiCb *cb, + U8 idx + )); +PRIVATE S16 rgSCHPwrChkUniqPuschTpcRntiIdx ARGS(( + RgSchCmnTpcRntiCb *cb, + U8 idx + )); +PRIVATE S16 rgSCHPwrChkTpcRntiIdx ARGS(( + RgSchCmnTpcRntiCb *cb, + U8 idx + )); +PRIVATE S8 rgSCHPwrGetPhValFromPhr ARGS(( + U8 phr + )); +PRIVATE S8 rgSCHPwrGetPCMaxValFromPCMax ARGS(( + U8 pCMax + )); + +/* local defines */ + + +/** + * @brief Does power related initialisation (not cell specific). + * + * + * @details + * + * Function : rgSCHPwrInit + * + * Processing Steps: + * - This shall precompute coding efficiency to power + * mappings (assuming beta of 1). + * + * @return Void + **/ +#ifdef ANSI +PUBLIC Void rgSCHPwrInit +( +Void +) +#else +PUBLIC Void rgSCHPwrInit() +#endif +{ + U8 idx; + TRC2(rgSCHPwrInit); + + rgSchPwrCqiToPwrTbl[0] = 0; /* This should never be used anyway */ + for (idx = 1; idx < RG_SCH_CMN_UL_NUM_CQI; ++idx) + { + rgSchPwrCqiToPwrTbl[idx] = rgSCHPwrCalcEfficncyPwr(rgSchCmnUlCqiTbl[idx].eff); + } + RETVOID; +} + +/*********************************************************** + * + * Func : rgSCHPwrGetCqiPwr + * + * Desc : Returns power corresponding to coding efficiency + * when beta pusch is assumed 1. + * + * Ret : U8 + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PRIVATE S8 rgSCHPwrGetCqiPwr +( +U8 cqi +) +#else +PRIVATE S8 rgSCHPwrGetCqiPwr(cqi) +U8 cqi; +#endif +{ + TRC2(rgSCHPwrGetCqiPwr); + + RETVALUE(rgSchPwrCqiToPwrTbl[cqi]); +} /* rgSCHPwrGetCqiPwr */ + +/*********************************************************** + * + * Func : rgSCHPwrGetCqiPwrForUe + * + * Desc : If MCS control is enabled for UE, returns + * power corresponding to CQI, else 0. + * + * Ret : U8 + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PRIVATE S8 rgSCHPwrGetCqiPwrForUe +( +RgSchCellCb *cell, +RgSchUeCb *ue, +U8 cqi +) +#else +PRIVATE S8 rgSCHPwrGetCqiPwrForUe(cell, ue, cqi) +RgSchCellCb *cell; +RgSchUeCb *ue; +U8 cqi; +#endif +{ + RgSchCmnUeUlPwrCb *uePwr = RG_SCH_PWR_GETUEPWR(ue, cell); + TRC2(rgSCHPwrGetCqiPwrForUe); + + if (!uePwr->deltaMcsEnbld) + { + RETVALUE(0); + } + RETVALUE(rgSCHPwrGetCqiPwr(cqi)); +} /* rgSCHPwrGetCqiPwrForUe */ + +/*********************************************************** + * + * Func : rgSCHPwrCalcEfficncyPwr + * + * Desc : Computes power corresponding to a coding + * efficiency. + * + * Ret : U8 + * + * Notes: Assumes beta pusch to be 1 + * + * File : + * + **********************************************************/ +#ifdef ANSI +PRIVATE S8 rgSCHPwrCalcEfficncyPwr +( +U32 eff +) +#else +PRIVATE S8 rgSCHPwrCalcEfficncyPwr(eff) +U32 eff; +#endif +{ + F64 ks = 1.25; /* or F64 */ + F64 tmp = cmPow(2, ks*eff/1024) - 1; + TRC2(rgSCHPwrCalcEfficncyPwr); + + if (tmp <= 0) + RETVALUE(0); + RETVALUE((S8)(10 * cmLog10(tmp))); +} /* rgSCHPwrCalcEfficncyPwr */ + + +/** + * @brief Returns TPC to be sent in UL allocation + * + * @details + * + * Function : rgSCHPwrPuschTpcForUe + * + * Invoking Module Processing: + * - After allocation for UE, this function shall + * be invoked to retrieve TPC. + * - This assumes that rgSCHPwrGetMaxUlRb() was + * invoked prior to final allocation for UE. + * + * Processing Steps: + * - Just return TPC that was determined + * earlier. + * - After this, do necessary updates. + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ue + * @return U8 + **/ +#ifdef ANSI +PUBLIC U8 rgSCHPwrPuschTpcForUe +( +RgSchCellCb *cell, +RgSchUeCb *ue +) +#else +PUBLIC U8 rgSCHPwrPuschTpcForUe(cell, ue) +RgSchCellCb *cell; +RgSchUeCb *ue; +#endif +{ + RgSchCmnUeUlPwrCb *uePwr = RG_SCH_PWR_GETUEPWR(ue,cell); + + UNUSED(cell); + TRC2(rgSCHPwrPuschTpcForUe); + + rgSCHPwrOnSchedPuschTpc(cell, ue); + RETVALUE(uePwr->puschTpc); +} + +/** + * @brief Handles Pusch power control for DCI format 0 + * + * @details + * + * Function : rgSCHPwrGetMaxUlRb + * + * Invoking Module Processing: + * - This shall be invoked to determine maximum + * number of UL RBs for scheduling. + * - This is expected to be invoked every time + * priority to attempt at UE allocation. Later + * TPC retrieval depends on it. + * + * Processing Steps: + * - Returns maximum allowed UL RBs to be granted + * after invoking Pusch power control. + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ue + * @return Void + **/ +#ifdef ANSI +PUBLIC U8 rgSCHPwrGetMaxUlRb +( +RgSchCellCb *cell, +RgSchUeCb *ue +) +#else +PUBLIC U8 rgSCHPwrGetMaxUlRb(cell, ue) +RgSchCellCb *cell; +RgSchUeCb *ue; +#endif +{ + RgSchCmnUeUlPwrCb *uePwr = RG_SCH_PWR_GETUEPWR(ue, cell); + TRC2(rgSCHPwrGetMaxUlRb); + + rgSCHPwrPuschCntrl(cell, ue); /* This stores tpc, delta and maxRb + * in uePwr */ + RETVALUE(uePwr->maxUlRbs); +} + +/** + * @brief Handles Pusch power control for DCI format 0 + * + * @details + * + * Function : rgSCHPwrPuschCntrl + * + * Invoking Module Processing: + * - This shall be invoked to determine TPC + * and maximum number of UL RBs for scheduling + * (through DCI format 0). + * + * Processing Steps: + * - 'remPuschPwr' is the final delta power that the UE + * should apply to get to target CQI. + * - The available headroom (availPwr) is determined. + * - Power command is given by considering remPuschPwr and + * availPwr. + * - After factoring in the power command into availPwr, the + * maximum number of RBs that can be supported is determined + * assuming that UE is going to use transmission efficiency + * corresponding to current CQI. + * - The results determined in this function are stored + * in the UE power control block. + * - [Not doing anything of power control of msg3 + * retransmissions now] + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ue + * @return Void + **/ +#ifdef ANSI +PRIVATE Void rgSCHPwrPuschCntrl +( +RgSchCellCb *cell, +RgSchUeCb *ue +) +#else +PRIVATE Void rgSCHPwrPuschCntrl(cell, ue) +RgSchCellCb *cell; +RgSchUeCb *ue; +#endif +{ + RgSchCmnUlUe *ueUl = RG_SCH_CMN_GET_UL_UE(ue, cell); + RgSchCmnUeUlPwrCb *uePwr = RG_SCH_PWR_GETUEPWR(ue, cell); + RgSchCmnUlCell *cellUl = RG_SCH_CMN_GET_UL_CELL(cell); + S8 delta; +#ifdef TFU_UPGRADE + U8 cqi = ueUl->validUlCqi; + S32 tmp; +#else + U8 cqi = ueUl->crntUlCqi[0]; +#endif + Bool isAcc = uePwr->isAccumulated; + U8 tpc; + S8 availPwr; + U8 maxRb; + + UNUSED(cell); + + TRC2(rgSCHPwrPuschCntrl); + + if (!uePwr->isPhrAvail) + { + availPwr = 60; /* setting a large value so that availPwr does + * not constrain delta */ + } + else + { + availPwr = uePwr->maxUePwr - uePwr->pwrPerRb; + availPwr -= rgSCHPwrGetCqiPwrForUe(cell, ue, cqi); + } + delta = uePwr->remPuschPwr; + rgSCHPwrGetPuschTpc(isAcc, delta, availPwr, &tpc, &delta); + availPwr -= delta; + + maxRb = rgSCHPwrGetMaxRb(cell,availPwr); + + /* Store the results in ue power control block to be used later */ + if(maxRb < cellUl->sbSize) + { + maxRb = cellUl->sbSize; +#ifdef TFU_UPGRADE + if(uePwr->maxPwrDeltaByPhr < 0) + { + tmp = ueUl->validUlCqi; + tmp = tmp + uePwr->maxPwrDeltaByPhr; + if (tmp < 1 ) + { + ueUl->validUlCqi = 1; + } + else + { + ueUl->validUlCqi = tmp; + } + } +#endif + } + RLOG_ARG4(L_UNUSED,DBG_CELLID,cell->cellId, + "UEID:%d Output Max Rb (%d), phVal (%d) AvailPwr (%d) ", + ue->ueId, maxRb, uePwr->phVal, availPwr); + RLOG_ARG3(L_UNUSED,DBG_CELLID,cell->cellId, + "UEID:%d pwrPerRb %d remPuschPwr %d", + ue->ueId, + uePwr->pwrPerRb, + uePwr->remPuschPwr); + uePwr->delta = delta; + uePwr->maxUlRbs = maxRb; + uePwr->puschTpc = tpc; + RETVOID; +} + +/** + * @brief Returns TPC to be sent in DL allocation + * + * @details + * + * Function : rgSCHPwrPucchTpcForUe + * + * Invoking Module Processing: + * - After DL allocation for UE, this function shall + * be invoked to obtain TPC. + * + * Processing Steps: + * - Do Pucch power control processing + * and return TPC + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ue + * @return U8 + **/ +#ifdef ANSI +PUBLIC U8 rgSCHPwrPucchTpcForUe +( +RgSchCellCb *cell, +RgSchUeCb *ue +) +#else +PUBLIC U8 rgSCHPwrPucchTpcForUe(cell, ue) +RgSchCellCb *cell; +RgSchUeCb *ue; +#endif +{ + RgSchCmnUeUlPwrCb *uePwr = RG_SCH_PWR_GETUEPWR(ue, cell); + TRC2(rgSCHPwrPucchTpcForUe); + + rgSCHPwrPucchCntrl(cell, ue); + RETVALUE(uePwr->pucchTpc); +} + +/*********************************************************** + * + * Func : rgSCHPwrGetDelta2FrmCqi + * + * Desc : Get power to be applied to achieve + * target CQI (the power returned is + * twice is actual power) + * + * Ret : S8 + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PRIVATE S8 rgSCHPwrGetDelta2FrmCqi +( +U8 crntCqi, +U8 trgCqi, +RgSchUeCb *ue, +RgSchCellCb *cell + +) +#else +PRIVATE S8 rgSCHPwrGetDelta2FrmCqi(crntCqi, trgCqi) +U8 crntCqi; +U8 trgCqi; +RgSchUeCb *ue; +RgSchCellCb *cell; +#endif +{ + RgSchCmnUeUlPwrCb *uePwr = RG_SCH_PWR_GETUEPWR(ue, cell); + TRC2(rgSCHPwrGetDelta2FrmCqi); + + if (uePwr->isPhrAvail) + { + //uePwr->maxPwrDeltaByPhr = uePwr->maxPwrPerRb - uePwr->pwrPerRb - uePwr->remPuschPwr; + uePwr->maxPwrDeltaByPhr = uePwr->maxPwrPerRb - uePwr->pwrPerRb; + } + else + { + uePwr->maxPwrDeltaByPhr = 0; + } + + if (uePwr->maxPwrDeltaByPhr < 0 && (trgCqi - crntCqi) * + RG_SCH_UL_CQI_DB_STEP_2 > 0) + { + RETVALUE(0); + } + RETVALUE(RGSCH_MIN(uePwr->maxPwrDeltaByPhr, + (trgCqi - crntCqi) * RG_SCH_UL_CQI_DB_STEP_2)); +} /* rgSCHPwrGetDelta2FrmCqi */ + +/*********************************************************** + * + * Func : rgSCHPwrGetPuschTpc + * + * Desc : Based on whether accumulation is enabled or + * not, this returns an applicable power delta + * to be applied based on the input delta. + * + * Ret : S8 + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PRIVATE Void rgSCHPwrGetPuschTpc +( +U8 isAcc, +S8 delta, +S8 availPwr, +U8 *tpc, +S8 *tpcDelta +) +#else +PRIVATE Void rgSCHPwrGetPuschTpc(isAcc, delta, availPwr, tpc, tpcDelta) +U8 isAcc; +S8 delta; +S8 availPwr; +U8 *tpc; +S8 *tpcDelta; +#endif +{ + TRC2(rgSCHPwrGetPuschTpc); + + delta = RGSCH_MIN(delta, availPwr); + + /* As of now, the functions below possibly cause delta + * to be breached by 1 only. So calling these as is. */ + if (isAcc) + { + rgSCHPwrGetAcc2bitTpc(delta, tpc, tpcDelta); + } + else + { + rgSCHPwrGetAbsTpc(delta, tpc, tpcDelta); + } + RETVOID; +} /* rgSCHPwrGetPuschTpc */ + +/*********************************************************** + * + * Func : rgSCHPwrGetMaxRb + * + * Desc : Get the maximum number of RBs that can be + * expected to be supported by the passed + * power headroom. + * + * Ret : U8 + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PRIVATE U8 rgSCHPwrGetMaxRb +( +RgSchCellCb *cell, +S8 pwr +) +#else +PRIVATE U8 rgSCHPwrGetMaxRb(cell, pwr) +RgSchCellCb *cell; +S8 pwr; +#endif +{ + RgSchCmnUlCell *cellUl; + + TRC2(rgSCHPwrGetMaxRb); + + cellUl = RG_SCH_CMN_GET_UL_CELL(cell); + if (pwr <= 0) + { + /* Give 4 RBS so that UE can report changed power status*/ + /* [ccpu00119916] Mod -return 0th index of rgSchPwrToRbTbl when pwr <=0 + * Change the Macros from RGSCH_MAX_DL_BW to RGSCH_MAX_UL_BW*/ + RETVALUE(rgSchPwrToRbTbl[0]); + } + if (pwr > rgSchPwrRbToPwrTbl[cellUl->maxUlBwPerUe]) + { + RETVALUE(cellUl->maxUlBwPerUe); + } + RETVALUE(RGSCH_MIN(cellUl->maxUlBwPerUe,rgSchPwrToRbTbl[(U8)pwr])); +} /* rgSCHPwrGetMaxRb */ + +/*********************************************************** + * + * Func : rgSCHPwrRbToPwr + * + * Desc : Get the power corresponding to number of RBs + * + * Ret : U8 + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PRIVATE U8 rgSCHPwrRbToPwr +( +RgSchCellCb *cell, +U8 numRb +) +#else +PRIVATE U8 rgSCHPwrRbToPwr(cell,numRb) +RgSchCellCb *cell; +U8 numRb; +#endif +{ +#ifndef NO_ERRCLS + RgSchCmnUlCell *cellUl; +#endif + TRC2(rgSCHPwrRbToPwr); +#if (ERRCLASS & ERRCLS_DEBUG) + cellUl = RG_SCH_CMN_GET_UL_CELL(cell); + if (numRb > cellUl->maxUlBwPerUe) + { + numRb = cellUl->maxUlBwPerUe; + } +#endif + RETVALUE(rgSchPwrRbToPwrTbl[numRb]); +} /* rgSCHPwrRbToPwr */ + + +/** + * @brief Handles Pucch power control for DCI formats 1A/1B/1D/1/2A/2 + * + * @details + * + * Function : rgSCHPwrPucchCntrl + * + * Processing Steps: + * - Determine 2 bit TPC to be sent using remPucchPwr. + * - Update remPucchPwr appropriately + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ue + * @return Void + **/ +#ifdef ANSI +PRIVATE Void rgSCHPwrPucchCntrl +( +RgSchCellCb *cell, +RgSchUeCb *ue +) +#else +PRIVATE Void rgSCHPwrPucchCntrl(cell, ue) +RgSchCellCb *cell; +RgSchUeCb *ue; +#endif +{ + S8 delta; + RgSchCmnUeUlPwrCb *uePwr = RG_SCH_PWR_GETUEPWR(ue, cell); + TRC2(rgSCHPwrPucchCntrl); + + rgSCHPwrGetAcc2bitTpc(uePwr->remPucchPwr, &uePwr->pucchTpc, &delta); + rgSCHPwrOnSchedPucchTpc(cell, ue, delta); + RETVOID; +} + +/** + * @brief Handles group power control for DCI formats 3/3A for Pucch and Pusch + * + * @details + * + * Function : rgSCHPwrGrpCntrlPucch + * + * Invoking Module Processing: + * - This shall be invoked to do group power control for + * all TPC RNTIs for which it is deemed necessary to + * do the same (group power control). + * - This function should only be invoked after all UEs + * have been scheduled for uplink (re)transmissions + * requiring DL DCI format in the passed subframe. + * + * Processing Steps: + * - For Pucch group power control + * - For each TPC-Pucch-RNTI in the pucchGrpPwr List and + * TPC-Pusch-RNTI in the puschGrpPwr List, + * - Request for PDCCH, skip if not available + * - Form DCI format 3/3A information depending + * on the format type of the TPC-RNTI and add it to the sub-frame. + * - For each Ue in ueLst of TPC RNTI Cb + * - if (fmtType == 3A) + * - if((Ue not scheduled DL dci formats) + * && (remPwr >= 2 || remPwr <= -2)) + * - Determine TPC. Set puschTpc/pucchTpc. + * - remPwr -= TPC + * - if (remPwr >= -1 && remPwr <= 1) + * - If already added, remove from toBeSchdLst + * - else + * - Toggle the remainig power value + * - else if (fmtType == 3) + * - if((Ue not scheduled DL dci formats) + * && (remPwr)) + * - Determine TPC. Set puschTpc/pucchTpc. + * - remPwr -= TPC + * - if (!remPwr) + * - If already added, remove from toBeSchdLst + * - if (!toBeSchdUeCnt) + * - Remove the tpcRntiCb frm pucchGrpPwr/puschGrpPwr List + * - else, Move the tpcRntiCb to end of the list (not doing + * this) + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchDlSf *dlSf + * @return Void + **/ +#ifdef ANSI +PUBLIC Void rgSCHPwrGrpCntrlPucch +( +RgSchCellCb *cell, +RgSchDlSf *dlSf +) +#else +PUBLIC Void rgSCHPwrGrpCntrlPucch(cell, dlSf) +RgSchCellCb *cell; +RgSchDlSf *dlSf; +#endif +{ + RgSchCmnUlPwrCb *cellPwr = RG_SCH_PWR_GETCELLPWR(cell); + CmLListCp *lst; + CmLList *lnk; + RgSchPdcch *pdcch; + TRC2(rgSCHPwrGrpCntrlPucch); + + lst = &cellPwr->pucchGrpPwr; + lnk = lst->first; + while (lnk && ((pdcch = rgSCHCmnCmnPdcchAlloc(cell, dlSf)) != NULLP)) + { + RgSchCmnTpcRntiCb *cb = (RgSchCmnTpcRntiCb *)lnk->node; + Bool sched; + lnk = lnk->next; + rgSCHPwrSchedPucchRnti(cell, cb, pdcch, dlSf, &sched); + if (!sched) + { + rgSCHUtlPdcchPut(cell, &dlSf->pdcchInfo, pdcch); + } + /* TPC RNTI would not have been removed if needs to + * be scheduled again */ + } + + RETVOID; +} + +/** + * @brief Handles group power control for DCI formats 3/3A for Pusch and Pusch + * + * @details + * + * Function : rgSCHPwrGrpCntrlPusch + * + * Invoking Module Processing: + * - This shall be invoked to do group power control for + * all TPC RNTIs for which it is deemed necessary to + * do the same (group power control). + * - This function should only be invoked after all UEs + * have been scheduled for uplink (re)transmissions + * requiring DCI format 0 in the passed subframe. + * + * Processing Steps: + * - For Pusch group power control + * - For each TPC-Pusch-RNTI in the puschGrpPwr List and + * - Request for PDCCH, skip if not available + * - Form DCI format 3/3A information depending + * on the format type of the TPC-RNTI and add it to the sub-frame. + * - For each Ue in ueLst of TPC RNTI Cb + * - if (fmtType == 3A) + * - if (Ue not scheduled for dci format 0) and + * (remPwr >= 2 || remPwr <= -2)) + * - Determine TPC. Set puschTpc/puschTpc. + * - remPwr -= TPC + * - if (remPwr >= -1 && remPwr <= 1) + * - If already added, remove from toBeSchdLst + * - else + * - Toggle the remainig power value + * - else if (fmtType == 3) + * - if((Ue not scheduled for dci format 0) && (remPwr)) + * - Determine TPC. Set puschTpc. + * - remPwr -= TPC + * - if (!remPwr) + * - If already added, remove from toBeSchdLst + * - if (!toBeSchdUeCnt) + * - Remove the tpcRntiCb frm puschGrpPwr/puschGrpPwr List + * - else, Move the tpcRntiCb to end of the list (not doing + * this now) + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchDlSf *sf + * @return Void + **/ +#ifdef ANSI +PUBLIC Void rgSCHPwrGrpCntrlPusch +( +RgSchCellCb *cell, +RgSchDlSf *dlSf, +RgSchUlSf *ulSf +) +#else +PUBLIC Void rgSCHPwrGrpCntrlPusch(cell, dlSf, ulSf) +RgSchCellCb *cell; +RgSchDlSf *dlSf; +RgSchUlSf *ulSf; +#endif +{ + RgSchCmnUlPwrCb *cellPwr = RG_SCH_PWR_GETCELLPWR(cell); + CmLListCp *lst; + CmLList *lnk; + RgSchPdcch *pdcch; + TRC2(rgSCHPwrGrpCntrlPusch); + + lst = &cellPwr->puschGrpPwr; + lnk = lst->first; + while (lnk && ((pdcch = rgSCHCmnCmnPdcchAlloc(cell, dlSf)) != NULLP)) + { + RgSchCmnTpcRntiCb *cb = (RgSchCmnTpcRntiCb *)lnk->node; + Bool sched; + lnk = lnk->next; + rgSCHPwrSchedPuschRnti(cell, cb, pdcch, ulSf, &sched); + if (!sched) + { + rgSCHUtlPdcchPut(cell, &dlSf->pdcchInfo, pdcch); + } + /* TPC RNTI would not have been removed if needs to + * be scheduled again */ + } + + RETVOID; +} + +/*********************************************************** + * + * Func : rgSCHPwrSchedPucchRnti + * + * Desc : Schedule TPC RNTI to be sent out + * + * Ret : Void + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PRIVATE Void rgSCHPwrSchedPucchRnti +( +RgSchCellCb *cell, +RgSchCmnTpcRntiCb *cb, +RgSchPdcch *pdcch, +RgSchDlSf *dlSf, +Bool *sched +) +#else +PRIVATE Void rgSCHPwrSchedPucchRnti(cell, cb, pdcch, dlSf, sched) +RgSchCellCb *cell; +RgSchCmnTpcRntiCb *cb; +RgSchPdcch *pdcch; +RgSchDlSf *dlSf; +Bool *sched; +#endif +{ + CmLListCp *lst; + CmLList *lnk; + U8 *tpcCmds; + U8 tpc; + S8 delta; + Bool atleastOne; + TRC2(rgSCHPwrSchedPucchRnti); + + pdcch->rnti = cb->tpcRnti; + + if (cb->isFmt3a) + { + /* Go through all UEs for format 3A case */ + lst = &cb->cfgdUes; + pdcch->dci.dciFormat = TFU_DCI_FORMAT_3A; + pdcch->dciNumOfBits = cell->dciSize.size[TFU_DCI_FORMAT_3A]; + pdcch->dci.u.format3AInfo.isPucch = TRUE; + + tpcCmds = pdcch->dci.u.format3AInfo.tpcCmd; + /* No need to memset zero initially as every TPC is going + * to be filled up for every configured UE */ + for (atleastOne = FALSE, lnk = lst->first; lnk; lnk = lnk->next) + { + RgSchUeCb *ue = (RgSchUeCb *)lnk->node; + RgSchCmnUeUlPwrCb *uePwr = RG_SCH_PWR_GETUEPWR(ue, cell); + + if ( ue->isDrxEnabled == TRUE && + !RG_SCH_DRX_DL_IS_UE_ACTIVE(ue->drxCb)) + { + /* UE is in its DRX time. So we cannot give command + * to this UE. + */ + continue; + } + + if (rgSCHPwrIsDlUeSched(cell, ue, dlSf)) + { + /* UE already scheduled in downlink with PDCCH + * carrying PUCCH pwr cmd. So don't care about + * giving command to this UE. */ + continue; + } + rgSCHPwrGetPucchFmt3aTpcForUe(ue, &tpc, &delta); + tpcCmds[uePwr->pucchIdx] = tpc; + atleastOne = TRUE; + rgSCHPwrOnPucchGrpPwrForUe(cell, ue, delta); + } + } + else + { + /* Go through to-be-scheduled UEs for format 3 case */ + lst = &cb->toBeSchdUes; + pdcch->dci.dciFormat = TFU_DCI_FORMAT_3; + pdcch->dciNumOfBits = cell->dciSize.size[TFU_DCI_FORMAT_3]; + tpcCmds = pdcch->dci.u.format3Info.tpcCmd; + pdcch->dci.u.format3Info.isPucch = TRUE; + + /* Fill TPC 1 (corresponding to no power change) initially */ + cmMemset((U8 *)tpcCmds, 1, sizeof(pdcch->dci.u.format3Info.tpcCmd)); + + for (atleastOne = FALSE, lnk = lst->first; lnk; lnk = lnk->next) + { + RgSchUeCb *ue = (RgSchUeCb *)lnk->node; + RgSchCmnUeUlPwrCb *uePwr = RG_SCH_PWR_GETUEPWR(ue, cell); + + if ( ue->isDrxEnabled == TRUE && + !RG_SCH_DRX_DL_IS_UE_ACTIVE(ue->drxCb)) + { + /* UE is in its DRX time. So we cannot give command + * to this UE. + */ + continue; + } + + if (rgSCHPwrIsDlUeSched(cell, ue, dlSf)) + { + /* UE already scheduled in downlink with PDCCH + * carrying PUCCH pwr cmd. So don't care about + * giving command to this UE. */ + continue; + } + rgSCHPwrGetPucchFmt3TpcForUe(ue, &tpc, &delta); + tpcCmds[uePwr->pucchIdx] = tpc; + atleastOne = TRUE; + rgSCHPwrOnPucchGrpPwrForUe(cell, ue, delta); + } + } + + *sched = atleastOne; + + /* Check if no more UEs in TPC RNTI, and then remove + * this TPC RNTI from scheduled list */ + if (cb->toBeSchdUes.count == 0) + { + rgSCHPwrRmvSchdPucchTpcRntiCb(cell, cb); + } + + RETVOID; +} /* rgSCHPwrSchedPucchRnti */ + +/*********************************************************** + * + * Func : rgSCHPwrSchedPuschRnti + * + * Desc : Schedule TPC RNTI to be sent out + * + * Ret : Void + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PRIVATE Void rgSCHPwrSchedPuschRnti +( +RgSchCellCb *cell, +RgSchCmnTpcRntiCb *cb, +RgSchPdcch *pdcch, +RgSchUlSf *ulSf, +Bool *sched +) +#else +PRIVATE Void rgSCHPwrSchedPuschRnti(cell, cb, pdcch, ulSf, sched) +RgSchCellCb *cell; +RgSchCmnTpcRntiCb *cb; +RgSchPdcch *pdcch; +RgSchUlSf *ulSf; +Bool *sched; +#endif +{ + CmLListCp *lst; + CmLList *lnk; + U8 *tpcCmds; + U8 tpc; + S8 delta; + Bool atleastOne; + TRC2(rgSCHPwrSchedPuschRnti); + + pdcch->rnti = cb->tpcRnti; + + if (cb->isFmt3a) + { + /* Go through all UEs for format 3A case */ + lst = &cb->cfgdUes; + pdcch->dci.dciFormat = TFU_DCI_FORMAT_3A; + pdcch->dciNumOfBits = cell->dciSize.size[TFU_DCI_FORMAT_3A]; + pdcch->dci.u.format3AInfo.isPucch = FALSE; + tpcCmds = pdcch->dci.u.format3AInfo.tpcCmd; + /* No need to memset zero initially as every TPC is going + * to be filled up for every configured UE */ + for (atleastOne = FALSE, lnk = lst->first; lnk; lnk = lnk->next) + { + RgSchUeCb *ue = (RgSchUeCb *)lnk->node; + RgSchCmnUeUlPwrCb *uePwr = RG_SCH_PWR_GETUEPWR(ue, cell); + if (rgSCHPwrIsUlUeSched(cell, ue, ulSf)) + { + /* UE already scheduled in uplink with DCI + * format 0. So don't care about giving + * command to this UE. */ + continue; + } + + if ( ue->isDrxEnabled == TRUE && + !RG_SCH_DRX_DL_IS_UE_ACTIVE(ue->drxCb)) + { + /* UE is in its DRX time. So we cannot give command + * to this UE. + */ + continue; + } + + rgSCHPwrGetPuschFmt3aTpcForUe(ue, &tpc, &delta); + tpcCmds[uePwr->puschIdx] = tpc; + atleastOne = TRUE; + rgSCHPwrOnPuschGrpPwrForUe(cell, ue, delta); + } + } + else + { + /* Go through to-be-scheduled UEs for format 3 case */ + lst = &cb->toBeSchdUes; + pdcch->dci.dciFormat = TFU_DCI_FORMAT_3; + pdcch->dciNumOfBits = cell->dciSize.size[TFU_DCI_FORMAT_3]; + pdcch->dci.u.format3Info.isPucch = FALSE; + tpcCmds = pdcch->dci.u.format3Info.tpcCmd; + + /* Fill TPC 1 (corresponding to no power change) initially */ + cmMemset((U8 *)tpcCmds, 1, sizeof(pdcch->dci.u.format3Info.tpcCmd)); + + for (atleastOne = FALSE, lnk = lst->first; lnk; lnk = lnk->next) + { + RgSchUeCb *ue = (RgSchUeCb *)lnk->node; + RgSchCmnUeUlPwrCb *uePwr = RG_SCH_PWR_GETUEPWR(ue, cell); + if (rgSCHPwrIsUlUeSched(cell, ue, ulSf)) + { + /* UE already scheduled in uplink with DCI + * format 0. So don't care about giving + * command to this UE. */ + continue; + } + + if ( ue->isDrxEnabled == TRUE && + !RG_SCH_DRX_DL_IS_UE_ACTIVE(ue->drxCb)) + { + /* UE is in its DRX time. So we cannot give command + * to this UE. + */ + continue; + } + + rgSCHPwrGetPuschFmt3TpcForUe(ue, &tpc, &delta); + tpcCmds[uePwr->puschIdx] = tpc; + atleastOne = TRUE; + rgSCHPwrOnPuschGrpPwrForUe(cell, ue, delta); + } + } + + *sched = atleastOne; + + /* Check if no more UEs in TPC RNTI, and then remove + * this TPC RNTI from scheduled list */ + if (cb->toBeSchdUes.count == 0) + { + rgSCHPwrRmvSchdPuschTpcRntiCb(cell, cb); + } + + RETVOID; +} /* rgSCHPwrSchedPuschRnti */ + +/*********************************************************** + * + * Func : rgSCHPwrGetPucchFmt3TpcForUe + * + * Desc : Gets 2 bit TPC cmd for PUCCH + * + * Ret : Void + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PRIVATE Void rgSCHPwrGetPucchFmt3TpcForUe +( +RgSchUeCb *ue, +U8 *tpc, +S8 *delta +) +#else +PRIVATE Void rgSCHPwrGetPucchFmt3TpcForUe(ue, tpc, delta) +RgSchUeCb *ue; +U8 *tpc; +S8 *delta; +#endif +{ + RgSchCmnUeUlPwrCb *uePwr = RG_SCH_PWR_GETUEPWR(ue, ue->cell); + TRC2(rgSCHPwrGetPucchFmt3TpcForUe); + + rgSCHPwrGetAcc2bitTpc(uePwr->remPucchPwr, tpc, delta); + RETVOID; +} /* rgSCHPwrGetPucchFmt3TpcForUe */ + +/*********************************************************** + * + * Func : rgSCHPwrGetPucchFmt3aTpcForUe + * + * Desc : Gets 1 bit TPC cmd for PUCCH + * + * Ret : Void + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PRIVATE Void rgSCHPwrGetPucchFmt3aTpcForUe +( +RgSchUeCb *ue, +U8 *tpc, +S8 *delta +) +#else +PRIVATE Void rgSCHPwrGetPucchFmt3aTpcForUe(ue, tpc, delta) +RgSchUeCb *ue; +U8 *tpc; +S8 *delta; +#endif +{ + RgSchCmnUeUlPwrCb *uePwr = RG_SCH_PWR_GETUEPWR(ue, ue->cell); + TRC2(rgSCHPwrGetPucchFmt3aTpcForUe); + + rgSCHPwrGetAcc1bitTpc(uePwr->remPucchPwr, tpc, delta); + RETVOID; +} /* rgSCHPwrGetPucchFmt3aTpcForUe */ + +/*********************************************************** + * + * Func : rgSCHPwrGetPuschFmt3TpcForUe + * + * Desc : Gets 2 bit TPC cmd for PUCCH + * + * Ret : Void + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PRIVATE Void rgSCHPwrGetPuschFmt3TpcForUe +( +RgSchUeCb *ue, +U8 *tpc, +S8 *delta +) +#else +PRIVATE Void rgSCHPwrGetPuschFmt3TpcForUe(ue, tpc, delta) +RgSchUeCb *ue; +U8 *tpc; +S8 *delta; +#endif +{ + RgSchCmnUeUlPwrCb *uePwr = RG_SCH_PWR_GETUEPWR(ue, ue->cell); + S8 adj = RGSCH_MIN(uePwr->remPuschPwr, uePwr->phVal); + TRC2(rgSCHPwrGetPuschFmt3TpcForUe); + + rgSCHPwrGetAcc2bitTpc(adj, tpc, delta); + RETVOID; +} /* rgSCHPwrGetPuschFmt3TpcForUe */ + +/*********************************************************** + * + * Func : rgSCHPwrGetPuschFmt3aTpcForUe + * + * Desc : Gets 1 bit TPC cmd for PUCCH + * + * Ret : Void + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PRIVATE Void rgSCHPwrGetPuschFmt3aTpcForUe +( +RgSchUeCb *ue, +U8 *tpc, +S8 *delta +) +#else +PRIVATE Void rgSCHPwrGetPuschFmt3aTpcForUe(ue, tpc, delta) +RgSchUeCb *ue; +U8 *tpc; +S8 *delta; +#endif +{ + RgSchCmnUeUlPwrCb *uePwr = RG_SCH_PWR_GETUEPWR(ue, ue->cell); + TRC2(rgSCHPwrGetPuschFmt3aTpcForUe); + + /* Don't attempt to look at headroom now, power + * adjustment is small anyway */ + rgSCHPwrGetAcc1bitTpc(uePwr->remPuschPwr, tpc, delta); + RETVOID; +} /* rgSCHPwrGetPuschFmt3aTpcForUe */ + +/*********************************************************** + * + * Func : rgSCHPwrGetAcc1bitTpc + * + * Desc : Gets 1 bit TPC cmd + * + * Ret : Void + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PRIVATE Void rgSCHPwrGetAcc1bitTpc +( +S8 remPwr, +U8 *tpc, +S8 *delta +) +#else +PRIVATE Void rgSCHPwrGetAcc1bitTpc(remPwr, tpc, delta) +S8 remPwr; +U8 *tpc; +S8 *delta; +#endif +{ + TRC2(rgSCHPwrGetAcc1bitTpc); + /* + * TPC delta + * 0 -1 + * 1 1 + */ + if (remPwr <= 0) + { + *delta = -1; + *tpc = 0; + } + else + { + *delta = 1; + *tpc = 1; + } + RETVOID; +} /* rgSCHPwrGetAcc1bitTpc */ + +/*********************************************************** + * + * Func : rgSCHPwrGetAcc2bitTpc + * + * Desc : Allocate PDCCH for group power control + * + * Ret : Void + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PRIVATE Void rgSCHPwrGetAcc2bitTpc +( +S8 remPwr, +U8 *tpc, +S8 *delta +) +#else +PRIVATE Void rgSCHPwrGetAcc2bitTpc(remPwr, tpc, delta) +S8 remPwr; +U8 *tpc; +S8 *delta; +#endif +{ + /* + * TPC delta + * 0 -1 + * 1 0 + * 2 1 + * 3 3 + */ + U8 tpcs[3] = {1, 2, 2}; + U8 deltas[3] = {0, 1, 1}; + TRC2(rgSCHPwrGetAcc2bitTpc); + if (remPwr <= -1) + { + *tpc = 0; + *delta = -1; + } + else if (remPwr >= 3) + { + *tpc = 3; + *delta = 3; + } + else + { + *tpc = tpcs[(U8)remPwr]; + *delta = deltas[(U8)remPwr]; + } + RETVOID; +} /* rgSCHPwrGetAcc2bitTpc */ + +/*********************************************************** + * + * Func : rgSCHPwrGetAbsTpc + * + * Desc : Allocate PDCCH for group power control + * + * Ret : Void + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PRIVATE Void rgSCHPwrGetAbsTpc +( +S8 remPwr, +U8 *tpc, +S8 *delta +) +#else +PRIVATE Void rgSCHPwrGetAbsTpc(remPwr, tpc, delta) +S8 remPwr; +U8 *tpc; +S8 *delta; +#endif +{ + TRC2(rgSCHPwrGetAbsTpc); + /* + * TPC delta + * 0 -4 + * 1 -1 + * 2 1 + * 3 4 + */ + if (remPwr <= -3) + { + *tpc = 0; + *delta = -4; + } + else if (remPwr < 1) + { + *tpc = 1; + *delta = -1; + } + else if (remPwr < 4) + { + *tpc = 2; + *delta = 1; + } + else + { + *tpc = 3; + *delta = 4; + } + RETVOID; +} /* rgSCHPwrGetAbsTpc */ + +/*********************************************************** + * + * Func : rgSCHPwrOnPucchGrpPwrForUe + * + * Desc : Processing on sending TPC for UE through group power + * control. Apart from updating remPwr, this only takes + * care of possibly removing UE from scheduled + * list in TPC RNTI. + * It does not take care of possibly removing TPC RNTI + * from scheduled list in cell. This is done + * in the caller after TPC for all UEs has been + * determined. (This is where it differs + * from the usual OnSendingPu[cs]ch TPC] + * + * Ret : ROK/RFAILED + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PRIVATE Void rgSCHPwrOnPucchGrpPwrForUe +( +RgSchCellCb *cell, +RgSchUeCb *ue, +S8 delta +) +#else +PRIVATE Void rgSCHPwrOnPucchGrpPwrForUe(cell, ue, delta) +RgSchCellCb *cell; +RgSchUeCb *ue; +S8 delta; +#endif +{ + RgSchCmnUeUlPwrCb *uePwr = RG_SCH_PWR_GETUEPWR(ue, ue->cell); + Bool rmvUe = FALSE; + + UNUSED(cell); + + TRC2(rgSCHPwrOnPucchGrpPwrForUe); + + uePwr->remPucchPwr -= delta; + + /* UE was already scheduled for PUCCH group power + * control which is why we came here. Don't + * again check for this. */ + + /* UE was scheduled for pucch grp pwr, sent TPC may + * possibly cause it to be removed. */ + if (!uePwr->remPucchPwr) + { + rmvUe = TRUE; + } + if (rmvUe) + { + rgSCHPwrRmvSchdUeOnlyFrmPucchTpcRntiCb(cell, uePwr->tpcPucchRntiCb, ue); + /* Not removing TPC RNTI from scheduled list, + * this will happen in the caller once this + * function is called for every UE scheduled. */ + } + RETVOID; +} + +/*********************************************************** + * + * Func : rgSCHPwrOnPuschGrpPwrForUe + * + * Desc : Processing on sending TPC for UE through group power + * control. Apart from updating remPwr, this only takes + * care of possibly removing UE from scheduled + * list in TPC RNTI. + * It does not take care of possibly removing TPC RNTI + * from scheduled list in cell. This is done + * in the caller after TPC for all UEs has been + * determined. (This is where it differs + * from the usual OnSendingPu[cs]ch TPC] + * + * Ret : ROK/RFAILED + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PRIVATE Void rgSCHPwrOnPuschGrpPwrForUe +( +RgSchCellCb *cell, +RgSchUeCb *ue, +S8 delta +) +#else +PRIVATE Void rgSCHPwrOnPuschGrpPwrForUe(cell, ue, delta) +RgSchCellCb *cell; +RgSchUeCb *ue; +S8 delta; +#endif +{ + RgSchCmnUeUlPwrCb *uePwr = RG_SCH_PWR_GETUEPWR(ue, ue->cell); + Bool rmvUe = FALSE; + + UNUSED(cell); + TRC2(rgSCHPwrOnPuschGrpPwrForUe); + + uePwr->delta = delta; + uePwr->remPuschPwr -= delta; + if (uePwr->isPhrAvail) + { + uePwr->phVal -= uePwr->delta; + uePwr->phVal = RGSCH_MAX(-23, uePwr->phVal); + } + + /* UE was already scheduled for PUSCH group power + * control which is why we came here. Don't + * again check for this. */ + + /* UE was scheduled for pusch grp pwr, sent TPC may + * possibly cause it to be removed. */ + + if (!uePwr->remPuschPwr) + { + rmvUe = TRUE; + } + + if (rmvUe) + { + rgSCHPwrRmvSchdUeOnlyFrmPuschTpcRntiCb(cell, uePwr->tpcPuschRntiCb, ue); + /* Not removing TPC RNTI from scheduled list, + * this will happen in the caller once this + * function is called for every UE scheduled. */ + } + RETVOID; +} + +/*********************************************************** + * + * Func : rgSCHPwrIsDlUeSched + * + * Desc : Check if UE is scheduled in the passed DL SF + * + * Ret : Void + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PRIVATE Bool rgSCHPwrIsDlUeSched +( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgSchDlSf *sf +) +#else +PRIVATE Bool rgSCHPwrIsDlUeSched(cell, ue, sf) +RgSchCellCb *cell; +RgSchUeCb *ue; +RgSchDlSf *sf; +#endif +{ + RgSchDlHqEnt *hqEnt = RG_SCH_CMN_GET_UE_HQE(ue, cell); + RgSchDlHqProcCb *proc = rgSCHDhmLastSchedHqProc(hqEnt); + + TRC2(rgSCHPwrIsDlUeSched); + + if (proc == NULLP) + { + RETVALUE(FALSE); + } + + /* + * The following subframe check is assumed enough, since + * scheduled procs stay for a short time (until feedback + * arrives), which typically is expected to have a + * turnaround time of less than 8 subframes. So + * we are probably never going to come across cases + * where a process stays in the list for more than + * 10 subframes, which would have otherwise caused + * the check to succeed for a possibly older process. + */ + if ((proc->tbInfo[0].timingInfo.subframe == sf->sfNum) || + (proc->tbInfo[1].timingInfo.subframe == sf->sfNum)) + { + /* + * Later, if a proc can be scheduled without having an + * associated PDCCH, need to also check if PDCCH exists. + * This is because for power, what matters is whether + * TPC is going out for UE at this time or not, at least + * that is what this function was introduced for. + * Checking for PDCCH would have to be in common proc + * the way things are now. + */ + RETVALUE(TRUE); + } + else + { + RETVALUE(FALSE); + } +} /* rgSCHPwrIsDlUeSched */ + +/*********************************************************** + * + * Func : rgSCHPwrIsUlUeSched + * + * Desc : Check if UE is scheduled in the passed UL SF + * + * Ret : Void + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PRIVATE Bool rgSCHPwrIsUlUeSched +( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgSchUlSf *sf +) +#else +PRIVATE Bool rgSCHPwrIsUlUeSched(cell, ue, sf) +RgSchCellCb *cell; +RgSchUeCb *ue; +RgSchUlSf *sf; +#endif +{ + RgSchCmnUlCell *cmnCell = RG_SCH_CMN_GET_UL_CELL(cell); + RgSchUlHqProcCb *proc = rgSCHUhmGetUlHqProc(cell, ue, cmnCell->schdHqProcIdx); + + TRC2(rgSCHPwrIsUlUeSched); + + UNUSED(sf); + +#if (ERRCLASS & ERRCLS_DEBUG) + if( proc == NULLP ) + { + RETVALUE (FALSE); + } +#endif + + if (proc->alloc) + { + RETVALUE(TRUE); + } + else + { + RETVALUE(FALSE); + } +} /* rgSCHPwrIsUlUeSched */ + +/** + * @brief Handles Pucch power delta indication recieved from PHY + * + * @details + * + * Function : rgSCHPwrPucchDeltaInd + * + * Invoking Module Processing: + * - This shall be invoked on reception of Pucch power + * delta indication from PHY. + * + * Processing Steps: + * - Update the remPucchPwr + * ue->remPucchPwr = pwrDelta + * - If (ue->tpcPucchRntiCb) + * - If (fmtType = 3A) + * - if (remPucchPwr >= 2 || remPucchPwr <= -2 ) + * - if (tpcPucchRntiCb is not in the pucchGrpPwr List) + * - Add tpcPucchRntiCb to the pucchGrpPwr list. + * - If not added, add to toBeSchdLst + * - else + * - If already added, remove from toBeSchdLst + * - else If (fmtType == 3) + * - if (remPucchPwr) + * - if (tpcPucchRntiCb is not in the pucchGrpPwr List) + * - Add tpcPucchRntiCb to the pucchGrpPwr list. + * - If not added, add to toBeSchdLst + * - else + * - If already added, remove from toBeSchdLst + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ue + * @param[in] U8 pwrDelta + * @return Void + **/ +#ifdef ANSI +PUBLIC Void rgSCHPwrPucchDeltaInd +( +RgSchCellCb *cell, +RgSchUeCb *ue, +S8 pwrDelta +) +#else +PUBLIC Void rgSCHPwrPucchDeltaInd(cell, ue, pwrDelta) +RgSchCellCb *cell; +RgSchUeCb *ue; +S8 pwrDelta; +#endif +{ + RgSchCmnUeUlPwrCb *uePwr = RG_SCH_PWR_GETUEPWR(ue, cell); + RgSchCmnTpcRntiCb *cb; + Bool toAdd; + TRC2(rgSCHPwrPucchDeltaInd); + + uePwr->remPucchPwr = pwrDelta; + + if ((cb = uePwr->tpcPucchRntiCb) == NULLP) + { + RETVOID; + } + + toAdd = FALSE; + + if (0 != uePwr->remPucchPwr) + { + toAdd = TRUE; + } + + + if (toAdd) + { + rgSCHPwrAddSchdUeToPucchTpcRntiCb(cell, cb, ue); + } + else + { + rgSCHPwrRmvSchdUeFrmPucchTpcRntiCb(cell, cb, ue); + } + + RETVOID; +} + +/** + * @brief Does processing after TPC for Pucch has been sent + * + * @details + * + * Function : rgSCHPwrOnSchedPucchTpc + * + * Invoking Module Processing: + * - It shall be invoked after it is determined that PDCCH for UE + * is finalised to go out, and thus TPC for PUCCH is being + * sent out. + * + * Processing Steps: + * - Update remPucchPwr with the delta + * - Do group power control related processing + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ue + * @param[in] S8 delta + * @return Void + **/ +#ifdef ANSI +PRIVATE Void rgSCHPwrOnSchedPucchTpc +( +RgSchCellCb *cell, +RgSchUeCb *ue, +S8 delta +) +#else +PRIVATE Void rgSCHPwrOnSchedPucchTpc(cell, ue, delta) +RgSchCellCb *cell; +RgSchUeCb *ue; +S8 delta; +#endif +{ + /* Similar to rgSCHPwrPucchDeltaInd.. not reusing + * that since we use the fact that UE could only have + * improved its remPwr as part of power control. */ + RgSchCmnUeUlPwrCb *uePwr = RG_SCH_PWR_GETUEPWR(ue, cell); + Bool rmvUe = FALSE; + TRC2(rgSCHPwrOnSchedPucchTpc); + + uePwr->remPucchPwr -= delta; + + if (uePwr->schdPucchGrpLnk.node == NULLP) + { + RETVOID; + } + + /* UE was scheduled for TPC, sent TPC may + * possibly cause it to be removed. */ + + if (!uePwr->remPucchPwr) + { + rmvUe = TRUE; + } + + if (rmvUe) + { + rgSCHPwrRmvSchdUeFrmPucchTpcRntiCb(cell, uePwr->tpcPucchRntiCb, ue); + if (uePwr->tpcPucchRntiCb->toBeSchdUes.count == 0) + { + rgSCHPwrRmvSchdPucchTpcRntiCb(cell, uePwr->tpcPucchRntiCb); + } + } + RETVOID; +} + + +/** + * @brief Does processing after TPC for Pusch has been sent + * + * @details + * + * Function : rgSCHPwrOnSchedPuschTpc + * + * Processing Steps: + * - If accumulative + * - Update remPuschPwr with the delta + * - Do group power related processing if applicable + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ue + * @return Void + **/ +#ifdef ANSI +PRIVATE Void rgSCHPwrOnSchedPuschTpc +( +RgSchCellCb *cell, +RgSchUeCb *ue +) +#else +PRIVATE Void rgSCHPwrOnSchedPuschTpc(cell, ue) +RgSchCellCb *cell; +RgSchUeCb *ue; +#endif +{ + RgSchCmnUeUlPwrCb *uePwr = RG_SCH_PWR_GETUEPWR(ue, cell); + Bool rmvUe = FALSE; + TRC2(rgSCHPwrOnSchedPuschTpc); + + /* Don't do anything for the case of absolute TPC commands */ + if (!uePwr->isAccumulated) + { + RETVOID; + } + + uePwr->remPuschPwr -= uePwr->delta; + if (uePwr->isPhrAvail) + { + uePwr->phVal -= uePwr->delta; + uePwr->phVal = RGSCH_MAX(-23, uePwr->phVal); + } + + if (uePwr->schdPuschGrpLnk.node == NULLP) + { + RETVOID; + } + + /* UE was scheduled for pusch TPC, sent TPC may + * possibly cause it to be removed. */ + + if (!uePwr->remPuschPwr) + { + rmvUe = TRUE; + } + + if (rmvUe) + { + rgSCHPwrRmvSchdUeFrmPuschTpcRntiCb(cell, uePwr->tpcPuschRntiCb, ue); + } + + RETVOID; +} + +/** + * @brief Handles PHR updation for the UE + * + * @details + * + * Function : rgSCHPwrUpdExtPhr + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ue + * @param[in] RgInfExtPhrCEInfo *extPhr + * @param[in] RgSchCmnAllocRecord allocInfo + * @return Void + **/ +#ifdef ANSI +PUBLIC Void rgSCHPwrUpdExtPhr +( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgInfExtPhrCEInfo *extPhr, +RgSchCmnAllocRecord *allocInfo +) +#else +PUBLIC Void rgSCHPwrUpdExtPhr(cell, ue, extPhr, allocInfo) +RgSchCellCb *cell; +RgSchUeCb *ue; +RgInfExtPhrCEInfo *extPhr; +RgSchCmnAllocRecord *allocInfo; +#endif +{ + U8 idx; + RgInfExtPhrSCellInfo *servCellPhr; + S8 pCMax; + + TRC2(rgSCHPwrUpdExtPhr); + + for (idx = 0; idx < extPhr->numServCells; idx++) + { + servCellPhr = &extPhr->servCellPhr[idx]; + + if (RG_SCH_REF_PCMAX == servCellPhr->pCmax) + { + pCMax = RG_SCH_CMN_PWR_USE_CFG_MAX_PWR; + } + else + { + pCMax = rgSCHPwrGetPCMaxValFromPCMax(servCellPhr->pCmax); + } + rgSCHPwrUpdPhr(ue->cellInfo[servCellPhr->sCellIdx]->cell, + ue, servCellPhr->phr, allocInfo, pCMax); + } + RETVOID; +} + +/** + * @brief Handles PHR updation for the UE + * + * @details + * + * Function : rgSCHPwrUpdPhr + * + * Invoking Module Processing: + * - This shall be invoked on reception of PHR from MAC to SCH. It shall + * pass the information of number of RBs, coding efficiency and TPC for + * the Pusch transmission for which PHR has been reported. + * + * Processing Steps: + * - Compute power per RB using the PHR report + * - ue_transmit_pwr = ue_max_pwr - PHR + * - if isDeltaMcs = TRUE + * - ue_transmit_pwr - + * [10log(phr_num_rb) + 10log(2^ (1.25 * phr_coding_effeciency) -1) + * + phr_tpc(if absolute TPC)] = pwrPerRB + * - else + * - ue_transmit_pwr - [10log(phr_num_rb) + phr_tpc(if absolute TPC)] + * = pwrPerRB + * (Use the number of RBs and efficiency used by UE which caused the PHR + * report to happen) + * - Adjust PHR according to last allocation (take into account + * number of RBs granted in the last allocation) + * - Update the PHR report in the control block + * - Set isPhrAvail = TRUE + * - Do group power control related processing if applicable + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ue + * @param[in] U8 phr + * @param[in] RgSchCmnAllocRecord allocInfo + * @param[in] U8 maxUePwr + * @return Void + **/ +#ifdef ANSI +PUBLIC Void rgSCHPwrUpdPhr +( +RgSchCellCb *cell, +RgSchUeCb *ue, +U8 phr, +RgSchCmnAllocRecord *allocInfo, +S8 maxUePwr +) +#else +PUBLIC Void rgSCHPwrUpdPhr(cell, ue, phr, allocInfo, maxUePwr) +RgSchCellCb *cell; +RgSchUeCb *ue; +U8 phr; +RgSchCmnAllocRecord *allocInfo; +S8 maxUePwr; +#endif +{ + RgSchCmnUeUlPwrCb *uePwr = RG_SCH_PWR_GETUEPWR(ue, cell); + U8 rbPwr; + U8 effPwr; + RgSchCmnUlCell *cellUl = RG_SCH_CMN_GET_UL_CELL(cell); + + TRC2(rgSCHPwrUpdPhr); + + uePwr->phVal = rgSCHPwrGetPhValFromPhr(phr); + + if (maxUePwr == RG_SCH_CMN_PWR_USE_CFG_MAX_PWR) + { + maxUePwr = uePwr->maxUePwr; + } + rbPwr = rgSCHPwrRbToPwr(cell,allocInfo->numRb); + effPwr = rgSCHPwrGetCqiPwrForUe(cell, ue, allocInfo->cqi); + uePwr->pwrPerRb = maxUePwr - uePwr->phVal - rbPwr - effPwr; + /*if (!uePwr->isAccumulated) + { + uePwr->pwrPerRb -= rgSCHPwrGetDeltaFrmAbsTpc(allocInfo->tpc); + }*/ + + /* Let headroom reflect remaining power according to last + * allocated number of RBs. Intermediate TPCs not yet + * taken care of (for accumulated case, it is anyway + * not applicable for absolute commands). */ + uePwr->phVal -= (rgSCHPwrRbToPwr(cell, cellUl->sbSize)) - rbPwr; + uePwr->phVal = RGSCH_MAX(-23, uePwr->phVal); + uePwr->isPhrAvail = TRUE; + + rgSCHPwrOnPuschPwrUpd(cell, ue); + + RLOG_ARG4(L_DEBUG,DBG_UEID,ue->ueId, + "Output: Reported PHR[%d] cqi[%u] allocRb[%u] uePwr->pwrPerRb[%d]", + uePwr->phVal, + allocInfo->cqi, + allocInfo->numRb, + uePwr->pwrPerRb); + RETVOID; +} + +/** + * @brief Handles UL CQI indication + * + * @details + * + * Function : rgSCHPwrUlCqiInd + * + * Invoking Module Processing: + * - This shall be invoked when uplink CQI indication + * is receiving from PHY for a UE. + * + * Processing Steps: + * - Update remPuschPwr. + * - Possibly schedule for group power control. + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ue + * @param[in] U8 numRb + * @return Void + **/ +#ifdef ANSI +PUBLIC Void rgSCHPwrUlCqiInd +( +RgSchCellCb *cell, +RgSchUeCb *ue +) +#else +PUBLIC Void rgSCHPwrUlCqiInd(cell, ue) +RgSchCellCb *cell; +RgSchUeCb *ue; +#endif +{ + RgSchCmnUlUe *ueUl = RG_SCH_CMN_GET_UL_UE(ue, cell); + RgSchCmnUeUlPwrCb *uePwr = RG_SCH_PWR_GETUEPWR(ue, cell); +#ifdef TFU_UPGRADE + S32 tmp; +#endif + TRC2(rgSCHPwrUlCqiInd); + + /* + * For absolute power cmd case, we could look at the time + * at which CQI was received, determine if there was a + * PUSCH TPC cmd for that time (this could come from + * group power control too), and (if this + * CQI report is indeed based on the the PUSCH tx) + * then factor in that cmd here. Not doing + * this as of now. + */ + + /* See how much power needs to be adjusted based on cqi + * differential */ + uePwr->remPuschPwr = +#ifdef TFU_UPGRADE + rgSCHPwrGetDelta2FrmCqi(ueUl->validUlCqi, uePwr->trgCqi, ue, cell); +#else + rgSCHPwrGetDelta2FrmCqi(ueUl->crntUlCqi[0], uePwr->trgCqi, ue, cell); +#endif + + rgSCHPwrOnPuschPwrUpd(cell, ue); +#ifdef TFU_UPGRADE + if(uePwr->maxPwrDeltaByPhr < 0) + { + tmp = ueUl->validUlCqi; + tmp = tmp + uePwr->maxPwrDeltaByPhr; + if (tmp < 1 ) + { + ueUl->validUlCqi = 1; + } + else + { + ueUl->validUlCqi = tmp; + } + } +#endif + + RETVOID; +} + +/** + * @brief Updates the stored last number of RBs allocated + * + * @details + * + * Function : rgSCHPwrRecordRbAlloc + * + * Invoking Module Processing: + * - This shall be invoked when uplink allocation is made for + * a UE. + * - Note: If outstanding TPCs are considered at the time + * of PHR report, the last numRb would also be known + * and then this API would not be needed. + * + * Processing Steps: + * - Adjust PHR according to now allocated number of RBs + * - Store the number of RBs + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ue + * @param[in] U8 numRb + * @return Void + **/ +#ifdef ANSI +PUBLIC Void rgSCHPwrRecordRbAlloc +( +RgSchCellCb *cell, +RgSchUeCb *ue, +U8 numRb +) +#else +PUBLIC Void rgSCHPwrRecordRbAlloc(cell, ue, numRb) +RgSchCellCb *cell; +RgSchUeCb *ue; +U8 numRb; +#endif +{ + RgSchCmnUeUlPwrCb *uePwr = RG_SCH_PWR_GETUEPWR(ue, cell); + UNUSED(cell); + TRC2(rgSCHPwrRecordRbAlloc); + RETVOID; + + if (uePwr->isPhrAvail) + { + uePwr->phVal += rgSCHPwrRbToPwr(cell,numRb) - rgSCHPwrRbToPwr(cell,uePwr->numRb); + uePwr->phVal = RGSCH_MIN(40, uePwr->phVal); + } + uePwr->numRb = numRb; + RETVOID; +} + +/** + * @brief Handles power related configuration for a cell + * + * @details + * + * Function : rgSCHPwrCellCfg + * + * Invoking Module Processing: + * - This shall be invoked during cell config + * + * Processing Steps: + * - Set pMax + * - Set target CQI + * - Update TPC-RNTI information for the cell for Pucch and Pusch. + * - For each TPC-Pucch-RNTI, + * - Call rgSCHAddRntiToPucchRntiLst() + * - For each TPC-Pusch-RNTI, + * - Call rgSCHAddRntiToPuschRntiLst() + * - Return ROK + * + * @param[in] RgSchCellCb *cell + * @param[in] RgrCellCfg *cfg + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 rgSCHPwrCellCfg +( +RgSchCellCb *cell, +RgrCellCfg *cfg +) +#else +PUBLIC S16 rgSCHPwrCellCfg(cell, cfg) +RgSchCellCb *cell; +RgrCellCfg *cfg; +#endif +{ + RgSchCmnUlPwrCb *cellPwr = RG_SCH_PWR_GETCELLPWR(cell); + CmLteRnti rnti; + CmLteRnti startRnti; + U16 size; + Bool isFmt3a; + TRC2(rgSCHPwrCellCfg); + + /* Right now, all UEs have fixed maximum power capability. So + * we store cell wide pMax as minimum of configured pMax and + * UE's max power */ + cellPwr->pMax = RGSCH_MIN(cfg->pMax, RG_SCH_PWR_UE_MAX_PWR); + + /* trgUlCqi already validated by common */ + cellPwr->trgUlCqi = cfg->trgUlCqi.trgCqi; + + /* Validate number of TPC RNTIs */ + if ((cfg->pwrCfg.pucchPwrFmt3.size + cfg->pwrCfg.pucchPwrFmt3a.size + > RG_SCH_CMN_MAX_NUM_TPC_PUCCH_RNTI) + || (cfg->pwrCfg.puschPwrFmt3.size + cfg->pwrCfg.puschPwrFmt3a.size + > RG_SCH_CMN_MAX_NUM_TPC_PUSCH_RNTI)) + { + RETVALUE(RFAILED); + } + + /* Now initialise TPC RNTIs */ + + /* Format 3 Pucch TPC RNTIs */ + isFmt3a = FALSE; + startRnti = cfg->pwrCfg.pucchPwrFmt3.startTpcRnti; + size = cfg->pwrCfg.pucchPwrFmt3.size; + for (rnti = startRnti; (rnti < startRnti + size); ++rnti) + { + rgSCHPwrAddRntiToPucchRntiLst(cell, rnti, isFmt3a); + } + + /* Format 3A Pucch TPC RNTIs */ + isFmt3a = TRUE; + startRnti = cfg->pwrCfg.pucchPwrFmt3a.startTpcRnti; + size = cfg->pwrCfg.pucchPwrFmt3a.size; + for (rnti = startRnti; (rnti < startRnti + size); ++rnti) + { + rgSCHPwrAddRntiToPucchRntiLst(cell, rnti, isFmt3a); + } + + /* Format 3 Pusch TPC RNTIs */ + isFmt3a = FALSE; + startRnti = cfg->pwrCfg.puschPwrFmt3.startTpcRnti; + size = cfg->pwrCfg.puschPwrFmt3.size; + for (rnti = startRnti; (rnti < startRnti + size); ++rnti) + { + rgSCHPwrAddRntiToPuschRntiLst(cell, rnti, isFmt3a); + } + + /* Format 3A Pusch TPC RNTIs */ + isFmt3a = TRUE; + startRnti = cfg->pwrCfg.puschPwrFmt3a.startTpcRnti; + size = cfg->pwrCfg.puschPwrFmt3a.size; + for (rnti = startRnti; (rnti < startRnti + size); ++rnti) + { + rgSCHPwrAddRntiToPuschRntiLst(cell, rnti, isFmt3a); + } + + RETVALUE(ROK); +} + +/** + * @brief Handles power related re-configuration for a cell + * + * @details + * + * Function : rgSCHPwrCellRecfg + * + * Processing Steps: + * - NONE + * + * @param[in] RgSchCellCb *cell + * @param[in] RgrCellRecfg *recfg + * @return S16 + * -# ROK + **/ +#ifdef ANSI +PUBLIC S16 rgSCHPwrCellRecfg +( +RgSchCellCb *cell, +RgrCellRecfg *recfg +) +#else +PUBLIC S16 rgSCHPwrCellRecfg(cell, recfg) +RgSchCellCb *cell; +RgrCellRecfg *recfg; +#endif +{ + UNUSED(cell); + UNUSED(recfg); + TRC2(rgSCHPwrCellRecfg); + + /* Not doing anything for power reconfig, so such structure + * in RGR */ + RETVALUE(ROK); +} + +/** + * @brief Frees power related data structures in cell + * + * @details + * + * Function : rgSCHPwrCellDel + * + * Processing Steps: + * - NONE + * + * @param[in] RgSchCellCb *cell + * @return Void + **/ +#ifdef ANSI +PUBLIC Void rgSCHPwrCellDel +( +RgSchCellCb *cell +) +#else +PUBLIC Void rgSCHPwrCellDel(cell) +RgSchCellCb *cell; +#endif +{ + UNUSED(cell); + TRC2(rgSCHPwrCellDel); + + /* There is no allocated memory, so do nothing */ + RETVOID; +} + + +#ifdef LTE_ADV +/** + * @brief Configures ULPC CB for a SCELL being added + * + * @details + * + * Function : rgSCHPwrUeSCellCfg + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ue + * @param[in] RgrUeCfg *cfg + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 rgSCHPwrUeSCellCfg +( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgrUeSecCellCfg *sCellInfoCfg +) +#else +PUBLIC S16 rgSCHPwrUeSCellCfg(cell, ue, sCellInfoCfg) +RgSchCellCb *cell; +RgSchUeCb *ue; +RgrUeSecCellCfg *sCellInfoCfg; +#endif +{ + RgSchCmnUlPwrCb *cellPwr = RG_SCH_PWR_GETCELLPWR(cell); + RgSchCmnUeUlPwrCb *uePwr = RG_SCH_PWR_GETUEPWR(ue, cell); + RgSchCmnUeUlPwrCb *uePwrPCell = RG_SCH_PWR_GETUEPWR(ue, ue->cell); + RgSchCmnUlUe *ueUl = RG_SCH_CMN_GET_UL_UE(ue, cell); + + RgSchCmnUlCell *cellUl = RG_SCH_CMN_GET_UL_CELL(cell); + + TRC2(rgSCHPwrUeSCellCfg); + + uePwr->maxUePwr = cellPwr->pMax; + uePwr->trgCqi = cellPwr->trgUlCqi; /* Overriding with UE's happens later */ + uePwr->numRb = 1; + + uePwr->maxPwrPerRb = uePwr->maxUePwr - rgSchPwrRbToPwrTbl[cellUl->sbSize]; + + uePwr->isPhrAvail = FALSE; + uePwr->phVal = 40; + uePwr->maxUlRbs = RGSCH_MAX_DL_BW; + uePwr->delta = 0; + uePwr->puschTpc = 1; + uePwr->remPuschPwr = 0; + + /* Rest of the vars update and group power control related + * config happens in the function below */ + uePwr->isAccumulated = sCellInfoCfg->ueSCellUlDedPwrCfg.isAccumulated; + uePwr->deltaMcsEnbld = sCellInfoCfg->ueSCellUlDedPwrCfg.isDeltaMCSEnabled; + + uePwr->trgCqi = uePwrPCell->trgCqi; + + if (ueUl->maxUlCqi < uePwr->trgCqi) + { + uePwr->trgCqi = ueUl->maxUlCqi; + } + uePwr->p0UePusch = sCellInfoCfg->ueSCellUlDedPwrCfg.p0UePusch; + + RETVALUE(ROK); +} +#endif + +/** + * @brief Handles power related configuration for a UE + * + * @details + * + * Function : rgSCHPwrUeCfg + * + * Processing Steps: + * - If Pusch group power configuration exists && accumulation enabled, + * - Fetch the TPC-Pusch-RNTI control block for the configured + * TPC-Pusch-RNTI. Call rgSCHGetRntiFrmPuschRntiLst(). If it does not + * exist, return RFAILED. + * - Add Ue to the ueLst of TPC-Pusch-RNTI control block. + * - Update tpcPuschRntiCb pointer in UE. + * - Update the puschIdx value. + * - If Pucch group power configuration exists && accumulation enabled, + * - Fetch the TPC-Pucch-RNTI control block for the configured + * TPC-Pucch-RNTI. Call rgSCHGetRntiFrmPucchRntiLst(). If it does not + * exist, return RFAILED. + * - Add Ue to the ueLst of TPC-Pucch-RNTI control block. + * - Update tpcPucchRntiCb pointer in UE. + * - Update the pucchIdx value. + * - Update isAccumulated and isDeltaMcs variables. + * - maxUlRbs = configured maximum UL bandwidth value per UE. + * - trgUlCqi = configured value, if any, else cell-wide default trg CQI value. + * - If format type is format 3A, update remaining power to +1 + * - Update TPC-RNTI information for the cell for Pucch and Pusch. + * - Return ROK + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ue + * @param[in] RgrUeCfg *cfg + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 rgSCHPwrUeCfg +( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgrUeCfg *cfg +) +#else +PUBLIC S16 rgSCHPwrUeCfg(cell, ue, cfg) +RgSchCellCb *cell; +RgSchUeCb *ue; +RgrUeCfg *cfg; +#endif +{ + S16 ret; + RgSchCmnUlPwrCb *cellPwr = RG_SCH_PWR_GETCELLPWR(cell); + RgSchCmnUeUlPwrCb *uePwr = RG_SCH_PWR_GETUEPWR(ue, cell); + + RgSchCmnUlCell *cellUl = RG_SCH_CMN_GET_UL_CELL(cell); + + TRC2(rgSCHPwrUeCfg); + + uePwr->maxUePwr = cellPwr->pMax; + uePwr->trgCqi = cellPwr->trgUlCqi; /* Overriding with UE's happens later */ + uePwr->numRb = 1; + + uePwr->maxPwrPerRb = uePwr->maxUePwr - rgSchPwrRbToPwrTbl[cellUl->sbSize]; + + rgSCHPwrUeResetPucch(cell, ue); + rgSCHPwrUeResetPusch(cell, ue); + + /* Rest of the vars update and group power control related + * config happens in the function below */ + ret = rgSCHPwrApplyUePwrCfg(cell, ue, &cfg->ueUlPwrCfg); + + RETVALUE(ret); +} + +/** + * @brief Handles power related re-configuration for a UE + * + * @details + * + * Function : rgSCHPwrUeRecfg + * + * Invoking Module Processing: + * - This shall be invoked by SCH_GOM at UE re-configuration. + * + * Processing Steps: + * - If change in TPC-RNTI, update the pointer and the TPC RNTI Cb appropriately. + * - If accumulation disabled, remove the UE from TPC-RNTI lists of UE, if + * it exists. + * - If group power configuration disabled, remove the UE from TPC-RNTI lists of UE, if + * it exists. + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ue + * @param[in] RgrUeRecfg *recfg + * + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 rgSCHPwrUeRecfg +( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgrUeRecfg *recfg +) +#else +PUBLIC S16 rgSCHPwrUeRecfg(cell, ue, recfg) +RgSchCellCb *cell; +RgSchUeCb *ue; +RgrUeRecfg *recfg; +#endif +{ + S16 ret; + RgSchCmnUeUlPwrCb *uePwr = RG_SCH_PWR_GETUEPWR(ue, cell); + RgrUeUlPwrCfg *pwrCfg = &recfg->ueUlPwrRecfg; + TRC2(rgSCHPwrUeRecfg); + + if (pwrCfg->p0UePucch != uePwr->p0UePucch) + { + rgSCHPwrUeResetPucch(cell, ue); + } + if ((pwrCfg->isAccumulated != uePwr->isAccumulated) + || (pwrCfg->p0UePusch != uePwr->p0UePusch)) + { + rgSCHPwrUeResetPusch(cell, ue); + } + ret = rgSCHPwrApplyUePwrCfg(cell, ue, &recfg->ueUlPwrRecfg); + + RETVALUE(ret); +} + +/*********************************************************** + * + * Func : rgSCHPwrApplyUePwrCfg + * + * Desc : Applies power config for UE. Meants to be + * used during both power config and reconfig. + * + * Ret : ROK/RFAILED + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PRIVATE S16 rgSCHPwrApplyUePwrCfg +( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgrUeUlPwrCfg *pwrCfg +) +#else +PRIVATE S16 rgSCHPwrApplyUePwrCfg(cell, ue, pwrCfg) +RgSchCellCb *cell; +RgSchUeCb *ue; +RgrUeUlPwrCfg *pwrCfg; +#endif +{ + S16 ret; + RgSchCmnUlUe *ueUl = RG_SCH_CMN_GET_UL_UE(ue, cell); + RgSchCmnUeUlPwrCb *uePwr = RG_SCH_PWR_GETUEPWR(ue, cell); + RgSchCmnTpcRntiCb *pucchRntiCb = NULLP; + RgSchCmnTpcRntiCb *puschRntiCb = NULLP; + U8 pucchIdx = 0; + U8 puschIdx = 0; + TRC2(rgSCHPwrApplyUePwrCfg); + + /* Validate Pucch group power control config */ + if (pwrCfg->uePucchPwr.pres) + { + pucchRntiCb = + rgSCHPwrGetPucchRntiCb(cell, pwrCfg->uePucchPwr.tpcRnti); + if (pucchRntiCb == NULLP) + { + RETVALUE(RFAILED); + } + pucchIdx = pwrCfg->uePucchPwr.idx; + ret = rgSCHPwrChkPucchTpcRntiIdx(pucchRntiCb, pucchIdx); + if (ret != ROK) + { + RETVALUE(ret); + } + } + + /* Validate Pusch group power control config */ + if (pwrCfg->uePuschPwr.pres) + { + puschRntiCb = + rgSCHPwrGetPuschRntiCb(cell, pwrCfg->uePuschPwr.tpcRnti); + if (puschRntiCb == NULLP) + { + RETVALUE(RFAILED); + } + puschIdx = pwrCfg->uePuschPwr.idx; + ret = rgSCHPwrChkPuschTpcRntiIdx(puschRntiCb, puschIdx); + if (ret != ROK) + { + RETVALUE(ret); + } + } + + /* Apply Pucch group power control config */ + if (pucchRntiCb) + { + if (uePwr->tpcPucchRntiCb != pucchRntiCb) /* This part for recfg */ + { + if (uePwr->tpcPucchRntiCb) + { + rgSCHPwrDelUeFrmPucchTpcRntiCb(cell, uePwr->tpcPucchRntiCb, ue); + } + uePwr->tpcPucchRntiCb = pucchRntiCb; + rgSCHPwrAddUeToPucchTpcRntiCb(cell, pucchRntiCb, ue); + } + uePwr->pucchIdx = pucchIdx; +#ifndef ALIGN_64BIT + RLOG_ARG4(L_UNUSED,DBG_CELLID,cell->cellId, + "PucchRntiCb cfgdUes(%ld %lu %lu) UEID:%d", + pucchRntiCb->cfgdUes.count,((U32)pucchRntiCb->cfgdUes.first), + ((U32)pucchRntiCb->cfgdUes.last),ue->ueId); + RLOG_ARG3(L_UNUSED,DBG_CELLID,cell->cellId, + "UEID:%d isFmt3a(%u) ueNode(%ld)", + ue->ueId,pucchRntiCb->isFmt3a, + pucchRntiCb->schdLnk.node); + RLOG_ARG4(L_UNUSED,DBG_CELLID,cell->cellId, + "toBeSchdUes(%ld %lu %lu) tpcRnti(%u)", + pucchRntiCb->toBeSchdUes.count, + ((U32)pucchRntiCb->toBeSchdUes.first), + ((U32)pucchRntiCb->toBeSchdUes.last), + pucchRntiCb->tpcRnti); +#else + RLOG_ARG4(L_UNUSED,DBG_CELLID,cell->cellId, + "PucchRntiCb cfgdUes(%ld %lu %lu) UEID:%d", + pucchRntiCb->cfgdUes.count,((U64)pucchRntiCb->cfgdUes.first), + ((U64)pucchRntiCb->cfgdUes.last),ue->ueId); + RLOG_ARG3(L_UNUSED,DBG_CELLID,cell->cellId, + "UEID:%d isFmt3a(%u) ueNode(%ld)", + ue->ueId,pucchRntiCb->isFmt3a, + pucchRntiCb->schdLnk.node); + RLOG_ARG4(L_UNUSED,DBG_CELLID,cell->cellId, + "toBeSchdUes(%ld %lu %lu) tpcRnti(%u)", + pucchRntiCb->toBeSchdUes.count, + ((U64)pucchRntiCb->toBeSchdUes.first), + ((U64)pucchRntiCb->toBeSchdUes.last), + pucchRntiCb->tpcRnti); + +#endif + } + + /* Apply Pusch group power control config */ + if (puschRntiCb) + { + if (uePwr->tpcPuschRntiCb != puschRntiCb) /* This part for recfg */ + { + if (uePwr->tpcPuschRntiCb) + { + rgSCHPwrDelUeFrmPuschTpcRntiCb(cell, uePwr->tpcPuschRntiCb, ue); + } + uePwr->tpcPuschRntiCb = puschRntiCb; + rgSCHPwrAddUeToPuschTpcRntiCb(puschRntiCb, ue); + } + uePwr->puschIdx = puschIdx; + } + + /* Update vars */ + uePwr->isAccumulated = pwrCfg->isAccumulated; + uePwr->deltaMcsEnbld = pwrCfg->isDeltaMCSEnabled; + if (pwrCfg->trgCqi) + { + uePwr->trgCqi = pwrCfg->trgCqi; + } + if (ueUl->maxUlCqi < uePwr->trgCqi) + { + uePwr->trgCqi = ueUl->maxUlCqi; + } + uePwr->p0UePusch = pwrCfg->p0UePusch; + uePwr->p0UePucch = pwrCfg->p0UePucch; + + RETVALUE(ROK); +} + + +/** + * @brief Deletes power related information for UE + * + * @details + * + * Function : rgSCHPwrUeDel + * + * Invoking Module Processing: + * - This shall be invoked by at the time of UE deletion. + * + * Processing Steps: + * - if (ue->tpcPucchRntiCb) + * - delete UE from tpcPucchRntiCb->ueLst + * - ue->tpcPucchRntiCb = NULLP + * - If in (ue->tpcPucchRntiCb->toBeSchdLst) + * - remove from the list. + * - if (ue->tpcPuschRntiCb) + * - delete UE from tpcPuschRntiCb->ueLst + * - ue->tpcPuschRntiCb = NULLP + * - If in (ue->tpcPuschRntiCb->toBeSchdLst) + * - remove from the list. + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ue + * @return Void + **/ +#ifdef ANSI +PUBLIC Void rgSCHPwrUeDel +( +RgSchCellCb *cell, +RgSchUeCb *ue +) +#else +PUBLIC Void rgSCHPwrUeDel(cell, ue) +RgSchCellCb *cell; +RgSchUeCb *ue; +#endif +{ + RgSchCmnUeUlPwrCb *uePwr = RG_SCH_PWR_GETUEPWR(ue, cell); + TRC2(rgSCHPwrUeDel); + + if (uePwr->tpcPucchRntiCb) + { + rgSCHPwrDelUeFrmPucchTpcRntiCb(cell, uePwr->tpcPucchRntiCb, ue); + uePwr->tpcPucchRntiCb = NULLP; + } + if (uePwr->tpcPuschRntiCb) + { + rgSCHPwrDelUeFrmPuschTpcRntiCb(cell, uePwr->tpcPuschRntiCb, ue); + uePwr->tpcPuschRntiCb = NULLP; + } + RETVOID; +} + +/** + * @brief Resets UE's power state + * + * @details + * + * Function : rgSCHPwrUeReset + * + * Invoking Module Processing: + * - This shall be invoked by at the time PDCCH order. + * + * Processing Steps: + * - Reset PUSCH power state + * - Reset PUCCH power state + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ue + * @return Void + **/ +#ifdef ANSI +PUBLIC Void rgSCHPwrUeReset +( +RgSchCellCb *cell, +RgSchUeCb *ue +) +#else +PUBLIC Void rgSCHPwrUeReset(cell, ue) +RgSchCellCb *cell; +RgSchUeCb *ue; +#endif +{ + TRC2(rgSCHPwrUeReset); + + rgSCHPwrUeResetPucch(cell, ue); + rgSCHPwrUeResetPusch(cell, ue); + RETVOID; +} + +/*********************************************************** + * + * Func : rgSCHPwrUeResetPucch + * + * Desc : This function is called to reset UE + * to initial PUCCH power state. + * + * Ret : Void + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PRIVATE Void rgSCHPwrUeResetPucch +( +RgSchCellCb *cell, +RgSchUeCb *ue +) +#else +PRIVATE Void rgSCHPwrUeResetPucch(cell, ue) +RgSchCellCb *cell; +RgSchUeCb *ue; +#endif +{ + RgSchCmnUeUlPwrCb *uePwr = RG_SCH_PWR_GETUEPWR(ue, cell); + TRC2(rgSCHPwrUeResetPucch); + + uePwr->pucchTpc = 1; + uePwr->remPucchPwr = 0; + if (uePwr->tpcPucchRntiCb) + { + rgSCHPwrRmvSchdUeFrmPucchTpcRntiCb(cell, uePwr->tpcPucchRntiCb, ue); + } + + /* Stack Crash problem for TRACE5 changes. Added the line below */ + RETVOID; + +} + +/*********************************************************** + * + * Func : rgSCHPwrUeResetPusch + * + * Desc : This function is called to reset UE + * to initial PUSCH power state. + * + * Ret : Void + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PRIVATE Void rgSCHPwrUeResetPusch +( +RgSchCellCb *cell, +RgSchUeCb *ue +) +#else +PRIVATE Void rgSCHPwrUeResetPusch(cell, ue) +RgSchCellCb *cell; +RgSchUeCb *ue; +#endif +{ + RgSchCmnUeUlPwrCb *uePwr = RG_SCH_PWR_GETUEPWR(ue, cell); + TRC2(rgSCHPwrUeResetPusch); + + uePwr->isPhrAvail = FALSE; + uePwr->phVal = 40; + uePwr->maxUlRbs = RGSCH_MAX_DL_BW; + uePwr->delta = 0; + uePwr->puschTpc = 1; + uePwr->remPuschPwr = 0; + if (uePwr->tpcPuschRntiCb) + { + rgSCHPwrRmvSchdUeFrmPuschTpcRntiCb(cell, uePwr->tpcPuschRntiCb, ue); + } + RETVOID; +} + +/*********************************************************** + * + * Func : rgSCHPwrOnPuschPwrUpd + * + * Desc : This function is called whenever 'remPuschPwr' + * is updated + * + * Ret : Void + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PRIVATE Void rgSCHPwrOnPuschPwrUpd +( +RgSchCellCb *cell, +RgSchUeCb *ue +) +#else +PRIVATE Void rgSCHPwrOnPuschPwrUpd(cell, ue) +RgSchCellCb *cell; +RgSchUeCb *ue; +#endif +{ + RgSchCmnUeUlPwrCb *uePwr = RG_SCH_PWR_GETUEPWR(ue, cell); + RgSchCmnTpcRntiCb *cb; + Bool toAdd; + TRC2(rgSCHPwrOnPuschPwrUpd); + + if ((cb = uePwr->tpcPuschRntiCb) == NULLP) + { + RETVOID; + } + + /* Not checking for uwPwr->isPhrAvail as uePwr->phVal + * is set to a large value initially */ + toAdd = FALSE; + + + if ((uePwr->phVal != 0) && (uePwr->remPuschPwr != 0)) + { + toAdd = TRUE; + } + + + if (toAdd) + { + rgSCHPwrAddSchdUeToPuschTpcRntiCb(cell, cb, ue); + } + else + { + rgSCHPwrRmvSchdUeFrmPuschTpcRntiCb(cell, cb, ue); + } + + RETVOID; +} + + +/*********************************************************** + * + * Func : rgSCHPwrAddRntiToPucchRntiLst + * + * + * Desc : Adds RNTI to Pucch Rnti list and updates requisite + * information. + * + * Ret : Void + * + * Notes: Assumed that array bounds are checked + * in caller before adding. + * + * File : + * + **********************************************************/ +#ifdef ANSI +PRIVATE Void rgSCHPwrAddRntiToPucchRntiLst +( +RgSchCellCb *cell, +CmLteRnti rnti, +Bool isFmt3a +) +#else +PRIVATE Void rgSCHPwrAddRntiToPucchRntiLst(cell, rnti, isFmt3a) +RgSchCellCb *cell; +CmLteRnti rnti; +Bool isFmt3a; +#endif +{ + RgSchCmnUlPwrCb *cellPwr = RG_SCH_PWR_GETCELLPWR(cell); + TRC2(rgSCHPwrAddRntiToPucchRntiLst); + + rgSCHPwrInitTpcRntiCb(&cellPwr->tpcPucchRntiLst[cellPwr->tpcPucchRntiCnt++], + rnti, isFmt3a); + RETVOID; +} + +/*********************************************************** + * + * Func : rgSCHPwrAddRntiToPuschRntiLst + * + * + * Desc : Adds RNTI to Pusch Rnti list and updates requisite + * information. + * + * Ret : Void + * + * Notes: Assumed that array bounds are checked + * in caller before adding. + * + * File : + * + **********************************************************/ +#ifdef ANSI +PRIVATE Void rgSCHPwrAddRntiToPuschRntiLst +( +RgSchCellCb *cell, +CmLteRnti rnti, +Bool isFmt3a +) +#else +PRIVATE Void rgSCHPwrAddRntiToPuschRntiLst(cell, rnti, isFmt3a) +RgSchCellCb *cell; +CmLteRnti rnti; +Bool isFmt3a; +#endif +{ + RgSchCmnUlPwrCb *cellPwr = RG_SCH_PWR_GETCELLPWR(cell); + TRC2(rgSCHPwrAddRntiToPuschRntiLst); + + rgSCHPwrInitTpcRntiCb(&cellPwr->tpcPuschRntiLst[cellPwr->tpcPuschRntiCnt++], + rnti, isFmt3a); + RETVOID; +} + +/*********************************************************** + * + * Func : rgSCHPwrInitTpcRntiCb + * + * + * Desc : Initialises a TPC RNTI CB + * + * Ret : Void + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PRIVATE Void rgSCHPwrInitTpcRntiCb +( +RgSchCmnTpcRntiCb *cb, +CmLteRnti rnti, +Bool isFmt3a +) +#else +PRIVATE Void rgSCHPwrInitTpcRntiCb(cb, rnti, isFmt3a) +RgSchCmnTpcRntiCb *cb; +CmLteRnti rnti; +Bool isFmt3a; +#endif +{ + TRC2(rgSCHPwrInitTpcRntiCb); + + cmMemset((U8 *)cb, 0, sizeof(*cb)); + cb->tpcRnti = rnti; + cb->isFmt3a = isFmt3a; + /* Not initialising lists as memset 0 takes care of it */ + /* cb->schdLnk.node is set when this rnti is to be scheduled */ + RETVOID; +} + +/*********************************************************** + * + * Func : rgSCHPwrGetPucchRntiCb + * + * + * Desc : Gets TPC RNTI control block from Pucch rnti list + * + * Ret : RgSchCmnTpcRntiCb * - Success + * NULLP - Fail + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PRIVATE RgSchCmnTpcRntiCb* rgSCHPwrGetPucchRntiCb +( +RgSchCellCb *cell, +CmLteRnti tpcRnti +) +#else +PRIVATE RgSchCmnTpcRntiCb* rgSCHPwrGetPucchRntiCb(cell, tpcRnti) +RgSchCellCb *cell; +CmLteRnti tpcRnti; +#endif +{ + RgSchCmnUlPwrCb *cellPwr = RG_SCH_PWR_GETCELLPWR(cell); + U16 idx; + TRC2(rgSCHPwrGetPucchRntiCb); + + if (!cellPwr->tpcPucchRntiCnt) + { + RETVALUE(NULLP); + } + for (idx = 0; idx < cellPwr->tpcPucchRntiCnt; ++idx) + { + if (cellPwr->tpcPucchRntiLst[idx].tpcRnti == tpcRnti) + { + RETVALUE(&cellPwr->tpcPucchRntiLst[idx]); + } + } + RETVALUE(NULLP); +} + +/*********************************************************** + * + * Func : rgSCHPwrGetPuschRntiCb + * + * + * Desc : Gets TPC RNTI control block from Pusch rnti list + * + * Ret : RgSchCmnTpcRntiCb * - Success + * NULLP - Fail + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PRIVATE RgSchCmnTpcRntiCb* rgSCHPwrGetPuschRntiCb +( +RgSchCellCb *cell, +CmLteRnti tpcRnti +) +#else +PRIVATE RgSchCmnTpcRntiCb* rgSCHPwrGetPuschRntiCb(cell, tpcRnti) +RgSchCellCb *cell; +CmLteRnti tpcRnti; +#endif +{ + RgSchCmnUlPwrCb *cellPwr = RG_SCH_PWR_GETCELLPWR(cell); + U16 idx; + TRC2(rgSCHPwrGetPuschRntiCb); + + if (!cellPwr->tpcPuschRntiCnt) + { + RETVALUE(NULLP); + } + for (idx = 0; idx < cellPwr->tpcPuschRntiCnt; ++idx) + { + if (cellPwr->tpcPuschRntiLst[idx].tpcRnti == tpcRnti) + { + RETVALUE(&cellPwr->tpcPuschRntiLst[idx]); + } + } + RETVALUE(NULLP); +} + + +/*********************************************************** + * + * Func : rgSCHPwrAddUeToPucchTpcRntiCb + * + * + * Desc : Add UE to cfgd list of UEs in rnti cb + * + * Ret : + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PRIVATE Void rgSCHPwrAddUeToPucchTpcRntiCb +( +RgSchCellCb *cell, +RgSchCmnTpcRntiCb *cb, +RgSchUeCb *ue +) +#else +PRIVATE Void rgSCHPwrAddUeToPucchTpcRntiCb(cell, cb, ue) +RgSchCellCb *cell; +RgSchCmnTpcRntiCb *cb; +RgSchUeCb *ue; +#endif +{ + RgSchCmnUeUlPwrCb *uePwr = RG_SCH_PWR_GETUEPWR(ue, ue->cell); + UNUSED(cell); + TRC2(rgSCHPwrAddUeToPucchTpcRntiCb); + + cmLListAdd2Tail(&cb->cfgdUes, &uePwr->pucchGrpLnk); + uePwr->pucchGrpLnk.node = (PTR)ue; + RETVOID; +} + +/*********************************************************** + * + * Func : rgSCHPwrDelUeFrmPucchTpcRntiCb + * + * + * Desc : Remove UE from Pucch TPC RNTI CB + * + * Ret : + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PRIVATE Void rgSCHPwrDelUeFrmPucchTpcRntiCb +( +RgSchCellCb *cell, +RgSchCmnTpcRntiCb *cb, +RgSchUeCb *ue +) +#else +PRIVATE Void rgSCHPwrDelUeFrmPucchTpcRntiCb(cell, cb, ue) +RgSchCellCb *cell; +RgSchCmnTpcRntiCb *cb; +RgSchUeCb *ue; +#endif +{ + RgSchCmnUeUlPwrCb *uePwr = RG_SCH_PWR_GETUEPWR(ue, ue->cell); + TRC2(rgSCHPwrDelUeFrmPucchTpcRntiCb); + + rgSCHPwrRmvSchdUeFrmPucchTpcRntiCb(cell, cb, ue); + cmLListDelFrm(&cb->cfgdUes, &uePwr->pucchGrpLnk); + uePwr->pucchGrpLnk.node = NULLP; + RETVOID; +} + +/*********************************************************** + * + * Func : rgSCHPwrRmvSchdUeFrmPucchTpcRntiCb + * + * + * Desc : Remove UE from to-be-scheduled list of UEs + * in Pusch RNTI CB + * + * Ret : + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PRIVATE Void rgSCHPwrRmvSchdUeFrmPucchTpcRntiCb +( +RgSchCellCb *cell, +RgSchCmnTpcRntiCb *cb, +RgSchUeCb *ue +) +#else +PRIVATE Void rgSCHPwrRmvSchdUeFrmPucchTpcRntiCb(cell, cb, ue) +RgSchCellCb *cell; +RgSchCmnTpcRntiCb *cb; +RgSchUeCb *ue; +#endif +{ + RgSchCmnUeUlPwrCb *uePwr = RG_SCH_PWR_GETUEPWR(ue, ue->cell); + TRC2(rgSCHPwrRmvSchdUeFrmPucchTpcRntiCb); + + if (uePwr->schdPucchGrpLnk.node == NULLP) + { + RETVOID; + } + rgSCHPwrRmvSchdUeOnlyFrmPucchTpcRntiCb(cell, cb, ue); + if (!cb->toBeSchdUes.count) + { + rgSCHPwrRmvSchdPucchTpcRntiCb(cell, cb); + } + RETVOID; +} + +/*********************************************************** + * + * Func : rgSCHPwrRmvSchdUeOnlyFrmPucchTpcRntiCb + * + * Desc : Remove UE from to-be-scheduled list of UEs + * in Pucch RNTI CB. Do not both about + * possibly removing Pucch RNTI CB from + * the cell wide to-be-scheduled list. + * + * Ret : + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PRIVATE Void rgSCHPwrRmvSchdUeOnlyFrmPucchTpcRntiCb +( +RgSchCellCb *cell, +RgSchCmnTpcRntiCb *cb, +RgSchUeCb *ue +) +#else +PRIVATE Void rgSCHPwrRmvSchdUeOnlyFrmPucchTpcRntiCb(cell, cb, ue) +RgSchCellCb *cell; +RgSchCmnTpcRntiCb *cb; +RgSchUeCb *ue; +#endif +{ + RgSchCmnUeUlPwrCb *uePwr = RG_SCH_PWR_GETUEPWR(ue, ue->cell); + TRC2(rgSCHPwrRmvSchdUeOnlyFrmPucchTpcRntiCb); + + if (uePwr->schdPucchGrpLnk.node != NULLP) + { + cmLListDelFrm(&cb->toBeSchdUes, &uePwr->schdPucchGrpLnk); + uePwr->schdPucchGrpLnk.node = NULLP; + } + RETVOID; +} + +/*********************************************************** + * + * Func : rgSCHPwrRmvSchdPucchTpcRntiCb + * + * Desc : Remove Pucch TPC RNTI CB from to-be-scheduled + * list in cell + * + * Ret : Void + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PRIVATE Void rgSCHPwrRmvSchdPucchTpcRntiCb +( +RgSchCellCb *cell, +RgSchCmnTpcRntiCb *cb +) +#else +PRIVATE Void rgSCHPwrRmvSchdPucchTpcRntiCb(cell, cb) +RgSchCellCb *cell; +RgSchCmnTpcRntiCb *cb; +#endif +{ + RgSchCmnUlPwrCb *cellPwr = RG_SCH_PWR_GETCELLPWR(cell); + TRC2(rgSCHPwrRmvSchdPucchTpcRntiCb); + + if (cb->schdLnk.node == NULLP) + { + RETVOID; + } + cmLListDelFrm(&cellPwr->pucchGrpPwr, &cb->schdLnk); + cb->schdLnk.node = NULLP; + RETVOID; +} + +/*********************************************************** + * + * Func : rgSCHPwrAddSchdUeToPucchTpcRntiCb + * + * Desc : Add UE to to-be-scheduled list of UEs + * in Pucch RNTI CB + * + * Ret : + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PRIVATE Void rgSCHPwrAddSchdUeToPucchTpcRntiCb +( +RgSchCellCb *cell, +RgSchCmnTpcRntiCb *cb, +RgSchUeCb *ue +) +#else +PRIVATE Void rgSCHPwrAddSchdUeToPucchTpcRntiCb(cell, cb, ue) +RgSchCellCb *cell; +RgSchCmnTpcRntiCb *cb; +RgSchUeCb *ue; +#endif +{ + RgSchCmnUeUlPwrCb *uePwr = RG_SCH_PWR_GETUEPWR(ue, ue->cell); + TRC2(rgSCHPwrAddSchdUeToPucchTpcRntiCb); + + if (uePwr->schdPucchGrpLnk.node != NULLP) + { + /* UE is already in the list */ + RETVOID; + } + cmLListAdd2Tail(&cb->toBeSchdUes, &uePwr->schdPucchGrpLnk); + uePwr->schdPucchGrpLnk.node = (PTR)ue; + if (cb->toBeSchdUes.count == 1) + { + /* This is first UE, so queue up this TPC RNTI + * for scheduling */ + rgSCHPwrAddSchdPucchTpcRntiCb(cell, cb); + } + RETVOID; +} + +/*********************************************************** + * + * Func : rgSCHPwrAddSchdPucchTpcRntiCb + * + * Desc : Add Pucch TPC RNTI CB from to-be-scheduled + * list in cell + * + * Ret : Void + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PRIVATE Void rgSCHPwrAddSchdPucchTpcRntiCb +( +RgSchCellCb *cell, +RgSchCmnTpcRntiCb *cb +) +#else +PRIVATE Void rgSCHPwrAddSchdPucchTpcRntiCb(cell, cb) +RgSchCellCb *cell; +RgSchCmnTpcRntiCb *cb; +#endif +{ + RgSchCmnUlPwrCb *cellPwr = RG_SCH_PWR_GETCELLPWR(cell); + TRC2(rgSCHPwrAddSchdPucchTpcRntiCb); + + cmLListAdd2Tail(&cellPwr->pucchGrpPwr, &cb->schdLnk); + cb->schdLnk.node = (PTR)cb; + RETVOID; +} + + +/*********************************************************** + * + * Func : rgSCHPwrAddUeToPuschTpcRntiCb + * + * + * Desc : Add UE to cfgd list of UEs in rnti cb + * + * Ret : + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PRIVATE Void rgSCHPwrAddUeToPuschTpcRntiCb +( +RgSchCmnTpcRntiCb *cb, +RgSchUeCb *ue +) +#else +PRIVATE Void rgSCHPwrAddUeToPuschTpcRntiCb(cb, ue) +RgSchCmnTpcRntiCb *cb; +RgSchUeCb *ue; +#endif +{ + RgSchCmnUeUlPwrCb *uePwr = RG_SCH_PWR_GETUEPWR(ue, ue->cell); + TRC2(rgSCHPwrAddUeToPuschTpcRntiCb); + + cmLListAdd2Tail(&cb->cfgdUes, &uePwr->puschGrpLnk); + uePwr->puschGrpLnk.node = (PTR)ue; + RETVOID; +} + +/*********************************************************** + * + * Func : rgSCHPwrAddSchdUeToPuschTpcRntiCb + * + * Desc : Add UE to to-be-scheduled list of UEs + * in Pusch RNTI CB + * + * Ret : + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PRIVATE Void rgSCHPwrAddSchdUeToPuschTpcRntiCb +( +RgSchCellCb *cell, +RgSchCmnTpcRntiCb *cb, +RgSchUeCb *ue +) +#else +PRIVATE Void rgSCHPwrAddSchdUeToPuschTpcRntiCb(cell, cb, ue) +RgSchCellCb *cell; +RgSchCmnTpcRntiCb *cb; +RgSchUeCb *ue; +#endif +{ + RgSchCmnUeUlPwrCb *uePwr = RG_SCH_PWR_GETUEPWR(ue, ue->cell); + TRC2(rgSCHPwrAddSchdUeToPuschTpcRntiCb); + + if (uePwr->schdPuschGrpLnk.node != NULLP) + { + /* UE is already in the list */ + RETVOID; + } + cmLListAdd2Tail(&cb->toBeSchdUes, &uePwr->schdPuschGrpLnk); + uePwr->schdPuschGrpLnk.node = (PTR)ue; + if (cb->toBeSchdUes.count == 1) + { + /* This is first UE, so queue up this TPC RNTI + * for scheduling */ + rgSCHPwrAddSchdPuschTpcRntiCb(cell, cb); + } + RETVOID; +} + +/*********************************************************** + * + * Func : rgSCHPwrDelUeFrmPuschTpcRntiCb + * + * + * Desc : Add UE to cfgd list of UEs in rnti cb + * + * Ret : + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PRIVATE Void rgSCHPwrDelUeFrmPuschTpcRntiCb +( +RgSchCellCb *cell, +RgSchCmnTpcRntiCb *cb, +RgSchUeCb *ue +) +#else +PRIVATE Void rgSCHPwrDelUeFrmPuschTpcRntiCb(cell, cb, ue) +RgSchCellCb *cell; +RgSchCmnTpcRntiCb *cb; +RgSchUeCb *ue; +#endif +{ + RgSchCmnUeUlPwrCb *uePwr = RG_SCH_PWR_GETUEPWR(ue, ue->cell); + TRC2(rgSCHPwrDelUeFrmPuschTpcRntiCb); + + rgSCHPwrRmvSchdUeFrmPuschTpcRntiCb(cell, cb, ue); + cmLListDelFrm(&cb->cfgdUes, &uePwr->puschGrpLnk); + uePwr->puschGrpLnk.node = NULLP; + RETVOID; +} + +/*********************************************************** + * + * Func : rgSCHPwrRmvSchdUeFrmPuschTpcRntiCb + * + * Desc : Remove UE from to-be-scheduled list of UEs + * in Pusch RNTI CB + * + * Ret : + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PRIVATE Void rgSCHPwrRmvSchdUeFrmPuschTpcRntiCb +( +RgSchCellCb *cell, +RgSchCmnTpcRntiCb *cb, +RgSchUeCb *ue +) +#else +PRIVATE Void rgSCHPwrRmvSchdUeFrmPuschTpcRntiCb(cell, cb, ue) +RgSchCellCb *cell; +RgSchCmnTpcRntiCb *cb; +RgSchUeCb *ue; +#endif +{ + RgSchCmnUeUlPwrCb *uePwr = RG_SCH_PWR_GETUEPWR(ue, ue->cell); + TRC2(rgSCHPwrRmvSchdUeFrmPuschTpcRntiCb); + + if (uePwr->schdPuschGrpLnk.node == NULLP) + { + RETVOID; + } + rgSCHPwrRmvSchdUeOnlyFrmPuschTpcRntiCb(cell, cb, ue); + if (!cb->toBeSchdUes.count) + { + rgSCHPwrRmvSchdPuschTpcRntiCb(cell, cb); + } + RETVOID; +} + +/*********************************************************** + * + * Func : rgSCHPwrRmvSchdUeOnlyFrmPuschTpcRntiCb + * + * Desc : Remove UE from to-be-scheduled list of UEs + * in Pusch RNTI CB. Do not both about + * possibly removing Pusch RNTI CB from + * the cell wide to-be-scheduled list. + * + * Ret : + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PRIVATE Void rgSCHPwrRmvSchdUeOnlyFrmPuschTpcRntiCb +( +RgSchCellCb *cell, +RgSchCmnTpcRntiCb *cb, +RgSchUeCb *ue +) +#else +PRIVATE Void rgSCHPwrRmvSchdUeOnlyFrmPuschTpcRntiCb(cell, cb, ue) +RgSchCellCb *cell; +RgSchCmnTpcRntiCb *cb; +RgSchUeCb *ue; +#endif +{ + RgSchCmnUeUlPwrCb *uePwr = RG_SCH_PWR_GETUEPWR(ue, ue->cell); + TRC2(rgSCHPwrRmvSchdUeOnlyFrmPuschTpcRntiCb); + + if (uePwr->schdPuschGrpLnk.node != NULLP) + { + cmLListDelFrm(&cb->toBeSchdUes, &uePwr->schdPuschGrpLnk); + uePwr->schdPuschGrpLnk.node = NULLP; + } + RETVOID; +} + +/*********************************************************** + * + * Func : rgSCHPwrAddSchdPuschTpcRntiCb + * + * Desc : Add Pusch TPC RNTI CB from to-be-scheduled + * list in cell + * + * Ret : Void + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PRIVATE Void rgSCHPwrAddSchdPuschTpcRntiCb +( +RgSchCellCb *cell, +RgSchCmnTpcRntiCb *cb +) +#else +PRIVATE Void rgSCHPwrAddSchdPuschTpcRntiCb(cell, cb) +RgSchCellCb *cell; +RgSchCmnTpcRntiCb *cb; +#endif +{ + RgSchCmnUlPwrCb *cellPwr = RG_SCH_PWR_GETCELLPWR(cell); + TRC2(rgSCHPwrAddSchdPuschTpcRntiCb); + + cmLListAdd2Tail(&cellPwr->puschGrpPwr, &cb->schdLnk); + cb->schdLnk.node = (PTR)cb; + RETVOID; +} + +/*********************************************************** + * + * Func : rgSCHPwrRmvSchdPuschTpcRntiCb + * + * Desc : Remove Pusch TPC RNTI CB from to-be-scheduled + * list in cell + * + * Ret : Void + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PRIVATE Void rgSCHPwrRmvSchdPuschTpcRntiCb +( +RgSchCellCb *cell, +RgSchCmnTpcRntiCb *cb +) +#else +PRIVATE Void rgSCHPwrRmvSchdPuschTpcRntiCb(cell, cb) +RgSchCellCb *cell; +RgSchCmnTpcRntiCb *cb; +#endif +{ + RgSchCmnUlPwrCb *cellPwr = RG_SCH_PWR_GETCELLPWR(cell); + TRC2(rgSCHPwrRmvSchdPuschTpcRntiCb); + + if (cb->schdLnk.node == NULLP) + { + RETVOID; + } + cmLListDelFrm(&cellPwr->puschGrpPwr, &cb->schdLnk); + cb->schdLnk.node = NULLP; + RETVOID; +} + +/*********************************************************** + * + * Func : rgSCHPwrChkPucchTpcRntiIdx + * + * Desc : Validate that the given index is OK to + * be assigned to a new UE for the Pucch TPC + * RNTI + * + * Ret : + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PRIVATE S16 rgSCHPwrChkPucchTpcRntiIdx +( +RgSchCmnTpcRntiCb *cb, +U8 idx +) +#else +PRIVATE S16 rgSCHPwrChkPucchTpcRntiIdx(cb, idx) +RgSchCmnTpcRntiCb *cb; +U8 idx; +#endif +{ + TRC2(rgSCHPwrChkPucchTpcRntiIdx); + + if (rgSCHPwrChkTpcRntiIdx(cb, idx) != ROK) + { + RETVALUE(RFAILED); + } + if (rgSCHPwrChkUniqPucchTpcRntiIdx(cb, idx) != ROK) + { + RETVALUE(RFAILED); + } + RETVALUE(ROK); +} + +/*********************************************************** + * + * Func : rgSCHPwrChkPuschTpcRntiIdx + * + * Desc : Validate that the given index is OK to + * be assigned to a new UE for the Pusch TPC + * RNTI + * + * Ret : + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PRIVATE S16 rgSCHPwrChkPuschTpcRntiIdx +( +RgSchCmnTpcRntiCb *cb, +U8 idx +) +#else +PRIVATE S16 rgSCHPwrChkPuschTpcRntiIdx(cb, idx) +RgSchCmnTpcRntiCb *cb; +U8 idx; +#endif +{ + TRC2(rgSCHPwrChkPuschTpcRntiIdx); + + if (rgSCHPwrChkTpcRntiIdx(cb, idx) != ROK) + { + RETVALUE(RFAILED); + } + if (rgSCHPwrChkUniqPuschTpcRntiIdx(cb, idx) != ROK) + { + RETVALUE(RFAILED); + } + RETVALUE(ROK); +} + +/*********************************************************** + * + * Func : rgSCHPwrChkUniqPucchTpcRntiIdx + * + * Desc : Validate index against format type of TPC RNTI + * + * Ret : + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PRIVATE S16 rgSCHPwrChkUniqPucchTpcRntiIdx +( +RgSchCmnTpcRntiCb *cb, +U8 idx +) +#else +PRIVATE S16 rgSCHPwrChkUniqPucchTpcRntiIdx(cb, idx) +RgSchCmnTpcRntiCb *cb; +U8 idx; +#endif +{ + CmLList *lnk; + TRC2(rgSCHPwrChkUniqPucchTpcRntiIdx); + + for (lnk = cb->cfgdUes.first; lnk; lnk = lnk->next) + { + RgSchUeCb *ue = (RgSchUeCb *)lnk->node; + RgSchCmnUeUlPwrCb *uePwr = RG_SCH_PWR_GETUEPWR(ue, ue->cell); + if (uePwr->pucchIdx == idx) + { + RETVALUE(RFAILED); + } + } + RETVALUE(ROK); +} + +/*********************************************************** + * + * Func : rgSCHPwrChkUniqPuschTpcRntiIdx + * + * Desc : Validate index against format type of TPC RNTI + * + * Ret : + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PRIVATE S16 rgSCHPwrChkUniqPuschTpcRntiIdx +( +RgSchCmnTpcRntiCb *cb, +U8 idx +) +#else +PRIVATE S16 rgSCHPwrChkUniqPuschTpcRntiIdx(cb, idx) +RgSchCmnTpcRntiCb *cb; +U8 idx; +#endif +{ + CmLList *lnk; + TRC2(rgSCHPwrChkUniqPuschTpcRntiIdx); + + for (lnk = cb->cfgdUes.first; lnk; lnk = lnk->next) + { + RgSchUeCb *ue = (RgSchUeCb *)lnk->node; + RgSchCmnUeUlPwrCb *uePwr = RG_SCH_PWR_GETUEPWR(ue, ue->cell); + if (uePwr->puschIdx == idx) + { + RETVALUE(RFAILED); + } + } + RETVALUE(ROK); +} + +/*********************************************************** + * + * Func : rgSCHPwrChkTpcRntiIdx + * + * Desc : Validate index against format type of TPC RNTI. + * + * Ret : + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PRIVATE S16 rgSCHPwrChkTpcRntiIdx +( +RgSchCmnTpcRntiCb *cb, +U8 idx +) +#else +PRIVATE S16 rgSCHPwrChkTpcRntiIdx(cb, idx) +RgSchCmnTpcRntiCb *cb; +U8 idx; +#endif +{ + TRC2(rgSCHPwrChkTpcRntiIdx); + + if (cb->isFmt3a) + { + if (idx >= TFU_MAX_1BIT_TPC) + { + RETVALUE(RFAILED); + } + } + else + { + if (idx >= TFU_MAX_2BIT_TPC) + { + RETVALUE(RFAILED); + } + } + RETVALUE(ROK); +} +/* Warning Fix: Commenting out as not used */ + +/*********************************************************** + * + * Func : rgSCHPwrGetPCMaxValFromPCMax + * + * Desc : Returns the power headroom in dB + * corresponding to a power headroom + * report + * + * Ret : S8 + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PRIVATE S8 rgSCHPwrGetPCMaxValFromPCMax +( +U8 pCMax +) +#else +PRIVATE S8 rgSCHPwrGetPCMaxValFromPCMax(pCMax) +U8 pCMax; +#endif +{ + TRC2(rgSCHPwrGetPCMaxValFromPCMax); + RETVALUE((pCMax & 63) - 30); +} + + + +/*********************************************************** + * + * Func : rgSCHPwrGetPhValFromPhr + * + * Desc : Returns the power headroom in dB + * corresponding to a power headroom + * report + * + * Ret : S8 + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PRIVATE S8 rgSCHPwrGetPhValFromPhr +( +U8 phr +) +#else +PRIVATE S8 rgSCHPwrGetPhValFromPhr(phr) +U8 phr; +#endif +{ + TRC2(rgSCHPwrGetPhValFromPhr); + RETVALUE((phr & 63) - 23); +} + + + +/********************************************************************** + + End of file +**********************************************************************/ diff --git a/src/5gnrmac/rg_sch_ram.c b/src/5gnrmac/rg_sch_ram.c new file mode 100755 index 000000000..ad27fe08c --- /dev/null +++ b/src/5gnrmac/rg_sch_ram.c @@ -0,0 +1,1659 @@ +/******************************************************************************* +################################################################################ +# Copyright (c) [2017-2019] [Radisys] # +# # +# 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. # +################################################################################ +*******************************************************************************/ + +/************************************************************************ + + Name: LTE-MAC layer + + Type: C source file + + Desc: C source code for Entry point fucntions + + File: rg_sch_ram.c + +**********************************************************************/ + +/** @file rg_sch_ram.c +@brief This file has APIs to handle the random access procedure functionality for the scheduler. +*/ + +static const char* RLOG_MODULE_NAME="MAC"; +static int RLOG_MODULE_ID=4096; +static int RLOG_FILE_ID=171; + +/* header include files (.h) */ +#include "envopt.h" /* environment options */ +#include "envdep.h" /* environment dependent */ +#include "envind.h" /* environment independent */ + +#include "gen.h" /* general */ +#include "ssi.h" /* system services */ + +#include "cm_tkns.h" /* Common Token Defines */ +#include "cm_llist.h" /* Common Link List Defines */ +#include "cm_hash.h" /* Common Hash List Defines */ +#include "cm_mblk.h" /* common memory link list library */ +#include "cm_lte.h" /* Common LTE */ + +#include "rg_env.h" /* MAC Environment Defines */ +#include "rgr.h" /* RGR Interface defines */ +#include "rgm.h" /* RGR Interface defines */ +#include "tfu.h" /* TFU Interface defines */ +#include "lrg.h" /* LRG Interface defines */ +#include "rg_env.h" /* Scheduler error defines */ +#include "rg_sch_inf.h" /* Scheduler defines */ +#include "rg_sch_err.h" /* Scheduler error defines */ +#include "rg_sch.h" /* Scheduler defines */ +#include "rg_sch_cmn.h" +#include "rl_interface.h" +#include "rl_common.h" + +/* header/extern include files (.x) */ +#include "gen.x" /* general */ +#include "ssi.x" /* system services */ +#include "cm5.x" /* Timer */ +#include "cm_tkns.x" /* Common Token Definitions */ +#include "cm_llist.x" /* Common Link List Definitions */ +#include "cm_lib.x" /* Common Library Definitions */ +#include "cm_hash.x" /* Common Hash List Definitions */ +#include "cm_mblk.x" /* common memory link list library */ +#include "cm_lte.x" /* Common LTE */ + +#include "rgr.x" /* RGR Interface includes */ +#include "rgm.x" /* RGR Interface includes */ +#include "tfu.x" /* TFU Interface includes */ +#include "lrg.x" /* LRG Interface includes */ + +#include "rg_sch_inf.x" /* typedefs for Scheduler */ +#include "rg_sch.x" /* Scheduler includes */ +#include "rg_sch_cmn.x" +#ifdef EMTC_ENABLE +EXTERN Bool rgSCHRamVldtRgrEmtcUeCfg ARGS(( +RgSchCellCb *cell, +RgrUeCfg *ueCfg +)); + +EXTERN S16 rgSCHRamRmvAllFrmEmtcRaInfoSchdLst +( +RgSchCellCb *cell +); +EXTERN Void rgSCHEmtcUtlUpdCmnNb +( +RgSchRaCb *raCb +); +EXTERN Void rgSCHEmtcHqPAlloc +( +RgSchCellCb *cell, +RgSchDlHqEnt *hqEnt +); +#endif +/* local defines */ +/* local typedefs */ +PRIVATE Void rgSCHRamUlFreeAllocation ARGS((RgSchUlSf *sf,RgSchUlAlloc *alloc, + RgSchCellCb *cell,Bool isEmtc)); + +PRIVATE S16 rgSCHRamContResCrnti ARGS((RgSchCellCb *cell, RgSchUeCb *ue, + RgSchRaCb *raCb, RgSchErrInfo *err)); +PRIVATE S16 rgSCHRamContResCcchsdu ARGS((RgSchCellCb *cell, RgSchRaCb *raCb)); +#ifdef EMTC_ENABLE + +EXTERN S16 rgSCHEmtcRamContResCcchsdu ARGS((RgSchCellCb *cell, RgSchRaCb *raCb)); +EXTERN S16 rgSCHRamEmtcContResCcchsdu ARGS((RgSchCellCb *cell, RgSchRaCb *raCb)); +EXTERN Void rgSCHChkEmtcContResGrdTmrExp ARGS((RgSchCellCb *cell)); +EXTERN Void rgSCHChkEmtcContResTmrExp ARGS((RgSchCellCb *cell)); +EXTERN Void rgSCHEmtcRaInfoFree ARGS((RgSchCellCb *cell, RgSchRaCb *raCb)); +#endif +#ifdef RGR_V1 +PRIVATE Void rgSCHChkContResGrdTmrExp ARGS((RgSchCellCb *cell)); +PRIVATE Void rgSCHChkContResTmrExp ARGS((RgSchCellCb *cell)); +PRIVATE Void rgSCHRamProcContResExp ARGS((RgSchCellCb *cell, + RgSchRaCb *raCb)); +PRIVATE Void rgSCHRamProcContResGrdExp ARGS((RgSchCellCb *cell, + RgSchRaCb *raCb)); +#ifdef EMTC_ENABLE +EXTERN Void rgSCHChkEmtcContResGrdTmrExp ARGS((RgSchCellCb *cell)); +EXTERN Void rgSCHChkEmtcContResTmrExp ARGS((RgSchCellCb *cell)); +#endif +#endif +/* forward references */ + +/** + * @brief Check configured preamble id not colliding with non dedicated or PDCCH + * order preamble sets. When valid preamble id given check that C-RNTI given + * in configuration is not amongst the C-RNTI'smanaged by scheduler + * + * @details + * + * Function : rgSCHRamVldtUeCfg + * + * Processing Steps: Check configured preamble id not colliding with non dedicated or PDCCH + * order preamble sets. When valid preamble id given check that C-RNTI given + * in configuration is not amongst the C-RNTI'smanaged by scheduler + * + * @param[in] RgSchCellCb *cell + * @param[in] RgrUeCfg *ueCfg + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 rgSCHRamVldtUeCfg +( +RgSchCellCb *cell, +RgrUeCfg *ueCfg +) +#else +PUBLIC S16 rgSCHRamVldtUeCfg(cell, ueCfg) +RgSchCellCb *cell; +RgrUeCfg *ueCfg; +#endif +{ + TRC2(rgSCHRamVldtUeCfg); + if (ueCfg->dedPreambleId.pres == PRSNT_NODEF) + { + if ((ueCfg->dedPreambleId.val < cell->rachCfg.numRaPreamble) || + (ueCfg->dedPreambleId.val >= RGSCH_MAX_NUM_RA_PREAMBLE) || + ((ueCfg->dedPreambleId.val >= cell->macPreambleSet.start) && + (ueCfg->dedPreambleId.val <= cell->macPreambleSet.start + + cell->macPreambleSet.size - 1)) || + ((ueCfg->crnti >= cell->rntiDb.rntiStart) && + (ueCfg->crnti < cell->rntiDb.rntiStart + cell->rntiDb.maxRntis-1)) +#ifdef EMTC_ENABLE + || (rgSCHRamVldtRgrEmtcUeCfg(cell,ueCfg)) +#endif + ) + { + RETVALUE(RFAILED); + } + } + RETVALUE(ROK); +} + +/** + * @brief Handler for Random Access Request + * + * @details + * + * Function : rgSCHRamProcRaReq + * + * -# Create a node for each TfuRaReqInfo element received + * -# Initialize the list with the above elements at the raRnti index + * in the cell. + * + * + * @param[in] RgSchCellCb *cell + * @param[in] CmLteRnti raRnti + * @param[in] RgTfuRaReqInd *raReqInd + * @param[out] RgSchErrInfo *err + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 rgSCHRamProcRaReq +( +U8 raReqCnt, +RgSchCellCb *cell, +CmLteRnti raRnti, +TfuRachInfo *raReqInd, +CmLteTimingInfo timingInfo, +RgSchUeCb *ue, +RgSchErrInfo *err +) +#else +PUBLIC S16 rgSCHRamProcRaReq(raReqCnt, cell, raRnti, raReqInd, timingInfo, ue, err) +U8 raReqCnt; +RgSchCellCb *cell; +CmLteRnti raRnti; +TfuRachInfo *raReqInd; +CmLteTimingInfo timingInfo; +RgSchUeCb *ue; +RgSchErrInfo *err; +#endif +{ + RgSchRaReqInfo *raReqInfo; + U16 raIndex; +#ifdef LTE_TDD + U8 fid; + U8 tid; +#endif + + TRC2(rgSCHRamProcRaReq) + + + /* SR_RACH_STATS : RACH REQ */ + rgNumPrachRecvd += raReqInd->numRaReqInfo; + + /* ccpu00132523- Moved out this from for loop as updating of raIndex is + * relates to only raRnti and all preambles having same raRnti*/ +#ifdef LTE_TDD + /* UL subframes do not occupy all the subframes in a radio frame. + * So RA Rnti index to be calculated based on actual UL subframe index. */ + /* Get the actual subframe number */ + tid = (raRnti-1)%RGSCH_NUM_SUB_FRAMES; + /* Get the frequency index in the subframe */ + fid = ((raRnti-1) / RGSCH_NUM_SUB_FRAMES)* RGSCH_NUM_SUB_FRAMES; + /* Get the index of RA RNTI in the array */ + raIndex = ((timingInfo.sfn % cell->raInfo.maxRaSize) \ + * RGSCH_MAX_RA_RNTI_PER_SUBFRM * RGSCH_NUM_SUB_FRAMES) + \ + tid + fid; + /* Fixes for RACH handling in TDD: Removed deletion of queued RaReq */ +#else + /* ccpu00132523- Placing the raReq into array based on RA SFN */ + raIndex = (timingInfo.sfn & 1) * RGSCH_MAX_RA_RNTI + raRnti-1; +#endif + + /* allocate new raReqInfos and enqueue them */ + if (raReqInd->raReqInfoArr[raReqCnt].rapId >= RGSCH_MAX_NUM_RA_PREAMBLE) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId, + "RARNTI:%d rgSCHTomRaReqInd(): RAM processing failed errType(%d) ", + raReqInd->raRnti); + RETVALUE(RFAILED); + } + + /* SR_RACH_STATS : DED PREAMB*/ + if (RGSCH_IS_DEDPRM(cell, raReqInd->raReqInfoArr[raReqCnt].rapId)) + { + rgNumDedPream++; + } + + +#ifdef LTE_L2_MEAS + if (raReqInd->raReqInfoArr[raReqCnt].rapId < cell->rachCfg.sizeRaPreambleGrpA) + { + cell->raPrmbs.preamGrpA++; + } + else if (RGSCH_IS_DEDPRM(cell, raReqInd->raReqInfoArr[raReqCnt].rapId)) + { + cell->raPrmbs.dedPream++; + } + else + { + cell->raPrmbs.preamGrpB++; + } +#endif + + if((rgSCHUtlAllocSBuf(cell->instIdx, (Data **)(&raReqInfo), + sizeof(RgSchRaReqInfo))) == RFAILED) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,"rgSCHRamProcRaReq(): Allocation" + " of RaReq failed RARNTI:%d",raRnti); + err->errCause = RGSCHERR_RAM_MEM_EXHAUST; + RETVALUE(RFAILED); + } + + /* Insert the given raReqInfo */ + /* RACHO */ + raReqInfo->timingInfo = timingInfo; + raReqInfo->raReq = raReqInd->raReqInfoArr[raReqCnt]; + raReqInfo->raReqLstEnt.next = NULLP; + raReqInfo->raReqLstEnt.prev = NULLP; + raReqInfo->raReqLstEnt.node = (PTR)raReqInfo; + /* ccpu00133504 */ + raReqInfo->ue = ue; + +#ifndef LTE_TDD + RGSCH_ARRAY_BOUND_CHECK(cell->instIdx, cell->raInfo.raReqLst, raIndex); +#endif + /* RACHO: If dedicated preamble, then give preference by appending at front */ + if (RGSCH_IS_DEDPRM(cell, raReqInd->raReqInfoArr[raReqCnt].rapId)) + { + cmLListFirst(&cell->raInfo.raReqLst[raIndex]); + cmLListInsCrnt(&cell->raInfo.raReqLst[raIndex], &raReqInfo->raReqLstEnt); + } + else + { + cmLListAdd2Tail(&cell->raInfo.raReqLst[raIndex], &raReqInfo->raReqLstEnt); + } + + RETVALUE(ROK); +} /* rgSCHRamProcRaReq */ + +/** + * @brief Handler for Random Access control block creation + * + * @details + * + * Function : rgSCHRamCreateRaCb + * Creates a raCb and gives the same to scheduler for its updation + * + * + * @param[in] RgSchCellCb *cell + * @param[in, out] RgSchRaCb **raCb + * @param[out] RgSchErrInfo *err + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 rgSCHRamCreateRaCb +( +RgSchCellCb *cell, +RgSchRaCb **raCb, +RgSchErrInfo *err +) +#else +PUBLIC S16 rgSCHRamCreateRaCb(cell, raCb, err) +RgSchCellCb *cell; +RgSchRaCb **raCb; +RgSchErrInfo *err; +#endif +{ + RgSchRntiLnk *rntiLnk; + Inst inst = cell->instIdx; + + TRC2(rgSCHRamCreateRaCb) + + if((rgSCHUtlAllocSBuf(inst, (Data **)(raCb), + sizeof(RgSchRaCb))) == RFAILED) + { + RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,"rgSCHRamCreateRaCb(): Allocation of " + "RaCb failed"); + err->errCause = RGSCHERR_RAM_MEM_EXHAUST; + RETVALUE(RFAILED); + } + + rntiLnk = rgSCHDbmGetRnti(cell); + if(rntiLnk != NULLP) + { + (*raCb)->rntiLnk = rntiLnk; + (*raCb)->tmpCrnti = rntiLnk->rnti; + } + else + { + + /* SR_RACH_STATS: RNTI POOL Exhaution */ + rgNumRarFailDuetoRntiExhaustion++; + + /* No rnti available! */ + RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,"rgSCHRamCreateRaCb(): Allocation of " + "temporary RNTI failed at MAC(CRNTI exhausted)"); + /* ccpu00117052 - MOD - Passing double pointer + for proper NULLP assignment*/ + rgSCHUtlFreeSBuf(inst, (Data **)(raCb), sizeof(RgSchRaCb)); + err->errCause = RGSCHERR_RAM_RNTI_EXHAUST; + RETVALUE(RFAILED); + } + + /* Allocate and initialize the DL HARQ portion of the RACB */ + (*raCb)->dlHqE = rgSCHDhmHqEntInit(cell); + if ((*raCb)->dlHqE == NULLP) + { + /* No memory available! */ + RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,"rgSCHRamCreateRaCb(): Creation of" + " DL HARQ failed"); + /* ccpu00117052 - MOD - Passing double pointer + for proper NULLP assignment*/ + rgSCHUtlFreeSBuf(inst, (Data **)(raCb), sizeof(RgSchRaCb)); + err->errCause = RGSCHERR_RAM_MEM_EXHAUST; + RETVALUE(RFAILED); + } +#ifdef EMTC_ENABLE + (*raCb)->isEmtcRaCb = FALSE; + rgSCHEmtcHqPAlloc(cell, (*raCb)->dlHqE); +#endif + (*raCb)->dlHqE->raCb = (*raCb); + /* Initialize RaCb's contents */ + (*raCb)->timingInfo = cell->crntTime; + (*raCb)->raState = RGSCH_RA_MSG3_PENDING; + (*raCb)->toDel = FALSE; + (*raCb)->phr.pres = FALSE; + + /* Insert the created raCb into raCb list of cell */ + (*raCb)->raCbLnk.node = (PTR)(*raCb); + cmLListAdd2Tail(&cell->raInfo.raCbLst, &(*raCb)->raCbLnk); + + RETVALUE(ROK); +} /* rgSCHRamCreateRaCb */ + +/** + * @brief Handler for Ue Configuration Request + * + * @details + * + * Function : rgSCHRamRgrUeCfg + * + * This function handles the UE config received based on the state of the + * raCb. + * -# If raCb is in RGSCH_RA_MSG4_PENDING state, it shall update the harq + * information to UeCb and update the references. + * -# If raCb is in RGSCH_RA_MSG4_DONE, then it shall free the raCb + * + * + * @param[in] RgSchCellCb *cell + * @param[in,out] RgSchUeCb *ue + * @param[in,out] RgSchRaCb *raCb + * @param[out] RgSchErrInfo *err + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 rgSCHRamRgrUeCfg +( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgSchRaCb *raCb, +RgSchErrInfo *err +) +#else +PUBLIC S16 rgSCHRamRgrUeCfg(cell, ue, raCb, err) +RgSchCellCb *cell; +RgSchUeCb *ue; +RgSchRaCb *raCb; +RgSchErrInfo *err; +#endif +{ + /* Releasing HARQ processes of old UE when ue + * reconfig with new crnti */ + /* U32 cnt; */ + RgSchDlHqEnt **hqEnt = &(RG_SCH_CMN_GET_UE_HQE(ue, cell)); + RgSchCmnUlUe *ueUl = RG_SCH_CMN_GET_UL_UE(ue, cell); + TRC2(rgSCHRamRgrUeCfg) + + + /* Fix : set UE inactive in DL until UE is reinitialization completed */ + ue->dl.dlInactvMask |= RG_HQENT_INACTIVE; + ue->ul.ulInactvMask |= RG_HQENT_INACTIVE; + + if(raCb->raState == RGSCH_RA_MSG4_PENDING) + { + raCb->ue = ue; + ue->rntiLnk = raCb->rntiLnk; + /* Update UL Harq process information */ + /*ccpu00128820 - MOD - Msg3 alloc double delete issue*/ + ueUl->hqEnt.hqProcCb[raCb->msg3HqProcId].ndi = raCb->msg3HqProc.ndi; + } + else if(raCb->raState == RGSCH_RA_MSG4_DONE) + { + ue->rntiLnk = raCb->rntiLnk; + /* Update UL Harq process information */ + /*ccpu00128820 - MOD - Msg3 alloc double delete issue*/ + ueUl->hqEnt.hqProcCb[raCb->msg3HqProcId].ndi = raCb->msg3HqProc.ndi; + /* Fix : syed Assign hqEnt to UE only if msg4 is done */ + rgSCHDhmAssgnUeHqEntFrmRaCb(ue, raCb); + } + else + { + err->errCause = RGSCHERR_RAM_NO_MSG3_RCVD; + *hqEnt = NULLP; + raCb->dlHqE->ue = NULLP; + RETVALUE(RFAILED); + } + + RETVALUE(ROK); +} /* rgSCHRamRgrUeCfg */ + + +/** + * @brief Handler for C-RNTI based contention resolution + * + * @details + * + * Function : rgSCHRamContResCrnti + * + * This function shall be invoked once Msg3 indicates C-RNTI based + * contention resolution.This shall indicate the scheduler regarding + * C-RNTI based uplink grant. + * + * + * @param[in,out] RgSchCellCb *cell + * @param[in,out] RgSchUeCb *ue + * @param[in,out] RgSchRaCb *raCb + * @return S16 + * -# ROK + **/ +#ifdef ANSI +PRIVATE S16 rgSCHRamContResCrnti +( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgSchRaCb *raCb, +RgSchErrInfo *err +) +#else +PRIVATE S16 rgSCHRamContResCrnti(cell, ue, raCb, err) +RgSchCellCb *cell; +RgSchUeCb *ue; +RgSchRaCb *raCb; +RgSchErrInfo *err; +#endif +{ + TfuUlCqiRpt ulCqiRpt; + RgSchCmnCell *cellSch= (RgSchCmnCell *)(cell->sc.sch); + TRC2(rgSCHRamContResCrnti) + + + /* Fix: syed It is incorrect to copy over msg3HqProc to ueCb's + * UL harq proc. In case of Crnti based RACH, ueCb has valid context which + * cannot be over written. It was leading to a crash. */ + + rgSCHUtlRecMsg3Alloc(cell, ue, raCb); + + /* Fix for ccpu00123908: Reset the UL CQI to the cell default value here */ + ulCqiRpt.isTxPort0 = TRUE; + ulCqiRpt.numSubband = 0; + /* Fix : syed HO UE does not have a valid ue->rntiLnk */ + ulCqiRpt.rnti = ue->ueId; + /* rg002.301:[ccpu00124018]-MOD- Avoiding hard coding of CQI and retriving from cell config*/ + ulCqiRpt.wideCqi = cellSch->ul.dfltUlCqi; + rgSCHUtlUlCqiInd(cell, ue, &ulCqiRpt); + + + /* Invoke scheduler to indicate UL grant req for contention resolution */ + rgSCHUtlContResUlGrant(cell, ue, err); + + if (raCb->phr.pres == TRUE) + { + rgSCHUtlUpdPhr(cell, ue, raCb->phr.val, err); + } + /* No need of raCb any more */ + rgSCHRamDelRaCb(cell, raCb, TRUE); + + RETVALUE(ROK); +} /* rgSCHRamContResCrnti */ + + +/** + * @brief Handler for CCCH SDU based contention resolution + * + * @details + * + * Function : rgSCHRamContResCcchsdu + * + * This function shall be invoked once Msg3 indicates contention resolution + * based on CCCH sdu. This shall update the raCb state to + * RGSCH_RA_MSG4_PENDING. + * + * + * @param[in,out] RgSchRaCb *raCb + * @return S16 + * -# ROK + **/ +#ifdef ANSI +PRIVATE S16 rgSCHRamContResCcchsdu +( +RgSchCellCb *cell, +RgSchRaCb *raCb +) +#else +PRIVATE S16 rgSCHRamContResCcchsdu(cell, raCb) +RgSchCellCb *cell; +RgSchRaCb *raCb; +#endif +{ +#ifdef RGR_V1 + CmLteTimingInfo expTime = {0}; + RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell); +#endif + TRC2(rgSCHRamContResCcchsdu) + if(raCb->raState != RGSCH_RA_MSG3_PENDING) + { + RLOG_ARG2(L_DEBUG,DBG_CELLID,cell->cellId, + "RNTI:%d RaCb in wrong State %d Drop Msg 3", + raCb->rntiLnk->rnti, + raCb->raState); + RETVALUE(ROK); + } + + raCb->raState = RGSCH_RA_MSG4_PENDING; + +#ifdef RGR_V1 + if(cell->rachCfg.contResTmr - cellSch->dl.msg4TxDelay > 0) + { + /* Set the contension resolution guard timer = + Cont Res Timer - Max msg4 Tx Delay */ + RG_SCH_ADD_TO_CRNT_TIME(cell->crntTime, expTime, + (cell->rachCfg.contResTmr - cellSch->dl.msg4TxDelay)); + } + else + { + /* Schedule the CRI CE in the next Sf itself */ + RG_SCH_ADD_TO_CRNT_TIME(cell->crntTime, expTime, 1); + } + raCb->expiryTime = expTime; + raCb->contResTmrLnk.node = (PTR)(raCb); + cmLListAdd2Tail(&(cell->contResGrdTmrLst), &(raCb->contResTmrLnk)); +#endif + RETVALUE(ROK); +} /* rgSCHRamContResCcchsdu */ + + +/** + * @brief Handler for Msg3 + * + * @details + * + * Function : rgSCHRamProcMsg3 + * + * This function processes the received Msg3 and identifies the type of + * contention resolution and act accordingly. + * + * + * @param[in,out] RgSchCellCb *cell + * @param[in,out] RgSchUeCb *ue + * @param[in,out] RgSchRaCb *raCb + * @return S16 + * -# ROK + **/ +#ifdef ANSI +PUBLIC S16 rgSCHRamProcMsg3 +( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgSchRaCb *raCb, +RgInfUeDatInd *pdu, +RgSchErrInfo *err +) +#else +PUBLIC S16 rgSCHRamProcMsg3(cell, ue, raCb, pdu, err) +RgSchCellCb *cell; +RgSchUeCb *ue; +RgSchRaCb *raCb; +RgInfUeDatInd *pdu; +RgSchErrInfo *err; +#endif +{ + TRC2(rgSCHRamProcMsg3) + + + /* Update raCb with PHR if received along with Msg3 */ + if (pdu->ceInfo.bitMask & RGSCH_PHR_CE_PRSNT) + { + /* PHR present */ + raCb->phr.pres = TRUE; + raCb->phr.val = pdu->ceInfo.ces.phr; + } + if (ue) + { + rgSCHRamContResCrnti(cell, ue, raCb, err); + } + else + { +#ifdef EMTC_ENABLE + if(TRUE == raCb->isEmtcRaCb) + { + /* starting the emtc Contention resolution timer */ + rgSCHRamEmtcContResCcchsdu(cell,raCb); + } + else +#endif + { + rgSCHRamContResCcchsdu(cell, raCb); + } + } + + RETVALUE(ROK); +} /* rgSCHRamProcMsg3 */ + + +/** + * @brief Handler for Updating Bo received in StaRsp + * + * @details + * + * Function : rgSCHRamUpdtBo + * + * This function shall be invoked by RAM once it receives staRsp on CCCH + * + * @param[in] RgSchCellCb *cell + * @param[in,out] RgSchRaCb *raCb + * @param[in] RgRguCmnStaRsp *staRsp + * @return S16 + * -# ROK + **/ +#ifdef ANSI +PUBLIC S16 rgSCHRamUpdtBo +( +RgSchCellCb *cell, +RgSchRaCb *raCb, +RgInfCmnBoRpt *staRsp +) +#else +PUBLIC S16 rgSCHRamUpdtBo(cell, raCb, staRsp) +RgSchCellCb *cell; +RgSchRaCb *raCb; +RgInfCmnBoRpt *staRsp; +#endif +{ + TRC2(rgSCHRamUpdtBo) + + /* Update Bo in RaCb */ + raCb->dlCcchInfo.bo = (U32)(staRsp->bo); + /* SR_RACH_STATS : MSG4 WITH CCCH SDU */ + rgNumMsg4WithCCCHSdu++; + + /* add this to the "tobeSchdLst" */ + /* MSG4 Fix Start */ + rgSCHRamAddToRaInfoSchdLst(cell, raCb); + /* MSG4 Fix End */ + + RETVALUE(ROK); +} /* rgSCHRamUpdtBo */ + +/** + * @brief Handler for Msg3 Feedback indication + * + * @details + * + * Function : rgSCHRamMsg3DatInd + * + * This function shall be invoked by TOM once the transmission of Msg4 is + * ACKed/NACKed. + * This shall invoke UHM to set ACK for Msg3 reception. + * + * @param[in,out] RgSchRaCb *raCb + * @return S16 + * -# ROK + **/ +#ifdef ANSI +PUBLIC S16 rgSCHRamMsg3DatInd +( +RgSchRaCb *raCb +) +#else +PUBLIC S16 rgSCHRamMsg3DatInd(raCb) +RgSchRaCb *raCb; +#endif +{ + TRC2(rgSCHRamMsg3DatInd) + + /* SR_RACH_STATS : MSG3 ACK*/ + rgNumMsg3CrcPassed++; + /*ccpu00128820 - MOD - Msg3 alloc double delete issue*/ + rgSCHUhmProcMsg3DatInd(&(raCb->msg3HqProc)); + + RETVALUE(ROK); +} /* rgSCHRamMsg3DatInd */ + +/** + * @brief Handler for Msg3 Feedback indication + * + * @details + * + * Function : rgSCHRamMsg3FailureInd + * + * This function shall be invoked by TOM once the transmission of Msg4 is + * ACKed/NACKed. + * This shall invoke UHM to set ACK for Msg3 reception. + * + * @param[in,out] RgSchRaCb *raCb + * @return S16 + * -# ROK + **/ +#ifdef ANSI +PUBLIC S16 rgSCHRamMsg3FailureInd +( +RgSchRaCb *raCb +) +#else +PUBLIC S16 rgSCHRamMsg3FailureInd(raCb) +RgSchRaCb *raCb; +#endif +{ + TRC2(rgSCHRamMsg3FailureInd) + + /*ccpu00128820 - MOD - Msg3 alloc double delete issue*/ + rgSCHUhmProcMsg3Failure(&(raCb->msg3HqProc)); + + RETVALUE(ROK); +} /* rgSCHRamMsg3FailureInd */ + +/** + * @brief Handler for Msg4 Feedback indication + * + * @details + * + * Function : rgSCHRamMsg4FdbkInd + * + * This function shall be invoked by TOM once the transmission of Msg4 is + * ACKed/NACKed. + * This shall invoke UHM to set ACK for Msg3 reception. + * + * @param[in,out] RgSchRaCb *raCb + * @return S16 + * -# ROK + **/ +#ifdef ANSI +PUBLIC S16 rgSCHRamMsg4FdbkInd +( +RgSchRaCb *raCb +) +#else +PUBLIC S16 rgSCHRamMsg4FdbkInd(raCb) +RgSchRaCb *raCb; +#endif +{ + TRC2(rgSCHRamMsg4FdbkInd) + + RETVALUE(ROK); +} /* rgSCHRamMsg4FdbkInd */ + + +/** + * @brief Handler for Msg4 state updation + * + * @details + * + * Function : rgSCHRamMsg4Done + * + * This function shall be invoked by DHM once the transmission of Msg4 is + * done. This shall delete the raCb if there is a valid Ue or if this is to + * be deleted. If not this shall update the state of the raCb. + * + * + * @param[in] RgSchCellCb *cell + * @param[in,out] RgSchRaCb *raCb + * @return S16 + * -# ROK + **/ +#ifdef ANSI +PUBLIC S16 rgSCHRamMsg4Done +( +RgSchCellCb *cell, +RgSchRaCb *raCb +) +#else +PUBLIC S16 rgSCHRamMsg4Done(cell, raCb) +RgSchCellCb *cell; +RgSchRaCb *raCb; +#endif +{ + TRC2(rgSCHRamMsg4Done) + + RLOG_ARG1(L_DEBUG,DBG_CELLID,cell->cellId, + "rgSCHRamMsg4Done(): tmpCRNTI = %u", + raCb->tmpCrnti); + + if(raCb->ue != NULLP) + { + /* Fix : syed Let this funtion decide on releasing + * hqP than the caller of this function otherwise sometimes it + * might lead to incorrec NDI setting. */ + rgSCHDhmRlsHqpTb(raCb->dlHqE->msg4Proc, 0, TRUE); + /* Fix : syed Assign hqEnt to UE only if msg4 is done */ + rgSCHDhmAssgnUeHqEntFrmRaCb(raCb->ue, raCb); +#ifdef EMTC_ENABLE + if(TRUE == raCb->isEmtcRaCb) + { + rgSCHEmtcUtlUpdCmnNb(raCb); + } +#endif + /* MS_FIX :Proceed to CCCH scheduling irrespective of + * MSG4 result */ + if (raCb->ue->dlCcchInfo.bo) + { +#ifdef EMTC_ENABLE + /*if CR-ID Ack has been received ,Add emtc Ue to cchSduUeLst*/ + if(TRUE == raCb->isEmtcRaCb) + { + rgSCHUtlAddUeToEmtcCcchSduLst(cell, raCb->ue); + } + else +#endif + { + rgSCHUtlAddUeToCcchSduLst(cell, raCb->ue); + } + } + /* Rnti shall not be released as Ue exists with this rnti */ + rgSCHRamDelRaCb(cell, raCb, FALSE); + } + else if(raCb->toDel == TRUE) + { +#ifdef XEON_SPECIFIC_CHANGES + CM_LOG_DEBUG(CM_LOG_ID_SCH, "Deleting RacB:%d\n", raCb->tmpCrnti); +#endif + /* Delete RACB and release RNTI */ + rgSCHRamDelRaCb(cell, raCb, TRUE); + } + else + { +#ifdef XEON_SPECIFIC_CHANGES + CM_LOG_DEBUG(CM_LOG_ID_SCH, "Releasing Harq of RacB:%d\n", raCb->tmpCrnti); +#endif + raCb->raState = RGSCH_RA_MSG4_DONE; + /* Release harq process as final feedback is received for Msg4. In other + * cases, delRaCb will take care of releasing the harq process */ + printf("=======Harq process released \n"); + RLOG_ARG0(L_DEBUG,DBG_CELLID,cell->cellId, + "Harq process released "); + rgSCHDhmRlsHqpTb(raCb->dlHqE->msg4Proc, 0, TRUE); + } + + RETVALUE(ROK); +} /* rgSCHRamMsg4Done */ + + +/** + * @brief Handler for deletion + * + * @details + * + * Function : rgSCHRamDelRaCb + * + * This function shall be invoked whenever a raCb needs to be deleted. + * Invoked by both RAM and downlink scheduler + * + * @param[in] RgSchCellCb *cell + * @param[in,out] RgSchRaCb *raCb + * @param[in] Bool rlsRnti + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 rgSCHRamDelRaCb +( +RgSchCellCb *cell, +RgSchRaCb *raCb, +Bool rlsRnti +) +#else +PUBLIC S16 rgSCHRamDelRaCb(cell, raCb, rlsRnti) +RgSchCellCb *cell; +RgSchRaCb *raCb; +Bool rlsRnti; +#endif +{ + Inst inst = cell->instIdx; + Bool isEmtc = FALSE; + TRC2(rgSCHRamDelRaCb) + + /* Delete from all the lists it is enqueued */ + cmLListDelFrm(&(cell->raInfo.raCbLst),&(raCb->raCbLnk)); +#ifdef EMTC_ENABLE + /*ue Type is EMTC, then Delete the toBeSchedLst and stop the Guard Timer */ + if(TRUE == raCb->isEmtcRaCb) + { + rgSCHRamEmtcDelRaCb(cell,raCb); + isEmtc = TRUE; + } + else +#endif + { + if (raCb->schdLnk.node == (PTR)raCb) + { + rgSCHRamRmvFrmRaInfoSchdLst(cell, raCb); + } +#ifdef RGR_V1 + else if(raCb->contResTmrLnk.node != NULLP) + { + cmLListDelFrm(&cell->contResGrdTmrLst, &(raCb->contResTmrLnk)); + raCb->contResTmrLnk.node = NULLP; + } +#endif + } + + if(rlsRnti == TRUE) + { + rgSCHUtlRlsRnti(cell, raCb->rntiLnk, FALSE, 0); + } + + /* Check if msg4 Hq Proc has been released. If not, release it */ + if (raCb->dlHqE ) + { + if (raCb->dlHqE->msg4Proc != NULLP) + { + /* Fix: syed Remove the msg4Proc if it waiting in sf->tbs list for + * harq feedback */ + if ((raCb->dlHqE->msg4Proc->subFrm != NULLP) && + (raCb->dlHqE->msg4Proc->hqPSfLnk.node != NULLP)) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,"TMP CRNTI:%d RACH FAILURE!! " + "msg4proc removed from SF", raCb->tmpCrnti); + rgSCHUtlDlHqPTbRmvFrmTx(raCb->dlHqE->msg4Proc->subFrm, + raCb->dlHqE->msg4Proc, 0, FALSE); + } + /* Fix: syed Remove the msg4Proc from cell + * msg4Retx Queue. I have used CMN scheduler function + * directly. Please define a new API and call this + * function through that. */ + rgSCHCmnDlMsg4ProcRmvFrmRetx(cell, raCb->dlHqE->msg4Proc); + rgSCHDhmRlsHqpTb(raCb->dlHqE->msg4Proc, 0, TRUE); + } + + /* Mark the raCb pointer in dlHqE to NULLP */ + raCb->dlHqE->raCb = NULLP; + + rgSCHDhmDelHqEnt(cell, &raCb->dlHqE); + } + /* Fix: syed Adaptive Msg3 Retx crash. Remove the harqProc + * from adaptive retx List. Free the alloc if it exists. */ + if (raCb->msg3HqProc.reTxLnk.node) + { + //TODO_SID: Need to take care of retxLst + //cmLListDelFrm(raCb->msg3HqProc.reTxAlloc.reTxLst, &raCb->msg3HqProc.reTxLnk); + raCb->msg3HqProc.reTxLnk.node = (PTR)NULLP; + } + + if (raCb->msg3HqProc.alloc) + { + /* Fix: syed During GPR, please write an API instead of direct + * call to cmn scheduler function */ + RgSchCmnUlCell *cellUl = RG_SCH_CMN_GET_UL_CELL(cell); + /*ccpu00130356 - MOD- To avoid segmentation problem because of double + free due to recursive calling of rgSCHRamDelRaCb*/ + rgSCHRamUlFreeAllocation(&cellUl->ulSfArr[raCb->msg3HqProc.ulSfIdx], + raCb->msg3HqProc.alloc, + cell,isEmtc); + } + +#ifdef EMTC_ENABLE + if(TRUE == raCb->isEmtcRaCb) + { + rgSCHEmtcRaInfoFree(cell, raCb); + } +#endif + rgSCHUtlFreeSBuf(inst, (Data **)&raCb, sizeof(RgSchRaCb)); + + RETVALUE(ROK); +} /* rgSCHRamDelRaCb */ + + +/** + * @brief TTI Handler for RAM module + * + * @details + * + * Function : rgSCHRamTtiHndlr + * + * This function shall be invoked upon TtiInd by TOM + * This shall + * - remove RaReqs added to the queue for a raRnti for which PHY may + * give the requests in the next subframe + * - remove raCbs which are not yet processed once the + * counter for raCb processing expires. + * + * + * @param[in,out] RgSchCellCb *cell + * @return S16 + * -# ROK + **/ +#ifdef ANSI +PUBLIC S16 rgSCHRamTtiHndlr +( +RgSchCellCb *cell +) +#else +PUBLIC S16 rgSCHRamTtiHndlr(cell) +RgSchCellCb *cell; +#endif +{ + RgSchRaCb *raCb; + U16 raSfn; + U16 crntSfn; + U16 dist; /* Number of frames between raCb's creation and crnt + frame */ + U8 idx; + U32 maxCnt; +#ifndef LTE_TDD + U8 winGap; + U8 raIdx; + RgSchRaReqInfo *raReqInfo; +#else + CmLteTimingInfo frm; + U8 raIdx; +#endif + + TRC2(rgSCHRamTtiHndlr) + + crntSfn = cell->crntTime.sfn; + +#ifdef RGR_V1 + /*Check if Contention resolution guard timer expiring in the TTI*/ + rgSCHChkContResGrdTmrExp(cell); + /*Check if Contention resolution timer expiring in the TTI*/ + rgSCHChkContResTmrExp(cell); +#ifdef EMTC_ENABLE + /*Check if EMTC Contention resolution guard timer expiring in the TTI*/ + rgSCHChkEmtcContResGrdTmrExp(cell); + /*Check if EMTC Contention resolution timer expiring in the TTI*/ + rgSCHChkEmtcContResTmrExp(cell); +#endif +#endif +#ifndef LTE_TDD + + /* Delete the RA requests for which RAR window expired in this subframe + * And were not considered for RAR scheduling*/ + winGap = (rgRaPrmblToRaFrmTbl[cell->rachCfg.preambleFormat]-1)+ + (cell->rachCfg.raWinSize -1 ) + RGSCH_RARSP_WAIT_PERIOD; + + raIdx = (((crntSfn & 1) * RGSCH_MAX_RA_RNTI+ cell->crntTime.subframe + + RG_SCH_CMN_DL_DELTA - winGap)+ RGSCH_RAREQ_ARRAY_SIZE ) + % RGSCH_RAREQ_ARRAY_SIZE; + + /* Flush the already existing raReqs against the given raRnti */ + + maxCnt = cell->raInfo.raReqLst[raIdx].count; + for (idx = 0; idx < maxCnt; idx++) + { + raReqInfo = (RgSchRaReqInfo *)(cell->raInfo.raReqLst[raIdx].first->node); + cmLListDelFrm(&(cell->raInfo.raReqLst[raIdx]),&(raReqInfo->raReqLstEnt)); + /* ccpu00117052 - MOD - Passing double pointer + for proper NULLP assignment*/ + rgSCHUtlFreeSBuf(cell->instIdx, (Data **)&raReqInfo, + sizeof(RgSchRaReqInfo)); + } +#else + /* Fixes for RACH handling: Added deletion of queued RaReq */ + frm = cell->crntTime; + RGSCH_INCR_SUB_FRAME(frm, RG_SCH_CMN_DL_DELTA); + if(rgSchTddUlDlSubfrmTbl[cell->ulDlCfgIdx][frm.subframe] != + RG_SCH_TDD_UL_SUBFRAME) + { + raIdx = rgSchTddNumDlSubfrmTbl[cell->ulDlCfgIdx][frm.subframe]-1; + rgSCHRamDelRaReq(cell, cell->crntTime, raIdx); + } +#endif + + /* Remove the RACBs which are timed out */ + /* ccpu00132536:MOD- racb timeout will be verified in each SFN such that + * the RACB whose processing is not completed in RG_MAX_RA_PRC_FRM + * will be deleted*/ + if (cell->crntTime.subframe == 0) + { + maxCnt = cell->raInfo.raCbLst.count; + for (idx = 0; idx < maxCnt; idx++) + { + raCb = (RgSchRaCb *)(cell->raInfo.raCbLst.first->node); + /* Calculate number of frames between raCb's creation and crnt frame */ + raSfn = raCb->timingInfo.sfn; + dist = (crntSfn + (RGSCH_MAX_SFN - raSfn)) % RGSCH_MAX_SFN; + /* Delete RaCbs whose processing is not complete within + * "cell->t300TmrVal" frames */ + /* raCb not to be deleted if msg4 is not completed */ + /* raCb should not be deleted(RNTI should not be released) if UE is present + * as it means the application still holds the RNTI. raCb will get deleted + * as part of UE deletion. raCb will anyway get deleted without releasing RNTI on success/failure of MSG4*/ + + if (dist >= cell->t300TmrVal) + { + if ((raCb->dlHqE->msg4Proc == NULLP) && (raCb->dlHqE->ue == NULLP)) + { + rgSCHRamDelRaCb(cell, raCb, TRUE); + } + } + else + { + break; + } + } + } + + RETVALUE(ROK); +} /* rgSCHRamTtiHndlr */ + + +/** + * @brief Function for handling cell delete + * + * @details + * + * Function : rgSCHRamFreeCell + * + * This function shall be invoked whenever a cell needs to be deleted. + * This shall remove raCbs and raReqs stored in cell. + * + * + * @param[in,out] RgSchCellCb *cell + * @return S16 + * -# ROK + **/ +#ifdef ANSI +PUBLIC S16 rgSCHRamFreeCell +( +RgSchCellCb *cell +) +#else +PUBLIC S16 rgSCHRamFreeCell(cell) +RgSchCellCb *cell; +#endif +{ + RgSchRaReqInfo *raReqInfo; + RgSchRaCb *raCb; + U8 idx; + U8 raCbCnt; + Inst inst = cell->instIdx; + U8 lstSz; +#ifdef LTE_TDD + U8 maxUlSubframes; + U8 maxDlSubframes; +#endif + + + TRC2(rgSCHRamFreeCell) + + +#ifdef LTE_TDD + maxUlSubframes = + rgSchTddNumUlSubfrmTbl[cell->ulDlCfgIdx][RGSCH_NUM_SUB_FRAMES-1]; + maxDlSubframes = + rgSchTddNumDlSubfrmTbl[cell->ulDlCfgIdx][RGSCH_NUM_SUB_FRAMES-1]; + lstSz = cell->raInfo.maxRaSize * RGSCH_MAX_RA_RNTI_PER_SUBFRM * \ + maxUlSubframes; +#else + /* ccpu00133557- MEM LEAK FIX- Need to free all the nodes in RA Array list */ + lstSz = RGSCH_RAREQ_ARRAY_SIZE; +#endif + + for (idx = 0; idx < lstSz; idx++) + { + /* Delete and free raReqs stored */ + /* ccpu00133557- MEM LEAK FIX- Need to be freed till the count is non-zero */ + while(cell->raInfo.raReqLst[idx].count) + { + raReqInfo = (RgSchRaReqInfo *)(cell->raInfo.raReqLst[idx].first->node); + cmLListDelFrm(&(cell->raInfo.raReqLst[idx]),&(raReqInfo->raReqLstEnt)); + /* ccpu00117052 - MOD - Passing double pointer + for proper NULLP assignment*/ + rgSCHUtlFreeSBuf(inst, (Data **)&raReqInfo, sizeof(RgSchRaReqInfo)); + } + } + +#ifdef LTE_TDD + /* Delete the RACH response list*/ + /* ccpu00117052 - MOD - Passing double pointer + for proper NULLP assignment*/ + rgSCHUtlFreeSBuf(inst, + (Data **)(&(cell->rachRspLst)), sizeof(RgSchTddRachRspLst) * \ + maxDlSubframes); +#endif + + /* Delete raCbs in the "to be scheduled" list */ + /* ccpu00133557- MEM LEAK FIX- Need to be freed till the count is non-zero */ + while(cell->raInfo.toBeSchdLst.count) + { + raCb = (RgSchRaCb *)(cell->raInfo.toBeSchdLst.first->node); + /* MSG4 Fix Start */ + + rgSCHRamRmvFrmRaInfoSchdLst(cell, raCb); + /* MSG4 Fix End */ + } +#ifdef EMTC_ENABLE + /* Delete raCbs in the "Emtc to be scheduled" list */ + if(cell->emtcEnable) + { + rgSCHRamRmvAllFrmEmtcRaInfoSchdLst(cell); + } +#endif + + raCbCnt = cell->raInfo.raCbLst.count; + + /* Delete and free raCbs stored */ + for (idx = 0; idx < raCbCnt; idx++) + { + raCb = (RgSchRaCb *)(cell->raInfo.raCbLst.first->node); + rgSCHRamDelRaCb(cell, raCb, TRUE); + } + + RETVALUE(ROK); +} /* rgSCHRamFreeCell */ +#ifdef RGR_V1 +#ifdef ANSI +PRIVATE Void rgSCHRamProcContResExp +( +RgSchCellCb *cell, +RgSchRaCb *raCb +) +#else +PRIVATE Void rgSCHRamProcContResExp (cell, raCb) +RgSchCellCb *cell; +RgSchRaCb *raCb; +#endif +{ + TRC2(rgSCHRamProcContResExp); + raCb->expiryTime.sfn = RGSCH_CONTRES_EXP; + /*MSG4 Fix*/ + if (raCb->ue) + { + /* UE exists and RNTI will be released as part of UE DEL */ + rgSCHRamDelRaCb(cell, raCb, FALSE); + } + else + { + /* Calling Release RNTI, which would perform Racb deletion + * RNTI removal and RNTI release indication to MAC. */ + /* Delete RACB and release RNTI */ + rgSCHRamDelRaCb(cell, raCb, TRUE); + } + RETVOID; +} + +#ifdef ANSI +PRIVATE Void rgSCHRamProcContResGrdExp +( +RgSchCellCb *cell, +RgSchRaCb *raCb +) +#else +PRIVATE Void rgSCHRamProcContResGrdExp (cell, raCb) +RgSchCellCb *cell; +RgSchRaCb *raCb; +#endif +{ + TRC2(rgSCHRamProcContResGrdExp) + + +/*Guard timer has expired, schedule only the contention REsolution CE with + * zero bo*/ + raCb->dlCcchInfo.bo = 0; + /* SR_RACH_STATS : MSG4 WO CCCH SDU */ + rgNumMsg4WoCCCHSdu++; + + /* add this to the "tobeSchdLst" */ + raCb->schdLnk.node = (PTR)(raCb); + + cmLListDelFrm(&cell->contResGrdTmrLst, &(raCb->contResTmrLnk)); + raCb->contResTmrLnk.node = NULLP; + + /* MSG4 Fix Start */ + RLOG_ARG1(L_DEBUG,DBG_CELLID,cell->cellId, + "Con Res Grd Tmr exp RNTI:%d", + raCb->rntiLnk->rnti); + rgSCHRamAddToRaInfoSchdLst(cell, raCb); + /* MSG4 Fix End */ + RETVOID; + +} +/** + * @brief Check the Contention Resolution Guard Timer Expiry. + * + * @details + * + * Function: rgSCHChkContResTmrExp + * + * + * Invoked by: Scheduler + * @param[in] RgSchCellCb *cell + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PRIVATE Void rgSCHChkContResTmrExp +( +RgSchCellCb *cell +) +#else +PRIVATE Void rgSCHChkContResTmrExp(cell) +RgSchCellCb *cell; +#endif +{ + CmLList *chkLnk = NULLP; + RgSchRaCb *raCb = NULLP; + + TRC2(rgSCHChkContResTmrExp) + + chkLnk = cmLListFirst(&(cell->contResTmrLst)); + + for (; chkLnk; chkLnk = chkLnk->next) + { + raCb = (RgSchRaCb *)(chkLnk->node); + + if(RGSCH_TIMEINFO_SAME(raCb->expiryTime, cell->crntTime)) + { + /*If timer expired, call the handler function*/ + rgSCHRamProcContResExp(cell, raCb); + } + /*Fix: Need to traverse till end of list as the entries may not be in ascending order*/ + /* else + { + break; + }*/ + } +} +/** + * @brief Check the Contention Resolution Guard Timer Expiry. + * + * @details + * + * Function: rgSCHChkContResGrdTmrExp + * + * + * Invoked by: Scheduler + * @param[in] RgSchCellCb *cell + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PRIVATE Void rgSCHChkContResGrdTmrExp +( +RgSchCellCb *cell +) +#else +PRIVATE Void rgSCHChkContResGrdTmrExp(cell) +RgSchCellCb *cell; +#endif +{ + CmLList *chkLnk = NULLP; + RgSchRaCb *raCb = NULLP; + + TRC2(rgSCHChkContResGrdTmrExp) + + chkLnk = cmLListFirst(&(cell->contResGrdTmrLst)); + + /*[ccpu00131941]-MOD-List traversal should be done using the listCp */ + for (; chkLnk; chkLnk = cmLListNext(&cell->contResGrdTmrLst)) + { + raCb = (RgSchRaCb *)(chkLnk->node); + + if(RGSCH_TIMEINFO_SAME(raCb->expiryTime, cell->crntTime)) + { + /*If timer expired, call the handler function*/ + rgSCHRamProcContResGrdExp(cell, raCb); + } + else + { + break; + } + } +} +#endif +#ifdef LTE_TDD +/** + * @brief Function for handling RACH Request deletion + * + * @details + * + * Function : rgSCHRamDelRaReq + * + * This function shall be invoked to delete the RACH Requests + * that is not scheduled within the RA window size. + * + * + * @param[in,out] RgSchCellCb *cell + * @param[in] CmLteTimingInfo timingInfo + * @param[in] U8 raIdx + * @return S16 + * -# ROK + **/ +#ifdef ANSI +PUBLIC S16 rgSCHRamDelRaReq +( +RgSchCellCb *cell, +CmLteTimingInfo timingInfo, +U8 raIdx +) +#else +PUBLIC S16 rgSCHRamDelRaReq(cell, timingInfo, raIdx) +RgSchCellCb *cell; +CmLteTimingInfo timingInfo; +U8 raIdx; +#endif +{ + U8 subfrmIdx; + RgSchTddRachRspLst *rachRsp; + U16 sfnIdx; + S16 calcSfn; + U8 subfrm; + RgSchRaReqInfo *raReqInfo; + U8 idx; + U8 i; + U8 raRntiIdx; + CmLteRnti raRnti; + + TRC2(rgSCHRamDelRaReq) + + + rachRsp = &cell->rachRspLst[raIdx]; + /* Get the SFN Index to be deleted */ + calcSfn = timingInfo.sfn - rachRsp->delInfo.sfnOffset; + if(calcSfn < 0) + { + sfnIdx = (calcSfn + RGSCH_MAX_SFN) % cell->raInfo.maxRaSize; + } + else + { + sfnIdx = calcSfn; + } + + /* Iterate through all the subframes to be delted in the SFN */ + for(subfrmIdx=0; subfrmIdx < rachRsp->delInfo.numSubfrms; subfrmIdx++) + { + subfrm = rachRsp->delInfo.subframe[subfrmIdx]; + /* Get the subframe Index to be deleted */ + /* Fixes for RACH handling in TDD: + * Corrected the computation of raRntiIdx + * */ + raRntiIdx = ((sfnIdx % cell->raInfo.maxRaSize) * \ + RGSCH_MAX_RA_RNTI_PER_SUBFRM * \ + RGSCH_NUM_SUB_FRAMES) + subfrm; + + /* Iterate through all the RNTIs in the subframe */ + for(i=0; i < RGSCH_MAX_RA_RNTI_PER_SUBFRM; i++) + { + raRnti = raRntiIdx + (i*RGSCH_NUM_SUB_FRAMES); + for (idx = 0; idx < cell->raInfo.raReqLst[raRnti].count; idx++) + { + raReqInfo = + (RgSchRaReqInfo *)(cell->raInfo.raReqLst[raRnti].first->node); + cmLListDelFrm(&(cell->raInfo.raReqLst[raRnti]), + &(raReqInfo->raReqLstEnt)); + /* ccpu00117052 - MOD - Passing double pointer + for proper NULLP assignment*/ + rgSCHUtlFreeSBuf(cell->instIdx, + (Data **)&raReqInfo, sizeof(RgSchRaReqInfo)); + } + } + } + + RETVALUE(ROK); +} +#endif + +/*MSG4 Fix Start */ +#ifdef ANSI +PUBLIC S16 rgSCHRamAddToRaInfoSchdLst +( +RgSchCellCb *cell, +RgSchRaCb *raCb +) +#else +PUBLIC S16 rgSCHRamAddToRaInfoSchdLst(cell, raCb) +RgSchCellCb *cell; +RgSchRaCb *raCb; +#endif +{ + CmLteTimingInfo expTime ={0}; + RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell); + + TRC2(rgSCHRamAddToRaInfoSchdLst) + + /*Fix: This can be called even when guard timer is not expired. + * In this case CR timer expiry should be guard timer expiry time + Guard timer time*/ + RG_SCH_ADD_TO_CRNT_TIME(raCb->expiryTime, expTime, cellSch->dl.msg4TxDelay); + raCb->expiryTime = expTime; + raCb->schdLnk.node = (PTR)(raCb); + cmLListAdd2Tail(&(cell->raInfo.toBeSchdLst), &(raCb->schdLnk)); + raCb->contResTmrLnk.node = (PTR)(raCb); + cmLListAdd2Tail(&(cell->contResTmrLst), &(raCb->contResTmrLnk)); + RETVALUE(ROK); +} /* rgSCHRamAddToRaInfoSchdLst */ + + + +#ifdef ANSI +PUBLIC S16 rgSCHRamRmvFrmRaInfoSchdLst +( +RgSchCellCb *cell, +RgSchRaCb *raCb +) +#else +PUBLIC S16 rgSCHRamRmvFrmRaInfoSchdLst(cell, raCb) +RgSchCellCb *cell; +RgSchRaCb *raCb; +#endif +{ + TRC2(rgSCHRamRmvFrmRaInfoSchdLst) + + cmLListDelFrm(&(cell->raInfo.toBeSchdLst), &(raCb->schdLnk)); + raCb->schdLnk.node = NULLP; + cmLListDelFrm(&(cell->contResTmrLst), &(raCb->contResTmrLnk)); + raCb->contResTmrLnk.node = NULLP; + RETVALUE(ROK); +} /* rgSCHRamRmvFrmRaInfoSchdLst */ + +/*MSG4 Fix End*/ + +/*********************************************************** + * + * Func : rgSCHRamUlFreeAllocation + * + * Desc : Free an allocation - invokes UHM and releases + * alloc + * + * Ret : + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PRIVATE Void rgSCHRamUlFreeAllocation +( +RgSchUlSf *sf, +RgSchUlAlloc *alloc, +RgSchCellCb *cell, +Bool isEmtc + +) +#else +PRIVATE Void rgSCHRamUlFreeAllocation(sf, alloc, cell,isEmtc) +RgSchUlSf *sf; +RgSchUlAlloc *alloc; +RgSchCellCb *cell; +Bool isEmtc; +#endif +{ + TRC2(rgSCHRamUlFreeAllocation); + + rgSCHUhmFreeProc(alloc->hqProc, cell); + if(!isEmtc) + { + rgSCHUtlUlAllocRls(sf, alloc); + } + RETVOID; +} + +/********************************************************************** + + End of file +**********************************************************************/ diff --git a/src/5gnrmac/rg_sch_sc1.c b/src/5gnrmac/rg_sch_sc1.c new file mode 100755 index 000000000..49997af0d --- /dev/null +++ b/src/5gnrmac/rg_sch_sc1.c @@ -0,0 +1,5681 @@ +/******************************************************************************* +################################################################################ +# Copyright (c) [2017-2019] [Radisys] # +# # +# 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. # +################################################################################ +*******************************************************************************/ + +/************************************************************************ + + Name: LTE-MAC layer + + Type: C source file + + Desc: C source code for scheduler 1 + + File: rg_sch_sc1.c + +**********************************************************************/ + +/** @file rg_sch_sc1.c +@brief The scheduling functionality is implemented in this file. +*/ + +static const char* RLOG_MODULE_NAME="MAC"; +static int RLOG_MODULE_ID=4096; +static int RLOG_FILE_ID=173; + +/* header include files -- defines (.h) */ +#include "envopt.h" /* environment options */ +#include "envdep.h" /* environment dependent */ +#include "envind.h" /* environment independent */ +#include "gen.h" /* general layer */ +#include "ssi.h" /* system service interface */ +#include "cm5.h" /* common timers */ +#include "cm_hash.h" /* common hash list */ +#include "cm_llist.h" /* common linked list library */ +#include "cm_err.h" /* common error */ +#include "cm_lte.h" /* common LTE */ +#include "lrg.h" +#include "rgr.h" +#include "rgm.h" +#include "tfu.h" +#include "rg_env.h" +#include "rg_sch_inf.h" +#include "rg_sch_err.h" +#include "rg_sch.h" +#include "rg_sch_cmn.h" +#include "rg_sch_sc1.h" +#include "rl_interface.h" +#include "rl_common.h" + +/* header/extern include files (.x) */ +#include "gen.x" /* general layer typedefs */ +#include "ssi.x" /* system services typedefs */ +#include "cm5.x" /* common timers */ +#include "cm_hash.x" /* common hash list */ +#include "cm_lib.x" /* common library */ +#include "cm_llist.x" /* common linked list */ +#include "cm_mblk.x" /* memory management */ +#include "cm_tkns.x" /* common tokens */ +#include "cm_lte.x" /* common tokens */ +#include "tfu.x" /* RGU types */ +#include "lrg.x" /* layer management typedefs for MAC */ +#include "rgr.x" /* layer management typedefs for MAC */ +#include "rgm.x" /* layer management typedefs for MAC */ +#include "rg_sch_inf.x" /* typedefs for Scheduler */ +#include "rg_sch.x" /* typedefs for Scheduler */ +#include "rg_sch_cmn.x" +#include "rg_sch_sc1.x" /* typedefs for SC1 Scheduler */ + + + + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* Functions called from outside */ +PRIVATE S16 rgSCHSc1RgrDlCellRecfg ARGS(( +RgSchCellCb *cell, +RgrCellRecfg *recfg, +RgSchErrInfo *err +)); + +/*--------------------------* + * DL SCHED STATIC declarations START + *---------------------------*/ +PRIVATE Void rgSCHSc1DlSvcAddToSchd ARGS(( +RgSchCellCb *cell, +RgSchDlLcCb *svc +)); +PRIVATE Void rgSCHSc1DlAdd2UeSchdSvcs ARGS(( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgSchDlLcCb *svc +)); +PRIVATE Void rgSCHSc1DlRmvUeFrmPrioQs ARGS(( +RgSchCellCb *cell, +RgSchUeCb *ue +)); +PRIVATE Void rgSCHSc1DlSuspendUe ARGS(( +RgSchCellCb *cell, +RgSchUeCb *ue +)); +PRIVATE Void rgSCHSc1DlInactvtUe ARGS(( +RgSchCellCb *cell, +RgSchUeCb *ue +)); +PRIVATE Void rgSCHSc1DlProcRmvFrmCellRetx ARGS(( +RgSchCellCb *cell, +RgSchDlHqProcCb *hqP +)); +PRIVATE Void rgSCHSc1DlProcRmvFrmUeRetx ARGS(( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgSchDlHqProcCb *hqP +)); +PRIVATE Void rgSCHSc1DlMngPrio0SvcPosn ARGS(( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgSchDlLcCb *svc +)); +PRIVATE Void rgSCHSc1DlMngGbrSvcPosn ARGS(( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgSchDlLcCb *svc +)); +PRIVATE Void rgSCHSc1DlMngAmbrSvcPosn ARGS(( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgSchDlLcCb *svc +)); +PRIVATE Void rgSCHSc1DlMngSvcPosn ARGS(( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgSchDlLcCb *svc +)); +PRIVATE Void rgSCHSc1DlUeAddToSchd ARGS(( +RgSchCellCb *cell, +RgSchUeCb *ue +)); +PRIVATE Void rgSCHSc1DlTaCmd ARGS(( +RgSchCellCb *cell, +RgSchCmnDlRbAllocInfo *allocInfo +)); +PRIVATE Void rgSCHSc1DlInitQueues ARGS(( +RgSchSc1DlCell *cellDl +)); +PRIVATE Void rgSCHSc1DlDeinitQueues ARGS(( +RgSchSc1DlCell *cellDl +)); +PRIVATE Void rgSCHSc1DlAdd2UeLcsWithData ARGS(( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgSchDlLcCb *svc +)); +PRIVATE Void rgSCHSc1DlRmFrmUeLcsWithData ARGS(( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgSchDlLcCb *svc +)); +/*--------------------------* + * UL SCHED STATIC declarations START + *---------------------------*/ +PRIVATE Void rgSCHSc1UlPosnUeInQ ARGS(( +RgSchCellCb *cell, +RgSchUeCb *ue +)); +PRIVATE Void rgSCHSc1UlSchdUeTxLst ARGS(( +RgSchCellCb *cell, +CmLListCp *ueTxLst, +RgSchCmnUlRbAllocInfo *allocInfo, +U8 *remUe +)); +PRIVATE Void rgSCHSc1DlProcRmvFrmRetx ARGS(( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgSchDlHqProcCb *hqP +)); +PUBLIC Void rgSCHSc1DlScanUpdPdbPrio ARGS(( +RgSchCellCb *cell +)); +PUBLIC S16 rgSCHSc1DlFillFlowCntrlInfo ARGS(( +RgSchCellCb *cell, +RgInfSfAlloc *sfAlloc +)); + +PRIVATE Void rgSCHSc1DlPreSchd ARGS (( +RgSchCellCb *cell +)); +PRIVATE Void rgSCHSc1DlPstSchd ARGS (( + Inst schInst +)); +#ifdef __cplusplus +} +#endif /* __cplusplus */ + + + + +/***************** SC1 DL SCHEDULER FUNCTION DEFNs START HERE ********/ + +/*********************************************************** + * + * Func : rgSCHSc1DlUeReset + * + * Desc : Out of Meas Gap. Reposition the UEs Retx Hq Procs, + * and Svc in respective Prio Qs. + * + * + * Ret : Void + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PUBLIC Void rgSCHSc1DlUeReset +( +RgSchCellCb *cell, +RgSchUeCb *ue +) +#else +PUBLIC Void rgSCHSc1DlUeReset(cell, ue) +RgSchCellCb *cell; +RgSchUeCb *ue; +#endif +{ + TRC2(rgSCHSc1DlUeReset); + + rgSCHSc1DlSuspendUe(cell, ue); + + RETVOID; +} + + +/*********************************************************** + * + * Func : rgSCHSc1DlActvtUe + * + * Desc : Out of Meas Gap. Reposition the UEs Retx Hq Procs, + * and Svc in respective Prio Qs. + * + * + * Ret : Void + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PUBLIC Void rgSCHSc1DlActvtUe +( +RgSchCellCb *cell, +RgSchUeCb *ue +) +#else +PUBLIC Void rgSCHSc1DlActvtUe(cell, ue) +RgSchCellCb *cell; +RgSchUeCb *ue; +#endif +{ + RgSchSc1DlUe *ueDl = RG_GET_SC1_UE_DL(ue, cell); + CmLListCp *lst; + CmLList *node; + RgSchDlHqProcCb *hqP; + RgSchDlLcCb *svc; + U8 idx; + TRC2(rgSCHSc1DlActvtUe); + + /* Add UE's HqProcs From UERetxLst to CellRetxLst */ + lst = &ueDl->retxHqProcs; + node = lst->first; + while(node) + { + hqP = (RgSchDlHqProcCb *)node->node; + node = node->next; + rgSCHSc1DlProcRmvFrmUeRetx(cell, ue, hqP); + rgSCHSc1DlProcAddToCellRetx(cell, hqP); + } + + /* Iterate over all the Services if bo != 0 then add */ + for (idx = 0; idx < RGSCH_MAX_LC_PER_UE; ++idx) + { + svc = ue->dl.lcCb[idx]; + if (svc == NULLP) + { + continue; + } + rgSCHSc1DlMngSvcPosn(cell, ue, svc); + } + + /* Add UE to AMBR Prio Q */ + if (ueDl->ambrSvc) + { + rgSCHSc1DlUeAddToSchd(cell, ue); + } + + RETVOID; +} + + +/*********************************************************** + * + * Func : rgSCHSc1DlUeRefresh + * + * Desc : Handle 'refresh' for Downlink + * (ie UE's downlink AMBR and downlink GBR LCGs are + * refreshed at this point) + * + * Ret : Void + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PUBLIC Void rgSCHSc1DlUeRefresh +( +RgSchCellCb *cell, +RgSchUeCb *ue +) +#else +PUBLIC Void rgSCHSc1DlUeRefresh(cell, ue) +RgSchCellCb *cell; +RgSchUeCb *ue; +#endif +{ + RgSchSc1DlUe *ueDl = RG_GET_SC1_UE_DL(ue, cell); + /*cell added as part of CA dev*/ + RgSchCmnDlSvc *svcCmn; + RgSchSc1DlSvc *svcSc1; + CmLListCp *lst; + CmLList *node; + RgSchDlLcCb *svc; + TRC2(rgSCHSc1DlUeRefresh); + + if (ue->dl.ambrCfgd) + { + ueDl->ambr = ue->dl.ambrCfgd; + } + else + { + ueDl->ambr = RG_SC1_MAX_DL_AMBR; + } + + if (ueDl->ambrSvc != NULLP) + { + ueDl->effAmbr = RGSCH_MIN(ueDl->ambr, ueDl->ambrSvc->bo); + /* Update UEs position in the Queue */ + rgSCHSc1DlUeAddToSchd(cell, ue); + } + + lst = &ueDl->gbrSvcs; + node = lst->first; + while (node != NULLP) + { + svc = (RgSchDlLcCb *)node->node; + svcSc1 = RG_GET_SC1_SVC_DL(ue,svc,cell); + svcCmn = RG_SCH_CMN_GET_DL_SVC(svc); + node = node->next; + svcSc1->gbr = svcCmn->gbr; + svcSc1->mbr = svcCmn->mbr; + /* Update the SVC's positioning in the Queue */ + rgSCHSc1DlMngGbrSvcPosn(cell, ue, svc); + } + RETVOID; +} + + +/** + * @brief This function removes a HARQ process from the retx + * + * @details + * + * Function: rgSCHSc1DlProcRmvFrmCellRetx + * Purpose: This function removes a HARQ process from retransmission + * queue. This may be performed when a HARQ ack is successful + * for a retransmission or when the scheduling determines + * to throw out the process due to poor conditions + * + * Invoked by: LIM and Scheduler + * + * @param[in] RgSchSc1Cb* cell + * @param[in] RgDlHqProc* hqP + * @return Void + * + **/ +#ifdef ANSI +PRIVATE Void rgSCHSc1DlProcRmvFrmCellRetx +( +RgSchCellCb *cell, +RgSchDlHqProcCb *hqP +) +#else +PRIVATE Void rgSCHSc1DlProcRmvFrmCellRetx(cell, hqP) +RgSchCellCb *cell; +RgSchDlHqProcCb *hqP; +#endif +{ + RgSchSc1DlCell *cellDl = RG_GET_SC1_CELL_DL(cell); + RgSchCmnDlHqProc *hqProcDl = RG_SCH_CMN_GET_DL_HQP(hqP); + + TRC2(rgSCHSc1DlProcRmvFrmCellRetx); + + if (hqProcDl->retxLnk.node != NULLP) + { + cmLListDelFrm(&cellDl->retxLst[((RgSchSc1DlHqProc *)\ + (hqProcDl->schSpfc))->prio], &(hqProcDl->retxLnk)); + hqProcDl->retxLnk.node = NULLP; + } + RETVOID; +} + + +/** + * @brief This function removes a HARQ process from the UE retx + * + * @details + * + * Function: rgSCHSc1DlProcRmvFrmUeRetx + * Purpose: This function removes a HARQ process from UE retransmission + * queue. + * + * Invoked by: LIM and Scheduler + * + * @param[in] RgSchUeCb* ue + * @param[in] RgDlHqProc* hqP + * @return Void + * + **/ +#ifdef ANSI +PRIVATE Void rgSCHSc1DlProcRmvFrmUeRetx +( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgSchDlHqProcCb *hqP +) +#else +PRIVATE Void rgSCHSc1DlProcRmvFrmUeRetx(cell, ue, hqP) +RgSchCellCb *cell; +RgSchUeCb *ue; +RgSchDlHqProcCb *hqP; +#endif +{ + RgSchSc1DlUe *sc1Ue = RG_GET_SC1_UE_DL(ue, cell); + RgSchSc1DlHqProc *hqProcDl = RG_GET_SC1_HQP_DL(hqP); + + TRC2(rgSCHSc1DlProcRmvFrmUeRetx); + + if (hqProcDl->retxLnkUe.node != NULLP) + { + cmLListDelFrm(&sc1Ue->retxHqProcs, + &(hqProcDl->retxLnkUe)); + hqProcDl->retxLnkUe.node = NULLP; + } + RETVOID; +} + + +/** + * @brief This function adds a HARQ process for UEs retxLst + * + * @details + * + * Function: rgSCHSc1DlProcAddToUeRetx + * Purpose: This function adds a HARQ process to UE retransmission + * queue. This is performed when UE is suspended due + * to measurement gap. + * + * Invoked by: HARQ feedback processing + * + * @param[in] RgSchUeCb* ue + * @param[in] RgSchDlHqProc* hqP + * @return Void + * + **/ +#ifdef ANSI +PRIVATE Void rgSCHSc1DlProcAddToUeRetx +( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgSchDlHqProcCb *hqP +) +#else +PRIVATE Void rgSCHSc1DlProcAddToUeRetx(cell, ue, hqP) +RgSchCellCb *cell; +RgSchUeCb *ue; +RgSchDlHqProcCb *hqP; +#endif +{ + RgSchSc1DlUe *sc1Ue = RG_GET_SC1_UE_DL(ue, cell); + RgSchSc1DlHqProc *cmnHqDl = RG_GET_SC1_HQP_DL(hqP); + + TRC2(rgSCHSc1DlProcAddToUeRetx); + + cmLListAdd2Tail(&sc1Ue->retxHqProcs, + &(cmnHqDl->retxLnkUe)); + cmnHqDl->retxLnkUe.node = (PTR)hqP; + RETVOID; +} + + +/** + * @brief This function adds a HARQ process for retx + * + * @details + * + * Function: rgSCHSc1DlProcAddToCellRetx + * Purpose: This function adds a HARQ process to retransmission + * queue. This may be performed when a HARQ ack is + * unsuccessful. + * + * Invoked by: HARQ feedback processing + * + * @param[in] RgSchCellCb* cell + * @param[in] RgSchDlHqProc* hqP + * @return Void + * + **/ +#ifdef ANSI +PUBLIC Void rgSCHSc1DlProcAddToCellRetx +( +RgSchCellCb *cell, +RgSchDlHqProcCb *hqP +) +#else +PUBLIC Void rgSCHSc1DlProcAddToCellRetx(cell, hqP) +RgSchCellCb *cell; +RgSchDlHqProcCb *hqP; +#endif +{ + RgSchSc1DlCell *sc1CellDl = RG_GET_SC1_CELL_DL(cell); + RgSchCmnDlHqProc *cmnHqDl = RG_SCH_CMN_GET_DL_HQP(hqP); + + TRC2(rgSCHSc1DlProcAddToCellRetx); + + if (!RG_SCH_CMN_DL_IS_UE_ACTIVE(hqP->hqE->ue)) + { + rgSCHSc1DlProcAddToUeRetx(cell, hqP->hqE->ue, hqP); + RETVOID; + } + cmLListAdd2Tail(&sc1CellDl->retxLst[((RgSchSc1DlHqProc *)\ + (cmnHqDl->schSpfc))->prio], &(cmnHqDl->retxLnk)); + cmnHqDl->retxLnk.node = (PTR)hqP; + RETVOID; +} + + +/** + * @brief This function implements DL RETRANSMISSION allocation + * + * @details + * + * Function: rgSCHSc1DlRetxAlloc + * Purpose: This function implements downlink scheduler's + * retransmission allocation. + * + * Invoked by: Scheduler + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchDlSf *subFrm + * @param[out] RgSchCmnDlRbAllocInfo *allocInfo + * @return Void + * + **/ +#ifdef ANSI +PRIVATE Void rgSCHSc1DlRetxAlloc +( +RgSchCellCb *cell, +RgSchDlSf *subFrm, +RgSchCmnDlRbAllocInfo *allocInfo +) +#else +PRIVATE Void rgSCHSc1DlRetxAlloc(cell, subFrm, allocInfo) +RgSchCellCb *cell; +RgSchDlSf *subFrm; +RgSchCmnDlRbAllocInfo *allocInfo; +#endif +{ + U8 i; + CmLListCp *retxLst; + CmLList *node; + RgSchDlHqProcCb *hqP; + RgSchSc1DlCell *sc1CellDl; + RgSchSc1DlUe *sc1DlUe; + RgSchCmnDlUe *cmnUeDl; +#if (defined(LTEMAC_SPS) || (!defined(LTE_TDD))) + CmLteTimingInfo schdTime; +#endif + U32 effBo; + RgSchUeCb *ue = NULLP; +#ifdef LTEMAC_HDFDD + Bool dlAllowed = FALSE; +#endif + RgSchDlRbAlloc *dlAllocCb; + TRC2(rgSCHSc1DlRetxAlloc); + + sc1CellDl = RG_GET_SC1_CELL_DL(cell); +#if (defined(LTEMAC_SPS) || (!defined(LTE_TDD))) + schdTime = cell->crntTime; + + /* Increment by DL DELTA to determine the time for which scheduling + * is done */ + RGSCH_INCR_SUB_FRAME(schdTime, RG_SCH_CMN_DL_DELTA); +#endif + for (i = 0; i < RG_SCH_SC1_DL_PRIOS; i++) + { + retxLst = &sc1CellDl->retxLst[i]; + /* allocate bw for the retransmission..should be same are previous */ + /* If CQI gets worse, as we cannot find same TB size for another */ + /* MCS, we just remove this from the retransmission queue */ + node = retxLst->first; + while (node != NULLP) + { + hqP = (RgSchDlHqProcCb *)node->node; + node = node->next; + ue = hqP->hqE->ue; + +#ifndef LTE_TDD + if((0 == schdTime.subframe) || (5 == schdTime.subframe)) + { + Bool reTxAllw; + rgSCHCmnChkRetxAllowDtx(cell, ue, hqP, &reTxAllw); + if(FALSE == reTxAllw) + { + continue; + } + } +#endif +#ifdef LTEMAC_HDFDD + if (ue->hdFddEnbld) + { + rgSCHCmnHdFddChkDlAllow ( cell, ue, &dlAllowed); + if (dlAllowed == FALSE) + { + continue; + } + } +#endif + /* This UE is already scheduled for transmission */ + cmnUeDl = RG_SCH_CMN_GET_DL_UE(ue,cell); + /*cell added as part of CA dev*/ +#ifdef LTEMAC_SPS + if (RG_SCH_CMN_IS_UE_SPS_SCHDLD(ue, cell, schdTime)) + { + continue; + } +#endif + if (RG_SCH_CMN_IS_UE_SCHDLD(ue, cell)) + { + continue; + } + effBo = 0; + /* Extra check: indicate if there is furtherScope for NewTx + * addition for a HqProc. This information will + * be utilized by common scheduler, in case of SM + * UEs with only one of the TBs retransmitting and the + * other TB can be used for clubbing new TX. */ + sc1DlUe = RG_GET_SC1_UE_DL(ue, cell); + dlAllocCb = RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ue, cell); + if (sc1DlUe->lcsWithData.first != NULLP) + { + dlAllocCb->mimoAllocInfo.hasNewTxData = TRUE; + } + /* 3.1 MIMO : last parameter changed */ + if (rgSCHCmnDlAllocRetxRb(cell, subFrm, ue, 0, &effBo, hqP, allocInfo) !=\ + ROK) + { + /* SF/RETX Bandwidth expired */ + RETVOID; + } + if (effBo == 0) + { + continue; + } + + if ((hqP->tbInfo[0].state == HQ_TB_ACKED) + && (hqP->tbInfo[1].state == HQ_TB_ACKED)) + { + rgSCHSc1DlProcRmvFrmCellRetx(cell, hqP); + RETVOID; + } + + cmnUeDl->proc = hqP; + /* 3.1 MIMO moving this call in cmn scheduler */ + /*rgSCHCmnDlRbInfoAddUeRetx(allocInfo, ue);*/ + } + } + RETVOID; +} + +/*********************************************************** + * + * Func : rgSCHSc1RlsHqProc + * + * Desc : Toggles the NDI and releases the harq proc. + * + * Ret : Void + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PRIVATE Void rgSCHSc1RlsHqProc +( +RgSchDlHqProcCb *hqProc +) +#else +PRIVATE Void rgSCHSc1RlsHqProc(hqProc) +RgSchDlHqProcCb *hqProc; +#endif +{ + TRC2(rgSCHSc1RlsHqProc) + rgSCHDhmRlsHqProc(hqProc); + RETVOID; +} + +/** + * @brief This function implements dedicated logical channel data scheduling + * + * @details + * + * Function: rgSCHSc1DlDedSvcAlloc + * Purpose: This function implements dedicated logical + * channel data scheduling + * + * Invoked by: Scheduler + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchDlSf *subFrm + * @param[in] RgSchDlLcCb *svc + * @param[in] U32 bo + * @param[in] RgSchCmnDlRbAllocInfo *allocInfo + * @return S16 + * + **/ +#ifdef ANSI +PRIVATE S16 rgSCHSc1DlDedSvcAlloc +( +RgSchCellCb *cell, +RgSchDlSf *subFrm, +RgSchDlLcCb *svc, +U32 bo, +RgSchCmnDlRbAllocInfo *allocInfo +) +#else +PRIVATE S16 rgSCHSc1DlDedSvcAlloc(cell, subFrm, svc, bo, allocInfo) +RgSchCellCb *cell; +RgSchDlSf *subFrm; +RgSchDlLcCb *svc; +U32 bo; +RgSchCmnDlRbAllocInfo *allocInfo; +#endif +{ + RgSchUeCb *ue; + RgSchDlHqProcCb *proc; + U16 rlcHdrEstmt; + U32 effBo; + RgSchCmnDlCell *cmnCellDl = RG_SCH_CMN_GET_DL_CELL(cell); + RgSchCmnDlSvc *svcCmn = RG_SCH_CMN_GET_DL_SVC(svc); + RgSchSc1DlSvc *svcSc1; + RgSchCmnDlUe *ueDl; + RgSchSc1DlHqProc *sc1HqDl; + RgSchCmnDlHqProc *cmnHqDl; +#ifdef LTEMAC_SPS + CmLteTimingInfo schdTime; +#endif +#ifdef LTEMAC_HDFDD + Bool dlAllowed = FALSE; +#endif + S16 ret; + + TRC2(rgSCHSc1DlDedSvcAlloc); + + /* Get the UE to which this service belongs to */ + ue = svc->ue; +#ifdef LTEMAC_HDFDD + if (ue->hdFddEnbld) + { + rgSCHCmnHdFddChkDlAllow ( cell, ue, &dlAllowed); + if (dlAllowed == FALSE) + { + RETVALUE(ROK); + } + } +#endif + ueDl = RG_SCH_CMN_GET_DL_UE(ue,cell); + /*cell added as part of CA dev*/ +#ifdef LTEMAC_SPS + schdTime = cell->crntTime; + + /* Increment by DL DELTA to determine the time for which scheduling + * is done */ + RGSCH_INCR_SUB_FRAME(schdTime, RG_SCH_CMN_DL_DELTA); + if (RG_SCH_CMN_IS_UE_SPS_SCHDLD(ue, cell, schdTime)) + { + RETVALUE(ROK); + } +#endif + if (RG_SCH_CMN_IS_UE_SCHDLD(ue, cell)) + { + proc = (RgSchDlHqProcCb *)(ueDl->proc); + /* This UE is selected for retransmission. Hence no further */ + /* scheduling may be done for this UE */ + if (RG_SCH_CMN_PROC_SLCTD_FOR_RETX(proc)) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,"CRNTI:%d rgSCHSc1DlDedSvcAlloc():" + "Ue retransmitting",ue->ueId); + RETVALUE(ROK); + } + /* UE is scheduled for either other services or TA */ + sc1HqDl = RG_GET_SC1_HQP_DL(proc); + cmnHqDl = RG_SCH_CMN_GET_DL_HQP(proc); + if (sc1HqDl->prio > svcCmn->prio) + { + sc1HqDl->prio = svcCmn->prio; + } + } + else /* First consideration of this UE for scheduling */ + { + if (rgSCHDhmGetAvlHqProc(cell, ue, cmnCellDl->time, &proc) != ROK) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId, "CRNTI:%d rgSCHSc1DlDedSvcAlloc():" + " No HARQ Proc available", ue->ueId); + RETVALUE(ROK); + } + sc1HqDl = RG_GET_SC1_HQP_DL(proc); + cmnHqDl = RG_SCH_CMN_GET_DL_HQP(proc); + cmnHqDl->totBytes = 0; + /* Initialize some of the parameters of the HQ proc */ + sc1HqDl->prio = svcCmn->prio; + } + + /* Including each SDU's header size */ + RG_SCH_CMN_DL_GET_HDR_EST(svc, rlcHdrEstmt); + bo += rlcHdrEstmt; + effBo = 0; + ret = rgSCHCmnDlAllocTxRb(cell, subFrm, ue, bo, &effBo, proc, allocInfo); + if ((ret != ROK) || (effBo == 0)) + { + /* If no allocations so far, meaning proc obtained now */ + if (cmnHqDl->totBytes == 0) + { + rgSCHSc1RlsHqProc(proc); + /* Added the handling for removing + * UE from txHqPLst and resetting outStndAlloc.*/ + if(proc->reqLnk.node != (PTR)NULLP) + { + cmLListDelFrm(&allocInfo->dedAlloc.txHqPLst, &proc->reqLnk); + proc->reqLnk.node = (PTR)NULLP; + } + /*Re-set the outstanding alloc information.*/ + ueDl->outStndAlloc = 0; + + /* ccpu00126519: proc should be set to NULLP in UE's DL scratch pad info as well. */ + ueDl->proc = NULLP; + } + RETVALUE(ret); + } + svcSc1 = RG_GET_SC1_SVC_DL(ue,svc,cell); + svcSc1->hdrEstimate = rlcHdrEstmt; + svcSc1->reqBytes = bo; + ueDl->proc = proc; + cmnHqDl->totBytes += effBo; + + rgSCHSc1DlAdd2UeSchdSvcs(cell, ue, svc); + /* 3.1 MIMO moving this call to cmn scheduler */ + /*rgSCHCmnDlRbInfoAddUeTx(allocInfo, ue); */ + RETVALUE(ROK); +} + +/** + * @brief This function adds a SVC to UE's schdSvcsLst. + * + * @details + * + * Function: rgSCHSc1DlAdd2UeSchdSvcs + * Purpose: This function adds a SVC to UE's schdSvcsLst. + * + * Invoked by: Specific Scheduler + * + * @param[out] RgSchUeCb *ue + * @param[in] RgSchDlLcCb *svc + * @return Void + * + **/ +#ifdef ANSI +PRIVATE Void rgSCHSc1DlAdd2UeSchdSvcs +( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgSchDlLcCb *svc +) +#else +PRIVATE Void rgSCHSc1DlAdd2UeSchdSvcs(cell, ue, svc) +RgSchCellCb *cell; +RgSchUeCb *ue; +RgSchDlLcCb *svc; +#endif +{ + RgSchSc1DlSvc *svcSc1 = RG_GET_SC1_SVC_DL(ue,svc,cell); + RgSchSc1DlUe *ueSc1 = RG_GET_SC1_UE_DL(ue, cell); + TRC2(rgSCHSc1DlAdd2UeSchdSvcs); + + /* checking SVC's presence in this lst is unnecessary */ + cmLListAdd2Tail(&ueSc1->schdSvcs, &svcSc1->schdSvcLnk); + svcSc1->schdSvcLnk.node = (PTR)svc; + RETVOID; +} + + +/** + * @brief This function performs new allocations for UEs + * + * @details + * + * Function: rgSCHSc1DlDedTx + * Purpose: This function implements scheduler for DL allocation for + * new transmissions of UEs. + * 1. It performs across 9 priorities that it supports - + * This is from 3GPP specifications + * 2. There are known number of GBR/MBR queues + * 3. The first queue is highest priority queue and is + * satisfied completely prior to any other queues. This + * queue is for RRC signalling. + * 4. Futher GBR/MBR queues are satisfied for GBR and then MBR + * 5. Subsequently all other queues are looked at for AMBR + * + * Invoked by: Scheduler + * + * @param[in] RgSchCellCb* cell + * @param[in] RgSchDlSf *subFrm + * @param[out] RgSchCmnDlRbAllocInfo *allocInfo + * @return Void + * + **/ +#ifdef ANSI +PRIVATE Void rgSCHSc1DlDedTx +( +RgSchCellCb *cell, +RgSchDlSf *subFrm, +RgSchCmnDlRbAllocInfo *allocInfo +) +#else +PRIVATE Void rgSCHSc1DlDedTx(cell, subFrm, allocInfo) +RgSchCellCb *cell; +RgSchDlSf *subFrm; +RgSchCmnDlRbAllocInfo *allocInfo; +#endif +{ + CmLListCp *lst; + CmLList *node; + RgSchUeCb *ue = NULLP; + RgSchDlLcCb *svc; + U8 i; + RgSchSc1DlSvc *svcSc1; + RgSchSc1DlUe *ueDl; + RgSchSc1DlCell *sc1CellDl = RG_GET_SC1_CELL_DL(cell); + + TRC2(rgSCHSc1DlDedTx); + + /* Process the first queue that is for RRC signalling and is of */ + /* highest priority. */ + lst = &sc1CellDl->prioLst[0]; + node = lst->first; + while(node != NULLP) + { + /* Getting service instead of UE */ + svc = (RgSchDlLcCb *)node->node; + ue = svc->ue; + svcSc1 = RG_GET_SC1_SVC_DL(ue,svc,cell); + node = node->next; + if (rgSCHSc1DlDedSvcAlloc(cell, subFrm, svc, svcSc1->bo, allocInfo) != ROK) + { + /* sf bw expired */ + RETVOID; + } + } + + /* Perform allocation for the GBR transmissions */ + for(i = RG_SCH_SC1_DL_GBR_PRIO_START; i <= RG_SCH_SC1_DL_GBR_PRIO_END; i++) + { + lst = &sc1CellDl->prioLst[i]; + node = lst->first; + while(node != NULLP) + { + /* Getting service instead of UE */ + svc = (RgSchDlLcCb *)node->node; + ue = svc->ue; + svcSc1 = RG_GET_SC1_SVC_DL(ue,svc,cell); + node = node->next; + if (rgSCHSc1DlDedSvcAlloc(cell, subFrm, svc, svcSc1->effMbr, allocInfo) != ROK) + { + /* sf bw expired */ + RETVOID; + } + } + } + + /* To implement AMBR svc scheduling */ + for(i = RG_SCH_SC1_DL_GBR_PRIO_END + 1; i < RG_SCH_SC1_DL_PRIOS; i++) + { + lst = &sc1CellDl->prioLst[i]; + node = lst->first; + while(node != NULLP) + { + ue = (RgSchUeCb *)node->node; + ueDl = RG_GET_SC1_UE_DL(ue, cell); + node = node->next; + /* Get the Curr ambr svc for which allocation is to be made */ + svc = ueDl->ambrSvc; + if (rgSCHSc1DlDedSvcAlloc(cell, subFrm, svc, ueDl->effAmbr, allocInfo) != ROK) + { + /* sf bw expired */ + RETVOID; + } + } + } + RETVOID; +} + +/** + * @brief scheduling for a cell + * + * @details + * + * Function : rgSCHSc1DlPreSchd + * + * Processing Steps: + * - Nothing to be done in case of RR + * + * @param[in] Inst schInst + * @return Void + **/ +#ifdef ANSI +PRIVATE Void rgSCHSc1DlPreSchd +( + RgSchCellCb *cell +) +#else +PUBLIC Void rgSCHSc1DlPreSchd(cell) + RgSchCellCb *cell; +#endif +{ + TRC2(rgSCHSc1DlPreSchd); + + RETVOID; +} +/** + * @brief scheduling for a cell + * + * @details + * + * Function : rgSCHSc1DlPstSchd + * + * Processing Steps: + * - Nothing to be done in case of RR + * + * @param[in] Inst schInst + * @return Void + **/ +#ifdef ANSI +PRIVATE Void rgSCHSc1DlPstSchd +( + Inst schInst +) +#else +PUBLIC Void rgSCHSc1DlPstSchd(schInst) + Inst schInst +#endif +{ + TRC2(rgSCHSc1DlPstSchd); + + RETVOID; +} + + +/** + * @brief This function implements scheduler DL allocation + * + * @details + * + * Function: rgSCHSc1DlDedNewTx + * Purpose: This function implements scheduler for DL allocation for + * UEs. + * + * Invoked by: Scheduler + * + * @param[in] RgSchCellCb *cell + * @param[out] RgSchCmnDlRbAllocInfo *allocInfo + * @return Void + * + **/ +#ifdef ANSI +PRIVATE Void rgSCHSc1DlDedNewTx +( +RgSchCellCb *cell, +RgSchCmnDlRbAllocInfo *allocInfo +) +#else +PRIVATE Void rgSCHSc1DlDedNewTx(cell, allocInfo) +RgSchCellCb *cell; +RgSchCmnDlRbAllocInfo *allocInfo; +#endif +{ + RgSchDlSf *subFrm = allocInfo->dedAlloc.dedDlSf; +#ifdef DEBUGP + Inst inst = cell->instIdx; +#endif + TRC2(rgSCHSc1DlDedNewTx); + RGSCHDBGPRM(inst, (rgSchPBuf(inst), "rgSCHSc1DlDedNewTx\n")); + + /* Now perform the new UE selections */ + rgSCHSc1DlDedTx(cell, subFrm, allocInfo); + + /* Stack Crash problem for TRACE5 changes. Added the return below */ + RETVOID; + +} +/** + * @brief This function implements scheduler DL allocation + * + * @details + * + * Function: rgSCHSc1DlDedRetx + * Purpose: This function implements scheduler for DL allocation for + * UEs. + * + * Invoked by: Scheduler + * + * @param[in] RgSchCellCb *cell + * @param[out] RgSchCmnDlRbAllocInfo *allocInfo + * @return Void + * + **/ +#ifdef ANSI +PRIVATE Void rgSCHSc1DlDedRetx +( +RgSchCellCb *cell, +RgSchCmnDlRbAllocInfo *allocInfo +) +#else +PRIVATE Void rgSCHSc1DlDedRetx(cell, allocInfo) +RgSchCellCb *cell; +RgSchCmnDlRbAllocInfo *allocInfo; +#endif +{ + RgSchDlSf *subFrm = allocInfo->dedAlloc.dedDlSf; +#ifdef DEBUGP + Inst inst = cell->instIdx; +#endif + TRC2(rgSCHSc1DlDedRetx); + RGSCHDBGPRM(inst, (rgSchPBuf(inst), "rgSCHSc1DlDedRetx\n")); + + rgSCHSc1DlRetxAlloc(cell, subFrm, allocInfo); + + RETVOID; + +} + + + +/** + * @brief This function adds a service to scheduler + * + * @details + * + * Function: rgSCHSc1DlSvcAddToSchd + * Purpose: This function adds a service to the list of services + * based on the priority of the services. + * + * Invoked by: BO and Scheduler + * + * @param[in] RgSchCellCb* cell + * @param[in] RgSchUeCb* ue + * @return Void + * + **/ +#ifdef ANSI +PRIVATE Void rgSCHSc1DlSvcAddToSchd +( +RgSchCellCb *cell, +RgSchDlLcCb *svc +) +#else +PRIVATE Void rgSCHSc1DlSvcAddToSchd(cell, svc) +RgSchCellCb *cell; +RgSchDlLcCb *svc; +#endif +{ + CmLListCp *lst; + CmLList *node; + RgSchDlLcCb *lSvc; + RgSchSc1DlSvc *svcSc1; + RgSchSc1DlSvc *lSvcSc1; + RgSchSc1DlCell *sc1CellDl = RG_GET_SC1_CELL_DL(cell); + RgSchCmnDlSvc *svcCmn = RG_SCH_CMN_GET_DL_SVC(svc); + + TRC2(rgSCHSc1DlSvcAddToSchd); + + svcSc1 = RG_GET_SC1_SVC_DL(svc->ue,svc,cell); + /* The service is already in the scheduler */ + if (svcSc1->prioLnk.node != NULLP) + { + RETVOID; + } + + /* If the priority = 0, it is the highest priority with infinite */ + /* allowance and the priority is time bound and hence just place */ + /* it at the end of the queue */ + if (svcCmn->prio == 0) + { + lst = &(sc1CellDl->prioLst[0]); + cmLListAdd2Tail(lst, &svcSc1->prioLnk); + svcSc1->prioLnk.node = (PTR)svc; + /* If a svc is put in to cell wide priority Qs + * then add the same to UE's lcsWithData List */ + rgSCHSc1DlAdd2UeLcsWithData(cell, svc->ue, svc); + RETVOID; + } + + /* Handle GBR services. We have them of next importance */ + /* check changed from .._START to .._END */ + if (svcCmn->prio <= RG_SCH_SC1_DL_GBR_PRIO_END) + { + if (!RG_SC1_SVC_HAS_DATA(svc,cell)) + RETVOID; + lst = &(sc1CellDl->prioLst[svcCmn->prio]); + node = lst->first; + while(node) + { + lSvc = (RgSchDlLcCb *)(node->node); + lSvcSc1 = RG_GET_SC1_SVC_DL(lSvc->ue,lSvc,cell); + if (((svcSc1->effGbr > 0) && + (lSvcSc1->effGbr <= svcSc1->effGbr)) || + ((lSvcSc1->effGbr == 0) && (svcSc1->effMbr > 0) && + (lSvcSc1->effMbr <= svcSc1->effMbr))) + { + break; + } + node = node->next; + } + if (node == NULLP) + { + /* We have come to the end of the queue. Let's place it */ + /* here irresepctive of effGbr or effMBr */ + cmLListAdd2Tail(lst, &svcSc1->prioLnk); + svcSc1->prioLnk.node = (PTR)svc; + } + else + { + lst->crnt = node; + cmLListInsCrnt(lst, &svcSc1->prioLnk); + svcSc1->prioLnk.node = (PTR)svc; + } + /* If a svc is put in to cell wide priority Qs + * then add the same to UE's lcsWithData List */ + rgSCHSc1DlAdd2UeLcsWithData(cell, svc->ue, svc); + } + RETVOID; +} + + + +/** + * @brief This function removes a UE from scheduler Queue + * + * @details + * + * Function: rgSCHSc1DlUeRmvFrmSchd + * Purpose: This function removes a UE from the list of UEs + * based on the priority of the UEs Current AMBR SVC. + * + * Invoked by: BO and Scheduler + * + * @param[in] RgSchCellCb* cell + * @param[in] RgSchUeCb* ue + * @return Void + * + **/ +#ifdef ANSI +PRIVATE Void rgSCHSc1DlUeRmvFrmSchd +( +RgSchCellCb *cell, +RgSchUeCb *ue +) +#else +PRIVATE Void rgSCHSc1DlUeRmvFrmSchd(cell, ue) +RgSchCellCb *cell; +RgSchUeCb *ue; +#endif +{ + RgSchSc1DlCell *cellDl = RG_GET_SC1_CELL_DL(cell); + RgSchSc1DlUe *ueDl = RG_GET_SC1_UE_DL(ue, cell); + CmLListCp *lst; + + TRC2(rgSCHSc1DlUeRmvFrmSchd); + + lst = &cellDl->prioLst[ueDl->prio]; + if (ueDl->prioLnk.node != NULLP) + { + cmLListDelFrm(lst, &ueDl->prioLnk); + ueDl->prioLnk.node = (PTR)NULLP; + /* If a svc is removed from cell wide priority Qs + * then remove the same from UE's lcsWithData List */ + rgSCHSc1DlRmFrmUeLcsWithData(cell, ue, ueDl->ambrSvc); + } + RETVOID; +} + + +/** + * @brief This function removes a SVC from UEs AMBR LIST + * + * @details + * + * Function: rgSCHSc1DlSvcRmvFrmUeAmbrLst + * Purpose: This function removes a SVC from UEs AMBR List. + * + * Invoked by: BO and Scheduler + * + * @param[in] RgSchUeCb* ue + * @param[in] RgSchDlLcCb* svc + * @return Void + * + **/ +#ifdef ANSI +PRIVATE Void rgSCHSc1DlSvcRmvFrmUeAmbrLst +( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgSchDlLcCb *svc +) +#else +PRIVATE Void rgSCHSc1DlSvcRmvFrmUeAmbrLst(cell, ue, svc) +RgSchCellCb *cell; +RgSchUeCb *ue; +RgSchDlLcCb *svc; +#endif +{ + RgSchSc1DlUe *ueDl = RG_GET_SC1_UE_DL(ue, cell); + RgSchSc1DlSvc *svcSc1 = RG_GET_SC1_SVC_DL(ue,svc,cell); + CmLListCp *lst; + + TRC2(rgSCHSc1DlSvcRmvFrmUeAmbrLst); + + lst = &ueDl->ambrLst; + if (svcSc1->prioLnk.node != NULLP) + { + cmLListDelFrm(lst, &svcSc1->prioLnk); + svcSc1->prioLnk.node = (PTR)NULLP; + } + RETVOID; +} + + +/** + * @brief This function adds a SVC to UEs AMBR LIST + * + * @details + * + * Function: rgSCHSc1DlSvcAddToUeAmbrLst + * Purpose: This function adds a SVC to UEs AMBR List. + * + * Invoked by: BO and Scheduler + * + * @param[in] RgSchUeCb* ue + * @param[in] RgSchDlLcCb* svc + * @return Void + * + **/ +#ifdef ANSI +PRIVATE Void rgSCHSc1DlSvcAddToUeAmbrLst +( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgSchDlLcCb *svc +) +#else +PRIVATE Void rgSCHSc1DlSvcAddToUeAmbrLst(cell, ue, svc) +RgSchCellCb *cell; +RgSchUeCb *ue; +RgSchDlLcCb *svc; +#endif +{ + RgSchSc1DlUe *ueDl = RG_GET_SC1_UE_DL(ue, cell); + CmLList *node; + RgSchDlLcCb *lsvc; + RgSchSc1DlSvc *svcSc1 = RG_GET_SC1_SVC_DL(ue,svc,cell); + RgSchCmnDlSvc *svcCmn = RG_SCH_CMN_GET_DL_SVC(svc); + + TRC2(rgSCHSc1DlSvcAddToUeAmbrLst); + + /* If svc already present in AMBR List return */ + if (svcSc1->prioLnk.node != NULLP) + RETVOID; + + node = ueDl->ambrLst.first; + while(node) + { + lsvc = (RgSchDlLcCb *)(node->node); + if (((RgSchCmnDlSvc*)(lsvc->sch))->prio > svcCmn->prio) + { + break; + } + node = node->next; + } + if (node == NULLP) + { + cmLListAdd2Tail(&ueDl->ambrLst, &svcSc1->prioLnk); + svcSc1->prioLnk.node = (PTR)svc; + } + else + { + ueDl->ambrLst.crnt = node; + cmLListInsCrnt(&ueDl->ambrLst, &svcSc1->prioLnk); + svcSc1->prioLnk.node = (PTR)svc; + } + + RETVOID; +} + + +/** + * @brief This function removes a service from scheduler + * + * @details + * + * Function: rgSCHSc1DlSvcRmvFrmSchd + * Purpose: This function removes the SVC from the scheduler Qs. + * + * Invoked by: BO and Scheduler + * + * @param[in] RgSchCellCb* cell + * @param[in] RgSchUeCb* ue + * @return Void + * + **/ +#ifdef ANSI +PRIVATE Void rgSCHSc1DlSvcRmvFrmSchd +( +RgSchCellCb *cell, +RgSchDlLcCb *svc +) +#else +PRIVATE Void rgSCHSc1DlSvcRmvFrmSchd(cell, svc) +RgSchCellCb *cell; +RgSchDlLcCb *svc; +#endif +{ + RgSchSc1DlCell *cellDl = RG_GET_SC1_CELL_DL(cell); + RgSchSc1DlSvc *svcDl = RG_GET_SC1_SVC_DL(svc->ue,svc,cell); + RgSchCmnDlSvc *svcCmn = RG_SCH_CMN_GET_DL_SVC(svc); + CmLListCp *lst; + + TRC2(rgSCHSc1DlSvcRmvFrmSchd); + + lst = &(cellDl->prioLst[svcCmn->prio]); + if (svcDl->prioLnk.node != NULLP) + { + cmLListDelFrm(lst, &svcDl->prioLnk); + svcDl->prioLnk.node = NULLP; + /* If a svc is removed from cell wide priority Qs + * then remove the same from UE's lcsWithData List */ + rgSCHSc1DlRmFrmUeLcsWithData(cell, svc->ue, svc); + } + RETVOID; +} + + +/** + * @brief This function adds a service to scheduler for a UE + * + * @details + * + * Function: rgSCHSc1DlSvcAdd + * Purpose: This function is made available through a FP for + * making scheduler aware of a service added to UE + * + * Invoked by: BO and Scheduler + * + * @param[in] RgSchUeCb* ue + * @param[in] RgSchDlLcCb* svc + * @param[in] CrgDlLchCfg* qos + * @return Void + * + **/ +#ifdef ANSI +PRIVATE Void rgSCHSc1DlSvcAdd +( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgSchDlLcCb *svc, +RgrDlLchCfg *cfg +) +#else +PRIVATE Void rgSCHSc1DlSvcAdd(cell, ue, svc, cfg) +RgSchCellCb *cell; +RgSchUeCb *ue; +RgSchDlLcCb *svc; +RgrDlLchCfg *cfg; +#endif +{ + RgSchSc1DlUe *ueDl = RG_GET_SC1_UE_DL(ue, cell); + RgSchSc1DlSvc *svcSc1 = RG_GET_SC1_SVC_DL(ue,svc,cell); + RgSchCmnDlSvc *svcCmn = RG_SCH_CMN_GET_DL_SVC(svc); + TRC2(rgSCHSc1DlSvcAdd); + + UNUSED(cfg); + + if (RG_SCH_CMN_SVC_IS_GBR(svc)) + { + svcSc1->gbr = svcCmn->gbr; + svcSc1->mbr = svcCmn->mbr; + cmLListAdd2Tail(&ueDl->gbrSvcs, &svcSc1->gbrLnk); + svcSc1->gbrLnk.node = (PTR)svc; + } + RETVOID; +} + + +/** + * @brief This function deletes a service from scheduler + * + * @details + * + * Function: rgSCHSc1DlLcRmv + * Purpose: This function is made available through a FP for + * making scheduler aware of a service being deleted from UE + * + * Invoked by: BO and Scheduler + * + * @param[in] RgSchCellCb* cell + * @param[in] RgSchUeCb* ue + * @param[in] RgSchDlLcCb* svc + * @return Void + * + **/ +#ifdef ANSI +PUBLIC Void rgSCHSc1DlLcRmv +( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgSchDlLcCb *svc +) +#else +PUBLIC Void rgSCHSc1DlLcRmv(cell, ue, svc) +RgSchCellCb *cell; +RgSchUeCb *ue; +RgSchDlLcCb *svc; +#endif +{ + RgSchSc1DlUe *ueDl; + RgSchSc1DlSvc *svcSc1 = RG_GET_SC1_SVC_DL(ue,svc,cell); + RgSchCmnDlSvc *svcCmn = RG_SCH_CMN_GET_DL_SVC(svc); + + TRC2(rgSCHSc1DlLcRmv); + + if (svcSc1 == NULLP) + { + RETVOID; + } + ueDl = RG_GET_SC1_UE_DL(ue, cell); + + if (svcCmn->prio == 0) + { + rgSCHSc1DlSvcRmvFrmSchd(cell, svc); + } + else if (RG_SCH_CMN_SVC_IS_GBR(svc)) + { + if (svcSc1->gbrLnk.node != NULLP) + { + cmLListDelFrm(&ueDl->gbrSvcs, &svcSc1->gbrLnk); + svcSc1->gbrLnk.node = NULLP; + } + rgSCHSc1DlSvcRmvFrmSchd(cell, svc); + } + else /* if AMBR service */ + { + if (ueDl->ambrSvc == svc) + { + rgSCHSc1DlUeRmvFrmSchd(cell, ue); + rgSCHSc1DlSvcRmvFrmUeAmbrLst(cell, ue, svc); + ueDl->ambrSvc = NULLP; + if (ueDl->ambrLst.first != NULLP) + { + ueDl->ambrSvc = (RgSchDlLcCb *)(ueDl->ambrLst.first->node); + ueDl->effAmbr = RGSCH_MIN(ueDl->ambr, svc->bo); + if(ueDl->effAmbr) + { + rgSCHSc1DlUeAddToSchd(cell, ue); + } + } + } + else + { + rgSCHSc1DlSvcRmvFrmUeAmbrLst(cell, ue, svc); + } + } + /* ccpu00117052 - MOD - Passing double pointer + for proper NULLP assignment*/ + rgSCHUtlFreeSBuf(cell->instIdx, + (Data**)(&(RG_SCH_CMN_GET_LC_SCH_SPFC(ue,svc,cell))), (sizeof(RgSchSc1DlSvc))); + RETVOID; +} + +/** + * @brief This function is invoked as part of SVC reconfig + * + * @details + * + * Function: rgSCHSc1DlSvcMod + * Purpose: This function is made available through a FP for + * making scheduler aware of a service reconfiguration. + * + * Invoked by: Scheduler + * + * @param[in] RgSchDlLcCb* svc + * @param[in] CrgLchRecfg* recfg + * @return Void + * + **/ +#ifdef ANSI +PRIVATE Void rgSCHSc1DlSvcMod +( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgSchDlLcCb *svc, +RgrLchRecfg *recfg +) +#else +PRIVATE Void rgSCHSc1DlSvcMod(cell,ue,svc, recfg) +RgSchCellCb *cell; +RgSchUeCb *ue; +RgSchDlLcCb *svc; +RgrLchRecfg *recfg; +#endif +{ + RgSchSc1DlSvc *svcSc1 = RG_GET_SC1_SVC_DL(ue,svc,cell); + RgSchCmnDlSvc *svcCmn = RG_SCH_CMN_GET_DL_SVC(svc); + TRC2(rgSCHSc1DlSvcMod); + + if (RG_SCH_CMN_SVC_IS_GBR(svc)) + { + /* Convert the QOS to handle the refresh duration */ + svcSc1->gbr = svcCmn->gbr; + svcSc1->mbr = svcCmn->mbr; + } + RETVOID; +} + +/** + * @brief This function adds UE to scheduler for an AMBR service + * + * @details + * + * Function: rgSCHSc1DlUeAddToSchd + * Purpose: This function adds a UE to scheduler for the AMBR + * service of highest priority. + * + * Invoked by: BO and Scheduler + * + * @param[in] RgSchCellCb* cell + * @param[in] RgSchUeCb* ue + * @return Void + * + **/ +#ifdef ANSI +PRIVATE Void rgSCHSc1DlUeAddToSchd +( +RgSchCellCb *cell, +RgSchUeCb *ue +) +#else +PRIVATE Void rgSCHSc1DlUeAddToSchd(cell, ue) +RgSchCellCb *cell; +RgSchUeCb *ue; +#endif +{ + RgSchSc1DlCell *cellDl = RG_GET_SC1_CELL_DL(cell); + RgSchSc1DlUe *ueDl = RG_GET_SC1_UE_DL(ue, cell); + RgSchSc1DlUe *lueDl; + CmLList *node; + CmLListCp *lst; + RgSchUeCb *nodeUe = NULLP; + TRC2(rgSCHSc1DlUeAddToSchd); + + ueDl->prio = ((RgSchCmnDlSvc *)(ueDl->ambrSvc->sch))->prio; + lst = &cellDl->prioLst[ueDl->prio]; + /* if UE already in list, remove and + * readjust */ + if (ueDl->prioLnk.node != NULLP) + { + cmLListDelFrm(lst, &ueDl->prioLnk); + ueDl->prioLnk.node = NULLP; + /* If a svc is removed from cell wide priority Qs + * then remove the same from UE's lcsWithData List */ + rgSCHSc1DlRmFrmUeLcsWithData(cell, ue, ueDl->ambrSvc); + } + node = lst->first; + while(node) + { + nodeUe = (RgSchUeCb *)(node->node); + lueDl = RG_GET_SC1_UE_DL(nodeUe, cell); + if (lueDl->effAmbr < ueDl->effAmbr) + break; + node = node->next; + } + if (node == NULLP) + { + cmLListAdd2Tail(lst, &ueDl->prioLnk); + ueDl->prioLnk.node = (PTR)ue; + } + else + { + lst->crnt = node; + cmLListInsCrnt(lst, &ueDl->prioLnk); + ueDl->prioLnk.node = (PTR)ue; + } + /* If a svc is put in to cell wide priority Qs + * then add the same to UE's lcsWithData List */ + rgSCHSc1DlAdd2UeLcsWithData(cell, ue, ueDl->ambrSvc); + RETVOID; +} + + +/** + * @brief This function implements managing BO for an ABMR service + * + * @details + * + * Function: rgSCHSc1DlMngAmbrSvcPosn + * Purpose: This function should be called whenever there is a + * change BO for a AMBR service. + * + * Invoked by: BO and Scheduler + * + * @param[in] RgSchCellCb* cell + * @param[in] RgSchUeCb* ue + * @param[in] RgSchDlLcCb* svc + * @return Void + * + **/ +#ifdef ANSI +PRIVATE Void rgSCHSc1DlMngAmbrSvcPosn +( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgSchDlLcCb *svc +) +#else +PRIVATE Void rgSCHSc1DlMngAmbrSvcPosn(cell, ue, svc) +RgSchCellCb *cell; +RgSchUeCb *ue; +RgSchDlLcCb *svc; +#endif +{ + RgSchSc1DlUe *ueDl = RG_GET_SC1_UE_DL(ue, cell); + RgSchSc1DlSvc *svcSc1 = RG_GET_SC1_SVC_DL(ue,svc,cell); + + TRC2(rgSCHSc1DlMngAmbrSvcPosn); + + if (svcSc1->bo == 0) + { + if (ueDl->ambrSvc == svc) + { + rgSCHSc1DlUeRmvFrmSchd(cell, ue); + rgSCHSc1DlSvcRmvFrmUeAmbrLst(cell, ue, svc); + ueDl->ambrSvc = NULLP; + if (ueDl->ambrLst.first != NULLP) + { + ueDl->ambrSvc = (RgSchDlLcCb *)(ueDl->ambrLst.first->node); + ueDl->effAmbr = RGSCH_MIN(ueDl->ambr, svcSc1->bo); + if(ueDl->effAmbr) + { + rgSCHSc1DlUeAddToSchd(cell, ue); + } + } + } + else + { + rgSCHSc1DlSvcRmvFrmUeAmbrLst(cell, ue, svc); + } + } + else /* svcSc1->bo != 0 */ + { + if (svcSc1->prioLnk.node != NULLP) + { + if (svc == ueDl->ambrSvc) + { + ueDl->effAmbr = RGSCH_MIN(svcSc1->bo, ueDl->ambr); + /* Update UE's position in the scheduler */ + if(ueDl->effAmbr) + { + rgSCHSc1DlUeAddToSchd(cell, ue); + } + else + { + rgSCHSc1DlUeRmvFrmSchd(cell, ue); + } + } + RETVOID; + } + rgSCHSc1DlSvcAddToUeAmbrLst(cell, ue, svc); + /* Current ambr svc is always the first node of ambrLst.*/ + if (ueDl->ambrLst.first->node == (PTR)svc) + { + if(ueDl->ambrSvc != svc) + { + if(ueDl->ambrSvc) + { + rgSCHSc1DlUeRmvFrmSchd(cell, ue); + } + ueDl->ambrSvc = svc; + ueDl->effAmbr = RGSCH_MIN(ueDl->ambr, svcSc1->bo); + if(ueDl->effAmbr) + { + rgSCHSc1DlUeAddToSchd(cell, ue); + } + } + } + } + RETVOID; +} + + +/** + * @brief This function updates the scheduler with service for a UE + * + * @details + * + * Function: rgSCHSc1DlLcBoUpd + * Purpose: This function should be called whenever there is a + * change BO for a service. + * + * Invoked by: BO and Scheduler + * + * @param[in] RgSchCellCb* cell + * @param[in] RgSchUeCb* ue + * @param[in] RgSchDlLcCb* svc + * @return Void + * + **/ +#ifdef ANSI +PUBLIC Void rgSCHSc1DlLcBoUpd +( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgSchDlLcCb *svc +) +#else +PUBLIC Void rgSCHSc1DlLcBoUpd(cell, ue, svc) +RgSchCellCb *cell; +RgSchUeCb *ue; +RgSchDlLcCb *svc; +#endif +{ + RgSchSc1DlSvc *svcSc1 = RG_GET_SC1_SVC_DL(ue,svc,cell); + TRC2(rgSCHSc1DlLcBoUpd); + + if (svcSc1->bo == svc->bo) + { + RETVOID; + } + svcSc1->bo = svc->bo; + if (!RG_SCH_CMN_DL_IS_UE_ACTIVE(ue)) + { + RETVOID; + } + rgSCHSc1DlMngSvcPosn(cell, ue, svc); + + /* Stack Crash problem for TRACE5 changes. Added the return below */ + RETVOID; + +} + + +/** + * @brief This function updates the scheduler with Prio0 service for a UE + * + * @details + * + * Function: rgSCHSc1DlMngPrio0SvcPosn + * Purpose: This func shall be triggered whenever there is a + * change in the "Bo yet to be satisfied" field of the service. + * Appropriately positions the svc in its prio Q. + * Removes the SVC from the Q if BO is completely satisfied. + * + * Invoked by: BO and Scheduler + * + * @param[in] RgSchCellCb* cell + * @param[in] RgSchUeCb* ue + * @param[in] RgSchDlLcCb* svc + * @return Void + * + **/ +#ifdef ANSI +PRIVATE Void rgSCHSc1DlMngPrio0SvcPosn +( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgSchDlLcCb *svc +) +#else +PRIVATE Void rgSCHSc1DlMngPrio0SvcPosn(cell, ue, svc) +RgSchCellCb *cell; +RgSchUeCb *ue; +RgSchDlLcCb *svc; +#endif +{ + RgSchSc1DlSvc *svcSc1 = RG_GET_SC1_SVC_DL(ue,svc,cell); + TRC2(rgSCHSc1DlMngPrio0SvcPosn); + + /* In this priority, we just add or remove to the queue */ + if (svcSc1->bo > 0) + { + rgSCHSc1DlSvcAddToSchd(cell, svc); + } + else + { + rgSCHSc1DlSvcRmvFrmSchd(cell, svc); + } + RETVOID; +} + + +/** + * @brief This function updates the scheduler with GBR service for a UE + * + * @details + * + * Function: rgSCHSc1DlMngGbrSvcPosn + * Purpose: This func shall be triggered whenever there is a + * change in the "Bo yet to be satisfied" field of the service. + * Appropriately positions the svc in its prio Q. + * Removes the SVC from the Q if BO is completely satisfied. + * + * Invoked by: BO and Scheduler + * + * @param[in] RgSchCellCb* cell + * @param[in] RgSchUeCb* ue + * @param[in] RgSchDlLcCb* svc + * @return Void + * + **/ +#ifdef ANSI +PRIVATE Void rgSCHSc1DlMngGbrSvcPosn +( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgSchDlLcCb *svc +) +#else +PRIVATE Void rgSCHSc1DlMngGbrSvcPosn(cell, ue, svc) +RgSchCellCb *cell; +RgSchUeCb *ue; +RgSchDlLcCb *svc; +#endif +{ + RgSchSc1DlSvc *svcSc1 = RG_GET_SC1_SVC_DL(ue,svc,cell); + TRC2(rgSCHSc1DlMngGbrSvcPosn); + + /* Handle a GBR service. */ + svcSc1->effGbr = RGSCH_MIN(svcSc1->bo, svcSc1->gbr); + svcSc1->effMbr = RGSCH_MIN(svcSc1->bo, svcSc1->mbr); + /* Adjust the SVC priority within the queue */ + rgSCHSc1DlSvcRmvFrmSchd(cell, svc); + rgSCHSc1DlSvcAddToSchd(cell, svc); + RETVOID; +} + + +/** + * @brief This function updates the scheduler with service for a UE + * + * @details + * + * Function: rgSCHSc1DlMngSvcPosn + * Purpose: This func shall be triggered whenever there is a + * change in the "Bo yet to be satisfied" field of the service. + * Appropriately positions the svc in its prio Q. + * Removes the SVC from the Q if BO is completely satisfied. + * + * Invoked by: BO and Scheduler + * + * @param[in] RgSchCellCb* cell + * @param[in] RgSchUeCb* ue + * @param[in] RgSchDlLcCb* svc + * @return Void + * + **/ +#ifdef ANSI +PRIVATE Void rgSCHSc1DlMngSvcPosn +( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgSchDlLcCb *svc +) +#else +PRIVATE Void rgSCHSc1DlMngSvcPosn(cell, ue, svc) +RgSchCellCb *cell; +RgSchUeCb *ue; +RgSchDlLcCb *svc; +#endif +{ + RgSchCmnDlSvc *svcCmn = RG_SCH_CMN_GET_DL_SVC(svc); + RgSchSc1DlCell *cellDl = RG_GET_SC1_CELL_DL(cell); + TRC2(rgSCHSc1DlMngSvcPosn); + + (cellDl->svcMngFunc[svcCmn->prio])(cell, ue, svc); + RETVOID; +} + +/*--------------------------* + * DL specific functions END + *---------------------------*/ + + + +/** + * @brief Scheduler processing on cell configuration + * + * @details + * + * Function : rgSCHSc1RgrDlCellCfg + * + * This function does requisite initialisation + * and setup for scheduler1 when a cell is + * configured + * + * @param[in] RgSchCellCb *cell + * @param[in] RgrCellCfg *cellCfg + * @param[out] RgSchErrInfo *err + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 rgSCHSc1RgrDlCellCfg +( +RgSchCellCb *cell, +RgrCellCfg *cellCfg, +RgSchErrInfo *err +) +#else +PUBLIC S16 rgSCHSc1RgrDlCellCfg(cell, cellCfg, err) +RgSchCellCb *cell; +RgrCellCfg *cellCfg; +RgSchErrInfo *err; +#endif +{ + S16 ret; + RgSchSc1DlCell *cellDl; + + TRC2(rgSCHSc1RgrDlCellCfg); + + if((ret = rgSCHUtlAllocSBuf(cell->instIdx, + (Data**)&(((RgSchCmnCell*)((cell)->sc.sch))->dl.schSpfc), \ + (sizeof(RgSchSc1DlCell)))) != ROK) + { + RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId, + "Memory allocation FAILED"); + err->errCause = RGSCHERR_SCH_SC1_DL_CFG; + RETVALUE(ret); + } + + cellDl = RG_GET_SC1_CELL_DL(cell); + /* Now perform downlink Queues related initializations */ + rgSCHSc1DlInitQueues(cellDl); + RETVALUE(ROK); +} /* rgSCHSc1RgrDlCellCfg */ + +/*********************************************************** + * + * Func : rgSCHSc1DlDeinitQueues + * + * Desc : De-initialise downlink scheduler queues + * + * Ret : Void + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PRIVATE Void rgSCHSc1DlDeinitQueues +( +RgSchSc1DlCell *cellDl +) +#else +PRIVATE Void rgSCHSc1DlDeinitQueues(cellDl) +RgSchSc1DlCell *cellDl; +#endif +{ + U8 i; + TRC2(rgSCHSc1DlDeinitQueues); + + for (i = 0; i < RG_SC1_DL_NUM_Q; ++i) + { + cmLListInit(&cellDl->prioLst[i]); + cmLListInit(&cellDl->retxLst[i]); + } + RETVOID; +} + + +/** + * @brief Scheduler processing for cell delete + * + * @details + * + * Function : rgSCHSc1DlCellDel + * + * This functions de-initialises and frees memory + * taken up by scheduler1 for the entire cell. + * + * @param[in] RgSchCellCb *cell + * @return Void + **/ +#ifdef ANSI +PUBLIC Void rgSCHSc1DlCellDel +( +RgSchCellCb *cell +) +#else +PUBLIC Void rgSCHSc1DlCellDel(cell) +RgSchCellCb *cell; +#endif +{ + TRC2(rgSCHSc1DlCellDel); + + if (((RgSchSc1DlCell *)((RgSchCmnCell*)((cell)->sc.sch))->dl.schSpfc) \ + == NULLP) + { + RETVOID; + } + + /* Perform the deinit for the DL scheduler */ + rgSCHSc1DlDeinitQueues(RG_GET_SC1_CELL_DL(cell)); + /* ccpu00117052 - MOD - Passing double pointer + for proper NULLP assignment*/ + rgSCHUtlFreeSBuf(cell->instIdx, + (Data**)(&(((RgSchCmnCell*)((cell)->sc.sch))->dl.schSpfc)), + (sizeof(RgSchSc1DlCell))); + RETVOID; +} /* rgSCHSc1DlCellDel */ + +/** + * @brief UE initialisation for scheduler + * + * @details + * + * Function : rgSCHSc1RgrDlUeCfg + * + * This functions intialises UE specific scheduler + * information + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ue + * @param[int] RgrUeCfg *ueCfg + * @param[out] RgSchErrInfo *err + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 rgSCHSc1RgrDlUeCfg +( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgrUeCfg *ueCfg, +RgSchErrInfo *err +) +#else +PUBLIC S16 rgSCHSc1RgrDlUeCfg(cell, ue, ueCfg, err) +RgSchCellCb *cell; +RgSchUeCb *ue; +RgrUeCfg *ueCfg; +RgSchErrInfo *err; +#endif +{ + RgSchCmnUe *ueSchCmn = RG_SCH_CMN_GET_UE(ue, cell); + Inst inst = cell->instIdx; + RgSchSc1DlUe *ueDl; + + TRC2(rgSCHSc1RgrDlUeCfg); + + if((rgSCHUtlAllocSBuf(inst, + (Data**)&(ueSchCmn->dl.schSpfc), (sizeof(RgSchSc1DlUe))) != ROK)) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId, "Memory allocation FAILED" + "CRNTI:%d",ue->ueId); + err->errCause = RGSCHERR_SCH_SC1_DL_CFG; + RETVALUE(RFAILED); + } + ueDl = (RgSchSc1DlUe *)ueSchCmn->dl.schSpfc; + if (ue->dl.ambrCfgd) + { + ueDl->ambr = ue->dl.ambrCfgd; + } + else + { + ueDl->ambr = RG_SC1_MAX_DL_AMBR; + } + cmLListInit(&ueDl->lcsWithData); + cmLListInit(&ueDl->gbrSvcs); + cmLListInit(&ueDl->ambrLst); + cmLListInit(&ueDl->schdSvcs); + cmLListInit(&ueDl->retxHqProcs); + RETVALUE(ROK); +} /* rgSCHSc1RgrDlUeCfg */ + + +/** + * @brief Dl Harq Entity initialization for SC1 + * + * @details + * + * Function : rgSCHSc1DlUeHqEntInit + * + * Processing Steps: + * - Create SC1 related information per Harq Entity + * + * @param[in] RgrSchCellCb *cell + * @param[in] RgSchUeCb *ue + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 rgSCHSc1DlUeHqEntInit +( + RgSchCellCb *cell, + RgSchDlHqEnt *hqEnt + ) +#else +PUBLIC S16 rgSCHSc1DlUeHqEntInit(cell, hqEnt) + RgSchCellCb *cell; + RgSchDlHqEnt *hqEnt +#endif +{ + RgSchSc1DlHqProc *hqSpcSch; + RgSchDlHqProcCb *hqP; + U8 cnt; + TRC2(rgSCHSc1DlUeHqEntInit); + /* making use of hqE->sch for one shot allocation + * of RgSchSc1DlHqProc structures */ + if (rgSCHUtlAllocSBuf(cell->instIdx, + (Data**)&(hqEnt->sch), + (hqEnt->numHqPrcs * sizeof(RgSchSc1DlHqProc))) != ROK) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId, + "Memory allocation FAILED CRNTI:%d",hqEnt->ue->ueId); + RETVALUE(RFAILED); + } + hqSpcSch = (RgSchSc1DlHqProc *)(hqEnt->sch); + for(cnt = 0; cnt < hqEnt->numHqPrcs; cnt++) + { + hqP = &hqEnt->procs[cnt]; + ((RgSchCmnDlHqProc *)((hqP)->sch))->schSpfc = \ + hqSpcSch++; + } + RETVALUE(ROK); +} + +/** + * @brief Dl Harq Entity deletion for Sc1 + * + * @details + * + * Function : rgSCHSc1DlUeHqEntDeInit + * + * Processing Steps: + * - Free SC1 related information per Harq Entity + * + * @param[in] RgrSchCellCb *cell + * @param[in] RgSchDlHqEnt *hqE + * @return Void + **/ +#ifdef ANSI +PUBLIC S16 rgSCHSc1DlUeHqEntDeInit +( +RgSchCellCb *cell, +RgSchDlHqEnt *hqE +) +#else +PUBLIC S16 rgSCHSc1DlUeHqEntDeInit(cell, hqE) +RgSchCellCb *cell; +RgSchDlHqEnt *hqE; +#endif +{ + TRC2(rgSCHSc1DlUeHqEntDeInit); + + if(hqE->sch) + { + rgSCHUtlFreeSBuf(cell->instIdx, + (Data**)(&(hqE->sch)), + (hqE->numHqPrcs * sizeof(RgSchSc1DlHqProc))); + } + else + { + RETVALUE(RFAILED); + } + RETVALUE(ROK); +} +/** + * @brief UE reconfiguration for scheduler + * + * @details + * + * Function : rgSCHSc1RgrDlUeRecfg + * + * This functions updates UE specific scheduler + * information upon UE reconfiguration + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ue + * @param[int] RgrUeRecfg *ueRecfg + * @param[out] RgSchErrInfo *err + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 rgSCHSc1RgrDlUeRecfg +( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgrUeRecfg *ueRecfg, +RgSchErrInfo *err +) +#else +PUBLIC S16 rgSCHSc1RgrDlUeRecfg(cell, ue, ueRecfg, err) +RgSchCellCb *cell; +RgSchUeCb *ue; +RgrUeRecfg *ueRecfg; +RgSchErrInfo *err; +#endif +{ + RgSchSc1DlUe *ueDl = RG_GET_SC1_UE_DL(ue, cell); + RgSchCmnDlUe *ueCmnDl = RG_SCH_CMN_GET_DL_UE(ue,cell); + /*cell added as part of CA dev*/ + RgSchDlHqEnt *hqEnt = RG_SCH_CMN_GET_UE_HQE(ue, cell); + TRC2(rgSCHSc1RgrDlUeRecfg); + + if (ue->dl.ambrCfgd) + { + ueDl->ambr = ue->dl.ambrCfgd; + } + else + { + ueDl->ambr = RG_SC1_MAX_DL_AMBR; + } + + /* Discarding TB2's context from scheduling Queues. + * Since TB2 transmission needs signalling using + * TM specific formats. And since during this transient + * period of UE TM Recfg, SCH always uses Format 1A, + * the TB2s are discarded. */ + if (ueCmnDl->mimoInfo.forceTD & RG_SCH_CMN_TD_TXMODE_RECFG) + { + /* If HqP is in retx queue only for TB2 retx scheduling + * then remove the harp proc from retx Queue */ + + /* If Hqp is in retx queue for retx allocation of + * both TB1 and TB2, then reset TB2's state as ACKED */ + RgSchDlHqProcCb *hqP; + Pst pst; + RgInfRlsHqInfo *rlsHqBufs = &(cell->rlsHqArr[cell->crntHqIdx]); + U8 i; + + /* Prepare TB2 release information to be sent to MAC */ + rlsHqBufs->numUes = 0; + for(i = 0; i < hqEnt->numHqPrcs; i++) + { + hqP = &hqEnt->procs[i]; + rlsHqBufs->ueHqInfo[rlsHqBufs->numUes].rnti = ue->ueId; + rlsHqBufs->ueHqInfo[rlsHqBufs->numUes].hqProcId = hqP->procId; + if (hqP->tbInfo[1].state == HQ_TB_NACKED) + { + if (hqP->tbInfo[0].state != HQ_TB_NACKED) + { + /* Remove the HqP from retx Queue. + Release HqP.*/ + rgSCHSc1DlProcRmvFrmCellRetx(cell, hqP); + rgSCHSc1DlProcRmvFrmUeRetx(cell, ue, hqP); + } + rgSCHDhmRlsHqpTb(hqP, 1, TRUE); + rlsHqBufs->ueHqInfo[rlsHqBufs->numUes].tbId[0] = 2; + rlsHqBufs->ueHqInfo[rlsHqBufs->numUes].numOfTBs = 1; + } + rlsHqBufs->numUes++; + } + /* Send the hqProc list for MAC to clear TB1 contents */ + if (rlsHqBufs->numUes) + { + rgSCHUtlGetPstToLyr(&pst, &rgSchCb[cell->instIdx], cell->macInst); + RgSchMacRlsHq (&pst, rlsHqBufs); + } + } + RETVALUE(ROK); +} /* rgSCHSc1RgrDlUeRecfg */ + +/** + * @brief Removes UEs context from Priority Qs. + * + * @details + * + * Function : rgSCHSc1DlRmvUeFrmPrioQs + * + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ue + * @return Void + **/ +#ifdef ANSI +PRIVATE Void rgSCHSc1DlRmvUeFrmPrioQs +( +RgSchCellCb *cell, +RgSchUeCb *ue +) +#else +PRIVATE Void rgSCHSc1DlRmvUeFrmPrioQs(cell, ue) +RgSchCellCb *cell; +RgSchUeCb *ue; +#endif +{ + RgSchSc1DlUe *sc1Ue; + RgSchDlLcCb *svc; + U32 idx; + + TRC2(rgSCHSc1DlRmvUeFrmPrioQs); + + sc1Ue = RG_GET_SC1_UE_DL(ue, cell); + + /* Remove UE From DL priority queues */ + if (sc1Ue->ambrSvc != NULLP) + { + rgSCHSc1DlUeRmvFrmSchd(cell, ue); + } + + for (idx = 0; idx < RGSCH_MAX_LC_PER_UE; ++idx) + { + svc = ue->dl.lcCb[idx]; + if (svc == NULLP) + { + continue; + } + rgSCHSc1DlSvcRmvFrmSchd(cell, svc); + } + + RETVOID; +} /* rgSCHSc1DlRmvUeFrmPrioQs */ + +/** + * @brief Inactivate UE reason : measgap, acknaprept, poInactv. + * + * @details + * + * Function : rgSCHSc1DlInactvtUe + * + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ue + * @return Void + **/ +#ifdef ANSI +PRIVATE Void rgSCHSc1DlInactvtUe +( +RgSchCellCb *cell, +RgSchUeCb *ue +) +#else +PRIVATE Void rgSCHSc1DlInactvtUe(cell, ue) +RgSchCellCb *cell; +RgSchUeCb *ue; +#endif +{ + RgSchSc1DlCell *cellDl = RG_GET_SC1_CELL_DL(cell); + RgSchDlHqProcCb *hqP; + RgSchCmnDlHqProc *hqProcDl; + U8 i; + RgSchDlHqEnt *hqEnt = RG_SCH_CMN_GET_UE_HQE(ue, cell); + + TRC2(rgSCHSc1DlInactvtUe); + + /* ccpu00130170: UE related HARQ Procs are cleared only + if UE's Re-establishment procedure is not in progress*/ + if(!(ue->dl.dlInactvMask & RG_HQENT_INACTIVE)) + { + /* remove all in use HARQ processes from the subframes. + * Store them in UEs hqProc Lst. Add back to cell's + * retx lst when UE is activated again. */ + for(i = 0; i < hqEnt->numHqPrcs; i++) + { + hqP = &hqEnt->procs[i]; + hqProcDl = RG_SCH_CMN_GET_DL_HQP(hqP); + /* Remove retx procs from cell's list and + * add them to UE's List */ + if( +#ifdef LTEMAC_SPS + !(RG_SCH_CMN_SPS_DL_IS_SPS_HQP(hqP)) && +#endif + hqProcDl->retxLnk.node != NULLP) + { + cmLListDelFrm(&cellDl->retxLst[((RgSchSc1DlHqProc *)\ + (hqProcDl->schSpfc))->prio], &(hqProcDl->retxLnk)); + hqProcDl->retxLnk.node = NULLP; + rgSCHSc1DlProcAddToUeRetx(cell, ue, hqP); + } + } + } + + rgSCHSc1DlRmvUeFrmPrioQs(cell, ue); + + RETVOID; +} /* rgSCHSc1DlInactvtUe */ + + +/** + * @brief UE suspension. + * + * @details + * + * Function : rgSCHSc1DlSuspendUe + * + * Removes UE, its SVCs and its HqPs from CELL WIDE + * PrioQs and Retx Qs Respectively. + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ue + * @return Void + **/ +#ifdef ANSI +PRIVATE Void rgSCHSc1DlSuspendUe +( +RgSchCellCb *cell, +RgSchUeCb *ue +) +#else +PRIVATE Void rgSCHSc1DlSuspendUe(cell, ue) +RgSchCellCb *cell; +RgSchUeCb *ue; +#endif +{ + RgSchDlHqProcCb *hqP; + U8 i; + U8 j; + RgSchDlHqEnt *hqEnt = RG_SCH_CMN_GET_UE_HQE(ue, cell); + + TRC2(rgSCHSc1DlSuspendUe); + + /* remove all in use HARQ processes from the subframes. + * Store them in UEs hqProc Lst. Add back to cell's + * retx lst when UE is activated again. */ + for(i = 0; i < hqEnt->numHqPrcs; i++) + { + hqP = &hqEnt->procs[i]; + rgSCHSc1DlProcRmvFrmCellRetx(cell, hqP); + rgSCHSc1DlProcRmvFrmUeRetx(cell, ue, hqP); + /* Removing the Harq Proc from subframes list */ + if (hqP->hqPSfLnk.node != NULLP) + { + if (hqP->pdcch ) + { + cmLListDelFrm(&hqP->subFrm->pdcchInfo.pdcchs, + &hqP->pdcch->lnk); + cmLListAdd2Tail(&cell->pdcchLst, &hqP->pdcch->lnk); + hqP->pdcch = NULLP; + } + /*CA DEV Start */ + rgSCHUtlDlHqPTbRmvFrmTx(hqP->subFrm,hqP,0,FALSE); + /*CA DEV End*/ + for (j = 0; j < 2; j++) + { + if (hqP->tbInfo[j].state == HQ_TB_WAITING) + { + rgSCHDhmRlsHqpTb(hqP, j, TRUE); + } + } + } + } + rgSCHSc1DlRmvUeFrmPrioQs(cell, ue); + + RETVOID; +} /* rgSCHSc1DlSuspendUe */ + +/*********************************************************** + * + * Func : rgSCHSc1DlScanUpdPdbPrio + * + * Desc : Increment the pivot and reposition the LCs under the pivot to + * new location according to thieir PDB and elapsed time. + * + * Ret : Void + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PUBLIC Void rgSCHSc1DlScanUpdPdbPrio +( +RgSchCellCb *cell +) +#else +PUBLIC Void rgSCHSc1DlScanUpdPdbPrio (cell) +RgSchCellCb *cell; +#endif +{ + TRC2(rgSCHSc1DlScanUpdPdbPrio); + + RETVOID; +} + +/** + * @brief Function to update Flow control information + * to be sent to MAC. + * + * @details + * + * Function: rgSCHSc1DlFillFlowCntrlInfo + * + * update Flow control information + * + * Invoked by: + * SCHD + * + * Processing Steps: + * + * @param[in] RgSchCellCb *cell + RgInfSfAlloc *sfAlloc; + * @return S16 + * -# ROK + **/ +#ifdef ANSI +PUBLIC S16 rgSCHSc1DlFillFlowCntrlInfo +( +RgSchCellCb *cell, +RgInfSfAlloc *sfAlloc +) +#else +PUBLIC S16 rgSCHSc1DlFillFlowCntrlInfo(cell,sfAlloc) +RgSchCellCb *cell; +RgInfSfAlloc *sfAlloc; +#endif +{ + TRC2(rgSCHSc1DlFillFlowCntrlInfo); + RETVALUE(ROK); +} +/** + * @brief UE deletion for scheduler + * + * @details + * + * Function : rgSCHSc1DlUeDel + * + * This functions deletes all scheduler information + * pertaining to a UE + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ue + * @return Void + **/ +#ifdef ANSI +PUBLIC Void rgSCHSc1DlUeDel +( +RgSchCellCb *cell, +RgSchUeCb *ue +) +#else +PUBLIC Void rgSCHSc1DlUeDel(cell, ue) +RgSchCellCb *cell; +RgSchUeCb *ue; +#endif +{ + RgSchDlHqEnt *hqEnt = RG_SCH_CMN_GET_UE_HQE(ue, cell); + RgSchSc1DlUe *sc1DlUe = RG_GET_SC1_UE_DL(ue, cell); + + TRC2(rgSCHSc1DlUeDel); + + if (sc1DlUe == NULLP) + { + RETVOID; + } + if( hqEnt) + { + /* Remove UEs scheduler context */ + rgSCHSc1DlSuspendUe(cell, ue); + + /* Free all SC1 specific control blocks */ + if (hqEnt->sch != NULLP) + { + /* ccpu00117052 - MOD - Passing double pointer + for proper NULLP assignment*/ + rgSCHUtlFreeSBuf(cell->instIdx, + (Data**)(&(hqEnt->sch)), + (hqEnt->numHqPrcs * sizeof(RgSchSc1DlHqProc))); + } + } + + /* ccpu00117052 - MOD - Passing double pointer + for proper NULLP assignment*/ + rgSCHUtlFreeSBuf(cell->instIdx, (Data**)(&sc1DlUe), (sizeof(RgSchSc1DlUe))); + + RETVOID; +} /* rgSCHSc1DlUeDel */ + +/** + * @brief Scheduler invocation on Downlink logical channel addition + * + * @details + * + * Function : rgSCHSc1RgrLcCfg + * + * This functions does required processing when a new + * (dedicated) logical channel is added. + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ue + * @param[in] RgSchDlLcCb *dlLc + * @param[int] RgrLchCfg *lcCfg + * @param[out] RgSchErrInfo *err + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 rgSCHSc1RgrLcCfg +( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgSchDlLcCb *dlLc, +RgrLchCfg *lcCfg, +RgSchErrInfo *err +) +#else +PUBLIC S16 rgSCHSc1RgrLcCfg(cell, ue, dlLc, lcCfg, err) +RgSchCellCb *cell; +RgSchUeCb *ue; +RgSchDlLcCb *dlLc; +RgrLchCfg *lcCfg; +RgSchErrInfo *err; +#endif +{ + S16 ret; + TRC2(rgSCHSc1RgrLcCfg); + + ret = rgSCHUtlAllocSBuf(cell->instIdx, + (Data**)&(RG_SCH_CMN_GET_LC_SCH_SPFC(ue,dlLc,cell)), \ + (sizeof(RgSchSc1DlSvc))); + if (ret != ROK) + { + RLOG_ARG2(L_ERROR,DBG_CELLID,cell->cellId, "rgSCHSc1CrgLcCfg():" + "SCH struct alloc failed CRNTI:%d LCID:%d",ue->ueId,lcCfg->lcId); + err->errCause = RGSCHERR_SCH_SC1_DL_CFG; + RETVALUE(ret); + } + + rgSCHSc1DlSvcAdd(cell, ue, dlLc, &lcCfg->dlInfo); + RETVALUE(ROK); +} /* rgSCHSc1RgrLcCfg */ + + +/** + * @brief Scheduler invocation on logical channel addition + * + * @details + * + * Function : rgSCHSc1RgrLcRecfg + * + * This functions does required processing when an existing + * (dedicated) logical channel is reconfigured. Assumes lcg + * pointer in ulLc is set to the old value. + * Independent of whether new LCG is meant to be configured, + * the new LCG scheduler info is accessed and possibly modified. + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ue + * @param[in] RgSchDlLcCb *dlLc + * @param[int] RgrLchRecfg *lcRecfg + * @param[out] RgSchErrInfo *err + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 rgSCHSc1RgrLcRecfg +( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgSchDlLcCb *dlLc, +RgrLchRecfg *lcRecfg, +RgSchErrInfo *err +) +#else +PUBLIC S16 rgSCHSc1RgrLcRecfg(cell, ue, dlLc, lcRecfg, err) +RgSchCellCb *cell; +RgSchUeCb *ue; +RgSchDlLcCb *dlLc; +RgrLchRecfg *lcRecfg; +RgSchErrInfo *err; +#endif +{ + TRC2(rgSCHSc1RgrLcRecfg); + + UNUSED(err); + + rgSCHSc1DlSvcMod(cell,ue,dlLc, lcRecfg); + + RETVALUE(ROK); +} /* rgSCHSc1RgrLcRecfg */ + + +/** + * @brief This function handles the reconfiguration of cell + * + * @details + * + * Function: rgSCHSc1RgrDlCellRecfg + * Purpose: Update the reconfiguration parameters. + * + * Invoked by: Scheduler + * + * @param[in] RgSchCellCb* cell + * @return Void + * + **/ +#ifdef ANSI +PRIVATE S16 rgSCHSc1RgrDlCellRecfg +( +RgSchCellCb *cell, +RgrCellRecfg *recfg, +RgSchErrInfo *err +) +#else +PRIVATE S16 rgSCHSc1RgrDlCellRecfg(cell, recfg, err) +RgSchCellCb *cell; +RgrCellRecfg *recfg; +RgSchErrInfo *err; +#endif +{ + TRC2(rgSCHSc1DlUeReset); + RETVALUE(ROK); +} + + + +/** + * @brief This function implements scheduler DL allocation + * + * @details + * + * Function: rgSCHSc1DlTaCmd + * Purpose: This function implements scheduler for TA cmd alloc for + * UEs. The hq proc availed as part of this alloc can be used + * by the UEs Dedicated CH transmission allocation. + * + * Invoked by: Scheduler + * + * @param[in] RgSchCellCb* cell + * @param[out] RgSchCmnDlRbAllocInfo *allocInfo + * @return Void + * + **/ +#ifdef ANSI +PRIVATE Void rgSCHSc1DlTaCmd +( +RgSchCellCb *cell, +RgSchCmnDlRbAllocInfo *allocInfo +) +#else +PRIVATE Void rgSCHSc1DlTaCmd(cell, allocInfo) +RgSchCellCb *cell; +RgSchCmnDlRbAllocInfo *allocInfo; +#endif +{ + CmLListCp *lst; + CmLList *node; + RgSchDlHqProcCb *proc; + RgSchUeCb *ue; + U32 effBo; + RgSchCmnDlCell *cellCmnDl = RG_SCH_CMN_GET_DL_CELL(cell); + RgSchCmnDlUe *cmnUeDl; + RgSchSc1DlUe *ueDl; + RgSchCmnDlHqProc *cmnHqDl; + RgSchDlSf *subFrm = allocInfo->dedAlloc.dedDlSf; +#ifdef LTEMAC_HDFDD + Bool dlAllowed = FALSE; +#endif + TRC2(rgSCHSc1DlTaCmd); + + lst = &cellCmnDl->taLst; + node = lst->first; + while(node) + { + ue = (RgSchUeCb *)node->node; + node = node->next; +#ifdef LTEMAC_HDFDD + if (ue->hdFddEnbld) + { + rgSCHCmnHdFddChkDlAllow ( cell, ue, &dlAllowed); + if (dlAllowed == FALSE) + { + continue; + } + } +#endif + /* If Ue is inactive in DL then ignore */ + if (ue->dl.dlInactvMask) + { + continue; + } + cmnUeDl = RG_SCH_CMN_GET_DL_UE(ue,cell); + /*cell added as part of CA dev*/ + ueDl = RG_GET_SC1_UE_DL(ue, cell); + + if (rgSCHDhmGetAvlHqProc(cell, ue, cellCmnDl->time, &proc) != ROK) + { + continue; + } + /* Initialize some of the parameters of the HQ proc */ + cmnHqDl = RG_SCH_CMN_GET_DL_HQP(proc); + + effBo = 0; + /* 3.1 MIMO */ + cmnHqDl->totBytes = 0; + rgSCHCmnDlAllocTxRb(cell, subFrm, ue, RGSCH_TA_SIZE, &effBo, proc, allocInfo); + if (effBo == 0) + { + /* If no allocations so far, meaning proc obtained now */ + if (cmnHqDl->totBytes == 0) + { + rgSCHSc1RlsHqProc(proc); + /* Added the handling for removing + * UE from txHqPLst and resetting outStndalloc.*/ + if(proc->reqLnk.node != (PTR)NULLP) + { + cmLListDelFrm(&allocInfo->dedAlloc.txHqPLst, &proc->reqLnk); + proc->reqLnk.node = (PTR)NULLP; + } + /*Re-set the outstanding alloc information.*/ + cmnUeDl->outStndAlloc = 0; + } + /* Avl BW could not satisfy even TA so break */ + break; + } + ueDl->taReqBytes = RGSCH_TA_SIZE; + cmnUeDl->proc = proc; + cmnHqDl->totBytes += effBo; + /* 3.1 MIMO moving this call to cmn scheduler */ + /*rgSCHCmnDlRbInfoAddUeTx(allocInfo, ue);*/ + } + RETVOID; +} + +/** + * @brief Scheduler invocation + * + * @details + * + * Function: rgSCHSc1DlHndlInActUes + * Purpose: The list of inactive UEs present in inactvLst should + * be removed from the scheduling Qs. + * + * Invoked by: Common Scheduler (TTI processing) + * + * @param[in] RgSchCellCb *cell + * @param[out] CmLListCp *inactvLst + * @return Void + **/ +#ifdef ANSI +PUBLIC Void rgSCHSc1DlHndlInActUes +( +RgSchCellCb *cell, +CmLListCp *inactvLst +) +#else +PUBLIC Void rgSCHSc1DlHndlInActUes(cell, inactvLst) +RgSchCellCb *cell; +CmLListCp *inactvLst; +#endif +{ + CmLList *node; + RgSchUeCb *ue; + + TRC2(rgSCHSc1DlHndlInActUes); + + node = inactvLst->first; + while(node) + { + ue = (RgSchUeCb *)node->node; + node = node->next; + /* Suspend this UE from further scheduling + * till it is activated again. */ + rgSCHSc1DlInactvtUe(cell, ue); + } + RETVOID; +} + +/** + * @brief This function initializes all the data for the scheduler + * + * @details + * + * Function: rgSCHSc1DlInit + * Purpose: This function initializes the following information + * 1. Efficiency table + * 2. CQI to table index - It is one row for upto 3 RBs + * and another row for greater than 3 RBs + * + * currently extended prefix is compiled out. + * Invoked by: MAC intialization code..may be ActvInit + * + * @return Void + * + **/ +#ifdef ANSI +PUBLIC Void rgSCHSc1DlInit +( +RgDlSchdApis *rgSchDlApis +) +#else +PUBLIC Void rgSCHSc1DlInit(rgSchDlApis) +RgDlSchdApis *rgSchDlApis; +#endif +{ + TRC2(rgSCHSc1DlInit); + /* Init the function pointers */ + rgSchDlApis->rgSCHRgrDlUeCfg = rgSCHSc1RgrDlUeCfg; + rgSchDlApis->rgSCHRgrDlUeRecfg = rgSCHSc1RgrDlUeRecfg; + rgSchDlApis->rgSCHFreeDlUe = rgSCHSc1DlUeDel; + rgSchDlApis->rgSCHRgrDlCellCfg = rgSCHSc1RgrDlCellCfg; + rgSchDlApis->rgSCHRgrDlCellRecfg = rgSCHSc1RgrDlCellRecfg; + rgSchDlApis->rgSCHFreeDlCell = rgSCHSc1DlCellDel; + rgSchDlApis->rgSCHRgrDlLcCfg = rgSCHSc1RgrLcCfg; + rgSchDlApis->rgSCHRgrDlLcRecfg = rgSCHSc1RgrLcRecfg; + rgSchDlApis->rgSCHFreeDlLc = rgSCHSc1DlLcRmv; + rgSchDlApis->rgSCHDlNewSched = rgSCHSc1DlDedNewTx; + rgSchDlApis->rgSCHDlPreSched = rgSCHSc1DlPreSchd; + rgSchDlApis->rgSCHDlPstSched = rgSCHSc1DlPstSchd; + rgSchDlApis->rgSCHDlRetxSched = rgSCHSc1DlDedRetx; + rgSchDlApis->rgSCHDlCeSched = rgSCHSc1DlTaCmd; + rgSchDlApis->rgSCHDlDedBoUpd = rgSCHSc1DlLcBoUpd; + rgSchDlApis->rgSCHDlProcAddToRetx = rgSCHSc1DlProcAddToCellRetx; + rgSchDlApis->rgSCHDlAllocFnlz = rgSCHSc1DlAllocFnlz; + rgSchDlApis->rgSCHDlCqiInd = rgSCHSc1DlCqiInd; + rgSchDlApis->rgSCHDlUeRefresh = rgSCHSc1DlUeRefresh; + rgSchDlApis->rgSCHDlUeReset = rgSCHSc1DlUeReset; + rgSchDlApis->rgSCHDlActvtUe = rgSCHSc1DlActvtUe; + rgSchDlApis->rgSCHDlInactvtUes = rgSCHSc1DlHndlInActUes; + rgSchDlApis->rgSCHDlUeHqEntInit = rgSCHSc1DlUeHqEntInit; + rgSchDlApis->rgSCHDlUeHqEntDeInit = rgSCHSc1DlUeHqEntDeInit; + rgSchDlApis->rgSCHDlProcRmvFrmRetx = rgSCHSc1DlProcRmvFrmRetx; + rgSchDlApis->rgSCHDlTickForPdbTrkng = rgSCHSc1DlScanUpdPdbPrio; + rgSchDlApis->rgSCHDlFillFlwCtrlInfo = rgSCHSc1DlFillFlowCntrlInfo; + + RETVOID; +} + + + + +/*********************************************************** + * + * Func : rgSCHSc1DlInitQueues + * + * Desc : Initial downlink scheduler queues + * + * Ret : Void + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PRIVATE Void rgSCHSc1DlInitQueues +( +RgSchSc1DlCell *cellDl +) +#else +PRIVATE Void rgSCHSc1DlInitQueues(cellDl) +RgSchSc1DlCell *cellDl; +#endif +{ + U8 i; + TRC2(rgSCHSc1DlInitQueues); + + for (i = 0; i < RG_SC1_DL_NUM_Q; ++i) + { + cmLListInit(&cellDl->prioLst[i]); + cmLListInit(&cellDl->retxLst[i]); + } + /* Set appropriate "manage svc positioning" function based on + * svc priority as array index */ + /* for DCCH svcs */ + for (i = 0; i < RG_SCH_SC1_DL_GBR_PRIO_START; i++) + { + cellDl->svcMngFunc[i] = rgSCHSc1DlMngPrio0SvcPosn; + } + /* for GBR svcs */ + for (i = RG_SCH_SC1_DL_GBR_PRIO_START; i <= RG_SCH_SC1_DL_GBR_PRIO_END; i++) + { + cellDl->svcMngFunc[i] = rgSCHSc1DlMngGbrSvcPosn; + } + /* for Non-GBR svcs */ + for (i = RG_SCH_SC1_DL_GBR_PRIO_END+1; i <= RG_SCH_CMN_MAX_PRIO; i++) + { + cellDl->svcMngFunc[i] = rgSCHSc1DlMngAmbrSvcPosn; + } + RETVOID; +} + + + + +/** + * @brief This function Processes the Final Allocations + * made by the RB Allocator against the requested + * RETX allocations. + * + * @details + * + * Function: rgSCHSc1DlRetxAllocFnlz + * Purpose : Remove the Retx Hq Proc from the Cell's + * Retx list, if allocation is successful. + * Fill the HqProc and PDCCH and append it to the SubFrm. + * + * + * + * Invoked by: Common Scheduler + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchCmnDlRbAllocInfo *allocInfo + * @return Void + * + **/ +#ifdef ANSI +PRIVATE Void rgSCHSc1DlRetxAllocFnlz +( +RgSchCellCb *cell, +RgSchCmnDlRbAllocInfo *allocInfo +) +#else +PRIVATE Void rgSCHSc1DlRetxAllocFnlz(cell, allocInfo) +RgSchCellCb *cell; +RgSchCmnDlRbAllocInfo *allocInfo; +#endif +{ + CmLList *node; + RgSchUeCb *ue; + RgSchDlHqProcCb *hqP; + RgSchDlRbAlloc *dlAllocCb = NULLP; + TRC2(rgSCHSc1DlRetxAllocFnlz); + + node = allocInfo->dedAlloc.schdRetxHqPLst.first; + while(node) + { + hqP = (RgSchDlHqProcCb *)node->node; + ue = hqP->hqE->ue; + node = node->next; + /* Fill PDCCH and assign it to HqP */ + dlAllocCb = RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ue, cell); + + rgSCHCmnFillHqPPdcch(cell, dlAllocCb, hqP); +#ifdef LTEMAC_HDFDD + if (ue->hdFddEnbld) + { + rgSCHCmnHdFddUpdDLMark(cell, ue); + } +#endif + /* Extra Check: Retain the hqProc in the RETX Queue if one/more + * TBs of the HqProc are yet to be scheduled for RETX. + * Note: Here we are not tracking at TB Level, the priority Q + * to which it belongs to. The retx prio of transmission is still + * being maintained at hqProc level, rather than at TB level */ + if ((hqP->tbInfo[0].state != HQ_TB_NACKED) && + (hqP->tbInfo[1].state != HQ_TB_NACKED)) { + rgSCHSc1DlProcRmvFrmCellRetx(cell, hqP); + } + /* reset the UE allocation Information */ + rgSCHCmnDlUeResetTemp(ue, hqP); + } + + /* Traverse the nonSchdTxUeLst and reset the UE allocation Info */ + node = allocInfo->dedAlloc.nonSchdRetxHqPLst.first; + while(node) + { + hqP = (RgSchDlHqProcCb *)node->node; + ue = hqP->hqE->ue; + node = node->next; + /* reset the UE allocation Information */ + rgSCHCmnDlUeResetTemp(ue, hqP); + } + RETVOID; +} + +/* 3.1 MIMO Alloc distribution functions being performed + * TB wise */ + + +/*********************************************************** + * + * Func : rgSCHSc1DlSprTxTbDstn + * + * Desc : Perform Actual allocation distribution among + * UEs schd svcs and TA for a given spare TB "tbInfo" allocation. + * spare TB allocation is as a result of 1 RETX TB allocation, when + * conditions are favourable for 2 TB spatial multiplexing. + * + * Ret : Void + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PRIVATE Void rgSCHSc1DlSprTxTbDstn +( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgSchDlHqTbCb *tbInfo, +U32 *effAlloc, +CmLList **node +) +#else +PRIVATE Void rgSCHSc1DlSprTxTbDstn(cell, ue, tbInfo, effAlloc, node) +RgSchCellCb *cell; +RgSchUeCb *ue; +RgSchDlHqTbCb *tbInfo; +U32 *effAlloc; +CmLList **node; +#endif +{ + RgSchDlLcCb *svc; + RgSchSc1DlSvc *svcSc1; + RgSchSc1DlUe *ueDl = RG_GET_SC1_UE_DL(ue, cell); + U32 bytes; + RgSchLchAllocInfo lchSchdData; + U32 effBo; + U32 rlcHdrEstmt; + + TRC2(rgSCHSc1DlSprTxTbDstn); + + while((*node) && (*effAlloc > 0)) + { + svc = (RgSchDlLcCb *)(*node)->node; + *node = (*node)->next; + svcSc1 = RG_GET_SC1_SVC_DL(ue,svc,cell); + + RG_SCH_CMN_DL_GET_HDR_EST(svc, rlcHdrEstmt); + /* Update the SVC QOS Param */ + if (RG_SCH_CMN_SVC_IS_GBR(svc)) + { + effBo = svcSc1->effMbr + rlcHdrEstmt; + bytes = RGSCH_MIN(*effAlloc, effBo); + /* Determine How much BO is satisfied */ + if (bytes <= rlcHdrEstmt) + { + break; + } + (svcSc1->bo <= bytes-rlcHdrEstmt)?\ + (svcSc1->bo = 0):\ + (svcSc1->bo -= bytes-rlcHdrEstmt); + svc->bo = svcSc1->bo; + + /* L2_COUNTERS */ +#ifdef LTE_L2_MEAS + /* Increment qciActiveLCs once since this LCs buffer will be present + in Harq process */ + if (svc->lcType == CM_LTE_LCH_DTCH) + { + ue->qciActiveLCs[svc->qciCb->qci]++; + } + + if ((svc->bo == 0) && (svc->lcType == CM_LTE_LCH_DTCH)) + { + if (ue->qciActiveLCs[svc->qciCb->qci]) + { + ue->qciActiveLCs[svc->qciCb->qci]--; + } + if (!(ue->qciActiveLCs[svc->qciCb->qci])) + { + svc->qciCb->dlUeCount--; + } + } +#endif + (svcSc1->gbr <= bytes)? (svcSc1->gbr = 0): + (svcSc1->gbr -= bytes); + (svcSc1->mbr <= bytes)? (svcSc1->mbr = 0): + (svcSc1->mbr -= bytes); + } + else if(RG_SCH_CMN_SVC_IS_AMBR(svc)) + { + effBo = ueDl->effAmbr + rlcHdrEstmt; + bytes = RGSCH_MIN(*effAlloc, effBo); + /* Determine How much BO is satisfied */ + if (bytes <= rlcHdrEstmt) + { + break; + } + (svcSc1->bo <= bytes-rlcHdrEstmt)?\ + (svcSc1->bo = 0):\ + (svcSc1->bo -= bytes-rlcHdrEstmt); + + (ueDl->ambr <= bytes)? (ueDl->ambr = 0): + (ueDl->ambr -= bytes); + } + else /* Prio 0 SVC */ + { + effBo = svcSc1->bo + rlcHdrEstmt; + bytes = RGSCH_MIN(*effAlloc, effBo); + /* Determine How much BO is satisfied */ + if (bytes <= rlcHdrEstmt) + { + break; + } + (svcSc1->bo <= bytes-rlcHdrEstmt)?\ + (svcSc1->bo = 0):\ + (svcSc1->bo -= bytes-rlcHdrEstmt); + } + /* Position the service accordingly */ + rgSCHSc1DlMngSvcPosn(cell, svc->ue, svc); + /* Update effAlloc */ + *effAlloc -= bytes; + + /* Update DHM for this SVC */ + lchSchdData.lcId = svc->lcId; + lchSchdData.schdData = bytes; + rgSCHDhmAddLcData(cell->instIdx, &lchSchdData, tbInfo); + } + RETVOID; +} + + +/*********************************************************** + * + * Func : rgSCHSc1DlNewTxTbDstn + * + * Desc : Perform Actual allocation distribution among + * UEs schd svcs and TA for a given TB "tbInfo" allocation. + * Assumption: TA is given higher priority in Alloc Distribution. + * + * Ret : Void + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PRIVATE Void rgSCHSc1DlNewTxTbDstn +( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgSchDlHqTbCb *tbInfo, +U32 *effAlloc, +CmLList **node +) +#else +PRIVATE Void rgSCHSc1DlNewTxTbDstn(cell, ue, tbInfo, effAlloc, node) +RgSchCellCb *cell; +RgSchUeCb *ue; +RgSchDlHqTbCb *tbInfo; +U32 *effAlloc; +CmLList **node; +#endif +{ + RgSchDlLcCb *svc; + RgSchSc1DlSvc *svcSc1 = NULLP; + RgSchSc1DlUe *ueDl = RG_GET_SC1_UE_DL(ue, cell); + U32 bytes; + RgSchLchAllocInfo lchSchdData; + CmLList *prev = NULLP; + + TRC2(rgSCHSc1DlNewTxTbDstn); + + if (ueDl->taReqBytes) + { + if (ueDl->taReqBytes < *effAlloc) + { + /*TA satisfied, hence remove from TA Lst */ + rgSCHCmnRmvFrmTaLst(cell, ue); + /* Indicate to DHM that TA has been scheduled */ + rgSCHDhmSchdTa(ue, tbInfo); + *effAlloc -= ueDl->taReqBytes; + } + /* Reset the TA Req Bytes Field */ + ueDl->taReqBytes = 0; + } + while((*node) && (*effAlloc > 0)) + { + svc = (RgSchDlLcCb *)(*node)->node; + prev = *node; + *node = (*node)->next; + svcSc1 = RG_GET_SC1_SVC_DL(ue,svc,cell); + if (*effAlloc > svcSc1->reqBytes) + { + bytes = svcSc1->reqBytes; + if (bytes <= svcSc1->hdrEstimate) + { + break; + } + /* 3.1 MIMO updating the reqBytes field */ + svcSc1->reqBytes = 0; + svcSc1->bo = 0; + } + else + { + bytes = *effAlloc; + if (bytes <= svcSc1->hdrEstimate) + { + break; + } + /* 3.1 MIMO updating the reqBytes field */ + svcSc1->reqBytes -= bytes; + (svcSc1->bo <= bytes-svcSc1->hdrEstimate)?\ + (svcSc1->bo = 0):\ + (svcSc1->bo -= bytes-svcSc1->hdrEstimate); + } + svc->bo = svcSc1->bo; + + /* L2_COUNTERS */ +#ifdef LTE_L2_MEAS + + /* Increment qciActiveLCs once since this LCs buffer will be present + in Harq process */ + if (svc->lcType == CM_LTE_LCH_DTCH) + { + ue->qciActiveLCs[svc->qciCb->qci]++; + } + + if ((svc->bo == 0) && (svc->lcType == CM_LTE_LCH_DTCH)) + { + if (ue->qciActiveLCs[svc->qciCb->qci]) + { + ue->qciActiveLCs[svc->qciCb->qci]--; + } + if (!(ue->qciActiveLCs[svc->qciCb->qci])) + { + svc->qciCb->dlUeCount--; + } + } +#endif + + /* Update the SVC QOS Param */ + if (RG_SCH_CMN_SVC_IS_GBR(svc)) + { + (svcSc1->gbr <= bytes)? (svcSc1->gbr = 0): + (svcSc1->gbr -= bytes); + (svcSc1->mbr <= bytes)? (svcSc1->mbr = 0): + (svcSc1->mbr -= bytes); + } + else if(RG_SCH_CMN_SVC_IS_AMBR(svc)) + { + (ueDl->ambr <= bytes)? (ueDl->ambr = 0): + (ueDl->ambr -= bytes); + } + /* Position the service accordingly */ + rgSCHSc1DlMngSvcPosn(cell, svc->ue, svc); + /* Update effAlloc */ + *effAlloc -= bytes; + + /* Update DHM for this SVC */ + lchSchdData.lcId = svc->lcId; + lchSchdData.schdData = bytes; + rgSCHDhmAddLcData(cell->instIdx, &lchSchdData, tbInfo); + } + /* If no more scheduled LCs for TB data distribution + * then distribute the spare TB data among the LCs + * of the UE with non-zero BO. This is effective for + * schedulers work on LC level priorities rather than + * UE level. */ + if ((*node == NULLP) && (svcSc1) && (svcSc1->reqBytes == 0)) + { + rgSCHSc1DlSprTxTbDstn(cell, ue, tbInfo, effAlloc, + &ueDl->lcsWithData.first); + *node = NULLP; + RETVOID; + } + /* make sure node points to the svc not completely + * satisfied. + * make sure if not served completely then + * the other TB allocation accomodates the same */ + *node = prev; + RETVOID; +} + + + +/*********************************************************** + * + * Func : rgSCHSc1DlNewTxUeFnlz + * + * Desc : Perform allocation Distribution from scheduled TB + * among the list of services considered for scheduling. + * + * Ret : Void + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PRIVATE Void rgSCHSc1DlNewTxUeFnlz +( +RgSchCellCb *cell, +RgSchCmnDlRbAllocInfo *allocInfo, +RgSchUeCb *ue +) +#else +PRIVATE Void rgSCHSc1DlNewTxUeFnlz(cell, allocInfo, ue) +RgSchCellCb *cell; +RgSchCmnDlRbAllocInfo *allocInfo; +RgSchUeCb *ue; +#endif +{ + CmLList *node; + RgSchSc1DlUe *ueDl = RG_GET_SC1_UE_DL(ue, cell); + RgSchCmnDlUe *cmnUeDl = RG_SCH_CMN_GET_DL_UE(ue,cell); + /*cell added as part of CA dev*/ + /* 3.1 MIMO Distribute data of each TB across services */ + RgSchDlRbAlloc *dlAllocCb = RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ue, cell); + U32 remTb1Bytes = dlAllocCb->tbInfo[0].bytesAlloc; + U32 remTb2Bytes = dlAllocCb->tbInfo[1].bytesAlloc; + U32 effAlloc = 0; + /*ccpu00120365-ADD-added to code to check if second TB is utilized */ + U32 tb2Bytes = 0; + + TRC2(rgSCHSc1DlNewTxUeFnlz); + + + /* 3.1 MIMO Consider the allocation of New TX TB for distribution */ + /* Handle schd services */ + node = ueDl->schdSvcs.first; + if (remTb1Bytes){ + effAlloc += remTb1Bytes; + rgSCHSc1DlNewTxTbDstn(cell, ue, &cmnUeDl->proc->tbInfo[0],\ + &remTb1Bytes, &node); + /* In the event that TB1 is not completely filled by the DL LCs + * BO, consider the reducing the iMcs for increasing redundancy + * and hence reception quality at UE */ + rgSCHCmnRdcImcsTxTb(dlAllocCb, 0, + dlAllocCb->tbInfo[0].bytesAlloc - remTb1Bytes); + } + + /*ccpu00120365-ADD-assigning value of remTb2Bytes before utilization */ + tb2Bytes = remTb2Bytes; + + /* Extra check for a non SM UE allocation */ + if (remTb2Bytes){ + effAlloc += remTb2Bytes; + rgSCHSc1DlNewTxTbDstn(cell, ue, &cmnUeDl->proc->tbInfo[1],\ + &remTb2Bytes, &node); + /* In the event that TB2 is not completely filled by the DL LCs + * BO, consider the reducing the iMcs for increasing redundancy + * and hence reception quality at UE */ + rgSCHCmnRdcImcsTxTb(dlAllocCb, 1, + dlAllocCb->tbInfo[1].bytesAlloc - remTb2Bytes); + } + + /* ccpu00120365-ADD-Disable the second TB as the second TB is not + * utilized */ + if ( remTb2Bytes && ( tb2Bytes == remTb2Bytes) ) + { + dlAllocCb->mimoAllocInfo.precIdxInfo = 0; + dlAllocCb->mimoAllocInfo.numTxLyrs = 1; + dlAllocCb->tbInfo[1].schdlngForTb = FALSE; + dlAllocCb->tbInfo[1].isDisabled = TRUE; + } + + if (effAlloc == (remTb1Bytes + remTb2Bytes)) + { + /* Allocation such that Nothing could be satisfied */ + /* Return the grabbed PDCCH */ + rgSCHUtlPdcchPut(cell, &dlAllocCb->dlSf->pdcchInfo, + dlAllocCb->pdcch); + rgSCHSc1RlsHqProc(cmnUeDl->proc); + RETVOID; + } + + /* Fill PDCCH and assign it to HqP */ + rgSCHCmnFillHqPPdcch(cell, dlAllocCb, cmnUeDl->proc); + + RETVOID; +} + + +/** + * @brief This function Processes the Final Allocations + * made by the RB Allocator against the requested + * New TX allocations. + * + * @details + * + * Function: rgSCHSc1DlNewTxAllocFnlz + * Purpose : Distribute the allocation among the Scheduled SVCs. + * Fill pdcch and HqP for UEs will allocations. + * Release HqP for UE with no allocation. + * + * Invoked by: Common Scheduler + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchCmnDlRbAllocInfo *allocInfo + * @return Void + * + **/ +#ifdef ANSI +PRIVATE Void rgSCHSc1DlNewTxAllocFnlz +( +RgSchCellCb *cell, +RgSchCmnDlRbAllocInfo *allocInfo +) +#else +PRIVATE Void rgSCHSc1DlNewTxAllocFnlz(cell, allocInfo) +RgSchCellCb *cell; +RgSchCmnDlRbAllocInfo *allocInfo; +#endif +{ + CmLList *node; + RgSchUeCb *ue; + RgSchCmnDlUe *cmnUeDl; + RgSchDlHqProcCb *hqP; + TRC2(rgSCHSc1DlNewTxAllocFnlz); + + node = allocInfo->dedAlloc.schdTxHqPLst.first; + while(node) + { + hqP = (RgSchDlHqProcCb *)node->node; + ue = hqP->hqE->ue; + node = node->next; + cmnUeDl = RG_SCH_CMN_GET_DL_UE(ue,cell); + /*cell added as part of CA dev*/ + + rgSCHSc1DlNewTxUeFnlz(cell, allocInfo, ue); +#ifdef LTEMAC_HDFDD + if (ue->hdFddEnbld) + { + rgSCHCmnHdFddUpdDLMark(cell, ue); + } +#endif + /* reset the UE allocation Information */ + cmLListInit(&((RgSchSc1DlUe *)(cmnUeDl->schSpfc))->schdSvcs); + rgSCHCmnDlUeResetTemp(ue, hqP); + } + + /* Traverse the nonSchdTxUeLst and reset the UE allocation Info */ + node = allocInfo->dedAlloc.nonSchdTxHqPLst.first; + while(node) + { + hqP = (RgSchDlHqProcCb *)node->node; + ue = hqP->hqE->ue; + node = node->next; + cmnUeDl = RG_SCH_CMN_GET_DL_UE(ue, cell); + + /* Release HqProc */ + rgSCHSc1RlsHqProc(hqP); + /* reset the UE allocation Information */ + cmLListInit(&((RgSchSc1DlUe *)(cmnUeDl->schSpfc))->schdSvcs); + rgSCHCmnDlUeResetTemp(ue, hqP); + } + RETVOID; +} + +/* 3.1 Added new function to handle TX+RETX alloc fnlz'n */ + +/** + * @brief This function Processes the Final Allocations + * made by the RB Allocator against the requested + * RETX+New TX allocations. The NewTx TB allocation + * is considered for distribution among LCs. + * + * @details + * + * Function: rgSCHSc1DlRetxNewTxAllocFnlz + * Purpose : 1. Reached here due to 1 RETX TB allocation for a + * SM UE, which is capable to accomodate a newTX + * in the other TB. + * 2. Distribute NewTX TB allocation among the + * SVCs present in lcsWithData list of UE. + * + * + * Invoked by: Common Scheduler + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchCmnDlRbAllocInfo *cellAllocInfo + * @return Void + * + **/ +#ifdef ANSI +PRIVATE Void rgSCHSc1DlRetxNewTxAllocFnlz +( +RgSchCellCb *cell, +RgSchCmnDlRbAllocInfo *cellAllocInfo +) +#else +PRIVATE Void rgSCHSc1DlRetxNewTxAllocFnlz(cell, cellAllocInfo) +RgSchCellCb *cell; +RgSchCmnDlRbAllocInfo *cellAllocInfo; +#endif +{ + CmLList *node; + RgSchUeCb *ue; + RgSchSc1DlUe *sc1DlUe; + RgSchDlHqProcCb *hqP; + RgSchDlHqTbCb *newTxTbInfo; + U32 effAlloc; + U32 remTbBytes; + RgSchDlRbAlloc *ueAllocInfo; + RgSchDlRbAlloc *dlAllocCb; + + TRC2(rgSCHSc1DlRetxNewTxAllocFnlz); + + node = cellAllocInfo->dedAlloc.schdTxRetxHqPLst.first; + while(node) + { + hqP = (RgSchDlHqProcCb *)node->node; + ue = hqP->hqE->ue; + node = node->next; + sc1DlUe = RG_GET_SC1_UE_DL(ue, cell); + ueAllocInfo = RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ue, cell); + dlAllocCb = RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ue, cell); + /* Index 0 of ueAllocInfo->tbInfo will always hold the + * RETX TB and index 1 will hold the NewTX TB in case of + * RETX+TX allocation. */ + newTxTbInfo = ueAllocInfo->tbInfo[1].tbCb; + effAlloc = remTbBytes = ueAllocInfo->tbInfo[1].bytesAlloc; + rgSCHSc1DlSprTxTbDstn(cell, ue, newTxTbInfo,\ + &remTbBytes, &(sc1DlUe->lcsWithData.first)); + /* Trying to reduce mcs of TX TB to increase reception quality at UE. + * In case of RETX+TX allocation, TX TB allocation was irrespective + * of actual requirement by UE, hence in case if consumption is + * less than allocation, consider reducing the iMcs of this TX TB. */ + rgSCHCmnRdcImcsTxTb(dlAllocCb, 1, effAlloc - remTbBytes); + /* 3.1 MIMO Remove/Retain from/in cell RETX List */ + rgSCHSc1DlProcRmvFrmCellRetx(cell, hqP); + /* Fill PDCCH and assign it to HqP */ + rgSCHCmnFillHqPPdcch(cell, dlAllocCb, hqP); +#ifdef LTEMAC_HDFDD + if (ue->hdFddEnbld) + { + rgSCHCmnHdFddUpdDLMark(cell, ue); + } +#endif + /* reset the UE allocation Information */ + rgSCHCmnDlUeResetTemp(ue, hqP); + } + + /* Traverse the nonSchdTxRetxHqPLst and reset the UE allocation Info */ + node = cellAllocInfo->dedAlloc.nonSchdTxRetxHqPLst.first; + while(node) + { + hqP = (RgSchDlHqProcCb *)node->node; + ue = hqP->hqE->ue; + node = node->next; + /* reset the UE allocation Information */ + rgSCHCmnDlUeResetTemp(ue, hqP); + } +} + + +/** + * @brief This function Processes the Final Allocations + * made by the RB Allocator against the requested. + * + * @details + * + * Function: rgSCHSc1DlAllocFnlz + * Purpose: This function Processes the Final Allocations + * made by the RB Allocator against the requested. + * 1. Loop through scheduled TX and RETX lists. + * Fill in the corresponding PDCCH and HqProcs. + * In case of TX If actual Alloc < requested, then perform + * an appropriate distribution among the schdSvcs. + * If TA is satisfied, then remove UE from TA Lst. + * 2. Loop through UnScheduled TX and RETX Lists. + * Release grabbed HqProcs. + * Put back SVCs from schdSvcsLst to their corresponding Qs. + * + * + * Invoked by: Common Scheduler + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchCmnDlRbAllocInfo *allocInfo + * @return Void + * + **/ +#ifdef ANSI +PUBLIC Void rgSCHSc1DlAllocFnlz +( +RgSchCellCb *cell, +RgSchCmnDlRbAllocInfo *allocInfo +) +#else +PUBLIC Void rgSCHSc1DlAllocFnlz(cell, allocInfo) +RgSchCellCb *cell; +RgSchCmnDlRbAllocInfo *allocInfo; +#endif +{ + TRC2(rgSCHSc1DlAllocFnlz); + + rgSCHSc1DlRetxAllocFnlz(cell, allocInfo); + + rgSCHSc1DlNewTxAllocFnlz(cell, allocInfo); + + /*3.1 MIMO new Function added to handle TX+RETX + * harq process scheduling finalization */ + rgSCHSc1DlRetxNewTxAllocFnlz(cell, allocInfo); + RETVOID; +} + + + +/** + * @brief This function Updates the DL CQI for the UE. + * + * @details + * + * Function: rgSCHSc1DlCqiInd + * Purpose: Updates the DL CQI for the UE + * + * Invoked by: Common Scheduler. SC1 does nothing. + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ue + * @param[in] TfuDlCqiRpt *dlCqiRpt + * @return Void + * + **/ +#ifdef ANSI +PUBLIC Void rgSCHSc1DlCqiInd +( +RgSchCellCb *cell, +RgSchUeCb *ue, +Bool isPucchInfo, +Void *dlCqi +) +#else +PUBLIC Void rgSCHSc1DlCqiInd(cell, ue, isPucchInfo, dlCqi) +RgSchCellCb *cell; +RgSchUeCb *ue; +Bool isPucchInfo; +Void *dlCqi; +#endif +{ + TRC2(rgSCHSc1DlCqiInd); + RETVOID; +} + + +/** + * @brief This function adds a service to UE's list of lcsWithData. + * + * @details + * + * Function: rgSCHSc1DlAdd2UeLcsWithData + * Purpose: 1. This is to maintain a snapshot view of the + * DL SVCs distributions among the cellwide priority + * queues. + * 2. This snapshot view is maintained in the order + * of priority of the SVCs with in UE. + * 3. Addition of SVC to a cellwide priority Queue + * triggers this function. + * + * Invoked by: Functions of DL SC1 which add SVC or UE(for ambr svc) + * to cellwide priority Queues. + * + * @param[in] RgSchUeCb* ue + * @param[in] RgSchDlLcCb* svc + * @return Void + * + **/ +#ifdef ANSI +PRIVATE Void rgSCHSc1DlAdd2UeLcsWithData +( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgSchDlLcCb *svc +) +#else +PRIVATE Void rgSCHSc1DlAdd2UeLcsWithData(cell, ue, svc) +RgSchCellCb *cell; +RgSchUeCb *ue; +RgSchDlLcCb *svc; +#endif +{ + CmLListCp *lst; + CmLList *node; + RgSchCmnDlSvc *cmnDlSvc = RG_SCH_CMN_GET_DL_SVC(svc); + RgSchSc1DlSvc *sc1DlSvc = RG_GET_SC1_SVC_DL(ue,svc,cell); + RgSchSc1DlUe *sc1DlUe = RG_GET_SC1_UE_DL(ue, cell); + RgSchCmnDlSvc *cmnDlLstSvc; + + TRC2(rgSCHSc1DlAdd2UeLcsWithData); + + lst = &(sc1DlUe->lcsWithData); + node = lst->first; + while(node) + { + cmnDlLstSvc = RG_SCH_CMN_GET_DL_SVC(((RgSchDlLcCb *)(node->node))); + if (cmnDlSvc->prio <= cmnDlLstSvc->prio) + { + break; + } + node = node->next; + } + if (node == NULLP) + { + cmLListAdd2Tail(lst, &sc1DlSvc->lcWithDataLnk); + sc1DlSvc->lcWithDataLnk.node = (PTR)svc; + } + else + { + lst->crnt = node; + cmLListInsCrnt(lst, &sc1DlSvc->lcWithDataLnk); + sc1DlSvc->lcWithDataLnk.node = (PTR)svc; + } + RETVOID; +} + + +/** + * @brief This function adds a service to UE's list of lcsWithData. + * + * @details + * + * Function: rgSCHSc1DlRmFrmUeLcsWithData + * Purpose: 1. This is to maintain a snapshot view of the + * DL SVCs distributions among the cellwide priority + * queues. + * 2. This snapshot view is maintained in the order + * of priority of the SVCs with in UE. + * 3. Addition of SVC to a cellwide priority Queue + * triggers this function. + * + * Invoked by: Functions of DL SC1 which add SVC or UE(for ambr svc) + * to cellwide priority Queues. + * + * @param[in] RgSchUeCb* ue + * @param[in] RgSchDlLcCb* svc + * @return Void + * + **/ +#ifdef ANSI +PRIVATE Void rgSCHSc1DlRmFrmUeLcsWithData +( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgSchDlLcCb *svc +) +#else +PRIVATE Void rgSCHSc1DlRmFrmUeLcsWithData(cell, ue, svc) +RgSchCellCb *cell; +RgSchUeCb *ue; +RgSchDlLcCb *svc; +#endif +{ + RgSchSc1DlSvc *sc1DlSvc = RG_GET_SC1_SVC_DL(ue,svc,cell); + RgSchSc1DlUe *sc1DlUe = RG_GET_SC1_UE_DL(ue, cell); + + TRC2(rgSCHSc1DlRmFrmUeLcsWithData); + + cmLListDelFrm(&(sc1DlUe->lcsWithData), &sc1DlSvc->lcWithDataLnk); + sc1DlSvc->lcWithDataLnk.node = NULLP; + RETVOID; +} +/***************** SC1 DL SCHEDULER FUNCTION DEFNs END HERE ****************/ + +/***************************************************************************/ + +/***************** SC1 UL SCHEDULER FUNCTION DEFNs START HERE **************/ + +/*--------------------------* + * UL specific functions START + *---------------------------*/ + +/** + * @brief UE Lc Config for RR + * + * @details + * + * Function : rgSCHSc1UlLchCfg + * + * Processing Steps: Dummy function + * + * @param[in] RgrSchCellCb *cell + * @param[in] RgSchUeCb *ue + * @param[in] RgrLchCfg *cfg + * @param[in] RgSchErrInfo *err + * @return S16 + * -# ROK + **/ +PUBLIC S16 rgSCHSc1UlLchCfg +( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgrLchCfg *cfg, +RgSchErrInfo *err +) +{ + RETVALUE(ROK); +} +/** + * @brief UE Lc Reconfig for RR + * + * @details + * + * Function : rgSCHSc1UlLchRecfg + * + * Processing Steps: Dummy function + * + * @param[in] RgrSchCellCb *cell + * @param[in] RgSchUeCb *ue + * @param[in] RgrLchRecfg *recfg + * @param[in] RgSchErrInfo *err + * @return S16 + * -# ROK + **/ +PUBLIC S16 rgSCHSc1UlLchRecfg +( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgrLchRecfg *recfg, +RgSchErrInfo *err +) +{ + RETVALUE(ROK); +} +/** + * @brief LC deletion for PFS + * + * @details + * + * Function : rgSCHSc1UlLchDel + * + * Processing Steps: Dummy function + * + * @param[in] RgrSchCellCb *cell + * @param[in] RgSchUeCb *ue + * @param[in] CmLteLcId lcId + * @return S16 + * -# ROK + **/ +#ifdef ANSI +PUBLIC S16 rgSCHSc1UlLchDel +( +RgSchCellCb *cell, +RgSchUeCb *ue, +CmLteLcId lcId, +U8 lcgId +) +#else +PUBLIC S16 rgSCHRrUlLchDel(cell, ue, lcId, lcgId) +RgSchCellCb *cell; +RgSchUeCb *ue; +CmLteLcId lcId; +U8 lcgId; +#endif +{ + RETVALUE (ROK); +} + +/** + * @brief This function initializes all the data for the scheduler + * + * @details + * + * Function: rgSCHSc1UlInit + * Purpose: This function initializes the following information + * 1. Efficiency table + * 2. CQI to table index - It is one row for upto 3 RBs + * and another row for greater than 3 RBs + * + * currently extended prefix is compiled out. + * Invoked by: MAC intialization code..may be ActvInit + * + * @return Void + * + **/ +#ifdef ANSI +PUBLIC Void rgSCHSc1UlInit +( +RgUlSchdApis *rgSchUlApis +) +#else +PUBLIC Void rgSCHSc1UlInit(rgSchUlApis) +RgUlSchdApis *rgSchUlApis; +#endif +{ + TRC2(rgSCHSc1UlInit); + /* Init the function pointers */ + rgSchUlApis->rgSCHRgrUlUeCfg = rgSCHSc1RgrUlUeCfg; + rgSchUlApis->rgSCHRgrUlUeRecfg = rgSCHSc1RgrUlUeRecfg; + rgSchUlApis->rgSCHFreeUlUe = rgSCHSc1UlUeDel; + rgSchUlApis->rgSCHRgrUlCellCfg = rgSCHSc1RgrUlCellCfg; + rgSchUlApis->rgSCHRgrUlCellRecfg = rgSCHSc1RgrUlCellRecfg; + rgSchUlApis->rgSCHFreeUlCell = rgSCHSc1UlCellDel; + rgSchUlApis->rgSCHRgrUlLcCfg = rgSCHSc1UlLchCfg; + rgSchUlApis->rgSCHRgrUlLcRecfg = rgSCHSc1UlLchRecfg; + rgSchUlApis->rgSCHRgrUlLcgCfg = rgSCHSc1RgrLcgCfg; + rgSchUlApis->rgSCHRgrUlLcgRecfg = rgSCHSc1RgrLcgRecfg; + rgSchUlApis->rgSCHFreeUlLcg = rgSCHSc1LcgDel; + rgSchUlApis->rgSCHRgrUlLchDel = rgSCHSc1UlLchDel; + rgSchUlApis->rgSCHUlSched = rgSCHSc1UlSched; + rgSchUlApis->rgSCHUpdBsrShort = rgSCHSc1UpdBsrShort; + rgSchUlApis->rgSCHUpdBsrTrunc = rgSCHSc1UpdBsrTrunc; + rgSchUlApis->rgSCHUpdBsrLong = rgSCHSc1UpdBsrLong; + rgSchUlApis->rgSCHContResUlGrant = rgSCHSc1ContResUlGrant; + rgSchUlApis->rgSCHSrRcvd = rgSCHSc1SrRcvd; + rgSchUlApis->rgSCHUlCqiInd = rgSCHSc1UlCqiInd; + rgSchUlApis->rgSCHUlUeRefresh = rgSCHSc1UlUeRefresh; + rgSchUlApis->rgSCHUlAllocFnlz = rgSCHSc1UlAllocFnlz; + rgSchUlApis->rgSCHUlInactvtUes = rgSCHSc1UlHndlInActUes; + rgSchUlApis->rgSCHUlActvtUe = rgSCHSc1UlActvtUe; + rgSchUlApis->rgSCHUlUeReset = rgSCHSc1UlUeReset; + rgSchUlApis->rgSCHRgrUlLcgUpd = rgSCHSc1UlLcgUpd; + RETVOID; +} + +/** + * @brief UE initialisation for scheduler + * + * @details + * + * Function : rgSCHSc1RgrUlUeCfg + * + * This functions intialises UE specific scheduler + * information + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ue + * @param[int] RgrUeCfg *ueCfg + * @param[out] RgSchErrInfo *err + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 rgSCHSc1RgrUlUeCfg +( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgrUeCfg *ueCfg, +RgSchErrInfo *err +) +#else +PUBLIC S16 rgSCHSc1RgrUlUeCfg(cell, ue, ueCfg, err) +RgSchCellCb *cell; +RgSchUeCb *ue; +RgrUeCfg *ueCfg; +RgSchErrInfo *err; +#endif +{ + + RgSchCmnUe *ueSchCmn = RG_SCH_CMN_GET_UE(ue, cell); + TRC2(rgSCHSc1RgrUlUeCfg); + + if(rgSCHUtlAllocSBuf(cell->instIdx, + (Data**)&(ueSchCmn->ul.schSpfc), (sizeof(RgSchSc1UlUe))) != ROK) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId, + "Memory allocation FAILED CRNTI:%d",ue->ueId); + err->errCause = RGSCHERR_SCH_SC1_UL_CFG; + RETVALUE(RFAILED); + } + + RETVALUE(ROK); +} /* rgSCHSc1RgrUlUeCfg */ + +/** + * @brief UE reconfiguration for scheduler + * + * @details + * + * Function : rgSCHSc1RgrUlUeRecfg + * + * This functions updates UE specific scheduler + * information upon UE reconfiguration + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ue + * @param[int] RgrUeRecfg *ueRecfg + * @param[out] RgSchErrInfo *err + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 rgSCHSc1RgrUlUeRecfg +( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgrUeRecfg *ueRecfg, +RgSchErrInfo *err +) +#else +PUBLIC S16 rgSCHSc1RgrUlUeRecfg(cell, ue, ueRecfg, err) +RgSchCellCb *cell; +RgSchUeCb *ue; +RgrUeRecfg *ueRecfg; +RgSchErrInfo *err; +#endif +{ + TRC2(rgSCHSc1RgrUlUeRecfg); + RETVALUE(ROK); +} /* rgSCHSc1RgrUeRecfg */ + +/** + * @brief UE deletion for scheduler + * + * @details + * + * Function : rgSCHSc1UlUeDel + * + * This functions deletes all scheduler information + * pertaining to a UE + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ue + * @return Void + **/ +#ifdef ANSI +PUBLIC Void rgSCHSc1UlUeDel +( +RgSchCellCb *cell, +RgSchUeCb *ue +) +#else +PUBLIC Void rgSCHSc1UlUeDel(cell, ue) +RgSchCellCb *cell; +RgSchUeCb *ue; +#endif +{ + RgSchSc1UlCell *cellUl = RG_GET_SC1_CELL_UL(cell); + RgSchSc1UlUe *ueUl = RG_GET_SC1_UE_UL(ue, cell); + + TRC2(rgSCHSc1UlUeDel); + + if (ueUl == NULLP) + { + RETVOID; + } + if(ueUl->txLnk.node) + { + cmLListDelFrm(&(cellUl->ueTxLst[ueUl->qId]), &(ueUl->txLnk)); + ueUl->txLnk.node = NULLP; + } + if(ueUl->contResLnk.node) + { + cmLListDelFrm(&(cellUl->contResLst), &(ueUl->contResLnk)); + ueUl->contResLnk.node = NULLP; + } + /* ccpu00117052 - MOD - Passing double pointer + for proper NULLP assignment*/ + rgSCHUtlFreeSBuf(cell->instIdx, + (Data**)(&(ueUl)), (sizeof(RgSchSc1UlUe))); + + RETVOID; +} /* rgSCHSc1UlUeDel */ + +/** + * @brief UE Reset for scheduler + * + * @details + * + * Function : rgSCHSc1UlUeReset + * + * Remove this UE from all Scheduling Priority Qs + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ue + * @return Void + **/ +#ifdef ANSI +PUBLIC Void rgSCHSc1UlUeReset +( +RgSchCellCb *cell, +RgSchUeCb *ue +) +#else +PUBLIC Void rgSCHSc1UlUeReset(cell, ue) +RgSchCellCb *cell; +RgSchUeCb *ue; +#endif +{ + RgSchSc1UlCell *cellUl = RG_GET_SC1_CELL_UL(cell); + RgSchSc1UlUe *ueUl = RG_GET_SC1_UE_UL(ue, cell); + + TRC2(rgSCHSc1UlUeReset); + + ueUl->srRcvd = FALSE; + + if(ueUl->txLnk.node) + { + cmLListDelFrm(&(cellUl->ueTxLst[ueUl->qId]), &(ueUl->txLnk)); + ueUl->txLnk.node = NULLP; + } + if(ueUl->contResLnk.node) + { + cmLListDelFrm(&(cellUl->contResLst), &(ueUl->contResLnk)); + ueUl->contResLnk.node = NULLP; + } + RETVOID; +} /* rgSCHSc1UlUeReset */ + + +/** + * @brief Scheduler processing on cell configuration + * + * @details + * + * Function : rgSCHSc1RgrUlCellCfg + * + * This function does requisite initialisation + * and setup for scheduler1 when a cell is + * configured + * + * @param[in] RgSchCellCb *cell + * @param[in] RgrCellCfg *cellCfg + * @param[out] RgSchErrInfo *err + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 rgSCHSc1RgrUlCellCfg +( +RgSchCellCb *cell, +RgrCellCfg *cellCfg, +RgSchErrInfo *err +) +#else +PUBLIC S16 rgSCHSc1RgrUlCellCfg(cell, cellCfg, err) +RgSchCellCb *cell; +RgrCellCfg *cellCfg; +RgSchErrInfo *err; +#endif +{ + RgSchSc1UlCell *cellUl; + + TRC2(rgSCHSc1RgrUlCellCfg); + + if((rgSCHUtlAllocSBuf(cell->instIdx, + (Data**)&(((RgSchCmnCell*)((cell)->sc.sch))->ul.schSpfc), \ + (sizeof(RgSchSc1UlCell))) != ROK)) + { + RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId, + "Memory allocation FAILED"); + err->errCause = RGSCHERR_SCH_SC1_UL_CFG; + RETVALUE(RFAILED); + } + cellUl = RG_GET_SC1_CELL_UL(cell); + cmLListInit(&cellUl->contResLst); + cmLListInit(&cellUl->ueTxLst[0]); + cmLListInit(&cellUl->ueTxLst[1]); + + RETVALUE(ROK); +} /* rgSCHSc1RgrUlCellCfg */ + + +/** + * @brief This function handles the reconfiguration of cell + * + * @details + * + * Function: rgSCHSc1RgrUlCellRecfg + * Purpose: Update the reconfiguration parameters. + * + * Invoked by: Scheduler + * + * @param[in] RgSchCellCb* cell + * @return Void + * + **/ +#ifdef ANSI +PUBLIC S16 rgSCHSc1RgrUlCellRecfg +( +RgSchCellCb *cell, +RgrCellRecfg *recfg, +RgSchErrInfo *err +) +#else +PUBLIC S16 rgSCHSc1RgrUlCellRecfg(cell, recfg, err) +RgSchCellCb *cell; +RgrCellRecfg *recfg; +RgSchErrInfo *err; +#endif +{ + TRC2(rgSCHSc1RgrUlCellRecfg); + RETVALUE(ROK); +} + +/** + * @brief Scheduler processing for cell delete + * + * @details + * + * Function : rgSCHSc1UlCellDel + * + * This functions de-initialises and frees memory + * taken up by scheduler1 for the entire cell. + * + * @param[in] RgSchCellCb *cell + * @return Void + **/ +#ifdef ANSI +PUBLIC Void rgSCHSc1UlCellDel +( +RgSchCellCb *cell +) +#else +PUBLIC Void rgSCHSc1UlCellDel(cell) +RgSchCellCb *cell; +#endif +{ + RgSchSc1UlCell *cellUl = RG_GET_SC1_CELL_UL(cell); + + TRC2(rgSCHSc1UlCellDel); + + if (cellUl == NULLP) + { + RETVOID; + } + /* ccpu00117052 - MOD - Passing double pointer + for proper NULLP assignment*/ + rgSCHUtlFreeSBuf(cell->instIdx, + (Data**)(&(cellUl)), (sizeof(RgSchSc1UlCell))); + + RETVOID; +} /* rgSCHSc1UlCellDel */ + +/** + * @brief Scheduler invocation on logical channel Group addition + * + * @details + * + * Function : rgSCHSc1RgrLcgCfg + * + * This functions does required processing when a new + * (dedicated) logical channel is added. Assumes lcg + * pointer in ulLc is set. + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ue + * @param[in] RgSchLcgCb *lcg + * @param[int] RgrLcgCfg *lcgCfg + * @param[out] RgSchErrInfo *err + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 rgSCHSc1RgrLcgCfg +( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgSchLcgCb *lcg, +RgrLcgCfg *lcgCfg, +RgSchErrInfo *err +) +#else +PUBLIC S16 rgSCHSc1RgrLcgCfg(cell, ue, lcg, lcgCfg, err) +RgSchCellCb *cell; +RgSchUeCb *ue; +RgSchLcgCb *lcg; +RgrLcgCfg *lcgCfg; +RgSchErrInfo *err; +#endif +{ + TRC2(rgSCHSc1RgrLcgCfg); + RETVALUE(ROK); +} /* rgSCHSc1RgrLcgCfg */ + +/** + * @brief Scheduler invocation on logical channel addition + * + * @details + * + * Function : rgSCHSc1RgrLcgRecfg + * + * This functions does required processing when an existing + * (dedicated) logical channel is reconfigured. Assumes lcg + * pointer in ulLc is set to the old value. + * Independent of whether new LCG is meant to be configured, + * the new LCG scheduler info is accessed and possibly modified. + * + * @param[in] RgSchCellCb *cell, + * @param[in] RgSchUeCb *ue, + * @param[in] RgSchLcgCb *lcg, + * @param[in] RgrLcgRecfg *reCfg, + * @param[out] RgSchErrInfo *err + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 rgSCHSc1RgrLcgRecfg +( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgSchLcgCb *lcg, +RgrLcgRecfg *reCfg, +RgSchErrInfo *err +) +#else +PUBLIC S16 rgSCHSc1RgrLcgRecfg(cell, ue, lcg, reCfg, err) +RgSchCellCb *cell; +RgSchUeCb *ue; +RgSchLcgCb *lcg; +RgrLcgRecfg *reCfg; +RgSchErrInfo *err; +#endif +{ + TRC2(rgSCHSc1RgrLcgRecfg); + RETVALUE(ROK); +} /* rgSCHSc1RgrLcgRecfg */ + +/*********************************************************** + * + * Func : rgSCHSc1LcgDel + * + * Desc : Scheduler handling for a (dedicated) + * uplink lcg being deleted + * + * Ret : + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PUBLIC Void rgSCHSc1LcgDel +( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgSchLcgCb *lcg +) +#else +PUBLIC Void rgSCHSc1LcgDel(cell, ue, lcg) +RgSchCellCb *cell; +RgSchUeCb *ue; +RgSchLcgCb *lcg; +#endif +{ + TRC2(rgSCHSc1LcgDel); + rgSCHSc1UlPosnUeInQ(cell, ue); + RETVOID; +} + +/** + * @brief Perform alloction for this UE + * + * @details + * + * Function : rgSCHSc1UlSchdUe + * + * Processing Steps: cater to as much as UE needs, with + * a limitation on maxBits per scheduling instance(per TTI) + * per UE. Return failure, if UE is not considered + * for scheduling (case, where it is already selected for a + * retransmission). + * + * + * @param[in] RgSchUeCb *ue + * @return Void + **/ +#ifdef ANSI +PRIVATE Void rgSCHSc1UlSchdUe +( +RgSchUeCb *ue, +RgSchCellCb *cell +) +#else +PRIVATE Void rgSCHSc1UlSchdUe(ue,cell) +RgSchUeCb *ue; +RgSchCellCb *cell; +#endif +{ + RgSchCmnUlUe *cmnUlUe = RG_SCH_CMN_GET_UL_UE(ue, cell); + /*cell added as part of CA dev*/ + RgSchSc1UlUe *ulUe = RG_GET_SC1_UE_UL(ue, cell); + + TRC2(rgSCHSc1UlSchdUe); + + if(ulUe->srRcvd == TRUE) + { + cmnUlUe->alloc.reqBytes = RGSCH_MAX(RG_SCH_CMN_UL_SR_BYTES, \ + ue->ul.effBsr); + RETVOID; + } + + cmnUlUe->alloc.reqBytes = ue->ul.effBsr; + + RETVOID; +} + +/** + * @brief Scheduler invocation + * + * @details + * + * Function: rgSCHSc1UlSchdForDataTrans + * Purpose: Uplink Scheduling for UE data Transmission. + * + * + * Invoked by: Scheduler + * + * @param[in] RgSchCellCb *cell + * @param[out] RgSchCmnUlRbAllocInfo *allocInfo + * @param[in] U8 remUe + * @return Void + **/ +#ifdef ANSI +PRIVATE Void rgSCHSc1UlSchdForDataTrans +( +RgSchCellCb *cell, +RgSchCmnUlRbAllocInfo *allocInfo, +U8 remUe +) +#else +PRIVATE Void rgSCHSc1UlSchdForDataTrans(cell, allocInfo, remUe) +RgSchCellCb *cell; +RgSchCmnUlRbAllocInfo *allocInfo; +U8 remUe; +#endif +{ + RgSchSc1UlCell *sc1UlCell = RG_GET_SC1_CELL_UL(cell); + + TRC2(rgSCHSc1UlSchdForDataTrans); + + if (remUe == 0) + { + RETVOID; + } + /* Allocate UEs with LCG0 data pending */ + rgSCHSc1UlSchdUeTxLst(cell, &sc1UlCell->ueTxLst[0], allocInfo, &remUe); + + if (remUe == 0) + { + RETVOID; + } + /* Allocate UEs with other LCGs data pending */ + rgSCHSc1UlSchdUeTxLst(cell, &sc1UlCell->ueTxLst[1], allocInfo, &remUe); + + RETVOID; +} + +/** + * @brief Scheduler invocation + * + * @details + * + * Function: rgSCHSc1UlSchdUeTxLst + * Purpose: Uplink Scheduling for UE data Transmission. + * + * + * Invoked by: Scheduler + * + * @param[in] CmLListCp *ueTxLst + * @param[out] RgSchCmnUlRbAllocInfo *allocInfo + * @param[in] U8 *remUe + * @return Void + **/ +#ifdef ANSI +PRIVATE Void rgSCHSc1UlSchdUeTxLst +( +RgSchCellCb *cell, +CmLListCp *ueTxLst, +RgSchCmnUlRbAllocInfo *allocInfo, +U8 *remUe +) +#else +PRIVATE Void rgSCHSc1UlSchdUeTxLst(cell, ueTxLst, allocInfo, remUe) +RgSchCellCb *cell; +CmLListCp *ueTxLst; +RgSchCmnUlRbAllocInfo *allocInfo; +U8 *remUe; +#endif +{ + RgSchUeCb *ue; + CmLList *node; +#ifdef LTEMAC_HDFDD + Bool ulAllowed = FALSE; +#endif + + TRC2(rgSCHSc1UlSchdUeTxLst); + + node = ueTxLst->first; + while ((node) && (*remUe)) + { + ue = (RgSchUeCb *)node->node; + node = node->next; +#ifdef LTEMAC_HDFDD + if (ue->hdFddEnbld) + { + rgSCHCmnHdFddChkUlAllow (cell, ue, &ulAllowed); + if (ulAllowed == FALSE) + { + continue; + } + } +#endif + + if (RG_SCH_CMN_IS_UL_UE_RETX(ue, cell)) + { + /* UE already scheduled in this subframe (for retx) + * OR is inactive for UL Transmission.*/ + continue; + } + /* Added support for SPS*/ +#ifdef LTEMAC_SPS + else if (RG_SCH_CMN_IS_SPS_SCHD(ue, cell)) + { + /*-- Already Scheduled by SPS --*/ + continue; + } +#endif + + rgSCHSc1UlSchdUe(ue,cell);/*cell added as part of CA dev*/ + + rgSCHCmnUlAdd2UeLst(cell, allocInfo, ue); + + --(*remUe); + } + + RETVOID; +} + +/** + * @brief Scheduler invocation + * + * @details + * + * Function: rgSCHSc1UlSchdForContRes + * Purpose: Uplink Scheduling for Contention Resolution. + * + * + * Invoked by: Scheduler + * + * @param[in] RgSchCellCb *cell + * @param[out] RgSchCmnUlRbAllocInfo *allocInfo + * @param[out] U8 *remUe + * @return Void + **/ +#ifdef ANSI +PRIVATE Void rgSCHSc1UlSchdForContRes +( +RgSchCellCb *cell, +RgSchCmnUlRbAllocInfo *allocInfo, +U8 *remUe +) +#else +PRIVATE Void rgSCHSc1UlSchdForContRes(cell, allocInfo, remUe) +RgSchCellCb *cell; +RgSchCmnUlRbAllocInfo *allocInfo; +U8 *remUe; +#endif +{ + RgSchSc1UlCell *sc1UlCell = RG_GET_SC1_CELL_UL(cell); + RgSchUeCb *ue; + CmLList *node; + RgSchCmnUlUe *cmnUlUe; +#ifdef LTEMAC_HDFDD + Bool ulAllowed = FALSE; +#endif + + TRC2(rgSCHSc1UlSchdForContRes); + + node = sc1UlCell->contResLst.first; + while ((node) && (*remUe)) + { + ue = (RgSchUeCb *)node->node; + cmnUlUe = RG_SCH_CMN_GET_UL_UE(ue, cell); + /*cell added as part of CA dev*/ + node = node->next; +#ifdef LTEMAC_HDFDD + if (ue->hdFddEnbld) + { + rgSCHCmnHdFddChkUlAllow (cell, ue, &ulAllowed); + if (ulAllowed == FALSE) + { + continue; + } + } +#endif + if (RG_SCH_CMN_IS_UL_UE_RETX(ue, cell)) + { + /* UE already scheduled in this subframe (for retx) + * OR is inactive for UL Transmission.*/ + continue; + } + cmnUlUe->alloc.reqBytes = RG_SCH_CMN_MAX_UL_CONTRES_GRNT; + rgSCHCmnUlAdd2CntResLst(allocInfo, ue); + --(*remUe); + /* Node removal deferred to ULAllocFinalization */ + } + + RETVOID; +} + +/** + * @brief Scheduler invocation + * + * @details + * + * Function: rgSCHSc1UlNewTx + * Purpose: Uplink Scheduling for New Transmissions. + * + * + * Invoked by: Scheduler + * + * @param[in] RgSchCellCb *cell + * @param[out] RgSchCmnUlRbAllocInfo *allocInfo + * @return Void + **/ +#ifdef ANSI +PRIVATE Void rgSCHSc1UlNewTx +( +RgSchCellCb *cell, +RgSchCmnUlRbAllocInfo *allocInfo +) +#else +PRIVATE Void rgSCHSc1UlNewTx(cell, allocInfo) +RgSchCellCb *cell; +RgSchCmnUlRbAllocInfo *allocInfo; +#endif +{ + RgSchCmnUlCell *cellUl = RG_SCH_CMN_GET_UL_CELL(cell); + U8 remUe = cellUl->maxUeNewTxPerTti; + + TRC2(rgSCHSc1UlNewTx); + + rgSCHSc1UlSchdForContRes(cell, allocInfo, &remUe); + rgSCHSc1UlSchdForDataTrans(cell, allocInfo, remUe); + RETVOID; +} + +/** + * @brief Scheduler invocation + * + * @details + * + * Function: rgSCHSc1UlSched + * Purpose: This function implements an UL scheduler for LTE. This is + * made available as a function pointer to be called + * at the time of TTI processing by the MAC. + * + * Invoked by: Common Scheduler (TTI processing) + * + * @param[in] RgSchCellCb *cell + * @param[out] RgSchCmnUlRbAllocInfo *allocInfo + * @return Void + **/ +#ifdef ANSI +PUBLIC Void rgSCHSc1UlSched +( +RgSchCellCb *cell, +RgSchCmnUlRbAllocInfo *allocInfo +) +#else +PUBLIC Void rgSCHSc1UlSched(cell, allocInfo) +RgSchCellCb *cell; +RgSchCmnUlRbAllocInfo *allocInfo; +#endif +{ + TRC2(rgSCHSc1UlSched); + rgSCHSc1UlNewTx(cell, allocInfo); + RETVOID; +} + +/** + * @brief UEs Buffer Status Has changed so reposition it. + * + * @details + * + * Function : rgSCHSc1UlInsUeInQ + * + * In UE in the list in Descending order of effBsr. + * + * + * @param[in] CmLListCp *lst + * @param[in] RgSchUeCb *ue + * @return Void + **/ +#ifdef ANSI +PRIVATE Void rgSCHSc1UlInsUeInQ +( +CmLListCp *lst, +RgSchUeCb *ue, +RgSchCellCb *cell +) +#else +PRIVATE Void rgSCHSc1UlInsUeInQ(lst, ue, cell) +CmLListCp *lst; +RgSchUeCb *ue; +RgSchCellCb *cell; +#endif +{ + /*cell added as part of CA dev*/ + RgSchSc1UlUe *ueUl = RG_GET_SC1_UE_UL(ue, cell); + RgSchUeCb *lUe; + CmLList *node; + + TRC2(rgSCHSc1UlInsUeInQ); + + node = lst->first; + while(node) + { + lUe = (RgSchUeCb *)(node->node); + if (lUe->ul.effBsr <= ue->ul.effBsr) + { + break; + } + node = node->next; + } + if (node == NULLP) + { + /* We have come to the end of the queue, so Append */ + cmLListAdd2Tail(lst, &ueUl->txLnk); + ueUl->txLnk.node = (PTR)ue; + } + else + { + lst->crnt = node; + cmLListInsCrnt(lst, &ueUl->txLnk); + ueUl->txLnk.node = (PTR)ue; + } + + RETVOID; +} +/** + * @brief UEs Buffer Status Has changed so reposition it. + * + * @details + * + * Function : rgSCHSc1UlPosnUeInQ + * + * -Ues bs value for its LCG has changed, due to either + * allocation or BSR report OR the effUeBR, i.e the byteRate + * has changed due to some allocation, so add/reposition/remove + * it from Qs based on this new bs and/or effUeBR value. + * -If UE has non-zero lcg0 bs value, but the byteRate is + * consumed totally, UE is still schedulable for this control data. + * -If UE's LCG0 has pending bs then position this UE in + * ueTxLst[0]. + * -If Ue has pending BSR to be satisfied, but lcg0's BS + * is 0, then position it in ueTxLst[1]. + * -In any of these 2 Qs, insertion is such that UEs are + * positioned in Descending order of their Pending BS. + * + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ue + * @return Void + **/ +#ifdef ANSI +PRIVATE Void rgSCHSc1UlPosnUeInQ +( +RgSchCellCb *cell, +RgSchUeCb *ue +) +#else +PRIVATE Void rgSCHSc1UlPosnUeInQ(cell, ue) +RgSchCellCb *cell; +RgSchUeCb *ue; +#endif +{ + RgSchSc1UlUe *ueUl = RG_GET_SC1_UE_UL(ue, cell); + /*cell added as part of CA dev*/ + RgSchSc1UlCell *cellUl = RG_GET_SC1_CELL_UL(cell); + RgSchCmnLcg *cmnLcg0 = RG_SCH_CMN_GET_UL_LCG(&ue->ul.lcgArr[0]); + CmLListCp *lst; + + TRC2(rgSCHSc1UlPosnUeInQ); + + if (!RG_SCH_CMN_UL_IS_UE_ACTIVE(ue)) + { + RETVOID; + } + + /* Remove the UE from its existing position */ + if (ueUl->txLnk.node) + { + cmLListDelFrm(&(cellUl->ueTxLst[ueUl->qId]), &(ueUl->txLnk)); + ueUl->txLnk.node = (PTR)NULLP; + } + /* If UE has still bs left for scheduling + * then reposition it */ + if ((ue->ul.effBsr > 0) || (ueUl->srRcvd == TRUE)) + { + /* Select the Queue where UE would be Placed */ + if (cmnLcg0->bs > 0) + { + lst = &cellUl->ueTxLst[0]; + ueUl->qId = 0; + } + else + { + lst = &cellUl->ueTxLst[1]; + ueUl->qId = 1; + } + /* Insert the UE in the Q */ + rgSCHSc1UlInsUeInQ(lst, ue, cell);/*cell added as part of CA dev*/ + } +#ifdef RGR_V1 + else if(ue->ul.totalBsr != 0) + { + if (ue->bsrTmr.tmrEvnt != TMR_NONE) + { + rgSCHTmrStopTmr(cell, ue->bsrTmr.tmrEvnt, ue); + } + if (ue->ul.bsrTmrCfg.isPrdBsrTmrPres) + { + rgSCHTmrStartTmr(cell, ue, RG_SCH_TMR_BSR, + ue->ul.bsrTmrCfg.prdBsrTmr); + } + } +#endif + + RETVOID; +} + +/** + * @brief Short BSR update + * + * @details + * + * Function : rgSCHSc1UpdBsrShort + * + * This functions does requisite updates to handle short BSR reporting + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ue + * @param[in] RgSchLcgCb *lcg + * @param[in] U8 bsr + * @return Void + **/ +#ifdef ANSI +PUBLIC Void rgSCHSc1UpdBsrShort +( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgSchLcgCb *lcg, +U8 bsr +) +#else +PUBLIC Void rgSCHSc1UpdBsrShort(cell, ue, lcg, bsr) +RgSchCellCb *cell; +RgSchUeCb *ue; +RgSchLcgCb *lcg; +U8 bsr; +#endif +{ + TRC2(rgSCHSc1UpdBsrShort); + rgSCHSc1UlPosnUeInQ(cell, ue); + RETVOID; +} /* rgSCHSc1UpdBsrShort */ + +/** + * @brief Truncated BSR update + * + * @details + * + * Function : rgSCHSc1UpdBsrTrunc + * + * This functions does required updates to handle truncated BSR report + * + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ue + * @param[in] RgSchLcgCb *lcg + * @param[in] U8 bsr + * @return Void + **/ +#ifdef ANSI +PUBLIC Void rgSCHSc1UpdBsrTrunc +( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgSchLcgCb *lcg, +U8 bsr +) +#else +PUBLIC Void rgSCHSc1UpdBsrTrunc(cell, ue, lcg, bsr) +RgSchCellCb *cell; +RgSchUeCb *ue; +RgSchLcgCb *lcg; +U8 bsr; +#endif +{ + TRC2(rgSCHSc1UpdBsrTrunc); + rgSCHSc1UlPosnUeInQ(cell, ue); + RETVOID; +} /* rgSCHSc1UpdBsrTrunc */ + +/** + * @brief Long BSR update + * + * @details + * + * Function : rgSCHSc1UpdBsrLong + * + * - Update UE's position within/across uplink scheduling queues + * + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ue + * @param[in] U8 bsArr[] + * @return Void + **/ +#ifdef ANSI +PUBLIC Void rgSCHSc1UpdBsrLong +( +RgSchCellCb *cell, +RgSchUeCb *ue, +U8 *bsArr +) +#else +PUBLIC Void rgSCHSc1UpdBsrLong(cell, ue, bsArr) +RgSchCellCb *cell; +RgSchUeCb *ue; +U8 *bsArr; +#endif +{ + TRC2(rgSCHSc1UpdBsrLong); + rgSCHSc1UlPosnUeInQ(cell, ue); + RETVOID; +} /* rgSCHSc1UpdBsrLong */ + +/** + * @brief UL grant for contention resolution + * + * @details + * + * Function : rgSCHSc1ContResUlGrant + * + * Add UE to another queue specifically for CRNTI based contention + * resolution + * + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ue + * @return Void + **/ +#ifdef ANSI +PUBLIC Void rgSCHSc1ContResUlGrant +( +RgSchCellCb *cell, +RgSchUeCb *ue +) +#else +PUBLIC Void rgSCHSc1ContResUlGrant(cell, ue) +RgSchCellCb *cell; +RgSchUeCb *ue; +#endif +{ + RgSchSc1UlUe *ueUl = RG_GET_SC1_UE_UL(ue, cell); + RgSchSc1UlCell *cellUl = RG_GET_SC1_CELL_UL(cell); + + TRC2(rgSCHSc1ContResUlGrant); + + if (ueUl->contResLnk.node) + { + RETVOID; + } + + /* Remove the UE from other Qs */ + if(ueUl->txLnk.node) + { + cmLListDelFrm(&(cellUl->ueTxLst[ueUl->qId]), &(ueUl->txLnk)); + ueUl->txLnk.node = NULLP; + } + + cmLListAdd2Tail(&cellUl->contResLst, &ueUl->contResLnk); + ueUl->contResLnk.node = (PTR)ue; + RETVOID; +} /* rgSCHSc1ContResUlGrant */ + +/** + * @brief SR reception handling + * + * @details + * + * Function : rgSCHSc1SrRcvd + * Shift the UE with SrInd in to the lcgO queue. + * + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ue + * @return Void + **/ +#ifdef ANSI +PUBLIC Void rgSCHSc1SrRcvd +( +RgSchCellCb *cell, +RgSchUeCb *ue +) +#else +PUBLIC Void rgSCHSc1SrRcvd(cell, ue) +RgSchCellCb *cell; +RgSchUeCb *ue; +#endif +{ + RgSchSc1UlUe *ulUe = RG_GET_SC1_UE_UL(ue, cell); + RgSchSc1UlCell *ulCell = RG_GET_SC1_CELL_UL(cell); + + TRC2(rgSCHSc1SrRcvd); + + ulUe->srRcvd = TRUE; + + if (ulUe->txLnk.node != NULLP) + { + if (ulUe->qId == 0) + { + /* Already present in lcg0 Q */ + RETVOID; + } + cmLListDelFrm(&(ulCell->ueTxLst[ulUe->qId]), &(ulUe->txLnk)); + } + /* Adding the UE to the LCG0 list for SR IND */ + cmLListAdd2Tail(&ulCell->ueTxLst[0], &ulUe->txLnk); + ulUe->txLnk.node = (PTR)ue; + ulUe->qId = 0; + + RETVOID; +} /* rgSCHSc1SrRcvd */ + +/** + * @brief Indication of UL CQI + * + * @details + * + * Function : rgSCHSc1UlCqiInd + * + * - Common Scheduler. SC1 does nothing. + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ue + * @param[in] TfuUlCqiRpt *ulCqiInfo + * @return Void + **/ +#ifdef ANSI +PUBLIC Void rgSCHSc1UlCqiInd +( +RgSchCellCb *cell, +RgSchUeCb *ue, +TfuUlCqiRpt *ulCqiInfo +) +#else +PUBLIC Void rgSCHSc1UlCqiInd(cell, ue, ulCqiInfo) +RgSchCellCb *cell; +RgSchUeCb *ue; +TfuUlCqiRpt *ulCqiInfo; +#endif +{ + TRC2(rgSCHSc1UlCqiInd); + + /* Stack Crash problem for TRACE5 changes. Added the return below */ + RETVOID; + +} + +/** + * @brief UL Lcg received data updation + * + * @details + * + * Function : rgSCHSc1UlLcgUpd + * + * Processing Steps:Sc1 Does nothing + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ue + * @param[in] RgInfUeDatInd *datInd + * @return S16 + **/ +#ifdef ANSI +PUBLIC S16 rgSCHSc1UlLcgUpd +( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgInfUeDatInd *datInd +) +#else +PUBLIC S16 rgSCHSc1UlLcgUpd(cell, ue) +RgSchCellCb *cell; +RgSchUeCb *ue; +RgInfUeDatInd *datInd; +#endif +{ + + TRC2(rgSCHSc1UlLcgUpd); + + RETVALUE(ROK); +} + + +/*********************************************************** + * + * Func : rgSCHSc1UlUeRefresh + * + * Desc : Handle 'refresh' for uplink part of a UE + * (ie UE's uplink AMBR and uplink GBR LCGs are + * refreshed at this point) + * + * Ret : + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PUBLIC Void rgSCHSc1UlUeRefresh +( +RgSchCellCb *cell, +RgSchUeCb *ue +) +#else +PUBLIC Void rgSCHSc1UlUeRefresh(cell, ue) +RgSchCellCb *cell; +RgSchUeCb *ue; +#endif +{ + TRC2(rgSCHSc1UlUeRefresh); + rgSCHSc1UlPosnUeInQ(cell, ue); + RETVOID; +} + +/** + * @brief This function Processes the Final Allocations + * made by the RB Allocator against the requested + * UE data Trans Allocations. + * + * @details + * + * Function: rgSCHSc1UlDatTransAllocFnlz + * Purpose: This function Processes the Final Allocations + * made by the RB Allocator against the requested + * UE data Trans Allocations . + * + * Invoked by: Scheduler + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchCmnDlRbAllocInfo *allocInfo + * @return Void + * + **/ +#ifdef ANSI +PRIVATE Void rgSCHSc1UlDatTransAllocFnlz +( +RgSchCellCb *cell, +RgSchCmnUlRbAllocInfo *allocInfo +) +#else +PRIVATE Void rgSCHSc1UlDatTransAllocFnlz(cell, allocInfo) +RgSchCellCb *cell; +RgSchCmnUlRbAllocInfo *allocInfo; +#endif +{ + RgSchSc1UlUe *ueUl; + RgSchUeCb *ue; + CmLList *node; + RgSchDrxUeCb *drxUe = NULLP; + CmLListCp ulInactvLst; /* list of UE's becoming UL-inactive */ + TRC2(rgSCHSc1UlDatTransAllocFnlz); + + cmLListInit(&ulInactvLst); + node = allocInfo->schdUeLst.first; + while(node) + { + ue = (RgSchUeCb *)node->node; + node = node->next; + ueUl = RG_GET_SC1_UE_UL(ue, cell); + + if (ue->isDrxEnabled) + { + if(ueUl->srRcvd == TRUE) + { + drxUe = RG_SCH_DRX_GET_UE(ue); + drxUe->drxUlInactvMask |= RG_SCH_DRX_SR_BITMASK; + + if(!RG_SCH_DRX_UL_IS_UE_ACTIVE(drxUe)) + { + ue->ul.ulInactvMask |= RG_DRX_INACTIVE; + /* Add to Ul inactive List */ + ue->ulDrxInactvLnk.node = (PTR)ue; + cmLListAdd2Tail(&ulInactvLst,&(ue->ulDrxInactvLnk)); + } + drxUe->srRcvd = FALSE; + } + } + /* Reset no matter */ + ueUl->srRcvd = FALSE; + /* Reposition UE in Qs */ + rgSCHSc1UlPosnUeInQ(cell, ue); +#ifdef LTEMAC_HDFDD + if (ue->hdFddEnbld) + { + rgSCHCmnHdFddUpdULMark (cell,ue); + } +#endif + /* reset the UE UL allocation Information */ + rgSCHCmnUlUeResetTemp(cell, ue); + } + rgSCHSc1UlHndlInActUes(cell, &ulInactvLst); + node = allocInfo->nonSchdUeLst.first; + while(node) + { + ue = (RgSchUeCb *)node->node; + node = node->next; + /* reset the UE UL allocation Information */ + rgSCHCmnUlUeResetTemp(cell, ue); + } + + RETVOID; +} + +/** + * @brief This function Processes the Final Allocations + * made by the RB Allocator against the requested + * cont res Allocations. + * + * @details + * + * Function: rgSCHSc1UlContResAllocFnlz + * Purpose: This function Processes the Final Allocations + * made by the RB Allocator against the requested + * cont res Allocations . + * + * Invoked by: Scheduler + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchCmnDlRbAllocInfo *allocInfo + * @return Void + * + **/ +#ifdef ANSI +PRIVATE Void rgSCHSc1UlContResAllocFnlz +( +RgSchCellCb *cell, +RgSchCmnUlRbAllocInfo *allocInfo +) +#else +PRIVATE Void rgSCHSc1UlContResAllocFnlz(cell, allocInfo) +RgSchCellCb *cell; +RgSchCmnUlRbAllocInfo *allocInfo; +#endif +{ + RgSchSc1UlCell *sc1UlCell = RG_GET_SC1_CELL_UL(cell); + RgSchSc1UlUe *ueUl; + RgSchUeCb *ue; + CmLList *node; + TRC2(rgSCHSc1UlContResAllocFnlz); + + node = allocInfo->schdContResLst.first; + while(node) + { + ue = (RgSchUeCb *)node->node; + node = node->next; +#ifdef LTEMAC_HDFDD + if (ue->hdFddEnbld) + { + rgSCHCmnHdFddUpdULMark (cell,ue); + } +#endif + ueUl = RG_GET_SC1_UE_UL(ue, cell); + + /* Remove UE from Cont Res Q */ + cmLListDelFrm(&sc1UlCell->contResLst, + &ueUl->contResLnk); + ueUl->contResLnk.node = NULLP; + /* reset the UE UL allocation Information */ + rgSCHCmnUlUeResetTemp(cell, ue); + } + + node = allocInfo->nonSchdContResLst.first; + while(node) + { + ue = (RgSchUeCb *)node->node; + node = node->next; + /* reset the UE UL allocation Information */ + rgSCHCmnUlUeResetTemp(cell, ue); + } + + RETVOID; +} + +/** + * @brief This function Processes the Final Allocations + * made by the RB Allocator against the requested. + * + * @details + * + * Function: rgSCHSc1UlAllocFnlz + * Purpose: This function Processes the Final Allocations + * made by the RB Allocator against the requested. + * + * Invoked by: Common Scheduler + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchCmnDlRbAllocInfo *allocInfo + * @return Void + * + **/ +#ifdef ANSI +PUBLIC Void rgSCHSc1UlAllocFnlz +( +RgSchCellCb *cell, +RgSchCmnUlRbAllocInfo *allocInfo +) +#else +PUBLIC Void rgSCHSc1UlAllocFnlz(cell, allocInfo) +RgSchCellCb *cell; +RgSchCmnUlRbAllocInfo *allocInfo; +#endif +{ + TRC2(rgSCHSc1UlAllocFnlz); + + rgSCHSc1UlContResAllocFnlz(cell, allocInfo); + rgSCHSc1UlDatTransAllocFnlz(cell, allocInfo); + + RETVOID; +} + + +/** + * @brief Scheduler invocation + * + * @details + * + * Function: rgSCHSc1UlActvtUe + * Purpose: Put back the UE in to appropriate Qs. + * + * Invoked by: Common Scheduler + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ue + * @return Void + **/ +#ifdef ANSI +PUBLIC Void rgSCHSc1UlActvtUe +( +RgSchCellCb *cell, +RgSchUeCb *ue +) +#else +PUBLIC Void rgSCHSc1UlActvtUe(cell, ue) +RgSchCellCb *cell; +RgSchUeCb *ue; +#endif +{ + TRC2(rgSCHSc1UlActvtUe); + + rgSCHSc1UlPosnUeInQ(cell, ue); + RETVOID; +} + +/** + * @brief Scheduler invocation + * + * @details + * + * Function: rgSCHSc1UlHndlInActUes + * Purpose: The list of inactive UEs present in inactvLst should + * be removed from the scheduling Qs. + * But store the information pertaining to which Qs, + * were they belonging to. This information shall be used + * to put them back in appropriate Qs when their Activation + * is initiated. + * + * Invoked by: Common Scheduler (TTI processing) + * + * @param[in] RgSchCellCb *cell + * @param[out] CmLListCp *inactvLst + * @return Void + **/ +#ifdef ANSI +PUBLIC Void rgSCHSc1UlHndlInActUes +( +RgSchCellCb *cell, +CmLListCp *inactvLst +) +#else +PUBLIC Void rgSCHSc1UlHndlInActUes(cell, inactvLst) +RgSchCellCb *cell; +CmLListCp *inactvLst; +#endif +{ + RgSchUeCb *ue; + RgSchSc1UlUe *ulUe; + RgSchSc1UlCell *cellUl = RG_GET_SC1_CELL_UL(cell); + CmLList *node = inactvLst->first; + + TRC2(rgSCHSc1UlHndlInActUes); + + while (node) + { + ue = (RgSchUeCb *)node->node; + node = node->next; + ulUe = RG_GET_SC1_UE_UL(ue, cell); + if(ulUe->txLnk.node) + { + cmLListDelFrm(&(cellUl->ueTxLst[ulUe->qId]), &(ulUe->txLnk)); + /* This is required as lcg bs might change during + * inactivity to activity. So we need to recompute + * its position. */ + ulUe->txLnk.node = NULLP; + } + /* Do not remove UE from contResLst */ + } + RETVOID; +} +/** + * @brief Scheduler invocation + * + * @details + * + * Function: rgSCHSc1DlProcRmvFrmRetx + * Purpose: To remove the Harq process from the cell and from the UE + * retransmission list + * + * Invoked by: Common Scheduler (TTI processing) + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ue; + * @param[in] RgSchDlHqProcCb *hqP + * @return Void + **/ + +#ifdef ANSI +PUBLIC Void rgSCHSc1DlProcRmvFrmRetx( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgSchDlHqProcCb *hqP +) +#else +PUBLIC Void rgSCHSc1DlProcRmvFrmRetx(cell, ue, hqP) +RgSchCellCb *cell; +RgSchUeCb *ue; +RgSchDlHqProcCb *hqP; +#endif +{ + TRC2(rgSCHSc1DlProcRmvFrmRetx); + /* Remove the HqP from retx Queue. + Release HqP.*/ + rgSCHSc1DlProcRmvFrmCellRetx(cell, hqP); + rgSCHSc1DlProcRmvFrmUeRetx(cell, ue, hqP); + RETVOID; +} + + + + +/********************************************************************** + + End of file +**********************************************************************/ diff --git a/src/5gnrmac/rg_sch_sc1.h b/src/5gnrmac/rg_sch_sc1.h new file mode 100755 index 000000000..5af8afec6 --- /dev/null +++ b/src/5gnrmac/rg_sch_sc1.h @@ -0,0 +1,95 @@ +/******************************************************************************* +################################################################################ +# Copyright (c) [2017-2019] [Radisys] # +# # +# 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. # +################################################################################ +*******************************************************************************/ + +/********************************************************************** + Name: LTE MAC SC1 scheduler + + Type: C header file + + Desc: Defines required by SC1 scheduler + + File: rg_sch_sc1.h + +*********************************************************************21*/ + + +#ifndef __RGSCHSC1H__ +#define __RGSCHSC1H__ +#ifdef __cplusplus +extern "C" { +#endif + + +/*********************************************************************** + Macro Definitions + ***********************************************************************/ + +/* Scheduler1 tunable params */ + +#define RG_GET_SC1_CELL_UL(cell) \ + ((RgSchSc1UlCell *)((RgSchCmnCell*)((cell)->sc.sch))->ul.schSpfc) +#define RG_GET_SC1_CELL_DL(cell) \ + ((RgSchSc1DlCell *)((RgSchCmnCell*)((cell)->sc.sch))->dl.schSpfc) + +#define RG_GET_SC1_UE_DL(ue, cell) \ + ((RgSchSc1DlUe *)((RgSchCmnUe *)((ue->cellInfo[ue->cellIdToCellIdxMap\ + [RG_SCH_CELLINDEX(cell)]])->sch))->dl.schSpfc) +#define RG_GET_SC1_UE_UL(ue, cell) \ + ((RgSchSc1UlUe *)((RgSchCmnUe *)((ue->cellInfo[ue->cellIdToCellIdxMap\ + [RG_SCH_CELLINDEX(cell)]])->sch))->ul.schSpfc) + +#define RG_GET_SC1_SVC_DL(_ue,_svc,_cell) RG_SCH_CMN_GET_LC_SCH_SPFC(_ue,_svc,_cell) + +#define RG_GET_SC1_HQP_DL(hqP) \ + ((RgSchSc1DlHqProc *)((RgSchCmnDlHqProc *)((hqP)->sch))->schSpfc) + +#define RG_SC1_SVC_HAS_DATA(_svc,_cell) \ + (((RgSchSc1DlSvc *)(((RgSchCmnDlSvc *)(_svc->sch))->schSpfc[\ + svc->ue->cellIdToCellIdxMap[RG_SCH_CELLINDEX(_cell)]]))->effMbr != 0) + + +#define RG_SC1_ISGBRPRIO(qciPrio) ((qciPrio) >=2 && (qciPrio) <= 5) + +/* SC1 configuration error types */ +#define RGSCHERR_SCH_SC1_DL_CFG (RGSCHERR_SCH_CFG + 10) +#define RGSCHERR_SCH_SC1_UL_CFG (RGSCHERR_SCH_CFG + 11) + +/* Scheduler1 fixed params */ +#define RG_SC1_UL_INVALID_QID 255 +#define RG_SC1_QCIPRIOVAL_MAX 9 +#define RG_SC1_QCIPRIOVAL_MIN 1 +#define RG_SC1_UL_CONT_RES_QID 0 +#define RG_SC1_MAX_DL_AMBR 0xffffffff +#define RG_SC1_UL_NUM_Q (RG_SCH_CMN_NUM_QCI + 1) +#define RG_SC1_DL_NUM_Q (RG_SCH_CMN_MAX_PRIO + 1) +#ifdef RG_UNUSED +#define RG_SC1_UL_INVALID_BETA8 0xffff +#endif +#define RG_SCH_SC1_DL_GBR_PRIO_START 1 +#define RG_SCH_SC1_DL_GBR_PRIO_END 4 +#define RG_SCH_SC1_DL_PRIOS RG_SCH_CMN_MAX_PRIO + 1 + +#ifdef __cplusplus +} +#endif +#endif /* __RGSCHSC1H__ */ + +/********************************************************************30** + + End of file +**********************************************************************/ diff --git a/src/5gnrmac/rg_sch_sc1.x b/src/5gnrmac/rg_sch_sc1.x new file mode 100755 index 000000000..f60ab1029 --- /dev/null +++ b/src/5gnrmac/rg_sch_sc1.x @@ -0,0 +1,367 @@ +/******************************************************************************* +################################################################################ +# Copyright (c) [2017-2019] [Radisys] # +# # +# 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. # +################################################################################ +*******************************************************************************/ + +/********************************************************************** + + Name: LTE MAC SC1 scheduler + + Type: C include file + + Desc: Defines required by SC1 scheduler + + File: rg_sch_sc1.x + +**********************************************************************/ +/** @file rg_sch_sc1.x +@brief This file contains data structures for the SC1 scheduler. +*/ + +#ifndef __RGSCHSC1X__ +#define __RGSCHSC1X__ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + +typedef Void (*RgSchSc1SvcMngFunc) ARGS((RgSchCellCb *cell, RgSchUeCb *ue, RgSchDlLcCb *svc)); + +/** + * @brief + * Cell specific downlink scheduling information for Scheduler type 1. + */ +typedef struct rgSc1DlCell +{ + CmLListCp prioLst[RG_SC1_DL_NUM_Q]; /*!< Priority queues */ + CmLListCp retxLst[RG_SC1_DL_NUM_Q]; /*!< Retransmission queues */ + RgSchSc1SvcMngFunc svcMngFunc[RG_SC1_DL_NUM_Q]; /*!< Function for managing + services */ +} RgSchSc1DlCell; + +/** + * @brief + * Cell specific uplink scheduling information for Scheduler type 1. + */ +typedef struct rgSc1UlCell +{ + CmLListCp contResLst;/*!< UEs with pending UL alloc for msg4 */ + CmLListCp ueTxLst[2];/*!< Queue for UEs Ded Data Trans + * ueTxLst[0] for signalling and + * ueTxLst[1] for other data */ +} RgSchSc1UlCell; + +/** + * @brief + * Uplink information for scheduler per UE. + */ +typedef struct rgSc1UlUe +{ + CmLList txLnk; /* Lnk to one of Transmission Queues */ + CmLList contResLnk; /* Lnk to one of Cont Res Queue */ + Bool srRcvd; /* TRUE if SR reported is yet to be satisfied */ + U8 qId; /* Id of the Tx Q to which this UE belongs */ +} RgSchSc1UlUe; + +/** + * @brief + * Downlink information for scheduler per UE. + */ +typedef struct rgSc1DlUe +{ + CmLList prioLnk; /*!< To link UE into priority queues */ + CmLListCp gbrSvcs; /*!< List of GBR services */ + U8 prio; /*!< Current priority of UE for DL */ + CmLListCp ambrLst; /*!< To maintain services per priority for a UE */ + RgSchDlLcCb *ambrSvc;/*!< Points to the current AMBR service */ + U32 ambr; /*!< UE's Remaining AMBR */ + U32 effAmbr; /*!< min(svc->bo, ambr)*/ + CmLListCp schdSvcs; /*!< List of services for which + allocation requested */ + U8 taReqBytes;/*!< Set to the Number of bytes Requested for TA + allocation */ + CmLListCp retxHqProcs; /*!< List of RETX Hq Procs in suspension */ + CmLListCp lcsWithData; /*!< List of services with non-zero effBo */ +} RgSchSc1DlUe; + +/** + * @brief + * Downlink HARQ information for SC1 scheduler per UE. + */ +typedef struct rgSc1DlHqProc { + CmLList retxLnkUe; /*!< To link retransmitting HARQ processes in ue */ + U8 cqi; /*!< CQI at which the allocation was made */ + U8 prio; /*!< Priority of the allocation */ +}RgSchSc1DlHqProc; + +/** + * @brief + * Downlink service information for SC1 scheduler per UE. + */ +typedef struct rgSc1DlSvc { + U32 gbr; /*!< Pending GBR to be satisfied */ + U32 mbr; /*!< Pending MBR to be satisfied */ + U32 bo; /*!< BO yet to be satisfied */ + U32 effGbr; /*!< GBR/BO, lower of the two */ + U32 effMbr; /*!< MBR/BO, lower of the two */ + CmLList gbrLnk; /*!< used to maintain svcs to be refreshed */ + CmLList prioLnk; /*!< Used to queue up services on UE */ + CmLList schdSvcLnk; /*!< Used to queue up services on UE + * scheduled svcs list */ + U32 reqBytes; /*!< Set to number of bytes Req for Allocation */ + U16 hdrEstimate; /*!< RLC Hdr est computed during SVC allocn */ + CmLList lcWithDataLnk;/*!< Used to maintain svc in ue's + * lcsWithData List */ +} RgSchSc1DlSvc; + + +EXTERN Void rgSCHSc1DlLcRmv ARGS(( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgSchDlLcCb *svc +)); +EXTERN Void rgSCHSc1DlLcBoUpd ARGS(( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgSchDlLcCb *svc +)); +EXTERN Void rgSCHSc1DlProcAddToCellRetx ARGS(( +RgSchCellCb *cell, +RgSchDlHqProcCb *hqP +)); +EXTERN Void rgSCHSc1DlAllocFnlz ARGS(( +RgSchCellCb *cell, +RgSchCmnDlRbAllocInfo *allocInfo +)); +EXTERN Void rgSCHSc1UlAllocFnlz ARGS(( +RgSchCellCb *cell, +RgSchCmnUlRbAllocInfo *allocInfo +)); +EXTERN Void rgSCHSc1UlCqiInd ARGS(( +RgSchCellCb *cell, +RgSchUeCb *ue, +TfuUlCqiRpt *ulCqiInfo +)); +EXTERN S16 rgSCHSc1UlLcgUpd ARGS(( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgInfUeDatInd *datInd +)); + +EXTERN Void rgSCHSc1DlCqiInd ARGS(( +RgSchCellCb *cell, +RgSchUeCb *ue, +Bool isPucchInfo, +Void *dlCqi +)); +EXTERN Void rgSCHSc1UlUeRefresh ARGS(( +RgSchCellCb *cell, +RgSchUeCb *ue +)); +EXTERN Void rgSCHSc1UlUeReset ARGS(( +RgSchCellCb *cell, +RgSchUeCb *ue +)); +EXTERN Void rgSCHSc1DlUeRefresh ARGS(( +RgSchCellCb *cell, +RgSchUeCb *ue +)); +EXTERN Void rgSCHSc1DlHndlInActUes ARGS(( +RgSchCellCb *cell, +CmLListCp *inactvLst +)); +EXTERN Void rgSCHSc1UlHndlInActUes ARGS(( +RgSchCellCb *cell, +CmLListCp *inactvLst +)); +EXTERN Void rgSCHSc1UlActvtUe ARGS(( +RgSchCellCb *cell, +RgSchUeCb *ue +)); +EXTERN Void rgSCHSc1DlActvtUe ARGS(( +RgSchCellCb *cell, +RgSchUeCb *ue +)); +EXTERN Void rgSCHSc1DlInit ARGS(( +RgDlSchdApis *apis +)); +EXTERN Void rgSCHSc1UlInit ARGS(( +RgUlSchdApis *apis +)); +EXTERN S16 rgSCHSc1RgrUlCellCfg ARGS(( +RgSchCellCb *cell, +RgrCellCfg *cellCfg, +RgSchErrInfo *err +)); +EXTERN S16 rgSCHSc1RgrDlCellCfg ARGS(( +RgSchCellCb *cell, +RgrCellCfg *cellCfg, +RgSchErrInfo *err +)); +EXTERN Void rgSCHSc1UlCellDel ARGS(( +RgSchCellCb *cell +)); +EXTERN Void rgSCHSc1DlCellDel ARGS(( +RgSchCellCb *cell +)); +EXTERN S16 rgSCHSc1RgrUlUeCfg ARGS(( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgrUeCfg *ueCfg, +RgSchErrInfo *err +)); +EXTERN S16 rgSCHSc1RgrDlUeCfg ARGS(( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgrUeCfg *ueCfg, +RgSchErrInfo *err +)); +EXTERN S16 rgSCHSc1RgrUlUeRecfg ARGS(( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgrUeRecfg *ueRecfg, +RgSchErrInfo *err +)); +EXTERN S16 rgSCHSc1RgrDlUeRecfg ARGS(( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgrUeRecfg *ueRecfg, +RgSchErrInfo *err +)); +EXTERN Void rgSCHSc1UlUeDel ARGS(( +RgSchCellCb *cell, +RgSchUeCb *ue +)); +EXTERN Void rgSCHSc1DlUeDel ARGS(( +RgSchCellCb *cell, +RgSchUeCb *ue +)); +EXTERN S16 rgSCHSc1RgrLcCfg ARGS(( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgSchDlLcCb *dlLc, +RgrLchCfg *lcCfg, +RgSchErrInfo *err +)); +EXTERN S16 rgSCHSc1RgrLcgCfg ARGS(( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgSchLcgCb *lcg, +RgrLcgCfg *lcgCfg, +RgSchErrInfo *err +)); +EXTERN S16 rgSCHSc1RgrLcRecfg ARGS(( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgSchDlLcCb *dlLc, +RgrLchRecfg *lcRecfg, +RgSchErrInfo *err +)); +EXTERN S16 rgSCHSc1RgrLcgRecfg ARGS(( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgSchLcgCb *lcg, +RgrLcgRecfg *reCfg, +RgSchErrInfo *err +)); +EXTERN Void rgSCHSc1LcgDel ARGS(( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgSchLcgCb *lcg +)); +EXTERN Void rgSCHSc1UpdBsrShort ARGS(( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgSchLcgCb *lcg, +U8 bsr +)); +EXTERN Void rgSCHSc1UpdBsrTrunc ARGS(( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgSchLcgCb *lcg, +U8 bsr +)); +EXTERN Void rgSCHSc1UpdBsrLong ARGS(( +RgSchCellCb *cell, +RgSchUeCb *ue, +U8 bsArr[] +)); +EXTERN Void rgSCHSc1ContResUlGrant ARGS(( +RgSchCellCb *cell, +RgSchUeCb *ue +)); +EXTERN Void rgSCHSc1SrRcvd ARGS(( +RgSchCellCb *cell, +RgSchUeCb *ue +)); +EXTERN Void rgSCHSc1UlSched ARGS(( +RgSchCellCb *cell, +RgSchCmnUlRbAllocInfo *allocInfo +)); +EXTERN Void rgSCHSc1DlSched ARGS(( +RgSchCellCb *cell, +RgSchCmnDlRbAllocInfo *allocInfo +)); +EXTERN S16 rgSCHSc1RgrUlCellRecfg ARGS(( +RgSchCellCb *cell, +RgrCellRecfg *recfg, +RgSchErrInfo *err +)); +EXTERN Void rgSCHSc1DlUeReset ARGS(( +RgSchCellCb *cell, +RgSchUeCb *ue +)); + +EXTERN S16 rgSCHSc1DlUeHqEntInit ARGS(( +RgSchCellCb *cell, +RgSchDlHqEnt *hqEnt +)); + +EXTERN S16 rgSCHSc1DlUeHqEntDeInit ARGS(( +RgSchCellCb *cell, +RgSchDlHqEnt *hqE +)); + +EXTERN S16 rgSCHSc1UlLchCfg ARGS(( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgrLchCfg *cfg, +RgSchErrInfo *err +)); + +EXTERN S16 rgSCHSc1UlLchRecfg ARGS(( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgrLchRecfg *recfg, +RgSchErrInfo *err +)); + +EXTERN S16 rgSCHSc1UlLchDel ARGS(( +RgSchCellCb *cell, +RgSchUeCb *ue, +CmLteLcId lcId, +U8 lcgId +)); +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* __RGSCHSC1X__ */ + + +/********************************************************************** + End of file +**********************************************************************/ diff --git a/src/5gnrmac/rg_sch_scell.c b/src/5gnrmac/rg_sch_scell.c new file mode 100755 index 000000000..ffa51ba66 --- /dev/null +++ b/src/5gnrmac/rg_sch_scell.c @@ -0,0 +1,1990 @@ +/******************************************************************************* +################################################################################ +# Copyright (c) [2017-2019] [Radisys] # +# # +# 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. # +################################################################################ +*******************************************************************************/ + +/************************************************************************ + + Name: LTE-MAC layer + + Type: C source file + + Desc: C source code for Round Robin functions + + File: rg_sch_scell.c + +**********************************************************************/ + +/** @file rg_sch_rr.c +@brief This module handles the round robin scheduler functionality +*/ + +/* header include files -- defines (.h) */ +#include "envopt.h" /* environment options */ +#include "envdep.h" /* environment dependent */ +#include "envind.h" /* environment independent */ +#include "gen.h" /* general layer */ +#include "ssi.h" /* system service interface */ +#include "cm5.h" /* common timers */ +#include "cm_hash.h" /* common hash list */ +#include "cm_llist.h" /* common linked list library */ +#include "cm_err.h" /* common error */ +#include "cm_lte.h" /* common LTE */ +#include "lrg.h" +#include "rgr.h" +#include "rgm.h" +#include "tfu.h" +#include "rg_env.h" +#include "rg_sch_inf.h" +#include "rg_sch_err.h" +#include "rg_sch.h" +#include "rg_sch_cmn.h" + +/* header/extern include files (.x) */ +#include "gen.x" /* general layer typedefs */ +#include "ssi.x" /* system services typedefs */ +#include "cm5.x" /* common timers */ +#include "cm_hash.x" /* common hash list */ +#include "cm_lib.x" /* common library */ +#include "cm_llist.x" /* common linked list */ +#include "cm_mblk.x" /* memory management */ +#include "cm_tkns.x" /* common tokens */ +#include "cm_lte.x" /* common tokens */ +#include "tfu.x" /* RGU types */ +#include "lrg.x" /* layer management typedefs for MAC */ +#include "rgr.x" /* layer management typedefs for MAC */ +#include "rgm.x" /* layer management typedefs for MAC */ +#include "rg_sch_inf.x" /* typedefs for Scheduler */ +#include "rg_sch.x" /* typedefs for Scheduler */ +#include "rg_sch_cmn.x" + +#ifdef LTE_ADV + +PUBLIC Void rgSCHSCellActivation ARGS(( +RgSchUeCellInfo *sCell +)); + +PUBLIC Void rgSCHSCellSchdActDeactCe ARGS(( +RgSchUeCb *ueCb, +RgSchDlHqTbCb *tbInfo +)); +PUBLIC Void rgSCHSCellAddToActDeactLst ARGS(( +RgSchCellCb *cell, +RgSchUeCb *ue +)); + +PUBLIC Void rgSCHSCellRmvFrmActLst ARGS(( +RgSchCellCb *cell, +RgSchUeCb *ue +)); +PUBLIC S16 rgSCHSCellIsActive ARGS(( +RgSchCellCb *cell, +RgSchUeCb *ue +)); + +PUBLIC Void rgSCHSCellHndlFdbkInd ARGS(( +RgSchDlHqProcCb *hqP, +U8 tbIdx, +U8 fdbk, +Bool maxHqRetxReached +)); + +#ifdef LTE_ADV +PUBLIC Void rgSCHSCellDeactTmrExpry ARGS(( +RgSchUeCellInfo *sCell +)); +#endif + +PUBLIC Void rgSCHSCellDelUeSCell ARGS(( +RgSchCellCb *cellCb, +RgSchUeCb *ueCb, +U8 sCellIdx +)); + +PUBLIC S16 rgSCHSCellDelUe ARGS(( +RgSchCellCb *cellCb, +RgSchUeCb *ueCb +)); +#ifdef TFU_UPGRADE +PUBLIC S16 rgSCHSCellPCqiCfg ARGS(( +RgSchCellCb *priCellCb, +RgSchCellCb *secCellCb, +RgSchUeCb *ueCb, +RgrUePrdDlCqiCfg *cqiCfg, +CmLteUeCategory ueCat, +U8 sCellIdx +)); +#endif +PRIVATE S16 rgSCHSCellTrgMacHqEReset ARGS(( +Inst inst, +U16 secCellId, +U16 rnti +)); + + + +/** * @brief Handler for scheduling Scell Activation CE. + * + * @details + * + * Function : rgSCHDhmShcdSCellActCe + * + * This function is called by scheduler when resource allocation + * for SCell Activation CE transmission is done. + * + * @param[in] RgSchUeCb *ue + * @param[out] RgSchDlHqTbCb *tbInfo + * @return Void + * -# None. + **/ +#ifdef ANSI +PUBLIC Void rgSCHSCellSchdActDeactCe +( +RgSchUeCb *ueCb, +RgSchDlHqTbCb *tbInfo +) +#else +PUBLIC Void rgSCHSCellSchdActDeactCe(ueCb, tbInfo) +RgSchUeCb *ueCb; +RgSchDlHqTbCb *tbInfo; +#endif +{ + + U8 bitVal = 0; + U8 sCellActDeactBitMask = 0; + TRC3(rgSCHSCellSchdActDeactCe); + + /* Change the state of all Scells waiting for + * activation */ + + /* ------------------------- + * | C7|C6|C5|C4|C3|C2|C1|R| + * -------------------------*/ + /* 1 for activation + * 0 for deactivation + * */ + + for(U8 idx = 1; idx <= RG_SCH_MAX_SCELL ; idx++) + { + if(ueCb->cellInfo[idx] != NULLP) + { + switch(ueCb->cellInfo[idx]->sCellState) + { + case RG_SCH_SCELL_TOBE_ACTIVATED: + case RG_SCH_SCELL_ACTVTN_IN_PROG: + { + ueCb->cellInfo[idx]->sCellState = RG_SCH_SCELL_ACTVTN_IN_PROG; + bitVal = 1; + } + break; + case RG_SCH_SCELL_ACTIVE: + { + bitVal = 1; + } + break; + case RG_SCH_SCELL_TOBE_DEACTIVATED: + case RG_SCH_SCELL_DEACTVTN_IN_PROG: + { + ueCb->cellInfo[idx]->sCellState = RG_SCH_SCELL_DEACTVTN_IN_PROG; + bitVal = 0; + } + break; + case RG_SCH_SCELL_INACTIVE: + case RG_SCH_SCELL_READY: + { + bitVal = 0; + } + break; + } + } + if(1 == bitVal) + { + sCellActDeactBitMask |= 1 << (idx);/* servCellIdx = idx + 1 */ + bitVal = 0; + } + } + tbInfo->schdSCellActCe.pres = PRSNT_NODEF; + tbInfo->schdSCellActCe.val = sCellActDeactBitMask; + + RETVOID; +} /* rgSCHSCellSchdActDeactCe */ + + +/** + * @brief Adds an UE to the Cell's SCell Activation list + * + * @details + * + * Function: rgSCHSCellAddToActDeactLst + * Purpose: Adds an UE to Cell's SCEll Act list + * + * Invoked by: Common Scheduler + * + * @param[in] RgSchCellCb* cell + * @param[in] RgSchUeCb* ue + * @return Void + * + **/ +#ifdef ANSI +PUBLIC Void rgSCHSCellAddToActDeactLst +( +RgSchCellCb *cell, +RgSchUeCb *ue +) +#else +PUBLIC Void rgSCHSCellAddToActDeactLst(cell, ue) +RgSchCellCb *cell; +RgSchUeCb *ue; +#endif +{ + RgSchCmnDlCell *cellCmnDl = RG_SCH_CMN_GET_DL_CELL(cell); + TRC3(rgSCHSCellAddToActDeactLst); + + if(NULLP == ue->sCellActLnk.node) + {/* Ue is not present in the list */ + cmLListAdd2Tail(&cellCmnDl->secCellActCeLst, &ue->sCellActLnk); + ue->sCellActLnk.node = (PTR)ue; + } + else + { + RGSCHDBGINFONEW(cell->instIdx,(rgSchPBuf(cell->instIdx), + "SCell is already added in the Act List: ueId(%u)\n", ue->ueId)); + } + + RETVOID; +} + + +/** + * @brief Removes an UE from Cell's SCell Activation list + * + * @details + * + * Function: rgSCHSCellRmvFrmActLst + * Purpose: Removes an UE from Cell's SCEll Act list + * + * Invoked by: Specific Scheduler + * + * @param[in] RgSchCellCb* cell + * @param[in] RgSchUeCb* ue + * @return Void + * + **/ +#ifdef ANSI +PUBLIC Void rgSCHSCellRmvFrmActLst +( +RgSchCellCb *cell, +RgSchUeCb *ue +) +#else +PUBLIC Void rgSCHSCellRmvFrmActLst(cell, ue) +RgSchCellCb *cell; +RgSchUeCb *ue; +#endif +{ + RgSchCmnDlCell *cellCmnDl = RG_SCH_CMN_GET_DL_CELL(cell); + TRC3(rgSCHSCellRmvFrmActLst); + if (NULLP != ue->sCellActLnk.node) + { + cmLListDelFrm(&cellCmnDl->secCellActCeLst, &ue->sCellActLnk); + } + ue->sCellActLnk.node = (PTR)NULLP; + + RETVOID; +} + +/** + * @brief Handling of SCell Activation + * + * @details + * + * Function: rgSCHSCellActivation + * Purpose : Perform Activation of secondary cell + * : Move the state to ACTIVE + * : Start the procedure for PCQI/SRS for this scell + * + * Invoked by:Cfg/Commn Scheduler + * + * @param[in] RgSchUeCellInfo *sCellInfo + * + * @return ROK/RFAILED + * + **/ +#ifdef ANSI +PUBLIC Void rgSCHSCellActivation +( +RgSchUeCellInfo *sCellInfo +) +#else +PUBLIC Void rgSCHSCellActivation(sCellInfo) +RgSchUeCellInfo *sCellInfo +#endif +{ + RgSchCellCb *sCell = sCellInfo->cell; + RgSchUeCb *ueCb = sCellInfo->ue; + RgSchCmnCell *cellSch; +#ifdef TFU_UPGRADE +#ifdef DEBUGP + Inst inst = ueCb->cell->instIdx; +#endif + U16 tempIdx; + RgrUePrdDlCqiCfg *cqiCfg; + U8 j; /*Bandwidth Parts*/ + U16 riTrInsTime; + U16 periodicity; + U16 cqiTrInstTime; + RgSchUePCqiCb *cqiCb = NULLP; + CmLteTimingInfo timingInfo; + U16 crntTime; +#endif + + TRC3(rgSCHSCellActivation); + + sCellInfo->sCellState = RG_SCH_SCELL_ACTIVE; +#ifdef TENB_STATS + ueCb->tenbStats->stats.persistent.numActivation++; +#endif + +#ifdef CA_DBG + printf("ueId is SCELL_ACTIVE\n ueCb->ueId = %d sCell->sCellIdx =%d, sCell->sCellId=%d, sCell->sCellState=%d \n", ueCb->ueId, sCellInfo->sCellIdx, sCellInfo->sCellId, sCellInfo->sCellState); +#endif + /* Start the sCellDeactivation timer if cfgd */ + if(PRSNT_NODEF == ueCb->sCellDeactTmrVal.pres) + { + //rgSCHTmrStartTmr (sCell,sCellInfo ,RG_SCH_TMR_SCELL_DEACT, + // ueCb->sCellDeactTmrVal.val); + } + +#ifdef TFU_UPGRADE + /* Start receiving CQI for this SCell for this UE */ + crntTime = (ueCb->cell->crntTime.sfn * RGSCH_NUM_SUB_FRAMES_5G)+ + (ueCb->cell->crntTime.subframe); + + cqiCb = &sCellInfo->cqiCb; + cqiCfg = &cqiCb->cqiCfg; + if (cqiCfg->type == RGR_SCH_PCQI_SETUP) + { + cqiTrInstTime = ((cqiCb->cqiPeri+crntTime) - cqiCb->cqiOffset) + %cqiCb->cqiPeri; + cqiCb->nCqiTrIdx = (crntTime + + (cqiCb->cqiPeri - cqiTrInstTime)); + /* Introduced timing delta for reception req + * in FDD*/ + if(cqiCb->nCqiTrIdx <= (crntTime + TFU_RECPREQ_DLDELTA)) + { + cqiCb->nCqiTrIdx = cqiCb->nCqiTrIdx + cqiCb->cqiPeri; + } + + timingInfo.sfn = cqiCb->nCqiTrIdx/RGSCH_NUM_SUB_FRAMES_5G; + timingInfo.subframe = cqiCb->nCqiTrIdx%RGSCH_NUM_SUB_FRAMES_5G; + if(cqiCb->cqiCfg.cqiSetup.cqiRepType == RGR_UE_PCQI_SB_REP) + { + rgSCHTomUtlPcqiSbCalcBpIdx(timingInfo,ueCb,cqiCb); + } + + cqiCb->nCqiTrIdx = cqiCb->nCqiTrIdx + %RG_SCH_PCQI_SRS_SR_TRINS_SIZE; + RGSCHDBGINFONEW(inst, (rgSchPBuf(inst), "CQI Config: idx(%u) Periodicity %u" + "Offset %u uePosInQ (%u)\n", cqiCfg->cqiSetup.cqiPCfgIdx, + cqiCb->cqiPeri, cqiCb->cqiOffset,cqiCb->nCqiTrIdx)); + + cmLListAdd2Tail(&ueCb->cell->pCqiSrsSrLst[cqiCb->nCqiTrIdx].cqiLst, + &cqiCb->cqiLstEnt); + + rgSCHUtlSCellHndlCqiCollsn(cqiCb); + + RGSCHDBGINFO(inst,(rgSchPBuf(inst), + "\n rgSCHCfgPCqiUeCfg():" + " CrntTime=%d Next CqiTrInstTime=%d Index Stored at=%d ", + crntTime, cqiTrInstTime, cqiCb->nCqiTrIdx)); + + if(cqiCfg->cqiSetup.riEna) + { + cqiCb->perRiVal = 1; + cqiCb->invalidateCqi = FALSE; + + if(RGR_UE_PCQI_WB_REP == cqiCfg->cqiSetup.cqiRepType) + { + /* + 1. wideband RI reporting is configured + (Mode 1-0 or 1-1) + (10*sfn+floor(subframe)-Noffsetcqi-NoffsetRI )Mod(NCqiperiod + *MriPeriod)=0 + */ + periodicity = cqiCb->cqiPeri * cqiCb->riPeri; + } + else + { + /* + * Where Widesband and Subband RI reporting is configured + * (Mode 2-0 or 2-1 ) + * (10*sfn+floor(subframe)-Noffsetcqi-NoffsetRI ) + * Mod(H. NCqiperiod *MriPeriod )=0 + * where H= J * K +1; J=Number of bandwidth parts(BW/subsize). + * K is RGR interf input + */ + + RG_SCH_GET_CQI_J_VAL(sCell->bwCfg.dlTotalBw, j); + cqiCb->h = (cqiCb->cqiCfg.cqiSetup.k *j )+1; + periodicity = cqiCb->h * cqiCb->cqiPeri * + cqiCb->riPeri; + + } + + /* In case of SFN wraparound, the SB CQI reporting cycle breaks + * and RI->WB CQI->SBCQI.. should resume. RI is repositioned + * accordingly. WBCQI handling is naturally accomplished */ + if (periodicity >= RGSCH_MAX_SUBFRM_5G) + { + periodicity = cqiCb->cqiOffset - cqiCb->riOffset + + RGSCH_MAX_SUBFRM_5G - (crntTime); + tempIdx = crntTime + periodicity; + } + else + { + riTrInsTime = ((periodicity +crntTime )- \ + cqiCb->cqiOffset + cqiCb->riOffset)\ + % periodicity; + tempIdx = (crntTime + (periodicity -riTrInsTime)); + } + if (tempIdx <= (crntTime + TFU_RECPREQ_DLDELTA)) + { + tempIdx = tempIdx + periodicity; + } + cqiCb->nRiTrIdx = tempIdx + % RG_SCH_PCQI_SRS_SR_TRINS_SIZE; + if(periodicity >= RG_SCH_PCQI_SRS_SR_TRINS_SIZE) + { + cqiCb->riDist = rgSCHUtlFindDist((U16)(crntTime + TFU_RECPREQ_DLDELTA), + (U16) tempIdx); + } + else + { + cqiCb->riDist =0; + } + + + /* Start receiving RI for this SCell for this UE */ + cmLListAdd2Tail(&ueCb->cell->pCqiSrsSrLst[cqiCb->nRiTrIdx].riLst, + &cqiCb->riLstEnt); + RG_SCH_RECORD(&cqiCb->histElem,RGSCH_ACTION_ADD, + &ueCb->cell->pCqiSrsSrLst[cqiCb->nRiTrIdx].riLst); + + rgSCHUtlSCellHndlRiCollsn(cqiCb); + /*werror*/ +#ifndef BIT_64 + RGSCHDBGINFONEW(inst,(rgSchPBuf(inst), "SCel RI cfg:" + "idx %u period %u Offset %u posInQ(%u) riDist(%u)lst count" + "%lu\n", cqiCfg->cqiSetup.riCfgIdx, cqiCb->riPeri, + cqiCb->riOffset, cqiCb->nRiTrIdx, cqiCb->riDist, + ueCb->cell->pCqiSrsSrLst[cqiCb->nRiTrIdx].riLst.count)); +#else + RGSCHDBGINFONEW(inst,(rgSchPBuf(inst), "SCel RI cfg:" + "idx %u period %u Offset %u posInQ(%u) riDist(%u)lst count" + "%u\n", cqiCfg->cqiSetup.riCfgIdx, cqiCb->riPeri, + cqiCb->riOffset, cqiCb->nRiTrIdx, cqiCb->riDist, + ueCb->cell->pCqiSrsSrLst[cqiCb->nRiTrIdx].riLst.count)); + + +#endif + + RGSCHDBGINFO(inst,(rgSchPBuf(inst), + "\n rgSCHSCellActivation(): CrntTime=%d Next RiTrInstTime=%d" + "Index Stored at=%d riDis=%d ", + crntTime, riTrInsTime, cqiCb->nRiTrIdx, cqiCb->riDist)); + } + } +#endif + + cellSch = RG_SCH_CMN_GET_CELL(sCellInfo->cell); + cellSch->apisDl->rgSCHDlSCellActv(sCellInfo->cell, sCellInfo->ue); + + RETVOID; +} + +#ifdef TFU_UPGRADE + +/** + * @brief Remove CQI from Scell Lst + * + * @details + * + * Function: rgSCHCellClearScellLstOfCQI + * Purpose : Remove CQI from Scell Lst + * + * + * Invoked by: Timer + * + * @param[in] RgSchUeCellInfo *sCellInfo + * @return Void + * + **/ +#ifdef ANSI +PRIVATE Void rgSCHCellClearScellLstOfCQI +( +RgSchUeCellInfo *sCellInfo +) +#else +PRIVATE Void rgSCHCellClearScellLstOfCQI(sCellInfo) +RgSchUeCellInfo *sCellInfo; +#endif +{ + + TRC3(rgSCHCellClearScellLstOfCQI); + RgSchUePCqiCb *cqiRiCb = NULLP; + RgSchUeCb *ueCb; + ueCb = sCellInfo->ue; + /* Clear CQI/RI entry for this SCELL */ + cqiRiCb = &sCellInfo->cqiCb; + /* Delete Periodic CQI/PMI Transmission Instance */ + if (cqiRiCb->nCqiTrIdx != RG_SCH_INVALID_IDX) + { + cmLListDelFrm(&ueCb->cell->pCqiSrsSrLst[cqiRiCb->nCqiTrIdx].cqiLst, + &cqiRiCb->cqiLstEnt); + cqiRiCb->nCqiTrIdx = RG_SCH_INVALID_IDX; + + if (ueCb->nPCqiCb == cqiRiCb) + { + rgSCHUtlSCellHndlCqiCollsn(&ueCb->cellInfo[RGSCH_PCELL_INDEX]->cqiCb); + } + /* Delete Periodic RI Transmission Instance */ + + if (cqiRiCb->nRiTrIdx != RG_SCH_INVALID_IDX) + { + cmLListDelFrm(&ueCb->cell->pCqiSrsSrLst[cqiRiCb->nRiTrIdx].riLst, + &cqiRiCb->riLstEnt); + RG_SCH_RECORD(&cqiRiCb->histElem,RGSCH_ACTION_DEL, + &ueCb->cell->pCqiSrsSrLst[cqiRiCb->nRiTrIdx].riLst); + cqiRiCb->nRiTrIdx = RG_SCH_INVALID_IDX; + if (ueCb->nPRiCb == cqiRiCb) + { + rgSCHUtlSCellHndlRiCollsn(&ueCb->cellInfo[RGSCH_PCELL_INDEX]->cqiCb); + } + } + } + + RETVOID; +} +#endif/*TFU_UPGRADE*/ + +/** + * @brief Handling of SCell DeActivation + * + * @details + * + * Function: rgSCHSCellDeActivation + * Purpose : Perform Deactivation of secondary cell + * : Move the state to IN_ACTIVE + * : Flush the harqEntity + * : Trigger harqEntity flushing to MAC + * : Remove PCQI/SRS for this scell + * : Stop Deactivation timer if running + * + * Invoked by:Cfg/Commn Scheduler + * + * @param[in] RgSchUeCellInfo *sCellInfo + * + * @return ROK/RFAILED + * + **/ +#ifdef ANSI +PRIVATE S16 rgSCHSCellDeActivation +( +RgSchUeCellInfo *sCellInfo +) +#else +PRIVATE S16 rgSCHSCellDeActivation(sCellInfo) +RgSchUeCellInfo *sCellInfo +#endif +{ + RETVALUE(ROK); + RgSchCmnCell *cellSch; + Inst inst = sCellInfo->cell->instIdx; + + TRC3(rgSCHSCellDeActivation); + /* Stop the timer if running */ + + if(sCellInfo->deactTmr.tmrEvnt != TMR_NONE) + { + rgSCHTmrStopTmr(sCellInfo->cell, RG_SCH_TMR_SCELL_DEACT, sCellInfo); + } + + if (sCellInfo->actDelayTmr.tmrEvnt != TMR_NONE) + { + rgSCHTmrStopTmr(sCellInfo->cell, RG_SCH_TMR_SCELL_ACT_DELAY, sCellInfo); + } + + cellSch = RG_SCH_CMN_GET_CELL(sCellInfo->cell); + cellSch->apisDl->rgSCHDlUeReset(sCellInfo->cell, sCellInfo->ue); + + if(sCellInfo->ue->isDrxEnabled) + { + rgSCHDrxUeHqReset(sCellInfo->ue->cell, sCellInfo->ue, + sCellInfo->hqEnt, sCellInfo->sCellIdx); + } + + /* Flush the harqEntity at scheduler */ + if(sCellInfo->hqEnt != NULLP) + { + rgSCHDhmHqEntReset(sCellInfo->hqEnt); + } + /* Trigger harq flush req to MAC */ + + + rgSCHSCellTrgMacHqEReset(inst,sCellInfo->sCellId,sCellInfo->ue->ueId); + + sCellInfo->sCellState = RG_SCH_SCELL_READY; +#ifdef TFU_UPGRADE + rgSCHCellClearScellLstOfCQI(sCellInfo); +#endif + +#ifdef TENB_STATS + sCellInfo->ue->tenbStats->stats.persistent.numDeactivation++; +#endif + + cellSch->apisDl->rgSCHDlSCellDeactv(sCellInfo->cell, sCellInfo->ue); + +#ifdef CA_DBG + printf("SCELL DEATIVATED sCellInfo->ue->ueId =%d, sCellInfo->sCellId =%d\n", sCellInfo->ue->ueId, sCellInfo->sCellId); + //MSPD_DBG("SCELL DEATIVATED sCellInfo->ue->ueId =%d, sCellInfo->sCellId =%d\n", sCellInfo->ue->ueId, sCellInfo->sCellId); +#endif + RETVALUE(ROK); +} + + +/** + * @brief Triggering hqEntity reset to mac + * + * @details + * + * Function: rgSCHSCellTrgMacHqEReset + * Purpose: Frame the interface for mac to reset + * the mac + * Derive the macInstance corresponding + * to the secondary cell going to be deactivated. + * Triiger the msg to that macInstance + * + * Invoked by: CommonScheduler + * + * @param[in] U16 sCellId + * @param[in] U16 rnti + * @return Void + * + **/ +#ifdef ANSI +PRIVATE S16 rgSCHSCellTrgMacHqEReset +( +Inst inst, +U16 secCellId, +U16 rnti +) +#else +PRIVATE S16 rgSCHSCellTrgMacHqEReset(inst,secCellId,rnti) +Inst inst; +U16 secCellId; +U16 rnti; +#endif +{ + Pst pst; + RgSchCellCb *secCellCb = NULLP; + RgInfResetHqEnt hqEntRstInfo; + + if((secCellCb = (RgSchCellCb *)rgSchUtlGetCellCb(inst, secCellId)) == NULLP) + { + RGSCHDBGERRNEW(inst, (rgSchPBuf(inst), "SCell doesnt exists")); + RETVALUE(RFAILED); + } + + hqEntRstInfo.cellId = secCellId; + hqEntRstInfo.crnti = rnti; + + rgSCHUtlGetPstToLyr(&pst, &rgSchCb[inst], secCellCb->macInst); + + RgSchMacRstHqEnt(&pst, &hqEntRstInfo); + + RETVALUE(ROK); +} +/*removed endif*/ + + + +/** + * @brief Handling of harq feeback for SCell act CE txion + * + * @details + * + * Function: rgSCHSCellHndlFdbkInd + * Purpose: Handling the harq feedback for SCell ACT ce txion + * ACK:: Set the state as active for the Scells for which + * CE was sent + * HQ FAILURE/DTX/NACK:: Perform retxion. Add to Act CE list + * Set the state to TOBE_SCHEDULED + * + * + * Invoked by: CommonScheduler + * + * @param[in] RgSchCellCb* cell + * @param[in] RgSchUeCb* ue + * @return Void + * + **/ +#ifdef ANSI +PUBLIC Void rgSCHSCellHndlFdbkInd +( +RgSchDlHqProcCb *hqP, +U8 tbIdx, +U8 fdbk, +Bool maxHqRetxReached +) +#else +PUBLIC Void rgSCHSCellHndlFdbkInd(hqP, tbIdx, fdbk,maxHqRetxReached) +RgSchDlHqProcCb *hqP; +U8 tbIdx; +U8 fdbk; +Bool maxHqRetxReached; +#endif +{ + + RgSchUeCb *ueCb; + RgSchCellCb *cell; + RgSchUeCellInfo *sCellInfo; + + TRC3(rgSCHSCellHndlFdbkInd); + + ueCb = hqP->hqE->ue; + cell = ueCb->cell; + switch(fdbk) + { + case TFU_HQFDB_ACK: + { + hqP->tbInfo[tbIdx].schdSCellActCe.pres = FALSE; + + for(U8 idx = 1; idx <= RG_SCH_MAX_SCELL ; idx++) + { + if(ueCb->cellInfo[idx] != NULLP) + { + if(ueCb->cellInfo[idx]->sCellState == RG_SCH_SCELL_ACTVTN_IN_PROG) + { +#ifdef CA_DBG + printf("\n starting delay timer...\n"); +#endif + rgSCHTmrStartTmr (cell,ueCb->cellInfo[idx] ,RG_SCH_TMR_SCELL_ACT_DELAY, + RG_SCH_CMN_SCELL_ACT_DELAY_TMR); + } + else + { + if(ueCb->cellInfo[idx]->sCellState == RG_SCH_SCELL_DEACTVTN_IN_PROG) + { + sCellInfo = ueCb->cellInfo[idx]; + rgSCHSCellDeActivation(sCellInfo); + } + } + } + } + } + break; + case TFU_HQFDB_NACK: + case TFU_HQFDB_DTX: + { + if(TRUE == maxHqRetxReached) + { + hqP->tbInfo[tbIdx].schdSCellActCe.pres = FALSE; + for(U8 idx = 1; idx <= RG_SCH_MAX_SCELL ; idx++) + { + if(ueCb->cellInfo[idx] != NULLP) + { + if(ueCb->cellInfo[idx]->sCellState == RG_SCH_SCELL_ACTVTN_IN_PROG) + { + ueCb->cellInfo[idx]->sCellState = RG_SCH_SCELL_TOBE_ACTIVATED; + } + else + { + if(ueCb->cellInfo[idx]->sCellState == RG_SCH_SCELL_DEACTVTN_IN_PROG) + { + ueCb->cellInfo[idx]->sCellState = RG_SCH_SCELL_TOBE_DEACTIVATED; + } + } + } + /* Add to actDeactCe lst */ + rgSCHSCellAddToActDeactLst(cell,ueCb); + } + } + } + break; + default: + break; + } + RETVOID; +} + +#ifdef LTE_ADV +/** + * @brief Handling of SCell Deactivation Tmr Expiry + * + * @details + * + * Function: rgSCHSCellDeactTmrExpry + * Purpose : Deactivating the SCell. a + * Clear all the Harq Procs associated with this + * scell. + * Trigger Harq Reset to the respective MAC + * Set the state of the cell to Inactive + * + * + * Invoked by: Timer + * + * @param[in] RgSchUeCellInfo *sCellInfo + * @return Void + * + **/ +#ifdef ANSI +PUBLIC Void rgSCHSCellDeactTmrExpry +( +RgSchUeCellInfo *sCellInfo +) +#else +PUBLIC Void rgSCHSCellDeactTmrExpry(sCellInfo) +RgSchUeCellInfo *sCellInfo; +#endif +{ + + TRC3(rgSCHSCellDeactTmrExpry); + if (sCellInfo->ue->isScellExplicitDeAct == TRUE) + { + /* Deactivation Timer is not configured (infinity), thus send deactivation CE explicitly */ + /* No doing Deactivaiton of LAA Cell */ + if (FALSE == rgSCHLaaSCellEnabled(sCellInfo->cell)) + { + rgSCHSCellTrigActDeact(sCellInfo->ue->cell, sCellInfo->ue, sCellInfo->sCellIdx, RGR_SCELL_DEACT); + } + else + { + printf (" !!!!!! Avoiding DEACT for UE %d because of LAA Cell !!!!!!!!!!!!! \n", + sCellInfo->ue->ueId); + } + + } + else + { + /* Deactivation Timer is configured, thus assume that UE has deactivated */ + rgSCHSCellDeActivation(sCellInfo); + } + RETVOID; +} +#endif + +/** + * @brief This function handles the action of the SCell + * + * @details + * + * Function: rgSCHSCellTrigActDeact + * Purpose : + * 1) Prepares SCELL ready for activation OR + * 2) Initiates activation of SCELL OR + * 3) Initiate deactivation of SCELL OR + * + * Invoked by:Cfg/Commn Scheduler + * + * @param[in] RgSchCellCb *cellCb + * @param[in] RgSchUeCb *ueCb + * @param[in] U8 sCellIdx + * @param[in] U8 action + * + * @return ROK/RFAILED + * + **/ +#ifdef ANSI +PUBLIC S16 rgSCHSCellTrigActDeact +( +RgSchCellCb *cell, +RgSchUeCb *ueCb, +U8 sCellIdx, +U8 action +) +#else +PUBLIC S16 rgSCHSCellTrigActDeact(cell,ueCb,sCellIdx,action) +RgSchCellCb *cell, +RgSchUeCb *ueCb; +U8 sCellIdx; +U8 action; +#endif +{ + Inst inst = cell->instIdx; + S16 ret = ROK; + + TRC3(rgSCHSCellTrigActDeact); + + if((sCellIdx < 1) || + (sCellIdx > RGR_MAX_SCELL_PER_UE)) + { + RGSCHDBGERRNEW(inst, (rgSchPBuf(inst),"Invalid Serv Cell Idx %d\n", \ + sCellIdx)); + RETVALUE(RFAILED); + } + + if(ueCb->cellInfo[sCellIdx] == NULLP) + { + RGSCHDBGERRNEW(inst, (rgSchPBuf(inst),"Serv Cell not added to this Ue Scell Idx %d ueId %d\n", \ + sCellIdx,ueCb->ueId)); + RETVALUE(RFAILED); + } + + switch (action) + { + case RGR_SCELL_READY: + { + if(ueCb->cellInfo[sCellIdx]->sCellState != RG_SCH_SCELL_INACTIVE) + { + RGSCHDBGERRNEW(inst, (rgSchPBuf(inst),"Invalid state %u for preparing SCell Idx %u for UE %u\n", \ + ueCb->cellInfo[sCellIdx]->sCellState, sCellIdx, ueCb->ueId)); + ret = RFAILED; + } + else + { + ueCb->cellInfo[sCellIdx]->sCellState = RG_SCH_SCELL_READY; + //TODO_SID Activating the cell directly. Ignoring the ActCe procedure. + rgSCHSCellActivation(ueCb->cellInfo[sCellIdx]); + /* Setting allocCmnUlPdcch flag to FALSE, So that PDCCH allocation will be done + from UE Searchspace */ + ueCb->allocCmnUlPdcch = FALSE; + printf("\n***** SCellIdx=%d state Changed to %d State \n",sCellIdx, ueCb->cellInfo[sCellIdx]->sCellState); + printf("\n***** SCellInfo Addr=%p state Changed to RG_SCH_SCELL_READY\n",(void*)ueCb->cellInfo[sCellIdx]); + } + break; + } + case RGR_SCELL_ACT: + { + if(ueCb->cellInfo[sCellIdx]->sCellState != RG_SCH_SCELL_READY) + { + RGSCHDBGERRNEW(inst, (rgSchPBuf(inst),"Invalid state %u for activating SCell Idx %u for UE %u\n", \ + ueCb->cellInfo[sCellIdx]->sCellState, sCellIdx, ueCb->ueId)); + ret = RFAILED; + } + else + { + ueCb->cellInfo[sCellIdx]->sCellState = RG_SCH_SCELL_TOBE_ACTIVATED; + if (NULLP == ueCb->sCellActLnk.node) + { + /* Add only if UE is not already present in the activation/deactivation list */ + rgSCHSCellAddToActDeactLst(cell,ueCb); + } + } + break; + } + case RGR_SCELL_DEACT: + { + if(ueCb->cellInfo[sCellIdx]->sCellState != RG_SCH_SCELL_ACTIVE) + { + RGSCHDBGERRNEW(inst, (rgSchPBuf(inst),"Invalid state %u for deactivating SCell Idx %u for UE %u\n", \ + ueCb->cellInfo[sCellIdx]->sCellState, sCellIdx, ueCb->ueId)); + ret = RFAILED; + } + else + { + ueCb->cellInfo[sCellIdx]->sCellState = RG_SCH_SCELL_TOBE_DEACTIVATED; + if (NULLP == ueCb->sCellActLnk.node) + { + /* Add only if UE is not already present in the activation/deactivation list */ + rgSCHSCellAddToActDeactLst(cell,ueCb); + } + } + break; + } + default: + { + RGSCHDBGERRNEW(inst, (rgSchPBuf(inst),"Invalid action received for SCell Idx %u for UE %u\n", \ + sCellIdx, ueCb->ueId)); + ret = RFAILED; + break; + } + } + RETVALUE(ret); +} + + +/** + * @brief SCell Activation of selected cell + * + * @details + * + * Function: rgSCHSCellSelectForAct + * Purpose : Perform Selection of secondary cell for activation + * + * Invoked by:Cfg/Commn Scheduler + * + * @param[in] RgSchCellCb *cellCb + * @param[in] RgSchUeCb *ueCb + * + * @return ROK/RFAILED + * + **/ +#ifdef ANSI +PRIVATE S16 rgSCHSCellSelectForAct +( +RgSchCellCb *cell, +RgSchUeCb *ueCb, +U8 *sCellIdx +) +#else +PRIVATE S16 rgSCHSCellSelectForAct(cell, ueCb) +RgSchCellCb *cell; +RgSchUeCb *ueCb; +U8 *sCellIdx; +#endif +{ + TRC3(rgSCHSCellSelectAndAct); + + for((*sCellIdx) = 1; (*sCellIdx) <= RG_SCH_MAX_SCELL; (*sCellIdx)++) + { + if((ueCb->cellInfo[(*sCellIdx)] != NULLP) && + (ueCb->cellInfo[(*sCellIdx)]->sCellState == RG_SCH_SCELL_READY)) + { + RETVALUE(ROK); + } + } + RETVALUE(RFAILED); +} + +/** + * @brief SCell Activation of selected cell + * + * @details + * + * Function: rgSCHSCellSelectAndActDeAct + * Purpose : Perform Selection and Activation/Deactivation of secondary cell + * + * Invoked by:Cfg/Commn Scheduler + * + * @param[in] RgSchCellCb *cellCb + * @param[in] RgSchUeCb *ueCb + * @param[in] U8 action + * + * @return Void + * + **/ +#ifdef ANSI +PUBLIC Void rgSCHSCellSelectAndActDeAct +( +RgSchCellCb *pCell, +RgSchUeCb *ueCb, +U8 action +) +#else +PUBLIC Void rgSCHSCellSelectAndActDeAct(pCell, ueCb, action) +RgSchCellCb *pCell; +RgSchUeCb *ueCb; +U8 action; +#endif +{ + U8 sCellIdx = 0; + S16 ret = ROK; + + switch (action) + { + case RGR_SCELL_ACT: + { + + if(((ret = rgSCHSCellSelectForAct(pCell, ueCb, &sCellIdx)) == ROK) + && (sCellIdx == 0)) + RETVOID; + break; + } + default: + RETVOID; + } + if ((ret != ROK) || + (ROK != (rgSCHSCellTrigActDeact(pCell, ueCb, sCellIdx, action)))) + { + RGSCHDBGERR(pCell->instIdx,(rgSchPBuf(pCell->instIdx), "SCell Actication failed" + "for UE [%d] with SCellIdx [%d]\n", ueCb->ueId, sCellIdx)); + } + RETVOID; +} + + +/** + * @brief Handling of Scell Deletion + * + * @details + * + * Function: rgSCHSCellDelUeSCell + * Purpose : Perform Scell Deletion for an UE + * : flush harqEnttiy of the given scell associated + * with this UE + * + * + * Invoked by:Cfg module + * + * @param[in] RgSchCellCb *cellCb + * @param[in] RgSchUeCb *ueCb + * @param[in] U8 idx + * @return ROK/RFAILED + * + **/ +#ifdef ANSI +PUBLIC Void rgSCHSCellDelUeSCell +( +RgSchCellCb *cellCb, +RgSchUeCb *ueCb, +U8 sCellIdx +) +#else +PUBLIC Void rgSCHSCellDelUeSCell(cellCb,ueCb,sCellIdx) +RgSchCellCb *cellCb; +RgSchUeCb *ueCb; +U8 sCellIdx; +#endif +{ + RgUeUlHqCb *ulHqEnt; + Inst inst = cellCb->instIdx; + RgSchUeCellInfo *sCellInfo; + RgSchCmnUlUe *ueUl; + + TRC3(rgSCHSCellDelUeSCell); + sCellInfo = ueCb->cellInfo[sCellIdx]; + + + if(sCellInfo == NULLP) + { + RGSCHDBGERRNEW(inst, (rgSchPBuf(inst),"Serv Cell not added to this Ue Scell Idx %d\ + ueId %d\n", + sCellIdx,ueCb->ueId)); + RETVOID; + } + + rgSCHDbmDelUeCb(sCellInfo->cell, ueCb); + ueUl = RG_SCH_CMN_GET_UL_UE(ueCb, sCellInfo->cell); + + if (NULLP != sCellInfo->sCellLnk.node) + { + cmLListDelFrm(&sCellInfo->cell->sCellUeLst, &sCellInfo->sCellLnk); + } + + /* Clear Scheduler specific list for this UE from the + * corresponding CELL */ + + /*Updating 1BCS Value*/ + ueCb->f1bCsAVal = (ueCb->f1bCsAVal - + rgSCHUtlGetMaxTbSupp(sCellInfo->txMode.txModeEnum)); + +#ifdef LTE_TDD + rgSCHUtlDelUeANFdbkInfo(ueCb,sCellIdx); +#endif + + rgSCHSCellDeActivation(sCellInfo); + /* Release hqEnt mem */ + rgSCHDhmDelHqEnt(cellCb, &sCellInfo->hqEnt); + + ulHqEnt = &(ueUl->hqEnt); + + cellCb->sc.apis->rgSCHRgrSCellUeDel(sCellInfo, sCellInfo->ue); + + rgSCHUhmFreeUe(sCellInfo->cell, ulHqEnt); + + rgSCHUtlFreeSBuf(cellCb->instIdx, + (Data**)(&(sCellInfo)), (sizeof(RgSchUeCellInfo))); + + ueCb->cellInfo[sCellIdx] = NULLP; + + RETVOID; +} + +/** + * @brief Handling of UE Deletion + * + * @details + * + * Function: rgSCHSCellDelUe + * Purpose : Perform UE Deletion + * : Delete all the SCells added for this UE + * : flush harqEnttiy of all scells associated + * with this UE + * + * + * Invoked by:Cfg module + * + * @param[in] RgSchCellCb *cellCb + * @param[in] RgSchUeCb *ueCb + * @return ROK/RFAILED + * + **/ +#ifdef ANSI +PUBLIC S16 rgSCHSCellDelUe +( +RgSchCellCb *cellCb, +RgSchUeCb *ueCb +) +#else +PUBLIC S16 rgSCHSCellDelUe(cellCb,ueCb) +RgSchCellCb *cellCb; +RgSchUeCb *ueCb; +#endif +{ + + TRC3(rgSCHSCellDelUe); + + for(U8 idx = 1; idx <= RG_SCH_MAX_SCELL ; idx++) + { + rgSCHSCellDelUeSCell(cellCb,ueCb,idx); + } + + RETVALUE(ROK); +} + +#ifdef TFU_UPGRADE + +/** + * @brief Handling of PCqi cfg fro a scell + * + * @details + * + * Function: rgSCHSCellPCqiCfg + * Purpose : + * : Delete all the SCells added for this UE + * : flush harqEnttiy of all scells associated + * with this UE + * Processing Steps: + * - For SCell-specific Periodic CQI related configuration, + * - If Periodic CQI/PMI is configured, + * - Update SCell with the configured values. + * - Update the CQI offset and CQI perodicity information + * + * + * - For SCell-specific Periodic RI related configuration, + * - If Periodic RI is configured, + * - Update SCell with the configured values. + * - Update the RI offset and RI perodicity information + * + * + * Invoked by:Cfg module + * + * @param[in] RgSchCellCb *cellCb + * @param[in] RgSchUeCb *ueCb + * @return ROK/RFAILED + * + **/ +#ifdef ANSI +PUBLIC S16 rgSCHSCellPCqiCfg +( +RgSchCellCb *priCellCb, +RgSchCellCb *secCellCb, +RgSchUeCb *ueCb, +RgrUePrdDlCqiCfg *cqiCfg, +CmLteUeCategory ueCat, +U8 sCellIdx +) +#else +PUBLIC S16 rgSCHSCellPCqiCfg(priCellCb,secCellCb,ueCb,cqiCfg,ueCat,sCellIdx) +RgSchCellCb *priCellCb; +RgSchCellCb *secCellCb; +RgSchUeCb *ueCb; +RgrUePrdDlCqiCfg *cqiCfg; +CmLteUeCategory ueCat; +U8 sCellIdx; +#endif +{ + U8 j; /*Bandwidth Parts*/ + U8 temp; +#ifdef DEBUGP + Inst inst = priCellCb->instIdx; +#endif + RgSchUeCellInfo *sCellInfo; + RgSchUePCqiCb *cqiCb = NULLP; + + TRC3(rgSCHSCellPCqiCfg); + + RGSCHDBGINFO(priCellCb->instIdx, (rgSchPBuf(priCellCb->instIdx), + "rgSCHSCellPCqiCfg cellId =%d, ueId = %d, CfgType =%d\n", + secCellCb->cellId, ueCb->ueId, cqiCfg->type)); + + if((sCellIdx < 1) || + (sCellIdx > RGR_MAX_SCELL_PER_UE)) + { + RGSCHDBGERRNEW(inst, (rgSchPBuf(inst),"Invalid Serv Cell Idx %d\n", + sCellIdx)); + RETVALUE(RFAILED); + } + + sCellInfo = ueCb->cellInfo[sCellIdx]; + + cqiCb = &ueCb->cellInfo[sCellIdx]->cqiCb; + cqiCb->servCellInfo = sCellInfo; + + /* Periodic CQI is setup */ + if (cqiCfg->type == RGR_SCH_PCQI_SETUP) + { + /* 1. Copy the Received CQI Cfg parameters to ueCb */ + cmMemcpy((U8 *)&cqiCb->cqiCfg, (U8 *)cqiCfg, + sizeof(RgrUePrdDlCqiCfg)); + + /* 2. Compute Periodic CQI Periodicity and subframe offset */ +#ifndef LTE_TDD + rgSCHUtlGetCfgPerOff(RG_SCH_FDD_PCQI_TBL, cqiCfg->cqiSetup.cqiPCfgIdx, + &cqiCb->cqiPeri, &cqiCb->cqiOffset); +#else + rgSCHUtlGetCfgPerOff( RG_SCH_TDD_PCQI_TBL, + cqiCfg->cqiSetup.cqiPCfgIdx, + &cqiCb->cqiPeri, &cqiCb->cqiOffset); +#endif + + + RGSCHDBGINFO(priCellCb->instIdx,(rgSchPBuf(priCellCb->instIdx), + "\n rgSCHSCellPCqiCfg(): CQI Peri=%d, CQI Offset=%d", + cqiCb->cqiPeri,cqiCb->cqiOffset)); + + if(RGR_UE_PCQI_SB_REP == cqiCfg->cqiSetup.cqiRepType) + { + U8 k; /*SubBand Size (RB) */ + RG_SCH_GET_CQI_J_VAL(secCellCb->bwCfg.dlTotalBw, j); + RG_SCH_GET_CQI_K_VAL(secCellCb->bwCfg.dlTotalBw, k); + cqiCb->J = j; /*Number of Bandwidth Parts*/ + /*h: reporting instances required for a complete CQI/PMI report */ + /*j:Number of bandwidth parts; k: Subband Size*/ + cqiCb->h = (cqiCb->cqiCfg.cqiSetup.k *j )+1; + /* ccpu00140905- L-size is coming as 3 for 100Rbs where it should be 2*/ + temp = RGSCH_CEIL(secCellCb->bwCfg.dlTotalBw, (j*k)); + cqiCb->label = (temp & (temp-1)) ? + (1+ rgSCHUtlLog32bitNbase2(temp)) : rgSCHUtlLog32bitNbase2(temp); + } + else + { + /* Wideband Cqi Rep Type */ + cqiCb->prioLvl = RG_SCH_CQI_PRIO_LVL_1; + } + cqiCb->cqiLstEnt.node=(PTR)cqiCb; + cqiCb->isCqiIgnoByCollsn = FALSE; + + + /* 4. Rank Indicator Cfg handler */ + /* 1. Rank Indicator is enabled */ + if(cqiCfg->cqiSetup.riEna) + { + rgSCHUtlGetCfgPerOff(RG_SCH_RI_TBL, + cqiCfg->cqiSetup.riCfgIdx, + &cqiCb->riPeri, &cqiCb->riOffset); + + RGSCHDBGINFO(priCellCb->instIdx,(rgSchPBuf(priCellCb->instIdx), + "\n rgSCHSCellPCqiCfg(): RI Peri=%d, RI Offset=%d", + cqiCb->riPeri,cqiCb->riOffset)); + + if(ueCb->cellInfo[sCellIdx]->txMode.txModeEnum == RGR_UE_TM_3 + || ueCb->cellInfo[sCellIdx]->txMode.txModeEnum == RGR_UE_TM_4) + { + if (secCellCb->numTxAntPorts ==2) + { + cqiCb->riNumBits = 1; + } + else if(secCellCb->numTxAntPorts ==4) + { + if(ueCat == CM_LTE_UE_CAT_8) + { + cqiCb->riNumBits = 3; + } + else if((ueCat == CM_LTE_UE_CAT_5) || + (ueCat == CM_LTE_UE_CAT_6) || CM_LTE_UE_CAT_7) + { + cqiCb->riNumBits = 2; + } + else + { + cqiCb->riNumBits = 1; + } + } + } + cqiCb->riLstEnt.node=(PTR) cqiCb; + cqiCb->isRiIgnoByCollsn = FALSE; + + } + } + else + { + sCellInfo->cqiCb.cqiCfg.type = RGR_SCH_PCQI_REL; + } + /* Setting the indices to invalid during + scell addition. These indices will be set during + activation */ + cqiCb->nRiTrIdx = RG_SCH_INVALID_IDX; + cqiCb->riDist = RG_SCH_INVALID_IDX; + cqiCb->nCqiTrIdx = RG_SCH_INVALID_IDX; + + RETVALUE(ROK); +} +#endif + +/** + * @brief Handling of Ue Reset from common scheduler + * + * @details + * + * Function: rgSCHSCellDlUeReset + * Purpose: Call scheudler type spcefic UE RESET + * for all the secondary cells + * + * Invoked by: CommonScheduler + * + * @param[in] RgSchCellCb* cell + * @param[in] RgSchUeCb* ue + * @return Void + * + **/ +#ifdef ANSI +PUBLIC Void rgSCHSCellDlUeReset +( +RgSchCellCb *cell, +RgSchUeCb *ue +) +#else +PUBLIC Void rgSCHSCellDlUeReset(cell, ue) +RgSchCellCb *cell; +RgSchUeCb *ue; +#endif +{ + RgSchCmnCell *cellSch; + TRC3(rgSCHSCellDlUeReset); + + for(U8 idx = 1; idx <= RG_SCH_MAX_SCELL ; idx++) + { + if(ue->cellInfo[idx] != NULLP) + { + cellSch = RG_SCH_CMN_GET_CELL(ue->cellInfo[idx]->cell); + cellSch->apisDl->rgSCHDlUeReset(ue->cellInfo[idx]->cell, ue); + rgSCHSCellDeActivation(ue->cellInfo[idx]); + ue->cellInfo[idx]->sCellState = RG_SCH_SCELL_INACTIVE; + } + } + RETVOID; +} + + +/** + * @brief Handling of LC Cfg from common scheduler + * + * @details + * + * Function: rgSCHSCellDlLcCfg + * Purpose: Call scheudler type spcefic LC config + * for all the secondary cells + * + * Invoked by: CommonScheduler + * + * @param[in] RgSchCellCb* cell + * @param[in] RgSchUeCb* ue + * @return Void + * + **/ +#ifdef ANSI +PUBLIC Void rgSCHSCellDlLcCfg +( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgSchDlLcCb *svc +) +#else +PUBLIC Void rgSCHSCellDlLcCfg(cell, ue, svc) +RgSchCellCb *cell; +RgSchUeCb *ue; +RgSchDlLcCb *svc; +#endif +{ + RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell); + TRC3(rgSCHSCellDlLcCfg); + for(U8 idx = 1; idx <= RG_SCH_MAX_SCELL ; idx++) + { + if(ue->cellInfo[idx] != NULLP) + { + cellSch->apisDl->rgSCHRgrDlLcCfg(ue->cellInfo[idx]->cell, ue, svc,NULLP,NULLP); + } + } + RETVOID; +} + +/** + * @brief Handling of LC Delete from common scheduler + * + * @details + * + * Function: rgSCHSCellDlLcDel + * Purpose: Call scheudler type spcefic bo update handler + * for all the secondary cells + * + * Invoked by: CommonScheduler + * + * @param[in] RgSchCellCb* cell + * @param[in] RgSchUeCb* ue + * @return Void + * + **/ +#ifdef ANSI +PUBLIC Void rgSCHSCellDlLcDel +( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgSchDlLcCb *svc +) +#else +PUBLIC Void rgSCHSCellDlLcDel(cell, ue, svc) +RgSchCellCb *cell; +RgSchUeCb *ue; +RgSchDlLcCb *svc; +#endif +{ + RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell); + TRC3(rgSCHSCellDlLcDel); + for(U8 idx = 1; idx <= RG_SCH_MAX_SCELL ; idx++) + { + if(ue->cellInfo[idx] != NULLP) + { + cellSch->apisDl->rgSCHFreeDlLc(ue->cellInfo[idx]->cell, ue, svc); + } + } + RETVOID; +} + +/** + * @brief Handling of Bo update from common scheduler + * + * @details + * + * Function: rgSCHSCellDlDedBoUpd + * Purpose: Call scheudler type spcefic bo update handler + * for all the secondary cells + * + * Invoked by: CommonScheduler + * + * @param[in] RgSchCellCb* cell + * @param[in] RgSchUeCb* ue + * @return Void + * + **/ +#ifdef ANSI +PUBLIC Void rgSCHSCellDlDedBoUpd +( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgSchDlLcCb *svc +) +#else +PUBLIC Void rgSCHSCellDlDedBoUpd(cell, ue, svc) +RgSchCellCb *cell; +RgSchUeCb *ue; +RgSchDlLcCb *svc; +#endif +{ + RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell); + TRC3(rgSCHSCellDlDedBoUpd); + + /* If this is not invoked by PCell, then + invoke the call to PCell handler + This happens during finalization if LC Bo becomes zero*/ + if (ue->cell != cell) + { + cellSch->apisDl->rgSCHDlDedBoUpd(ue->cell, ue, svc); + } + for(U8 idx = 1; idx <= RG_SCH_MAX_SCELL ; idx++) + { + if((ue->cellInfo[idx] != NULLP) && + (ue->cellInfo[idx]->sCellState == RG_SCH_SCELL_ACTIVE) && + (ue->cellInfo[idx]->cell != cell)) + { + cellSch->apisDl->rgSCHDlDedBoUpd(ue->cellInfo[idx]->cell, ue, svc); + } + } + RETVOID; +} +#ifdef TFU_UPGRADE +/** + * @brief Compare two CQI CB configs are return the result + * + * @details + * + * Function: rgSCHUtlSCellCmpCqiCfg + * Purpose : Compare priority levels of cqiCb1 and cqiCb2 + * and set the isCqiIgnoByCollsn to TRUE for the + * cqiCb which has lower priority + * Invoked by:scell module + * + * @param[in] RgSchUePCqiCb *cqiCb1 + * @param[in] RgSchUePCqiCb *cqiCb2 + * @return U8 cqiCb cell idx which has the higher priority + * + **/ +#ifdef ANSI +PRIVATE U8 rgSCHUtlSCellCmpCqiCfg +( +RgSchUePCqiCb *cqiCb1, +RgSchUePCqiCb *cqiCb2 +) +#else +PRIVATE U8 rgSCHUtlSCellCmpCqiCfg(cqiCb1, cqiCb2) +RgSchUePCqiCb *cqiCb1; +RgSchUePCqiCb *cqiCb2; +#endif +{ + RgSchUePCqiCb *retCqiCb; + TRC3(rgSCHUtlSCellCmpCqiCfg); + /* Collision rules are defined in TS 36.213,7.2.2 */ + /* RI, WB first PMI > WB CQI > SB CQI */ + /* As of now only taking care of RI > WB CQI > SB CQI */ + + if (cqiCb1->prioLvl > cqiCb2->prioLvl) + { + cqiCb2->isCqiIgnoByCollsn = TRUE; + cqiCb1->isCqiIgnoByCollsn = FALSE; + retCqiCb = cqiCb1; + } + else if (cqiCb2->prioLvl > cqiCb1->prioLvl) + { + cqiCb1->isCqiIgnoByCollsn = TRUE; + cqiCb2->isCqiIgnoByCollsn = FALSE; + retCqiCb = cqiCb2; + } + else + { + if (cqiCb1->servCellInfo->sCellIdx > cqiCb2->servCellInfo->sCellIdx) + { + cqiCb1->isCqiIgnoByCollsn = TRUE; + cqiCb2->isCqiIgnoByCollsn = FALSE; + retCqiCb = cqiCb2; + } + else + { + cqiCb2->isCqiIgnoByCollsn = TRUE; + cqiCb1->isCqiIgnoByCollsn = FALSE; + retCqiCb = cqiCb1; + } + } + + RETVALUE(retCqiCb->servCellInfo->sCellIdx); +} + +/** + * @brief Handling of collision of CQI types between serving cells + * + * @details + * + * Function: rgSCHUtlSCellHndlCqiCollsn + * Purpose : Takes care of collision clauses specified in 36.213 7.2.2 Rel 10 + * and selects next nearest cqiCb + * Invoked by:Cfg module + * + * @param[in] RgSchCellCb *cellCb + * @param[in] RgSchUeCb *ueCb + * @return ROK/RFAILED + * + **/ +#ifdef ANSI +PUBLIC S16 rgSCHUtlSCellHndlCqiCollsn +( +RgSchUePCqiCb *cqiCb +) +#else +PUBLIC S16 rgSCHUtlSCellHndlCqiCollsn(cqiCb) +RgSchUePCqiCb *cqiCb; +#endif +{ + U32 nPCqiServCellIdx; + U32 minPCqiTrIdx; + U32 scellPCqiTrIdx; + U32 pCqiTrIdx; + RgSchCellCb *priCellCb = cqiCb->servCellInfo->ue->cell; + RgSchUeCb *ueCb = cqiCb->servCellInfo->ue; + U16 crntSfIdx; + U32 cellIdx; + U32 sCellCnt = 0; + CmLteTimingInfo timingInfo; + U8 idx = 0; + TRC3(rgSCHUtlSCellHndlCqiCollsn); + +#ifdef xLTE_TDD + RG_SCH_ADD_TO_CRNT_TIME(priCellCb->crntTime, timingInfo, TFU_DELTA); +#else + RG_SCH_ADD_TO_CRNT_TIME(priCellCb->crntTime, timingInfo, + TFU_RECPREQ_DLDELTA); +#endif + + RG_SCH_GET_IDX_PCQISRSSR(timingInfo, crntSfIdx); + + cqiCb->isCqiIgnoByCollsn = FALSE; + + pCqiTrIdx = cqiCb->nCqiTrIdx; + nPCqiServCellIdx = cqiCb->servCellInfo->sCellIdx; + /* Handle wrap around case */ + if (pCqiTrIdx < crntSfIdx) + { + pCqiTrIdx += RG_SCH_PCQI_SRS_SR_TRINS_SIZE; + } + minPCqiTrIdx = pCqiTrIdx; + + for (cellIdx =0; cellIdx <= RG_SCH_MAX_SCELL; cellIdx++) + { + /* If a serving cell is configured */ + if(ueCb->cellInfo[cellIdx] != NULLP) + { + /* If the serving cell is in ACTIVE state and + If it is not the same serving cell as cqiCb for which + collision is being checked */ + if ((ueCb->cellInfo[cellIdx]->sCellState == RG_SCH_SCELL_ACTIVE)&& + (cellIdx != cqiCb->servCellInfo->sCellIdx)) + { + scellPCqiTrIdx = ueCb->cellInfo[cellIdx]->cqiCb.nCqiTrIdx; + + /* Handle wrap around case */ + if (scellPCqiTrIdx < crntSfIdx) + { + scellPCqiTrIdx += RG_SCH_PCQI_SRS_SR_TRINS_SIZE; + } + + /* If cqiCb->isCqiIgnoByCollsn is TRUE then a higher prio cqiCb + is already found so need to compare */ + if ((FALSE == ueCb->cellInfo[cellIdx]->cqiCb.isCqiIgnoByCollsn) && + (FALSE == cqiCb->isCqiIgnoByCollsn) && + (scellPCqiTrIdx == pCqiTrIdx)) + { + /* Handle Collision */ + /* set isCqiIgnoByCollsn to TRUE for low prio CQI Rep type */ + nPCqiServCellIdx = rgSCHUtlSCellCmpCqiCfg(&ueCb->cellInfo[cellIdx]->cqiCb,cqiCb); + } + else if (scellPCqiTrIdx < minPCqiTrIdx) + { + minPCqiTrIdx = scellPCqiTrIdx; + nPCqiServCellIdx = cellIdx; + } + } + + /* If all of the num of configured scells are checked then break */ + if (sCellCnt == ueCb->numSCells) + { + break; + } + sCellCnt++; + } + } + + /* Set the next expected Cqi into nPCqiCb */ + idx = ((nPCqiServCellIdx)& (CM_LTE_MAX_CELLS -1)); + ueCb->nPCqiCb = &ueCb->cellInfo[idx]->cqiCb; + + RETVALUE(ROK); +} + + +/** + * @brief Handling of collision of RI types between serving cells + * + * @details + * + * Function: rgSCHUtlSCellHndlRiCollsn + * Purpose : Takes care of collision clauses specified in 36.213 7.2.2 Rel 10 + * and selects next nearest cqiCb + * Invoked by:Cfg module + * + * @param[in] RgSchCellCb *cellCb + * @param[in] RgSchUeCb *ueCb + * @return ROK/RFAILED + * + **/ +#ifdef ANSI +PUBLIC S16 rgSCHUtlSCellHndlRiCollsn +( +RgSchUePCqiCb *cqiCb +) +#else +PUBLIC S16 rgSCHUtlSCellHndlRiCollsn(cqiCb) +RgSchUePCqiCb *cqiCb; +#endif +{ + U32 nPRiServCellIdx; + U32 minPRiTrIdx; + U32 scellPRiTrIdx; + U32 pRiTrIdx; + RgSchCellCb *priCellCb = cqiCb->servCellInfo->ue->cell; + RgSchUeCb *ueCb = cqiCb->servCellInfo->ue; + U16 crntSfIdx; + U32 cellIdx; + U32 sCellCnt = 0; + CmLteTimingInfo timingInfo; + TRC3(rgSCHUtlSCellHndlRiCollsn); + +#ifdef xLTE_TDD + RG_SCH_ADD_TO_CRNT_TIME(priCellCb->crntTime, timingInfo, TFU_DELTA); +#else + RG_SCH_ADD_TO_CRNT_TIME(priCellCb->crntTime, timingInfo, + TFU_RECPREQ_DLDELTA); +#endif + + RG_SCH_GET_IDX_PCQISRSSR(timingInfo, crntSfIdx); + + pRiTrIdx = cqiCb->nRiTrIdx + cqiCb->riDist * RG_SCH_PCQI_SRS_SR_TRINS_SIZE; + + /* Handle wrap around case */ + if (pRiTrIdx < crntSfIdx) + { + pRiTrIdx += RG_SCH_PCQI_SRS_SR_TRINS_SIZE; + } + + cqiCb->isRiIgnoByCollsn = FALSE; + nPRiServCellIdx = cqiCb->servCellInfo->sCellIdx; + minPRiTrIdx = pRiTrIdx; + + for (cellIdx =0; cellIdx <= RG_SCH_MAX_SCELL; cellIdx++) + { + /* If a serving cell is configured */ + if(ueCb->cellInfo[cellIdx] != NULLP) + { + /* If the serving cell is in ACTIVE state and + If it is not the same serving cell as cqiCb for which + collision is being checked */ + if ((ueCb->cellInfo[cellIdx]->sCellState == RG_SCH_SCELL_ACTIVE)&& + (cellIdx != cqiCb->servCellInfo->sCellIdx)) + { + scellPRiTrIdx = ueCb->cellInfo[cellIdx]->cqiCb.nRiTrIdx + + ueCb->cellInfo[cellIdx]->cqiCb.riDist * RG_SCH_PCQI_SRS_SR_TRINS_SIZE; + + /* Handle wrap around case */ + if (scellPRiTrIdx < crntSfIdx) + { + scellPRiTrIdx += RG_SCH_PCQI_SRS_SR_TRINS_SIZE; + } + + /* If cqiCb->isRiIgnoByCollsn is TRUE then a higher prio cqiCb + is already found so need to compare */ + if ((FALSE == ueCb->cellInfo[cellIdx]->cqiCb.isRiIgnoByCollsn) && + (FALSE == cqiCb->isRiIgnoByCollsn) && + (scellPRiTrIdx == pRiTrIdx)) + { + /* Handle Collision */ + /* set isRiIgnoByCollsn to TRUE for low prio CQI Rep type */ + if (cqiCb->servCellInfo->sCellIdx < (ueCb->cellInfo[cellIdx]->sCellIdx)) + { + ueCb->cellInfo[cellIdx]->cqiCb.isRiIgnoByCollsn = TRUE; + } + else + { + cqiCb->isRiIgnoByCollsn = TRUE; + } + } + else if (scellPRiTrIdx < minPRiTrIdx) + { + minPRiTrIdx = scellPRiTrIdx; + nPRiServCellIdx = cellIdx; + } + } + + /* If all of the num of configured scells are checked then break */ + if (sCellCnt == ueCb->numSCells) + { + break; + } + sCellCnt++; + } + } + + /* Set the next expected Cqi into nPCqiCb */ + ueCb->nPRiCb = &ueCb->cellInfo[nPRiServCellIdx]->cqiCb; + + RETVALUE(ROK); +} +#endif/*TFU_UPGRADE*/ + +/** + * @brief Checking whethter the scell is active or not + * + * @details + * + * Function: rgSCHSCellIsActive + * Purpose: Check the Scell is in active state or not + * + * + * Invoked by: SpecificScheduler + * + * @param[in] RgSchCellCb* cell + * @param[in] RgSchUeCb* ue + * @return Void + * + **/ +#ifdef ANSI +PUBLIC S16 rgSCHSCellIsActive +( +RgSchCellCb *cell, +RgSchUeCb *ue +) +#else +PUBLIC S16 rgSCHSCellIsActive(cell, ue) +RgSchCellCb *cell; +RgSchUeCb *ue; +#endif +{ + S16 retVal = RFAILED; + TRC3(rgSCHSCellIsActive); + + for(U8 idx = 1; idx <= RG_SCH_MAX_SCELL ; idx++) + { + if((ue->cellInfo[idx] != NULLP) && + (ue->cellInfo[idx]->cell->cellId == cell->cellId)&& + (ue->cellInfo[idx]->sCellState == RG_SCH_SCELL_ACTIVE)) + { + retVal = ROK; + break; + } + } + RETVALUE(retVal); +} + +/** + * @brief Function to check for Acell Activation Trigered. + * + * @details + * + * Function : rgSCHIsActvReqd + * This function will check for Secondary cell activation criteria + * If met this will return TRUE else FALSE + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ue + * @return BOOL + * -# TRUE + **/ +#ifdef ANSI +PUBLIC Bool rgSCHIsActvReqd +( +RgSchCellCb *cell, +RgSchUeCb *ue +) +#else +PUBLIC Bool rgSCHIsActvReqd(cell, ue) +RgSchCellCb *cell; +RgSchUeCb *ue +#endif +{ + TRC2(rgSCHIsActvReqd) + /* Check if remBoCnt in this UE is greater than ZERO for sufficient number of + * Scheduling TTIs. If yes then We should activate a secondary cell to handle + * outstanding BO */ + if(ue->remBoCnt == RG_SCH_ACTIVATION_COUNT) + { + RETVALUE(TRUE); + } + RETVALUE(FALSE); +} +#endif/*LTE_ADV*/ + + + +/********************************************************************** + + End of file +**********************************************************************/ diff --git a/src/5gnrmac/rg_sch_tmr.c b/src/5gnrmac/rg_sch_tmr.c new file mode 100755 index 000000000..350f1bd57 --- /dev/null +++ b/src/5gnrmac/rg_sch_tmr.c @@ -0,0 +1,463 @@ +/******************************************************************************* +################################################################################ +# Copyright (c) [2017-2019] [Radisys] # +# # +# 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. # +################################################################################ +*******************************************************************************/ + +/************************************************************************ + + Name: LTE-MAC layer + + Type: C source file + + Desc: C source code for Entry point fucntions + + File: rg_sch_tmr.c + +**********************************************************************/ + +/** @file rg_sch_tmr.c +@brief This module does processing related to timers for the scheduler. +*/ +static const char* RLOG_MODULE_NAME="MAC"; +static int RLOG_MODULE_ID=4096; +static int RLOG_FILE_ID=175; + +/* header include files -- defines (.h) */ +#include "envopt.h" /* environment options */ +#include "envdep.h" /* environment dependent */ +#include "envind.h" /* environment independent */ +#include "gen.h" /* general layer */ +#include "ssi.h" /* system services */ +#include "cm5.h" /* common timers defines */ +#include "cm_hash.h" /* common hash list defines */ +#include "cm_llist.h" /* common linked list defines */ +#include "cm_mblk.h" /* memory management */ +#include "cm_tkns.h" /* common tokens */ +#include "cm_lte.h" /* common tokens */ +#include "tfu.h" /* RGU defines */ +#include "lrg.h" /* layer management defines for LTE-MAC */ +#include "rgr.h" /* layer management defines for LTE-MAC */ +#include "rg_env.h" /* defines and macros for MAC */ +#include "rg_sch_err.h" /* defines and macros for MAC */ +#include "rg_sch_inf.h" /* defines and macros for MAC */ +#include "rg_sch.h" /* defines and macros for MAC */ +#include "rl_interface.h" +#include "rl_common.h" + + +/* header/extern include files (.x) */ +#include "gen.x" /* general layer typedefs */ +#include "ssi.x" /* system services typedefs */ +#include "cm5.x" /* common timers */ +#include "cm_hash.x" /* common hash list */ +#include "cm_lib.x" /* common library */ +#include "cm_llist.x" /* common linked list */ +#include "cm_mblk.x" /* memory management */ +#include "cm_tkns.x" /* common tokens */ +#include "cm_lte.x" /* common tokens */ +#include "tfu.x" /* RGU types */ +#include "lrg.x" /* layer management typedefs for MAC */ +#include "rgr.x" /* layer management typedefs for MAC */ +#include "rg_sch_inf.x" /* typedefs for MAC */ +#include "rg_sch.x" /* typedefs for MAC */ + +#ifdef LTE_ADV +EXTERN PUBLIC Void rgSCHSCellActivation ARGS(( +RgSchUeCellInfo *sCell +)); +#endif + /** @brief This function is a utility function to start timers, it is a + * generic function. + * + * @details + * + * Function: rgSCHTmrStartTmr + * + * Processing steps: + * - Starts timer at scheduler + * + * @param[in] RgSchCellCb *cell + * @param[in] Ptr cb + * @param[in] S16 tmrEvnt + * @param[in] U32 tmrVal + * @return Void + */ +#ifdef ANSI +PUBLIC Void rgSCHTmrStartTmr +( +RgSchCellCb *cell, +Ptr cb, +S16 tmrEvnt, +U32 tmrVal +) +#else +PUBLIC Void rgSCHTmrStartTmr (cell, cb, tmrEvnt, tmrVal) +RgSchCellCb *cell; +Ptr cb; +S16 tmrEvnt; +U32 tmrVal; +#endif +{ + CmTmrArg arg; + RgSchUeCb *ue; +#ifdef LTE_ADV + RgSchUeCellInfo *sCellCb = NULLP; +#endif + + TRC2(rgSCHTmrStartTmr); + + +#ifndef LTE_ADV + ue = (RgSchUeCb*)cb; +#else + if(tmrEvnt == RG_SCH_TMR_SCELL_DEACT) + { + sCellCb = (RgSchUeCellInfo *)cb; + } + else + { + ue = (RgSchUeCb*)cb; + } +#endif + + switch (tmrEvnt) + { + case RG_SCH_TMR_ACKNACK_REP: + arg.timers = &(ue->ackNakRepCb.ackNakRepTmr); + RLOG_ARG0(L_ERROR,DBG_INSTID,cell->instIdx, + "Hit AckNackRep timer"); + break; + case RG_SCH_TMR_MEASGAP: + arg.timers = &(ue->measGapCb.measGapTmr); + break; + case RG_SCH_TMR_UL_ACKNACK: + arg.timers = &(ue->ackNakRepCb.ackNakRepUlInactvTmr); + break; + case RG_SCH_TMR_DL_ACKNACK: + arg.timers = &(ue->ackNakRepCb.ackNakRepDlInactvTmr); + break; + case RG_SCH_TMR_UL_MEASGAP: + arg.timers = &(ue->measGapCb.measGapUlInactvTmr); + break; + case RG_SCH_TMR_DL_MEASGAP: + arg.timers = &(ue->measGapCb.measGapDlInactvTmr); + break; + case RG_SCH_TMR_TA: + arg.timers = &(ue->taTmr); + break; + /*MS_WORKAROUND for CR FIXME */ +#ifndef RGR_V1 + case RG_SCH_TMR_BSR: + { + arg.timers = &(ue->bsrTmr); + break; + } +#else + case RG_SCH_TMR_BSR: + { +#ifdef NO_BSR_SR_5GTF + RETVOID; +#endif + arg.timers = &(ue->bsrTmr); + break; + } +#endif + case RG_SCH_TMR_TXMODE_TRNSTN: + { + arg.timers = &(ue->txModeTransTmr); + break; + } +#ifdef LTE_ADV + case RG_SCH_TMR_SCELL_DEACT: + { + arg.timers = &(sCellCb->deactTmr); + break; + } + case RG_SCH_TMR_SCELL_ACT_DELAY: + { + sCellCb = (RgSchUeCellInfo *)cb; + arg.timers = &(sCellCb->actDelayTmr); + break; + } +#endif + default: + RLOG_ARG0(L_ERROR,DBG_INSTID,cell->instIdx, + "rgSCHTmrStartTmr() Incorrect Timer event"); + RETVOID; + } + + arg.tqCp = &(cell->tqCp); + arg.tq = cell->tq; + arg.cb = (PTR)cb; + arg.evnt = tmrEvnt; + arg.wait = tmrVal; + arg.max = 1; + arg.tNum = NOTUSED; + cmPlcCbTq(&arg); + RETVOID; + +} /* end of */ + + /** @brief This function stops the timer. + * + * @details + * + * Function: rgSCHTmrStopTmr + * + * Processing steps: + * - Stops timer at scheduler. + * + * @param[in] RgSchCellCb *cell + * @param[in] S16 tmrEvnt + * @param[in] Ptr cb + * @return Void + */ +#ifdef ANSI +PUBLIC Void rgSCHTmrStopTmr +( +RgSchCellCb *cell, +S16 tmrEvnt, +Ptr cb +) +#else +PUBLIC Void rgSCHTmrStopTmr (cell, tmrEvnt, cb) +RgSchCellCb *cell; +S16 tmrEvnt; +Ptr cb; +#endif +{ + CmTmrArg arg; + RgSchUeCb *ue; +#ifdef LTE_ADV + RgSchUeCellInfo *sCellCb = NULLP; +#endif + + TRC2(rgSCHTmrStopTmr); + + +#ifndef LTE_ADV + ue = (RgSchUeCb*)cb; +#else + if(tmrEvnt == RG_SCH_TMR_SCELL_DEACT) + { + sCellCb = (RgSchUeCellInfo *)cb; + } + else + { + ue = (RgSchUeCb*)cb; + } +#endif + + switch (tmrEvnt) + { + case RG_SCH_TMR_ACKNACK_REP: + arg.timers = &(ue->ackNakRepCb.ackNakRepTmr); + break; + case RG_SCH_TMR_MEASGAP: + arg.timers = &(ue->measGapCb.measGapTmr); + break; + case RG_SCH_TMR_UL_ACKNACK: + arg.timers = &(ue->ackNakRepCb.ackNakRepUlInactvTmr); + break; + case RG_SCH_TMR_DL_ACKNACK: + arg.timers = &(ue->ackNakRepCb.ackNakRepDlInactvTmr); + break; + case RG_SCH_TMR_UL_MEASGAP: + arg.timers = &(ue->measGapCb.measGapUlInactvTmr); + break; + case RG_SCH_TMR_DL_MEASGAP: + arg.timers = &(ue->measGapCb.measGapDlInactvTmr); + break; + case RG_SCH_TMR_TA: + arg.timers = &(ue->taTmr); + break; + /*MS_WORKAROUND for CR FIXME */ +#ifndef RGR_V1 + case RG_SCH_TMR_BSR: + + { + arg.timers = &(ue->bsrTmr); + break; + } +#else + case RG_SCH_TMR_BSR: + { +#ifdef NO_BSR_SR_5GTF + RETVOID; +#endif + arg.timers = &(ue->bsrTmr); + break; + } + +#endif + case RG_SCH_TMR_TXMODE_TRNSTN: + { + arg.timers = &(ue->txModeTransTmr); + break; + } +#ifdef LTE_ADV + case RG_SCH_TMR_SCELL_DEACT: + { + arg.timers = &(sCellCb->deactTmr); + break; + } + case RG_SCH_TMR_SCELL_ACT_DELAY: + { + sCellCb = (RgSchUeCellInfo *)cb; + arg.timers = &(sCellCb->actDelayTmr); + break; + } +#endif + + default: + RLOG_ARG0(L_ERROR,DBG_INSTID,cell->instIdx, + "rgSCHTmrStopTmr() Incorrect Timer event"); + RETVOID; + } + + arg.tqCp = &(cell->tqCp); + arg.tq = cell->tq; + arg.cb = (PTR)cb; + arg.evnt = tmrEvnt; + arg.wait = NOTUSED; + arg.max = 0; + arg.tNum = NOTUSED; + cmRmvCbTq(&arg); + RETVOID; +} /* end of */ + + /** @brief This function handles timer expiry. + * + * @details + * + * Function: rgSCHTmrProcTmr + * + * Processing steps: + * - Handles processing on timer expiry at scheduler. + * + * @param[in] Ptr cb + * @param[in] S16 tmrEvnt + * @return Void + */ +#ifdef ANSI +PUBLIC Void rgSCHTmrProcTmr +( +Ptr cb, +S16 tmrEvnt +) +#else +PUBLIC Void rgSCHTmrProcTmr (cb, tmrEvnt) +Ptr cb; +S16 tmrEvnt; +#endif +{ + RgSchUeCb *ue = NULLP; +#ifdef LTE_ADV + RgSchUeCellInfo *sCellCb = NULLP; +#endif + + TRC2(rgSCHTmrProcTmr); + +#ifndef LTE_ADV + ue = (RgSchUeCb*)cb; +#else + if(tmrEvnt == RG_SCH_TMR_SCELL_DEACT) + { + sCellCb = (RgSchUeCellInfo *)cb; + } + else + { + ue = (RgSchUeCb*)cb; + } +#endif + + + switch (tmrEvnt) + { + case RG_SCH_TMR_ACKNACK_REP: + rgSCHAckNakRepTmrExpry (ue); + break; + case RG_SCH_TMR_MEASGAP: + rgSCHMeasGapANRepTmrExpry (ue); + break; + case RG_SCH_TMR_UL_MEASGAP: + case RG_SCH_TMR_UL_ACKNACK: + rgSCHMeasGapANRepUlInactvTmrExpry (ue, (U8)tmrEvnt); + break; + case RG_SCH_TMR_DL_ACKNACK: + case RG_SCH_TMR_DL_MEASGAP: + rgSCHMeasGapANRepDlInactvTmrExpry (ue, (U8)tmrEvnt); + break; + case RG_SCH_TMR_TA: +#ifdef EMTC_ENABLE + /*TODO Needto handle TA Timer expiry for EMTC UE*/ + if(TRUE == ue->isEmtcUe) + { + RLOG0(L_INFO,"TA Timer Expiry is not handled for EMTC UE\n"); + break; + } +#endif + rgSCHDhmProcTAExp (ue); + break; + /*MS_WORKAROUND for CR FIXME */ +#ifndef RGR_V1 + case RG_SCH_TMR_BSR: + { + rgSCHCmnBsrTmrExpry(ue); + } + break; +#else + case RG_SCH_TMR_BSR: + { + rgSCHCmnBsrTmrExpry(ue); + } + break; + +#endif + case RG_SCH_TMR_TXMODE_TRNSTN: + { + ue->txModeTransCmplt = TRUE; + break; + } +#ifdef LTE_ADV + case RG_SCH_TMR_SCELL_DEACT: + { + rgSCHSCellDeactTmrExpry(sCellCb); + break; + } + case RG_SCH_TMR_SCELL_ACT_DELAY: + { + sCellCb = (RgSchUeCellInfo *)cb; + rgSCHSCellActivation(sCellCb); + break; + } +#endif + default: + if(ue) + { + RLOG_ARG0(L_ERROR,DBG_INSTID,ue->cell->instIdx, + "rgSCHTmrProcTmr() Incorrect Timer event"); + } + RETVOID; + } + RETVOID; +} /* end of */ + + +/********************************************************************** + + End of file +**********************************************************************/ diff --git a/src/5gnrmac/rg_sch_tom.c b/src/5gnrmac/rg_sch_tom.c new file mode 100755 index 000000000..f3ae5fac1 --- /dev/null +++ b/src/5gnrmac/rg_sch_tom.c @@ -0,0 +1,8877 @@ +/******************************************************************************* +################################################################################ +# Copyright (c) [2017-2019] [Radisys] # +# # +# 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. # +################################################################################ +*******************************************************************************/ + +/************************************************************************ + + Name: LTE-MAC layer + + Type: C source file + + Desc: C source code for Entry point fucntions + + File: rg_sch_tom.c + +**********************************************************************/ + +/** @file rg_sch_tom.c +@brief This module does processing related to handling of lower interface APIs +invoked by PHY towards scheduler. +*/ +static const char* RLOG_MODULE_NAME="MAC"; +static int RLOG_FILE_ID=228; +static int RLOG_MODULE_ID=4096; + +/* header include files -- defines (.h) */ +#include "envopt.h" /* environment options */ +#include "envdep.h" /* environment dependent */ +#include "envind.h" /* environment independent */ +#include "gen.h" /* general layer */ +#include "ssi.h" /* system services */ +#include "cm5.h" /* common timers defines */ +#include "cm_hash.h" /* common hash list defines */ +#include "cm_llist.h" /* common linked list defines */ +#include "cm_mblk.h" /* memory management */ +#include "cm_tkns.h" /* common tokens */ +#include "cm_lte.h" /* common tokens */ +#include "tfu.h" /* RGU defines */ +#include "lrg.h" /* layer management defines for LTE-MAC */ +#include "rgr.h" /* layer management defines for LTE-MAC */ +#include "rgm.h" /* layer management defines for LTE-MAC */ +#include "rg_env.h" /* defines and macros for MAC */ +#include "rg_sch_err.h" /* defines and macros for MAC */ +#include "rg_sch_inf.h" /* defines and macros for MAC */ +#include "rg_sch.h" /* defines and macros for MAC */ +#include "rg_sch_cmn.h" /* typedefs for MAC */ +#include "rl_interface.h" +#include "rl_common.h" + + +/* header/extern include files (.x) */ +#include "gen.x" /* general layer typedefs */ +#include "ssi.x" /* system services typedefs */ +#include "cm5.x" /* common timers */ +#include "cm_hash.x" /* common hash list */ +#include "cm_lib.x" /* common library */ +#include "cm_llist.x" /* common linked list */ +#include "cm_mblk.x" /* memory management */ +#include "cm_tkns.x" /* common tokens */ +#include "cm_lte.x" /* common tokens */ +#include "tfu.x" /* RGU types */ +#include "lrg.x" /* layer management typedefs for MAC */ +#include "rgr.x" /* layer management typedefs for MAC */ +#include "rgm.x" /* layer management typedefs for MAC */ +#include "rg_sch_inf.x" /* typedefs for Scheduler */ +#include "rg_sch.x" /* typedefs for MAC */ +#include "rg_sch_cmn.x" /* typedefs for MAC */ +#ifdef EMTC_ENABLE +#include "rg_sch_emtc_ext.x" +#endif +/* local defines */ +#ifdef EMTC_ENABLE +EXTERN Bool rgSCHEmtcChkEmtcUe ARGS( +( +RgSchCellCb *cell, +U16 rapId +)); +EXTERN Void rgSchTomTtiEmtcSched ARGS( +( + RgSchCellCb *cell +)); + +EXTERN S16 rgSCHEmtcRamVldtProcRaReq +( +U8 raRntiCnt, +U8 raReqCnt, +RgSchCellCb *cell, +TfuRaReqIndInfo *raReqInd, +RgSchUeCb *ue, +Bool *isEmtcUe, +RgSchErrInfo *err +); +EXTERN Void rgSCHEmtcUpdCqiInfo +( +RgSchUeCb *ue, +RgSchUePCqiCb *cqiCb, +U16 *cqiIdx +); +EXTERN Void rgSCHEmtcUpdSRInfo +( +RgSchUeCb *ue, +U16 *srIdx +); +EXTERN Void rgSCHCmnEmtcHdlCrcFailInd +( +RgSchCellCb *cell, +RgSchRaCb *raCb +); +EXTERN S16 rgSCHEmtcTomUtlProcAtCrc +( +RgSchCellCb *cell, +CmLteTimingInfo crntHiDci0Frm, +TfuCntrlReqInfo *cntrlInfo, +RgSchErrInfo *err +); +EXTERN Void rgSCHEmtcInitUeRecpReqLst +( +TfuRecpReqInfo *recpReqInfo +); +EXTERN Void rgSCHEmtcFillPucchRecpInfo +( +RgSchCellCb *cell, +RgSchDlHqProcCb *hqCb, +U16 *hqRes +); +EXTERN Bool rgSCHEmtcAddRecpInfoToLst +( +RgSchDlHqProcCb *hqCb, +TfuRecpReqInfo *recpReqInfo, +TfuUeRecpReqInfo *pucchRecpInfo, +Bool isEmtcUe +); +EXTERN Void rgSCHEmtcWillUeRptCqi +( +RgSchUeCb *ue, +Bool *willUeRprtCqi +); +EXTERN Void rgSchEmtcTomTtiCnsldtSfAlloc +( +RgSchCellCb *cell +); + +EXTERN S16 rgSchEmtcTomTtiL1DlAndUlCfg +( +RgSchCellCb *cell, +RgTfuCntrlReqInfo *cntrlInfo +); + +EXTERN S16 rgSCHTomEmtcUtlFillDatRecpReq +( + TfuRecpReqInfo *recpReqInfo, + RgSchCellCb *cell, + U16 validIdx, + RgSchErrInfo *err +); + +EXTERN S16 rgSCHEmtcTomUtlFillHqFdbkRecpReq +( + TfuRecpReqInfo *recpReqInfo, + RgSchCellCb *cell, + U16 validIdx, + RgSchErrInfo *err +); + +EXTERN S16 rgSCHEmtcDhmRlsDlsfHqProc +( +RgSchCellCb *cell, +CmLteTimingInfo timingInfo +); + +EXTERN Void rgSCHEmtcCmnUlSch +( + RgSchCellCb *cell +); + +#ifdef RG_ULSCHED_AT_CRC +EXTERN S16 rgSCHEmtcTomUtlProcDlSfAtCrc +( +RgSchEmtcDlSf *ulSf, +CmLteTimingInfo crntUlFrm, +RgSchCellCb *cell, +TfuCntrlReqInfo *cntrlInfo, +RgSchErrInfo *err +); + +EXTERN RgSchEmtcDlSf* rgSCHEmtcUtlSubFrmGet +( +RgSchCellCb *cell, +CmLteTimingInfo frm +); +#endif + +EXTERN U32 gDlMpdcchBlank; +EXTERN U32 gUlMpdcchBlank; +EXTERN S16 rgSCHUtlIotResPrcTti +( +RgSchCellCb *cell +); + +#endif + +EXTERN RgSchUeCb* rgSCHCmnGetHoUe +( +RgSchCellCb *cell, +U16 rapId +); +EXTERN RgSchUeCb* rgSCHCmnGetPoUe +( +RgSchCellCb *cell, +U16 rapId, +CmLteTimingInfo timingInfo +); +PUBLIC S16 rgSCHTomUtlFillDatAperRecpReq ARGS( +( + RgSchCellCb *cell, + U8 cqiReq, + RgSchUlAlloc *alloc, + TfuUeRecpReqInfo *datRecpInfo, + CmLteTimingInfo *timeInfo, + Bool hqPres, + U16 validIdx + )); + +PUBLIC S16 rgSCHTomUtlFillDatPriRecpReq ARGS( +( + RgSchCellCb *cell, + RgSchUlAlloc *alloc, + TfuUeRecpReqInfo *datRecpInfo, + CmLteTimingInfo *timeInfo, + Bool hqPres, + U16 validIdx + )); + +PUBLIC S16 rgSCHTomUtlFillDatPCqiRecpReq ARGS( +( + RgSchCellCb *cell, + RgSchUlAlloc *alloc, + TfuUeRecpReqInfo *datRecpInfo, + CmLteTimingInfo *timeInfo, + Bool hqPres, + U16 validIdx + )); + +PUBLIC S16 rgSCHTomUtlFillDatSrsRecpReq ARGS( +( + RgSchCellCb *cell, + RgSchUlAlloc *alloc, + TfuUeRecpReqInfo *datRecpInfo, + CmLteTimingInfo *timeInfo, + Bool hqPres + )); + + +#ifdef CA_DBG +EXTERN U32 delayedApiCnt; +U32 gPCellTb1AckCount=0,gPCellTb2AckCount=0,gPCellTb1NackCount=0,gPCellTb2NackCount=0; +U32 gSCellSchedCount=0,gPrimarySchedCount=0; +U32 gSCellTb1AckCount=0,gSCellTb2AckCount=0,gSCellTb1NackCount=0,gSCellTb2NackCount=0; +U32 gPCellTb1DtxCount = 0, gPCellTb2DtxCount = 0, gSCellTb1DtxCount = 0, gSCellTb2DtxCount = 0; +U32 gHqFdbkCount = 0; + + + +U32 gCqiRecpCount = 0; +U32 gCqiRecpPuschCount = 0; +U32 gCqiRcvdCount = 0; +Bool gF1bCsPres = FALSE; +U32 gRiReqCount = 0; +U32 gCqiReqCount = 0; +U32 gF1bCsCount = 0; +U32 gACqiRcvdCount = 0; +U32 gCqiReptToAppCount = 0; +U32 gRawACqiCount= 0; +U32 gCqiDropCount,gPucchDropCount; +U32 gCqiPucchLowSnrDropCount,gCqiPucchConfMaskDropCount,gCqiPuschConfMaskDropCount; +U32 gDci0Count = 0; +U32 gUlCrcFailCount = 0; +U32 gUlCrcPassCount = 0; +U32 gPuschCqiDropCount = 0; +U32 gCaDbgCaFrmt = 0; +U32 gCaDbgNonCaFrmt = 0; +U32 gPcellZeroBoOcc=0,gScellZeroBoOcc=0, dbgDelayedDatReqInMac=0,gDropDatReqCnt=0, gIccPktRcvrMemDropCnt=0; +#endif + +#ifdef EMTC_ENABLE +U32 gUlCrcFailCounter = 0; +U32 gUlCrcPassCounter = 0; +#endif + +#ifdef RG_5GTF +EXTERN U32 gUl5gtfPdcchSend; +PRIVATE S16 rgSCHTomUtlFillCqiRiRecpReq ARGS( +( + TfuRecpReqInfo *recpReqInfo, + RgSchCellCb *cell, + U16 validIdx, + RgSchErrInfo *err + )); +#endif + + +/* local typedefs */ +PUBLIC U32 rgBwAlloInfo[RGSCH_NUM_SUB_FRAMES]; /* Num of Rbs Allocated in each SF */ +PUBLIC U32 rgBwAlcnt[RGSCH_NUM_SUB_FRAMES]; /*Num of times Allocation done in each Subframe */ + +/* local externs */ +/* rg006.201: [ccpu000111706, ccpu00112394]: Separated UL and DL TTI + * processing */ +#ifdef LTE_L2_MEAS + U64 glblTtiCnt = 0; +#endif +U32 ri1Cnt ; +U32 ri2Cnt ; +U32 gDlNumUePerTti[20] = {0}; +U32 gUlNumUePerTti[20] = {0}; +PRIVATE S16 rgSCHTomUtlProcDlSf ARGS(( + RgSchDlSf *dlSf, + RgSchDlSf *ulSf, + RgSchCellCb *cell, + RgTfuCntrlReqInfo *cntrlInfo, + RgSchErrInfo *err)); +#ifdef RG_ULSCHED_AT_CRC +PRIVATE S16 rgSCHTomUtlProcDlSfAtCrc ARGS(( + RgSchDlSf *ulSf, + CmLteTimingInfo crntUlFrm, + RgSchCellCb *cell, + TfuCntrlReqInfo *cntrlInfo, + RgSchErrInfo *err)); +#endif /* RG_ULSCHED_AT_CRC */ +#ifdef LTE_TDD +#ifdef TFU_UPGRADE +PRIVATE S16 rgSCHTomUtlPrcUlTddSpclSf ARGS(( + RgSchCellCb *cell, + RgSchErrInfo *err)); +#endif /* TFU_UPGRADE */ +#endif +PRIVATE S16 rgSCHTomUtlFillPhich ARGS(( + RgSchCellCb *cell, + TfuCntrlReqInfo *cntrlInfo, + RgSchDlSf *dlSf, + RgSchErrInfo *err)); + +PRIVATE S16 rgSCHTomUtlFillDlPdcch ARGS(( + RgSchCellCb *cell, + TfuCntrlReqInfo *cntrlInfo, + RgSchDlSf *dlSf, + RgSchErrInfo *err)); +PRIVATE S16 rgSCHTomUtlFillUlPdcch ARGS(( + RgSchCellCb *cell, + TfuCntrlReqInfo *cntrlInfo, + RgSchDlSf *ulSf, + RgSchErrInfo *err)); + +PRIVATE S16 rgSCHTomUtlProcTA ARGS(( + RgSchCellCb *cell)); +#ifdef TFU_UPGRADE +PRIVATE S16 rgSCHTomUtlFillHqFdbkRecpReq ARGS(( + TfuRecpReqInfo *recpReq, + RgSchCellCb *cell, + U16 validIdx, + RgSchErrInfo *err)); +#else +PRIVATE S16 rgSCHTomUtlFillHqFdbkRecpReq ARGS(( + TfuRecpReqInfo *recpReq, + RgSchCellCb *cell, + RgSchErrInfo *err)); +#endif +#ifdef TFU_UPGRADE + +PUBLIC S16 rgSCHTomFillOnlySrsRecpReq ARGS +(( + RgSchCellCb *cell, + RgSchUlAlloc *alloc, + TfuUeRecpReqInfo *datRecpInfo + )); + +PRIVATE S16 rgSCHTomUtlFillCqiSrsWithSr ARGS +(( + RgSchCellCb *cell, + RgSchUeCb *ue, + TfuRecpReqInfo *recpReqInfo, + TfuUeRecpReqInfo *pucchRecpInfo, + U16 validIdx + )); + +PRIVATE S16 rgSCHTomUtlFillCqiSrSrsWithHq ARGS +(( + RgSchCellCb *cell, + TfuRecpReqInfo *recpReqInfo, + RgSchUeCb *ue, + TfuUeRecpReqInfo *pucchRecpInfo, + U16 validIdx, + Bool isDatPresOnSecCell + )); + +PUBLIC S16 rgSCHTomUtlFillRiBitWidthInfo ARGS +(( + RgSchUeCb *ueCb +)); + +PUBLIC U8 rgSCHTomUtlFetchPcqiBitSz ARGS +(( +RgSchUeCb *ueCb, +U8 numTxAnt, +U8 *ri +)); + +PUBLIC U8 rgSCHTomUtlFetchPcqiBitSzPucchMode21 ARGS +(( +RgSchUeCb *ueCb, +TfuCqiPucchMode21 *mode21Info, +U8 numTxAnt, +U8 *ri +)); + +PUBLIC S16 rgSCHTomUtlMoveNxtOccasion ARGS +(( +RgSchCellCb *cell, +RgSchUeCb *ueCb, +U16 validIdx +)); + +PRIVATE S16 rgSCHTomUtlMovePcqiNxtOccasion ARGS +(( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgSchUePCqiCb *cqiCb +)); + +PRIVATE S16 rgSCHTomUtlMovePriNxtOccasion ARGS +(( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgSchUePCqiCb *riCb +)); + +PRIVATE S16 rgSCHTomUtlMoveSrNxtOccasion ARGS +(( +RgSchCellCb *cell, +RgSchUeCb *ue +)); + +PRIVATE S16 rgSCHTomUtlMoveSrsNxtOccasion ARGS +(( +RgSchCellCb *cell, +RgSchUeCb *ue +)); + +PRIVATE Bool rgSCHTomUtlFillDatHarqRecpReq ARGS +(( + RgSchCellCb *cell, + RgSchUlAlloc *alloc, + TfuUeRecpReqInfo *datRecpInfo, + TfuRecpReqInfo *recpReqInfo + )); + +PRIVATE S16 rgSCHTomUtlFillSrRecpReq ARGS(( + TfuRecpReqInfo *recpReq, + RgSchCellCb *cell, + U16 validIdx, + RgSchErrInfo *err)); + +PRIVATE S16 rgSCHTomUtlWillUeRprtCqiRi ARGS(( + RgSchUeCb *ue, + Bool *willueRprtCqiRii)); + +PRIVATE S16 rgSCHTomUtlFillRiRecpReq ARGS(( + TfuRecpReqInfo *recpReq, + RgSchCellCb *cell, + U16 validIdx, + RgSchErrInfo *err)); + +PRIVATE S16 rgSCHTomUtlFillPcqiRecpReq ARGS(( + TfuRecpReqInfo *recpReq, + RgSchCellCb *cell, + U16 validIdx, + RgSchErrInfo *err)); + +PRIVATE S16 rgSCHTomUtlFillSrsRecpReq ARGS(( + TfuRecpReqInfo *recpReq, + RgSchCellCb *cell, + U16 validIdx, + RgSchErrInfo *err)); + +PRIVATE S16 rgSCHTomUtlGenIndices ARGS(( + U32 label, + U8 posM, + U8 valN, + U8 valK, + TfuSubbandInfo* sbInfo)); + +#endif +#ifdef TFU_UPGRADE +PRIVATE S16 rgSCHTomUtlFillDatRecpReq ARGS(( + TfuRecpReqInfo *recpReq, + RgSchCellCb *cell, + U16 validIdx, + RgSchErrInfo *err)); +#else +PRIVATE S16 rgSCHTomUtlFillDatRecpReq ARGS(( + TfuRecpReqInfo *recpReq, + RgSchCellCb *cell, + RgSchErrInfo *err)); +#endif + +#ifdef LTE_TDD +#ifdef TFU_UPGRADE +PRIVATE S16 rgSCHTomUtlFillSfRepHqFdbk ARGS(( + TfuRecpReqInfo *recpReqInfo, + RgSchCellCb *cell, + RgSchErrInfo *err, + RgSchDlSf *dlSf, + U8 noFdbks, + CmMemListCp *memCp, + U8 elemIdx, + RgSchDlSf *nxtDlsf, + U16 validIdx + )); +#else +PRIVATE S16 rgSCHTomUtlFillSfRepHqFdbk ARGS(( + TfuRecpReqInfo *recpReqInfo, + RgSchCellCb *cell, + RgSchErrInfo *err, + RgSchDlSf *dlSf, + U8 noFdbks, + CmMemListCp *memCp, + U8 elemIdx, + RgSchDlSf *nxtDlsf + )); +#endif +#ifdef TFU_UPGRADE +PRIVATE S16 rgSCHTomUtlFillSfHqFdbk ARGS(( + TfuRecpReqInfo *recpReqInfo, + RgSchCellCb *cell, + RgSchErrInfo *err, + RgSchDlSf *dlSf, + U8 noFdbks, + CmMemListCp *memCp, + U8 elemIdx, + RgSchDlSf *nxtDlsf, + U16 validIdx + )); +#else +PRIVATE S16 rgSCHTomUtlFillSfHqFdbk ARGS(( + TfuRecpReqInfo *recpReqInfo, + RgSchCellCb *cell, + RgSchErrInfo *err, + RgSchDlSf *dlSf, + U8 noFdbks, + CmMemListCp *memCp, + U8 elemIdx, + RgSchDlSf *nxtDlsf + )); +#endif + +PRIVATE S16 rgSCHTomUtlFillSfHqFdbkForOneUe ARGS(( + RgSchDlHqProcCb *hqCb, + TfuRecpReqInfo *recpReqInfo, + RgSchCellCb *cellCb, + RgSchErrInfo *err, + RgSchDlSf *dlSf, + U8 noFdbks, + CmMemListCp *memCp, + U8 elemIdx, + RgSchDlSf *nxtDlsf, + CmLteRnti rnti, + RgrTddAckNackMode ackNackMode, + RgSchUePucchRecpInfo **pucchInfoRef, + RgSchPdcch *pdcch, + TknU16 n1PucchTkn, + Bool *allocRef, + U8 hqSz + )); +#endif +#ifdef LTEMAC_SPS +EXTERN PUBLIC Void rgSCHCmnDlSpsSch (RgSchCellCb *cell); +#ifndef LTE_TDD +#ifdef TFU_UPGRADE +PRIVATE S16 rgSCHTomCnsdrRelPdcch ARGS +(( + RgSchCellCb *cell, + RgSchDlSf *dlSf, + TfuRecpReqInfo *recpReqInfo, + U16 validIdx, + RgSchErrInfo *err + )); +#else + PRIVATE S16 rgSCHTomCnsdrRelPdcch ARGS +(( + RgSchCellCb *cell, + RgSchDlSf *dlSf, + TfuRecpReqInfo *recpReqInfo, + RgSchErrInfo *err + )); +#endif +#endif +#endif + +PRIVATE Void rgSchTomTtiMiscFunctions ARGS +(( +RgSchCellCb *cell +)); + +PRIVATE Void rgSchTomTtiUlAndDlCmnChSch ARGS +(( +RgSchCellCb *cell +)); + +PRIVATE Void rgSchTomTtiDlSch ARGS +(( +RgSchCellCb *cell +)); + +PRIVATE Void rgSchTomTtiCnsldtSfAlloc ARGS +(( +RgSchCellCb *cell +)); + +PRIVATE Void rgSchTomTtiL1DlAndUlCfg ARGS +(( +RgSchCellCb *cell, +RgTfuCntrlReqInfo *cntrlInfo +)); + +#ifdef RGR_RRM_TICK +PRIVATE Void rgSCHTomUtlSendSfnTick ARGS +(( +RgSchCellCb *cell +)); +#endif + +PRIVATE Void rgSchTomFillCellTtiInfo ARGS +(( +TfuTtiIndInfo *ttiInd, +Inst schInst, +U8 *nCell, +RgSchCellCb *cells[] +)); +#ifdef LTE_TDD +PRIVATE Void rgSchTomUtlTddRlsSfAndHarq ARGS +(( +RgSchCellCb *cell +)); +PRIVATE Void rgSCHTomUtlProcTddUlSf ARGS +(( +RgSchCellCb *cell +)); +#ifdef LTE_ADV +PRIVATE Void rgSCHTomUtlGethqRes ARGS +(( +U8 noFdbks, +RgSchDlSf *dlSf, +RgSchPdcch *pdcch, +RgSchCellCb *cellCb, +U16 *hqRes +)); +PRIVATE Void rgSCHTomUtlFillSfHqFdbkForFrmt1BCSForM1 ARGS +(( + RgSchDlHqProcCb *hqCb, + TfuUePucchRecpReq *hqRecpReq, + U8 noFdbks, + RgSchDlSf *dlSf, + RgSchPdcch *pdcch, + RgSchCellCb *cellCb +)); +PRIVATE Void rgSCHTomUtlFillSfHqFdbkForFrmt1BCSForM234 ARGS +(( + RgSchDlHqProcCb *hqCb, + TfuUePucchRecpReq *hqRecpReq, + U8 noFdbks, + RgSchDlSf *dlSf, + RgSchPdcch *pdcch, + RgSchCellCb *cellCb, + U8 elemIdx +)); +#endif/*LTE_ADV*/ +#endif/*LTE_TDD*/ + +PUBLIC U32 rgDlCqiRptCnt[16], rgTotDlCqiRpt; + +#ifdef RG_5GTF +U32 rgSch5gtfCqi2Mcs[15] = + {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14}; +#endif +/* forward references */ +#ifdef TFU_UPGRADE +/*HARQ Feedback interpretation in accordance with Femto Forum. +Note: There is no value as '0' in Femto Forum Spec but in order to retain +the existing usage in MAC (and its Acceptance), its being considered*/ +CONSTANT PRIVATE U8 rgSchTomHqFbkMap[8] = {0,1,0,0,4,4,4,4}; +/*added #defines instead of magic numbers*/ +CONSTANT PRIVATE U32 rgSCHTomBinCoe[RG_SCH_MAX_NUM_UE_SEL_SUBBANDS][RG_SCH_MAX_TOT_NUM_SUBBANDS]={ +{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28}, +{0,1,3,6,10,15,21,28,36,45,55,66,78,91,105,120,136,153,171,190,210,231,253,276,300,325,351,378}, +{0,0,1,4,10,20,35,56,84,120,165,220,286,364,455,560,680,816,969,1140,1330,1540,1771,2024,2300,2600,2925,3276}, +{0,0,0,1,5,15,35,70,126,210,330,495,715,1001,1365,1820,2380,3060,3876,4845,5985,7315,8855,10626,12650,14950,17550,20475}, +{0,0,0,0,1,6,21,56,126,252,462,792,1287,2002,3003,4368,6188,8568,11628,15504,20349,26334,33649,42504,53130,65780,80730,98280}, +{0,0,0,0,0,1,7,28,84,210,462,924,1716,3003,5005,8008,12376,18564,27132,38760,54264,74613,100947,134596,177100,230230,296010,376740} +}; + + +/*ccpu00116923 - ADD - SRS present support*/ +/*Tables Derived from 3GPP TS 36.211 Section 5.5.3.3 */ +/* Table 5.5.3.3-1 */ +#ifndef LTE_TDD +CONSTANT PUBLIC RgSchFddCellSpSrsSubfrmTbl rgSchFddCellSpSrsSubfrmTbl = { + {TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE}, + {TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE}, + {FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE}, + {TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE}, + {FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE}, + {FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE}, + {FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE}, + {TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE}, + {FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE}, + {TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE}, + {FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE}, + {FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE}, + {FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE}, + {TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE}, + {TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE}, + {FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE} +}; +#else +/* Table 5.5.3.3-2 */ +CONSTANT PUBLIC RgSchTddCellSpSrsSubfrmTbl rgSchTddCellSpSrsSubfrmTbl = { + {FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE}, + {FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE}, + {FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE}, + {FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, TRUE}, + {FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE}, + {FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE}, + {FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, TRUE}, + {FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE}, + {FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE}, + {FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE}, + {FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE}, + {FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE}, + {FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE}, + {FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE}, + {FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE}, + {FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE} +}; +#endif +PUBLIC S8 rgSchCmnAper20n22DiffCqi[4] = {1, 2, 3, 4}; +PUBLIC S8 rgSchCmnAper30n31DiffCqi[4] = {0, 1, 2, -1}; +#endif + +/** + * @brief get Ue for dedicated preamble rach + * + * @details + * + * Function: rgSCHGetDedPrmUe + * + * Invoked by: rgSCHTomRaReqInd + * + * @param[in] RgSchCellCb *cell + * @param[in] TfuRaReqIndInfo *raReqInd + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 rgSCHGetDedPrmUe +( +RgSchCellCb *cell, +U16 rapId, +CmLteTimingInfo timingInfo, +RgSchUeCb **ue +) +#else +PUBLIC S16 rgSCHGetDedPrmUe(cell, rapId, timingInfo, ue) +RgSchCellCb *cell; +U16 rapId; +CmLteTimingInfo timingInfo; +RgSchUeCb **ue; +#endif +{ + RgSchCmnCell *cellSch = (RgSchCmnCell *)(cell->sc.sch); + + printf("rapId[%d] cellSch->rachCfg.dedPrmStart[%d] cellSch->rachCfg.numDedPrm[%d]\n",rapId,cellSch->rachCfg.dedPrmStart,cellSch->rachCfg.numDedPrm); + /* Finding UE in handOver List */ + if ((rapId < cellSch->rachCfg.dedPrmStart) || + (rapId > cellSch->rachCfg.dedPrmStart + + cellSch->rachCfg.numDedPrm - 1)) + { + /* This ded Preamble corresponds to handover */ + *ue = rgSCHCmnGetHoUe(cell, rapId); + printf(" his ded Preamble corresponds to hando\n"); + } + else/* Finding UE from PDCCH Order Mappings */ + { + /* Get the UE which has transmitted this RaReq */ + *ue = rgSCHCmnGetPoUe(cell, rapId, timingInfo); + printf(" ==== inding UE from PDCCH Order Mapping\n"); + } + RETVALUE(ROK); +} +/** + * @brief Handler for processing Random Access request indication + * recieved from PHY. + * + * @details + * + * Function: rgSCHTomRaReqInd + * + * Handler for processing Random Access request indication recieved from + * PHY. + * + * Invoked by: RgLiTfuRaReqInd of LIM + * + * Processing Steps: + * - Validate the information received: cellId value and raRnti values + * - Process the request: Call rgSCHRamProcRaReq (cell, raRnti, raReqInd) + * + * @param[in] RgSchCellCb *cell + * @param[in] TfuRaReqIndInfo *raReqInd + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 rgSCHTomRaReqInd +( +RgSchCellCb *cell, +TfuRaReqIndInfo *raReqInd +) +#else +PUBLIC S16 rgSCHTomRaReqInd(cell, raReqInd) +RgSchCellCb *cell; +TfuRaReqIndInfo *raReqInd; +#endif +{ + S16 ret; + U8 raRntiCnt; + U8 raReqCnt; + RgSchErrInfo err; + Bool isEmtcUe = FALSE; + U16 rapId; + RgSchUeCb *ue = NULLP; + + TRC2(rgSCHTomRaReqInd); + + if(cell->cellId != raReqInd->cellId) + { + err.errType = RGSCHERR_TOM_RAREQIND; + err.errCause = RGSCHERR_TOM_INV_CELL_ID; + RLOG_ARG3(L_ERROR,DBG_CELLID,cell->cellId, + "rgSCHTomRaReqInd(): No cell found with raReq cellId = (%d) errorType (%d)" + " errorCause(%d)",raReqInd->cellId, err.errType, err.errCause); + RETVALUE(RFAILED); + } + + for (raRntiCnt = 0; raRntiCnt < raReqInd->nmbOfRaRnti; raRntiCnt++) + { + for (raReqCnt = 0; raReqCnt < raReqInd->rachInfoArr->numRaReqInfo; raReqCnt++) + { + rapId = raReqInd->rachInfoArr[raRntiCnt].raReqInfoArr[raReqCnt].rapId; + + if(RGSCH_IS_DEDPRM(cell, rapId)) + { + rgSCHGetDedPrmUe(cell, rapId, raReqInd->timingInfo, &ue); + if(NULLP == ue) + { + /* Since rapId is within dedicated range and No ue context + * is found means it is a spurious rach. So ignore it.*/ + continue; + } + } + + if(FALSE == isEmtcUe) + { +#if (ERRCLASS & ERRCLS_DEBUG) + if(raReqInd->rachInfoArr[raRntiCnt].raRnti > RGSCH_MAX_RA_RNTI) + { + RGSCHLOGERROR(cell->instIdx, ERRCLS_INT_PAR, ERG013, + (ErrVal)raReqInd->rachInfoArr[raRntiCnt].raRnti, + ("rgSCHTomRaReqInd(): raRnti is out of range\n")); + continue; + } +#endif + ret = rgSCHRamProcRaReq(raReqCnt, cell, raReqInd->rachInfoArr[raRntiCnt].raRnti, + (TfuRachInfo *)&raReqInd->rachInfoArr[raRntiCnt], + raReqInd->timingInfo, ue, &err); + if(ret == RFAILED) + { + err.errType = RGSCHERR_TOM_RAREQIND; + RLOG_ARG3(L_ERROR,DBG_CELLID,cell->cellId, + "RARNTI:%d rgSCHTomRaReqInd(): RAM processing failed errType(%d) " + "errCause(%d)", raReqInd->rachInfoArr[raRntiCnt].raRnti, + err.errType, err.errCause); + continue; + } + } + } + } + RETVALUE(ROK); +} /* rgSCHTomRaReqInd */ + + +/** + * @brief Handler for processing uplink CQI indication recieved from PHY. + * + * @details + * + * Function: rgSCHTomUlCqiInd + * + * Handler for processing uplink CQI indication recieved from PHY. + * + * Invoked by: RgLiTfuUlCqiInd + * + * Processing Steps: + * - Gets UE + * - Invoke scheduler to push reported CQI info rgSCHUtlUlCqiInd + * + * @param[in] RgSchCellCb *cell + * @param[in] TfuUlCqiIndInfo *ulCqiInd + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 rgSCHTomUlCqiInd +( +RgSchCellCb *cell, +TfuUlCqiIndInfo *ulCqiInd +) +#else +PUBLIC S16 rgSCHTomUlCqiInd(cell, ulCqiInd) +RgSchCellCb *cell; +TfuUlCqiIndInfo *ulCqiInd; +#endif +{ + RgSchUeCb *ue; + CmLList *node; + TfuUlCqiRpt *ulCqiInfo; + TRC2(rgSCHTomUlCqiInd); + + node = ulCqiInd->ulCqiRpt.first; + if(cell->cellId != ulCqiInd->cellId) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId, + "rgSCHTomUlCqiInd() Unable to get the ulCqiInd cell with id(%d)", + ulCqiInd->cellId); + RETVALUE(RFAILED); + } + + for (;node; node=node->next) + { + ulCqiInfo = (TfuUlCqiRpt *)node->node; +#if (ERRCLASS & ERRCLS_DEBUG) + if(ulCqiInfo->numSubband == 0) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,"Num Subband is" + "out of range RNTI:%d",ulCqiInfo->rnti); + continue; + } +#endif + if((ue = rgSCHDbmGetUeCb(cell, ulCqiInfo->rnti)) == NULLP) + { +#ifdef LTEMAC_SPS + if((ue = rgSCHDbmGetSpsUeCb(cell, ulCqiInfo->rnti)) == NULLP) +#endif + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,"Unable to get " + "the ue for RNTI:%d", ulCqiInfo->rnti); + continue; + } + } + /* wideband cqi is directly reported now. and also isTxPort0 */ + rgSCHUtlUlCqiInd(cell, ue, ulCqiInfo); + } + RETVALUE(ROK); +} /* rgSCHTomUlCqiInd */ + +/** + * @brief Handler for processing PUCCH power adjustment indication + * + * @details + * + * Function: rgSCHTomPucchDeltaPwrInd + * + * Handler for processing PUCCH power adjustment indication + * received from PHY. + * + * Invoked by: RgLiTfuPucchDeltaPwrInd + * + * Processing Steps: + * - Gets UE + * - Invoke scheduler to push reported CQI info rgSCHUtlPucchDeltaPwrInd + * + * @param[in] RgSchCellCb *cell + * @param[in] TfuPucchDeltaPwrIndInfo *pucchDeltaPwr + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 rgSCHTomPucchDeltaPwrInd +( +RgSchCellCb *cell, +TfuPucchDeltaPwrIndInfo *pucchDeltaPwr +) +#else +PUBLIC S16 rgSCHTomPucchDeltaPwrInd(cell, pucchDeltaPwr) +RgSchCellCb *cell; +TfuPucchDeltaPwrIndInfo *pucchDeltaPwr; +#endif +{ + RgSchUeCb *ue; + CmLList *node; + TfuPucchDeltaPwr *ueElem; + + TRC2(rgSCHTomPucchDeltaPwrInd); + + if(cell->cellId != pucchDeltaPwr->cellId) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId, + "rgSCHTomPucchDeltaPwrInd() Unable to get the pucchDeltaPwr cell with id(%d)", + pucchDeltaPwr->cellId); + RETVALUE(RFAILED); + } + + node = pucchDeltaPwr->pucchDeltaPwrLst.first; + for (;node; node=node->next) + { + ueElem = (TfuPucchDeltaPwr *)node->node; + if((ue = rgSCHDbmGetUeCb(cell, ueElem->rnti)) == NULLP) + { +#ifdef LTEMAC_SPS + if((ue = rgSCHDbmGetSpsUeCb(cell, ueElem->rnti)) == NULLP) +#endif + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,"RNTI:%d " + "rgSCHTomPucchDeltaPwrInd() Unable to get the ue ", + ueElem->rnti); + continue; + } + } + rgSCHUtlPucchDeltaPwrInd(cell, ue, ueElem->pucchDeltaPwr); + } + RETVALUE(ROK); +} /* rgSCHTomPucchDeltaPwrInd */ + +/** + * @brief Handler for processing harq ACK/NACK indication recieved from PHY. + * + * @details + * + * Function: rgSCHTomHarqAckInd + * + * Handler for processing harq ACK/NACK indication recieved from PHY. + * + * Invoked by: RgLiTfuHqInd + * + * Processing Steps: + * For each HqAckInfo received + * - Get UE + * - If UE doesnt exist look for a RaCb and invoke rgSCHRamMsg4FdbkInd + * - Invoke HARQ module to pass HARQ-ACK info rgSCHDhmHqFdbkInd + * + * @param[in] TfuHqIndInfo *harqAckInd + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 rgSCHTomHarqAckInd +( +RgSchCellCb *cell, +TfuHqIndInfo *harqAckInd +) +#else +PUBLIC S16 rgSCHTomHarqAckInd(cell, harqAckInd) +RgSchCellCb *cell; +TfuHqIndInfo *harqAckInd; +#endif +{ + RgSchErrInfo err; + RgSchUeCb *ue; + RgSchRaCb *raCb; + CmLList *node; + TfuHqInfo *hqInfo; + Pst pst; +#ifdef TFU_UPGRADE + U8 tbCnt; +#endif + + RgInfRlsHqInfo *rlsHqBufs = &(cell->rlsHqArr[cell->crntHqIdx]); + U32 cellIdx; + RgSchCellCb *iterCellP; + + TRC2(rgSCHTomHarqAckInd); + + if(cell->cellId != harqAckInd->cellId) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,"rgSCHTomHarqAckInd() Unable to get" + " the cell for cellId (%d)", harqAckInd->cellId); + err.errType = RGSCHERR_TOM_HARQACKIND; + err.errCause = RGSCHERR_TOM_INV_CELL_ID; + RETVALUE(RFAILED); + } +#ifdef RG_5GTF + node = harqAckInd->hqIndLst.first; + for (;node; node=node->next) + { + hqInfo = (TfuHqInfo *)node->node; + { + RgInfRlsHqInfo *rlsHqBufs = &(cell->rlsHqArr[cell->crntHqIdx]); + TfuHqFdbk fdbk = hqInfo->isAck[0]; + raCb = rgSCHDbmGetRaCb (cell, hqInfo->rnti); + ue = rgSCHDbmGetUeCb (cell, hqInfo->rnti); + if (ue != NULLP && raCb == NULLP) + { + if ((rgSCHDhm5gtfHqFdbkInd (ue, cell, harqAckInd->timingInfo, fdbk, &err)) != ROK) + { + err.errType = RGSCHERR_TOM_HARQACKIND; + RLOG_ARG2(L_ERROR,DBG_CELLID,cell->cellId,"rgSCHTomHarqAckInd() " + "HARQ feedback processing failed errType(%d)errCause(%d)n", + err.errType, err.errCause); + continue; + } + } + } + + } + + if ((rgSCHDhmRlsDlsfHqProc (cell, harqAckInd->timingInfo)) != ROK) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,"Unable to Release Downlink " + "subframe for cellId (%d) ", cell->cellId); + err.errType = RGSCHERR_TOM_HARQACKIND; + } + + for (cellIdx = 0; cellIdx < CM_LTE_MAX_CELLS; cellIdx++) + { + if (NULLP != rgSchCb[cell->instIdx].cells[cellIdx]) + { + iterCellP = rgSchCb[cell->instIdx].cells[cellIdx]; + + rlsHqBufs = &(iterCellP->rlsHqArr[iterCellP->crntHqIdx]); + if(rlsHqBufs->numUes) + { + rgSCHUtlGetPstToLyr(&pst, &rgSchCb[cell->instIdx], iterCellP->macInst); + RgSchMacRlsHq (&pst, rlsHqBufs); + } + rlsHqBufs->numUes = 0; + } + } +#else + rlsHqBufs->numUes = 0; + node = harqAckInd->hqIndLst.first; + for (;node; node=node->next) + { + hqInfo = (TfuHqInfo *)node->node; + for(tbCnt=0; tbCntisAck[tbCnt]=(TfuHqFdbk)rgSchTomHqFbkMap[hqInfo->isAck[tbCnt]]; + } + raCb = rgSCHDbmGetRaCb (cell, hqInfo->rnti); + ue = rgSCHDbmGetUeCb (cell, hqInfo->rnti); + if (ue == NULLP && raCb != NULLP) + { +#ifdef RG_UNUSED + rgSCHRamMsg4FdbkInd (raCb); +#endif + if ((rgSCHDhmHqFdbkInd (raCb, RGSCH_HQ_FDB_IND_CB_TYPE_RA_CB, + cell, harqAckInd->timingInfo, hqInfo, rlsHqBufs, &err)) != ROK) + { + err.errType = RGSCHERR_TOM_HARQACKIND; + RLOG_ARG2(L_ERROR,DBG_CELLID,cell->cellId,"rgSCHTomHarqAckInd() HARQ" + " feedback processing failed errType(%d) errCause(%d)", + err.errType, err.errCause); + continue; + } + continue; + } + else if (ue != NULLP && raCb == NULLP) + { + /* Get the Downlink HARQ entity from ue */ + if ((rgSCHDhmHqFdbkInd (ue, RGSCH_HQ_FDB_IND_CB_TYPE_HQ_ENT, + cell, harqAckInd->timingInfo, hqInfo, rlsHqBufs, &err)) != ROK) + { + err.errType = RGSCHERR_TOM_HARQACKIND; + RLOG_ARG2(L_ERROR,DBG_CELLID,cell->cellId,"rgSCHTomHarqAckInd() " + "HARQ feedback processing failed errType(%d)errCause(%d)n", + err.errType, err.errCause); + continue; + } + } + else if (ue != NULLP && raCb != NULLP) + { + if ((rgSCHDhmHqFdbkInd (raCb, RGSCH_HQ_FDB_IND_CB_TYPE_RA_CB, + cell, harqAckInd->timingInfo, hqInfo, rlsHqBufs, &err)) != ROK) + { + err.errType = RGSCHERR_TOM_HARQACKIND; + RLOG_ARG2(L_ERROR,DBG_CELLID,cell->cellId,"rgSCHTomHarqAckInd() HARQ" + " feedback processing failed errType(%d) errCause(%d).", + err.errType, err.errCause); + continue; + } + } + else + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,"RNTI:%d Unable to get the " + "UE CB or RA CB ", hqInfo->rnti); + err.errType = RGSCHERR_TOM_HARQACKIND; + continue; + } + } + + /* Check with TDD call DHM*/ + if ((rgSCHDhmRlsDlsfHqProc (cell, harqAckInd->timingInfo)) != ROK) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,"Unable to Release Downlink " + "subframe for cellId (%d) ", harqAckInd->cellId); + err.errType = RGSCHERR_TOM_HARQACKIND; + } + + for (cellIdx = 0; cellIdx < CM_LTE_MAX_CELLS; cellIdx++) + { + if (NULLP != rgSchCb[cell->instIdx].cells[cellIdx]) + { + iterCellP = rgSchCb[cell->instIdx].cells[cellIdx]; + + rlsHqBufs = &(iterCellP->rlsHqArr[iterCellP->crntHqIdx]); + if(rlsHqBufs->numUes) + { + rgSCHUtlGetPstToLyr(&pst, &rgSchCb[cell->instIdx], iterCellP->macInst); + RgSchMacRlsHq (&pst, rlsHqBufs); + } + rlsHqBufs->numUes = 0; + } + } +#endif + RETVALUE(ROK); +} /* rgSCHTomHarqAckInd */ + + +/** + * @brief Handler for processing Scheduling Request indication + * recieved from PHY for a list of UEs. + * + * @details + * + * Function: rgSCHTomSrInd + * + * Handler for processing Scheduling Request indication recieved from PHY + * for UEs. + * + * Invoked by: RgLiTfuSrInd + * + * Processing Steps: + * - Get UE + * - Invoke scheduler to indicate SR rgSCHUtlSrRcvd + * + * @param[in] TfuSrIndInfo *srInd + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 rgSCHTomSrInd +( +RgSchCellCb *cell, +TfuSrIndInfo *srInd +) +#else +PUBLIC S16 rgSCHTomSrInd(cell, srInd) +RgSchCellCb *cell; +TfuSrIndInfo *srInd; +#endif +{ + S16 ret = RFAILED; + RgSchErrInfo err; + RgSchUeCb *ue; + CmLList *node; + TfuSrInfo *srInfo; + + TRC2(rgSCHTomSrInd); + + if(cell->cellId != srInd->cellId) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,"Unable to get the cell for srcInd cellId" + ":%d ", srInd->cellId); + err.errType = RGSCHERR_TOM_SRIND; + err.errCause = RGSCHERR_TOM_INV_CELL_ID; + RETVALUE(RFAILED); + } + + + node = srInd->srLst.first; + for (;node; node=node->next) + { + rgNumSrRecvd++; + + srInfo = (TfuSrInfo *)node->node; + ue = rgSCHDbmGetUeCb (cell, srInfo->rnti); + if (ue == NULLP) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,"RNTI:%d Unable to get the UE CB", + srInfo->rnti); + continue; + } + rgSCHUtlHdlUlTransInd(cell, ue, srInd->timingInfo); + /*Need to activate UE as SR received*/ + if (ue->isDrxEnabled) + { + rgSCHDrxSrInd(cell, ue); + } + ret = rgSCHUtlSrRcvd (cell, ue, srInd->timingInfo, &err); + if (ret != ROK) + { + err.errType = RGSCHERR_TOM_SRIND; + RLOG_ARG3(L_ERROR,DBG_CELLID,cell->cellId,"Scheduler processing failed " + "errType(%d) errCause(%d) RNTI:%d", err.errType, err.errCause,srInfo->rnti); + continue; + } + } + RETVALUE(ret); +} /* end of rgSCHTomSrInd */ + +/** + * @brief Handler for processing downlink CQI indication recieved from + * PHY for a UE. + * + * @details + * + * Function: rgSCHTomDoaInd + * + * Handler for processing DOA recieved from PHY + * for a set of UEs. + * + * Invoked by: RgLiTfuDoaInd + * + * Processing Steps: + * - Get UE + * - Invoke scheduler to indicate DOA rgSCHUtlDoaInd + * + * @param[in] TfuDoaIndInfo *doaInd + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 rgSCHTomDoaInd +( +RgSchCellCb *cell, +TfuDoaIndInfo *doaInd +) +#else +PUBLIC S16 rgSCHTomDoaInd(cell, doaInd ) +RgSchCellCb *cell; +TfuDoaIndInfo *doaInd; +#endif +{ + RgSchUeCb *ue; + CmLList *node; + TfuDoaRpt *doaInfo; + TRC2(rgSCHTomDoaInd); + + if(cell->cellId != doaInd->cellId) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,"Unable to get the cell for doaInd cellId" + ":%d", doaInd->cellId); + RETVALUE(RFAILED); + } + + + node = doaInd->doaRpt.first; + for (;node; node=node->next) + { + doaInfo = (TfuDoaRpt *)node->node; + ue = rgSCHDbmGetUeCb (cell, doaInfo->rnti); + if (ue == NULLP) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,"RNTI:%d Unable to get the UE CB", + doaInfo->rnti); + continue; + } + rgSCHUtlDoaInd(cell, ue, doaInfo); + } + RETVALUE(ROK); +} /* rgSCHTomDoaInd */ +/** + * @brief Handler for processing downlink CQI indication recieved from + * PHY for a UE. + * + * @details + * + * Function: rgSCHTomDlCqiInd + * + * Handler for processing downlink CQI indication recieved from PHY + * for a set of UEs. + * + * Invoked by: RgLiTfuDlCqiInd + * + * Processing Steps: + * - Get UE + * - Invoke scheduler to indicate DL CQI rgSCHUtlDlCqiInd + * + * @param[in] TfuDlCqiIndInfo *dlCqiInd + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 rgSCHTomDlCqiInd +( +RgSchCellCb *cell, +TfuDlCqiIndInfo *dlCqiInd +) +#else +PUBLIC S16 rgSCHTomDlCqiInd(cell, dlCqiInd) +RgSchCellCb *cell; +TfuDlCqiIndInfo *dlCqiInd; +#endif +{ + RgSchUeCb *ue; + CmLList *node; + TfuDlCqiRpt *dlCqiInfo; + TRC2(rgSCHTomDlCqiInd); + + if(cell->cellId != dlCqiInd->cellId) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,"Unable to get the cell for cellId" + ":%d", dlCqiInd->cellId); + RETVALUE(RFAILED); + } + + + node = dlCqiInd->dlCqiRptsLst.first; + for (;node; node=node->next) + { + dlCqiInfo = (TfuDlCqiRpt *)node->node; + ue = rgSCHDbmGetUeCb (cell, dlCqiInfo->rnti); + if (ue == NULLP) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,"RNTI:%dUnable to get the UE CB", + dlCqiInfo->rnti); + continue; + } + rgSCHUtlDlCqiInd(cell, ue, dlCqiInfo, dlCqiInd->timingInfo); + rgSCHUtlHdlUlTransInd(cell, ue, dlCqiInd->timingInfo); + } + RETVALUE(ROK); +} /* rgSCHTomDlCqiInd */ + +/** + * @brief Handler for moving PCQI instance for the next periodic occasion + * + * @details + * + * Function: rgSCHTomUtlMovePcqiNxtOccasion + * + * Handler for moving PCQI instance for the next periodic occasion + * + * Invoked by: rgSCHTomUtlFill* + * + * Processing Steps: + * - For a UE move its occurence instance to next occasion + * depending on its periodicity + * - Remove it from the current list and insert it to the list + * having the index matching with the derived number. + * + * @param[in] RgSchCellCb *cell, + * [in] RgSchUeCb *ue + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PRIVATE S16 rgSCHTomUtlMovePcqiNxtOccasion +( + RgSchCellCb *cell, + RgSchUeCb *ue, + RgSchUePCqiCb *cqiCb + ) +#else +PRIVATE S16 rgSCHTomUtlMovePcqiNxtOccasion(cell, ue, cqiCb) + RgSchCellCb *cell; + RgSchUeCb *ue; + RgSchUePCqiCb *cqiCb; +#endif +{ + U16 cqiIdx = 0; + + CmLteTimingInfo timingInfo; + TRC2(rgSCHTomUtlMovePcqiNxtOccasion); + + if(cqiCb->cqiCfg.cqiSetup.cqiRepType == RGR_UE_PCQI_SB_REP) + { +#ifdef xLTE_TDD + RG_SCH_ADD_TO_CRNT_TIME(cell->crntTime, timingInfo, TFU_DELTA); +#else + RG_SCH_ADD_TO_CRNT_TIME(cell->crntTime, timingInfo, + TFU_RECPREQ_DLDELTA); +#endif + RG_SCH_ADD_TO_CRNT_TIME(timingInfo,timingInfo,cqiCb->cqiPeri); + rgSCHTomUtlPcqiSbCalcBpIdx(timingInfo,ue,cqiCb); + } + /* Compute Next Transmission Instance */ + cqiIdx = cqiCb->cqiPeri + cqiCb->nCqiTrIdx; + cqiIdx = cqiIdx%RG_SCH_PCQI_SRS_SR_TRINS_SIZE; + /* Delete from current List and move to new list */ + if (NULLP == cmLListDelFrm(&cell->pCqiSrsSrLst[cqiCb->nCqiTrIdx].cqiLst, + &cqiCb->cqiLstEnt)) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,"RNTI:%d Unable to remove node", + ue->ueId); + } + cqiCb->nCqiTrIdx = cqiIdx; + cmLListAdd2Tail(&(cell->pCqiSrsSrLst[cqiCb->nCqiTrIdx].cqiLst), + &(cqiCb->cqiLstEnt)); +#ifdef LTE_ADV + rgSCHUtlSCellHndlCqiCollsn(cqiCb); +#endif + + RETVALUE(ROK); +} /* rgSCHTomUtlMovePcqiNxtOccasion */ + +/** + * @brief Handler for moving RI instance for the next periodic occasion + * + * @details + * + * Function: rgSCHTomUtlMovePriNxtOccasion + * + * Handler for moving PCQI instance for the next periodic occasion + * + * Invoked by: rgSCHTomUtlFill* + * + * Processing Steps: + * - For a UE move its occurence instance to next occasion + * depending on its periodicity + * - Remove it from the current list and insert it to the list + * having the index matching with the derived number. + * + * @param[in] RgSchCellCb *cell, + * [in] RgSchUeCb *ue + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PRIVATE S16 rgSCHTomUtlMovePriNxtOccasion +( + RgSchCellCb *cell, + RgSchUeCb *ue, + RgSchUePCqiCb *riCb + ) +#else +PRIVATE S16 rgSCHTomUtlMovePriNxtOccasion(cell, ue, riCb) + RgSchCellCb *cell; + RgSchUeCb *ue; + RgSchUePCqiCb *riCb; +#endif +{ + U16 riIdx; + U16 riDist=0; + U16 effPeriodicity; + U16 riTrInsTime; + U16 crntTime; + U16 tempIdx; + + TRC2(rgSCHTomUtlMovePriNxtOccasion); + crntTime = (cell->crntTime.sfn * RGSCH_NUM_SUB_FRAMES_5G) + +(cell->crntTime.subframe); +#ifdef XEON_SPECIFIC_CHANGES + RGSCHCPYTIMEINFO(cell->crntTime, ue->riRecpTime); +#endif + /* Compute Next Transmission Instance */ + if (riCb->cqiCfg.cqiSetup.cqiRepType == RGR_UE_PCQI_WB_REP) + { + effPeriodicity = riCb->cqiPeri * riCb->riPeri; + tempIdx = effPeriodicity + riCb->nRiTrIdx; + } + else + { + effPeriodicity = (riCb->h * riCb->cqiPeri * riCb->riPeri); + /* In case of SFN wraparound, the SB CQI reporting cycle breaks + * and RI->WB CQI->SBCQI.. should resume. RI is repositioned + * accordingly. WBCQI handling is naturally accomplished */ + if ((crntTime + TFU_RECPREQ_DLDELTA + effPeriodicity) > + (RGSCH_MAX_SUBFRM_5G - 1)) + { + riTrInsTime = (effPeriodicity - riCb->cqiOffset + riCb->riOffset) % effPeriodicity; + tempIdx = RGSCH_MAX_SUBFRM_5G + (effPeriodicity - riTrInsTime); + /* In case of SFN wraparound, riDist should be distance from crntTime + * + TFU_RECPREQ_DLDELTA to tempIdx. Updating effPeriodicity + * to make riDist calculation consistent for both SFN wraparound + * case and normal case */ + effPeriodicity = tempIdx - TFU_RECPREQ_DLDELTA - crntTime; + } + else + { + tempIdx = effPeriodicity + riCb->nRiTrIdx; + } + } + riIdx = tempIdx % RG_SCH_PCQI_SRS_SR_TRINS_SIZE; + if (effPeriodicity >= RG_SCH_PCQI_SRS_SR_TRINS_SIZE) + { + riDist = rgSCHUtlFindDist((U16)(crntTime + TFU_RECPREQ_DLDELTA), + (U16)(crntTime + TFU_RECPREQ_DLDELTA + effPeriodicity)); + } + else + { + riDist = 0; + } + + /* ccpu00138306- If Periodicity is equal to Queue Size or multiple of it + * then the next occasion idx will be same as current Idx, Hence need not + * to delete and add + */ + if((effPeriodicity%RG_SCH_PCQI_SRS_SR_TRINS_SIZE) != 0) + { + /* Delete from current List and move to new list */ + if (NULLP == cmLListDelFrm(&cell->pCqiSrsSrLst[riCb->nRiTrIdx].riLst, + &riCb->riLstEnt)) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,"[%d]UEID:Unable to remove node", + ue->ueId); + } + RG_SCH_RECORD(&riCb->histElem,RGSCH_ACTION_DEL, &cell->pCqiSrsSrLst[riCb->nRiTrIdx].riLst); + cmLListAdd2Tail(&cell->pCqiSrsSrLst[riIdx].riLst, + &riCb->riLstEnt); + RG_SCH_RECORD(&riCb->histElem,RGSCH_ACTION_ADD, &cell->pCqiSrsSrLst[riIdx].riLst); + } + else + { + if(riDist > 0) + { + riDist--; + } + } + riCb->nRiTrIdx = riIdx; + riCb->riDist = riDist; + +#ifdef LTE_ADV + rgSCHUtlSCellHndlRiCollsn(riCb); +#endif + RETVALUE(ROK); +} /* rgSCHTomUtlMovePriNxtOccasion */ + +/** + * @brief Handler for moving SR instance for the next periodic occasion + * + * @details + * + * Function: rgSCHTomUtlMoveSrNxtOccasion + * + * Handler for moving SR instance for the next periodic occasion + * + * Invoked by: rgSCHTomUtlFill* + * + * Processing Steps: + * - For a UE move its occurence instance to next occasion + * depending on its periodicity + * - Remove it from the current list and insert it to the list + * having the index matching with the derived number. + * + * @param[in] RgSchCellCb *cell, + * [in] RgSchUeCb *ue + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PRIVATE S16 rgSCHTomUtlMoveSrNxtOccasion +( + RgSchCellCb *cell, + RgSchUeCb *ue + ) +#else +PRIVATE S16 rgSCHTomUtlMoveSrNxtOccasion(cell, ue) + RgSchCellCb *cell; + RgSchUeCb *ue; +#endif +{ + U16 srIdx = 0; + + TRC2(rgSCHTomUtlMoveSrNxtOccasion); + + /* Compute Next Transmission Instance */ + srIdx = ue->srCb.peri + ue->srCb.nSrTrIdx; + srIdx = srIdx%RG_SCH_PCQI_SRS_SR_TRINS_SIZE; + /* Delete from current List and move to new list */ + if (NULLP == cmLListDelFrm(&cell->pCqiSrsSrLst[ue->srCb.nSrTrIdx].srLst, + &ue->srCb.srLstEnt)) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,"RNTI:%d Unable to remove node", + ue->ueId); + } + ue->srCb.nSrTrIdx = srIdx; + cmLListAdd2Tail(&cell->pCqiSrsSrLst[ue->srCb.nSrTrIdx].srLst, + &ue->srCb.srLstEnt); + + RETVALUE(ROK); +} /* rgSCHTomUtlMoveSrNxtOccasion */ + +/** + * @brief Handler for moving SRS instance for the next periodic occasion + * + * @details + * + * Function: rgSCHTomUtlMoveSrsNxtOccasion + * + * Handler for moving SRS instance for the next periodic occasion + * + * Invoked by: rgSCHTomUtlFill* + * + * Processing Steps: + * - For a UE move its occurence instance to next occasion + * depending on its periodicity + * - Remove it from the current list and insert it to the list + * having the index matching with the derived number. + * + * @param[in] RgSchCellCb *cell, + * [in] RgSchUeCb *ue + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PRIVATE S16 rgSCHTomUtlMoveSrsNxtOccasion +( + RgSchCellCb *cell, + RgSchUeCb *ue + ) +#else +PRIVATE S16 rgSCHTomUtlMoveSrsNxtOccasion(cell, ue) + RgSchCellCb *cell; + RgSchUeCb *ue; +#endif +{ + U16 srsIdx; + U16 srsDist; + U16 tempIdx; + U16 crntTime; + + + TRC2(rgSCHTomUtlMoveSrsNxtOccasion); + crntTime = (cell->crntTime.sfn * RGSCH_NUM_SUB_FRAMES_5G) + +(cell->crntTime.subframe); + + /* Compute Next Transmission Instance */ + tempIdx = ue->srsCb.peri + ue->srsCb.nSrsTrIdx; + srsIdx = tempIdx %RG_SCH_PCQI_SRS_SR_TRINS_SIZE; + if (ue->srsCb.peri > RG_SCH_PCQI_SRS_SR_TRINS_SIZE) + { + srsDist = rgSCHUtlFindDist((U16)(crntTime + TFU_RECPREQ_DLDELTA), + (U16)(crntTime + TFU_RECPREQ_DLDELTA + ue->srsCb.peri)); + } + else + { + srsDist =0; + } + + /* ccpu00138306- If Periodicity is equal to Queue Size or multiple of it + * then the next occasion idx will be same as current Idx, Hence need not + * to delete and add + */ + if((ue->srsCb.peri%RG_SCH_PCQI_SRS_SR_TRINS_SIZE) != 0) + { + /* Delete from current List and move to new list */ + if (NULLP == cmLListDelFrm(&cell->pCqiSrsSrLst[ue->srsCb.nSrsTrIdx].srsLst, + &ue->srsCb.srsLstEnt)) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,"RNTI:%d Unable to remove node", + ue->ueId); + } + cmLListAdd2Tail(&cell->pCqiSrsSrLst[srsIdx].srsLst, + &ue->srsCb.srsLstEnt); + } + else + { + if(srsDist > 0) + { + srsDist--; + } + } + ue->srsCb.nSrsTrIdx = srsIdx; + ue->srsCb.srsDist = srsDist; + + RETVALUE(ROK); +} /* rgSCHTomUtlMoveSrsNxtOccasion */ + + +/** + * @brief Handler for processing RAW CQI indication recieved from + * PHY for a UE. + * + * @details + * + * Function: rgSCHTomRawCqiInd + * + * Handler for processing RAW CQI indication recieved from PHY + * for a set of UEs. + * + * Invoked by: RgLiTfuRawCqiInd + * + * Processing Steps: + * - Get UE + * - Invoke scheduler to indicate Raw CQI rgSCHUtlRawCqiInd + * + * @param[in] TfuRawCqiIndInfo *rawCqiInd + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 rgSCHTomRawCqiInd +( + RgSchCellCb *cell, + TfuRawCqiIndInfo *rawCqiInd +) +#else +PUBLIC S16 rgSCHTomRawCqiInd(cell, rawCqiInd) + RgSchCellCb *cell; + TfuRawCqiIndInfo *rawCqiInd; +#endif +{ + RgSchUeCb *ue; + CmLList *node; + TfuRawCqiRpt* rawCqiInfo; + + TfuDlCqiRpt dlCqiInfo; + Bool skipPerCqiRpt = FALSE; + RgSchErrInfo err; + U32 cellIdx; + RgInfRlsHqInfo *rlsHqBufs = &(cell->rlsHqArr[cell->crntHqIdx]); + RgSchCellCb *iterCellP; +#if DL_LA + RgSchCmnDlUe *ueDl; +#endif + U8 cqi; + U8 ri; + U8 hqAck; + Pst pst; + RgSchRaCb *raCb; + TfuHqInfo hqInfo; + + TRC2(rgSCHTomRawCqiInd); + + if(cell->cellId != rawCqiInd->cellId) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,"Unable to get the cell for cellId" + ":%d", rawCqiInd->cellId); + RETVALUE(RFAILED); + } + + + node = rawCqiInd->rawCqiRpt.first; + for (;node; node=node->next) + { + rawCqiInfo = (TfuRawCqiRpt *)node->node; + ue = rgSCHDbmGetUeCb (cell, rawCqiInfo->crnti); + raCb = rgSCHDbmGetRaCb (cell, rawCqiInfo->crnti); + /* + if (ue == NULLP) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,"CRNTI:%d Unable to get the UECB", + rawCqiInfo->crnti); + continue; + } + */ +#ifdef RG_5GTF + /* + if (rawCqiInfo->numBits >= 5) + printf("cellId [%d] crnti [%d] numBits [%d] uciPayload [0x%08x] sfn/sf [%d:%d]\n", + cell->cellId, rawCqiInfo->crnti, rawCqiInfo->numBits, rawCqiInfo->uciPayload, + rawCqiInd->timingInfo.sfn, rawCqiInd->timingInfo.subframe); + */ + if (rawCqiInfo->numBits == 1) + { + RgInfRlsHqInfo *rlsHqBufs = &(cell->rlsHqArr[cell->crntHqIdx]); + U8 fdbk = TFU_HQFDB_NACK; + /* Process HARQ FdbkInd */ + hqAck = (rawCqiInfo->uciPayload >> 31) & 0x1; + if (hqAck) + { + fdbk = TFU_HQFDB_ACK; + hqInfo.isAck[0] = fdbk; + } + if (ue != NULLP && raCb == NULLP) + { + if ((rgSCHDhm5gtfHqFdbkInd (ue, cell, rawCqiInd->timingInfo, fdbk, &err)) != ROK) + { + err.errType = RGSCHERR_TOM_HARQACKIND; + RLOG_ARG2(L_ERROR,DBG_CELLID,cell->cellId,"rgSCHTomHarqAckInd() " + "HARQ feedback processing failed errType(%d)errCause(%d)n", + err.errType, err.errCause); + continue; + } + } + else if (ue == NULLP && raCb != NULLP) + { + if ((rgSCHDhmHqFdbkInd (raCb, RGSCH_HQ_FDB_IND_CB_TYPE_RA_CB, + cell, rawCqiInd->timingInfo, &hqInfo, rlsHqBufs, &err)) != ROK) + { + err.errType = RGSCHERR_TOM_HARQACKIND; + RLOG_ARG2(L_ERROR,DBG_CELLID,cell->cellId,"rgSCHTomHarqAckInd() HARQ" + " feedback processing failed errType(%d) errCause(%d)", + err.errType, err.errCause); + continue; + } + continue; + } + else if (ue != NULLP && raCb != NULLP) + { + if ((rgSCHDhmHqFdbkInd (raCb, RGSCH_HQ_FDB_IND_CB_TYPE_RA_CB, + cell, rawCqiInd->timingInfo, &hqInfo, rlsHqBufs, &err)) != ROK) + { + err.errType = RGSCHERR_TOM_HARQACKIND; + RLOG_ARG2(L_ERROR,DBG_CELLID,cell->cellId,"rgSCHTomHarqAckInd() HARQ" + " feedback processing failed errType(%d) errCause(%d).", + err.errType, err.errCause); + continue; + } + } + else + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,"RNTI:%d Unable to get the " + "UE CB or RA CB ", rawCqiInfo->crnti); + err.errType = RGSCHERR_TOM_HARQACKIND; + continue; + } + /* + printf("rawCqiInfo->numBits [%d] uciPayload [0x%08x] sfn/sf [%d:%d]\n", rawCqiInfo->numBits, + rawCqiInfo->uciPayload, rawCqiInd->timingInfo.sfn, rawCqiInd->timingInfo.subframe); + */ + } + else if (rawCqiInfo->numBits == 5) + { + /* Process CQI-RI Ind*/ + ri = (rawCqiInfo->uciPayload >> 27) & 0x1; + cqi = (rawCqiInfo->uciPayload >> 28) & 0xF; + if(ue) { + if (cqi == 0) + { + printf("\n UE[%d] CQI[%d] Invalid\n", ue->ueId, cqi); + cqi = 15; + } + ue->ue5gtfCb.mcs = rgSch5gtfCqi2Mcs[cqi - 1]; + ue->ue5gtfCb.rank = ri + 1; +#ifdef DL_LA + if (rawCqiInfo->numBits > 1) + { + ueDl = RG_SCH_CMN_GET_DL_UE(ue,cell); + ueDl->mimoInfo.cwInfo[0].cqi = cqi; + ueDl->cqiFlag = TRUE; + rgSCHCmnDlSetUeAllocLmtLa(cell, ue); + // rgSCHCheckAndSetTxScheme(cell, ue); + } +#endif + } + /* + printf("UE[%d] CQI[%d] MCS[%d] RI[%d]\n", ue->ueId, cqi, ue->ue5gtfCb.mcs, ri); + */ + } + else if (rawCqiInfo->numBits == 6) + { + RgInfRlsHqInfo *rlsHqBufs = &(cell->rlsHqArr[cell->crntHqIdx]); + TfuHqFdbk fdbk = TFU_HQFDB_NACK; + /* Process both HARQ and CQI-RI Ind*/ + ri = (rawCqiInfo->uciPayload >> 26) & 0x1; + cqi = (rawCqiInfo->uciPayload >> 27) & 0xF; + hqAck = (rawCqiInfo->uciPayload >> 31) & 0x1; + if (cqi == 0) + { + printf("UE[%d] CQI[%d] Invalid\n", ue->ueId, cqi); + cqi = 13; + } + ue->ue5gtfCb.mcs = rgSch5gtfCqi2Mcs[cqi - 1]; + ue->ue5gtfCb.rank = ri + 1; +#ifdef DL_LA + if (rawCqiInfo->numBits > 1) + { + ueDl = RG_SCH_CMN_GET_DL_UE(ue,cell); + ueDl->mimoInfo.cwInfo[0].cqi = cqi; + ueDl->cqiFlag = TRUE; + rgSCHCmnDlSetUeAllocLmtLa(cell, ue); + // rgSCHCheckAndSetTxScheme(cell, ue); + } +#endif + if (hqAck) + { + fdbk = TFU_HQFDB_ACK; + hqInfo.isAck[0] = fdbk; + } + if (ue != NULLP && raCb == NULLP) + { + if ((rgSCHDhm5gtfHqFdbkInd (ue, cell, rawCqiInd->timingInfo, fdbk, &err)) != ROK) + { + err.errType = RGSCHERR_TOM_HARQACKIND; + RLOG_ARG2(L_ERROR,DBG_CELLID,cell->cellId,"rgSCHTomHarqAckInd() " + "HARQ feedback processing failed errType(%d)errCause(%d)n", + err.errType, err.errCause); + continue; + } + } + else if (ue == NULLP && raCb != NULLP) + { + if ((rgSCHDhmHqFdbkInd (raCb, RGSCH_HQ_FDB_IND_CB_TYPE_RA_CB, + cell, rawCqiInd->timingInfo, &hqInfo, rlsHqBufs, &err)) != ROK) + { + err.errType = RGSCHERR_TOM_HARQACKIND; + RLOG_ARG2(L_ERROR,DBG_CELLID,cell->cellId,"rgSCHTomHarqAckInd() HARQ" + " feedback processing failed errType(%d) errCause(%d)", + err.errType, err.errCause); + continue; + } + continue; + } + else if (ue != NULLP && raCb != NULLP) + { + if ((rgSCHDhmHqFdbkInd (raCb, RGSCH_HQ_FDB_IND_CB_TYPE_RA_CB, + cell, rawCqiInd->timingInfo, &hqInfo, rlsHqBufs, &err)) != ROK) + { + err.errType = RGSCHERR_TOM_HARQACKIND; + RLOG_ARG2(L_ERROR,DBG_CELLID,cell->cellId,"rgSCHTomHarqAckInd() HARQ" + " feedback processing failed errType(%d) errCause(%d).", + err.errType, err.errCause); + continue; + } + } + else + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,"RNTI:%d Unable to get the " + "UE CB or RA CB ", rawCqiInfo->crnti); + err.errType = RGSCHERR_TOM_HARQACKIND; + continue; + } + + /* + printf("\nUE[%u] CQI[%u] MCS[%u] RI[%u] HQ[%u]\n", ue->ueId, cqi, ue->ue5gtfCb.mcs, ri, hqAck); + */ + } + } + + if ((rgSCHDhmRlsDlsfHqProc (cell, rawCqiInd->timingInfo)) != ROK) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,"Unable to Release Downlink " + "subframe for cellId (%d) ", cell->cellId); + err.errType = RGSCHERR_TOM_HARQACKIND; + } + + for (cellIdx = 0; cellIdx < CM_LTE_MAX_CELLS; cellIdx++) + { + if (NULLP != rgSchCb[cell->instIdx].cells[cellIdx]) + { + iterCellP = rgSchCb[cell->instIdx].cells[cellIdx]; + + rlsHqBufs = &(iterCellP->rlsHqArr[iterCellP->crntHqIdx]); + if(rlsHqBufs->numUes) + { + rgSCHUtlGetPstToLyr(&pst, &rgSchCb[cell->instIdx], iterCellP->macInst); + RgSchMacRlsHq (&pst, rlsHqBufs); + } + rlsHqBufs->numUes = 0; + } + } + RETVALUE(ROK); +} /* rgSCHTomRawCqiInd */ + +/** + * @brief Handler for processing SRS indication recieved from + * PHY for a UE. + * + * @details + * + * Function: rgSCHTomSrsInd + * + * Handler for SRS indication recieved from PHY + * for a set of UEs. + * + * Invoked by: RgLiTfuSrsInd + * + * Processing Steps: + * - Get UE + * - Invoke scheduler to indicate UL SRS rgSCHUtlSrsInd + * + * @param[in] TfuSrsIndInfo *srsInd + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 rgSCHTomSrsInd +( + RgSchCellCb *cell, + TfuSrsIndInfo *srsInd + ) +#else +PUBLIC S16 rgSCHTomSrsInd(cell, srsInd) + RgSchCellCb *cell; + TfuSrsIndInfo *srsInd; +#endif +{ + RgSchUeCb *ue; + CmLList *node; + TfuSrsRpt* srsInfo; + + TRC2(rgSCHTomSrsInd); + + if(cell->cellId != srsInd->cellId) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,"Unable to get the cell for cellId" + ":%d", srsInd->cellId); + RETVALUE(RFAILED); + } + + node = srsInd->srsRpt.first; + for (;node; node=node->next) + { + srsInfo = (TfuSrsRpt *)node->node; + ue = rgSCHDbmGetUeCb (cell, srsInfo->ueId); + if (ue == NULLP) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,"RNTI:%d Unable to get the " + "UE CB", srsInfo->ueId); + continue; + } + rgSCHUtlSrsInd(cell, ue, srsInfo, srsInd->timingInfo); + rgSCHUtlHdlUlTransInd(cell, ue, srsInd->timingInfo); + } + RETVALUE(ROK); +} /* rgSCHTomSrsInd */ + +/* +* +* Fun: rgSCHTomUtlGenIndices +* +* Desc: This function reconstructs the Subband Indices for +* of M selected Subbands conveyed by the UE for APeriodic Modes +* 2-0 and 2-2. It decodes the Label which uniquely encodes M out +* of N subbands. +* +* +* Ret: ROK +* +* Notes: None +* +* File: rg_sch_utl.c +* +*/ +#ifdef ANSI +PRIVATE S16 rgSCHTomUtlGenIndices +( + U32 label, + U8 posM, + U8 valN, + U8 valK, + TfuSubbandInfo* sbInfo + ) +#else +PRIVATE S16 rgSCHTomUtlGenIndices(label, posM, valN, valK, sbInfo) + U32 label; + U8 posM; + U8 valN; + U8 valK; + TfuSubbandInfo* sbInfo; +#endif +{ + U8 idx, kval, xval, xmin; + U32 binCoe; + xmin =1; + for(kval=0; kvallabel) + { + xval = xval+1; + RGSCH_ARRAY_BOUND_CHECK_WITH_POS_IDX(0, rgSCHTomBinCoe[posM-kval-1], (valN-xval-1)); + binCoe = rgSCHTomBinCoe[posM-kval-1][valN-xval-1]; + } + idx = xval; + sbInfo[kval].numRb = valK; + sbInfo[kval].rbStart = idx*valK; + xmin = idx+1; + label = label-binCoe; + } + RETVALUE(ROK); +} /* end of rgSCHTomUtlGenIndices*/ +#endif +/** + * @brief Handler for processing decode failure indication recieved from + * PHY for a UE. + * + * @details + * + * Function: rgSCHTomCrcInd + * + * Handler for processing decode failure indication recieved from + * PHY for a set of UEs. + * + * Invoked by: RgLiTfuCrcInd of rg_sch.x + * + * Processing Steps: + * - Validate the information received and retrieve cell and ue. + * - Process Decode failure Indication: Call rgSCHUhmProcHqFailure(). + * + * @param[in] TfuCrcIndInfo *crcInd + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 rgSCHTomCrcInd +( +RgSchCellCb *cell, +TfuCrcIndInfo *crcInd +) +#else +PUBLIC S16 rgSCHTomCrcInd(cell, crcInd) +RgSchCellCb *cell; +TfuCrcIndInfo *crcInd; +#endif +{ + RgSchUeCb *ue = NULLP; + RgSchRaCb *raCb = NULLP; + CmLList *node; + TfuCrcInfo *crcInfo; +#ifdef RG_ULSCHED_AT_CRC + RgSchErrInfo err; + RgSchDlSf *ulSf; + CmLteTimingInfo crntHiDci0Frm; + //RgSchCmnUlCell *cellUl; + Inst inst = cell->instIdx; + TfuCntrlReqInfo *cntrlInfo; + U32 ret; +#ifdef LTE_TDD + U8 Mval; + U8 idx; +#endif +#endif +#ifdef LTE_TDD + RgSchUlHqProcCb *hqProc; +#endif + +#ifdef LTE_L2_MEAS + RgSchUlHqProcCb *ulHqProc; +#endif + + TRC2(rgSCHTomCrcInd); + + if(cell->cellId != crcInd->cellId) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,"Unable to get the cell for cellId" + ":%d", crcInd->cellId); + RETVALUE(RFAILED); + } +#ifdef RG_ULSCHED_AT_CRC +#ifndef LTE_ADV + { + static CmLteTimingInfo lastCrc = {2000,0}; + CmLteTimingInfo crntCrc = cell->crntTime; + if (RGSCH_TIMEINFO_SAME(lastCrc, crntCrc)) + { + /*Removed the WA to drop 2nd CRC*/ + RLOG_ARG2(L_ERROR,DBG_CELLID,cell->cellId,"Recieved CRC " + "twice per TTI @(%u,%u)", cell->crntTime.sfn, + cell->crntTime.subframe); + } + lastCrc = crntCrc; + } +#endif +#endif + node = crcInd->crcLst.first; + for (;node; node=node->next) + { + crcInfo = (TfuCrcInfo*)node->node; + ue = rgSCHDbmGetUeCb (cell, crcInfo->rnti); + if (ue == NULLP) + { +#ifdef LTEMAC_SPS + /* Fetch from SPS List */ + ue = rgSCHDbmGetSpsUeCb(cell, crcInfo->rnti); + if (ue == NULLP) +#endif + { + raCb = rgSCHDbmGetRaCb (cell, crcInfo->rnti); + if (raCb == NULLP) + { + continue; + } + } + } + /* Added Ul TB count for Uplink data scheduled*/ +#ifdef LTE_L2_MEAS + if(raCb) + { + ulHqProc = &(raCb->msg3HqProc); + if(ulHqProc->remTx == (cell->rachCfg.maxMsg3Tx -1)) + { + cell->dlUlTbCnt.tbTransUlTotalCnt++; + } + } + else + { + rgSCHUtlUlHqProcForUe(cell, crcInd->timingInfo, ue, &ulHqProc); + if(ulHqProc->remTx == ((RgUeUlHqCb*)ulHqProc->hqEnt)->maxHqRetx) + { + cell->dlUlTbCnt.tbTransUlTotalCnt++; + } + } +#endif + + if (crcInfo->isFailure == FALSE) + { + if(raCb) + { + rgSCHRamMsg3DatInd(raCb); +#ifdef LTE_TDD + /*ccpu00128820 - MOD - Msg3 alloc double delete issue*/ + hqProc = &(raCb->msg3HqProc); + RGSCH_UPD_PHICH(cell->ulDlCfgIdx, crcInd->timingInfo.subframe, + hqProc); +#endif + raCb = NULLP; + } + else + { +#ifdef EMTC_ENABLE + gUlCrcPassCounter++; +#endif +#ifdef CA_DBG + gUlCrcPassCount++; +#endif + RGSCHCPYTIMEINFO(crcInd->timingInfo, ue->datIndTime); +#ifndef MAC_SCH_STATS + rgSCHUhmProcDatInd(cell, ue, crcInd->timingInfo); + +#else + /** Stats update over here + */ + { + RgSchCmnUe *cmnUe = RG_SCH_CMN_GET_UE(ue,cell); + + rgSCHUhmProcDatInd(cell, ue, crcInd->timingInfo, cmnUe->ul.crntUlCqi[0]); + } +#endif /* MAC_SCH_STATS */ + + rgSCHUtlHdlUlTransInd(cell, ue, crcInd->timingInfo); +#ifdef LTEMAC_SPS + rgSCHUtlHdlCrcInd(cell, ue, crcInd->timingInfo); +#endif + } + } + else + { + if(raCb) + { + /* SR_RACH_STATS : MSG3 Nack / DTX*/ + if (crcInfo->isDtx == TRUE) + { + rgNumMsg3DtxRcvd++; + } + else + { + rgNumMsg3CrcFailed++; + } + rgSCHRamMsg3FailureInd(raCb); +#ifdef EMTC_ENABLE + rgSCHCmnEmtcHdlCrcFailInd(cell, raCb); +#endif + /* Added Ul TB count for CRC Failure of MSG3 */ +#ifdef LTE_L2_MEAS + ulHqProc = &(raCb->msg3HqProc); + if(ulHqProc->remTx == (cell->rachCfg.maxMsg3Tx -1)) + { + cell->dlUlTbCnt.tbTransUlFaulty++; + } +#endif + raCb = NULLP; + } + else + { +#ifdef EMTC_ENABLE + gUlCrcFailCounter++; +#endif +#ifdef CA_DBG + gUlCrcFailCount++; +#endif +#ifndef MAC_SCH_STATS + rgSCHUhmProcHqFailure (cell, ue, crcInd->timingInfo, crcInfo->rv); +#else + { + RgSchCmnUe *cmnUe = RG_SCH_CMN_GET_UE(ue,cell); + + rgSCHUhmProcHqFailure (cell, ue, crcInd->timingInfo, crcInfo->rv, cmnUe->ul.crntUlCqi[0]); + } +#endif /* MAC_SCH_STATS */ + rgSCHUtlHdlUlTransInd(cell, ue, crcInd->timingInfo); +#ifdef LTEMAC_SPS + rgSCHUtlHdlCrcFailInd(cell, ue, crcInd->timingInfo); +#endif + /* Added Ul TB count for CRC Failure of Uplink data */ +#ifdef LTE_L2_MEAS + rgSCHUtlUlHqProcForUe(cell, crcInd->timingInfo, ue, &ulHqProc); + if(ulHqProc->remTx == ((RgUeUlHqCb*)ulHqProc->hqEnt)->maxHqRetx) + { + cell->dlUlTbCnt.tbTransUlFaulty++; + } +#endif + } + } + } + +/* ccpu00132653-ADD Added Sched_At_Crc Changes for TDD and optimized here + the codebase across TDD and FDD*/ +#ifdef RG_ULSCHED_AT_CRC + /* Changes to do uplink scheduling at CRC Indication */ + //cellUl = RG_SCH_CMN_GET_UL_CELL(cell); + RG_SCH_ADD_TO_CRNT_TIME(cell->crntTime, crntHiDci0Frm, TFU_ULCNTRL_DLDELTA); + + + rgSCHCmnRlsUlSf(cell,0); + + + /* Allocating memory for CntrlReq as it required for both EMTC and + * Normal UEs */ + if ((ret = rgSCHUtlAllocEventMem(inst, (Ptr *)&cntrlInfo, + sizeof(TfuCntrlReqInfo))) != ROK) + { + RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,"Unable to Allocate TfuCntrlReqInfo " + "for cell"); + RETVALUE(ret); + } + rgSCHCmnUlSch(cell); +#ifdef LTE_L2_MEAS + rgSCHL2Meas(cell,TRUE); +#endif + /* Also, sending UL DCI and PHICH for just scheduled subframe */ + ulSf = rgSCHUtlSubFrmGet (cell, crntHiDci0Frm); + + if ((rgSCHTomUtlProcDlSfAtCrc (ulSf, crntHiDci0Frm, cell, cntrlInfo, &err)) != ROK) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,"rgSCHTomCrcInd() Unable to process" + " downlink subframe for cellId %d", crcInd->cellId); + err.errType = RGSCHERR_TOM_TTIIND; + RETVALUE(RFAILED); + } +#endif /* RG_ULSCHED_AT_CRC */ + RETVALUE(ROK); +} /* rgSCHTomCrcInd */ + +/** + * @brief Handler for processing timing Advance indication recieved from + * PHY for a UE. + * + * @details + * + * Function: rgSCHTomTimingAdvInd + * + * Handler for processing timing advance indication recieved from PHY + * for a set of UEs. + * + * Invoked by: RgLiTfuTimingAdvInd + * + * Processing Steps: + * - Get UE. + * - Call DHM to update value of Timing Advance rgSCHDhmUpdTa. + * + * @param[in] TfuTimingAdvIndInfo *timingAdvInd + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 rgSCHTomTimingAdvInd +( +RgSchCellCb *cell, +TfuTimingAdvIndInfo *timingAdvInd + ) +#else +PUBLIC S16 rgSCHTomTimingAdvInd(cell, timingAdvInd) +RgSchCellCb *cell; +TfuTimingAdvIndInfo *timingAdvInd; +#endif +{ + RgSchUeCb *ue; + CmLList *node; + TfuTimingAdvInfo *timingAdvInfo; + + + TRC2(rgSCHTomTimingAdvInd); + + if(cell->cellId != timingAdvInd->cellId) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,"Unable to get the cell for cellId" + "=(%d)", timingAdvInd->cellId); + RETVALUE(RFAILED); + } + + + node = timingAdvInd->timingAdvLst.first; + for (;node; node=node->next) + { + timingAdvInfo = (TfuTimingAdvInfo *)node->node; + ue = rgSCHDbmGetUeCb (cell, timingAdvInfo->rnti); + if (ue == NULLP) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,"RNTI:%d Unable to get the UE CB", + timingAdvInfo->rnti); + continue; + } + rgSCHDhmUpdTa (cell, ue, timingAdvInfo->timingAdv); + } + RETVALUE(ROK); +} /* rgSCHTomTimingAdvInd */ + +/** + * @brief Handler for processing TTI indication recieved from + * PHY for 'n' cells. + * + * @details + * + * Function: rgSCHTomTtiInd + * + * Handler for processing TTI indication recieved from PHY + * for a cell. This is split into the below Steps. + * + * 1: Complete the Uplink and Common Channel Scheduling for each Cell + * 2: Complete the UE specific Scheduling for each Cell / across Cells. + * 3: Consolidate the subframe allocations and send to each MAC instance + * 4: Fill the Tfu structures for DL and UL Config requests + * 5: Handle the RGR Config messages per Cell + * + * @param[in] TfuTtiIndInfo *ttiInd + * @param[in] Inst schInst + * @return Void + **/ +#ifdef ANSI +PUBLIC Void rgSCHTomTtiInd +( +TfuTtiIndInfo *ttiInd, +Inst schInst +) +#else +PUBLIC Void rgSCHTomTtiInd(ttiInd, schInst) +TfuTtiIndInfo *ttiInd; +Inst schInst; +#endif +{ + RgInfSfAlloc *subfrmAlloc; + RgTfuCntrlReqInfo *cntrlInfo = NULLP; + S16 ret = ROK; + U8 i; + U8 nCell = 0; + RgSchCellCb *cell[CM_LTE_MAX_CELLS]; + RgSchCellCb *cellLst[CM_LTE_MAX_CELLS]; + + TRC2(rgSCHTomTtiInd); + +#ifdef LTE_L2_MEAS + glblTtiCnt++; +#endif + + rgSchTomFillCellTtiInfo(ttiInd, schInst, &nCell, &cell[0]); + for (i = 0; i < nCell; i++) + { + /* Perform UL and DL Common Channel scheduling */ + rgSchTomTtiUlAndDlCmnChSch (cell[i]); + } + + /* Perform scheduling in Order of + * 1. SPS + * 2. CEs + * 3. Retx */ + for (i = 0; i < nCell; i++) + { + + if (cell[i]->isDlDataAllwd && (cell[i]->stopDlSch == FALSE)) + { + RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell[i]); + /* Perform DL Retx scheduling */ + cellSch->apisDl->rgSCHDlRetxSched(cell[i], &cellSch->allocInfo); + } + } + + rgSchCmnPreDlSch(cell, nCell, cellLst); + for (i = 0; i < nCell; i++) + { + /* Perform DL scheduling */ + rgSchTomTtiDlSch (cellLst[i]); + } + rgSchCmnPstDlSch(cell[0]); + + for (i = 0; i < nCell; i++) + { +#ifdef LTE_TDD +#ifndef RG_ULSCHED_AT_CRC + /* Perform UL scheduling for TDD */ + rgSCHCmnUlSch (cell[i]); +#endif +#endif + } + /* Init SF Alloc info per Cell */ + for (i = 0; i < nCell; i++) + { + subfrmAlloc = &(cell[i]->sfAllocArr[cell[i]->crntSfIdx]); + rgSCHUtlResetSfAlloc(subfrmAlloc,FALSE,TRUE); + } + for (i = 0; i < nCell; i++) + { + if (cell[i]->isDlDataAllwd && (cell[i]->stopSiSch == FALSE)) + { + subfrmAlloc = &(cell[i]->sfAllocArr[cell[i]->crntSfIdx]); + /* + * TFU_DLDATA_DLDELTA is used in this calculation because the subfrmAlloc + * timingInfo which is being calculated here will be used by MAC + */ + RG_SCH_ADD_TO_CRNT_TIME(cell[i]->crntTime, subfrmAlloc->timingInfo, + RG_DL_DELTA - TFU_DLDATA_DLDELTA); + /* Consolidate the Allocations and send response to MAC instances */ + rgSchTomTtiCnsldtSfAlloc (cell[i]); + } + } + + for (i = 0; i < nCell; i++) + { + if (cell[i]->isDlDataAllwd && (cell[i]->stopSiSch == FALSE)) + { + /* Send the consolidated Alloc Info to MAC instances */ + rgSCHCmnSndCnsldtInfo (cell[i]); + } + } + + for (i = 0; i < nCell; i++) + { + /* Fill control data from scheduler to PHY */ + if ((ret = rgSCHUtlAllocEventMem((cell[i]->instIdx), (Ptr *)&cntrlInfo, + sizeof(RgTfuCntrlReqInfo))) != ROK) + { + RLOG_ARG0(L_ERROR,DBG_CELLID,cell[i]->cellId,"Unable to Allocate TfuCntrlReqInfo" + " for cell"); + RETVOID; + } + +#ifdef EMTC_ENABLE + /* Fill the TFU structures and send to CL */ + if(TRUE == cell[i]->emtcEnable) + { + ret = rgSchEmtcTomTtiL1DlAndUlCfg (cell[i], cntrlInfo); + } +#endif + if((ROK == ret) + && (NULLP != cntrlInfo)) + { + /* Fill the TFU structures and send to CL */ + rgSchTomTtiL1DlAndUlCfg (cell[i], cntrlInfo); + } + } +#ifdef RGR_RRM_TICK + rgSCHTomUtlSendSfnTick(cell[0]); +#endif + + for (i = 0; i < nCell; i++) + { + /* Invoke non critical functions like measurements, etc */ + rgSchTomTtiMiscFunctions (cell[i]); + } + +#ifdef CA_DBG + { + U32 dbgUeIdChngAndDatReqInClCnt = 0; + static U32 gTtiCount = 0; + gTtiCount++; + + if(gTtiCount == 3000) + { +#ifdef XEON_SPECIFIC_CHANGES + printf("SChed:: (P/S)::(%u/%u) \n", + gPrimarySchedCount,gSCellSchedCount); + + printf("\n HQFDBK :: %u\n",gHqFdbkCount); + + long int total; + long int total2 ; + + total = gPCellTb1AckCount + gPCellTb1NackCount + gPCellTb1DtxCount; + total2 = gPCellTb2AckCount + gPCellTb2NackCount + gPCellTb2DtxCount; + + printf("\n PCell:: TB1:: (A/N/D)::(%u/%u/%u) TB2:: (A/N/D)::(%u/%u/%u)\n", + gPCellTb1AckCount,gPCellTb1NackCount,gPCellTb1DtxCount, + gPCellTb2AckCount,gPCellTb2NackCount,gPCellTb2DtxCount); + if ((total != 0 ) && total2 != 0) + { + printf("\n PCell:: TB1:: (AP/NP/DP)::(%.2f/%.2f/%.2f) TB2:: (AP/NP/DP)::(%.2f/%.2f/%.2f)\n", + (float)gPCellTb1AckCount/total * 100,(float)gPCellTb1NackCount/total * 100,(float)gPCellTb1DtxCount/total * 100, + (float)gPCellTb2AckCount/total2 *100 ,(float)gPCellTb2NackCount/total2 *100 ,(float)gPCellTb2DtxCount/total2 *2); + } + + total = gSCellTb1AckCount + gSCellTb1NackCount + gSCellTb1DtxCount; + total2 = gSCellTb2AckCount + gSCellTb2NackCount + gSCellTb2DtxCount; + + + printf("\n SCell:: TB1:: (A/N/D)::(%u/%u/%u) TB2:: (A/N/D)::(%u/%u/%u)\n", + gSCellTb1AckCount,gSCellTb1NackCount,gSCellTb1DtxCount, + gSCellTb2AckCount,gSCellTb2NackCount,gSCellTb2DtxCount); + if ((total != 0 ) && total2 != 0) + { + printf("\n SCell:: TB1:: (AP/NP/DP)::(%.2f/%.2f/%.2f) TB2:: (AP/NP/DP)::(%.2f/%.2f/%.2f)\n", + (float)gSCellTb1AckCount/total * 100,(float)gSCellTb1NackCount/total * 100,(float)gSCellTb1DtxCount/total * 100, + (float)gSCellTb2AckCount/total2 *100 ,(float)gSCellTb2NackCount/total2 *100 ,(float)gSCellTb2DtxCount/total2 *2); + } + + + printf("\n CQI:: Recp(Pucch/Pusch):Rcvd(pcqi/rawacqireport/apcqi/AppReprt)::(%u/%u):(%u/%u/%u/%u)\n", + gCqiRecpCount,gCqiRecpPuschCount,gCqiRcvdCount,gRawACqiCount, + gACqiRcvdCount,gCqiReptToAppCount); + + printf("\n (F1BCS Count/Cqi/Ri/CqiDrop/PucchDrop/PuschCqiDrop)::(%u/%u/%u/%u/%u/%u)\n", + gF1bCsCount,gCqiReqCount,gRiReqCount,gCqiDropCount,gPucchDropCount,gPuschCqiDropCount); + + printf("UL::(DCI0/CrcPass/CrcFail)::(%u/%u/%u)\n" + "gPcellZeroBoOcc:%u\t gScellZeroBoOcc:%u dbgUeIdChngAndDatReqInClCnt: %u\n" + "DelayedDatReqInMac: %u DelayedDatReqInCl : %u gIccPktRcvrMemDropCnt :%u\n", + gDci0Count, + gUlCrcPassCount, + gUlCrcFailCount, + gPcellZeroBoOcc, + gScellZeroBoOcc, + dbgUeIdChngAndDatReqInClCnt, + dbgDelayedDatReqInMac, + gDropDatReqCnt, gIccPktRcvrMemDropCnt); +#else + printf("SChed:: (P/S)::(%ld/%ld) \n", + gPrimarySchedCount,gSCellSchedCount); + + printf("\n HQFDBK :: %ld\n",gHqFdbkCount); + + printf("\n PCell:: TB1:: (A/N/D)::(%ld/%ld/%ld) TB2:: (A/N/D)::(%ld/%ld/%ld)\n", + gPCellTb1AckCount,gPCellTb1NackCount,gPCellTb1DtxCount, + gPCellTb2AckCount,gPCellTb2NackCount,gPCellTb2DtxCount); + + printf("\n SCell:: TB1:: (A/N/D)::(%ld/%ld/%ld) TB2:: (A/N/D)::(%ld/%ld/%ld)\n", + gSCellTb1AckCount,gSCellTb1NackCount,gSCellTb1DtxCount, + gSCellTb2AckCount,gSCellTb2NackCount,gSCellTb2DtxCount); + + printf("\n CQI:: Recp(Pucch/Pusch):Rcvd(pcqi/rawacqireport/apcqi/AppReprt)::(%ld/%ld):(%ld/%ld/%ld/%ld)\n", + gCqiRecpCount,gCqiRecpPuschCount,gCqiRcvdCount,gRawACqiCount, + gACqiRcvdCount,gCqiReptToAppCount); + printf("\n CQI:: PucchCqiSnrDropCnt/PucchCqiConfBitMaskDropCnt/PuschCqiConfMaskDropCount :: (%ld/%ld/%ld) \n",gCqiPucchLowSnrDropCount,gCqiPucchConfMaskDropCount,gCqiPuschConfMaskDropCount); + + printf("\n (F1BCS Count/Cqi/Ri/CqiDrop/PucchDrop/PuschCqiDrop)::(%ld/%ld/%ld/%ld/%ld/%ld)\n", + gF1bCsCount,gCqiReqCount,gRiReqCount,gCqiDropCount,gPucchDropCount,gPuschCqiDropCount); + + printf("UL::(DCI0/CrcPass/CrcFail)::(%ld/%ld/%ld)\n" + "gPcellZeroBoOcc:%ld\t gScellZeroBoOcc:%ld dbgUeIdChngAndDatReqInClCnt: %ld\n" + "DelayedDatReqInMac: %ld DelayedDatReqInCl : %ld gIccPktRcvrMemDropCnt :%ld\n", + gDci0Count, + gUlCrcPassCount, + gUlCrcFailCount, + gPcellZeroBoOcc, + gScellZeroBoOcc, + dbgUeIdChngAndDatReqInClCnt, + dbgDelayedDatReqInMac, + gDropDatReqCnt, gIccPktRcvrMemDropCnt); + //printf ("\n delayedApiCnt:%ld",delayedApiCnt); +#endif + + /*LAA STATS*/ + rgSCHLaaPrintStats(); + + gCaDbgNonCaFrmt = gIccPktRcvrMemDropCnt = 0; + + gCaDbgCaFrmt = 0; + + gF1bCsCount = 0; + gCqiReqCount = 0; + gACqiRcvdCount = 0; + gRawACqiCount= 0; + gRiReqCount = 0; + gCqiDropCount = 0; + gPucchDropCount= 0; + + gCqiPucchLowSnrDropCount = 0; + gCqiPucchConfMaskDropCount = 0; + gCqiPuschConfMaskDropCount = 0; + gPuschCqiDropCount = 0; + + gDci0Count = 0; + gUlCrcPassCount = 0; + gUlCrcFailCount = 0; + + gCqiRecpCount = 0; + gCqiRecpPuschCount = 0; + gCqiRcvdCount = 0; + + gCqiReptToAppCount = 0; + + gTtiCount = 0; + + gHqFdbkCount = 0; + gPrimarySchedCount = 0; + gSCellSchedCount = 0; + gSCellTb1AckCount = 0; + gSCellTb2AckCount = 0; + gSCellTb2AckCount = 0; + gSCellTb2NackCount = 0; + gPCellTb1AckCount = 0; + gPCellTb1NackCount = 0; + gPCellTb2AckCount = 0; + gPCellTb2NackCount = 0; + gSCellTb1NackCount=0; + + gPCellTb1DtxCount = 0; + gPCellTb2DtxCount = 0; + gSCellTb1DtxCount = 0; + gSCellTb2DtxCount = 0; + gPcellZeroBoOcc = 0; + gScellZeroBoOcc = 0; + + } + + } + +#endif + RETVOID; +} /* rgSCHTomTtiInd */ + +/** @brief This function does the TTI processin for the uplink subframe, + * already populated by the scheduler. + * + * @details + * + * Function: rgSCHTomUtlProcUlSf + * + * Processing steps: + * - Loop through the Uplink allocations present in the uplink subframe. + * - For each allocation Fill a data reception request to be sent to PHY + * - Also fills the harq reception requests for the expected HQ feedbacks. + * + * + * @param [in] RgSchCellCb *cell + * @param [out] RgSchErrInfo *err + * @return S16 + * -# ROK + * -# RFAILED + */ + +#ifdef ANSI +PRIVATE S16 rgSCHTomUtlProcUlSf +( +RgSchCellCb *cell, +RgSchErrInfo *err +) +#else +PRIVATE S16 rgSCHTomUtlProcUlSf (cell, err) +RgSchCellCb *cell; +RgSchErrInfo *err; +#endif +{ + S16 ret; + TfuRecpReqInfo *recpReqInfo; +#ifdef TFU_UPGRADE + U16 validIdx; /* Index computed from recreq's timing info*/ +#endif + Inst inst = cell->instIdx; + + TRC2(rgSCHTomUtlProcUlSf) + + if ((ret = rgSCHUtlAllocEventMem(inst, (Ptr *)&recpReqInfo, + sizeof(TfuRecpReqInfo))) != ROK) + { + RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,"Unable to Allocate TfuRecpReqInfo " + "for cell"); + err->errCause = RGSCHERR_TOM_MEM_EXHAUST; + RETVALUE(ret); + } + recpReqInfo->cellId = cell->cellId; + cmLListInit(&recpReqInfo->ueRecpReqLst); + + RG_SCH_ADD_TO_CRNT_TIME(cell->crntTime, recpReqInfo->timingInfo, + TFU_RECPREQ_DLDELTA); + + /* Filling data Reception requests */ + ret = rgSCHTomUtlFillDatRecpReq(recpReqInfo, cell, + validIdx, + err); + if (ret != ROK) + { + RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,"Unable to fill Data recption " + "requests for cell"); + RGSCH_FREE_MEM(recpReqInfo); + RETVALUE(ret); + } + /* Filling HARQ Reception requests */ + ret = rgSCHTomUtlFillHqFdbkRecpReq (recpReqInfo, cell, validIdx,err); + if (ret != ROK) + { + RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,"Unable to fill Harq Feedback " + "reception requests for cell"); + RGSCH_FREE_MEM(recpReqInfo); + RETVALUE(ret); + } + /* sending the RecpReq to Phy */ + if (rgSCHUtlTfuRecpReq(inst, cell->tfuSap->sapCfg.suId, recpReqInfo) != ROK) + { + RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,"Unable to send Cntrl info for cell"); + } + RETVALUE(ROK); +} /* end of rgSCHTomUtlProcUlSf */ + +#ifdef LTE_TDD +#ifdef TFU_UPGRADE +/** @brief This function does the TTI processin for the uplink subframe, + * already populated by the scheduler. + * + * @details + * + * Function: rgSCHTomUtlPrcUlTddSpclSf + * + * Processing steps: + * - Fill the SRS Info for the Special Subframe in Reception Req. + * - Send the Reception Req to TFU + * + * + * @param [in] RgSchCellCb *cell + * @param [out] RgSchErrInfo *err + * @return S16 + * -# ROK + * -# RFAILED + */ +#ifdef ANSI +PRIVATE S16 rgSCHTomUtlPrcUlTddSpclSf +( +RgSchCellCb *cell, +RgSchErrInfo *err +) +#else +PRIVATE S16 rgSCHTomUtlPrcUlTddSpclSf (cell, err) +RgSchCellCb *cell; +RgSchErrInfo *err; +#endif +{ + S16 ret; + TfuRecpReqInfo *recpReqInfo; + U16 validIdx; /* Index computed from recreq's timing info*/ + Inst inst = cell->instIdx; + + TRC2(rgSCHTomUtlPrcUlTddSpclSf) + + if ((ret = rgSCHUtlAllocEventMem(inst, (Ptr *)&recpReqInfo, + sizeof(TfuRecpReqInfo))) != ROK) + { + RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,"rgSCHTomUtlPrcUlTddSpclSf() Unable to " + "Allocate TfuRecpReqInfo for cell"); + err->errCause = RGSCHERR_TOM_MEM_EXHAUST; + RETVALUE(ret); + } + recpReqInfo->cellId = cell->cellId; + cmLListInit(&recpReqInfo->ueRecpReqLst); + + RG_SCH_ADD_TO_CRNT_TIME(cell->crntTime, recpReqInfo->timingInfo, TFU_RECPREQ_DLDELTA); + + RG_SCH_GET_IDX_PCQISRSSR(recpReqInfo->timingInfo, validIdx); + + /*ccpu00130768 */ + if(cell->srsCfg.isSrsCfgPres && + rgSchTddCellSpSrsSubfrmTbl[cell->srsCfg.srsSubFrameCfg][recpReqInfo->timingInfo.subframe]) + { + recpReqInfo->srsPres = TRUE; + } + else + { + recpReqInfo->srsPres = FALSE; + } + + /* Filling SRS Reception requests */ + ret = rgSCHTomUtlFillSrsRecpReq (recpReqInfo, cell, validIdx, err); + if (ret != ROK) + { + RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,"rgSCHTomUtlPrcUlTddSpclSf() Unable to fill" + " SRS recption requests for cell");; + RGSCH_FREE_MEM(recpReqInfo); + RETVALUE(ret); + } + /* sending the RecpReq to Phy */ + if (rgSCHUtlTfuRecpReq(inst, cell->tfuSap->sapCfg.suId, recpReqInfo) != ROK) + { + RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,"rgSCHTomUtlPrcUlTddSpclSf() Unable to send " + "Cntrl info for cell"); + } + RETVALUE(ROK); +} /* end of rgSCHTomUtlPrcUlTddSpclSf */ +#endif +#endif +/** @brief This function does all the processing related to a single downlink + * subframe. + * + * @details + * + * Function: rgSCHTomUtlProcDlSf + * + * Processing steps: + * - collate control data for all UEs and send to PHY + * - collate data buffers for all UEs and send to PHY + * + * @param [in] RgSchDlSf *dlSf + * @param [in] RgSchDlSf *ulSf + * @param [in] RgSchCellCb *cell + * @param [out] RgSchErrInfo *err + * @return S16 + */ +#ifdef ANSI +PRIVATE S16 rgSCHTomUtlProcDlSf +( +RgSchDlSf *dlSf, +RgSchDlSf *ulSf, +RgSchCellCb *cell, +RgTfuCntrlReqInfo *cntrlInfo, +RgSchErrInfo *err +) +#else +PRIVATE S16 rgSCHTomUtlProcDlSf (dlSf, ulSf, cell, cntrlInfo, err) +RgSchDlSf *dlSf; +RgSchDlSf *ulSf; +RgSchCellCb *cell; +RgTfuCntrlReqInfo *cntrlInfo; +RgSchErrInfo *err; +#endif +{ + Inst inst = cell->instIdx; + S16 ret; + U8 sfTyp = 1; /* Dl Subframe */ + + TRC2(rgSCHTomUtlProcDlSf); + + cmLListInit(&cntrlInfo->phichLst); + cmLListInit(&cntrlInfo->dlPdcchLst); + cmLListInit(&cntrlInfo->ulPdcchLst); + +#ifdef TFU_ALLOC_EVENT_NO_INIT + cntrlInfo->ulTiming.sfn = cntrlInfo->ulTiming.subframe = 0; +#endif + cntrlInfo->dlTiming = cell->dlDciTime; + cntrlInfo->cellId = cell->cellId; + cntrlInfo->ulTiming = cell->hiDci0Time; + if((0 == (cntrlInfo->dlTiming.sfn % 30)) && (0 == cntrlInfo->dlTiming.subframe)) + { + //printf("5GTF_CHECK rgSCHTomUtlProcDlSf Cntrl dl (%d : %d) ul (%d : %d)\n", cntrlInfo->dlTiming.sfn, cntrlInfo->dlTiming.subframe, cntrlInfo->ulTiming.sfn, cntrlInfo->ulTiming.subframe); + } + /* Fill PCFICH info */ + /* Fix for DCFI FLE issue: when DL delta is 1 and UL delta is 0 and CFI + *change happens in that SF then UL PDCCH allocation happens with old CFI + *but CFI in control Req goes updated one since it was stored in the CELL + */ + cntrlInfo->cfi = dlSf->pdcchInfo.currCfi; +#ifndef RG_ULSCHED_AT_CRC + U8 Mval = 1; +#ifdef LTE_TDD + Mval = rgSchTddPhichMValTbl[cell->ulDlCfgIdx] + [cell->hiDci0Time.subframe]; + if(dlSf->sfType == RG_SCH_SPL_SF_DATA) + { + RGSCH_GET_SPS_SF_CFI(cell->bwCfg.dlTotalBw, cntrlInfo->cfi); + } +#endif + if(Mval) + { + /* Fill PHICH info */ + if ((ret = rgSCHTomUtlFillPhich (cell, cntrlInfo, ulSf, err)) != ROK) + { + RGSCHDBGERRNEW(inst,(rgSchPBuf(inst),"Unable to send PHICH info " + "for cellId (%d)\n", cell->cellId)); + RGSCH_FREE_MEM(cntrlInfo); + RETVALUE(ret); + } + if ((ret = rgSCHTomUtlFillUlPdcch (cell, cntrlInfo, ulSf, err)) != + ROK) + { + RGSCHDBGERRNEW(inst,(rgSchPBuf(inst),"Unable to send PDCCH info " + "for cellId (%d)\n", cell->cellId)); + RGSCH_FREE_MEM(cntrlInfo); + RETVALUE(ret); + } + } +#ifdef EMTC_ENABLE + if(0 == cntrlInfo->ulMpdcchLst.count) + { + gUlMpdcchBlank++; + } +#endif +#endif +#ifdef LTE_TDD + sfTyp = rgSchTddUlDlSubfrmTbl[cell->ulDlCfgIdx] + [cell->dlDciTime.subframe]; +#endif + if (sfTyp != 2) /* Uplink subframe */ + { + /* Fill PDCCH info */ + if ((ret = rgSCHTomUtlFillDlPdcch(cell,cntrlInfo, dlSf, err)) != ROK) + { + RGSCHDBGERRNEW(inst,(rgSchPBuf(inst),"Unable to send PDCCH info " + "for cellId (%d)\n", cell->cellId)); + RGSCH_FREE_MEM(cntrlInfo); + RETVALUE(ret); + } + rgBwAlloInfo[dlSf->sfNum] += dlSf->bwAssigned; + rgBwAlcnt[dlSf->sfNum] ++; + + } +#ifdef LTEMAC_SPS /* SPS_NEW_CHGS */ + cntrlInfo->isSPSOcc = dlSf->isSPSOcc; +#endif + cntrlInfo->numDlActvUes += dlSf->numDlActvUes; /* 4UE_TTI_DELTA */ + dlSf->numDlActvUes = 0; +#ifdef EMTC_ENABLE +if(0 == cntrlInfo->dlMpdcchLst.count) +{ + gDlMpdcchBlank++; +} +#endif + /* Now always sending down a cntrl req */ + /* sending the cntrl data to Phy */ + if (rgSCHUtlTfuCntrlReq(inst, cell->tfuSap->sapCfg.suId, cntrlInfo) + != ROK) + { + RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,"Unable to send Cntrl info " + "for cell"); + } + + RETVALUE(ROK); +} + + +/** @brief This function handles sending of the PHICH information for the + * downlink subframe to be sent in the next TTI. + * + * @details + * + * Function: + * + * Processing steps: + * - Loop through the PHICH information present in the downlink + * subframe and fill the information in cntrlInfo. + * + * @param [out] TfuCntrlReqInfo *cntrlInfo + * @param [in] RgSchDlSf *dlSf + * @param [out] RgSchErrInfo *err + * @return S16 + * -# ROK + * -# RFAILED + */ +#ifdef ANSI +PRIVATE S16 rgSCHTomUtlFillPhich +( +RgSchCellCb *cell, +TfuCntrlReqInfo *cntrlInfo, +RgSchDlSf *dlSf, +RgSchErrInfo *err + ) +#else +PRIVATE S16 rgSCHTomUtlFillPhich(cell, cntrlInfo, dlSf, err) +RgSchCellCb *cell; +TfuCntrlReqInfo *cntrlInfo; +RgSchDlSf *dlSf; +RgSchErrInfo *err; +#endif +{ + S16 ret; + CmLList *node; + RgSchPhich *phich; + TfuPhichInfo *harqAck; +#ifdef TFU_UPGRADE + RgSchCmnDlCell *cellDl = RG_SCH_CMN_GET_DL_CELL(cell); +#endif + + TRC2(rgSCHTomUtlFillPhich) + ret = ROK; + /* Traversing the list of Phichs */ + node = dlSf->phichInfo.phichs.first; + while (node) + { + phich = (RgSchPhich*)node->node; + if ((ret = rgSCHUtlGetEventMem((Ptr *)&harqAck, sizeof(TfuPhichInfo), + &(cntrlInfo->memCp))) != ROK) + { + err->errCause = RGSCHERR_TOM_MEM_EXHAUST; + RETVALUE(ret); + } +#ifdef TFU_ALLOC_EVENT_NO_INIT + harqAck->txPower = 0; +#endif + /* fill in the tfu structure from the information present in the + * phich node */ + harqAck->rbStart = phich->rbStart; + harqAck->nDmrs = phich->nDmrs; + harqAck->isAck = phich->hqFeedBack; + harqAck->isForMsg3 = phich->isForMsg3; /*SR_RACH_STATS : PHICH ACK/NACK for MSG3 */ +#ifdef LTE_TDD + /* Changes for passing iPhich at TFU interface*/ + harqAck->iPhich = phich->iPhich; +#endif + /* ccpu00138898 - Added Tx pwr offset for PHICH Tx*/ +#ifdef TFU_UPGRADE + harqAck->txPower = cellDl->phichTxPwrOffset; +#endif + cmLListAdd2Tail(&cntrlInfo->phichLst, &(harqAck->lnk)); + harqAck->lnk.node = (PTR)harqAck; + node = node->next; + } /* end of while */ + RETVALUE(ret); +} /* end of */ + + +#ifdef LTE_ADV +/** @brief This function is a utility function to restart + * deactivation timer. + * + * @details + * + * Function: rgSCHTmrRestartScellDeactTmr + * + * Processing steps: + * - Starts timer at scheduler + * + * @param[in] RgSchCellCb *cell + * @param[in] CmLteRnti rnti + * @return Void + */ +#ifdef ANSI +PRIVATE Void rgSCHTmrRestartScellDeactTmr +( + RgSchCellCb *cell, + RgSchUeCb *ueCb + ) +#else +PRIVATE Void rgSCHTmrRestartScellDeactTmr (cell, ueCb) + RgSchCellCb *cell; + RgSchUeCb *ueCb; + +#endif +{ + RgSchUeCellInfo *sCellInfo = NULLP; + + if(NULLP != ueCb) + { + if(RG_SCH_IS_CELL_SEC(ueCb, cell)) + { + sCellInfo = ueCb->cellInfo[(ueCb->cellIdToCellIdxMap[RG_SCH_CELLINDEX(cell)])]; + + if(sCellInfo->deactTmr.tmrEvnt != TMR_NONE) + { + rgSCHTmrStopTmr(cell, RG_SCH_TMR_SCELL_DEACT, sCellInfo); + } + if(PRSNT_NODEF == ueCb->sCellDeactTmrVal.pres) + { + /* + rgSCHTmrStartTmr(cell,sCellInfo,RG_SCH_TMR_SCELL_DEACT, + ueCb->sCellDeactTmrVal.val); + */ + } + } + } +}/*end of rgSCHTmrRestartScellDeactTmr*/ +#endif + +/** @brief This function will send all the PDCCH's for the given downlink + * subframe. + * + * @details + * + * Function: + * + * Processing steps: + * - Loop through all the scheduled HARQ processes and fill + * the PDCCH information in cntrlInfo. + * + * @param [out] TfuCntrlReqInfo *cntrlInfo + * @param [in] RgSchDlSf *dlSf + * @param [out] RgSchErrInfo *err + * @return S16 + * -# ROK + * -# RFAILED + */ +EXTERN U32 numdlSpsRelSentToTf; +#ifdef ANSI +PRIVATE S16 rgSCHTomUtlFillDlPdcch +( +RgSchCellCb *cell, +TfuCntrlReqInfo *cntrlInfo, +RgSchDlSf *dlSf, +RgSchErrInfo *err + ) +#else +PRIVATE S16 rgSCHTomUtlFillDlPdcch(cell,cntrlInfo, dlSf, err) +RgSchCellCb *cell; +TfuCntrlReqInfo *cntrlInfo; +RgSchDlSf *dlSf; +RgSchErrInfo *err; +#endif +{ + S16 ret; + CmLList *node; + RgSchPdcch *pdcch; + TfuPdcchInfo *tfuPdcch; + U8 isDcivld = FALSE; + U8 numUePerTti = 0; + + TRC2(rgSCHTomUtlFillDlPdcch) + ret = ROK; + /* Traversing the scheduled Harq processes */ + node = dlSf->pdcchInfo.pdcchs.first; + while (node) + { + pdcch = (RgSchPdcch*)node->node; + switch(pdcch->dci.dciFormat) + { + case TFU_DCI_FORMAT_3: + isDcivld = (pdcch->dci.u.format3Info.isPucch) ? TRUE : FALSE; + break; + + case TFU_DCI_FORMAT_3A: + isDcivld = (pdcch->dci.u.format3AInfo.isPucch) ? TRUE : FALSE; + break; + + default: + isDcivld = TRUE; + break; + } + if(!isDcivld) + { + node = node->next; + continue; + } + + /*ccpu00117179 - ADD - Build only non DCI format-0 messages */ + if((pdcch->dci.dciFormat == TFU_DCI_FORMAT_0) || + (pdcch->dci.dciFormat == TFU_DCI_FORMAT_A1) || + (pdcch->dci.dciFormat == TFU_DCI_FORMAT_A2)) + { + node = node->next; + continue; + } + + +#ifdef RGSCH_SPS_STATS + if((pdcch->dci.dciFormat == TFU_DCI_FORMAT_1A) && + (pdcch->dci.u.format1aInfo.t.pdschInfo.allocInfo.mcs == 0x1F) && + (pdcch->dci.u.format1aInfo.t.pdschInfo.allocInfo.alloc.type == TFU_ALLOC_TYPE_RIV) && + (pdcch->dci.u.format1aInfo.t.pdschInfo.allocInfo.alloc.u.riv == 0xFFFFFFFF)) + { + numdlSpsRelSentToTf++; + } +#endif + + if ((ret = rgSCHUtlGetEventMem((Ptr *)&tfuPdcch, sizeof(TfuPdcchInfo), + &(cntrlInfo->memCp))) != ROK) + { + err->errCause = RGSCHERR_TOM_MEM_EXHAUST; + RETVALUE(ret); + } +#ifdef LTEMAC_SPS + tfuPdcch->crnti = pdcch->crnti; + tfuPdcch->isSpsRnti = pdcch->isSpsRnti; +#endif + tfuPdcch->rnti = pdcch->rnti; + +#ifdef LTE_ADV + rgSCHTmrRestartScellDeactTmr(cell,pdcch->ue); +#endif + tfuPdcch->dciNumOfBits = pdcch->dciNumOfBits; + + tfuPdcch->nCce = pdcch->nCce; + tfuPdcch->aggrLvl = pdcch->aggrLvl; + tfuPdcch->dci = pdcch->dci; +#ifdef RG_5GTF + //TODO_SID: Need to check these values during INT + tfuPdcch->sectorId = 0; + tfuPdcch->sccIdx = 0; + tfuPdcch->grpId = +#endif + /* SR_RACH_STATS : Reset isTBMsg4 */ + pdcch->dci.u.format1aInfo.t.pdschInfo.isTBMsg4 = FALSE; + /* To be enhanced later for 2.1 */ + cmLListAdd2Tail(&cntrlInfo->dlPdcchLst, &(tfuPdcch->lnk)); + tfuPdcch->lnk.node = (PTR)tfuPdcch; + node = node->next; + if((pdcch->rnti > 60) && (pdcch->rnti < 5000)) + { +#if defined (TENB_STATS) && defined (RG_5GTF) + cell->tenbStats->sch.dl5gtfPdcchSend++; +#endif + numUePerTti++; + } + } /* end of while */ + + if((numUePerTti) && (numUePerTti < RG_MAX_NUM_UE_PER_TTI )) + { + cell->dlNumUeSchedPerTti[numUePerTti-1]++; + { + gDlNumUePerTti[numUePerTti-1]++; + } + } + RETVALUE(ret); +} /* end of rgSCHTomUtlFillDlPdcch*/ + +#ifdef RGSCH_SPS_STATS +extern U32 rgSchSpsRelSentToTf; +extern U32 rgSchSpsRelPdcchAllocd; +#endif +/** @brief This function will send all the UL PDCCH's for the given + * subframe. + * + * @details + * + * Function: + * + * Processing steps: + * - Loop through all the scheduled HARQ processes and fill + * the PDCCH information in cntrlInfo. + * + * @param [out] TfuCntrlReqInfo *cntrlInfo + * @param [in] RgSchDlSf *dlSf + * @param [out] RgSchErrInfo *err + * @return S16 + * -# ROK + * -# RFAILED + */ +#ifdef ANSI +PRIVATE S16 rgSCHTomUtlFillUlPdcch +( +RgSchCellCb *cell, +TfuCntrlReqInfo *cntrlInfo, +RgSchDlSf *dlSf, +RgSchErrInfo *err + ) +#else +PRIVATE S16 rgSCHTomUtlFillUlPdcch(cntrlInfo, dlSf, err) +RgSchCellCb *cell; +TfuCntrlReqInfo *cntrlInfo; +RgSchDlSf *dlSf; +RgSchErrInfo *err; +#endif +{ + S16 ret; + CmLList *node; + RgSchPdcch *pdcch; + TfuPdcchInfo *tfuPdcch; + U8 isDcivld = FALSE; + + TRC2(rgSCHTomUtlFillUlPdcch) + ret = ROK; + /* Traversing the scheduled Harq processes */ + node = dlSf->pdcchInfo.pdcchs.first; + while (node) + { + pdcch = (RgSchPdcch*)node->node; + node = node->next; + /*ccpu00116712- Function should pick only UL allocation related control + * info- start */ + switch(pdcch->dci.dciFormat) + { + case TFU_DCI_FORMAT_A1: + isDcivld = TRUE; + break; + + case TFU_DCI_FORMAT_A2: + isDcivld = TRUE; + break; + + case TFU_DCI_FORMAT_3: + isDcivld = (pdcch->dci.u.format3Info.isPucch) ? FALSE : TRUE; + break; + + case TFU_DCI_FORMAT_3A: + isDcivld = (pdcch->dci.u.format3AInfo.isPucch) ? FALSE : TRUE; + break; + + default: + isDcivld = FALSE; + break; + } + if(!isDcivld) + { + continue; + } +#ifdef CA_DBG + gDci0Count++; +#endif + + /*ccpu00116712- Function should pick only UL allocation related control + * info- end */ + if ((ret = rgSCHUtlGetEventMem((Ptr *)&tfuPdcch, sizeof(TfuPdcchInfo), + &(cntrlInfo->memCp))) != ROK) + { + err->errCause = RGSCHERR_TOM_MEM_EXHAUST; + RETVALUE(ret); + } + tfuPdcch->rnti = pdcch->rnti; +#ifdef LTE_ADV + rgSCHTmrRestartScellDeactTmr(cell,pdcch->ue); +#endif + tfuPdcch->dciNumOfBits = pdcch->dciNumOfBits; + + tfuPdcch->nCce = pdcch->nCce; + tfuPdcch->aggrLvl = pdcch->aggrLvl; + tfuPdcch->dci = pdcch->dci; +#ifdef RG_5GTF + //TODO_SID: Need to check these values during INT + tfuPdcch->sectorId = 0; + tfuPdcch->sccIdx = 0; + tfuPdcch->grpId = +#endif + /* To be enhanced later for 2.1 */ + gUl5gtfPdcchSend++; +#if defined (TENB_STATS) && defined (RG_5GTF) + cell->tenbStats->sch.ul5gtfPdcchSend++; +#endif + cmLListAdd2Tail(&cntrlInfo->ulPdcchLst, &(tfuPdcch->lnk)); + tfuPdcch->lnk.node = (PTR)tfuPdcch; + } /* end of while */ + +#ifdef RGSCH_SPS_STATS + if (rgSchSpsRelSentToTf != rgSchSpsRelPdcchAllocd) + { + // abort(); + } +#endif + RETVALUE(ret); +} /* end of rgSCHTomUtlFillUlPdcch*/ + +/** @brief This function does the processing for Timing adjustment. + * + * @details + * + * Function: + * + * Processing steps: + * - Loop through the ue present ueTimeLst, decrement the remaining + * frames left. + * + * + * @param [in] RgSchCellCb *cell + * @return S16 + * -# ROK + * -# RFAILED + */ +#ifdef ANSI +PRIVATE S16 rgSCHTomUtlProcTA +( +RgSchCellCb *cell +) +#else +PRIVATE S16 rgSCHTomUtlProcTA (cell) +RgSchCellCb *cell; +#endif +{ + CmLList *node; + RgSchUeCb *ue; + + TRC2(rgSCHTomUtlProcTA); + + node = cell->taUeLst.first; + while (node) + { + ue = (RgSchUeCb *)node->node; + node = node->next; + if (ue->dl.taCb.numRemSf == 0) + { + ue->dl.taCb.state = RGSCH_TA_IDLE; + /* If Outstanding Ta is present, schedule it */ + if(ue->dl.taCb.outStndngTa == TRUE) + { + rgSCHUtlReTxTa(cell, ue); + } + else + { + /* We need to reset state and also value of TA, + * then we start the timer */ + ue->dl.taCb.ta = RGSCH_NO_TA_RQD; + /* Start the timer only if TA is cfgd as FINITE value */ + if (ue->dl.taCb.cfgTaTmr) + { + rgSCHTmrStartTmr (cell, ue, RG_SCH_TMR_TA, ue->dl.taCb.cfgTaTmr); + } + } + /* need to delete from the link list */ + cmLListDelFrm(&(cell->taUeLst), &(ue->taLnk)); + ue->taLnk.node = NULLP; + } + else + { + ue->dl.taCb.numRemSf--; + } + } /* end of taUeLst */ + + RETVALUE(ROK); +} /* end of rgSCHTomUtlProcTA */ + +/** @brief This function handles filling of Hq reception request to + * Per Hq Proc. + * + * @details + * + * Function: + * + * Processing steps: + * + * @return S16 + * -# ROK + * -# RFAILED + */ +#ifdef TFU_UPGRADE +#ifdef ANSI +PUBLIC S16 rgSCHTomUtlFillHqFdbkInfo +( + TfuRecpReqInfo *recpReqInfo, + RgSchCellCb *cell, + U16 validIdx, + RgSchDlHqProcCb *hqCb, + RgSchDlSf *nxtDlsf, + TfuUeRecpReqInfo *pucchRecpInfo, + RgSchDlHqProcCb *prvHqCb, + RgSchErrInfo *err + ) +#else +PUBLIC S16 rgSCHTomUtlFillHqFdbkInfo (recpReqInfo, cell, validIdx, hqCb, nxtDlsf, pucchRecpInfo, prvHqCb, err) + TfuRecpReqInfo *recpReqInfo; + RgSchCellCb *cell; + U16 validIdx; + RgSchDlHqProcCb *hqCb; + RgSchDlSf *nxtDlsf; + TfuUeRecpReqInfo *pucchRecpInfo; + RgSchDlHqProcCb *prvHqCb; + RgSchErrInfo *err; +#endif +#else +#ifdef ANSI +PUBLIC S16 rgSCHTomUtlFillHqFdbkInfo +( +TfuRecpReqInfo *recpReqInfo, +RgSchCellCb *cell, +RgSchDlHqProcCb *hqCb, +RgSchDlSf *nxtDlsf, +TfuUeRecpReqInfo *pucchRecpInfo, +RgSchDlHqProcCb *prvHqCb, +RgSchErrInfo *err +) +#else +PUBLIC S16 rgSCHTomUtlFillHqFdbkInfo (recpReqInfo, cell, hqCb, nxtDlsf, pucchRecpInfo, prvHqCb, err) +TfuRecpReqInfo *recpReqInfo; +RgSchCellCb *cell; +RgSchDlHqProcCb *hqCb; +RgSchDlSf *nxtDlsf; +TfuUeRecpReqInfo *pucchRecpInfo; +RgSchDlHqProcCb *prvHqCb; +RgSchErrInfo *err; +#endif +#endif +{ + S16 ret; + RgSchDlHqTbCb *tbCb; + U32 idx; + Bool isAddToLst = FALSE; + + for (idx = 0 ;idx < 2; idx++) + { + if (HQ_TB_WAITING == hqCb->tbInfo[idx].state) + { + tbCb = &hqCb->tbInfo[idx]; + + /* FOR ACK NAK REP */ + if ((hqCb->hqE->ue != NULLP) && + (hqCb->hqE->ue->measGapCb.isMeasuring == TRUE)) + { + if ((tbCb->fbkRecpRepCntr) && + (--tbCb->fbkRecpRepCntr)) + { + /* Add to next subfarme */ + /* Add this hqCb to the next dlSf's ackNakRepQ */ + cmLListAdd2Tail (&(nxtDlsf->ackNakRepQ), + &(tbCb->anRepLnk[tbCb->fbkRecpRepCntr])); + tbCb->anRepLnk[tbCb->fbkRecpRepCntr].node = (PTR)tbCb; + tbCb->crntSubfrm[tbCb->fbkRecpRepCntr] = nxtDlsf; + } +#ifdef TFU_UPGRADE + rgSCHTomUtlMoveNxtOccasion(cell, hqCb->hqE->ue, validIdx); +#endif + continue; + } +#ifdef TFU_UPGRADE + if (hqCb->tbCnt) + { + hqCb->tbCnt--; + /* Go to the next node */ + continue; + } +#endif + + + //if (hqCb != prvHqCb) + { + ret = rgSCHUtlGetEventMem((Ptr *)&pucchRecpInfo, + sizeof(TfuUeRecpReqInfo), &(recpReqInfo->memCp)); + if (ret != ROK) + { + RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,"Unable to Allocate " + "TfuUeRecpReqInfo for cell"); + err->errCause = RGSCHERR_TOM_MEM_EXHAUST; + RETVALUE(ret); + } + pucchRecpInfo->type = TFU_RECP_REQ_PUCCH; + if ((hqCb->hqE->ue != NULLP) /*&& + ((tbCb->lchSchdData[0].lcId != 0) || (tbCb->taSnt == + TRUE))*/ + ) + { + pucchRecpInfo->rnti = hqCb->hqE->ue->ueId; + } + else + { + if (hqCb->hqE->raCb) + { + pucchRecpInfo->rnti = hqCb->hqE->raCb->tmpCrnti; + } + } +#ifndef TFU_UPGRADE +#ifndef TFU_TDD +#ifdef LTEMAC_SPS + if (!hqCb->spsN1PucchRes.pres) +#endif + { + pucchRecpInfo->t.pucchRecpReq.hqType = + TFU_HQ_RECP_REQ_NORMAL; + pucchRecpInfo->t.pucchRecpReq.t.nCce = + hqCb->pdcch->nCce; + } +#ifdef LTEMAC_SPS + else + { + pucchRecpInfo->t.pucchRecpReq.hqType = + TFU_HQ_RECP_REQ_N1PUCCH; + pucchRecpInfo->t.pucchRecpReq.t.n1Pucch = + hqCb->spsN1PucchRes.val; + } +#endif +#endif + /* Handling of other types */ + pucchRecpInfo->t.pucchRecpReq.type = TFU_UCI_HARQ; +#else /* TFU_UPGRADE */ + pucchRecpInfo->t.pucchRecpReq.uciInfo = TFU_PUCCH_HARQ; + if ((hqCb->tbInfo[0].state == HQ_TB_WAITING) && + (hqCb->tbInfo[1].state == HQ_TB_WAITING)) + { + pucchRecpInfo->t.pucchRecpReq.hqInfo.hqSz = 2; /* MIMO */ + } + else + { + pucchRecpInfo->t.pucchRecpReq.hqInfo.hqSz = 1; /* NON-MIMO */ + } + { +#ifdef LTEMAC_SPS + /* PucchRecpReq needs to be filled up for n1Pucch resource for SPS + * ocassions */ + if (hqCb->spsN1PucchRes.pres) + { + pucchRecpInfo->t.pucchRecpReq.hqInfo.hqRes[0] = hqCb->spsN1PucchRes.val; + } + else +#endif /* LTEMAC_SPS */ + { + pucchRecpInfo->t.pucchRecpReq.hqInfo.hqRes[0] = (hqCb->pdcch->nCce + + cell->pucchCfg.n1PucchAn); + } +#ifdef EMTC_ENABLE + rgSCHEmtcFillPucchRecpInfo(cell, hqCb, &(pucchRecpInfo->t.pucchRecpReq.hqInfo.hqRes[0])); +#endif + } +#endif/*TFU_UPGRADE*/ + +#ifdef TFU_UPGRADE + rgSCHTomUtlFillCqiSrSrsWithHq(cell,recpReqInfo, hqCb->hqE->ue, + pucchRecpInfo, validIdx,FALSE); +#endif +#ifdef EMTC_ENABLE + /* Passing last parameter as FALSE in this case as it will be verified from hqCb*/ + isAddToLst = rgSCHEmtcAddRecpInfoToLst(hqCb,recpReqInfo, pucchRecpInfo,FALSE); +#endif + if(!isAddToLst) + { + cmLListAdd2Tail(&recpReqInfo->ueRecpReqLst, &(pucchRecpInfo->lnk)); + } + pucchRecpInfo->lnk.node = (PTR)pucchRecpInfo; + } + + if ((tbCb->fbkRecpRepCntr) && + (--tbCb->fbkRecpRepCntr)) + { + /* Add to next subfarme */ + /* Add this hqCb to the next dlSf's ackNakRepQ */ + cmLListAdd2Tail (&(nxtDlsf->ackNakRepQ), + &(tbCb->anRepLnk[tbCb->fbkRecpRepCntr])); + tbCb->anRepLnk[tbCb->fbkRecpRepCntr].node = (PTR)tbCb; + tbCb->crntSubfrm[tbCb->fbkRecpRepCntr] = nxtDlsf; + } + break; + } + } + RETVALUE(ROK); +}/* end of rgSCHTomUtlFillHqFdbkInfo */ + +#ifdef RG_5GTF +/** @brief This function handles filling of Hq reception request to + * Per Hq Proc. + * + * @details + * + * Function:rgSCHTomUtlFillHqFdbkFor5gtf + * + * Processing steps: + * + * @param [out] TfuRecpReqInfo *recpReqInfo + * @param [in] RgSchCellCb *cell + * @param [in] U16 validIdx, + * @param [in] RgSchDlHqInfo *dlSfHqInfo, + * @param [in] RgSchDlSf *dlSf, + * @param [in] TfuUeRecpReqInfo *pucchRecpInfo, + * @param [out] RgSchErrInfo *err + * + * @return S16 + * -# ROK + * -# RFAILED + */ +#ifdef ANSI +PRIVATE S16 rgSCHTomUtlFillHqFdbkFor5gtf +( + TfuRecpReqInfo *recpReqInfo, + RgSchCellCb *cell, + U16 validIdx, + RgSchDlHqInfo *dlSfHqInfo, + RgSchDlSf *dlSf, + TfuUeRecpReqInfo *pucchRecpInfo, + RgSchErrInfo *err + ) +#else +PRIVATE S16 rgSCHTomUtlFillHqFdbkFor5gtf (recpReqInfo, cell, validIdx, hqCb, dlSf, pucchRecpInfo, err) + TfuRecpReqInfo *recpReqInfo; + RgSchCellCb *cell; + U16 validIdx; + RgSchDlHqInfo *dlSfHqInfo; + RgSchDlSf *dlSf; + TfuUeRecpReqInfo *pucchRecpInfo; + RgSchErrInfo *err; +#endif +{ +#ifdef DEBUGP + Inst inst = cell->instIdx; +#endif + S16 ret; + CmLList *hqPNode; + RgSchDlHqProcCb *hqCb = NULLP; + RgSchUeCb *ue; + TfuUePucchRecpReq *pucchReqInfo = NULLP; + Bool isDatPresOnSecCell = FALSE; + U8 primCellTbCount = 0; + + hqPNode = dlSfHqInfo->hqPLst.first; + ue = (RgSchUeCb*)dlSfHqInfo->dlSfUeLnk.node; + + if (ue == NULLP) + { + RETVALUE(RFAILED); + } + ret = rgSCHUtlGetEventMem((Ptr *)&pucchRecpInfo, + sizeof(TfuUeRecpReqInfo), &(recpReqInfo->memCp)); + if (ret != ROK) + { + RGSCHDBGERRNEW(inst,(rgSchPBuf(inst),"Unable to Allocate " + "TfuUeRecpReqInfo for cellId=%d \n", cell->cellId)); + err->errCause = RGSCHERR_TOM_MEM_EXHAUST; + RETVALUE(ret); + } + pucchRecpInfo->type = TFU_RECP_REQ_PUCCH; + pucchRecpInfo->rnti = ue->ueId; /* Even for Rel pdcch also setting CRNTI + * instead of SPS-CRNTI */ + + pucchReqInfo = &(pucchRecpInfo->t.pucchRecpReq); + + pucchReqInfo->uciInfo = TFU_XPUCCH_UCI_INFO; + + /* 5gtf TODO : Hardcoded nPUCCHIdx */ + pucchReqInfo->uciPduInfo.pucchIndex = 0; + + pucchReqInfo->uciPduInfo.numBits = 1; + + /* 5gtf TODO : CQI Periodicity Hardcoded to (n,0)*/ + if (RGSCH_TIMEINFO_SAME (recpReqInfo->timingInfo, ue->ue5gtfCb.nxtCqiRiOccn)) + { + pucchReqInfo->uciPduInfo.numBits += 5; + RG_SCH_ADD_TO_CRNT_TIME(recpReqInfo->timingInfo, ue->ue5gtfCb.nxtCqiRiOccn, + ue->ue5gtfCb.cqiRiPer); + } + + cmLListAdd2Tail(&recpReqInfo->ueRecpReqLst, &(pucchRecpInfo->lnk)); + pucchRecpInfo->lnk.node = (PTR)pucchRecpInfo; + RETVALUE(ROK); +}/* end of rgSCHTomUtlFillHqFdbkForFrmt1B */ +#endif + +#ifdef LTE_ADV +/** @brief This function handles filling of Hq reception request to + * Per Hq Proc. + * + * @details + * + * Function:rgSCHTomUtlFillHqFdbkForFrmt1B + * + * Processing steps: + * Allocates the N1Pucch Resources based on teh A Value + * + * @param [out] TfuRecpReqInfo *recpReqInfo + * @param [in] RgSchCellCb *cell + * @param [in] U16 validIdx, + * @param [in] RgSchDlHqInfo *dlSfHqInfo, + * @param [in] RgSchDlSf *dlSf, + * @param [in] TfuUeRecpReqInfo *pucchRecpInfo, + * @param [out] RgSchErrInfo *err + * + * @return S16 + * -# ROK + * -# RFAILED + */ +#ifdef TFU_UPGRADE +#ifdef ANSI +PRIVATE S16 rgSCHTomUtlFillHqFdbkForFrmt1B +( + TfuRecpReqInfo *recpReqInfo, + RgSchCellCb *cell, + U16 validIdx, + RgSchDlHqInfo *dlSfHqInfo, + RgSchDlSf *dlSf, + TfuUeRecpReqInfo *pucchRecpInfo, + RgSchErrInfo *err + ) +#else +PRIVATE S16 rgSCHTomUtlFillHqFdbkForFrmt1B (recpReqInfo, cell, validIdx, hqCb, dlSf, pucchRecpInfo, err) + TfuRecpReqInfo *recpReqInfo; + RgSchCellCb *cell; + U16 validIdx; + RgSchDlHqInfo *dlSfHqInfo; + RgSchDlSf *dlSf; + TfuUeRecpReqInfo *pucchRecpInfo; + RgSchErrInfo *err; +#endif +#else +#ifdef ANSI +PRIVATE S16 rgSCHTomUtlFillHqFdbkForFrmt1B +( +TfuRecpReqInfo *recpReqInfo, +RgSchCellCb *cell, +RgSchDlHqInfo *dlSfHqInfo, +RgSchDlSf *dlSf, +TfuUeRecpReqInfo *pucchRecpInfo, +RgSchErrInfo *err +) +#else +PRIVATE S16 rgSCHTomUtlFillHqFdbkForFrmt1B (recpReqInfo, cell, hqCb, dlSf, pucchRecpInfo, err) +TfuRecpReqInfo *recpReqInfo; +RgSchCellCb *cell; +RgSchDlHqInfo *dlSfHqInfo; +RgSchDlSf *dlSf; +TfuUeRecpReqInfo *pucchRecpInfo; +RgSchErrInfo *err; +#endif +#endif +{ +#ifdef DEBUGP + Inst inst = cell->instIdx; +#endif + S16 ret; + CmLList *hqPNode; + RgSchDlHqProcCb *hqCb = NULLP; + RgSchUeCb *ue; + TfuUePucchRecpReq *pucchReqInfo = NULLP; + Bool isDatPresOnSecCell = FALSE; + U8 primCellTbCount = 0; + + hqPNode = dlSfHqInfo->hqPLst.first; + ue = (RgSchUeCb*)dlSfHqInfo->dlSfUeLnk.node; + + if (ue == NULLP) + { + RETVALUE(RFAILED); + } + ret = rgSCHUtlGetEventMem((Ptr *)&pucchRecpInfo, + sizeof(TfuUeRecpReqInfo), &(recpReqInfo->memCp)); + if (ret != ROK) + { + RGSCHDBGERRNEW(inst,(rgSchPBuf(inst),"Unable to Allocate " + "TfuUeRecpReqInfo for cellId=%d \n", cell->cellId)); + err->errCause = RGSCHERR_TOM_MEM_EXHAUST; + RETVALUE(ret); + } + pucchRecpInfo->type = TFU_RECP_REQ_PUCCH; + pucchRecpInfo->rnti = ue->ueId; /* Even for Rel pdcch also setting CRNTI + * instead of SPS-CRNTI */ + + pucchReqInfo = &(pucchRecpInfo->t.pucchRecpReq); + +#ifndef TFU_UPGRADE + pucchReqInfo->hqType = TFU_HQ_RECP_REQ_NORMAL; + /* Handling of other types */ + pucchReqInfo->type = TFU_UCI_HARQ; +#else /* TFU_UPGRADE */ + pucchReqInfo->uciInfo = TFU_PUCCH_HARQ; + /* Fill hqFdbkMode by using uciFrmtTyp from dlSfHqInfo */ + pucchReqInfo->hqInfo.hqFdbkMode = rgSchUtlGetFdbkMode(dlSfHqInfo->uciFrmtTyp); + /* Fill HqSz by using totalTbCnt based on the TM mode and + * the number of serv cells configured*/ + + pucchReqInfo->hqInfo.hqSz = ue->f1bCsAVal; + pucchReqInfo->hqInfo.pucchResCnt = ue->f1bCsAVal; + + cmMemset((U8 *)pucchReqInfo->hqInfo.hqRes,0xff,sizeof(U16)*TFU_MAX_HQ_RES); +#ifdef LTEMAC_SPS + /* Two Resources needs to be configured if the + * serving cell is in mimo mode else single + * resource */ + if ((dlSf->relPdcch != NULLP) && + (RGSCH_TIMEINFO_SAME(recpReqInfo->timingInfo, ue->relPdcchFbkTiming))) + {/* Pcell is having sps rel pdcch present */ + if(rgSCHUtlGetMaxTbSupp(ue->mimoInfo.txMode) > 1) + {/* prim cell is in mimo mode, use 0 and 1 */ + pucchReqInfo->hqInfo.hqRes[0] = (dlSf->relPdcch->nCce + + cell->pucchCfg.n1PucchAn); + pucchReqInfo->hqInfo.hqRes[1] = pucchReqInfo->hqInfo.hqRes[0] + 1; + + + }else + { + pucchReqInfo->hqInfo.hqRes[2] = (dlSf->relPdcch->nCce + + cell->pucchCfg.n1PucchAn); + } + /* Release the pdcch so that it will not further processed */ + rgSCHUtlPdcchPut(ue->cell,&dlSf->pdcchInfo, dlSf->relPdcch); + dlSf->relPdcch = NULLP;/* only one UE will be scheduled for release pdcch order in one tti */ + } +#endif/*LTEMAC_SPS*/ +#endif/*TFU_UPGRADE*/ + while(hqPNode) + { + hqCb = (RgSchDlHqProcCb *)hqPNode->node; + hqPNode = hqPNode->next; + /* In case of CSI + 1BCS , CSI will be + * dropped if scheduling is present on + * seconday cell.36.213 10.1.1 + * */ + if(RG_SCH_IS_CELL_SEC(ue,hqCb->hqE->cell)) + { + isDatPresOnSecCell = TRUE; + }else + { + if ((hqCb->tbInfo[0].state == HQ_TB_WAITING) && + (hqCb->tbInfo[1].state == HQ_TB_WAITING)) + { + primCellTbCount = 2; + }else + { + primCellTbCount = 1; + } + } +#ifndef TFU_UPGRADE + pucchReqInfo->t.nCce = hqCb->pdcch->nCce; +#else + { + switch(ue->f1bCsAVal) + {/* A Value */ + case RG_SCH_A_VAL_2: + /* harq(0) is primary harq(1) is secondary) */ + if(RG_SCH_IS_CELL_SEC(ue,hqCb->hqE->cell)) + { + pucchReqInfo->hqInfo.hqRes[1] = ue->n1PucchF1bResCb.\ + cw1N1Res[hqCb->tpc].n1PucchIdx; + } + else/* primary cell */ + { +#ifdef LTEMAC_SPS + /* Need to consider only sps occasions */ + if (hqCb->spsN1PucchRes.pres) + { + pucchReqInfo->hqInfo.hqRes[0] = hqCb->spsN1PucchRes.val; + } + else +#endif /* LTEMAC_SPS */ + { + + pucchReqInfo->hqInfo.hqRes[0] = (hqCb->pdcch->nCce + + cell->pucchCfg.n1PucchAn); + } + } + break; + case RG_SCH_A_VAL_3: + /* Serving cell in mimo mode should be + * in 0 and 1 and the serving cell in siso + * mode should be in 2 indices */ + if(RG_SCH_IS_CELL_SEC(ue,hqCb->hqE->cell)) + { + U8 cellIdx = ue->cellIdToCellIdxMap[RG_SCH_CELLINDEX(hqCb->hqE->cell)]; + if(rgSCHUtlGetMaxTbSupp(ue->cellInfo[cellIdx]->txMode.txModeEnum) > 1) + {/* Sec cell is in mimo mode, use 0 and 1 */ + pucchReqInfo->hqInfo.hqRes[0] = + ue->n1PucchF1bResCb.cw1N1Res[hqCb->tpc].n1PucchIdx; + + pucchReqInfo->hqInfo.hqRes[1] = + ue->n1PucchF1bResCb.cw2N1Res[hqCb->tpc].n1PucchIdx; + } + else + {/* Sec cell is in siso mode, use 2 */ + pucchReqInfo->hqInfo.hqRes[2] = + ue->n1PucchF1bResCb.cw1N1Res[hqCb->tpc].n1PucchIdx; + } + } + else + {/* primary cell hq */ + if(rgSCHUtlGetMaxTbSupp(ue->mimoInfo.txMode) > 1) + {/* prim cell is in mimo mode, use 0 and 1 */ +#ifdef LTEMAC_SPS + if (hqCb->spsN1PucchRes.pres) + {/* SPS occasions */ + pucchReqInfo->hqInfo.hqRes[0] = hqCb->spsN1PucchRes.val; + pucchReqInfo->hqInfo.hqRes[1] = hqCb->spsN1PucchRes.val + 1; + } + else +#endif /* LTEMAC_SPS */ + { + pucchReqInfo->hqInfo.hqRes[0] = (hqCb->pdcch->nCce + + cell->pucchCfg.n1PucchAn); + pucchReqInfo->hqInfo.hqRes[1] = (hqCb->pdcch->nCce + + cell->pucchCfg.n1PucchAn + 1); + } + } + else + {/* prim cell is in siso mode use 2 */ +#ifdef LTEMAC_SPS + /* Need to consider only sps occasions */ + if (hqCb->spsN1PucchRes.pres) + { + pucchReqInfo->hqInfo.hqRes[2] = hqCb->spsN1PucchRes.val; + } + else +#endif /* LTEMAC_SPS */ + { + + pucchReqInfo->hqInfo.hqRes[2] = (hqCb->pdcch->nCce + + cell->pucchCfg.n1PucchAn); + + } + } + } + break; + case RG_SCH_A_VAL_4: + { + if(RG_SCH_IS_CELL_SEC(ue,hqCb->hqE->cell)) + {/* 2 and 3 for sec cell */ + pucchReqInfo->hqInfo.hqRes[2] = + ue->n1PucchF1bResCb.cw1N1Res[hqCb->tpc].n1PucchIdx; + pucchReqInfo->hqInfo.hqRes[3] = + ue->n1PucchF1bResCb.cw2N1Res[hqCb->tpc].n1PucchIdx; + } + else/* primary cell */ + {/* 0 and 1 are for primary cell */ +#ifdef LTEMAC_SPS + /* Need to consider only sps occasions */ + if (hqCb->spsN1PucchRes.pres) + { + pucchReqInfo->hqInfo.hqRes[0] = hqCb->spsN1PucchRes.val; + pucchReqInfo->hqInfo.hqRes[1] = hqCb->spsN1PucchRes.val + 1; + } + else +#endif /* LTEMAC_SPS */ + { + + pucchReqInfo->hqInfo.hqRes[0] = (hqCb->pdcch->nCce + + cell->pucchCfg.n1PucchAn); + pucchReqInfo->hqInfo.hqRes[1] = (hqCb->pdcch->nCce + + cell->pucchCfg.n1PucchAn + 1); + } + } + } + + break; + default: + /* TOD:: Add error print */ + break; + } + } +#endif/*TFU_UPGRADE*/ + } +#ifdef TFU_UPGRADE + +#ifdef CA_DBG + { + gF1bCsCount++; + gF1bCsPres = TRUE; + } + +#endif + rgSCHTomUtlFillCqiSrSrsWithHq(cell,recpReqInfo, ue, + pucchRecpInfo, validIdx,isDatPresOnSecCell); + + /* Channel selection wil not be used in case of + * CQI + HARQ. if the data was present only on + * primary cell */ + if((isDatPresOnSecCell == FALSE) && + (dlSfHqInfo->uciFrmtTyp == RG_SCH_UCI_FORMAT1B_CS)) + {/* Data is present only on primary cell */ + + switch(pucchReqInfo->uciInfo) + { + case TFU_PUCCH_HARQ_SRS: + case TFU_PUCCH_HARQ_CQI: + case TFU_PUCCH_HARQ_SR_SRS: + case TFU_PUCCH_HARQ_SR_CQI: + { + dlSfHqInfo->uciFrmtTyp = RG_SCH_UCI_FORMAT1A_1B; + pucchReqInfo->hqInfo.hqSz = primCellTbCount; + pucchReqInfo->hqInfo.hqFdbkMode = rgSchUtlGetFdbkMode(dlSfHqInfo->uciFrmtTyp); + } + break; + default: + { + break; + } + } + } +#endif/*TFU_UPGRADE*/ + cmLListAdd2Tail(&recpReqInfo->ueRecpReqLst, &(pucchRecpInfo->lnk)); + pucchRecpInfo->lnk.node = (PTR)pucchRecpInfo; + RETVALUE(ROK); +}/* end of rgSCHTomUtlFillHqFdbkForFrmt1B */ +/** @brief This function handles filling of Hq reception request to + * Per Hq Proc. + * + * @details + * + * Function:rgSCHTomUtlFillHqFdbkForFrmt3 + * + * Processing steps: + * Allocates the N1Pucch Resources based on teh A Value + * + * @param [out] TfuRecpReqInfo *recpReqInfo + * @param [in] RgSchCellCb *cell + * @param [in] U16 validIdx, + * @param [in] RgSchDlHqInfo *dlSfHqInfo, + * @param [in] RgSchDlSf *dlSf, + * @param [in] TfuUeRecpReqInfo *pucchRecpInfo, + * @param [out] RgSchErrInfo *err + * + * @return S16 + * -# ROK + * -# RFAILED + */ +#ifdef TFU_UPGRADE +#ifdef ANSI +PRIVATE S16 rgSCHTomUtlFillHqFdbkForFrmt3 +( + TfuRecpReqInfo *recpReqInfo, + RgSchCellCb *cell, + U16 validIdx, + RgSchDlHqInfo *dlSfHqInfo, + RgSchDlSf *dlSf, + TfuUeRecpReqInfo *pucchRecpInfo, + RgSchErrInfo *err + ) +#else +PRIVATE S16 rgSCHTomUtlFillHqFdbkForFrmt3 (recpReqInfo, cell, validIdx, hqCb, dlSf, pucchRecpInfo, err) + TfuRecpReqInfo *recpReqInfo; + RgSchCellCb *cell; + U16 validIdx; + RgSchDlHqInfo *dlSfHqInfo; + RgSchDlSf *dlSf; + TfuUeRecpReqInfo *pucchRecpInfo; + RgSchErrInfo *err; +#endif +#else +#ifdef ANSI +PRIVATE S16 rgSCHTomUtlFillHqFdbkForFrmt3 +( +TfuRecpReqInfo *recpReqInfo, +RgSchCellCb *cell, +RgSchDlHqInfo *dlSfHqInfo, +RgSchDlSf *dlSf, +TfuUeRecpReqInfo *pucchRecpInfo, +RgSchErrInfo *err +) +#else +PRIVATE S16 rgSCHTomUtlFillHqFdbkForFrmt3 (recpReqInfo, cell, hqCb, dlSf, pucchRecpInfo, err) +TfuRecpReqInfo *recpReqInfo; +RgSchCellCb *cell; +RgSchDlHqInfo *dlSfHqInfo; +RgSchDlSf *dlSf; +TfuUeRecpReqInfo *pucchRecpInfo; +RgSchErrInfo *err; +#endif +#endif +{ +#ifdef DEBUGP + Inst inst = cell->instIdx; +#endif + S16 ret; + //CmLList *hqPNode; + RgSchUeCb *ue; + TfuUePucchRecpReq *pucchReqInfo = NULLP; + + //hqPNode = dlSfHqInfo->hqPLst.first; + ue = (RgSchUeCb*)dlSfHqInfo->dlSfUeLnk.node; + + if (ue == NULLP) + { + RETVALUE(RFAILED); + } + ret = rgSCHUtlGetEventMem((Ptr *)&pucchRecpInfo, + sizeof(TfuUeRecpReqInfo), &(recpReqInfo->memCp)); + if (ret != ROK) + { + RGSCHDBGERRNEW(inst,(rgSchPBuf(inst),"Unable to Allocate " + "TfuUeRecpReqInfo for cellId=%d \n", cell->cellId)); + err->errCause = RGSCHERR_TOM_MEM_EXHAUST; + RETVALUE(ret); + } + pucchRecpInfo->type = TFU_RECP_REQ_PUCCH; + pucchRecpInfo->rnti = ue->ueId; /* Even for Rel pdcch also setting CRNTI + * instead of SPS-CRNTI */ + + pucchReqInfo = &(pucchRecpInfo->t.pucchRecpReq); + +#ifndef TFU_UPGRADE + pucchReqInfo->hqType = TFU_HQ_RECP_REQ_NORMAL; + /* Handling of other types */ + pucchReqInfo->type = TFU_UCI_HARQ; +#else /* TFU_UPGRADE */ + pucchReqInfo->uciInfo = TFU_PUCCH_HARQ; + /* Fill hqFdbkMode by using uciFrmtTyp from dlSfHqInfo */ + pucchReqInfo->hqInfo.hqFdbkMode = rgSchUtlGetFdbkMode(dlSfHqInfo->uciFrmtTyp); + /* Fill HqSz by using totalTbCnt based on the TM mode and + * the number of serv cells configured*/ + + pucchReqInfo->hqInfo.hqSz = ue->f1bCsAVal; + pucchReqInfo->hqInfo.pucchResCnt = 1; + + cmMemset((U8 *)pucchReqInfo->hqInfo.hqRes,0xff,sizeof(U16)*TFU_MAX_HQ_RES); +#endif/*TFU_UPGRADE*/ + pucchReqInfo->hqInfo.hqRes[0] = dlSfHqInfo->n3ScellPucch.n3PucchIdx; +#ifdef TFU_UPGRADE + rgSCHTomUtlFillCqiSrSrsWithHq(cell,recpReqInfo, ue, + pucchRecpInfo, validIdx,TRUE); +#endif/*TFU_UPGRADE*/ + cmLListAdd2Tail(&recpReqInfo->ueRecpReqLst, &(pucchRecpInfo->lnk)); + pucchRecpInfo->lnk.node = (PTR)pucchRecpInfo; + RETVALUE(ROK); +}/* end of rgSCHTomUtlFillHqFdbkForFrmt3 */ + +#endif/*LTE_ADV*/ + +/** @brief This function handles filling of HARQ feedback recption request to + * PHY. + * + * @details + * + * Function: + * + * Processing steps: + * + * @param [out] TfuRecpReqInfo *recpReqInfo + * @param [in] RgSchCellCb *cell + * @param [out] RgSchErrInfo *err + * @return S16 + * -# ROK + * -# RFAILED + */ +#ifdef TFU_UPGRADE +#ifdef ANSI +PRIVATE S16 rgSCHTomUtlFillHqFdbkRecpReq +( + TfuRecpReqInfo *recpReqInfo, + RgSchCellCb *cell, + U16 validIdx, + RgSchErrInfo *err + ) +#else +PRIVATE S16 rgSCHTomUtlFillHqFdbkRecpReq (recpReqInfo, cell, validIdx, err) + TfuRecpReqInfo *recpReqInfo; + RgSchCellCb *cell; + U16 validIdx; + RgSchErrInfo *err; +#endif +#else +#ifdef ANSI +PRIVATE S16 rgSCHTomUtlFillHqFdbkRecpReq +( +TfuRecpReqInfo *recpReqInfo, +RgSchCellCb *cell, +RgSchErrInfo *err +) +#else +PRIVATE S16 rgSCHTomUtlFillHqFdbkRecpReq (recpReqInfo, cell, err) +TfuRecpReqInfo *recpReqInfo; +RgSchCellCb *cell; +RgSchErrInfo *err; +#endif +#endif +{ + CmLList *node; + CmLList *hqPNode; + RgSchDlHqProcCb *hqCb; + CmLteTimingInfo futTime; + RgSchDlSf *dlSf; + RgSchDlSf *nxtDlsf; + TfuUeRecpReqInfo *pucchRecpInfo = NULLP; + S16 ret; +#ifdef DEBUGP + Inst inst = cell->instIdx; +#endif + RgSchUeCb *ue; + RgSchDlHqTbCb *tbCb; + RgSchDlHqProcCb *prvHqCb=NULLP; + + TRC2(rgSCHTomUtlFillHqFdbkRecpReq); + +#ifdef CA_DBG + { + gF1bCsPres = FALSE; + } +#endif + /* ccpu00133109: Removed RGSCHSUBFRMCRNTTIME as it is not giving proper output + * if diff is more than 10. Instead using RGSCHDECRFRMCRNTTIME() as it is + * serving the purpose */ + RGSCHDECRFRMCRNTTIME(cell->crntTime, futTime, (RG_SCH_CMN_HARQ_INTERVAL - + TFU_RECPREQ_DLDELTA)); + dlSf = rgSCHUtlSubFrmGet (cell, futTime); + /* Get the next dlsf as well */ + RG_SCH_ADD_TO_CRNT_TIME(futTime, futTime, 1) + nxtDlsf = rgSCHUtlSubFrmGet (cell, futTime); + + prvHqCb = NULLP; + + if (dlSf->ueLst.count != 0) + { + node = dlSf->ueLst.first; + while (node) + { + ue = (RgSchUeCb *)(node->node); + node = node->next; + + if(ue->dl.dlSfHqInfo[cell->cellId][dlSf->dlIdx].isPuschHarqRecpPres == TRUE) + {/* This UE is already considered for PUSCH + Ignore for PUCCH */ + continue; + } + rgSCHTomUtlFillHqFdbkFor5gtf(recpReqInfo, cell, validIdx, + &ue->dl.dlSfHqInfo[cell->cellId][dlSf->dlIdx], dlSf, pucchRecpInfo, err); + } /* end of while */ + } /* If hq is expected */ + + if (dlSf->msg4HqPLst.count != 0) + { + prvHqCb = NULLP; + node = dlSf->msg4HqPLst.first; + while (node) + { + hqCb = (RgSchDlHqProcCb*)(node->node); + node = node->next; + //TODO_SID: need to check validIdx + rgSCHTomUtlFillHqFdbkInfo (recpReqInfo, cell, validIdx, hqCb, nxtDlsf, pucchRecpInfo, prvHqCb, err); + prvHqCb = hqCb; + } /* end of while */ + } + + /* Check with TDD Code */ + /* FOR ACK NACK REP */ + RETVALUE(ROK); +} /* end of rgSCHTomUtlFillHqFdbkRecpReq */ +#ifdef TFU_UPGRADE +/** @brief This function handles filling of SR reception request to + * PHY. + * + * @details + * + * Function: + * + * Processing steps: + * + * @param [out] TfuRecpReqInfo *recpReqInfo + * @param [in] RgSchCellCb *cell + * @param [out] RgSchErrInfo *err + * @return S16 + * -# ROK + * -# RFAILED + */ +#ifdef ANSI +PRIVATE S16 rgSCHTomUtlFillSrRecpReq +( + TfuRecpReqInfo *recpReqInfo, + RgSchCellCb *cell, + U16 validIdx, + RgSchErrInfo *err + ) +#else +PRIVATE S16 rgSCHTomUtlFillSrRecpReq (recpReqInfo, cell, validIdx, err) + TfuRecpReqInfo *recpReqInfo; + RgSchCellCb *cell; + U16 validIdx; + RgSchErrInfo *err; +#endif +{ + CmLList *node; + TfuUeRecpReqInfo *pucchRecpInfo; + S16 ret; + + RgSchUeCb *ue; + Bool isAddToLst; +#ifdef LTEMAC_SPS + RgSchCmnUlUeSpsInfo *ulSpsUe = NULL; +#endif + + + TRC2(rgSCHTomUtlFillSrRecpReq); + + isAddToLst = FALSE; + + node = cell->pCqiSrsSrLst[validIdx].srLst.first; + while(node) + { + ue = (RgSchUeCb *)(node->node); + /* Fix: ccpu00124011: Fix for missing reception request for UE with same offset */ + node = node->next; + if(ue == NULLP) + { + continue; + } + if ((ret = rgSCHUtlGetEventMem((Ptr *)&pucchRecpInfo, + sizeof(TfuUeRecpReqInfo),&(recpReqInfo->memCp))) != ROK) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,"Unable to Allocate " + "TfuUeRecpReqInfo for cell RNTI:%d",ue->ueId); + err->errCause = RGSCHERR_TOM_MEM_EXHAUST; + RETVALUE(ret); + } +#ifdef TFU_ALLOC_EVENT_NO_INIT + cmMemset((U8 *)&pucchRecpInfo->t.pucchRecpReq, 0, sizeof(TfuUePucchRecpReq)); + pucchRecpInfo->type = TFU_RECP_REQ_PUCCH; +#endif + /*Fill SR params*/ + + +#ifdef LTEMAC_SPS + /* Should we check for Rel8 and above??? + * Dont send SR recp req if logicalChannelSR-Mask enabled and UL SPS is + * active*/ + ulSpsUe = RG_SCH_CMN_GET_UL_SPS_UE(ue, cell); + /* Avoiding check for ulSpsEnabled as isUlSpsActv FALSE if sps is not enabled*/ + if((ue->ul.ulSpsCfg.isLcSRMaskEnab) && + (ulSpsUe->isUlSpsActv)) + { + rgSCHTomUtlMoveSrNxtOccasion(cell, ue); + continue; + } +#endif + + pucchRecpInfo->rnti = ue->ueId; + pucchRecpInfo->t.pucchRecpReq.srInfo.n1PucchIdx = + ue->srCb.srCfg.srSetup.srResIdx; + pucchRecpInfo->t.pucchRecpReq.uciInfo = TFU_PUCCH_SR; + rgSCHTomUtlMoveSrNxtOccasion(cell, ue); + rgSCHTomUtlFillCqiSrsWithSr(cell, ue, recpReqInfo, + pucchRecpInfo, validIdx); +#ifdef EMTC_ENABLE + isAddToLst = rgSCHEmtcAddRecpInfoToLst(NULLP,recpReqInfo, pucchRecpInfo,ue->isEmtcUe); +#endif + if(!isAddToLst) + { + cmLListAdd2Tail(&recpReqInfo->ueRecpReqLst, &(pucchRecpInfo->lnk)); + } + pucchRecpInfo->lnk.node = (PTR)pucchRecpInfo; + } + RETVALUE(ROK); +}/* end of rgSCHTomUtlFillSrRecpReq */ + + +/** @brief This function tells will the UE has a periodic CQI/PMI/RI + * reporting + * + * @details + * + * Function: + * + * Processing steps: + * + * @param [in] RgSchUeCb *ue + * @param [out] Bool *willueRprtCqiRi + * @return S16 + * -# ROK + * -# RFAILED + */ + +#ifdef ANSI +PRIVATE S16 rgSCHTomUtlWillUeRprtCqiRi +( + RgSchUeCb *ue, + Bool *willueRprtCqiRi + ) +#else +PRIVATE S16 rgSCHTomUtlWillUeRprtCqiRi ( ue, willueRprtCqiRi) + RgSchUeCb *ue; + Bool *willueRprtCqiRi; +#endif +{ + TRC2(rgSCHTomUtlWillUeRprtCqiRi); + + /* Intialising Reporting probability as TRUE */ + *willueRprtCqiRi = TRUE; + + /* Checking the cases in which UE will not report CQIPMI/RI */ + if(ue->isDrxEnabled && ue->drxCb) + { +#ifdef LTEMAC_R9 + if(ue->drxCb->cqiMask.pres && ue->drxCb->cqiMask.val == RGR_DRX_SETUP) + {/*cqiMask is setup by upper layers */ + if((ue->drxCb->drxUlInactvMask & RG_SCH_DRX_ONDUR_BITMASK) == + RG_SCH_DRX_ONDUR_BITMASK) + {/*onDuration NOT running, do not expect cqi/pmi/ri*/ + *willueRprtCqiRi = FALSE; + } + RETVALUE(ROK); + } +#endif /*end of LTEMAC_R9*/ + /* ccpu00134258: Fix for CQI DRX issue*/ + if(ue->drxCb->onDurTmrLen > 2) + { + if ( !RG_SCH_DRX_UL_IS_UE_ACTIVE(ue->drxCb) ) + {/*UE is not active, do not expect cqi/pmi/ri*/ + *willueRprtCqiRi = FALSE; + } + } + }/*ue->isDrxEnabled*/ + + RETVALUE(ROK); +} /*End of rgSCHTomUtlWillUeRprtCqiRi*/ + +/** @brief This function handles filling of RI reception request to + * PHY. + * + * @details + * + * Function: + * + * Processing steps: + * + * @param [out] TfuRecpReqInfo *recpReqInfo + * @param [in] RgSchCellCb *cell + * @param [in] U16 validIdx + * @param [out] RgSchErrInfo *err + * @return S16 + * -# ROK + * -# RFAILED + */ +#ifdef ANSI +PRIVATE S16 rgSCHTomUtlFillRiRecpReq +( + TfuRecpReqInfo *recpReqInfo, + RgSchCellCb *cell, + U16 validIdx, + RgSchErrInfo *err + ) +#else +PRIVATE S16 rgSCHTomUtlFillRiRecpReq (recpReqInfo, cell, validIdx, err) + TfuRecpReqInfo *recpReqInfo; + RgSchCellCb *cell; + U16 validIdx; + RgSchErrInfo *err; +#endif +{ + CmLList *node; + TfuUeRecpReqInfo *pucchRecpInfo; + S16 ret; + RgSchUeCb *ue; + Bool willUeRprtCqi; /* Flag set due to CQI Mask + and UE inactive state (DRX) */ + RgSchUePCqiCb *riCb = NULLP; + TRC2(rgSCHTomUtlFillRiRecpReq); + + node = cell->pCqiSrsSrLst[validIdx].riLst.first; + while(node) + { + riCb = (RgSchUePCqiCb *)(node->node); + ue = riCb->servCellInfo->ue; + /* Fix: ccpu00124011: Fix for missing reception request for UE with same offset */ + node = node->next; + if(riCb->riRecpPrcsd) + { + /*ccpu00140578:: RI Proecssing is already done for this TTI + * as part of PUSCH reception process or HARQ + * Reception processing. Hence skipping this UE + * */ + riCb->riRecpPrcsd = FALSE; + continue; + } + if(riCb->riDist ==0) + { + rgSCHTomUtlWillUeRprtCqiRi(ue, &willUeRprtCqi); +#ifdef XEON_SPECIFIC_CHANGES + if(RGSCH_TIMEINFO_SAME(cell->crntTime, ue->riRecpTime)) + { + continue; + } +#endif +#ifdef LTE_ADV + if((TRUE == riCb->isRiIgnoByCollsn) + || (willUeRprtCqi == FALSE)) +#else + if(willUeRprtCqi == FALSE) +#endif + { + rgSCHTomUtlMovePriNxtOccasion(cell, ue, riCb); + continue; + } + if ((ret = rgSCHUtlGetEventMem((Ptr *)&pucchRecpInfo, + sizeof(TfuUeRecpReqInfo),&(recpReqInfo->memCp))) != ROK) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,"Unable to Allocate " + "TfuUeRecpReqInfo for cell RNTI:%d",ue->ueId); + err->errCause = RGSCHERR_TOM_MEM_EXHAUST; + RETVALUE(ret); + } +#ifdef TFU_ALLOC_EVENT_NO_INIT + cmMemset((U8 *)&pucchRecpInfo->t.pucchRecpReq, 0, sizeof(TfuUePucchRecpReq)); + pucchRecpInfo->type = TFU_RECP_REQ_PUCCH; +#endif + /*Fill RI params*/ + pucchRecpInfo->rnti = ue->ueId; + pucchRecpInfo->t.pucchRecpReq.cqiInfo.n2PucchIdx = + riCb->cqiCfg.cqiSetup.cqiPResIdx; + pucchRecpInfo->t.pucchRecpReq.cqiInfo.cqiPmiSz = riCb->riNumBits; + pucchRecpInfo->t.pucchRecpReq.uciInfo = TFU_PUCCH_CQI; + ue->rawCqiBitW[ue->cqiRiWritIdx].recvTime = recpReqInfo->timingInfo; +#ifdef LTE_ADV + ue->rawCqiBitW[ue->cqiRiWritIdx].u.pucch.sCellIdx = + riCb->servCellInfo->sCellIdx; +#endif + rgSCHTomUtlFillRiBitWidthInfo(ue); + rgSCHTomUtlMovePriNxtOccasion(cell, ue, riCb); + if (ue->nPCqiCb->nCqiTrIdx == validIdx) + { + rgSCHTomUtlMovePcqiNxtOccasion(cell, ue, ue->nPCqiCb); + } + if((ue->srsCb.nSrsTrIdx == validIdx) && (ue->srsCb.srsDist ==0)) + { + rgSCHTomUtlMoveSrsNxtOccasion(cell, ue); + } + cmLListAdd2Tail(&recpReqInfo->ueRecpReqLst, &(pucchRecpInfo->lnk)); + pucchRecpInfo->lnk.node = (PTR)pucchRecpInfo; + } + else + { + riCb->riDist--; + } + } + RETVALUE(ROK); +}/* end of rgSCHTomUtlFillRiRecpReq */ + +#ifdef RG_5GTF +/** @brief This function handles filling of 5GTF CQI-RI reception request to + * PHY. + * + * @details + * + * Function: + * + * Processing steps: + * + * @param [out] TfuRecpReqInfo *recpReqInfo + * @param [in] RgSchCellCb *cell + * @param [in] U16 validIdx + * @param [out] RgSchErrInfo *err + * @return S16 + * -# ROK + * -# RFAILED + */ +#ifdef ANSI +PRIVATE S16 rgSCHTomUtlFillCqiRiRecpReq +( + TfuRecpReqInfo *recpReqInfo, + RgSchCellCb *cell, + U16 validIdx, + RgSchErrInfo *err + ) +#else +PRIVATE S16 rgSCHTomUtlFillCqiRiRecpReq (recpReqInfo, cell, validIdx, err) + TfuRecpReqInfo *recpReqInfo; + RgSchCellCb *cell; + U16 validIdx; + RgSchErrInfo *err; +#endif +{ + TfuUeRecpReqInfo *pucchRecpInfo; + RgSchUeCb *ue = NULLP; + U16 ret; + + TRC2(rgSCHTomUtlFillCqiRiRecpReq); + + while ((ue = rgSCHDbmGetNextUeCb(cell, ue)) != NULLP) + { + if (RGSCH_TIMEINFO_SAME (recpReqInfo->timingInfo, ue->ue5gtfCb.nxtCqiRiOccn)) + { + if ((ret = rgSCHUtlGetEventMem((Ptr *)&pucchRecpInfo, + sizeof(TfuUeRecpReqInfo),&(recpReqInfo->memCp))) != ROK) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,"Unable to Allocate " + "TfuUeRecpReqInfo for cell RNTI:%d ", ue->ueId); + err->errCause = RGSCHERR_TOM_MEM_EXHAUST; + RETVALUE(ret); + } +#ifdef TFU_ALLOC_EVENT_NO_INIT + cmMemset((U8 *)&pucchRecpInfo->t.pucchRecpReq, 0, sizeof(TfuUePucchRecpReq)); + pucchRecpInfo->type = TFU_RECP_REQ_PUCCH; +#endif + pucchRecpInfo->rnti = ue->ueId; + pucchRecpInfo->t.pucchRecpReq.uciInfo = TFU_XPUCCH_UCI_INFO; + pucchRecpInfo->t.pucchRecpReq.uciPduInfo.pucchIndex = 0; + pucchRecpInfo->t.pucchRecpReq.uciPduInfo.numBits = 5; + + RG_SCH_ADD_TO_CRNT_TIME(recpReqInfo->timingInfo, ue->ue5gtfCb.nxtCqiRiOccn, + ue->ue5gtfCb.cqiRiPer); + cmLListAdd2Tail(&recpReqInfo->ueRecpReqLst, &(pucchRecpInfo->lnk)); + pucchRecpInfo->lnk.node = (PTR)pucchRecpInfo; + } + } + + RETVALUE(ROK); +}/* end of rgSCHTomUtlFillCqiRiRecpReq */ +#endif + +/** @brief This function handles filling of PCQI reception request to + * PHY. + * + * @details + * + * Function: + * + * Processing steps: + * + * @param [out] TfuRecpReqInfo *recpReqInfo + * @param [in] RgSchCellCb *cell + * @param [in] U16 validIdx + * @param [out] RgSchErrInfo *err + * @return S16 + * -# ROK + * -# RFAILED + */ +#ifdef ANSI +PRIVATE S16 rgSCHTomUtlFillPcqiRecpReq +( + TfuRecpReqInfo *recpReqInfo, + RgSchCellCb *cell, + U16 validIdx, + RgSchErrInfo *err + ) +#else +PRIVATE S16 rgSCHTomUtlFillPcqiRecpReq (recpReqInfo, cell, validIdx, err) + TfuRecpReqInfo *recpReqInfo; + RgSchCellCb *cell; + U16 validIdx; + RgSchErrInfo *err; +#endif +{ + CmLList *node; + TfuUeRecpReqInfo *pucchRecpInfo; + S16 ret; + + RgSchUeCb *ue; + U8 ri; /*RI value*/ + Bool willUeRprtCqi; /* Flag set due to CQI Mask + and UE Inactive state (DRX)*/ + U8 cqiPmiSz; + RgSchUePCqiCb *cqiCb = NULLP; + Bool isAddToLst = FALSE; + + TRC2(rgSCHTomUtlFillPcqiRecpReq); + + node = cell->pCqiSrsSrLst[validIdx].cqiLst.first; + while(node) + { + cqiCb = (RgSchUePCqiCb*)(node->node); + ue = cqiCb->servCellInfo->ue; + /* Fix: ccpu00124011: Fix for missing reception request for UE with same offset */ + node = node->next; + rgSCHTomUtlWillUeRprtCqiRi(ue, &willUeRprtCqi); +#ifdef LTE_ADV + if ((cqiCb->isCqiIgnoByCollsn == TRUE) || + (willUeRprtCqi == FALSE)) +#else + if(willUeRprtCqi == FALSE) +#endif + { + rgSCHTomUtlMovePcqiNxtOccasion(cell, ue, cqiCb); + continue; + } + + ue->rawCqiBitW[ue->cqiRiWritIdx].recvTime = recpReqInfo->timingInfo; +#ifdef LTE_ADV + ue->rawCqiBitW[ue->cqiRiWritIdx].u.pucch.sCellIdx = + cqiCb->servCellInfo->sCellIdx; +#endif + cqiPmiSz = rgSCHTomUtlFetchPcqiBitSz(ue, cell->numTxAntPorts, &ri); + if(!cqiPmiSz) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,"RNTI:%d Unable to Fill CqiPmi " + "size", ue->ueId); + continue; + } + + if ((ret = rgSCHUtlGetEventMem((Ptr *)&pucchRecpInfo, + sizeof(TfuUeRecpReqInfo),&(recpReqInfo->memCp))) != ROK) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,"Unable to Allocate " + "TfuUeRecpReqInfo for cell RNTI:%d ", ue->ueId); + err->errCause = RGSCHERR_TOM_MEM_EXHAUST; + RETVALUE(ret); + } +#ifdef TFU_ALLOC_EVENT_NO_INIT + cmMemset((U8 *)&pucchRecpInfo->t.pucchRecpReq, 0, sizeof(TfuUePucchRecpReq)); + pucchRecpInfo->type = TFU_RECP_REQ_PUCCH; +#endif + + /*Fill PCQI params*/ + pucchRecpInfo->rnti = ue->ueId; + pucchRecpInfo->t.pucchRecpReq.cqiInfo.n2PucchIdx = + cqiCb->cqiCfg.cqiSetup.cqiPResIdx; + pucchRecpInfo->t.pucchRecpReq.cqiInfo.cqiPmiSz = cqiPmiSz; + pucchRecpInfo->t.pucchRecpReq.uciInfo = TFU_PUCCH_CQI; + rgSCHTomUtlMovePcqiNxtOccasion(cell, ue, cqiCb); + if((ue->srsCb.nSrsTrIdx == validIdx) && (ue->srsCb.srsDist ==0)) + { + rgSCHTomUtlMoveSrsNxtOccasion(cell, ue); + } +#ifdef EMTC_ENABLE + isAddToLst = rgSCHEmtcAddRecpInfoToLst(NULLP,recpReqInfo, pucchRecpInfo,ue->isEmtcUe); +#endif + if(!isAddToLst) + { + cmLListAdd2Tail(&recpReqInfo->ueRecpReqLst, &(pucchRecpInfo->lnk)); + } + pucchRecpInfo->lnk.node = (PTR)pucchRecpInfo; + } + RETVALUE(ROK); +}/* end of rgSCHTomUtlFillPcqiRecpReq */ + +/** @brief This function handles filling of SRS reception request to + * PHY. + * + * @details + * + * Function: + * + * Processing steps: + * + * @param [out] TfuRecpReqInfo *recpReqInfo + * @param [in] RgSchCellCb *cell + * @param [in] U16 validIdx + * @param [out] RgSchErrInfo *err + * @return S16 + * -# ROK + * -# RFAILED + */ +#ifdef ANSI +PRIVATE S16 rgSCHTomUtlFillSrsRecpReq +( + TfuRecpReqInfo *recpReqInfo, + RgSchCellCb *cell, + U16 validIdx, + RgSchErrInfo *err + ) +#else +PRIVATE S16 rgSCHTomUtlFillSrsRecpReq (recpReqInfo, cell, validIdx, err) + TfuRecpReqInfo *recpReqInfo; + RgSchCellCb *cell; + U16 validIdx; + RgSchErrInfo *err; +#endif +{ + CmLList *node; + TfuUeRecpReqInfo *pucchRecpInfo; + S16 ret; + RgSchUeCb *ue; + + TRC2(rgSCHTomUtlFillSrsRecpReq); + + node = cell->pCqiSrsSrLst[validIdx].srsLst.first; + while(node) + { + ue = (RgSchUeCb *)(node->node); + /* Fix: ccpu00124011: Fix for missing reception request for UE with same offset */ + node = node->next; + if(ue->srsCb.srsRecpPrcsd) + { + /* ccpu00140578::SRS Proecssing is already done for this TTI + * as part of PUSCH or HARQ reception process and + * hence skipping this UE */ + ue->srsCb.srsRecpPrcsd = FALSE; + continue; + } + + if(ue->srsCb.srsDist ==0) + { + /* We need to add the recp request to be sent on the pucchANRep value. */ + if ((ret = rgSCHUtlGetEventMem((Ptr *)&pucchRecpInfo, + sizeof(TfuUeRecpReqInfo),&(recpReqInfo->memCp))) != ROK) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,"Unable to Allocate " + "TfuUeRecpReqInfo for RNTI:%d ",ue->ueId); + err->errCause = RGSCHERR_TOM_MEM_EXHAUST; + RETVALUE(ret); + } + +#ifdef TFU_ALLOC_EVENT_NO_INIT + pucchRecpInfo->type = TFU_RECP_REQ_PUCCH; +#endif + + /*Fill SRS params*/ + pucchRecpInfo->rnti = ue->ueId; + pucchRecpInfo->t.pucchRecpReq.srsInfo.srsBw = + (TfuUlSrsBwInfo)ue->srsCb.srsCfg.srsSetup.srsBw; + pucchRecpInfo->t.pucchRecpReq.srsInfo.nRrc = + ue->srsCb.srsCfg.srsSetup.fDomPosi; + pucchRecpInfo->t.pucchRecpReq.srsInfo.srsHopBw = + (TfuUlSrsHoBwInfo)ue->srsCb.srsCfg.srsSetup.srsHopBw; + pucchRecpInfo->t.pucchRecpReq.srsInfo.transComb = + ue->srsCb.srsCfg.srsSetup.txComb; + pucchRecpInfo->t.pucchRecpReq.srsInfo.srsCfgIdx = + ue->srsCb.srsCfg.srsSetup.srsCfgIdx; + pucchRecpInfo->t.pucchRecpReq.srsInfo.srsCyclicShft = + (TfuUlSrsCycShiftInfo)ue->srsCb.srsCfg.srsSetup.cycShift; + + pucchRecpInfo->t.pucchRecpReq.uciInfo = TFU_PUCCH_SRS; + rgSCHTomUtlMoveSrsNxtOccasion(cell, ue); + cmLListAdd2Tail(&recpReqInfo->ueRecpReqLst, &(pucchRecpInfo->lnk)); + pucchRecpInfo->lnk.node = (PTR)pucchRecpInfo; + } + else + { + ue->srsCb.srsDist--; + } + } + RETVALUE(ROK); +}/* end of rgSCHTomUtlFillSrsRecpReq */ +#endif +#ifndef TFU_UPGRADE +/** @brief This function handles filling of data reception requests for + * PUSCH and MSG3. + * + * @details + * + * Function: + * + * Processing steps: + * + * @param [out] TfuRecpReqInfo *recpReqInfo + * @param [in] RgSchCellCb *cell + * @param [out] RgSchErrInfo *err + * @return S16 + * -# ROK + * -# RFAILED + */ +#ifdef ANSI +PRIVATE S16 rgSCHTomUtlFillDatRecpReq +( +TfuRecpReqInfo *recpReqInfo, +RgSchCellCb *cell, +RgSchErrInfo *err +) +#else +PRIVATE S16 rgSCHTomUtlFillDatRecpReq (recpReqInfo, cell, err) +TfuRecpReqInfo *recpReqInfo; +RgSchCellCb *cell; +RgSchErrInfo *err; +#endif +{ + S16 ret; + RgSchUlAlloc *alloc; + TfuUeRecpReqInfo *datRecpInfo; + + TRC2(rgSCHTomUtlFillDatRecpReq) + + /* processing steps are + * - Run through the UL allocations going out in this subframe. + * - Run through the UL receptions expected the next subframe. + */ + alloc = rgSCHUtlFirstRcptnReq (cell); + while(alloc) + { + /* FOR ACK NACK REP */ + if (NULLP != alloc->ue) + { + /* If measuring or ackNakRep we shall not send dat RecpReq */ + if ((alloc->ue->measGapCb.isMeasuring == TRUE) || + (alloc->ue->ackNakRepCb.isAckNakRep == TRUE)) + { + alloc = rgSCHUtlNextRcptnReq (cell, alloc); + continue; + } + + } + if ((ret = rgSCHUtlGetEventMem((Ptr *)&datRecpInfo, + sizeof(TfuUeRecpReqInfo), + &(recpReqInfo->memCp))) != ROK) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,"Unable to Allocate " + "TfuUeRecpReqInfo for RNTI:%d ", alloc->ue->ueId); + err->errCause = RGSCHERR_TOM_MEM_EXHAUST; + RETVALUE(ret); + } + if (!alloc->forMsg3) + { + datRecpInfo->type = TFU_RECP_REQ_PUSCH; + rgSCHUtlAllocRcptInfo (alloc, + &datRecpInfo->rnti, + &datRecpInfo->t.puschRecpReq.mcs, + &datRecpInfo->t.puschRecpReq.rbStart, + &datRecpInfo->t.puschRecpReq.numRb, + &datRecpInfo->t.puschRecpReq.rv, + &datRecpInfo->t.puschRecpReq.size, + &datRecpInfo->t.puschRecpReq.modType, + &datRecpInfo->t.puschRecpReq.isRtx, + &datRecpInfo->t.puschRecpReq.nDmrs, + &datRecpInfo->t.puschRecpReq.ndi, + &datRecpInfo->t.puschRecpReq.harqProcId + ); + } + else + { + datRecpInfo->type = TFU_RECP_REQ_MSG3; + rgSCHUtlAllocRcptInfo (alloc, + &datRecpInfo->rnti, + &datRecpInfo->t.msg3RecpReq.mcs, + &datRecpInfo->t.msg3RecpReq.rbStart, + &datRecpInfo->t.msg3RecpReq.numRb, + /*ccpu00128993 - MOD - fix for msg3 softcombining bug*/ + &datRecpInfo->t.msg3RecpReq.rv, + &datRecpInfo->t.msg3RecpReq.size, + &datRecpInfo->t.msg3RecpReq.modType, + &datRecpInfo->t.msg3RecpReq.isRtx, + &datRecpInfo->t.msg3RecpReq.nDmrs, + &datRecpInfo->t.msg3RecpReq.ndi, + &datRecpInfo->t.msg3RecpReq.harqProcId + ); + + } + /* Other fields of datRecpInfo shall be filled + * here for new features */ + cmLListAdd2Tail(&recpReqInfo->ueRecpReqLst, &(datRecpInfo->lnk)); + datRecpInfo->lnk.node = (PTR)datRecpInfo; + + alloc = rgSCHUtlNextRcptnReq (cell, alloc); + } /* end of while */ + RETVALUE(ROK); +} /* end of rgSCHTomUtlFillDatRecpReq */ + +#else +/** @brief This function handles filling of data reception requests for + * PUSCH and MSG3. + * + * @details + * + * Function: + * + * Processing steps: + * + * @param [out] TfuRecpReqInfo *recpReqInfo + * @param [in] RgSchCellCb *cell + * @param [in] U16 validIdx + * @param [out] RgSchErrInfo *err + * @return S16 + * -# ROK + * -# RFAILED + */ +#ifdef ANSI +PRIVATE S16 rgSCHTomUtlFillDatRecpReq +( + TfuRecpReqInfo *recpReqInfo, + RgSchCellCb *cell, + U16 validIdx, + RgSchErrInfo *err + ) +#else +PRIVATE S16 rgSCHTomUtlFillDatRecpReq (recpReqInfo, cell, validIdx, err) + TfuRecpReqInfo *recpReqInfo; + RgSchCellCb *cell; + U16 validIdx; + RgSchErrInfo *err; +#endif +{ + CmLteTimingInfo dci0Time; + U8 idx; + Bool recvCtrl = TRUE; + S16 ret; + RgSchUlAlloc *alloc; + TfuUeRecpReqInfo *datRecpInfo; + + Bool hqPres; /*Set when HARQ Rec Req is present*/ + Bool isAperiodic = FALSE; /*Set when Aperiodic CQI is expected */ + U8 numUePerTti = 0; + + TRC2(rgSCHTomUtlFillDatRecpReq); + + if((0 == (recpReqInfo->timingInfo.sfn % 30)) && (0 == recpReqInfo->timingInfo.subframe)) + { + //printf("5GTF_CHECK rgSCHTomUtlFillDatRecpReq (%d : %d)\n", recpReqInfo->timingInfo.sfn, recpReqInfo->timingInfo.subframe); + } + /* processing steps are + * - Run through the UL allocations going out in this subframe. + * - Run through the UL receptions expected the next subframe. + */ + + alloc = rgSCHUtlFirstRcptnReq (cell); + while(alloc) + { + isAperiodic = FALSE; + ret = rgSCHUtlGetEventMem((Ptr *)&datRecpInfo, + sizeof(TfuUeRecpReqInfo), &(recpReqInfo->memCp)); + if(ret != ROK) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,"Unable to Allocate " + "TfuUeRecpReqInfo for RNTI:%d ", alloc->rnti); + err->errCause = RGSCHERR_TOM_MEM_EXHAUST; + RETVALUE(ret); + } +#ifdef TFU_ALLOC_EVENT_NO_INIT + datRecpInfo->t.puschRecpReq.initialNSrs.pres = FALSE; + datRecpInfo->t.puschRecpReq.initialNumRbs.pres = FALSE; +#endif + datRecpInfo->type = TFU_RECP_REQ_PUSCH; + /* ccpu00131944 - Intializing hqPres in each iteration*/ + hqPres = FALSE; + /* Check if this if for MSG3 - no scope for feedback along with it. */ + if ((FALSE == alloc->forMsg3)) + { + /* Check if any DL HARQ processes has a feedback coming at the time of + * this reception request. + */ +/* ACC-TDD */ + if(alloc->ue) + { + RGSCHDECRFRMCRNTTIME(cell->crntTime,dci0Time,(RGSCH_ULCTRL_RECP_DIST)); + + idx = (dci0Time.sfn * RGSCH_NUM_SUB_FRAMES_5G + dci0Time.subframe)% + RGSCH_ULCTRL_RECP_DIST; + datRecpInfo->t.puschRecpReq.rcpInfo = TFU_PUSCH_DATA; + datRecpInfo->rnti = alloc->rnti; + rgSCHUtlAllocRcptInfo (cell,alloc, &recpReqInfo->timingInfo, + &datRecpInfo->t.puschRecpReq.ulSchInfo); + } + } + else /*Enters for Msg3 == TRUE condition*/ + { + /* ccpu00130884 - ADD - HO case when Msg3 alloc and Cqi/Ri/SRS opportunity + * occur at same time */ + if(NULLP != alloc->ue) + { + + /* Only DATA is expected */ + datRecpInfo->t.puschRecpReq.rcpInfo = TFU_PUSCH_DATA; + datRecpInfo->rnti = alloc->rnti; + rgSCHUtlAllocRcptInfo (cell,alloc, &recpReqInfo->timingInfo, + &datRecpInfo->t.puschRecpReq.ulSchInfo); + } + } + if(alloc->ue) + { + if(datRecpInfo->t.puschRecpReq.rcpInfo != TFU_PUSCH_DATA && + datRecpInfo->t.puschRecpReq.rcpInfo != TFU_PUSCH_DATA_SRS && + isAperiodic == FALSE) + { + datRecpInfo->t.puschRecpReq.initialNumRbs.pres = TRUE; + datRecpInfo->t.puschRecpReq.initialNumRbs.val = alloc->ue->initNumRbs; + } + else + { + datRecpInfo->t.puschRecpReq.initialNumRbs.pres = FALSE; + } + } + cmLListAdd2Tail(&recpReqInfo->ueRecpReqLst, &(datRecpInfo->lnk)); + datRecpInfo->lnk.node = (PTR)datRecpInfo; + alloc = rgSCHUtlNextRcptnReq (cell, alloc); + numUePerTti++; + } /* end of while */ + + if(numUePerTti && (numUePerTti < RG_MAX_NUM_UE_PER_TTI)) + { + cell->ulNumUeSchedPerTti[numUePerTti-1]++; + gUlNumUePerTti[numUePerTti - 1]++; + } + RETVALUE(ROK); +} /* end of rgSCHTomUtlFillDatRecpReq */ +#endif +/* rg009.201. Added changes of TFU_UPGRADE */ +#ifdef TFU_UPGRADE +/*********************************************************** + * + * Func : rgSCHTomUtlFillRiBitWidthInfo + * + * + * Desc : Fills the RI BitWidth and stores it for decoding. + * + * Ret : S16 + * ROK - Success + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PUBLIC S16 rgSCHTomUtlFillRiBitWidthInfo +( + RgSchUeCb *ueCb + ) +#else +PUBLIC S16 rgSCHTomUtlFillRiBitWidthInfo(ueCb) + RgSchUeCb *ueCb; +#endif +{ + RgSchUePCqiCb *riCb = ueCb->nPRiCb; + TRC2(rgSCHTomUtlFillRiBitWidthInfo); + + if (ueCb->mimoInfo.txMode != RGR_UE_TM_3 && + ueCb->mimoInfo.txMode != RGR_UE_TM_4) + { + RETVALUE(RFAILED); + } + + ueCb->rawCqiBitW[ueCb->cqiRiWritIdx].type = TFU_RECP_REQ_PUCCH; + ueCb->rawCqiBitW[ueCb->cqiRiWritIdx].u.pucch.pucchRawCqiInfo.mode= + (TfuDlCqiPucchMode)riCb->cqiCfg.cqiSetup.prdModeEnum; + switch(ueCb->rawCqiBitW[ueCb->cqiRiWritIdx].u.pucch.pucchRawCqiInfo.mode) + { + case TFU_PUCCH_CQI_MODE10: + ueCb->rawCqiBitW[ueCb->cqiRiWritIdx].u.pucch.pucchRawCqiInfo.u.mode10Info.type = TFU_RPT_RI; + ueCb->rawCqiBitW[ueCb->cqiRiWritIdx].u.pucch.pucchRawCqiInfo.u.mode10Info.u.ri = + riCb->riNumBits; + break; + case TFU_PUCCH_CQI_MODE11: + ueCb->rawCqiBitW[ueCb->cqiRiWritIdx].u.pucch.pucchRawCqiInfo.u.mode11Info.type = TFU_RPT_RI; + ueCb->rawCqiBitW[ueCb->cqiRiWritIdx].u.pucch.pucchRawCqiInfo.u.mode11Info.u.ri = + riCb->riNumBits; + break; + case TFU_PUCCH_CQI_MODE20: + ueCb->rawCqiBitW[ueCb->cqiRiWritIdx].u.pucch.pucchRawCqiInfo.u.mode20Info.type = TFU_RPT_RI; + ueCb->rawCqiBitW[ueCb->cqiRiWritIdx].u.pucch.pucchRawCqiInfo.u.mode20Info.u.ri = + riCb->riNumBits; + break; + case TFU_PUCCH_CQI_MODE21: + ueCb->rawCqiBitW[ueCb->cqiRiWritIdx].u.pucch.pucchRawCqiInfo.u.mode21Info.type = TFU_RPT_RI; + ueCb->rawCqiBitW[ueCb->cqiRiWritIdx].u.pucch.pucchRawCqiInfo.u.mode21Info.u.ri = + riCb->riNumBits; + break; + default: + break; + } + + RG_SCH_INCR_CQIRI_INDEX(ueCb->cqiRiWritIdx); + RETVALUE(ROK); +} + +/*********************************************************** + * + * Func : rgSCHTomUtlFetchPcqiBitSz + * + * + * Desc : Fetch the CQI/PMI bits for a UE based on the mode, periodicity. + * + * Ret : U8 + * ROK - Success + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PUBLIC U8 rgSCHTomUtlFetchPcqiBitSz +( + RgSchUeCb *ueCb, + U8 numTxAnt, + U8 *ri + ) +#else +PUBLIC U8 rgSCHTomUtlFetchPcqiBitSz(ueCb, numTxAnt, ri) + RgSchUeCb *ueCb; + U8 numTxAnt; + U8 *ri; +#endif +{ + U8 confRepMode; + U8 pcqiSz; + TfuCqiPucchMode10 *mode10Info; + TfuCqiPucchMode11 *mode11Info; + TfuCqiPucchMode20 *mode20Info; + TfuCqiPucchMode21 *mode21Info; + RgSchUePCqiCb *cqiCb = ueCb->nPCqiCb; + + TRC3(rgSCHTomUtlFetchPcqiBitSz); + + confRepMode = cqiCb->cqiCfg.cqiSetup.prdModeEnum; + if((ueCb->mimoInfo.txMode != RGR_UE_TM_3) && + (ueCb->mimoInfo.txMode != RGR_UE_TM_4)) + { + *ri =1; + } + else + { + *ri = cqiCb->perRiVal; + } + ueCb->rawCqiBitW[ueCb->cqiRiWritIdx].type = TFU_RECP_REQ_PUCCH; + ueCb->rawCqiBitW[ueCb->cqiRiWritIdx].u.pucch.pucchRawCqiInfo.mode= + (TfuDlCqiPucchMode)confRepMode; + switch(confRepMode) + { + case RGR_PRD_CQI_MOD10: + { + mode10Info = &ueCb->rawCqiBitW[ueCb->cqiRiWritIdx].u.pucch.pucchRawCqiInfo.u.mode10Info; + pcqiSz = 4; + mode10Info->type = TFU_RPT_CQI; + mode10Info->u.cqi = 4; + } + break; + + case RGR_PRD_CQI_MOD11: + { + mode11Info = &ueCb->rawCqiBitW[ueCb->cqiRiWritIdx].u.pucch.pucchRawCqiInfo.u.mode11Info; + mode11Info->type = TFU_RPT_CQI; + if(numTxAnt == 2) + { + if (*ri ==1) + { + pcqiSz = 6; + mode11Info->u.cqi.cqi = 4; + mode11Info->u.cqi.wideDiffCqi.pres = FALSE; + mode11Info->u.cqi.pmi = 2; + } + else + { + pcqiSz = 8; + mode11Info->u.cqi.cqi = 4; + mode11Info->u.cqi.wideDiffCqi.pres = TRUE; + mode11Info->u.cqi.wideDiffCqi.val = 3; + mode11Info->u.cqi.pmi = 1; + } + } + else if(numTxAnt == 4) + { + if (*ri ==1) + { + pcqiSz = 8; + mode11Info->u.cqi.cqi = 4; + mode11Info->u.cqi.wideDiffCqi.pres = FALSE; + mode11Info->u.cqi.pmi = 4; + } + else + { + pcqiSz = 11; + mode11Info->u.cqi.cqi = 4; + mode11Info->u.cqi.wideDiffCqi.pres = TRUE; + mode11Info->u.cqi.wideDiffCqi.val = 3; + mode11Info->u.cqi.pmi = 4; + } + } + else + { + /* This is number of antenna case 1. + * This is not applicable for Mode 1-1. + * So setting it to invalid value */ + pcqiSz = 0; + } + } + break; + + case RGR_PRD_CQI_MOD20: + { + mode20Info = &ueCb->rawCqiBitW[ueCb->cqiRiWritIdx].u.pucch.pucchRawCqiInfo.u.mode20Info; + mode20Info->type = TFU_RPT_CQI; + if(cqiCb->isWb) + { + pcqiSz = 4; + mode20Info->u.cqi.isWideband = TRUE; + mode20Info->u.cqi.u.wideCqi = 4; + } + else + { + pcqiSz = 4 + cqiCb->label; + mode20Info->u.cqi.isWideband = FALSE; + mode20Info->u.cqi.u.subCqi.cqi = 4; + mode20Info->u.cqi.u.subCqi.l = cqiCb->label; + } + } + break; + + case RGR_PRD_CQI_MOD21: + { + mode21Info = &ueCb->rawCqiBitW[ueCb->cqiRiWritIdx].u.pucch.pucchRawCqiInfo.u.mode21Info; + mode21Info->type = TFU_RPT_CQI; + //pcqiSz = rgSCHTomUtlFetchPcqiBitSzPucchMode21(ueCb, + // mode21Info, numTxAnt, ri); + } + break; + default: + pcqiSz = 0; + break; + } + + RG_SCH_INCR_CQIRI_INDEX(ueCb->cqiRiWritIdx); + RETVALUE(pcqiSz); +} + + +/*********************************************************** + * + * Func : rgSCHTomUtlPcqiSbCalcBpIdx + * + * + * Desc : Determines the BP index from the timing info + * + * Ret : S16 + * ROK - Success + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PUBLIC S16 rgSCHTomUtlPcqiSbCalcBpIdx +( + CmLteTimingInfo crntTimInfo, + RgSchUeCb *ueCb, + RgSchUePCqiCb *cqiCb + ) +#else +PUBLIC S16 rgSCHTomUtlPcqiSbCalcBpIdx(crntTimInfo, ueCb, cqiCb) + CmLteTimingInfo crntTimInfo; + RgSchUeCb *ueCb; + RgSchUePCqiCb *cqiCb; +#endif +{ + U16 tti = (crntTimInfo.sfn * RGSCH_NUM_SUB_FRAMES_5G + crntTimInfo.subframe); + U16 prdNum = tti/cqiCb->cqiPeri; + + TRC2(rgSCHTomUtlPcqiSbCalcBpIdx); + if((prdNum % cqiCb->h) == 0) + { + cqiCb->isWb = TRUE; +#ifdef LTE_ADV + cqiCb->prioLvl = RG_SCH_CQI_PRIO_LVL_1; +#endif + } + else + { + cqiCb->isWb = FALSE; + cqiCb->bpIdx = ((prdNum % cqiCb->h) - 1) % cqiCb->J; +#ifdef LTE_ADV + cqiCb->prioLvl = RG_SCH_CQI_PRIO_LVL_0; +#endif + } + RETVALUE(ROK); +} + + +/** + * @brief Function which moves PCQI, RI, SR and SRS to next periodicity + * Occasions as that needs to be done in case of Ack/Nack repetition + * reception request occasions or during Measurement Gap occasions. + * + * @details + * + * Function: rgSCHTomUtlMoveNxtOccasion + * + * Function which moves PCQI, RI, SR and SRS to next perodicity + * Occasions as that needs to be done in case of Ack/Nack repetition + * reception request occasions or during Measurement Gap occasions. + * + * Invoked by: rgSCHTomUtlFillDatRecpReq of rg_sch_tom.c + * + * Processing Steps: + * - Check whether the current Tx Instance matches with the rec req time + * - If true, then move them to their next Tx Instance + * + * @param[in] RgSchCellCb *cell, + * RgSchUeCb *ue, + * U16 validIdx + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 rgSCHTomUtlMoveNxtOccasion +( + RgSchCellCb *cell, + RgSchUeCb *ue, + U16 validIdx + ) +#else +PUBLIC S16 rgSCHTomUtlMoveNxtOccasion(cell, ue, validIdx) + RgSchCellCb *cell; + RgSchUeCb *ue; + U16 validIdx; +#endif +{ + RgSchUePCqiCb *cqiCb = ue->nPCqiCb; + RgSchUePCqiCb *riCb = ue->nPRiCb; + TRC2(rgSCHTomUtlMoveNxtOccasion); + + /* ccpu00140578::Skip the UE if already RI recpetion + * is processed in the same subframe */ + if ((riCb->nRiTrIdx == validIdx) && + (riCb->riRecpPrcsd == FALSE)) + { + if(riCb->riDist ==0) + { + rgSCHTomUtlMovePriNxtOccasion(cell, ue, riCb); + } + else + { + riCb->riDist--; + } + /* ccpu00140578:: As this UE is considered for this TTI + * Same UE should not get processed for RI reception + * or for updating th RI distance.*/ + if(riCb->nRiTrIdx == validIdx) + { + riCb->riRecpPrcsd = TRUE; + } + } + if (cqiCb->nCqiTrIdx == validIdx) + { + rgSCHTomUtlMovePcqiNxtOccasion(cell, ue, cqiCb); + } + + /* ccpu00140578::Skip the UE if SRS recpetion + * is already processed in the same subframe */ + if ((ue->srsCb.nSrsTrIdx == validIdx) && + (ue->srsCb.srsRecpPrcsd == FALSE)) + { + if(ue->srsCb.srsDist ==0) + { + rgSCHTomUtlMoveSrsNxtOccasion(cell, ue); + } + else + { + ue->srsCb.srsDist--; + } + /* ccpu00140578:: As this UE is considered for this TTI + * Same UE should not get processed for SRS reception + * or for updating th SRS distance.*/ + if(ue->srsCb.nSrsTrIdx == validIdx) + { + ue->srsCb.srsRecpPrcsd = TRUE; + } + } + if (ue->srCb.nSrTrIdx == validIdx) + { + rgSCHTomUtlMoveSrNxtOccasion(cell, ue); + } + RETVALUE(ROK); +} /* rgSCHTomUtlMoveNxtOccasion */ + + +/*********************************************************** + * + * Func : rgSCHTomPrepareAcqiRecp + * + * + * Desc : Fetch the CQI/PMI bits for a UE based on the mode and store them + * for decoding. Fill RECP request and prepare the scartchpad + * to aid decoding of Aperiodic CQI. + * + * Ret : Void + * ROK - RETVOID + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PUBLIC Void rgSCHTomPrepareAcqiRecp +( + RgSchUeCb *ueCb, + RgSchCellCb *cell, + TfuUePuschCqiRecpInfo *cqiRecpReqInfo, + U8 ccIdx + ) +#else +PUBLIC Void rgSCHTomPrepareAcqiRecp(ueCb, cell, cqiRecpReqInfo, ccIdx) + RgSchUeCb *ueCb; + RgSchCellCb *cell; + TfuUePuschCqiRecpInfo *cqiRecpReqInfo; + U8 ccIdx; +#endif +{ + U8 confRepMode; + RgSchCqiRawPuschMode12 *mode12Info; + RgSchCqiRawPuschMode20 *mode20Info; + RgSchCqiRawPuschMode22 *mode22Info; + RgSchCqiRawPuschMode30 *mode30Info; + RgSchCqiRawPuschMode31 *mode31Info; + U8 numTxAnt = cell->numTxAntPorts; + U8 sCellIdx = ueCb->cellIdToCellIdxMap[RG_SCH_CELLINDEX(cell)]; + U8 numOfCells = 0; + RgSchUeACqiCb *acqiCb = &ueCb->cellInfo[sCellIdx]->acqiCb; + + TRC2(rgSCHTomPrepareAcqiRecp); + + /* Fill TFU Recp */ + cqiRecpReqInfo->reportType = TFU_APERIODIC_CQI_TYPE; /* Aperiodic */ + if (ueCb->mimoInfo.txMode == RGR_UE_TM_3 || + ueCb->mimoInfo.txMode == RGR_UE_TM_4) + { + cqiRecpReqInfo->riSz[ccIdx].pres = TRUE; + cqiRecpReqInfo->riSz[ccIdx].val = acqiCb->riNumBits; + } + /* This flag will be rmeoved after making changes in BRDCM CL + * Sachin is doing the change + * */ +#if (defined (TENB_T2K3K_SPECIFIC_CHANGES) && defined(LTE_TDD)) + //LTE_ADV_ACQI_SUPP + cqiRecpReqInfo->cqiPmiSzR1[ccIdx] = acqiCb->cqiPmiSzR1; + cqiRecpReqInfo->cqiPmiSzRn1[ccIdx] = acqiCb->cqiPmiSzRn1; +#else + if(ueCb->nPCqiCb->perRiVal == 1) + { + cqiRecpReqInfo->cqiPmiSzR1[ccIdx] = acqiCb->cqiPmiSzR1; + } + else + { + cqiRecpReqInfo->cqiPmiSzRn1[ccIdx] = acqiCb->cqiPmiSzRn1; + } +#endif + /* Fill scratchpad to aid decoding of aper CQI upon + * reception */ + confRepMode = acqiCb->aCqiCfg.aprdModeEnum; + ueCb->rawCqiBitW[ueCb->cqiRiWritIdx].type = TFU_RECP_REQ_PUSCH; + + numOfCells = ueCb->rawCqiBitW[ueCb->cqiRiWritIdx].u.pusch.numOfCells; + + ueCb->rawCqiBitW[ueCb->cqiRiWritIdx].u.pusch.cqiBitWidth[numOfCells].\ + puschRawCqiInfo.mode = (TfuDlCqiPuschMode)confRepMode; + + ueCb->rawCqiBitW[ueCb->cqiRiWritIdx].u.pusch.cqiBitWidth[numOfCells].\ + puschRawCqiInfo.ri.pres = cqiRecpReqInfo->riSz[ccIdx].pres; + + ueCb->rawCqiBitW[ueCb->cqiRiWritIdx].u.pusch.cqiBitWidth[numOfCells].\ + puschRawCqiInfo.ri.val = cqiRecpReqInfo->riSz[ccIdx].val; + + /* Setting the sCellIdx */ + ueCb->rawCqiBitW[ueCb->cqiRiWritIdx].u.pusch.cqiBitWidth[numOfCells].\ + sCellIdx = sCellIdx; + + switch(confRepMode) + { + case RGR_APRD_CQI_MOD12: + { + mode12Info = &ueCb->rawCqiBitW[ueCb->cqiRiWritIdx].u.pusch.\ + cqiBitWidth[numOfCells].puschRawCqiInfo.u.mode12Info; + mode12Info->wideBCqiCw0 = 4; + mode12Info->r1WideBCqiCw1 = 0; + mode12Info->rg1WideBCqiCw1 = 4; + if(numTxAnt == 2) + { + mode12Info->r1TotalPmiBitLen = 2*acqiCb->N; + mode12Info->rg1TotalPmiBitLen = acqiCb->N; + } + else if(numTxAnt == 4) + { + mode12Info->r1TotalPmiBitLen = 4*acqiCb->N; + mode12Info->rg1TotalPmiBitLen = 4*acqiCb->N; + } + } + break; + + case RGR_APRD_CQI_MOD20: + { + mode20Info = &ueCb->rawCqiBitW[ueCb->cqiRiWritIdx].u.pusch.\ + cqiBitWidth[numOfCells].puschRawCqiInfo.u.mode20Info; + mode20Info->wideBCqiCw = 4; + mode20Info->subBandDiffCqi = 2; + mode20Info->posOfM = acqiCb->L; + } + break; + + case RGR_APRD_CQI_MOD22: + { + mode22Info = &ueCb->rawCqiBitW[ueCb->cqiRiWritIdx].u.pusch.\ + cqiBitWidth[numOfCells].puschRawCqiInfo.u.mode22Info; + mode22Info->wideBCqiCw0 = 4; + mode22Info->sBDiffCqiCw0 = 2; + mode22Info->r1WideBCqiCw1 = 0; + mode22Info->r1SbDiffCqiCw1 = 0; + mode22Info->rg1WideBCqiCw1 = 4; + mode22Info->rg1SbDiffCqiCw1 = 2; + mode22Info->posOfM = acqiCb->L; + if(numTxAnt == 2) + { + mode22Info->r1PmiBitLen = 4; + mode22Info->rg1PmiBitLen = 2; + } + else if(numTxAnt == 4) + { + mode22Info->r1PmiBitLen = 8; + mode22Info->rg1PmiBitLen = 8; + } + } + break; + + case RGR_APRD_CQI_MOD30: + { + mode30Info = &ueCb->rawCqiBitW[ueCb->cqiRiWritIdx].u.pusch.\ + cqiBitWidth[numOfCells].puschRawCqiInfo.u.mode30Info; + mode30Info->wideBCqiCw = 4; + mode30Info->totLenSbDiffCqi = 2*acqiCb->N; + } + break; + + case RGR_APRD_CQI_MOD31: + { + mode31Info = &ueCb->rawCqiBitW[ueCb->cqiRiWritIdx].u.pusch.\ + cqiBitWidth[numOfCells].puschRawCqiInfo.u.mode31Info; + mode31Info->wideBCqiCw0 = 4; + mode31Info->totLenSbDiffCqiCw0 = 2*acqiCb->N; + mode31Info->r1WideBCqiCw1 = 0; + mode31Info->r1TotLenSbDiffCqiCw1 =0; + mode31Info->rg1WideBCqiCw1 = 4; + mode31Info->rg1TotLenSbDiffCqiCw1 = 2*acqiCb->N; + if(numTxAnt == 2) + { + mode31Info->r1PmiBitLen = 2; + mode31Info->rg1PmiBitLen = 1; + } + else if(numTxAnt == 4) + { + mode31Info->r1PmiBitLen = 4; + mode31Info->rg1PmiBitLen = 4; + } + } + break; + default: + break; + } + RETVOID; +} + +/** + * @brief Function which handles the filling of Aperiodic CQI/RI reception + * request values + * + * @details + * + * Function: rgSCHTomUtlFillDatAperRecpReq + * + * Function which handles the filling of Aperiodic CQI/RI reception + * request values + * + * Invoked by: rgSCHTomUtlFillDatRecpReq of rg_sch_tom.c + * + * Processing Steps: + * - Fill the reception request for the data arriving on the ULSCH + * - Fill the reception request information for the Aperiodic CQI/PMI/RI + * + * @param[in] RgSchCellCb *cell, + * RgSchUlAlloc *alloc, + * TfuUeRecpReqInfo *datRecpInfo, + * CmLteTimingInfo *timeInfo, + * Bool hqPres + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 rgSCHTomUtlFillDatAperRecpReq +( + RgSchCellCb *cell, + U8 cqiReq, + RgSchUlAlloc *alloc, + TfuUeRecpReqInfo *datRecpInfo, + CmLteTimingInfo *timeInfo, + Bool hqPres, + U16 validIdx + ) +#else +PUBLIC S16 rgSCHTomUtlFillDatAperRecpReq(cell, cqiReq, alloc, datRecpInfo, timeInfo, hqPres, validIdx) + RgSchCellCb *cell; + U8 cqiReq; + RgSchUlAlloc *alloc; + TfuUeRecpReqInfo *datRecpInfo; + CmLteTimingInfo *timeInfo; + Bool hqPres; + U16 validIdx; +#endif +{ + TfuUePuschCqiRecpInfo *cqiRecpReqInfo; + RgSchUeCb *ueCb = alloc->ue; +#ifdef LTE_ADV + U8 triggerSet = 0; + U8 sIdx = 0; +#endif + TRC2(rgSCHTomUtlFillDatAperRecpReq); + + /*Fill RI Reception Params*/ + cqiRecpReqInfo = &datRecpInfo->t.puschRecpReq.cqiRiInfo; + cqiRecpReqInfo->riBetaOff = alloc->ue->ul.betaRiOffst; + cqiRecpReqInfo->cqiBetaOff = alloc->ue->ul.betaCqiOffst; + + + cqiRecpReqInfo->cCNum = 0; + ueCb->rawCqiBitW[ueCb->cqiRiWritIdx].u.pusch.numOfCells = 0; + +#ifdef LTE_ADV + rgSCHTomUtlGetTrigSet(cell, ueCb, cqiReq, &triggerSet); + for (sIdx = 0; sIdx < CM_LTE_MAX_CELLS; sIdx++) + { + /* The Aperiodic request for SCell index sIdx */ + if ((triggerSet >> (7 - sIdx)) & 0x01) + { + /* The Aperiodic request for SCell index sIdx */ + rgSCHTomPrepareAcqiRecp(ueCb, ueCb->cellInfo[sIdx]->cell, cqiRecpReqInfo, cqiRecpReqInfo->cCNum); + cqiRecpReqInfo->cCNum++; + ueCb->rawCqiBitW[ueCb->cqiRiWritIdx].u.pusch.numOfCells++; + } + } +#else + rgSCHTomPrepareAcqiRecp(ueCb, ueCb->cellInfo[0]->cell, cqiRecpReqInfo, cqiRecpReqInfo->cCNum); + ueCb->rawCqiBitW[ueCb->cqiRiWritIdx].u.pusch.numOfCells++; +#endif + + RG_SCH_INCR_CQIRI_INDEX(ueCb->cqiRiWritIdx); + + if((alloc->ue->srsCb.nSrsTrIdx == validIdx) && (alloc->ue->srsCb.srsDist ==0)) + { + rgSCHTomFillOnlySrsRecpReq(cell,alloc, datRecpInfo); + datRecpInfo->t.puschRecpReq.rcpInfo = TFU_PUSCH_DATA_CQI_SRS; + + } + if(hqPres && + (datRecpInfo->t.puschRecpReq.rcpInfo == TFU_PUSCH_DATA_CQI_SRS)) + { + datRecpInfo->t.puschRecpReq.rcpInfo = TFU_PUSCH_DATA_CQI_HARQ_SRS; + } + else if (hqPres) + { + datRecpInfo->t.puschRecpReq.rcpInfo = TFU_PUSCH_DATA_CQI_HARQ; + } + else if(datRecpInfo->t.puschRecpReq.rcpInfo != TFU_PUSCH_DATA_CQI_SRS) + { + datRecpInfo->t.puschRecpReq.rcpInfo = TFU_PUSCH_DATA_CQI; + } + datRecpInfo->rnti = alloc->rnti; + rgSCHUtlAllocRcptInfo (cell, alloc, timeInfo, + &datRecpInfo->t.puschRecpReq.ulSchInfo); + RETVALUE(ROK); +} /* rgSCHTomUtlFillDatAperRecpReq */ + + + +/** + * @brief Function which handles the filling of Periodic RI reception + * request values which arrives along with UL Data on ULSCH + * + * @details + * + * Function: rgSCHTomUtlFillDatPriRecpReq + * + * Function which handles the filling of Periodic RI reception + * request values which arrives along with UL Data on ULSCH + * + * Invoked by: rgSCHTomUtlFillDatRecpReq of rg_sch_tom.c + * + * Processing Steps: + * - Fill the reception request for the data arriving on the ULSCH + * - Fill the reception request information for the Periodic RI + * + * @param[in] RgSchCellCb *cell, + * RgSchUlAlloc *alloc, + * TfuUeRecpReqInfo *datRecpInfo, + * CmLteTimingInfo *timeInfo, + * Bool hqPres + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 rgSCHTomUtlFillDatPriRecpReq +( + RgSchCellCb *cell, + RgSchUlAlloc *alloc, + TfuUeRecpReqInfo *datRecpInfo, + CmLteTimingInfo *timeInfo, + Bool hqPres, + U16 validIdx + ) +#else +PUBLIC S16 rgSCHTomUtlFillDatPriRecpReq(cell, alloc, datRecpInfo, timeInfo, +hqPres, validIdx) + RgSchCellCb *cell; + RgSchUlAlloc *alloc; + TfuUeRecpReqInfo *datRecpInfo; + CmLteTimingInfo *timeInfo; + Bool hqPres; + U16 validIdx; +#endif +{ + TfuUePuschCqiRecpInfo *cqiRecpReqInfo; + TRC2(rgSCHTomUtlFillDatPriRecpReq); + + /*Fill RI Reception Params*/ + cqiRecpReqInfo = &datRecpInfo->t.puschRecpReq.cqiRiInfo; +#ifdef TFU_ALLOC_EVENT_NO_INIT + cqiRecpReqInfo->cqiBetaOff = 0; + /* Fill only the first RI index since Periodic can come + * only for 1 CC */ + cqiRecpReqInfo->cqiPmiSzR1[0] = 0; + cqiRecpReqInfo->cqiPmiSzRn1[0] = 0; +#endif + cqiRecpReqInfo->reportType = TFU_PERIODIC_CQI_TYPE; /* periodic */ + cqiRecpReqInfo->riBetaOff = alloc->ue->ul.betaRiOffst; + + /* Fill only the first RI index since Periodic can come + * only for 1 CC */ + cqiRecpReqInfo->cCNum = 1; + cqiRecpReqInfo->riSz[0].pres = TRUE; + cqiRecpReqInfo->riSz[0].val = alloc->ue->nPRiCb->riNumBits; + /*Other params*/ + rgSCHTomUtlFillRiBitWidthInfo(alloc->ue); + if((alloc->ue->srsCb.nSrsTrIdx == validIdx) && (alloc->ue->srsCb.srsDist ==0)) + { + rgSCHTomFillOnlySrsRecpReq(cell,alloc, datRecpInfo); + datRecpInfo->t.puschRecpReq.rcpInfo = TFU_PUSCH_DATA_CQI_SRS; + + } + if(hqPres && + (datRecpInfo->t.puschRecpReq.rcpInfo == TFU_PUSCH_DATA_CQI_SRS)) + { + datRecpInfo->t.puschRecpReq.rcpInfo = TFU_PUSCH_DATA_CQI_HARQ_SRS; + } + else if (hqPres) + { + datRecpInfo->t.puschRecpReq.rcpInfo = TFU_PUSCH_DATA_CQI_HARQ; + } + else if(datRecpInfo->t.puschRecpReq.rcpInfo != TFU_PUSCH_DATA_CQI_SRS) + { + datRecpInfo->t.puschRecpReq.rcpInfo = TFU_PUSCH_DATA_CQI; + } + datRecpInfo->rnti = alloc->rnti; + rgSCHUtlAllocRcptInfo (cell, alloc, timeInfo, + &datRecpInfo->t.puschRecpReq.ulSchInfo); + RETVALUE(ROK); +} /* rgSCHTomUtlFillDatPriRecpReq */ + + +/** + * @brief Function which handles the filling of Periodic CQI/PMI reception + * request values which arrives along with UL Data on ULSCH + * + * @details + * + * Function: rgSCHTomUtlFillDatPCqiRecpReq + * + * Function which handles the filling of Periodic CQI/PMI reception + * request values which arrives along with UL Data on ULSCH + * + * Invoked by: rgSCHTomUtlFillDatRecpReq of rg_sch_tom.c + * + * Processing Steps: + * - Fill the reception request for the data arriving on the ULSCH + * - Fill the reception request information for the Periodic CQI/PMI + * + * @param[in] RgSchCellCb *cell, + * RgSchUlAlloc *alloc, + * TfuUeRecpReqInfo *datRecpInfo, + * CmLteTimingInfo *timeInfo, + * Bool hqPres + * @return S16 + * -# ROK + * -# RFAILED + **/ + +#ifdef ANSI +PUBLIC S16 rgSCHTomUtlFillDatPCqiRecpReq +( + RgSchCellCb *cell, + RgSchUlAlloc *alloc, + TfuUeRecpReqInfo *datRecpInfo, + CmLteTimingInfo *timeInfo, + Bool hqPres, + U16 validIdx + ) +#else +PUBLIC S16 rgSCHTomUtlFillDatPCqiRecpReq(cell, alloc, datRecpInfo, + timeInfo, hqPres, validIdx) + RgSchCellCb *cell; + RgSchUlAlloc *alloc; + TfuUeRecpReqInfo *datRecpInfo; + CmLteTimingInfo *timeInfo; + Bool hqPres; + U16 validIdx; +#endif +{ + TfuUePuschCqiRecpInfo *cqiRecpReqInfo; + U8 cqiPmiSz; /*Raw CQI/PMI Size*/ + U8 ri; + + TRC2(rgSCHTomUtlFillDatPCqiRecpReq); + + + /*Fill CQI Reception Params*/ + cqiRecpReqInfo = &datRecpInfo->t.puschRecpReq.cqiRiInfo; +#ifdef TFU_ALLOC_EVENT_NO_INIT + cqiRecpReqInfo->riBetaOff = 0; +#endif + cqiRecpReqInfo->cqiBetaOff = alloc->ue->ul.betaCqiOffst; + cqiPmiSz = rgSCHTomUtlFetchPcqiBitSz(alloc->ue, cell->numTxAntPorts, &ri); + if(0 == cqiPmiSz) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,"Unable to Fill " + "CqiPmi size RNTI:%d",alloc->rnti); + RETVALUE(RFAILED); + } + + /* Fill only the first RI index since Periodic can come + * only for 1 CC */ + cqiRecpReqInfo->cCNum = 1; + cqiRecpReqInfo->reportType = TFU_PERIODIC_CQI_TYPE; /* Periodic */ + /* This flags will be removed once Sachin does changes + * in BRDCM CL */ +#if (defined (TENB_T2K3K_SPECIFIC_CHANGES) && defined(LTE_TDD)) + cqiRecpReqInfo->cqiPmiSzR1[0] = cqiPmiSz; + cqiRecpReqInfo->cqiPmiSzRn1[0] = cqiPmiSz; +#else + if (ri ==1) + { + cqiRecpReqInfo->cqiPmiSzR1[0] = cqiPmiSz; + cqiRecpReqInfo->cqiPmiSzRn1[0] = 0; + } + else + { + cqiRecpReqInfo->cqiPmiSzRn1[0] = cqiPmiSz; + cqiRecpReqInfo->cqiPmiSzR1[0] = 0; + } +#endif + cqiRecpReqInfo->riSz[0].pres = FALSE; + + if((alloc->ue->srsCb.nSrsTrIdx == validIdx) && (alloc->ue->srsCb.srsDist ==0)) + { + rgSCHTomFillOnlySrsRecpReq(cell,alloc, datRecpInfo); + datRecpInfo->t.puschRecpReq.rcpInfo = TFU_PUSCH_DATA_CQI_SRS; + } + if(hqPres && + (datRecpInfo->t.puschRecpReq.rcpInfo == TFU_PUSCH_DATA_CQI_SRS)) + { + datRecpInfo->t.puschRecpReq.rcpInfo = TFU_PUSCH_DATA_CQI_HARQ_SRS; + } + else if (hqPres) + { + datRecpInfo->t.puschRecpReq.rcpInfo = TFU_PUSCH_DATA_CQI_HARQ; + } + else if(datRecpInfo->t.puschRecpReq.rcpInfo != TFU_PUSCH_DATA_CQI_SRS) + { + datRecpInfo->t.puschRecpReq.rcpInfo = TFU_PUSCH_DATA_CQI; + } + datRecpInfo->rnti = alloc->rnti; + rgSCHUtlAllocRcptInfo (cell, alloc, timeInfo, + &datRecpInfo->t.puschRecpReq.ulSchInfo); + RETVALUE(ROK); +} /* rgSCHTomUtlFillDatPCqiRecpReq */ + +/** + * @brief Function which handles the filling of SRS reception + * request values which arrives along with UL Data on ULSCH + * + * @details + * + * Function: rgSCHTomUtlFillDatSrsRecpReq + * + * Function which handles the filling of SRS reception + * request values which arrives along with UL Data on ULSCH + * + * Invoked by: rgSCHTomUtlFillDatRecpReq of rg_sch_tom.c + * + * Processing Steps: + * - Fill the reception request for the data arriving on the ULSCH + * - Fill the reception request information for the SRS + * + * @param[in] RgSchCellCb *cell, + * RgSchUlAlloc *alloc, + * TfuUeRecpReqInfo *datRecpInfo, + * CmLteTimingInfo *timeInfo, + * Bool hqPres + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 rgSCHTomUtlFillDatSrsRecpReq +( + RgSchCellCb *cell, + RgSchUlAlloc *alloc, + TfuUeRecpReqInfo *datRecpInfo, + CmLteTimingInfo *timeInfo, + Bool hqPres + ) +#else +PUBLIC S16 rgSCHTomUtlFillDatSrsRecpReq(cell, alloc, datRecpInfo, timeInfo, + hqPres) + RgSchCellCb *cell; + RgSchUlAlloc *alloc; + TfuUeRecpReqInfo *datRecpInfo; + CmLteTimingInfo *timeInfo; + Bool hqPres; +#endif +{ + TRC2(rgSCHTomUtlFillDatSrsRecpReq); + datRecpInfo->rnti = alloc->rnti; + rgSCHTomFillOnlySrsRecpReq(cell,alloc, datRecpInfo); + if(hqPres) + { + datRecpInfo->t.puschRecpReq.rcpInfo = TFU_PUSCH_DATA_HARQ_SRS; + } + else + { + datRecpInfo->t.puschRecpReq.rcpInfo = TFU_PUSCH_DATA_SRS; + } + datRecpInfo->rnti = alloc->rnti; + rgSCHUtlAllocRcptInfo (cell, alloc, timeInfo, + &datRecpInfo->t.puschRecpReq.ulSchInfo); + RETVALUE(ROK); +} /* rgSCHTomUtlFillDatSrsRecpReq */ + +/** + * @brief Function which handles the filling of only SRS reception + * request values on ULSCH + * + * @details + * + * Function: rgSCHTomFillOnlySrsRecpReq + * + * Function which handles the filling of SRS reception + * request values which arrives along with UL Data on ULSCH + * + * Invoked by: rgSCHTomUtlFillDatSrsRecpReq of rg_sch_tom.c + * + * Processing Steps: + * - Fill the reception request for the data arriving on the ULSCH + * - Fill the reception request information for the SRS + * + * @param[in] RgSchCellCb *cell, + * RgSchUlAlloc *alloc, + * TfuUeRecpReqInfo *datRecpInfo, + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 rgSCHTomFillOnlySrsRecpReq +( + RgSchCellCb *cell, + RgSchUlAlloc *alloc, + TfuUeRecpReqInfo *datRecpInfo + ) +#else +PUBLIC S16 rgSCHTomFillOnlySrsRecpReq(cell, alloc, datRecpInfo) + RgSchCellCb *cell; + RgSchUlAlloc *alloc; + TfuUeRecpReqInfo *datRecpInfo; +#endif +{ + TfuUePuschSrsRecpInfo *srsRecpReqInfo; + TRC2(rgSCHTomFillOnlySrsRecpReq); + + srsRecpReqInfo = &datRecpInfo->t.puschRecpReq.srsInfo; + srsRecpReqInfo->srsBw = (TfuUlSrsBwInfo)alloc->ue->srsCb.srsCfg.srsSetup.srsBw; + srsRecpReqInfo->nRrc = alloc->ue->srsCb.srsCfg.srsSetup.fDomPosi; + srsRecpReqInfo->srsHopBw = (TfuUlSrsHoBwInfo)alloc->ue->srsCb.srsCfg.srsSetup.srsHopBw; + srsRecpReqInfo->transComb = alloc->ue->srsCb.srsCfg.srsSetup.txComb; + srsRecpReqInfo->srsCfgIdx = alloc->ue->srsCb.srsCfg.srsSetup.srsCfgIdx; + srsRecpReqInfo->srsCyclicShft = (TfuUlSrsCycShiftInfo)alloc->ue->srsCb.srsCfg.srsSetup.cycShift; + + /* ccpu00117050 - ADD - nSrs setting + * Refer Section 5.2.2.6 of TS 36.212 V8.5.0*/ + datRecpInfo->t.puschRecpReq.ulSchInfo.nSrs = 1; + + RETVALUE(ROK); +} /* rgSCHTomFillOnlySrsRecpReq */ + +/** + * @brief Function which handles the filling of PCQI/RI, SRS and SR + * Reception Request Information along + * with the HARQ reception Request + * + * @details + * + * Function: rgSCHTomUtlFillCqiSrSrsWithHq + * + * Function which handles the filling of PCQI/RI, SRS ans SR + * Reception Request Information along + * with the HARQ reception Request + * + * + * Invoked by: rgSCHTomUtlFillHqFdbkRecpReq & + * rgSCHTomUtlFillSfHqFdbk of rg_sch_tom.c + * + * Processing Steps: + * - Fill the reception request for the Control Info arriving on the PUCCH + * - Fill the reception request information for the SR, RI, CQI, SRS + * + * @param[in] RgSchCellCb *cell, + * TfuRecpReqInfo *recpReqInfo, + * RgSchDlHqProcCb *hqCb, + * @param[out] TfuUeRecpReqInfo *pucchRecpInfo + * @param[in] U16 validIdx + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PRIVATE S16 rgSCHTomUtlFillCqiSrSrsWithHq +( + RgSchCellCb *cell, + TfuRecpReqInfo *recpReqInfo, + RgSchUeCb *ue, + TfuUeRecpReqInfo *pucchRecpInfo, + U16 validIdx, + Bool isDatPresOnSecCell + ) +#else +PRIVATE S16 rgSCHTomUtlFillCqiSrSrsWithHq(cell, recpReqInfo, ue, + pucchRecpInfo, validIdx,isDatPresOnSecCell) +RgSchCellCb *cell; +TfuRecpReqInfo *recpReqInfo; +RgSchUeCb *ue; +TfuUeRecpReqInfo *pucchRecpInfo; +U16 validIdx; +Bool isDatPresOnSecCell; +#endif +{ + RgSchUePCqiCb *cqiCb; + RgSchUePCqiCb *riCb; + U8 ri; /*To fetch RI value*/ + Bool willUeRprtCqi; /* Flag set due to CQI Mask and + UE Inactive state (DRX)*/ + Bool willUeRprtSr = TRUE; + TfuAckNackMode hqFdbkMode; + U8 numCqiBit; + U8 totalPucchBits; + Bool dropCqi = FALSE; +#ifdef LTEMAC_SPS + RgSchCmnUlUeSpsInfo *ulSpsUe = NULL; +#endif +#ifdef EMTC_ENABLE + RgSchEmtcUeInfo *emtcUe = NULLP; +#endif + + TRC2(rgSCHTomUtlFillCqiSrSrsWithHq); + + if(ue) + { + /*Changes for PUCCH Format3 */ + hqFdbkMode = pucchRecpInfo->t.pucchRecpReq.hqInfo.hqFdbkMode; + numCqiBit = rgSCHCmnCalcPcqiBitSz (ue,cell->numTxAntPorts); + totalPucchBits = pucchRecpInfo->t.pucchRecpReq.hqInfo.hqSz + numCqiBit; + +#ifdef EMTC_ENABLE + emtcUe = RG_GET_EMTC_UE_CB(ue); +#endif + rgSCHTomUtlWillUeRprtCqiRi(ue, &willUeRprtCqi); +#ifdef EMTC_ENABLE /*VINU*/ + if (ue->isEmtcUe) + { + if((emtcUe->pucchRepNumFr1 > 1) || (emtcUe->pucchRepNumFr2 > 1)) + { + willUeRprtCqi = FALSE; + willUeRprtSr = FALSE; + } + } +#endif + if(ue->srCb.nSrTrIdx == validIdx) + { + +#ifdef LTEMAC_SPS + /* Should we check for Rel8 and above??? + * Dont send SR recp req if logicalChannelSR-Mask enabled and UL SPS is + * active*/ + ulSpsUe = RG_SCH_CMN_GET_UL_SPS_UE(ue, cell); + /* Avoiding check for ulSpsEnabled as isUlSpsActv FALSE if sps is not enabled*/ + if(!((ue->ul.ulSpsCfg.isLcSRMaskEnab) && + (ulSpsUe->isUlSpsActv))) + { +#endif + + if(willUeRprtSr) + { + /*Fill SR params*/ + pucchRecpInfo->t.pucchRecpReq.srInfo.n1PucchIdx = + ue->srCb.srCfg.srSetup.srResIdx; + pucchRecpInfo->t.pucchRecpReq.uciInfo = TFU_PUCCH_HARQ_SR; + /* FORMAT3: If SR is present it will be appended after HARQ */ + totalPucchBits = totalPucchBits + 1; + } + +#ifdef LTEMAC_SPS + } +#endif + + rgSCHTomUtlMoveSrNxtOccasion(cell, ue); + } + /* LTE_ADV:: UE will drop CSI during CSI+1BCS if data is present + * on sec cell(isDatPresOnSecCell)*/ +#ifdef LTE_TDD + if (hqFdbkMode == TFU_ACK_NACK_CHANNEL_SELECTION) +#else + if (hqFdbkMode == TFU_UCI_FORMAT_1B_CS) +#endif + { + if (isDatPresOnSecCell == TRUE) + { + dropCqi = TRUE; + } + } +#ifdef LTE_ADV +#ifndef LTE_TDD + /* Format 3 Changes : If Hq + SR + CQI bits < 22 and simultaneousAckNackAndCQI-Format3 + is enabled then CQI will be multiplexed with HQ otherwise CQI will be dropped + Spec 36.213 Sec 10.1.1 */ + else if (hqFdbkMode == TFU_UCI_FORMAT_3) + { + if ((isDatPresOnSecCell == TRUE) && + ((!ue->simulAckNackCQIFormat3) || (totalPucchBits > 22))) + { + dropCqi = TRUE; + } + } +#endif +#endif + riCb = ue->nPRiCb; + cqiCb = ue->nPCqiCb; + if(riCb->nRiTrIdx == validIdx) + { + /*ccpu00140578:: Skip the UE if the RI is already processed + * for PUSCH */ + if(riCb->riRecpPrcsd == FALSE) + { + if(riCb->riDist == 0) + { + if((riCb->cqiCfg.cqiSetup.sANCQI == TRUE) && (willUeRprtCqi == TRUE)&& + (isDatPresOnSecCell == FALSE)) + { + /*Fill RI params*/ + pucchRecpInfo->t.pucchRecpReq.cqiInfo.n2PucchIdx = + riCb->cqiCfg.cqiSetup.cqiPResIdx; + pucchRecpInfo->t.pucchRecpReq.cqiInfo.cqiPmiSz = + riCb->riNumBits; + if(pucchRecpInfo->t.pucchRecpReq.uciInfo == TFU_PUCCH_HARQ_SR) + { + pucchRecpInfo->t.pucchRecpReq.uciInfo = TFU_PUCCH_HARQ_SR_CQI; + } + else + { + pucchRecpInfo->t.pucchRecpReq.uciInfo = TFU_PUCCH_HARQ_CQI; + } + ue->rawCqiBitW[ue->cqiRiWritIdx].recvTime = recpReqInfo->timingInfo; +#ifdef LTE_ADV + ue->rawCqiBitW[ue->cqiRiWritIdx].u.pucch.sCellIdx = + ue->nPRiCb->servCellInfo->sCellIdx; +#endif + rgSCHTomUtlFillRiBitWidthInfo(ue); + if (ue->nPCqiCb->nCqiTrIdx == validIdx) + { + rgSCHTomUtlMovePcqiNxtOccasion(cell, ue, ue->nPCqiCb); + } +#ifdef CA_DBG + { + if(gF1bCsPres) + { + gRiReqCount++; + } + } + +#endif + + + + } + rgSCHTomUtlMovePriNxtOccasion(cell, ue, riCb); + } + else + { + riCb->riDist--; + } + /* Skip the UE for RI processing on PUCCH + * in the same subframe as it already processed */ + if(riCb->nRiTrIdx == validIdx) + { + /* As the new idx is same is current idx + * then PUCCH reception processing will consider + * RI also in the same subframe. To block this + * below flag is used*/ + riCb->riRecpPrcsd = TRUE; + } + } + } + else if(cqiCb->nCqiTrIdx == validIdx) + { + if((cqiCb->cqiCfg.cqiSetup.sANCQI == TRUE) && (willUeRprtCqi == TRUE)&& + (isDatPresOnSecCell == FALSE)) + { + /*Fill CQI Params*/ + pucchRecpInfo->t.pucchRecpReq.cqiInfo.n2PucchIdx = + cqiCb->cqiCfg.cqiSetup.cqiPResIdx; + + ue->rawCqiBitW[ue->cqiRiWritIdx].recvTime = recpReqInfo->timingInfo; +#ifdef LTE_ADV + ue->rawCqiBitW[ue->cqiRiWritIdx].u.pucch.sCellIdx = + cqiCb->servCellInfo->sCellIdx; +#endif + pucchRecpInfo->t.pucchRecpReq.cqiInfo.cqiPmiSz = + rgSCHTomUtlFetchPcqiBitSz(ue, cell->numTxAntPorts, &ri); + if(0 == pucchRecpInfo->t.pucchRecpReq.cqiInfo.cqiPmiSz) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,"RNTI:%d " + "Unable to Fill CqiPmi size", ue->ueId); + RETVALUE(RFAILED); + } + if(pucchRecpInfo->t.pucchRecpReq.uciInfo == TFU_PUCCH_HARQ_SR) + { + pucchRecpInfo->t.pucchRecpReq.uciInfo = TFU_PUCCH_HARQ_SR_CQI; + } + else + { + pucchRecpInfo->t.pucchRecpReq.uciInfo = TFU_PUCCH_HARQ_CQI; + } + } +#ifdef CA_DBG + { + if(gF1bCsPres) + { + gCqiReqCount++; + } + } + +#endif + + rgSCHTomUtlMovePcqiNxtOccasion(cell, ue, cqiCb); + } + if(ue->srsCb.nSrsTrIdx == validIdx) + { + /* ccpu00140578::Skip the UE for SRS reception processing + * if already done as part of PUSCH recpetion + * process*/ + if(ue->srsCb.srsRecpPrcsd == FALSE) + { + if(ue->srsCb.srsDist ==0 ) + { + if((pucchRecpInfo->t.pucchRecpReq.uciInfo != TFU_PUCCH_HARQ_CQI) + && (ue->srsCb.srsCfg.srsSetup.sANSrs) + && (isDatPresOnSecCell == FALSE)) + { + /*Fill SRS params*/ + pucchRecpInfo->t.pucchRecpReq.srsInfo.srsBw = + (TfuUlSrsBwInfo)ue->srsCb.srsCfg.srsSetup.srsBw; + pucchRecpInfo->t.pucchRecpReq.srsInfo.nRrc = + ue->srsCb.srsCfg.srsSetup.fDomPosi; + pucchRecpInfo->t.pucchRecpReq.srsInfo.srsHopBw = + (TfuUlSrsHoBwInfo)ue->srsCb.srsCfg.srsSetup.srsHopBw; + pucchRecpInfo->t.pucchRecpReq.srsInfo.transComb = + ue->srsCb.srsCfg.srsSetup.txComb; + pucchRecpInfo->t.pucchRecpReq.srsInfo.srsCfgIdx = + ue->srsCb.srsCfg.srsSetup.srsCfgIdx; + pucchRecpInfo->t.pucchRecpReq.srsInfo.srsCyclicShft = + (TfuUlSrsCycShiftInfo)ue->srsCb.srsCfg.srsSetup.cycShift; + /* ccpu00116923 - ADD - New Reception Request types for CQI and SRS with SR */ + switch(pucchRecpInfo->t.pucchRecpReq.uciInfo) + { + case TFU_PUCCH_HARQ_SR: + pucchRecpInfo->t.pucchRecpReq.uciInfo = TFU_PUCCH_HARQ_SR_SRS; + break; + case TFU_PUCCH_HARQ_SR_CQI: + pucchRecpInfo->t.pucchRecpReq.uciInfo = TFU_PUCCH_HARQ_SR_CQI_SRS; + break; + default: + pucchRecpInfo->t.pucchRecpReq.uciInfo = TFU_PUCCH_HARQ_SRS; + break; + } + } + rgSCHTomUtlMoveSrsNxtOccasion(cell, ue); + } + else + { + ue->srsCb.srsDist--; + } + /* Skip the UE for SRS processing on PUCCH + * in the same subframe as it already processed */ + if(ue->srsCb.nSrsTrIdx == validIdx) + { + /* As the new idx is same is current idx + * then PUCCH reception processing will consider + * SRS also in the same subframe. To block this + * below flag is used*/ + ue->srsCb.srsRecpPrcsd = TRUE; + } + + } + } + } + + RETVALUE(ROK); +} /* rgSCHTomUtlFillCqiSrSrsWithHq */ + +/** + * @brief Function which handles the filling of PCQI/RI, SRS + * Reception Request Information along with SR reception + * Request + * + * @details + * + * Function: rgSCHTomUtlFillCqiSrsWithSr + * + * Function which handles the filling of PCQI/RI, SRS + * Reception Request Information along + * with the SR reception Request + * + * + * Invoked by: rgSCHTomUtlFillSrRecpReq of rg_sch_tom.c + * + * Processing Steps: + * - Fill the reception request for CQI/RI, SRS if they occur + * in the same instance as of SR. + * + * @param[in] RgSchCellCb *cell, + * RgSchUeCb *ue + * TfuRecpReqInfo *recpReqInfo, + * @param[out] TfuUeRecpReqInfo *pucchRecpInfo + * @param[in] U16 validIdx + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PRIVATE S16 rgSCHTomUtlFillCqiSrsWithSr +( + RgSchCellCb *cell, + RgSchUeCb *ue, + TfuRecpReqInfo *recpReqInfo, + TfuUeRecpReqInfo *pucchRecpInfo, + U16 validIdx + ) +#else +PRIVATE S16 rgSCHTomUtlFillCqiSrsWithSr(cell, ue, recpReqInfo, + pucchRecpInfo, validIdx) +RgSchCellCb *cell; +RgSchUeCb *ue; +TfuRecpReqInfo *recpReqInfo; +TfuUeRecpReqInfo *pucchRecpInfo; +U16 validIdx; +#endif +{ + RgSchUePCqiCb *cqiCb; + RgSchUePCqiCb *riCb; + U8 ri; /*To fetch RI value*/ + Bool willUeRprtCqi; /* Flag set due to CQI Mask and + UE Inactive state (DRX)*/ + TRC2(rgSCHTomUtlFillCqiSrsWithSr); + + riCb = ue->nPRiCb; + cqiCb = ue->nPCqiCb; + rgSCHTomUtlWillUeRprtCqiRi(ue, &willUeRprtCqi); +#ifdef EMTC_ENABLE + rgSCHEmtcWillUeRptCqi(ue, &willUeRprtCqi); +#endif + if(riCb->nRiTrIdx == validIdx) + { + /*ccpu00140578:: Skip the UE if the RI is already processed + * for PUSCH */ + if(riCb->riRecpPrcsd == FALSE) + { + if(riCb->riDist == 0) + { + if(willUeRprtCqi == TRUE) + { + /*Fill RI params*/ + pucchRecpInfo->t.pucchRecpReq.cqiInfo.n2PucchIdx = + riCb->cqiCfg.cqiSetup.cqiPResIdx; + pucchRecpInfo->t.pucchRecpReq.cqiInfo.cqiPmiSz = + riCb->riNumBits; + + pucchRecpInfo->t.pucchRecpReq.uciInfo = TFU_PUCCH_SR_CQI; + ue->rawCqiBitW[ue->cqiRiWritIdx].recvTime = recpReqInfo->timingInfo; +#ifdef LTE_ADV + ue->rawCqiBitW[ue->cqiRiWritIdx].u.pucch.sCellIdx = + ue->nPRiCb->servCellInfo->sCellIdx; +#endif + rgSCHTomUtlFillRiBitWidthInfo(ue); + /* TODO:: syed Shouldn't this be done outside this if condition */ + if (cqiCb->nCqiTrIdx == validIdx) + { + rgSCHTomUtlMovePcqiNxtOccasion(cell, ue, cqiCb); + } + } + rgSCHTomUtlMovePriNxtOccasion(cell, ue, riCb); + } + else + { + riCb->riDist--; + } + if(riCb->nRiTrIdx == validIdx) + {/* Need to skip this UE during PUCCH RI recpetion process + in the current subframe */ + riCb->riRecpPrcsd = TRUE; + } + } + } + else if(cqiCb->nCqiTrIdx == validIdx) + { + if(willUeRprtCqi == TRUE) + { + /*Fill CQI Params*/ + pucchRecpInfo->t.pucchRecpReq.cqiInfo.n2PucchIdx = + cqiCb->cqiCfg.cqiSetup.cqiPResIdx; + + ue->rawCqiBitW[ue->cqiRiWritIdx].recvTime = recpReqInfo->timingInfo; + +#ifdef LTE_ADV + ue->rawCqiBitW[ue->cqiRiWritIdx].u.pucch.sCellIdx = + cqiCb->servCellInfo->sCellIdx; +#endif + pucchRecpInfo->t.pucchRecpReq.cqiInfo.cqiPmiSz = + rgSCHTomUtlFetchPcqiBitSz(ue, cell->numTxAntPorts, &ri); + if(0 == pucchRecpInfo->t.pucchRecpReq.cqiInfo.cqiPmiSz) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,"RNTI:%d" + " Unable to Fill CqiPmi size", ue->ueId); + RETVALUE(RFAILED); + } + + pucchRecpInfo->t.pucchRecpReq.uciInfo = TFU_PUCCH_SR_CQI; + } + rgSCHTomUtlMovePcqiNxtOccasion(cell, ue, cqiCb); + } + if(ue->srsCb.nSrsTrIdx == validIdx) + { + /* ccpu00140578:: Cnsider the SRS processing + * only if not done in the same TTI + * as part of PUSCH or HARQ reception process*/ + if(ue->srsCb.srsRecpPrcsd == FALSE) + { + if(ue->srsCb.srsDist ==0 ) + { + if(ue->srsCb.srsCfg.srsSetup.sANSrs) + { + /*Fill SRS params*/ + pucchRecpInfo->t.pucchRecpReq.srsInfo.srsBw = + (TfuUlSrsBwInfo)ue->srsCb.srsCfg.srsSetup.srsBw; + pucchRecpInfo->t.pucchRecpReq.srsInfo.nRrc = + ue->srsCb.srsCfg.srsSetup.fDomPosi; + pucchRecpInfo->t.pucchRecpReq.srsInfo.srsHopBw = + (TfuUlSrsHoBwInfo)ue->srsCb.srsCfg.srsSetup.srsHopBw; + pucchRecpInfo->t.pucchRecpReq.srsInfo.transComb = + ue->srsCb.srsCfg.srsSetup.txComb; + pucchRecpInfo->t.pucchRecpReq.srsInfo.srsCfgIdx = + ue->srsCb.srsCfg.srsSetup.srsCfgIdx; + pucchRecpInfo->t.pucchRecpReq.srsInfo.srsCyclicShft = + (TfuUlSrsCycShiftInfo)ue->srsCb.srsCfg.srsSetup.cycShift; + /* ccpu00116923 - ADD - New Reception Request types for CQI and + * SRS with SR */ + if(pucchRecpInfo->t.pucchRecpReq.uciInfo == TFU_PUCCH_SR_CQI) + { + pucchRecpInfo->t.pucchRecpReq.uciInfo = TFU_PUCCH_SR_CQI_SRS; + } + else + { + pucchRecpInfo->t.pucchRecpReq.uciInfo = TFU_PUCCH_SR_SRS; + } + + } + rgSCHTomUtlMoveSrsNxtOccasion(cell, ue); + } + else + { + ue->srsCb.srsDist--; + } + /* Skip the UE for SRS processing on PUCCH + * in the same subframe as it already processed */ + if(ue->srsCb.nSrsTrIdx == validIdx) + { + /* As the new idx is same is current idx + * then PUCCH reception processing will consider + * SRS also in the same subframe. To block this + * below flag is used*/ + ue->srsCb.srsRecpPrcsd = TRUE; + } + + } + } + RETVALUE(ROK); +} /* rgSCHTomUtlFillCqiSrsWithSr */ + +#endif + + +#ifdef LTE_TDD +/** @brief This function handles filling of HARQ feedback repetition + * recption request for each subframe + * + * @details + * + * Function: rgSCHTomUtlFillSfRepHqFdbk + * + * Processing steps: + * + * @param [out] TfuRecpReqInfo *recpReqInfo + * @param [in] RgSchCellCb *cell + * @param [out] RgSchErrInfo *err + * @param [in] RgSchDlSf *dlSf + * @param [in] U8 noFdbks + * @param [in] CmMemListCp *memCp + * @param [in] U8 elemIdx + * @param [in] RgSchDlSf *nxtDlsf + * @return S16 + * -# ROK + * -# RFAILED + */ +#ifdef TFU_UPGRADE +#ifdef ANSI +PRIVATE S16 rgSCHTomUtlFillSfRepHqFdbk +( + TfuRecpReqInfo *recpReqInfo, + RgSchCellCb *cellCb, + RgSchErrInfo *err, + RgSchDlSf *dlSf, + U8 noFdbks, + CmMemListCp *memCp, + U8 elemIdx, + RgSchDlSf *nxtDlsf, + U16 validIdx + ) +#else +PRIVATE S16 rgSCHTomUtlFillSfRepHqFdbk (recpReqInfo, cellCb, err, dlSf, +noFdbks, memCp, elemIdx, nxtDlsf, validIdx) + TfuRecpReqInfo *recpReqInfo; + RgSchCellCb *cellCb; + RgSchErrInfo *err; + RgSchDlSf *dlSf; + U8 noFdbks; + CmMemListCp *memCp; + U8 elemIdx; + RgSchDlSf *nxtDlsf; + U16 validIdx; +#endif +#else +#ifdef ANSI +PRIVATE S16 rgSCHTomUtlFillSfRepHqFdbk +( +TfuRecpReqInfo *recpReqInfo, +RgSchCellCb *cellCb, +RgSchErrInfo *err, +RgSchDlSf *dlSf, +U8 noFdbks, +CmMemListCp *memCp, +U8 elemIdx, +RgSchDlSf *nxtDlsf +) +#else +PRIVATE S16 rgSCHTomUtlFillSfRepHqFdbk (recpReqInfo, cellCb, err, dlSf, +noFdbks, memCp, elemIdx, nxtDlsf) + TfuRecpReqInfo *recpReqInfo; + RgSchCellCb *cellCb; + RgSchErrInfo *err; + RgSchDlSf *dlSf; + U8 noFdbks; + CmMemListCp *memCp; + U8 elemIdx; + RgSchDlSf *nxtDlsf; +#endif +#endif +{ + RgSchDlHqProcCb *hqCb; + CmLList *node; + S16 ret; + RgSchUeCb *ueCb; + TfuUeRecpReqInfo *pucchRecpInfo; +#ifdef TFU_UPGRADE + TfuUePucchHqRecpInfo *hqRecpReq; +#endif + RgSchDlHqTbCb *tbCb; + RgSchDlHqProcCb *prvHqCb = NULLP; + + TRC2(rgSCHTomUtlFillSfRepHqFdbk) + + node = dlSf->ackNakRepQ.first; + while (node) + { + tbCb = (RgSchDlHqTbCb *)(node->node); + hqCb = tbCb->hqP; + ueCb = hqCb->hqE->ue; + + if (--tbCb->fbkRecpRepCntr) + { + /* Add to next subfarme */ + /* Add this hqCb to the next dlSf's ackNakRepQ */ + cmLListAdd2Tail (&(nxtDlsf->ackNakRepQ), + &(tbCb->anRepLnk[tbCb->fbkRecpRepCntr])); + tbCb->anRepLnk[tbCb->fbkRecpRepCntr].node = (PTR)tbCb; + tbCb->crntSubfrm[tbCb->fbkRecpRepCntr] = nxtDlsf; + } + +#ifdef TFU_UPGRADE + if (hqCb->tbCnt) + { + hqCb->tbCnt--; + /* Go to the next node */ + node = node->next; + continue; + } +#endif + if ((hqCb->hqE->ue != NULLP) && + (hqCb->hqE->ue->measGapCb.isMeasuring != TRUE) + && (hqCb != prvHqCb) + ) + { + /* We need to add the recp request to be sent on the pucchANRep + * value. + */ + ret = rgSCHUtlGetEventMem((Ptr *)&pucchRecpInfo, + sizeof(TfuUeRecpReqInfo), &(recpReqInfo->memCp)); + if (ret != ROK) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cellCb->cellId,"Unable to" + "Allocate TfuUeRecpReqInfo for RNTI:%d ", ueCb->ueId); + err->errCause = RGSCHERR_TOM_MEM_EXHAUST; + RETVALUE(ret); + } + pucchRecpInfo->rnti = ueCb->ueId; +#ifndef TFU_UPGRADE + pucchRecpInfo->t.pucchRecpReq.type = TFU_UCI_HARQ; +#else + pucchRecpInfo->type = TFU_RECP_REQ_PUCCH; +#endif + + /* FOR repetition Feedback shall come on n1PucchAnRep Configured per + * UE. + */ +#ifndef TFU_UPGRADE + pucchRecpInfo->t.pucchRecpReq.hqType = TFU_HQ_RECP_REQ_N1PUCCH; + pucchRecpInfo->t.pucchRecpReq.t.n1Pucch = ueCb->ackNakRepCb.pucchRes; +#else + pucchRecpInfo->t.pucchRecpReq.uciInfo = TFU_PUCCH_HARQ; + hqRecpReq = &(pucchRecpInfo->t.pucchRecpReq.hqInfo); + /* ACK NACK rep works only in bundling mode . */ + hqRecpReq->hqFdbkMode = (TfuAckNackMode)RGR_TDD_ACKNACK_MODE_BUNDL; + if ((hqCb->hqPSfLnk.node != NULLP) && + (hqCb->hqPSfLnk.node != NULLP)) + { + + hqRecpReq->hqSz = 2; + } + else + { + hqRecpReq->hqSz = 1; + } + hqRecpReq->pucchResCnt = 1; + hqRecpReq->hqRes[0] = ueCb->ackNakRepCb.pucchRes; +#endif + cmLListAdd2Tail(&recpReqInfo->ueRecpReqLst, &(pucchRecpInfo->lnk)); + pucchRecpInfo->lnk.node = (PTR)pucchRecpInfo; + } + /* In a given dlSf, if there is 2 TBs context + * stored for a given harq, then they are added + * adjacent to each other in the subframe. To avoid + * adding duplicate recpnInfo for each TB, store this + * hqCb in prvHqCb. If nextHqCb is same as prvHqCb then + * do not add reception req info.*/ + prvHqCb = hqCb; +#ifdef TFU_UPGRADE + RGSCH_NULL_CHECK(cellCb->instIdx, hqCb->hqE->ue); + rgSCHTomUtlMoveNxtOccasion(cellCb, hqCb->hqE->ue, validIdx); +#endif + /* Go to the next node */ + node = node->next; + } + + RETVALUE(ROK); +} + +/** @brief This function handles filling of HARQ feedback recption request + * for each subframe + * + * @details + * + * Function: rgSCHTomUtlFillSfHqFdbkInfo + * + * Processing steps: + * + * @param [out] TfuRecpReqInfo *recpReqInfo + * @param [in] RgSchCellCb *cell + * @param [out] RgSchErrInfo *err + * @param [in] RgSchDlSf *dlSf + * @param [in] U8 noFdbks + * @param [in] CmMemListCp *memCp + * @param [in] U8 elemIdx + * @param [in] RgSchDlSf *nxtDlsf +* @param [in] U16 validIdx; + * @return S16 + * -# ROK + * -# RFAILED + */ +#ifdef TFU_UPGRADE +#ifdef ANSI +PRIVATE S16 rgSCHTomUtlFillSfHqFdbkInfo +( + TfuRecpReqInfo *recpReqInfo, + RgSchCellCb *cellCb, + RgSchErrInfo *err, + RgSchDlSf *dlSf, + U8 noFdbks, + CmMemListCp *memCp, + U8 elemIdx, + RgSchDlSf *nxtDlsf, + U16 validIdx, + RgSchDlHqProcCb *hqCb, + RgSchUePucchRecpInfo *pucchInfo, + Bool alloc, + RgSchDlHqProcCb *prvHqCb + ) +#else +PRIVATE S16 rgSCHTomUtlFillSfHqFdbkInfo (recpReqInfo, cellCb, err, dlSf, + noFdbks, memCp, elemIdx, nxtDlsf, validIdx, hqCb, pucchInfo, alloc, prvHqCb) +TfuRecpReqInfo *recpReqInfo; +RgSchCellCb *cellCb; +RgSchErrInfo *err; +RgSchDlSf *dlSf; +U8 noFdbks; +CmMemListCp *memCp; +U8 elemIdx; +RgSchDlSf *nxtDlsf; +U16 validIdx; +RgSchDlHqProcCb *hqCb; +RgSchUePucchRecpInfo *pucchInfo; +Bool alloc; +RgSchDlHqProcCb *prvHqCb; +#endif +#else +#ifdef ANSI +PRIVATE S16 rgSCHTomUtlFillSfHqFdbkInfo +( + TfuRecpReqInfo *recpReqInfo, + RgSchCellCb *cellCb, + RgSchErrInfo *err, + RgSchDlSf *dlSf, + U8 noFdbks, + CmMemListCp *memCp, + U8 elemIdx, + RgSchDlSf *nxtDlsf, + RgSchDlHqProcCb *hqCb, + RgSchUePucchRecpInfo *pucchInfo, + Bool alloc, + RgSchDlHqProcCb *prvHqCb + ) +#else +PRIVATE S16 rgSCHTomUtlFillSfHqFdbkInfo (recpReqInfo, cellCb, err, dlSf, + noFdbks, memCp, elemIdx, nxtDlsf, hqCb, pucchInfo, alloc, prvHqCb) +TfuRecpReqInfo *recpReqInfo; +RgSchCellCb *cellCb; +RgSchErrInfo *err; +RgSchDlSf *dlSf; +U8 noFdbks; +CmMemListCp *memCp; +U8 elemIdx; +RgSchDlSf *nxtDlsf; +RgSchDlHqProcCb *hqCb; +RgSchUePucchRecpInfo *pucchInfo; +Bool alloc; +RgSchDlHqProcCb *prvHqCb; +#endif +#endif +{ + S16 ret; + RgSchUeCb *ueCb = hqCb->hqE->ue; +#ifndef TFU_UPGRADE + CmLteTimingInfo futTime; + RgSchTddANInfo *anInfo; +#else +#endif + RgrTddAckNackMode ackNackMode; + RgSchDlHqTbCb *tbCb; + CmLteRnti rnti; + U8 hqSz = 0; + U32 idx = 0; + + TRC2(rgSCHTomUtlFillSfHqFdbkInfo) + +#ifndef TFU_UPGRADE + RG_SCH_ADD_TO_CRNT_TIME(cellCb->crntTime, futTime, TFU_RECPREQ_DLDELTA); +#endif + + + for (idx = 0 ;idx < 2; idx++) + { + if (HQ_TB_WAITING == hqCb->tbInfo[idx].state) + { + + tbCb = &hqCb->tbInfo[idx]; + if (ueCb) + { + rnti = ueCb->ueId; + ackNackMode = ueCb->dl.ackNackMode; +#ifndef TFU_UPGRADE + if(ackNackMode == RGR_TDD_ACKNACK_MODE_BUNDL) + { + anInfo = rgSCHUtlGetUeANFdbkInfo(ueCb, &futTime); + /* Only the last scheduled TB for the UE is for HARQ + * ACK/NACK reception in Bundling case */ + if((anInfo == NULLP) || + (anInfo->latestMIdx != dlSf->dlFdbkInfo.m)) + { + RETVALUE(ROK); + } + } + else + { + /* Get the TFU reception request pointer, if present */ + cmHashListFind(&cellCb->ueTfuPendLst, (U8*) &ueCb->ueId, + sizeof(ueCb->ueId), 0, (PTR *) &pucchInfo); + } +#else + /* For upgrade we shall use the existing logic of pending list. */ + cmHashListFind(&cellCb->ueTfuPendLst, (U8*) &ueCb->ueId, + sizeof(ueCb->ueId), 0, (PTR *) &pucchInfo); +#endif + } + else if(hqCb->hqE->raCb != NULLP) + { + /* For RACH it is set to Bundling */ + ackNackMode = RGR_TDD_ACKNACK_MODE_BUNDL; + rnti = hqCb->hqE->raCb->tmpCrnti; + } + else + { + RETVALUE(ROK); + } + + /* Do not proceed if PUSCH + reception req is already filled*/ +#ifdef TFU_UPGRADE + if (hqCb->tbCnt) + { + hqCb->tbCnt--; + /* Go to the next node */ + continue; + } +#endif + if(((ueCb == NULLP) || (ueCb->measGapCb.isMeasuring != TRUE)) + &&(hqCb != prvHqCb) + ) + { + TknU16 n1PucchTkn = {FALSE, 0}; + RgSchPdcch *pdcch; + U8 tbIndx; + pdcch = tbCb->hqP->pdcch; +#ifdef LTEMAC_SPS + n1PucchTkn = hqCb->spsN1PucchRes; +#endif + for (tbIndx = 0; tbIndx < TFU_MAX_TB; tbIndx++) + { + if (hqCb->tbInfo[tbIndx].state == HQ_TB_WAITING && + (RGSCH_TIMEINFO_SAME(hqCb->tbInfo[tbIndx].fdbkTime, + recpReqInfo->timingInfo))) + { + hqSz++; + hqCb->tbInfo[tbIndx].pucchFdbkIdx = hqCb->ulDai; + } + } + ret = rgSCHTomUtlFillSfHqFdbkForOneUe(hqCb,recpReqInfo, cellCb, err, dlSf, noFdbks, + memCp, elemIdx, nxtDlsf, rnti, ackNackMode, &pucchInfo, pdcch, + n1PucchTkn, &alloc, hqSz); + if (ret != ROK) + { + RETVALUE(ret); + } + /* TODO:: In case of F1BCS and CSI in same subframe + * UE shall drop the CSI if there was at least one + * PDSCH transmission in any of the DL subframe + * mapping to this UL subframe + * */ +#ifdef TFU_UPGRADE + rgSCHTomUtlFillCqiSrSrsWithHq(cellCb,recpReqInfo, hqCb->hqE->ue, + pucchInfo->pucchRecpInfo, validIdx,FALSE); +#ifdef LTE_ADV + if((hqCb->hqE->ue) && + (hqCb->hqE->ue->uciFrmtTyp == RG_SCH_UCI_FORMAT1B_CS)) + { + + if(RG_SCH_IS_CELL_SEC(hqCb->hqE->ue,hqCb->hqE->cell)) + { + switch(pucchInfo->pucchRecpInfo->t.pucchRecpReq.uciInfo) + { + case TFU_PUCCH_HARQ_SR_CQI: + pucchInfo->pucchRecpInfo->t.pucchRecpReq.uciInfo = TFU_PUCCH_HARQ_SR; + RG_SCH_DECR_CQIRI_INDEX(ueCb->cqiRiWritIdx); + break; + case TFU_PUCCH_HARQ_CQI: + pucchInfo->pucchRecpInfo->t.pucchRecpReq.uciInfo = TFU_PUCCH_HARQ; + RG_SCH_DECR_CQIRI_INDEX(ueCb->cqiRiWritIdx); + break; + case TFU_PUCCH_HARQ_SR_CQI_SRS: + pucchInfo->pucchRecpInfo->t.pucchRecpReq.uciInfo = TFU_PUCCH_HARQ_SR_SRS; + RG_SCH_DECR_CQIRI_INDEX(ueCb->cqiRiWritIdx); + break; + case TFU_PUCCH_HARQ_SR_SRS: + pucchInfo->pucchRecpInfo->t.pucchRecpReq.uciInfo = TFU_PUCCH_HARQ_SR; + break; + case TFU_PUCCH_HARQ_SRS: + pucchInfo->pucchRecpInfo->t.pucchRecpReq.uciInfo = TFU_PUCCH_HARQ; + break; + default: + break; + } + } + } +#endif + +#endif + + /* TODO antz - pushing the following code (under TFU_UPGRADE) + * into the above function (...ForOneUe) did not work (caused + * two additional TCs to fail). Don't know why. If this + * is done later, make sure that the code branch + * for relPdcch (later in this func) is also modified appropriately. + */ + /* Now add to the recp request or pending list */ + //if((elemIdx != (noFdbks - 1))) + { + cmHashListInsert(&cellCb->ueTfuPendLst, (PTR) pucchInfo, + (U8 *)&rnti ,(U16) sizeof(CmLteRnti)); + alloc = FALSE; + } + + } /* If measuring */ + /* Go to the next node */ + if ((tbCb->fbkRecpRepCntr) && (--tbCb->fbkRecpRepCntr)) + { + /* Add to next subfarme */ + /* Add this hqCb to the next dlSf's ackNakRepQ */ + cmLListAdd2Tail (&(nxtDlsf->ackNakRepQ), + &(tbCb->anRepLnk[tbCb->fbkRecpRepCntr])); + tbCb->anRepLnk[tbCb->fbkRecpRepCntr].node = (PTR)tbCb; + tbCb->crntSubfrm[tbCb->fbkRecpRepCntr] = nxtDlsf; + } + /* In a given dlSf, if there is 2 TBs context + * stored for a given harq, then they are added + * adjacent to each other in the subframe. To avoid + * adding duplicate recpnInfo for each TB, store this + * hqCb in prvHqCb. If nextHqCb is same as prvHqCb then + * do not add reception req info.*/ + prvHqCb = hqCb; + } + } + RETVALUE(ROK); +} + +#ifdef LTE_ADV +/** @brief This function calculates the pucch resource idx + * that is to be filled in harq reception request + * + * @details + * + * Function: rgSCHTomUtlGethqRes + * + * Processing steps: + * -Calculate the pucch resource idx + * Harq Reception Request for Format 1B with + * Channel Selection + * + * @param [in] U8 noFdbks + * @param [in] RgSchDlSf *dlSf + * @param [in] RgSchPdcch *pdcch + * @param [in] RgSchCellCb *cellCb + * @param [out]U16 *hqRes + * @return void + */ +#ifdef ANSI +PRIVATE Void rgSCHTomUtlGethqRes +( +U8 noFdbks, +RgSchDlSf *dlSf, +RgSchPdcch *pdcch, +RgSchCellCb *cellCb, +U16 *hqRes +) +#else +PRIVATE Void rgSCHTomUtlGethqRes(noFdbks,dlSf,pdcch,cellCb,hqRes) +U8 noFdbks; +RgSchDlSf *dlSf; +RgSchPdcch *pdcch; +RgSchCellCb *cellCb; +U16 *hqRes; +#endif +{ + U8 M; + U8 P; + U8 m; + U8 nP; + U8 nPlusOne; + U8 nCce; + + M = noFdbks; + m = dlSf->dlFdbkInfo.m; + nCce = pdcch->nCce; + P = rgSCHCmnGetPValFrmCCE(cellCb, nCce); + nP = cellCb->rgSchTddNpValTbl[P]; + nPlusOne = cellCb->rgSchTddNpValTbl[P + 1]; + *hqRes = (M - m - 1)* nP + (m * nPlusOne) + pdcch->nCce + + cellCb->pucchCfg.n1PucchAn; + + RETVOID; +} + +/** @brief This function fills the harq reception request for + * TDD in case of Fomat 1B with CS for M=1 + * + * @details + * + * Function: rgSCHTomUtlFillSfHqFdbkForFrmt1BCSForM1 + * + * Processing steps: + * -Fill Harq Reception Request for Format 1B with + * Channel Selection + * + * @param [in] RgSchDlHqProcCb *hqCb + * @param [in] TfuUePucchRecpReq *hqRecpReq + * @param [in] U8 noFdbks + * @param [in] RgSchDlSf *dlSf + * @param [in] RgSchPdcch *pdcch + * @param [in] RgSchCellCb *cellCb + * @return void + */ +#ifdef ANSI +PRIVATE Void rgSCHTomUtlFillSfHqFdbkForFrmt1BCSForM1 +( + RgSchDlHqProcCb *hqCb, + TfuUePucchRecpReq *hqRecpReq, + U8 noFdbks, + RgSchDlSf *dlSf, + RgSchPdcch *pdcch, + RgSchCellCb *cellCb +) +#else +PRIVATE Void rgSCHTomUtlFillSfHqFdbkForFrmt1BCSForM1(hqCb, hqRecpReq, + noFdbks,dlSf,pdcch,cellCb) + RgSchDlHqProcCb *hqCb; + TfuUePucchRecpReq *hqRecpReq; + U8 noFdbks; + RgSchDlSf *dlSf; + RgSchPdcch *pdcch; + RgSchCellCb *cellCb; +#endif +{ + RgSchUeCb *ue = NULLP; + Bool isCellSec = FALSE; + U16 hqRes; + + /*ccpu00147920: UeCb is NULL for SPS activation*/ + if(pdcch && pdcch->ue) + {/* SPS Release pdcch or dynamic data */ + ue = pdcch->ue; + }else + {/* SPS occasion */ +#ifdef ERRCLS_KW + if(hqCb == NULLP) + { + /* This is not supposed to happen + * Error case. hqCB has to be ter + * when pdcch is present . Adding + * if check bcs of kwork*/ + RETVOID; + } +#endif + ue = hqCb->hqE->ue; + } + + if((hqCb != NULLP) && + (RG_SCH_IS_CELL_SEC(ue,hqCb->hqE->cell))) + { + isCellSec = TRUE; + } + + switch(ue->f1bCsAVal) + { + case RG_SCH_A_VAL_2: + /* harq(0) is primary harq(1) is secondary) */ + if(isCellSec) + { + hqRecpReq->hqInfo.hqRes[1] = ue->n1PucchF1bResCb. + cw1N1Res[hqCb->tpc].n1PucchIdx; + } + else/* primary cell */ + { +#ifdef LTEMAC_SPS + /* hqCb will be null in case of sps rel pdcch */ + if ((hqCb) && hqCb->spsN1PucchRes.pres) + {/* SPS occasion or dyn sched*/ + hqRecpReq->hqInfo.hqRes[0] = hqCb->spsN1PucchRes.val; + } + else +#endif /* LTEMAC_SPS */ + {/* dyn data or sps release */ +#ifdef ERRCLS_KW + if(pdcch == NULLP) + { + /* This is not supposed to happen + * Error case. hqCB has to be ter + * when pdcch is present . Adding + * if check bcs of kwork*/ + RETVOID; + } +#endif + + rgSCHTomUtlGethqRes(noFdbks,dlSf,pdcch,cellCb,&hqRes); + hqRecpReq->hqInfo.hqRes[0] = hqRes; + } + } + break; + case RG_SCH_A_VAL_3: + { + /* Serving cell in mimo mode should be + * in 0 and 1 and the serving cell in siso + * mode should be in 2 indices */ + if(isCellSec) + { + U8 servCellIdx = rgSchUtlGetServCellIdx(hqCb->hqE->cell->instIdx, + hqCb->hqE->cell->cellId, + hqCb->hqE->ue); + + if(rgSCHUtlGetMaxTbSupp(ue->cellInfo[servCellIdx]->txMode.txModeEnum) > 1) + {/* Sec cell is in mimo mode, use 0 and 1 */ + hqRecpReq->hqInfo.hqRes[0] = + ue->n1PucchF1bResCb.cw1N1Res[hqCb->tpc].n1PucchIdx; + hqRecpReq->hqInfo.hqRes[1] = + ue->n1PucchF1bResCb.cw2N1Res[hqCb->tpc].n1PucchIdx; + } + else + {/* Sec cell is in siso mode, use 2 */ + hqRecpReq->hqInfo.hqRes[2] = + ue->n1PucchF1bResCb.cw1N1Res[hqCb->tpc].n1PucchIdx; + } + } + else + {/* primary cell hq */ + + if(rgSCHUtlGetMaxTbSupp(ue->mimoInfo.txMode) > 1) + {/* prim cell is in mimo mode, use 0 and 1 */ +#ifdef LTEMAC_SPS + if (hqCb && hqCb->spsN1PucchRes.pres) + {/* Not sps release */ + hqRecpReq->hqInfo.hqRes[0] = hqCb->spsN1PucchRes.val; + } + else +#endif /* LTEMAC_SPS */ + {/* sps rel or dyn */ +#ifdef ERRCLS_KW + if(pdcch == NULLP) + { + /* This is not supposed to happen + * Error case. hqCB has to be ter + * when pdcch is present . Adding + * if check bcs of kwork*/ + RETVOID; + } +#endif + + rgSCHTomUtlGethqRes(noFdbks,dlSf,pdcch,cellCb,&hqRes); + hqRecpReq->hqInfo.hqRes[0] = hqRes; + hqRecpReq->hqInfo.hqRes[1] = hqRes + 1; + } + } + else + {/* prim cell is in siso mode use 2 */ +#ifdef LTEMAC_SPS + /* Consider sps occasions */ + if (hqCb && hqCb->spsN1PucchRes.pres) + {/* Not sps release */ + hqRecpReq->hqInfo.hqRes[2] = hqCb->spsN1PucchRes.val; + } + else +#endif /* LTEMAC_SPS */ + { +#ifdef ERRCLS_KW + if(pdcch == NULLP) + { + /* This is not supposed to happen + * Error case. hqCB has to be ter + * when pdcch is present . Adding + * if check bcs of kwork*/ + RETVOID; + } +#endif + + rgSCHTomUtlGethqRes(noFdbks,dlSf,pdcch,cellCb,&hqRes); + hqRecpReq->hqInfo.hqRes[2] = hqRes; + } + } + } + } + break; + case RG_SCH_A_VAL_4: + {/* Both the serv cells are in mimo mode */ + if(isCellSec) + {/* 2 and 3 for sec cell */ + hqRecpReq->hqInfo.hqRes[2] = + ue->n1PucchF1bResCb.cw1N1Res[hqCb->tpc].n1PucchIdx; + hqRecpReq->hqInfo.hqRes[3] = + ue->n1PucchF1bResCb.cw2N1Res[hqCb->tpc].n1PucchIdx; + } + else/* primary cell */ + {/* 0 and 1 are for primary cell */ +#ifdef LTEMAC_SPS + if (hqCb && hqCb->spsN1PucchRes.pres) + {/* Not sps release */ + hqRecpReq->hqInfo.hqRes[0] = hqCb->spsN1PucchRes.val; + } + else +#endif /* LTEMAC_SPS */ + { +#ifdef ERRCLS_KW + if(pdcch == NULLP) + { + /* This is not supposed to happen + * Error case. hqCB has to be ter + * when pdcch is present . Adding + * if check bcs of kwork*/ + RETVOID; + } +#endif + + rgSCHTomUtlGethqRes(noFdbks,dlSf,pdcch,cellCb,&hqRes); + hqRecpReq->hqInfo.hqRes[0] = hqRes; + hqRecpReq->hqInfo.hqRes[1] = hqRes + 1; + } + } + } + break; + default: + break; + } + RETVOID; +} + +/** @brief This function fills the harq reception request for + * TDD in case of Fomat 1B with CS for M>=2 + * + * @details + * + * Function: rgSCHTomUtlFillSfHqFdbkForFrmt1BCSForM234 + * + * Processing steps: + * -Fill Harq Reception Request for Format 1B with + * Channel Selection + * + * @param [in] RgSchDlHqProcCb *hqCb + * @param [in] TfuUePucchRecpReq *hqRecpReq + * @param [in] U8 noFdbks + * @param [in] RgSchDlSf *dlSf + * @param [in] RgSchPdcch *pdcch + * @param [in] RgSchCellCb *cellCb + * @param [in] U8 elemIdx + * @return void + */ +#ifdef ANSI +PRIVATE Void rgSCHTomUtlFillSfHqFdbkForFrmt1BCSForM234 +( + RgSchDlHqProcCb *hqCb, + TfuUePucchRecpReq *hqRecpReq, + U8 noFdbks, + RgSchDlSf *dlSf, + RgSchPdcch *pdcch, + RgSchCellCb *cellCb, + U8 elemIdx +) +#else +PRIVATE Void rgSCHTomUtlFillSfHqFdbkForFrmt1BCSForM234( + hqCb,hqRecpReq,noFdbks,dlSf,pdcch,cellCb,elemIdx) + RgSchDlHqProcCb *hqCb; + TfuUePucchRecpReq *hqRecpReq; + U8 noFdbks; + RgSchDlSf *dlSf; + RgSchPdcch *pdcch; + RgSchCellCb *cellCb; + U8 elemIdx; +#endif +{ + RgSchUeCb *ue; + Bool isCellSec = FALSE; + U16 hqRes = 0; + U8 servCellIdx; + + if(pdcch) + {/* SPS Release pdcch or dynamic data */ + ue = pdcch->ue; + }else + {/* SPS occasion */ +#ifdef ERRCLS_KW + if(hqCb == NULLP) + { + /* This is not supposed to happen + * Error case. hqCB has to be ter + * when pdcch is present . Adding + * if check bcs of kwork*/ + RETVOID; + } +#endif + ue = hqCb->hqE->ue; + } + + if((hqCb != NULLP) && (ue != NULLP) && + (RG_SCH_IS_CELL_SEC(ue,hqCb->hqE->cell))) + { + isCellSec = TRUE; + } + + if(isCellSec) + {/* Sec Cell indices are 2 and 3*/ + servCellIdx = rgSchUtlGetServCellIdx(hqCb->hqE->cell->instIdx, + hqCb->hqE->cell->cellId, + hqCb->hqE->ue); + + hqRecpReq->hqInfo.hqRes[2] = + ue->n1PucchF1bResCb.cw1N1Res[hqCb->tpc].n1PucchIdx; + + if(rgSCHUtlGetMaxTbSupp(ue->cellInfo[servCellIdx]->txMode.txModeEnum) > 1) + { + hqRecpReq->hqInfo.hqRes[3] = + ue->n1PucchF1bResCb.cw2N1Res[hqCb->tpc].n1PucchIdx; + } + } + else + {/* Primary cell indices are 0 and 1 */ + /* SPS occasions + * M > 2 if SPS occasion is present in any of the + * DL subframe in the bundle, the n1Pucch(0) is + * the SPS resource and n1Pucch(1) is the resource + * derived from pdcch with DAI = 1 + * If No SPS Occasion + * Then n1Pucch(0) is from pdcch with DAI =1 + * and n1Pucch(1) is from pdcch with DAI = 2 + * */ + + if(hqCb != NULLP) + {/* this is not sps release pdcch */ + if(hqCb->spsN1PucchRes.pres == TRUE) + {/* SPS occasion*/ + hqRes = hqCb->spsN1PucchRes.val; + } + } + + if(pdcch) + {/*Dynamic scheduling or SPS Release + Derive from pdcch */ + if(pdcch->dlDai < 3) + {/* No need to calcualte from DAI > 2 */ + rgSCHTomUtlGethqRes(noFdbks,dlSf,pdcch,cellCb,&hqRes); + } + } + + if(2 == noFdbks) + {/* M == 2 case */ + hqRecpReq->hqInfo.hqRes[elemIdx] = hqRes; + } + else + {/* Pdcch with DAI = 1 and 2 needs to be used + for resource calculation*/ + if(hqCb && hqCb->spsN1PucchRes.pres == TRUE) + {/* dyn or sps occasion */ + /* Shift the hqRes[0] if it was filled + * if there was a pdcch with DAI 1 before to this + * subframe*/ + if(hqCb->ulDai > 1) + {/* SPS occasion happened in the middle + of the bundle */ + /* shifting the non SPS resource to n1Pucch(1) */ + hqRecpReq->hqInfo.hqRes[1] = hqRecpReq->hqInfo.hqRes[0]; + } + + hqRecpReq->hqInfo.hqRes[0] = hqRes; + } +#ifdef ERRCLS_KW + else if(pdcch && pdcch->dlDai < 3) +#else + else if(pdcch->dlDai < 3) +#endif + {/* sps rel or dyn sched */ + /* hqCb wil not be present for sps release pdcch */ + if(hqCb && (pdcch->dlDai != hqCb->ulDai)) + {/* there was a SPS occasion before to this */ + if(pdcch->dlDai == 1) + { + hqRecpReq->hqInfo.hqRes[1] = hqRes; + }/* ignore the DAI 2 in this case */ + }else + {/* There was no SPS occasion before to this */ +#ifdef ERRCLS_KW + if(pdcch->dlDai) +#endif + {/* Added check to ignore kwork warning */ + hqRecpReq->hqInfo.hqRes[(pdcch->dlDai)-1] = hqRes; + } + } + } + } + } + RETVOID; +} + +/** @brief This function fills the harq reception request for + * TDD in case of Fomat 1B with CS + * + * @details + * + * Function: rgSCHTomUtlFillSfHqFdbkForFrmt1BCS + * + * Processing steps: + * -Fill Harq Reception Request for Format 1B with + * Channel Selection + * + * @param [in] RgSchDlSf *ulSf + * @param [in] RgSchCellCb *cell + * @param [out]TfuUePucchRecpReq *hqRecpReq + * @return S16 + */ +#ifdef ANSI +PRIVATE S16 rgSCHTomUtlFillSfHqFdbkForFrmt1BCS +( + RgSchDlHqProcCb *hqCb, + TfuUePucchRecpReq *hqRecpReq, + U8 noFdbks, + RgSchDlSf *dlSf, + RgSchPdcch *pdcch, + U8 elemIdx, + RgSchCellCb *cellCb +) +#else +PRIVATE S16 rgSCHTomUtlFillSfHqFdbkForFrmt1BCS(hqCb,hqRecpReq,noFdbks,dlSf,pdcch, + n1PucchTkn,elemIdx,cellCb) + RgSchDlHqProcCb *hqCb; + TfuUePucchRecpReq *hqRecpReq; + U8 noFdbks; + RgSchDlSf *dlSf; + RgSchPdcch *pdcch; + U8 elemIdx; + RgSchCellCb *cellCb; +#endif +{ + /* Update teh fdbk mode if something different is present + * in L1 API file for F1BS *//* 1 --> F1BCS */ + hqRecpReq->hqInfo.hqFdbkMode = TFU_ACK_NACK_CHANNEL_SELECTION; + + switch(noFdbks) + {/* M Value */ + case RG_SCH_M_VAL_1: + { + + rgSCHTomUtlFillSfHqFdbkForFrmt1BCSForM1(hqCb,hqRecpReq, + noFdbks,dlSf,pdcch,cellCb); + break; + } + case RG_SCH_M_VAL_2: + case RG_SCH_M_VAL_3: + case RG_SCH_M_VAL_4: + { + /* Spatial bundling will be applied */ + rgSCHTomUtlFillSfHqFdbkForFrmt1BCSForM234(hqCb,hqRecpReq, + noFdbks,dlSf,pdcch,cellCb,elemIdx); + break; + } + default: + break; + } + RETVALUE(ROK); +} +#endif + +/*********************************************************** + * + * Func : rgSCHTomUtlFillSfHqFdbkForOneUe + * + * Desc : Fill HARQ feedback info for one UE/entry + * + * Ret : ROK/RFAILED + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PRIVATE S16 rgSCHTomUtlFillSfHqFdbkForOneUe +( +RgSchDlHqProcCb *hqCb, +TfuRecpReqInfo *recpReqInfo, +RgSchCellCb *cellCb, +RgSchErrInfo *err, +RgSchDlSf *dlSf, +U8 noFdbks, +CmMemListCp *memCp, +U8 elemIdx, +RgSchDlSf *nxtDlsf, +CmLteRnti rnti, +RgrTddAckNackMode ackNackMode, +RgSchUePucchRecpInfo **pucchInfoRef, +RgSchPdcch *pdcch, +TknU16 n1PucchTkn, +Bool *allocRef, +U8 hqSz +) +#else +PRIVATE S16 rgSCHTomUtlFillSfHqFdbkForOneUe(hqCb,recpReqInfo, cellCb, err, dlSf, + noFdbks, memCp, elemIdx, nxtDlsf, rnti, ackNackMode, pucchInfoRef, + pdcch, n1PucchTkn, allocRef, hqSz) +RgSchDlHqProcCb *hqCb; +TfuRecpReqInfo *recpReqInfo; +RgSchCellCb *cellCb; +RgSchErrInfo *err; +RgSchDlSf *dlSf; +U8 noFdbks; +CmMemListCp *memCp; +U8 elemIdx; +RgSchDlSf *nxtDlsf; +CmLteRnti rnti; +RgrTddAckNackMode ackNackMode; +RgSchUePucchRecpInfo **pucchInfoRef; +RgSchPdcch *pdcch; +TknU16 n1PucchTkn; +Bool *allocRef; +U8 hqSz; +#endif +{ + RgSchUePucchRecpInfo *pucchInfo = *pucchInfoRef; + Bool alloc = FALSE; + S16 ret; + TfuUePucchRecpReq *hqRecpReq; +#ifdef TFU_UPGRADE + U8 M; + U8 P; + U8 m; + U8 nP; + U8 nPlusOne; + U16 pucchRes; + U8 resIdx; + U8 nCce; + U8 prevHqSize; +#else + U8 multCnt; +#endif +#ifdef LTEMAC_SPS + Bool isFirstFdbk = FALSE; +#endif + if(pucchInfo == NULLP) + { + if ((ret = rgSCHUtlGetEventMem((Ptr *)&pucchInfo, + sizeof(RgSchUePucchRecpInfo), memCp)) != ROK) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cellCb->cellId,"Unable to " + "Allocate TfuUeRecpReqInfo for cell RNTI:%d",rnti); + err->errCause = RGSCHERR_TOM_MEM_EXHAUST; + RETVALUE(ret); + } + alloc = TRUE; +#ifdef TFU_ALLOC_EVENT_NO_INIT + pucchInfo->hashLstEnt.hashVal = 0; + pucchInfo->hashLstEnt.keyLen = 0; + pucchInfo->hashLstEnt.key = 0; + pucchInfo->hashLstEnt.list.prev = pucchInfo->hashLstEnt.list.next = 0; +#endif + if ((ret = rgSCHUtlGetEventMem((Ptr *)&(pucchInfo->pucchRecpInfo), + sizeof(TfuUeRecpReqInfo), &(recpReqInfo->memCp))) != ROK) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cellCb->cellId,"Unable to " + "Allocate TfuUeRecpReqInfo for cell RNTI:%d",rnti); + err->errCause = RGSCHERR_TOM_MEM_EXHAUST; + RETVALUE(ret); + } + cmMemset((U8 *)pucchInfo->pucchRecpInfo->t.pucchRecpReq.hqInfo.hqRes,0xff,sizeof(U16)*TFU_MAX_HQ_RES); +#ifdef TFU_ALLOC_EVENT_NO_INIT + cmMemset((U8 *)&pucchInfo->pucchRecpInfo->t.pucchRecpReq, 0, sizeof(TfuUePucchRecpReq)); +#endif + pucchInfo->pucchRecpInfo->type = TFU_RECP_REQ_PUCCH; + pucchInfo->pucchRecpInfo->rnti = rnti; +#ifdef TFU_UPGRADE + pucchInfo->pucchRecpInfo->t.pucchRecpReq.uciInfo=TFU_PUCCH_HARQ; +#endif +#ifdef LTEMAC_SPS + isFirstFdbk = TRUE; +#endif + } + /* Fill m, M, P */ + /* Calculation of resources same for both bundling and muxing for M = 1 + * */ +#ifdef LTE_ADV + RgSchUeCb *ue = rgSCHDbmGetUeCb (cellCb, rnti); + if((ue) && (1 == ue->numSCells)) + { + if(ue->uciFrmtTyp == RG_SCH_UCI_FORMAT1B_CS) + { + hqRecpReq = &(pucchInfo->pucchRecpInfo->t.pucchRecpReq); + rgSCHTomUtlFillSfHqFdbkForFrmt1BCS(hqCb,hqRecpReq, + noFdbks,dlSf,pdcch,elemIdx,cellCb); + + if(noFdbks == 1) + {/* M = 1 case . size is same as A Value*/ + hqRecpReq->hqInfo.hqSz = ue->f1bCsAVal; + hqRecpReq->hqInfo.pucchResCnt = hqRecpReq->hqInfo.hqSz; + }else + {/* M > 1 case */ + hqRecpReq->hqInfo.hqSz = (noFdbks * 2); /* M for 2 cells */ + hqRecpReq->hqInfo.pucchResCnt = 4; + } + hqRecpReq->hqInfo.a = ue->f1bCsAVal; + /* handling for SPS occasions*/ + if(elemIdx == 0) + { + /* set the datPresinFirstSUbframe to TRUE if this + * is for pcell txion*/ +#ifdef ERRCLS_KW + RgSchTddANInfo *anInfo = NULLP; +#endif + /* if this txion is on pcell + * sps occaion, dyn sched or sps release pdcch + * set the sched present in first + * dl subframe of the bundle to TRUE. This + * is required for mapping the feedbak when SPS occasion + * is present in any of the DL subframe in the bundle in + * case of M > 2*/ + + /* SPS will happen only on pcell */ + if((hqCb == NULLP) || (!RG_SCH_IS_CELL_SEC(ue,hqCb->hqE->cell))) + { +#ifdef ERRCLS_KW + anInfo = rgSCHUtlGetUeANFdbkInfo(ue, + &recpReqInfo->timingInfo,RGSCH_PCELL_INDEX); + if(anInfo == NULL) + {/* ANInfo must be there. adding block + because of kworks*/ + RGSCHDBGERRNEW(cellCb->instIdx,(rgSchPBuf(cellCb->instIdx), + "ANInfo should not be NULL for cellId=%d \n", cellCb->cellId)); + RETVALUE(RFAILED); + + } +#endif + } + } + }else + {/* This needs to be revisited while + adding support for PUCCH format 3 */ + RGSCHDBGERRNEW(cellCb->instIdx,(rgSchPBuf(cellCb->instIdx),"Invalid Pucch format configured..")); + RETVALUE(RFAILED); + } + } + else +#endif + { + if((ackNackMode == RGR_TDD_ACKNACK_MODE_BUNDL) || + ((noFdbks == 1) && (ackNackMode == RGR_TDD_ACKNACK_MODE_MULT))) + { + hqRecpReq = &(pucchInfo->pucchRecpInfo->t.pucchRecpReq); +#ifdef TFU_UPGRADE + prevHqSize = hqRecpReq->hqInfo.hqSz; +#endif +#ifndef TFU_UPGRADE + /* Only one index for bundling case */ + hqRecpReq->M = noFdbks; + hqRecpReq->hqType = + TFU_HQ_RECP_REQ_NORMAL; + hqRecpReq->multCnt = 1; + hqRecpReq->t.nCce[0] = + pdcch->nCce; + hqRecpReq->m[0] = + dlSf->dlFdbkInfo.m; + hqRecpReq->p[0] = + rgSCHCmnGetPValFrmCCE(cellCb, pdcch->nCce); + + hqRecpReq->type = TFU_UCI_HARQ; + +#else /* TFU_UPGRADE */ + +#ifdef LTEMAC_SPS + if ((TRUE == isFirstFdbk) && (TRUE == n1PucchTkn.pres)) + { + hqRecpReq->hqInfo.hqFdbkMode = (TfuAckNackMode)ackNackMode; + hqRecpReq->hqInfo.pucchResCnt=1; + hqRecpReq->hqInfo.hqRes[0] = n1PucchTkn.val; + hqRecpReq->hqInfo.hqSz = hqSz; + } + /* ccpu00139413 */ + else if (FALSE == n1PucchTkn.pres) +#endif + { + hqRecpReq->hqInfo.hqFdbkMode = (TfuAckNackMode)ackNackMode; + M = noFdbks; + P = rgSCHCmnGetPValFrmCCE(cellCb, pdcch->nCce); + nP = cellCb->rgSchTddNpValTbl[P]; + nPlusOne = cellCb->rgSchTddNpValTbl[P + 1]; + m = dlSf->dlFdbkInfo.m; + /* In case of no UE */ + pucchRes = (M - m - 1)* nP + (m * nPlusOne) + pdcch->nCce + + cellCb->pucchCfg.n1PucchAn; + /*ccpu00130164:MOD-Changed to maitain value of + hqRecpReq->hqInfo.pucchResCnt=1 in case of bundling*/ + /*ccpu00132284 -MOD- hqRes need to be updated after pucchReCnt set to 1 + * and resource should be update at index-0*/ + hqRecpReq->hqInfo.pucchResCnt=1; + hqRecpReq->hqInfo.hqRes[hqRecpReq->hqInfo.pucchResCnt-1] = pucchRes; + + if((ackNackMode == RGR_TDD_ACKNACK_MODE_BUNDL) && (hqSz > prevHqSize)) + hqRecpReq->hqInfo.hqSz = hqSz; + else if (ackNackMode == RGR_TDD_ACKNACK_MODE_MULT) + hqRecpReq->hqInfo.hqSz = hqSz; + else + hqRecpReq->hqInfo.hqSz = prevHqSize; + } +#endif /* TFU_UPGRADE */ +#ifndef TFU_UPGRADE + cmLListAdd2Tail(&recpReqInfo->ueRecpReqLst, + &(pucchInfo->pucchRecpInfo->lnk)); + pucchInfo->pucchRecpInfo->lnk.node = + (PTR)pucchInfo->pucchRecpInfo; +#endif + } + else /* Multiplexing */ + { +#ifndef TFU_UPGRADE + pucchInfo->pucchRecpInfo->t.pucchRecpReq.M = noFdbks; +#ifdef LTEMAC_SPS + if (n1PucchTkn.pres == TRUE) + { + pucchInfo->pucchRecpInfo->t.pucchRecpReq.hqType = + TFU_HQ_RECP_REQ_N1PUCCH; + pucchInfo->pucchRecpInfo->t.pucchRecpReq.t.n1Pucch = n1PucchTkn.val; + } + else +#endif + { + pucchInfo->pucchRecpInfo->t.pucchRecpReq.hqType = + TFU_HQ_RECP_REQ_NORMAL; + multCnt = pucchInfo->pucchRecpInfo->t.pucchRecpReq.multCnt; + pucchInfo->pucchRecpInfo->t.pucchRecpReq.t.nCce[multCnt] = + pdcch->nCce; + pucchInfo->pucchRecpInfo->t.pucchRecpReq.m[multCnt] = + dlSf->dlFdbkInfo.m; + pucchInfo->pucchRecpInfo->t.pucchRecpReq.p[multCnt] = + rgSCHCmnGetPValFrmCCE(cellCb, pdcch->nCce); + + pucchInfo->pucchRecpInfo->t.pucchRecpReq.multCnt++; + } +#else /* TFU_UPGRADE */ + + hqRecpReq = &(pucchInfo->pucchRecpInfo->t.pucchRecpReq); + hqRecpReq->hqInfo.hqFdbkMode = (TfuAckNackMode)RGR_TDD_ACKNACK_MODE_MULT; + hqRecpReq->hqInfo.hqSz = noFdbks; + + resIdx = hqRecpReq->hqInfo.pucchResCnt; + hqRecpReq->hqInfo.pucchResCnt++; + +#ifdef LTEMAC_SPS + if (n1PucchTkn.pres == TRUE) + { + hqRecpReq->hqInfo.hqRes[resIdx] = n1PucchTkn.val; + } + else +#endif + { + M = noFdbks; + m = dlSf->dlFdbkInfo.m; + nCce = pdcch->nCce; + P = rgSCHCmnGetPValFrmCCE(cellCb, nCce); + nP = cellCb->rgSchTddNpValTbl[P]; + nPlusOne = cellCb->rgSchTddNpValTbl[P + 1]; + hqRecpReq->hqInfo.hqRes[resIdx] = (M - m - 1)* nP + + (m * nPlusOne) + pdcch->nCce + + cellCb->pucchCfg.n1PucchAn; + } +#endif /* TFU_UPGRADE */ + /* If all the DL subframes are scanned, then + * send TFU request*/ +#ifndef TFU_UPGRADE + if((elemIdx != noFdbks) && alloc) + { + cmHashListInsert(&cellCb->ueTfuPendLst, (PTR) pucchInfo, + (U8 *)&rnti, (U16) sizeof(rnti)); + alloc = FALSE; + } + else + { + pucchInfo->pucchRecpInfo->t.pucchRecpReq.type = TFU_UCI_HARQ; + cmLListAdd2Tail(&recpReqInfo->ueRecpReqLst, + &(pucchInfo->pucchRecpInfo->lnk)); + pucchInfo->pucchRecpInfo->lnk.node = + (PTR)pucchInfo->pucchRecpInfo; + /* Delete the entry after addition to the list */ + cmHashListDelete(&cellCb->ueTfuPendLst, (PTR) pucchInfo); + } +#endif + } + } + + *pucchInfoRef = pucchInfo; + *allocRef = alloc; + RETVALUE(ROK); +} +#endif + +#ifdef RG_ULSCHED_AT_CRC +/** @brief This function does all the processing related to a single downlink + * subframe. + * + * @details + * + * Function: rgSCHTomUtlProcDlSfAtCrc + * + * Processing steps: + * - collate control data for all UEs and send to PHY + * - collate data buffers for all UEs and send to PHY + * + * @param [in] RgSchDlSf *ulSf + * @param [in] RgSchCellCb *cell + * @param [in] TfuCntrlReqInfo *cntrlInfo + * @param [out] RgSchErrInfo *err + * @return S16 + */ +#ifdef ANSI +PRIVATE S16 rgSCHTomUtlProcDlSfAtCrc +( +RgSchDlSf *ulSf, +CmLteTimingInfo crntUlFrm, +RgSchCellCb *cell, +TfuCntrlReqInfo *cntrlInfo, +RgSchErrInfo *err +) +#else +PRIVATE S16 rgSCHTomUtlProcDlSfAtCrc (ulSf, crntUlFrm, cell, cntrlInfo, err) +RgSchDlSf *ulSf; +CmLteTimingInfo crntUlFrm; +RgSchCellCb *cell; +TfuCntrlReqInfo *cntrlInfo; +RgSchErrInfo *err; +#endif +{ + Inst inst = cell->instIdx; + S16 ret; + + TRC2(rgSCHTomUtlProcDlSfAtCrc); + + + cntrlInfo->numDlActvUes = 0; + cmLListInit(&cntrlInfo->phichLst); + cmLListInit(&cntrlInfo->dlPdcchLst); + cmLListInit(&cntrlInfo->ulPdcchLst); +#ifdef TFU_ALLOC_EVENT_NO_INIT + cntrlInfo->dlTiming.sfn = cntrlInfo->dlTiming.subframe = 0; + cntrlInfo->cfi = 0; +#endif + + cntrlInfo->ulTiming = crntUlFrm; + RG_SCH_ADD_TO_CRNT_TIME(cell->crntTime, cntrlInfo->ulTiming, TFU_ULCNTRL_DLDELTA); + + cntrlInfo->cellId = cell->cellId; + /* Fill PHICH info */ + if ((ret = rgSCHTomUtlFillPhich (cell, cntrlInfo, ulSf, err)) != ROK) + { + RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,"Unable to send PHICH info for " + "cell"); + RGSCH_FREE_MEM(cntrlInfo); + RETVALUE(ret); + } + + /* Fill UL Pdcch */ + if ((ret = rgSCHTomUtlFillUlPdcch (cell, cntrlInfo, ulSf, err)) != ROK) + { + RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,"Unable to send PDCCH info for " + "cell"); + RGSCH_FREE_MEM(cntrlInfo); + RETVALUE(ret); + } + +#ifdef EMTC_ENABLE + if(0 == cntrlInfo->ulMpdcchLst.count) + { + gUlMpdcchBlank++; + } +#endif + +#ifdef EMTC_ENABLE + if ((cntrlInfo->ulPdcchLst.count || cntrlInfo->phichLst.count) || RG_SCH_EMTC_GET_PDCCHLST_CNT(cntrlInfo)) +#else + if (cntrlInfo->ulPdcchLst.count || cntrlInfo->phichLst.count) +#endif + { + if (rgSCHUtlTfuCntrlReq(inst, cell->tfuSap->sapCfg.suId, cntrlInfo) + != ROK) + { + RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,"Unable to send Cntrl info for" + " cell"); + } + } + else + { + RGSCH_FREE_MEM(cntrlInfo); + } + + RETVALUE(ROK); +} /* end of */ +#endif /* #ifdef RG_ULSCHED_AT_CRC*/ + +#ifdef RGR_RRM_TICK +/** @brief This function sends the SFN Tick to L3 + * subframe. + * + * @details + * + * Function: rgSCHTomUtlSendSfnTick + * + * @param [in] RgSchCellCb *cell + */ +#ifdef ANSI +PRIVATE Void rgSCHTomUtlSendSfnTick +( +RgSchCellCb *cell +) +#else +PRIVATE Void rgSCHTomUtlSendSfnTick (cell) +RgSchCellCb *cell; +#endif +{ + RgrTtiIndInfo *rgrTtiInd; + + TRC2(rgSCHTomUtlSendSfnTick); + + /* TTI to be sent to RRM only once per system frame */ + /* Added support for period = 0 to disable tick to RRM */ + if ((cell->rrmTtiIndPrd != 0) && + ((cell->crntTime.sfn % cell->rrmTtiIndPrd) == 0) && + (cell->crntTime.subframe == 0)) + { + /* Allocate a TTI indication structure and send to RRM over RGR interface */ + if (rgSCHUtlAllocSBuf (cell->instIdx, + (Data**)&rgrTtiInd, sizeof(RgrTtiIndInfo)) != ROK) + { + RGSCHDBGERRNEW(cell->instIdx,(rgSchPBuf(cell->instIdx), + "Mem alloc failed for RGR TTI ind, cellId (%d))\n", + cell->cellId)); + RETVOID; + } + rgrTtiInd->cellId = cell->cellId; + rgrTtiInd->hSfn = cell->crntTime.hSfn; + rgrTtiInd->sfn = cell->crntTime.sfn; + + if (rgSCHUtlRgrTtiInd (cell, rgrTtiInd) != ROK) + { + RGSCHDBGERRNEW(cell->instIdx,(rgSchPBuf(cell->instIdx), + "Failed to send RGR TTI ind, cellId (%d))\n", + cell->cellId)); + rgSCHUtlFreeSBuf(cell->instIdx, (Data**)&rgrTtiInd, + sizeof(RgrTtiIndInfo)); + RETVOID; + } + } + RETVOID; +} +#endif + +#ifdef RG_5GTF + +/* @brief Mark Dyn TDD CrntSfIdx. + * + * @details + * + * Function: rgSCHDynTDDMrkCrntSfIdx + * Purpose: update the dyn tdd sunframe index + * @param[in] Inst schInst + * @RETVALUE None + */ +#ifdef ANSI +PRIVATE Void rgSCHDynTDDMrkCrntSfIdx +( +Inst schInst +) +#else /* ANSI */ +PRIVATE Void rgSCHDynTDDMrkCrntSfIdx(schInst) +Inst schInst; +#endif /* ANSI */ +{ + RgSchDynTddCb *rgSchDynTddInfo = &(rgSchCb[schInst].rgSchDynTdd); + + TRC2(rgSCHDynTDDMrkCrntSfIdx) + + RG_SCH_DYN_TDD_MARKTYPE(rgSchDynTddInfo, rgSchDynTddInfo->crntDTddSfIdx, + RG_SCH_DYNTDD_NOTDEF); + rgSchDynTddInfo->crntDTddSfIdx = (rgSchDynTddInfo->crntDTddSfIdx + 1) % + RG_SCH_DYNTDD_MAX_SFINFO; + + //printf("Initializing Index %d \n", rgSchDynTddInfo->crntDTddSfIdx); + + RETVOID; +} + +#endif +/** @brief This function fills the TTI timinig info for each cell + * + * @details + * + * Function: rgSchTomFillCellTtiInfo + * + * @param [in] TfuTtiIndInfo *ttiInd + * @param [in] Inst schInst + * @param [out] U8 *nCell + * @param [out] RgSchCellCb *cell[] + * + * Returns: Void + * + */ +#ifdef ANSI +PRIVATE Void rgSchTomFillCellTtiInfo +( +TfuTtiIndInfo *ttiInd, +Inst schInst, +U8 *nCell, +RgSchCellCb *cells[] +) +#else +PRIVATE Void rgSchTomFillCellTtiInfo (ttiInd, schInst, nCell, cells) +TfuTtiIndInfo *ttiInd; +Inst schInst; +U8 *nCell; +RgSchCellCb *cells[]; +#endif +{ + U8 i = 0; + U8 strtCellId; + TfuTtiCellInfo *cellInfo; + RgSchCellCb *cell; + U32 Idx1; + + CmLteTimingInfo frm; + + TRC2 (rgSchTomFillCellTtiInfo); + + if (CM_LTE_MAX_CELLS < ttiInd->numCells) + { + RETVOID; + } + +#ifdef RG_5GTF + rgSCHDynTDDMrkCrntSfIdx(schInst); +#endif + + for (i = 0; i < ttiInd->numCells; i++) + { + cellInfo = &ttiInd->cells[i]; + strtCellId = rgSchCb[schInst].genCfg.startCellId; + Idx1 = (U8)((cellInfo->cellId - strtCellId)&(CM_LTE_MAX_CELLS-1)); + cell = rgSchCb[schInst].cells[Idx1]; + /* Validate the cell */ + if (cell == NULLP) + { + /* Use SCH inst 0 print buff */ + RGSCHDBGERRNEW(schInst,(rgSchPBuf(schInst), + "RgLiTfuTtiInd()No cell exists for cellId %d\n", + cellInfo->cellId)); + continue; + } + *nCell = *nCell + 1; + cells[i] = (RgSchCellCb *)cell; + + /* 4UE_TTI_DELTA */ + if(cell->schTickDelta != cellInfo->schTickDelta) + { + printf("\nMukesh: Delta changed for cellId=%d: curr delta=%d new delta=%d\n" + "dlblankSf=%d ulblankSf=%d dummyTti=%d \n", + cell->cellId, cell->schTickDelta, cellInfo->schTickDelta, cellInfo->dlBlankSf,cellInfo->ulBlankSf, + cellInfo->isDummyTti); + } + RGSCH_UPDATE_DELTA(schInst, cellInfo->schTickDelta); + cell->schTickDelta = cellInfo->schTickDelta; + /* 4UE_TTI_DELTA */ + + cell->stopSiSch = cellInfo->dlBlankSf; + cell->stopDlSch = cellInfo->dlBlankSf; + cell->stopUlSch = cellInfo->ulBlankSf; + if (cellInfo->isDummyTti) + { + cell->stopDlSch = TRUE; + } + if((0 == (cellInfo->timingInfo.sfn % 30)) && (0 == cellInfo->timingInfo.subframe)) + { + //printf("5GTF_CHECK rgSCHTOMTtiInd (%d : %d)\n", cellInfo->timingInfo.sfn, cellInfo->timingInfo.subframe); + } +#ifndef EMTC_ENABLE + RGSCHCPYTIMEINFO(cellInfo->timingInfo, cell->crntTime); + RG_SCH_ADD_TO_CRNT_TIME(cell->crntTime, cell->hiDci0Time, + TFU_ULCNTRL_DLDELTA); + RG_SCH_ADD_TO_CRNT_TIME(cell->crntTime, cell->dlDciTime, + TFU_DLCNTRL_DLDELTA); + RG_SCH_ADD_TO_CRNT_TIME(cell->crntTime, cell->rcpReqTime, + TFU_RECPREQ_DLDELTA); + RGSCHDECRFRMCRNTTIME(cell->crntTime, cell->hqRlsTime, + TFU_HQFBKIND_ULDELTA); + RGSCHDECRFRMCRNTTIME(cell->crntTime, cell->dlSfRlsTime, + RGSCH_RLS_SF_IDX); +#else + RGSCHCPYTIMEINFO_EMTC(cellInfo->timingInfo, cell->crntTime); + RG_SCH_ADD_TO_CRNT_TIME_EMTC(cell->crntTime, cell->hiDci0Time, + TFU_ULCNTRL_DLDELTA); + RG_SCH_ADD_TO_CRNT_TIME_EMTC(cell->crntTime, cell->dlDciTime, + TFU_DLCNTRL_DLDELTA); + RG_SCH_ADD_TO_CRNT_TIME_EMTC(cell->crntTime, cell->rcpReqTime, + TFU_RECPREQ_DLDELTA); + RGSCHDECRFRMCRNTTIME_EMTC(cell->crntTime, cell->hqRlsTime, + TFU_HQFBKIND_ULDELTA); + RGSCHDECRFRMCRNTTIME_EMTC(cell->crntTime, cell->dlSfRlsTime, + RGSCH_RLS_SF_IDX); +#endif + rgSCHCmnUpdVars(cell); + cell->isDlDataAllwd = TRUE; +/* Get DownLink SubFrame */ + RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell); + frm = cell->crntTime; +#ifndef EMTC_ENABLE + RGSCH_INCR_SUB_FRAME(frm, RG_SCH_CMN_DL_DELTA); +#else + RGSCH_INCR_SUB_FRAME_EMTC(frm, RG_SCH_CMN_DL_DELTA); +#endif + cellSch->dl.time = frm; + +#ifdef RG_PFS_STATS + cell->totalTime++; +#endif +#ifdef LTE_TDD + U8 idx = (cell->crntTime.subframe + RG_SCH_CMN_DL_DELTA) % + RGSCH_NUM_SUB_FRAMES_5G; + + cell->isDlDataAllwd = RG_SCH_CMN_CHK_DL_DATA_ALLOWED(cell, idx); + + /*ccpu00130639 -ADD - used in UL HARQ proc id calculation*/ + if((cell->crntTime.sfn == 0) && (cell->crntTime.subframe == 0)) + { + /* sfn Cycle used for Tdd UL Harq Proc Determination. + This sfn Cycle will have values from 0 to numUl Harq-1. */ + cell->tddHqSfnCycle = (cell->tddHqSfnCycle + 1 ) % + (rgSchTddUlNumHarqProcTbl[cell->ulDlCfgIdx]); + } +#endif +#ifdef EMTC_ENABLE + if(cell->emtcEnable) + { + rgSCHUtlEmtcResPrcTti(cell); + } +#endif + } +} + +/** @brief This function prepares the TTI for scheduling and + * invokes the Common channel scheduler. Uplink scheduler + * is invoked first if UL Scheduling at CRC is not enabled + * + * @details + * + * Function: rgSchTomTtiUlAndDlCmnChSch + * + * @param [out] RgSchCellCb *cell + * + * Returns: Void + * + */ +#ifdef ANSI +PRIVATE Void rgSchTomTtiUlAndDlCmnChSch +( +RgSchCellCb *cell +) +#else +PRIVATE Void rgSchTomTtiUlAndDlCmnChSch (cell) +RgSchCellCb *cell; +#endif +{ + + TRC2(rgSchTomTtiUlAndDlCmnChSch); + + cell->rlsHqArr[cell->crntHqIdx].numUes = 0; + cell->crntHqIdx++; + cell->crntHqIdx = cell->crntHqIdx % RGSCH_NUM_SUB_FRAMES; + + cmPrcTmr(&cell->tqCp, cell->tq, (PFV)rgSCHTmrProcTmr); + rgSCHMeasGapANRepTtiHndl (cell); + /* We need to fill the PHICH for the UL Data, first we need to get the UL + * SF from Scheduler, next we fill the dlSf that goes out this TTI. + * This must be performed prior to any other processing of the TTI + * so that we do not wrap around and generate feedback prior to + * reception of UL data. + */ +#ifndef RG_ULSCHED_AT_CRC + { + U8 Mval = 1; + U8 idx; /* Index into Uplink Sf array */ +#ifdef LTE_TDD + Mval = rgSchTddPhichMValTbl[cell->ulDlCfgIdx] + [cell->hiDci0Time.subframe]; +#endif + if(Mval) + { + for(idx=0; idx < Mval; idx++) + { + rgSCHCmnRlsUlSf(cell, idx); + } + } + } +#endif + + /* DTX processing for those Harq's which did not get feedback from L1 */ + rgSCHDhmRlsDlsfHqProc (cell, cell->hqRlsTime); + /* Re-Init the Downlink subframe */ + rgSCHUtlDlRlsSubFrm(cell, cell->dlSfRlsTime); + /* Added handling to retransmit + * release PDCCH in case of DTX + */ + + /*Check for DRX every TTI*/ + rgSCHDrxTtiInd(cell); + + /* For TDD, UL scheduling should happen after DL scheduling */ +#ifndef LTE_TDD +#ifndef RG_ULSCHED_AT_CRC + /* Perform UL scheduling */ + rgSCHCmnUlSch(cell); +#endif +#endif + /* Perform DL scheduling for Common channels */ + rgSCHCmnDlCommonChSch(cell); + + RETVOID; +} + +/** @brief This function invokes the Non critical procedures like measurements, + * and RGR configurations. + * + * @details + * + * Function: rgSchTomTtiMiscFunctions + * + * @param [in] RgSchCellCb *cell + * + * Returns: Void + * + */ +#ifdef ANSI +PRIVATE Void rgSchTomTtiMiscFunctions +( +RgSchCellCb *cell +) +#else +PRIVATE Void rgSchTomTtiMiscFunctions (cell) +RgSchCellCb *cell; +#endif +{ + U8 suId = cell->tfuSap->sapCfg.suId; + + TRC2(rgSchTomTtiMiscFunctions); + + /* Invoke RAM Tti Handler */ + rgSCHRamTtiHndlr(cell); + + /* Handle RGR configurations */ + rgSCHGomTtiHndlr(cell, suId); +#ifdef LTE_L2_MEAS + if((RGM_PRB_REPORT_START == cell->prbUsage.prbRprtEnabld) + && (!(cell->prbUsage.rprtPeriod) || ((glblTtiCnt % cell->prbUsage.rprtPeriod) == 0))) + { + rgSCHUtlUpdAvgPrbUsage(cell); + } + rgSCHL2Meas(cell,FALSE); +#endif + + /* LTE_ADV_FLAG_REMOVED_START */ + /* Report ABS Load information to application periodically */ + if((RGR_ENABLE == cell->lteAdvCb.absCfg.status) && + (cell->lteAdvCb.absCfg.absLoadPeriodicity)) + { + RgrLoadInfIndInfo *rgrLoadInf; + U8 idx; + + cell->lteAdvCb.absLoadTtiCnt++; + if(cell->lteAdvCb.absLoadTtiCnt >= cell->lteAdvCb.absCfg.absLoadPeriodicity) + { + /* ccpu00134492 */ + if(rgSCHUtlAllocSBuf (cell->instIdx,(Data**)&rgrLoadInf, + sizeof(RgrLoadInfIndInfo)) != ROK) + { + RGSCHDBGERRNEW(cell->instIdx,(rgSchPBuf(cell->instIdx),"Could not " + "allocate memory for sending LoadInfo\n")); + RETVOID; + } + cell->lteAdvCb.absLoadTtiCnt = 0; + rgrLoadInf->cellId = cell->cellId; + rgrLoadInf->bw = cell->bwCfg.dlTotalBw; + rgrLoadInf->type = RGR_ABS; + for(idx= 0; idxu.absLoadInfo[idx] = cell->lteAdvCb.absLoadInfo[idx]; + cell->lteAdvCb.absLoadInfo[idx] = 0; + } + rgSCHUtlRgrLoadInfInd(cell, rgrLoadInf); + } + } + +#ifdef LTE_TDD + if(cell->isDlDataAllwd) + { + /* Calling function to update CFI parameters*/ + rgSchCmnUpdCfiDb(cell, RG_SCH_CMN_DL_DELTA); + } + else + { + /* Incrementing the ttiCnt in case of UL subframe */ + if(!cell->dynCfiCb.switchOvrInProgress) + { + cell->dynCfiCb.ttiCnt++; + } + } +#else + rgSchCmnUpdCfiDb(cell, RG_SCH_CMN_DL_DELTA); +#endif + + /* LTE_ADV_FLAG_REMOVED_END */ + RETVOID; +} + + +/** @brief This function invokes the Downlink scheduler + * + * @details + * + * Function: rgSchTomTtiDlSch + * + * @param [in] RgSchCellCb *cell + * + * Returns: Void + * + */ +#ifdef ANSI +PRIVATE Void rgSchTomTtiDlSch +( +RgSchCellCb *cell +) +#else +PRIVATE Void rgSchTomTtiDlSch (cell) +RgSchCellCb *cell; +#endif +{ + TRC2(rgSchTomTtiDlSch); + + if (cell->isDlDataAllwd && (cell->stopDlSch == FALSE)) + { + rgSCHCmnDlSch(cell); + } + + RETVOID; +} + +/** @brief This function invokes Consolidates the allocations + * send the Subframe allocation info to MAC + * + * @details + * + * Function: rgSchTomTtiCnsldtSfAlloc + * + * @param [in] RgSchCellCb *cell + * + * Returns: Void + * + */ +#ifdef ANSI +PRIVATE Void rgSchTomTtiCnsldtSfAlloc +( +RgSchCellCb *cell +) +#else +PRIVATE Void rgSchTomTtiCnsldtSfAlloc (cell) +RgSchCellCb *cell; +#endif +{ + RgSchDlSf *dlSf; + RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell); + + dlSf = rgSCHUtlSubFrmGet(cell, cellSch->dl.time); + + TRC2(rgSchTomTtiCnsldtSfAlloc); + + /* Prepare Subframe allocation info and send to MAC */ + rgSCHCmnCnsldtSfAlloc(cell); + + /* Call ACK NACK module to add to dlsf Queue */ + rgSCHAckNakRepAddToQ(cell, dlSf); + + rgSCHTomUtlProcTA(cell); + + RETVOID; +} + +/** @brief This function prepares the DL and UL Config requests + * and sends to CL + * + * @details + * + * Function: rgSchTomTtiL1DlAndUlCfg + * + * @param [in] RgSchCellCb *cell + * + * Returns: Void + * + */ +#ifdef ANSI +PRIVATE Void rgSchTomTtiL1DlAndUlCfg +( +RgSchCellCb *cell, +RgTfuCntrlReqInfo *cntrlInfo +) +#else +PRIVATE Void rgSchTomTtiL1DlAndUlCfg (cell, cntrlInfo) +RgSchCellCb *cell; +RgTfuCntrlReqInfo *cntrlInfo; +#endif +{ + RgSchDlSf *dlSf = rgSCHUtlSubFrmGet (cell, cell->dlDciTime); + RgSchDlSf *ulSf = rgSCHUtlSubFrmGet (cell, cell->hiDci0Time); + RgSchErrInfo err; + + TRC2(rgSchTomTtiL1DlAndUlCfg); + + rgSCHTomUtlProcDlSf (dlSf, ulSf, cell, cntrlInfo, &err); + /* Mark this frame as sent */ + dlSf->txDone = TRUE; + + rgBwAlloInfo[dlSf->sfNum] += dlSf->bwAssigned; + rgBwAlcnt[dlSf->sfNum] ++; + + +#ifdef LTE_TDD + rgSCHTomUtlProcTddUlSf(cell); +#else + rgSCHTomUtlProcUlSf (cell, &err); +#endif + + RETVOID; +} +#ifdef LTE_TDD +/** @brief This function prepares does the Downlink subframe re-init and + * Harq DTX processing + * + * @details + * + * Function: rgSchTomUtlTddRlsSfAndHarq + * + * @param [in] RgSchCellCb *cell + * + * Returns: Void + * + */ +#ifdef ANSI +PRIVATE Void rgSchTomUtlTddRlsSfAndHarq +( +RgSchCellCb *cell +) +#else +PRIVATE Void rgSchTomUtlTddRlsSfAndHarq (cell) +RgSchCellCb *cell; +#endif +{ + TRC2(rgSchTomUtlTddRlsSfAndHarq); + + /* ccpu00132341-MOD- rgSchTddRlsDlSubfrmTbl is dependent on DELTA(=2). + * Instead rgSchTddDlAscSetIdxKTbl can be used as the K set gives proper + * UL subframes*/ + /* ccpu00133109: Removed RGSCHSUBFRMCRNTTIME as it is not giving proper + * output if diff is more than 10. Instead using RGSCHDECRFRMCRNTTIME() + * as it is serving the purpose */ + if(rgSchTddDlAscSetIdxKTbl[cell->ulDlCfgIdx][cell->hqRlsTime.subframe]. + numFdbkSubfrms) + { + /* ccpu00132341-MOD- Providing the UL SF timing for avoiding + * calculation inside the function */ + rgSCHDhmTddRlsSubFrm(cell, cell->hqRlsTime); + rgSCHDhmRlsDlsfHqProc(cell, cell->hqRlsTime); + } + RETVOID; +} + +/** @brief This function processes the UL subframe and fills TFU reception + * request + * + * @details + * + * Function: rgSCHTomUtlProcTddUlSf + * + * @param [in] RgSchCellCb *cell + * + * Returns: Void + * + */ +#ifdef ANSI +PRIVATE Void rgSCHTomUtlProcTddUlSf +( +RgSchCellCb *cell +) +#else +PRIVATE Void rgSCHTomUtlProcTddUlSf (cell) +RgSchCellCb *cell; +#endif +{ + RgSchErrInfo err; + + TRC2(rgSCHTomUtlProcTddUlSf); + + if(rgSchTddUlDlSubfrmTbl[cell->ulDlCfgIdx] + [cell->rcpReqTime.subframe] == RG_SCH_TDD_UL_SUBFRAME) + { + if (rgSCHTomUtlProcUlSf (cell, &err) != ROK) + { + /* fill in err type and call sta ind */ + RGSCHDBGERRNEW(cell->instIdx, (rgSchPBuf(cell->instIdx), + "Unable to process Uplink subframe for cellId (%d))\n", + cell->cellId)); + } + } + /* TDD Fix , to allow Special SF SRS CFg */ + else if(rgSchTddUlDlSubfrmTbl[cell->ulDlCfgIdx] + [cell->rcpReqTime.subframe] == RG_SCH_TDD_SPL_SUBFRAME) + { + if (rgSCHTomUtlPrcUlTddSpclSf(cell, &err) != ROK) + { + /* fill in err type and call sta ind */ + RGSCHDBGERRNEW(cell->instIdx, (rgSchPBuf(cell->instIdx), + "Unable to process Sipceial subframe for cellId (%d))\n", + cell->cellId)); + } + } + + RETVOID; +} +#endif + + +/********************************************************************** + + End of file +**********************************************************************/ diff --git a/src/5gnrmac/rg_sch_uhm.c b/src/5gnrmac/rg_sch_uhm.c new file mode 100755 index 000000000..f2ad46c31 --- /dev/null +++ b/src/5gnrmac/rg_sch_uhm.c @@ -0,0 +1,1089 @@ +/******************************************************************************* +################################################################################ +# Copyright (c) [2017-2019] [Radisys] # +# # +# 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. # +################################################################################ +*******************************************************************************/ + +/************************************************************************ + + Name: LTE-MAC layer + + Type: C source file + + Desc: C source code for Entry point fucntions + + File: rg_sch_uhm.c + +**********************************************************************/ + +/** @file rg_sch_uhm.c +@brief This module handles uplink harq related functionality in MAC. +*/ + +/* header include files -- defines (.h) */ +#include "envopt.h" /* environment options */ +#include "envdep.h" /* environment dependent */ +#include "envind.h" /* environment independent */ + +#include "gen.h" /* general */ +#include "ssi.h" /* system services */ + +#include "cm_lte.h" /* Common LTE */ +#include "cm_tkns.h" /* Common Token Defines */ +#include "cm_llist.h" /* Common Link List Defines */ +#include "cm_hash.h" /* Common Hash List Defines */ +#include "cm_mblk.h" /* memory management */ + +#include "rg_env.h" /* MAC Environment Defines */ +#include "tfu.h" /* TFU Interface defines */ +#include "rgr.h" /* RGR Interface defines */ +#include "lrg.h" /* LRG Interface defines */ + +#include "rg_sch.h" /* Scheduler defines */ +#include "rg_sch_inf.h" /* Scheduler defines */ +#include "rg_sch_err.h" /* MAC error defines */ + +/* header/extern include files (.x) */ +#include "gen.x" /* general */ +#include "ssi.x" /* system services */ +#include "cm5.x" /* system services */ +#include "cm_lte.x" /* Common LTE */ +#include "cm_tkns.x" /* Common Token Definitions */ +#include "cm_llist.x" /* Common Link List Definitions */ +#include "cm_lib.x" /* Common Library Definitions */ +#include "cm_hash.x" /* Common Hash List Definitions */ +#include "cm_mblk.x" /* memory management */ + +#include "tfu.x" /* TFU Interface defines */ +#include "rgr.x" /* RGR Interface includes */ +#include "lrg.x" /* LRG Interface includes */ +#include "rgm.x" +#include "rg_sch_inf.x" /* Scheduler defines */ +#include "rg_sch.x" /* Scheduler includes */ +#include "rg_sch_cmn.h" +#include "rg_sch_cmn.x" + +/* local defines */ + +/* local typedefs */ + +/* local externs */ + +/* forward references */ + +#ifdef EMTC_ENABLE + U32 gUlRetxPassCntr = 0; + /*EXTERN U32 gUlRetxFailCntr; + EXTERN U32 gUlCrcPassCounter; + EXTERN U32 gUlCrcFailCounter;*/ +#endif +PUBLIC U8 rgRvIdxTable[] = {0, 3, 1, 2}; /* This gives rvIdx for a given rv */ +PUBLIC U8 rgRvTable[] = {0, 2, 3 ,1}; /* This gives rv for a given rvIdx */ + +#ifdef EMTC_ENABLE +PUBLIC Void rgSCHCmnEmtcHdlHarqProcFail +( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgSchUlHqProcCb *hqProc, +CmLteTimingInfo frm +); +PUBLIC Void rgSCHEmtcInitUlUeHqEnt +( +RgSchCellCb *cell, +RgrUeCfg *ueCfg, +RgSchUeCb *ueCb +); + +#endif + +/** + * @brief Handler for HARQ processing on recieving Data indication from PHY. + * + * @details + * + * Function: rgSCHUhmProcDatInd + * + * Invoked by: rgSCHTomTfuDatInd of TOM + * + * Processing Steps: + * - Set rcvdCrcInd variable to TRUE + * + * @param[in] *cell + * @param[in] *ue + * @param[in] frm + * @return Void + **/ +#ifndef MAC_SCH_STATS +#ifdef ANSI +PUBLIC Void rgSCHUhmProcDatInd +( +RgSchCellCb *cell, +RgSchUeCb *ue, +CmLteTimingInfo frm +) +#else +PUBLIC Void rgSCHUhmProcDatInd(cell, ue, frm) +RgSchCellCb *cell; +RgSchUeCb *ue; +CmLteTimingInfo frm; +#endif +#else /* MAC_SCH_STATS */ +#ifdef ANSI +PUBLIC Void rgSCHUhmProcDatInd +( +RgSchCellCb *cell, +RgSchUeCb *ue, +CmLteTimingInfo frm, +U8 cqi +) +#else +PUBLIC Void rgSCHUhmProcDatInd(cell, ue, frm, cqi) +RgSchCellCb *cell; +RgSchUeCb *ue; +CmLteTimingInfo frm; +U8 cqi; +#endif +#endif /* MAC_SCH_STATS */ +{ + RgSchUlHqProcCb *hqProc; +#ifdef UL_LA + RgSchCmnUlUe *ueUl = RG_SCH_CMN_GET_UL_UE(ue, cell); + S32 iTbs; + U8 maxiTbs = rgSchCmnUlCqiToTbsTbl[cell->isCpUlExtend] + [ueUl->maxUlCqi]; +#endif + + TRC2(rgSCHUhmProcDatInd); + + rgSCHUtlUlHqProcForUe(cell, frm, ue, &hqProc); + if (hqProc == NULLP) + { + printf("UE[%d] failed to find UL HqProc for [%d:%d]\n", + ue->ueId, frm.sfn, frm.subframe); + RETVOID; + } + hqProc->rcvdCrcInd = TRUE; + +#ifdef UL_LA + { + ueUl->ulLaCb.deltaiTbs += UL_LA_STEPUP; + iTbs = (ueUl->ulLaCb.cqiBasediTbs + ueUl->ulLaCb.deltaiTbs)/100; + + if (iTbs > maxiTbs) + { + ueUl->ulLaCb.deltaiTbs = (maxiTbs * 100) - ueUl->ulLaCb.cqiBasediTbs; + } + + } +#endif +#ifdef MAC_SCH_STATS + /** Stats update over here + */ + { + hqFailStats.ulCqiStat[cqi - 1].numOfAcks++; + } +#endif + +#ifdef TENB_STATS + /* UL stats are filled in primary index as of now */ + cell->tenbStats->sch.ulAckNack[rgRvTable[hqProc->rvIdx]]++; + ue->tenbStats->stats.nonPersistent.sch[RG_SCH_CELLINDEX(cell)].ulAckNackCnt++; + if(hqProc->alloc) + { + ue->tenbStats->stats.nonPersistent.sch[RG_SCH_CELLINDEX(cell)].ulTpt += (hqProc->alloc->grnt.datSz << 3); + cell->tenbStats->sch.ulTtlTpt +=(hqProc->alloc->grnt.datSz << 3);//pverma + } +#endif + + RETVOID; +} /* rgSCHUhmProcDatInd */ + +/** + * @brief Handler for HARQ processing on recieving Data indication from PHY. + * + * @details + * + * Function: rgSCHUhmProcMsg3DatInd + * + * Invoked by: rgSCHTomTfuDatInd of TOM + * + * Processing Steps: + * - Set rcvdCrcInd variable to TRUE + * + * @param[in,out] *hqProc + * @return Void + **/ +#ifdef ANSI +PUBLIC Void rgSCHUhmProcMsg3DatInd +( +RgSchUlHqProcCb *hqProc +) +#else +PUBLIC Void rgSCHUhmProcMsg3DatInd(hqProc) +RgSchUlHqProcCb *hqProc; +#endif +{ + TRC2(rgSCHUhmProcMsg3DatInd); + hqProc->rcvdCrcInd = TRUE; + hqProc->remTx = 0; /*Reseting the value of rem Tx*/ + printf("\nrgSCHUhmProcMsg3DatInd,id:%u\n",hqProc->procId); + RETVOID; +} /* rgSCHUhmProcMsg3DatInd */ + +/** + * @brief Handler for HARQ processing on recieving Data indication from PHY. + * + * @details + * + * Function: rgSCHUhmProcMsg3Failure + * + * Invoked by: rgSCHTomTfuDatInd of TOM + * + * Processing Steps: + * - Set rcvdCrcInd variable to TRUE + * + * @param[in,out] *hqProc + * @return Void + **/ +#ifdef ANSI +PUBLIC Void rgSCHUhmProcMsg3Failure +( +RgSchUlHqProcCb *hqProc +) +#else +PUBLIC Void rgSCHUhmProcMsg3Failure(hqProc) +RgSchUlHqProcCb *hqProc; +#endif +{ + TRC2(rgSCHUhmProcMsg3Failure); +#ifdef EMTC_ENABLE + RG_SCH_EMTC_IS_CRCIND_RCVD_CHK_RACB(hqProc); +#endif + if(hqProc->rcvdCrcInd != TRUE) + { + hqProc->rcvdCrcInd = FALSE; + } + + RETVOID; +} /* rgSCHUhmProcMsg3Failure */ + +/** + * @brief Handler for HARQ processing on recieving Decode failure from PHY. + * + * @details + * + * Function: rgSCHUhmProcHqFailure + * + * Invoked by: rgSCHTomTfuDecFailInd of TOM + * + * Processing Steps: + * - Update NACK information in harq info. + * - Update RV index of received RV from PHY in harq info. + * - Set PhichInfo in DlSf + * + * @param[in] *cell + * @param[in] *ue + * @param[in] frm + * @param[in] rv + * @return Void + **/ +#ifndef MAC_SCH_STATS +#ifdef ANSI +PUBLIC Void rgSCHUhmProcHqFailure +( +RgSchCellCb *cell, +RgSchUeCb *ue, +CmLteTimingInfo frm, +TknU8 rv +) +#else +PUBLIC Void rgSCHUhmProcHqFailure(cell, ue, frm, rv) +RgSchCellCb *cell; +RgSchUeCb *ue; +CmLteTimingInfo frm; +TknU8 rv; +#endif +#else /* MAC_SCH_STATS */ +#ifdef ANSI +PUBLIC Void rgSCHUhmProcHqFailure +( +RgSchCellCb *cell, +RgSchUeCb *ue, +CmLteTimingInfo frm, +TknU8 rv, +U8 cqi +) +#else +PUBLIC Void rgSCHUhmProcHqFailure(cell, ue, frm, rv, cqi) +RgSchCellCb *cell; +RgSchUeCb *ue; +CmLteTimingInfo frm; +TknU8 rv; +U8 cqi; +#endif +#endif /* MAC_SCH_STATS */ +{ + RgSchUlHqProcCb *hqProc; +#ifdef UL_LA + RgSchCmnUlUe *ueUl = RG_SCH_CMN_GET_UL_UE(ue,cell); + S32 iTbs; +#endif + TRC2(rgSCHUhmProcHqFailure); + + rgSCHUtlUlHqProcForUe(cell, frm, ue, &hqProc); + if (hqProc == NULLP) + { + printf("UE[%d] failed to find UL HqProc for [%d:%d]\n", + ue->ueId, frm.sfn, frm.subframe); + RETVOID; + } +#ifdef UL_LA + { + ueUl->ulLaCb.deltaiTbs -= UL_LA_STEPDOWN; + iTbs = (ueUl->ulLaCb.cqiBasediTbs + ueUl->ulLaCb.deltaiTbs)/100; + + if (iTbs < 0) + { + ueUl->ulLaCb.deltaiTbs = -(ueUl->ulLaCb.cqiBasediTbs); + } + + } +#endif +#ifdef MAC_SCH_STATS + /** Stats update over here */ + { + static U32 retxCnt = 0; + ++retxCnt; + hqFailStats.ulCqiStat[cqi - 1].numOfNacks++; + } +#endif /* MAC_SCH_STATS */ + if(hqProc->rcvdCrcInd != TRUE) + { + hqProc->rcvdCrcInd = FALSE; + } +#ifdef TENB_STATS + /* UL stats are filled in primary index as of now */ + cell->tenbStats->sch.ulAckNack[rgRvTable[hqProc->rvIdx]]++; + ue->tenbStats->stats.nonPersistent.sch[RG_SCH_CELLINDEX(cell)].ulAckNackCnt++; + cell->tenbStats->sch.ulNack[rgRvTable[hqProc->rvIdx]]++; + ue->tenbStats->stats.nonPersistent.sch[RG_SCH_CELLINDEX(cell)].ulNackCnt++; +#endif + hqProc->rvIdxPhy.pres = rv.pres; + if(rv.pres) + { + hqProc->rvIdxPhy.val = rgRvIdxTable[rv.val]; + } + RETVOID; +} /* rgSCHUhmProcHqFailure */ + +/** + * @brief Handler for identifying the HARQ process cb associated with the + * index. + * + * @details + * + * Function: rgSCHUhmGetUlHqProc + * + * Processing Steps: + * - Return pointer to uplink harq process corresponding to the timing + * information passed. + * + * @param[in] *ue + * @param[in] idx + * @return RgSchUlHqProcCb* + * -# Pointer to harq process corresponding to index + * -# NULL + **/ +#ifdef ANSI +PUBLIC RgSchUlHqProcCb* rgSCHUhmGetUlHqProc +( +RgSchCellCb *cell, +RgSchUeCb *ue, +U8 idx +) +#else +PUBLIC RgSchUlHqProcCb* rgSCHUhmGetUlHqProc(cell, ue, idx) +RgSchCellCb *cell; +RgSchUeCb *ue; +U8 idx; +#endif +{ + RgSchCmnUlUe *ueUl = RG_SCH_CMN_GET_UL_UE(ue, cell); + TRC2(rgSCHUhmGetUlHqProc); + +#if (ERRCLASS & ERRCLS_DEBUG) + if(idx >= ueUl->hqEnt.numHqPrcs) + { + RETVALUE(NULLP); + } +#endif + RETVALUE(&(ueUl->hqEnt.hqProcCb[idx])); +} /* rgSCHUhmGetUlHqProc */ + +/** + * @brief Handler for HARQ processing on recieving new trasmission indication + * from USM. + * + * @details + * + * Function: rgSCHUhmNewTx + * + * Invoked by: USM + * + * Processing Steps: + * - Update harq info with values indicating new HARQ transmission. + * + * @param[in,out] *hqProc + * @param[in] *alloc + * @return Void + **/ +#ifdef ANSI +PUBLIC Void rgSCHUhmNewTx +( +RgSchUlHqProcCb *hqProc, +U8 maxHqRetx, +RgSchUlAlloc *alloc +) +#else +PUBLIC Void rgSCHUhmNewTx(hqProc, maxHqRetx, alloc) +RgSchUlHqProcCb *hqProc; +U8 maxHqRetx; +RgSchUlAlloc *alloc; +#endif +{ + TRC2(rgSCHUhmNewTx); + + hqProc->ndi ^= 1; + hqProc->alloc = alloc; + hqProc->remTx = maxHqRetx; + hqProc->rcvdCrcInd = FALSE; + hqProc->rvIdx = 0; + hqProc->rvIdxPhy.pres = FALSE; +#ifdef LTE_L2_MEAS + if (hqProc->alloc->ue) + { + ((RgUeUlHqCb*)hqProc->hqEnt)->numBusyHqProcs++; + } +#endif + RETVOID; +} /* rgSCHUhmNewTx */ + +/** + * @brief Free an uplink HARQ process. + * + * @details + * + * Function: rgSCHUhmFreeProc + * + * Invoked by: USM + * + * Processing Steps: + * - Set alloc pointer to NULLP + * + * @param[in] RgSchUlHqProcCb *hqProc + * @param[in] RgSchCellCb *cell + * @return Void + **/ +#ifdef ANSI +PUBLIC Void rgSCHUhmFreeProc +( +RgSchUlHqProcCb *hqProc, +RgSchCellCb *cell +) +#else +PUBLIC Void rgSCHUhmFreeProc(hqProc, cell) +RgSchUlHqProcCb *hqProc; +RgSchCellCb *cell; +#endif +{ +#ifdef LTEMAC_SPS + RgSchCmnUlUeSpsInfo *ulSpsUe = NULLP; +#endif +#ifdef LTE_L2_MEAS + RgSchUeCb *ueCb; + U8 qci = 1; +#endif + TRC2(rgSCHUhmFreeProc); + +#ifdef LTE_L2_MEAS + if (hqProc->alloc && hqProc->alloc->ue) + { + ueCb = hqProc->alloc->ue; + if (ueCb && cell) + { + U32 nonLcg0ReportedBs = ((RgSchCmnLcg *)(ueCb->ul.lcgArr[1].sch))->reportedBs + \ + ((RgSchCmnLcg *)(ueCb->ul.lcgArr[2].sch))->reportedBs + \ + ((RgSchCmnLcg *)(ueCb->ul.lcgArr[3].sch))->reportedBs; + ((RgUeUlHqCb*)hqProc->hqEnt)->numBusyHqProcs--; + if (! ((RgUeUlHqCb*)hqProc->hqEnt)->numBusyHqProcs && !(nonLcg0ReportedBs)) + { + while (ueCb->ulActiveLCs) + { + if (ueCb->ulActiveLCs & 0x1) + { + cell->qciArray[qci].ulUeCount--; + } + qci++; + ueCb->ulActiveLCs >>= 1; + } + } + } + } +#endif + + + if(hqProc && (RgUeUlHqCb*)hqProc->hqEnt) + { + +#ifdef UL_ADPT_DBG + printf("\n\n########HARQ FREED HARQPROC ID (%d )after rgSCHUhmFreeProc inuse %ld free %ld \n",hqProc->alloc->grnt.hqProcId, (CmLListCp *)(&((RgUeUlHqCb*)hqProc->hqEnt)->inUse)->count,(CmLListCp *) (&((RgUeUlHqCb*)hqProc->hqEnt)->free)->count); +#endif + hqProc->alloc = NULLP; + hqProc->ulSfIdx = RGSCH_INVALID_INFO; + /*ccpu00116293 - Correcting relation between UL subframe and DL subframe based on RG_UL_DELTA*/ + hqProc->isRetx = FALSE; + hqProc->remTx = 0; /*Reseting the remTx value to 0*/ +#ifdef EMTC_ENABLE + RG_SCH_EMTC_SET_ISDTX_TO_FALSE(hqProc); +#endif + cmLListDelFrm(&((RgUeUlHqCb*)hqProc->hqEnt)->inUse,&hqProc->lnk); + cmLListAdd2Tail(&((RgUeUlHqCb*)hqProc->hqEnt)->free, &hqProc->lnk); + + /* + printf("after rgSCHUhmFreeProc inuse %ld free %ld \n", + (CmLListCp *)(&((RgUeUlHqCb*)hqProc->hqEnt)->inUse)->count, + (CmLListCp *) (&((RgUeUlHqCb*)hqProc->hqEnt)->free)->count); + */ + } + else + { + printf("\nhqEnt is NULL\n"); + } + RETVOID; +} /* rgSCHUhmFreeProc */ + +/** + * @brief Handler for HARQ processing on recieving re-trasmission + * indication from USM. + * + * @details + * + * Function: rgSCHUhmRetx + * + * Invoked by: USM + * + * Processing Steps: + * - Update harq info with values corresponding to + * re-transmission. + * + * @param[in,out] *hqProc + * @return Void + **/ +#ifdef ANSI +PUBLIC Void rgSCHUhmRetx +( +RgSchUlHqProcCb *hqProc, +RgSchUlAlloc *alloc +) +#else +PUBLIC Void rgSCHUhmRetx(hqProc, alloc) +RgSchUlHqProcCb *hqProc; +RgSchUlAlloc *alloc; +#endif +{ + TRC2(rgSCHUhmRetx); + + hqProc->alloc = alloc; + --hqProc->remTx; + hqProc->rvIdx = (hqProc->rvIdx + 1) % 4; + hqProc->rvIdxPhy.pres = FALSE; + RETVOID; +} /* rgSCHUhmRetx */ + + +/** + * @brief Handler for initializing the HARQ entity. + * + * @details + * + * Function: rgSCHUhmRgrUeCfg + * + * Invoked by: RGR + * + * Processing Steps: + * - Initialize maxHqRetx + * + * @param[in] *cellCb + * @param[in,out] *ueCb + * @param[in] *ueCfg + * @param[out] *err + * @return Void + **/ +#ifdef ANSI +PUBLIC Void rgSCHUhmRgrUeCfg +( +RgSchCellCb *cellCb, +RgSchUeCb *ueCb, +RgrUeCfg *ueCfg +) +#else +PUBLIC Void rgSCHUhmRgrUeCfg(cellCb, ueCb, ueCfg) +RgSchCellCb *cellCb; +RgSchUeCb *ueCb; +RgrUeCfg *ueCfg; +#endif +{ + U8 i; + RgSchCmnUlUe *ueUl = RG_SCH_CMN_GET_UL_UE(ueCb, cellCb); + + TRC2(rgSCHUhmRgrUeCfg); + + ueUl->hqEnt.maxHqRetx = ((ueCfg->ueUlHqCfg.maxUlHqTx) - 1); +#ifdef TFU_UPGRADE + /* Storing the delta HARQ offset for HARQ + PUSCH */ + ueCb->ul.betaHqOffst = ueCfg->puschDedCfg.bACKIdx; +#endif + cmLListInit(&ueUl->hqEnt.free); + cmLListInit(&ueUl->hqEnt.inUse); + for(i=0; i < ueUl->hqEnt.numHqPrcs; i++) + { + ueUl->hqEnt.hqProcCb[i].hqEnt = (void*)(&ueUl->hqEnt); + ueUl->hqEnt.hqProcCb[i].procId = i; + ueUl->hqEnt.hqProcCb[i].remTx = 0; + ueUl->hqEnt.hqProcCb[i].ulSfIdx = RGSCH_INVALID_INFO; + ueUl->hqEnt.hqProcCb[i].alloc = NULLP; +#ifdef LTEMAC_SPS + /* ccpu00139513- Initializing SPS flags*/ + ueUl->hqEnt.hqProcCb[i].isSpsActvnHqP = FALSE; + ueUl->hqEnt.hqProcCb[i].isSpsOccnHqP = FALSE; +#endif + cmLListAdd2Tail(&ueUl->hqEnt.free, &ueUl->hqEnt.hqProcCb[i].lnk); + ueUl->hqEnt.hqProcCb[i].lnk.node = (PTR)&ueUl->hqEnt.hqProcCb[i]; + } + +#ifdef EMTC_ENABLE + rgSCHEmtcInitUlUeHqEnt(cellCb, ueCfg, ueCb); +#endif + RETVOID; +} /* rgSCHUhmRgrUeCfg */ + +/** + * @brief Handler for re-initializing the HARQ entity. + * + * @details + * + * Function: rgSCHUhmRgrUeRecfg + * + * Invoked by: RGR + * + * Processing Steps: + * - Re-initialize maxHqRetx + * + * @param[in] *cellCb + * @param[in,out] *ueCb + * @param[in] *ueCfg + * @param[out] *err + * @return Void + **/ +#ifdef ANSI +PUBLIC Void rgSCHUhmRgrUeRecfg +( +RgSchCellCb *cellCb, +RgSchUeCb *ueCb, +RgrUeRecfg *ueRecfg +) +#else +PUBLIC Void rgSCHUhmRgrUeRecfg(cellCb, ueCb, ueRecfg) +RgSchCellCb *cellCb; +RgSchUeCb *ueCb; +RgrUeRecfg *ueRecfg; +#endif +{ + RgSchCmnUlUe *ueUl = RG_SCH_CMN_GET_UL_UE(ueCb, cellCb); + TRC2(rgSCHUhmRgrUeRecfg); + + /* [ccpu00123958]-ADD- Check for HARQ Reconfig from the bit mask */ + if(RGR_UE_ULHARQ_RECFG & ueRecfg->ueRecfgTypes) + { + ueUl->hqEnt.maxHqRetx = (ueRecfg->ueUlHqRecfg.maxUlHqTx - 1); + } + + RETVOID; +} /* rgSCHUhmRgrUeRecfg */ + +/** + * @brief Handler for de-initializing the HARQ entity. + * + * @details + * + * Function: rgSCHUhmFreeUe + * + * Invoked by: RGR + * + * Processing Steps: + * - + * + * @param[in,out] *ueCb + * @return Void + **/ +#ifdef ANSI +PUBLIC Void rgSCHUhmFreeUe +( +RgSchCellCb *cellCb, +RgUeUlHqCb *hqEnt +) +#else +PUBLIC Void rgSCHUhmFreeUe(cellCb, hqEnt) +RgSchCellCb *cellCb; +RgUeUlHqCb *hqEnt; +#endif +{ + TRC2(rgSCHUhmFreeUe); +#ifdef LTE_TDD + /* ccpu00117052 - MOD - Passing double pointer + for proper NULLP assignment*/ + rgSCHUtlFreeSBuf(cellCb->instIdx, + (Data **)(&(hqEnt->hqProcCb)), + hqEnt->numHqPrcs * sizeof(RgSchUlHqProcCb)); +#endif + + RETVOID; +} /* rgSCHUhmFreeUe */ + + +/** +* @brief Handler for appending the PHICH information in to the dlSf. +* +* @details +* +* Function: rgSCHUhmAppendPhich +* +* Invoked by: TOM +* +* Processing Steps: +* - Set PhichInfo in DlSf for each Hq +* +* @param[in] *RgSchCellCb +* @param[in] CmLteTimingInfo +* @param[in] idx +* @return Void +*/ +#ifdef ANSI +PUBLIC S16 rgSCHUhmAppendPhich +( +RgSchCellCb *cellCb, +CmLteTimingInfo frm, +U8 idx +) +#else +PUBLIC S16 rgSCHUhmAppendPhich (cellCb, frm, idx) +RgSchCellCb *cellCb; +CmLteTimingInfo frm; +U8 idx; +#endif +{ + U8 nDmrs; + U8 rbStart; +#ifdef LTE_TDD + U8 iPhich; +#endif + RgSchUlAlloc *ulAlloc; +#ifdef LTEMAC_HDFDD + Bool allwNack = TRUE; +#endif /* LTEMAC_HDFDD */ + RgSchCmnUlCell *cellUl = RG_SCH_CMN_GET_UL_CELL(cellCb); + + TRC2(rgSCHUhmAppendPhich) + +#ifdef RG_5GTF + RETVALUE(ROK); +#endif + if(cellUl->hqFdbkIdx[idx] != RGSCH_INVALID_INFO) + { + ulAlloc = rgSCHUtlFirstHqFdbkAlloc (cellCb, idx); + while (ulAlloc) + { + /*ccpu00106104 MOD added check for ACKNACK rep*/ + /*added check for acknack so that adaptive retx considers ue + inactivity due to ack nack repetition*/ + if((ulAlloc->ue != NULLP) && ((TRUE != ulAlloc->forMsg3) && + ((ulAlloc->ue->measGapCb.isMeasuring == TRUE) || + (ulAlloc->ue->ackNakRepCb.isAckNakRep == TRUE)))) + { + /* Mark the UE for retransmission */ + /* If UE is measuring then we should not be sending PHICH unless msg3 */ + /*UE assumes ack, if nack then do adaptive re-transmission*/ + /*ulAlloc->hqProc->rcvdCrcInd = FALSE;--*/ + ulAlloc = rgSCHUtlNextHqFdbkAlloc (cellCb, ulAlloc, idx); + continue; + } +#ifdef LTE_TDD + if (rgSCHUtlGetPhichInfo (ulAlloc->hqProc, &rbStart, &nDmrs, &iPhich) != ROK) +#else + if (rgSCHUtlGetPhichInfo (ulAlloc->hqProc, &rbStart, &nDmrs) != ROK) +#endif + { + RETVALUE (RFAILED); + } + if(nDmrs != RGSCH_INVALID_NDMRS) + { + if(cellCb->dynCfiCb.switchOvrInProgress) + { + ulAlloc->hqProc->rcvdCrcInd = TRUE; + } + + if(ulAlloc->hqProc->rcvdCrcInd) + { +#ifdef LTE_TDD + rgSCHUtlAddPhich (cellCb, frm, TRUE, nDmrs, rbStart, iPhich); +#else + rgSCHUtlAddPhich (cellCb, frm, TRUE, nDmrs, rbStart, ulAlloc->forMsg3); +#endif + } + /* Sending NACK in PHICH for failed UL TX */ + else + { +#ifdef LTE_TDD + rgSCHUtlAddPhich (cellCb, frm, FALSE, nDmrs, rbStart, iPhich); +#else +#ifdef LTEMAC_HDFDD + if (ulAlloc->ue != NULLP && ulAlloc->ue->hdFddEnbld) + { + rgSCHCmnHdFddChkNackAllow( cellCb, ulAlloc->ue, frm, &allwNack); + /* Present implementaion of non-HDFDD does not send phich req + incase of NACK. So commented this part to maintain same right + now.*/ + + if (allwNack) + { + rgSCHUtlAddPhich (cellCb, frm, FALSE, nDmrs, rbStart, ulAlloc->forMsg3); + } + else + { + rgSCHUtlAddPhich (cellCb, frm, TRUE, nDmrs, rbStart, ulAlloc->forMsg3); + } + } + else + { + rgSCHUtlAddPhich (cellCb, frm, FALSE, nDmrs, rbStart, ulAlloc->forMsg3); + } +#else + rgSCHUtlAddPhich (cellCb, frm, FALSE, nDmrs, rbStart, ulAlloc->forMsg3); +#endif/* LTEMAC_HDFDD */ +#endif + } + } + ulAlloc = rgSCHUtlNextHqFdbkAlloc (cellCb, ulAlloc, idx); + } + } + RETVALUE(ROK); +} /* rgSCHUhmAppendPhich */ + +/** + * @brief This function initializes the DL HARQ Entity of UE. + * + * @details + * + * Function: rgSCHUhmHqEntInit + * Purpose: This function initializes the UL HARQ Processes of + * UE control block. This is performed at the time + * of creating UE control block. + * + * Invoked by: configuration module + * + * @param[in] RgSchUeCb* ueCb + * @return S16 + * -# ROK + * -# RFAILED + * + **/ +#ifdef ANSI +PUBLIC S16 rgSCHUhmHqEntInit +( +RgSchCellCb *cellCb, +RgSchUeCb *ueCb +) +#else +PUBLIC S16 rgSCHUhmHqEntInit(cellCb, ueCb) +RgSchCellCb *cellCb; +RgSchUeCb *ueCb; +#endif +{ + RgSchCmnUlUe *ueUl = RG_SCH_CMN_GET_UL_UE(ueCb, cellCb); +#ifdef LTE_TDD + Inst inst = ueCb->cell->instIdx; +#endif + TRC2(rgSCHUhmHqEntInit) + +#ifndef LTE_TDD + /* Init the HARQ processes */ + ueUl->hqEnt.numHqPrcs = RGSCH_NUM_UL_HQ_PROC; +#else + /* Init the HARQ processes */ + ueUl->hqEnt.numHqPrcs = + rgSchTddUlNumHarqProcTbl[ueCb->cell->ulDlCfgIdx]; + if (rgSCHUtlAllocSBuf(inst, (Data **)&ueUl->hqEnt.hqProcCb, + ueUl->hqEnt.numHqPrcs * \ + sizeof(RgSchUlHqProcCb)) != ROK) + { + RETVALUE(RFAILED); + } +#endif + + RETVALUE(ROK); +} /* rgSCHUhmHqEntInit */ + +#ifdef RG_5GTF +/** + * @brief This function gets an available HARQ process. + * + * @details + * + * Function: rgSCHUhmGetAvlHqProc + * Purpose: This function returns an available HARQ process in + * the UL direction. All HARQ processes are maintained + * in queues of free and inuse. + * + * 1. Check if the free queue is empty. If yes, return + * RFAILED + * 2. If not empty, update the proc variable with the + * first process in the queue. Return ROK. + * + * Invoked by: scheduler + * + * @param[in] RgSchUeCb *ue + * @param[in] CmLteTimingInfo timingInfo + * @param[out] RgSchDlHqProc **hqP + * @return S16 + * -#ROK if successful + * -#RFAILED otherwise + * + **/ +#ifdef ANSI +PUBLIC S16 rgSCHUhmGetAvlHqProc +( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgSchUlHqProcCb **hqP +) +#else +PUBLIC S16 rgSCHUhmGetAvlHqProc (cell, ue, hqP) +RgSchCellCb *cell; +RgSchUeCb *ue; +RgSchUlHqProcCb **hqP; +#endif +{ + RgSchCmnUlCell *cellUl = RG_SCH_CMN_GET_UL_CELL(cell); + RgSchCmnUlUe *ueUl = RG_SCH_CMN_GET_UL_UE(ue, cell); + RgSchUlHqProcCb *tmpHqProc; + CmLList *tmp; + RgUeUlHqCb *hqE; + + TRC2(rgSCHUhmGetAvlHqProc); + + hqE = &ueUl->hqEnt; + + CM_LLIST_FIRST_NODE(&(hqE->free), tmp); + + if (NULLP == tmp) + { + //RLOG_ARG3(L_ERROR,DBG_CELLID,cell->cellId, + // "rgSCHUhmGetAvlHqProc free %ld inUse %ld ue %d" + // , hqE->free.count, hqE->inUse.count, ue->ueId); + //printf("5GTF_ERROR rgSCHUhmGetAvlHqProc cellId %d %ld inUse %ld ue %d" + //, cell->cellId, hqE->free.count, hqE->inUse.count, ue->ueId); + /* No Harq Process available in the free queue. */ + RETVALUE(RFAILED); + } + + tmpHqProc = (RgSchUlHqProcCb *)(tmp->node); + + /* Remove the element from the free Queue */ + cmLListDelFrm(&hqE->free, tmp); + + /* Add the element into the inUse Queue as well */ + cmLListAdd2Tail(&hqE->inUse, &tmpHqProc->lnk); + +#ifdef UL_ADPT_DBG + printf("rgSCHUhmGetAvlHqProc cellId %d free %ld inUse %ld ue %d time (%d %d)\n",cell->cellId, hqE->free.count, hqE->inUse.count, ue->ueId,cellUl->schdTime.sfn,cellUl->schdTime.subframe); +#endif + tmpHqProc->schdTime = cellUl->schdTime; + + *hqP = tmpHqProc; + + RETVALUE(ROK); +} /* rgSCHUhmGetAvlHqProc */ + +/** + * @brief Handler for identifying the HARQ process cb associated with the + * TX Time. + * + * @details + * + * Function: rgSCHUhmGetUlProcByTime + * + * Processing Steps: + * - Return pointer to uplink harq process corresponding to the timing + * information passed. + * + * @param[in] *ue + * @param[in] idx + * @return RgSchUlHqProcCb* + * -# Pointer to harq process corresponding to index + * -# NULL + **/ +#ifdef ANSI +PUBLIC RgSchUlHqProcCb* rgSCHUhmGetUlProcByTime +( +RgSchCellCb *cell, +RgSchUeCb *ue, +CmLteTimingInfo frm +) +#else +PUBLIC RgSchUlHqProcCb* rgSCHUhmGetUlProcByTime(cell, ue, frm) +RgSchCellCb *cell; +RgSchUeCb *ue; +CmLteTimingInfo frm; +#endif +{ + RgSchCmnUlUe *ueUl = RG_SCH_CMN_GET_UL_UE(ue, cell); + CmLListCp *lst = &ueUl->hqEnt.inUse; + CmLList *lnk = lst->first; + RgSchUlHqProcCb *proc; + + TRC2(rgSCHUhmGetUlProcByTime); + + while (lnk) + { + proc = (RgSchUlHqProcCb *)(lnk->node); + lnk = lnk->next; + // printf("compare rgSCHUhmGetUlProcByTime time (%d %d) CRC time (%d %d) proc->procId %d \n",proc->schdTime.sfn,proc->schdTime.subframe,frm.sfn,frm.subframe ,proc->procId); + if (RGSCH_TIMEINFO_SAME(proc->schdTime, frm)) + { + // printf("Harq timing Matched rgSCHUhmGetUlProcByTime time (%d %d) proc->procId %d \n",proc->schdTime.sfn,proc->schdTime.subframe, proc->procId); + RETVALUE(proc); + } + } + + RETVALUE(NULLP); +} /* rgSCHUhmGetUlProcByTime */ +#endif + + +/********************************************************************** + + End of file +**********************************************************************/ diff --git a/src/5gnrmac/rg_sch_utl.c b/src/5gnrmac/rg_sch_utl.c new file mode 100755 index 000000000..c72396837 --- /dev/null +++ b/src/5gnrmac/rg_sch_utl.c @@ -0,0 +1,12631 @@ +/******************************************************************************* +################################################################################ +# Copyright (c) [2017-2019] [Radisys] # +# # +# 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. # +################################################################################ +*******************************************************************************/ + +/************************************************************************ + + Name: LTE-MAC layer + + Type: C source file + + Desc: C source code for Entry point fucntions + + File: rg_sch_utl.c + +**********************************************************************/ + +/** @file rg_sch_utl.c +@brief This file implements the schedulers main access to MAC layer code. +*/ + +static const char* RLOG_MODULE_NAME="MAC"; +static int RLOG_MODULE_ID=4096; +static int RLOG_FILE_ID=177; + +/* header include files -- defines (.h) */ +#include "envopt.h" /* environment options */ +#include "envdep.h" /* environment dependent */ +#include "envind.h" /* environment independent */ +#include "gen.h" /* general layer */ +#include "ssi.h" /* system service interface */ +#include "cm_hash.h" /* common hash list */ +#include "cm_llist.h" /* common linked list library */ +#include "cm_err.h" /* common error */ +#include "cm_lte.h" /* common LTE */ +#include "lrg.h" +#include "rgr.h" +#include "tfu.h" +#include "rg_env.h" +#include "rg_sch_err.h" +#include "rg_sch_inf.h" +#include "rg_sch.h" +#include "rg_sch_cmn.h" +#include "rgm.h" +#include "rl_interface.h" +#include "rl_common.h" + +/* header/extern include files (.x) */ +#include "gen.x" /* general layer typedefs */ +#include "ssi.x" /* system services typedefs */ +#include "cm5.x" /* common timers */ +#include "cm_hash.x" /* common hash list */ +#include "cm_lib.x" /* common library */ +#include "cm_llist.x" /* common linked list */ +#include "cm_mblk.x" /* memory management */ +#include "cm_tkns.x" /* common tokens */ +#include "cm_lte.x" /* common tokens */ +#include "tfu.x" /* TFU types */ +#include "lrg.x" /* layer management typedefs for MAC */ +#include "rgr.x" /* layer management typedefs for MAC */ +#include "rgm.x" +#include "rg_sch_inf.x" /* typedefs for Scheduler */ +#include "rg_sch.x" /* typedefs for Scheduler */ +#include "rg_sch_cmn.x" /* typedefs for Scheduler */ +#ifdef EMTC_ENABLE +#include "rg_sch_emtc_ext.x" +#endif + + +/* SR_RACH_STATS */ +U32 rgNumPrachRecvd =0; /* Num of Rach Req received including dedicated preambles */ +U32 rgNumRarSched =0; /* Num of RARs sent */ +U32 rgNumBI =0; /* Num of BackOff Ind sent */ +U32 rgNumMsg3CrcPassed =0; /* Num of CRC success for Msg3 */ +U32 rgNumMsg3CrcFailed =0; /* Num of CRC fail for Msg 3 */ +U32 rgNumMsg3FailMaxRetx =0; /* Num of Msg3 fail after Max Retx attempts */ +U32 rgNumMsg4Ack =0; /* Num of Acks for Msg4 Tx */ +U32 rgNumMsg4Nack =0; + /* Num of Nacks for Msg4 Tx */ +U32 rgNumMsg4FailMaxRetx =0; /* Num of Msg4 Tx failed after Max Retx attempts */ +U32 rgNumSrRecvd =0; /* Num of Sched Req received */ +U32 rgNumSrGrant =0; /* Num of Sched Req Grants sent */ +U32 rgNumMsg3CrntiCE =0; /* Num of Msg 3 CRNTI CE received */ +U32 rgNumDedPream =0; /* Num of Dedicated Preambles recvd */ +U32 rgNumMsg3CCCHSdu =0; /* Num of Msg 3 CCCH Sdus recvd */ +U32 rgNumCCCHSduCrntiNotFound =0; /*UE Ctx not found for CCCH SDU Msg 3 */ +U32 rgNumCrntiCeCrntiNotFound =0; /*UE Ctx not found for CRNTI CE Msg 3 */ +U32 rgNumMsg4WithCCCHSdu =0; /* Num of Msg4 with CCCH Sdu */ +U32 rgNumMsg4WoCCCHSdu =0; /* Num of Msg4 without CCCH Sdu */ +U32 rgNumMsg4Dtx =0; /* Num of DTX received for Msg 4 */ +U32 rgNumMsg3AckSent =0; /* Num of PHICH Ack sent for Msg 3 */ +U32 rgNumMsg3NackSent =0; /* Num of PHICH Nack sent for Msg 3 */ +U32 rgNumMsg4PdcchWithCrnti =0; /* Num of PDCCH for CRNTI based contention resolution */ +U32 rgNumRarFailDuetoRntiExhaustion =0; /* Num of RACH Failures due to RNTI pool exhaution */ +U32 rgNumTAModified =0; /* Num of times TA received is different from prev value */ +U32 rgNumTASent =0; /* Num of TA Command sent */ +U32 rgNumMsg4ToBeTx =0; /* Num of times MSG4 that should be sent */ +U32 rgNumMsg4Txed =0; /* Num of MSG4 actually sent *//* ysNumMsg4ToBeTx -ysNumMsg4Txed == Failed MSG4 TX */ +U32 rgNumMsg3DtxRcvd =0; /* CRC Fail with SINR < 0 */ + +U32 rgNumDedPreamUECtxtFound =0; /* Num of Dedicated Preambles recvd */ + +PRIVATE U8 rgSchDciAmbigSizeTbl[61] = {0,0,0,0,0,0,0,0,0,0,0, + 0,1,0,1,0,1,0,0,0,1, + 0,0,0,1,0,1,0,0,0,0, + 0,1,0,0,0,0,0,0,0,1, + 0,0,0,1,0,0,0,0,0,0, + 0,0,0,0,0,1,0,0,0,0}; + +/* local defines */ + +EXTERN U32 rgSchCmnBetaCqiOffstTbl[16]; +EXTERN U32 rgSchCmnBetaRiOffstTbl[16]; +EXTERN RgSchdApis rgSchCmnApis; +EXTERN PUBLIC S16 RgUiRgmSendPrbRprtInd ARGS(( +Pst* pst, +SuId suId, +RgmPrbRprtInd *prbRprtInd +)); + +EXTERN PUBLIC S16 RgUiRgmSendTmModeChangeInd ARGS(( +Pst* pst, +SuId suId, +RgmTransModeInd *txModeChngInd +)); +#ifdef EMTC_ENABLE +EXTERN PUBLIC S16 rgSCHEmtcUtlGetSfAlloc ARGS(( +RgSchCellCb *cell +)); +EXTERN PUBLIC S16 rgSCHEmtcUtlPutSfAlloc ARGS(( +RgSchCellCb *cell +)); +EXTERN PUBLIC Void rgSCHEmtcUtlUpdUeDciSize ARGS(( +RgSchCellCb *cell, +RgSchUeCb *ueCb +)); +EXTERN PUBLIC Void rgSCHEmtcGetDciFrmt61ASize ARGS(( +RgSchCellCb *cell +)); +EXTERN PUBLIC Void rgSCHEmtcGetDciFrmt60ASize ARGS(( +RgSchCellCb *cell +)); +EXTERN PUBLIC S16 rgSCHEmtcUtlFillPdschDciInfo ARGS(( +TfuPdschDciInfo *pdsch, +TfuDciInfo *pdcchDci +)); +EXTERN PUBLIC Void rgSCHEmtcUtlRlsRnti ARGS(( +RgSchCellCb *cell, +RgSchRntiLnk *rntiLnk, +U8 *isLegacy +)); +EXTERN PUBLIC S16 rgSCHEmtcPdcchAlloc ARGS(( +RgSchCellCb *cell, +RgSchPdcch *pdcch +)); +EXTERN PUBLIC Void rgSCHEmtcPdcchFree ARGS(( +RgSchCellCb *cell, +RgSchPdcch *pdcch +)); +#endif +/* Functions specific to TM1/TM2/TM6/TM7 for PRB calculation*/ +PUBLIC Void rgSchUtlDlCalc1CwPrb ARGS(( RgSchCellCb *cell, + RgSchUeCb *ue, + U32 bo, + U32 *prbReqrd)); + +/* Functions specific to TM3/TM4 for PRB calculation*/ +PUBLIC Void rgSchUtlDlCalc2CwPrb ARGS(( RgSchCellCb *cell, + RgSchUeCb *ue, + U32 bo, + U32 *prbReqrd)); + +#ifdef LTE_ADV +PUBLIC RgSchCellCb* rgSchUtlGetCellCb ARGS(( Inst inst, + U16 cellId +)); +#endif + +typedef Void (*RgSchUtlDlCalcPrbFunc) ARGS((RgSchCellCb *cell, RgSchUeCb *ue, + U32 bo, U32 *prbRequrd)); +#ifndef LTE_ADV +/* Functions specific to each transmission mode for PRB calculation*/ +RgSchUtlDlCalcPrbFunc dlCalcPrbFunc[7] = {rgSchUtlDlCalc1CwPrb, +rgSchUtlDlCalc1CwPrb, rgSchUtlDlCalc2CwPrb, rgSchUtlDlCalc2CwPrb, +NULLP, rgSchUtlDlCalc1CwPrb, rgSchUtlDlCalc1CwPrb}; + +#else +/* Functions specific to each transmission mode for PRB calculation*/ +RgSchUtlDlCalcPrbFunc dlCalcPrbFunc[9] = {rgSchUtlDlCalc1CwPrb, +rgSchUtlDlCalc1CwPrb, rgSchUtlDlCalc2CwPrb, rgSchUtlDlCalc2CwPrb, +NULLP, rgSchUtlDlCalc1CwPrb, rgSchUtlDlCalc1CwPrb, NULLP, NULLP}; + +#endif + +#ifdef LTE_TDD +/* The below table will be used to map the UL SF number in a TDD Cfg 0 + frame to the ul Sf array maintained in cellCb */ +PRIVATE U8 rgSchTddCfg0UlSfTbl[] = {2, 3, 4, 7, 8, 9}; +#endif + +PRIVATE S16 rgSCHUtlUlAllocDbInit ARGS(( + RgSchCellCb *cell, + RgSchUlAllocDb *db, + U8 maxAllocs + )); +PRIVATE Void rgSCHUtlUlAllocDbDeinit ARGS(( + RgSchCellCb *cell, + RgSchUlAllocDb *db + )); +PRIVATE S16 rgSCHUtlUlHoleDbInit ARGS(( + RgSchCellCb *cell, + RgSchUlHoleDb *db, + U8 maxHoles, + U8 start, + U8 num + )); +PRIVATE Void rgSCHUtlUlHoleDbDeinit ARGS(( + RgSchCellCb *cell, + RgSchUlHoleDb *db + )); + +PRIVATE S16 rgSCHChkBoUpdate ARGS(( + RgSchCellCb *cell, + RgInfCmnBoRpt *boUpdt + )); +#ifdef TFU_UPGRADE +PRIVATE U8 rgSCHUtlFetchPcqiBitSz ARGS(( + RgSchCellCb *cell, + RgSchUeCb *ueCb, + U8 numTxAnt + )); +#endif +/* sorted in ascending order of tbSz */ +CONSTANT struct rgSchUtlBcchPcchTbSz +{ + U8 rbIndex; /* RB index {2,3} */ + U16 tbSz; /* one of the Transport block size in bits of + * rbIndex 2 or 3 */ + /* Corrected allocation for common channels */ + U8 mcs; /* imcs */ +} rgSchUtlBcchPcchTbSzTbl[44] = { + { 2, 32, 0 }, { 2, 56, 1 }, { 2, 72, 2 }, { 3, 88, 1 }, + { 2, 104, 3 }, { 2, 120, 4 }, { 2, 144, 5 }, { 2, 176, 6 }, + { 3, 208, 4 }, { 2, 224, 7 }, { 2, 256, 8 }, { 2, 296, 9 }, + { 2, 328, 10 }, { 2, 376, 11 }, { 3, 392, 8 }, { 2, 440, 12 }, + { 3, 456, 9 }, { 2, 488, 13 }, { 3, 504, 10 }, { 2, 552, 14 }, + { 3, 584, 11 }, { 2, 600, 15 }, { 2, 632, 16 }, { 3, 680, 12 }, + { 2, 696, 17 }, { 3, 744, 13 }, { 2, 776, 18 }, { 2, 840, 19 }, + { 2, 904, 20 }, { 3, 968, 16 }, { 2, 1000, 21 }, { 2, 1064, 22 }, + { 2, 1128, 23 }, { 3, 1160, 18 }, { 2, 1192, 24 }, { 2, 1256, 25 }, + { 3, 1288, 19 }, { 3, 1384, 20 }, { 2, 1480, 26 }, { 3, 1608, 22 }, + { 3, 1736, 23 }, { 3, 1800, 24 }, { 3, 1864, 25 }, { 3, 2216, 26 } +}; + +/* local typedefs */ + +/* local externs */ + +/* forward references */ +#ifdef LTE_TDD +PRIVATE Void rgSCHUtlUpdPrachOcc ARGS(( +RgSchCellCb *cell, +RgrTddPrachInfo *cellCfg)); +#endif + +#define RGSCH_NUM_PCFICH_REG 4 +#define RGSCH_NUM_REG_PER_CCE 9 +#define RGSCH_NUM_REG_PER_PHICH_GRP 3 + +#ifdef LTE_TDD +#define RGSCH_INITPHICH(_phich, _hqFeedBack, _nDmrs, _rbStart, _iPhich) {\ + (_phich)->hqFeedBack = _hqFeedBack; \ + (_phich)->rbStart = _rbStart; \ + (_phich)->nDmrs = _nDmrs; \ + (_phich)->iPhich = _iPhich; \ + (_phich)->lnk.next = NULLP; \ + (_phich)->lnk.prev = NULLP; \ + (_phich)->lnk.node = (PTR)(_phich); \ +} +#else +#define RGSCH_INITPHICH(_phich, _hqFeedBack, _nDmrs, _rbStart, _isForMsg3) {\ + (_phich)->hqFeedBack = _hqFeedBack; \ + (_phich)->rbStart = _rbStart; \ + (_phich)->nDmrs = _nDmrs; \ + (_phich)->isForMsg3 = _isForMsg3; \ + (_phich)->lnk.next = NULLP; \ + (_phich)->lnk.prev = NULLP; \ + (_phich)->lnk.node = (PTR)(_phich); \ +} +#endif + +#define RGSCH_PHICH_ALLOC(_inst,_dataPtr, _size, _ret) {\ + _ret = rgSCHUtlAllocSBuf(_inst, (Data **)&_dataPtr, _size); \ +} + +/* ccpu00117052 - MOD - Passing double pointer +for proper NULLP assignment*/ +#define RGSCH_PHICH_FREE(_inst, _dataPtr, _size) {\ + rgSCHUtlFreeSBuf(_inst, (Data **)(&(_dataPtr)), _size); \ +} + +#ifdef TFU_UPGRADE +#define RGSCH_GETBIT(a, b) ((((U8*)a)[(b)>>3] >> ((7-((b)&7)))) & 1) + +/* +* +* Fun: rgSCHUtlPower +* +* Desc: This function finds of the Power of x raised to n +* +* Ret: value of x raised to n +* +* Notes: None +* +* File: rg_sch_utl.c +* +*/ +#ifdef ANSI +PUBLIC F64 rgSCHUtlPower +( +F64 x, +F64 n +) +#else +PUBLIC F64 rgSCHUtlPower(x, n) +F64 x; +F64 n; +#endif +{ + if( n==0 ) + { + RETVALUE( 1 ); + } + else if ( n>0 ) + { + RETVALUE( x * rgSCHUtlPower( x, n-1 ) ); + } + else + { + RETVALUE( (1/x) * rgSCHUtlPower( x, n+1 ) ); + } +} /* end of rgSCHUtlPower*/ + +/* +* +* Fun: rgSCHUtlParse +* +* Desc: This function parses bits x to y of an array and +* returns the integer value out of it. +* +* Ret: integer value of z bits +* +* Notes: None +* +* File: rg_sch_utl.c +* +*/ +#ifdef ANSI +PUBLIC U32 rgSCHUtlParse +( +U8 *buff, +U8 startPos, +U8 endPos, +U8 buffSize +) +#else +PUBLIC U32 rgSCHUtlParse(buff, startPos, endPos, buffSize) +U8 *buff; +U8 startPos; +U8 endPos; +U8 buffSize; +#endif +{ + U8 pointToChar,pointToEnd, loop; + U8 size = endPos - startPos; + F64 result = 0; + TRC2(rgSCHUtlParse); + pointToEnd = (startPos)%8; + for ( loop=0; loopinstIdx; + S16 ret; + U16 offsetStepMask; + + TRC2(rgSCHUtlPdcchAvail); + + /* V5G_213 : 10.1 */ + offset = 0; + byte = &pdcchInfo->map[0]; + initMask = (0xffff >> (16 - aggrLvl)); + currMask = initMask; + /* if N(symbol, xPDCCH) =2, then xPDCCH will be candidates in + * search space of index {0,1,2,3} and {8,9,..14} + */ + if ((cell->cell5gtfCb.cfi == 2) && (aggrLvl == CM_LTE_AGGR_LVL2)) + { + offsetStepMask = 0xc; + } + else + { + offsetStepMask = 0xc0; + } + + /* Loop till the number of bytes available in the CCE map */ + while (offset < ((pdcchInfo->nCce+ 7) >> 3)) + { + byte = &pdcchInfo->map[offset]; + /* Checking for available CCE */ + if ((*byte & currMask) == 0) + { + break; + } + /* if the number of CCEs required are not available, move to next offset */ + if (currMask & offsetStepMask) + { + offset++; + currMask = initMask; + } + else + { + /* Move to the next available CCE index in the current byte(cce map) */ + currMask = currMask << aggrLvl; + } + } + + if ((offset >= ((pdcchInfo->nCce + 7) >> 3)) || + ((aggrLvl == CM_LTE_AGGR_LVL16) && (offset > 0))) + { + RETVALUE(FALSE); + } + + byte = &pdcchInfo->map[offset]; + + if (cell->pdcchLst.first != NULLP) + { + *pdcch = (RgSchPdcch *)(cell->pdcchLst.first->node); + cmLListDelFrm(&cell->pdcchLst, cell->pdcchLst.first); + } + else + { + ret = rgSCHUtlAllocSBuf(inst, (Data **)pdcch, sizeof(RgSchPdcch)); + if(ROK != ret) + { + RETVALUE(FALSE); + } + } + + if (*pdcch) + { + (*byte) |= currMask; + /* ALL CCEs will be used in case of level 16 */ + if (aggrLvl == CM_LTE_AGGR_LVL16) + { + *(byte+1) |= currMask; + } + (*pdcch)->aggrLvl = aggrLvl; + cmLListAdd2Tail(&pdcchInfo->pdcchs, &((*pdcch)->lnk)); + (*pdcch)->lnk.node = (PTR)*pdcch; + (*pdcch)->nCce = aggrLvl; + (*pdcch)->ue = NULLP; + } + RETVALUE(TRUE); +} + + + +/** + * @brief This function releases a PDCCH + * + * @details + * + * Function: rgSCHUtlPdcchPut + * Purpose: This function releases a PDCCH. + * steps: + * 1. Locate the set of bits that represent the PDCCH for + * the provided location. + * 2. Set all of the bits to zero. + * 3. Release the memory of PDCCH to the cell free Q + * + * Invoked by: scheduler + * + * @param[in] RgSchPdcchInfo* pdcchInfo + * @param[in] U8 loc + * @param[in] U8 aggrLvl + * @return Void + * + **/ +#ifdef ANSI +PUBLIC Void rgSCHUtlPdcchPut +( +RgSchCellCb *cell, +RgSchPdcchInfo *pdcchInfo, +RgSchPdcch *pdcch +) +#else +PUBLIC Void rgSCHUtlPdcchPut(cell, pdcchInfo, pdcch) +RgSchCellCb *cell; +RgSchPdcchInfo *pdcchInfo; +RgSchPdcch *pdcch; +#endif +{ + U8 *byte; + U8 offset; + U8 mask; + + TRC2(rgSCHUtlPdcchPut); + + switch(pdcch->aggrLvl) + { + case CM_LTE_AGGR_LVL2: + offset = (pdcch->nCce >> 1) & 3; + mask = 0x3 << (offset * 2); /*ccpu00128826 - Offset Correction */ + break; + case CM_LTE_AGGR_LVL4: + offset = (pdcch->nCce >> 2) & 1; + mask = 0xf << (offset * 4);/*ccpu00128826 - Offset Correction */ + break; + case CM_LTE_AGGR_LVL8: + mask = 0xff; + break; + case CM_LTE_AGGR_LVL16: + mask = 0xffff; + break; + default: + RETVOID; + } + /* Placing common computation of byte from all the cases above here + for optimization */ + byte = &pdcchInfo->map[pdcch->nCce >> 3]; + + cmLListDelFrm(&pdcchInfo->pdcchs, &pdcch->lnk); + cmLListAdd2Tail(&cell->pdcchLst, &pdcch->lnk); + pdcch->lnk.node = (PTR)pdcch; + pdcch->ue = NULLP; + (*byte) &= ~mask; + + RETVOID; +} + + +/** + * @brief This function initializes PDCCH information for frame + * + * @details + * + * Function: rgSCHUtlPdcchInit + * Purpose: This function initializes PDCCH information for + * a subframe. It removes the list of PDCCHs allocated + * in the prior use of this subframe structure. + * + * Invoked by: rgSCHUtlSubFrmPut + * + * @param[in] RgSchCellCb* cell + * @param[in] RgSubFrm* subFrm + * @return Void + * + **/ +#ifdef ANSI +PUBLIC Void rgSCHUtlPdcchInit +( +RgSchCellCb *cell, +RgSchDlSf *subFrm, +U16 nCce +) +#else +PUBLIC Void rgSCHUtlPdcchInit(cell, subFrm, nCce) +RgSchCellCb *cell; +RgSchDlSf *subFrm; +U16 nCce; +#endif +{ + RgSchPdcchInfo *pdcchInfo; + RgSchPdcch *pdcch; + Inst inst = cell->instIdx; + U8 extraBits; + U32 cceMapSz; + + TRC2(rgSCHUtlPdcchInit); + + pdcchInfo = &subFrm->pdcchInfo; + while(pdcchInfo->pdcchs.first != NULLP) + { + pdcch = (RgSchPdcch *)pdcchInfo->pdcchs.first->node; + cmLListDelFrm(&pdcchInfo->pdcchs, pdcchInfo->pdcchs.first); + cmLListAdd2Tail(&cell->pdcchLst, &pdcch->lnk); + pdcch->ue = NULLP; + } + cmLListInit(&pdcchInfo->pdcchs); + +#ifdef LTEMAC_SPS + subFrm->relPdcch = NULLP; +#endif + + cceMapSz = ((pdcchInfo->nCce + 7) >> 3); + + /* The bitMap array size is the number of ceiling(CCEs/8) */ + /* If nCce received is not the same as the one stored in + * pdcchInfo, free the pdcchInfo map */ + + if(pdcchInfo->nCce != nCce) + { + if(pdcchInfo->nCce) + { + rgSCHUtlFreeSBuf(inst, (Data **)(&(pdcchInfo->map)), cceMapSz); + } + pdcchInfo->nCce = nCce; + cceMapSz = ((pdcchInfo->nCce + 7) >> 3); + rgSCHUtlAllocSBuf(inst, (Data **)&pdcchInfo->map, + cceMapSz); + if (pdcchInfo->map == NULLP) + { + /* Generate log error here */ + RETVOID; + } + } + + cmMemset(subFrm->pdcchInfo.map, 0, cceMapSz); + /* If nCce is not exactly same as the bitMap size(no of bits allocated + * to represent the Cce's, then mark the extra bits as unavailable + extra bits = (((pdcchInfo->nCce + 7) >> 3)*8) - pdcchInfo->nCce + The last byte of bit map = subFrm->pdcchInfo.map[((pdcchInfo->nCce + 7) >> 3) - 1] + NOTE : extra bits are most significant of the last byte eg. */ + extraBits = (cceMapSz)*8 - pdcchInfo->nCce; + subFrm->pdcchInfo.map[cceMapSz - 1] |= + ((1 << extraBits) - 1) << (8 - extraBits); + RETVOID; +} + +/* LTE_ADV_FLAG_REMOVED_START */ +/** + * @brief This function frees Pool + * @details + * + * Function: rgSchSFRTotalPoolFree + * + * Invoked by: rgSchSFRTotalPoolInit + * + * @param[in] RgSchCellCb* cell + * @param[in] RgSubFrm* subFrm + * @return Void + * + **/ +#ifdef ANSI +PUBLIC Void rgSchSFRTotalPoolFree +( + RgSchSFRTotalPoolInfo *sfrTotalPoolInfo, + RgSchCellCb *cell + ) +#else +PUBLIC Void rgSchSFRTotalPoolFree(sfrTotalPoolInfo, cell) + RgSchSFRTotalPoolInfo *sfrTotalPoolInfo; + RgSchCellCb *cell; +#endif +{ + CmLListCp *l; + CmLList *n; + TRC2(rgSchSFRTotalPoolFree); + + /*Deinitialise if these cc pools and ce pools are already existent*/ + l = &sfrTotalPoolInfo->ccPool; + n = cmLListFirst(l); + while (n != NULL) + { + /*REMOVING Cell Centred POOLS IF ANY*/ + n = cmLListDelFrm(l, n); + + /* Deallocate buffer */ + rgSCHUtlFreeSBuf(cell->instIdx, (Data **)(&(n->node)), sizeof(RgSchSFRPoolInfo)); + + /* Deallocate buffer */ + rgSCHUtlFreeSBuf(cell->instIdx, (Data **)(&(n)), sizeof(CmLList)); + n = cmLListNext(l); + } + + /*REMOVING Cell Edged POOLS IF ANY*/ + l = &sfrTotalPoolInfo->cePool; + n = cmLListFirst(l); + while (n != NULL) + { + n = cmLListDelFrm(l, n); + + /* Deallocate buffer */ + rgSCHUtlFreeSBuf(cell->instIdx, (Data **)(&(n->node)), sizeof(RgSchSFRPoolInfo)); + + /* Deallocate buffer */ + rgSCHUtlFreeSBuf(cell->instIdx, (Data **)(&(n)), sizeof(CmLList)); + n = cmLListNext(l); + } + +} + +/** + * @brief This function resets temporary variables in Pool + * @details + * + * Function: rgSchSFRResetPoolVariables + * + * Invoked by: rgSCHSFRUtlTotalPoolInit + * + * @param[in] RgSchCellCb* cell + * @param[in] RgSubFrm* subFrm + * @return Void + * + **/ +#ifdef ANSI +PUBLIC S16 rgSchSFRTotalPoolInit +( + RgSchCellCb *cell, + RgSchDlSf *sf + ) +#else +PRIVATE Void rgSchSFRTotalPoolInit(cell, sf) + RgSchCellCb *cell; + RgSchDlSf *sf; +#endif +{ + /* Initialise the variables */ + RgSchSFRPoolInfo *sfrCCPool; + RgSchSFRPoolInfo *sfrCEPool; + CmLListCp *l; + CmLList *n; + CmLList *temp = NULLP; + S16 ret = 0; + + TRC2(rgSchSFRTotalPoolInit); + + rgSchSFRTotalPoolFree(&sf->sfrTotalPoolInfo, cell); + sf->sfrTotalPoolInfo.CCPool1BwAvlbl = 0; + sf->sfrTotalPoolInfo.CCPool2BwAvlbl = 0; + sf->sfrTotalPoolInfo.CEPoolBwAvlbl = 0; + sf->sfrTotalPoolInfo.CC1 = FALSE; + sf->sfrTotalPoolInfo.CC2 = FALSE; + /*Initialise the CE Pools*/ + cmLListInit (&(sf->sfrTotalPoolInfo.cePool)); + + ret = rgSCHUtlAllocSBuf(cell->instIdx, (Data **)&temp, sizeof(CmLList)); + if (ret != ROK) + { + RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId, + "CE Pool memory allocation FAILED for cell"); + rgSchSFRTotalPoolFree(&sf->sfrTotalPoolInfo, cell); + RETVALUE(RFAILED); + } + + ret = rgSCHUtlAllocSBuf(cell->instIdx, (Data **)&temp->node, sizeof(RgSchSFRPoolInfo)); + if (ret != ROK) + { + RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId, + "CE Pool memory allocation FAILED for cell "); + rgSchSFRTotalPoolFree(&sf->sfrTotalPoolInfo,cell); + RETVALUE(RFAILED); + } + + l = &sf->sfrTotalPoolInfo.cePool; + cmLListAdd2Tail(l, temp); + + /*Initialise Bandwidth and startRB and endRB for each pool*/ + n = cmLListFirst(l); + + /* Initialise the CE Pools */ + sfrCEPool = (RgSchSFRPoolInfo*)n->node; + + sfrCEPool->poolstartRB = cell->lteAdvCb.sfrCfg.cellEdgeRbRange.startRb; + sfrCEPool->poolendRB = cell->lteAdvCb.sfrCfg.cellEdgeRbRange.endRb; + sfrCEPool->bw = sfrCEPool->poolendRB - sfrCEPool->poolstartRB + 1; + sf->sfrTotalPoolInfo.CEPoolBwAvlbl = sfrCEPool->bw; + + sfrCEPool->bwAlloced = 0; + sfrCEPool->type2Start = sfrCEPool->poolstartRB; + sfrCEPool->type2End = RGSCH_CEIL(sfrCEPool->poolstartRB, cell->rbgSize); + sfrCEPool->type0End = ((sfrCEPool->poolendRB + 1) / cell->rbgSize) - 1; + sfrCEPool->pwrHiCCRange.startRb = 0; + sfrCEPool->pwrHiCCRange.endRb = 0; + + /*Initialise CC Pool*/ + cmLListInit (&(sf->sfrTotalPoolInfo.ccPool)); + + /*Add memory and Update CCPool*/ + ret = rgSCHUtlAllocSBuf(cell->instIdx, (Data **)&temp, sizeof(CmLList)); + if (ret != ROK) + { + RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId, + "CC Pool memory allocation FAILED for cell "); + rgSchSFRTotalPoolFree(&sf->sfrTotalPoolInfo,cell); + RETVALUE(RFAILED); + } + + ret = rgSCHUtlAllocSBuf(cell->instIdx, (Data **)&temp->node, sizeof(RgSchSFRPoolInfo)); + if (ret != ROK) + { + RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId, + "CC Pool memory allocation FAILED for cell "); + rgSchSFRTotalPoolFree(&sf->sfrTotalPoolInfo,cell); + RETVALUE(RFAILED); + } + + l = &sf->sfrTotalPoolInfo.ccPool; + cmLListAdd2Tail(l, temp); + + /*Initialise Bandwidth and startRB and endRB for each pool*/ + if(sfrCEPool->poolstartRB) + { + n = cmLListFirst(l); + sfrCCPool = (RgSchSFRPoolInfo*)n->node; + + sfrCCPool->poolstartRB = 0; + sfrCCPool->poolendRB = sfrCEPool->poolstartRB - 1; + sfrCCPool->bw = sfrCCPool->poolendRB - sfrCCPool->poolstartRB + 1; + sf->sfrTotalPoolInfo.CCPool1BwAvlbl = sfrCCPool->bw; + sfrCCPool->bwAlloced = 0; + sfrCCPool->type2Start = 0; + sfrCCPool->type2End = 0; + sfrCCPool->type0End = ((sfrCCPool->poolendRB + 1) / cell->rbgSize) - 1; + sf->sfrTotalPoolInfo.CC1 = TRUE; + sfrCCPool->pwrHiCCRange.startRb = 0; + sfrCCPool->pwrHiCCRange.endRb = 0; + } + else + { + n = cmLListFirst(l); + sfrCCPool = (RgSchSFRPoolInfo*)n->node; + + sfrCCPool->poolstartRB = sfrCEPool->poolendRB + 1; + sfrCCPool->poolendRB = sf->bw - 1; + sfrCCPool->bw = sfrCCPool->poolendRB - sfrCCPool->poolstartRB + 1; + sf->sfrTotalPoolInfo.CCPool2BwAvlbl = sfrCCPool->bw; + sfrCCPool->CCPool2Exists = TRUE; + sfrCCPool->bwAlloced = 0; + sfrCCPool->type2Start = sfrCCPool->poolstartRB; + sfrCCPool->type2End = RGSCH_CEIL(sfrCCPool->poolstartRB, cell->rbgSize); + sfrCCPool->type0End = ((sfrCCPool->poolendRB + 1) / cell->rbgSize) - 1; + sf->sfrTotalPoolInfo.CC2 = TRUE; + sfrCEPool->adjCCPool = sfrCCPool; /* SFR_FIX */ + sfrCCPool->pwrHiCCRange.startRb = 0; + sfrCCPool->pwrHiCCRange.endRb = 0; + } + + if((sfrCEPool->poolendRB != sf->bw - 1) && (!sfrCCPool->poolstartRB)) + { + /*Add memory and Update CCPool*/ + ret = rgSCHUtlAllocSBuf(cell->instIdx, (Data **)&temp, sizeof(CmLList)); + if (ret != ROK) + { + RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId, + "CC Pool memory allocation FAILED for cell "); + rgSchSFRTotalPoolFree(&sf->sfrTotalPoolInfo,cell); + RETVALUE(RFAILED); + } + + ret = rgSCHUtlAllocSBuf(cell->instIdx, (Data **)&temp->node, sizeof(RgSchSFRPoolInfo)); + if (ret != ROK) + { + RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId, + "CC Pool memory allocation FAILED for cell "); + rgSchSFRTotalPoolFree(&sf->sfrTotalPoolInfo,cell); + RETVALUE(RFAILED); + } + + cmLListAdd2Tail(l, temp); + + n = cmLListCrnt(l); + sfrCCPool = (RgSchSFRPoolInfo*)n->node; + + sfrCCPool->poolstartRB = sfrCEPool->poolendRB + 1; + sfrCCPool->poolendRB = sf->bw - 1; + sfrCCPool->bw = sfrCCPool->poolendRB - sfrCCPool->poolstartRB + 1; + sf->sfrTotalPoolInfo.CCPool2BwAvlbl = sfrCCPool->bw; + sfrCCPool->CCPool2Exists = TRUE; + sfrCCPool->bwAlloced = 0; + sfrCCPool->type2Start = sfrCCPool->poolstartRB; + sfrCCPool->type2End = RGSCH_CEIL(sfrCCPool->poolstartRB, cell->rbgSize); + sfrCCPool->type0End = ((sfrCCPool->poolendRB + 1) / cell->rbgSize) - 1; + sf->sfrTotalPoolInfo.CC2 = TRUE; + sfrCEPool->adjCCPool = sfrCCPool; /* SFR_FIX */ + sfrCCPool->pwrHiCCRange.startRb = 0; + sfrCCPool->pwrHiCCRange.endRb = 0; + } + + sf->sfrTotalPoolInfo.CCRetx = FALSE; + sf->sfrTotalPoolInfo.CERetx = FALSE; + + sf->sfrTotalPoolInfo.ccBwFull = FALSE; + sf->sfrTotalPoolInfo.ceBwFull = FALSE; + sf->sfrTotalPoolInfo.isUeCellEdge = FALSE; + RETVALUE(ROK); +} +/** + * @brief This function resets temporary variables in RNTP Prepration + * @details + * + * Function: rgSchDSFRRntpInfoInit + * + * Invoked by: rgSCHSFRUtlTotalPoolInit + * + * @param[in] TknStrOSXL* rntpPtr + * @param[in] RgSubFrm* subFrm + * @return S16 + * + **/ +#ifdef ANSI +PUBLIC S16 rgSchDSFRRntpInfoInit +( + TknStrOSXL *rntpPtr, + RgSchCellCb *cell, + U16 bw + ) +#else +PRIVATE Void rgSchDSFRRntpInfoInit(rntpPtr, cell, bw) + TknStrOSXL *rntpPtr; + RgSchCellCb *cell; + U16 bw; +#endif +{ + Inst inst = cell->instIdx; + U16 len; + + TRC2(rgSchDSFRRntpInfoInit); + + rntpPtr->pres = PRSNT_NODEF; + + len = (bw % 8 == 0) ? (bw/8) : (bw/8 + 1); + + rntpPtr->len = len; + + /* Allocate memory for "scheduled UE" Info */ + if((rgSCHUtlAllocSBuf(inst, (Data**)&(rntpPtr->val), + (len * sizeof(U8)))) != ROK) + { + RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,"Memory allocation FAILED for RNTP Alloc"); + RETVALUE(RFAILED); + } + + RETVALUE(ROK); +} + +/** + * @brief This function release RNTP pattern from subFrame and Cell + * @details + * + * Function: rgSchDSFRRntpInfoFree + * + * Invoked by: rgSCHSFRUtlTotalPoolInit + * + * @param[in] TknStrOSXL* rntpPtr + * @param[in] RgSubFrm* subFrm + * @return S16 + * + **/ +#ifdef ANSI +PUBLIC S16 rgSchDSFRRntpInfoFree +( + TknStrOSXL *rntpPtr, + RgSchCellCb *cell, + U16 bw + ) +#else +PRIVATE Void rgSchDSFRRntpInfoFree(rntpPtr, cell, bw) + TknStrOSXL *rntpPtr; + RgSchCellCb *cell; + U16 bw; +#endif +{ + Inst inst = cell->instIdx; + U16 len; + + TRC2(rgSchDSFRRntpInfoFree); + + len = (bw % 8 == 0) ? (bw/8) : (bw/8 + 1); + + if(rntpPtr->pres == PRSNT_NODEF) + { + rgSCHUtlFreeSBuf(inst, (Data **)(&(rntpPtr->val)),(len * sizeof(U8))); + rntpPtr->pres = NOTPRSNT; + rntpPtr->len = 0; + } + + RETVALUE(ROK); +} + +/** + * @brief This function resets temporary variables in Pool + * @details + * + * Function: rgSchSFRResetPoolVariables + * Purpose: Initialise the dynamic variables in each pool. + * Reset bwAlloced, bwAssigned, type2End, type0End, type2Start + * Invoked by: rgSCHSFRUtlTotalPoolReset + * + * @param[in] RgSchCellCb* cell + * @param[in] RgSchSFRPoolInfo *pool + * @return Void + * + **/ +#ifdef ANSI +PRIVATE Void rgSchSFRResetPoolVariables +( + RgSchCellCb *cell, + RgSchSFRPoolInfo *pool + ) +#else +PRIVATE Void rgSchSFRResetPoolVariables(cell, pool) + RgSchCellCb *cell; + RgSchSFRPoolInfo *pool; +#endif +{ + + TRC2(rgSchSFRResetPoolVariables); + pool->bwAlloced = 0; + + /*type0end will be the last RBG in pool with all available RBs*/ + pool->type0End = (((pool->poolendRB + 1)/cell->rbgSize) - 1); + + /*type2end will be the first RBG in pool with all available RBs*/ + pool->type2End = RGSCH_CEIL(pool->poolstartRB, cell->rbgSize); + pool->type2Start = pool->poolstartRB; + pool->bw = pool->poolendRB - pool->poolstartRB + 1; + + RETVOID; +} +/** + * @brief This function resets SFR Pool information for frame + * + * @details + * + * Function: rgSCHSFRUtlTotalPooReset + * Purpose: Update the dynamic variables in each pool as they will be modified in each subframe. + * Dont modify the static variables like startRB, endRB, BW + * Invoked by: rgSCHUtlSubFrmPut + * + * @param[in] RgSchCellCb* cell + * @param[in] RgSchDlSf* subFrm + * @return Void + * + **/ +#ifdef ANSI +PRIVATE Void rgSCHSFRUtlTotalPoolReset +( + RgSchCellCb *cell, + RgSchDlSf *subFrm + ) +#else +PRIVATE Void rgSCHSFRUtlTotalPoolReset(cell, subFrm) + RgSchCellCb *cell; + RgSchDlSf *subFrm; +#endif +{ + RgSchSFRTotalPoolInfo *totalPoolInfo = &subFrm->sfrTotalPoolInfo; + CmLListCp *ccPool = &totalPoolInfo->ccPool; + CmLListCp *cePool = &totalPoolInfo->cePool; + CmLList *node = NULLP; + RgSchSFRPoolInfo *tempPool = NULLP; + + TRC2(rgSCHSFRUtlTotalPoolReset); + + totalPoolInfo->ccBwFull = FALSE; + totalPoolInfo->ceBwFull = FALSE; + totalPoolInfo->isUeCellEdge = FALSE; + totalPoolInfo->CCPool1BwAvlbl = 0; + totalPoolInfo->CCPool2BwAvlbl = 0; + totalPoolInfo->CEPoolBwAvlbl = 0; + totalPoolInfo->CCRetx = FALSE; + totalPoolInfo->CERetx = FALSE; + + node = ccPool->first; + while(node) + { + tempPool = (RgSchSFRPoolInfo *)(node->node); + node = node->next; + rgSchSFRResetPoolVariables(cell, tempPool); + if(tempPool->poolstartRB == 0) + totalPoolInfo->CCPool1BwAvlbl = tempPool->bw; + else + totalPoolInfo->CCPool2BwAvlbl = tempPool->bw; + } + + node = cePool->first; + while(node) + { + tempPool = (RgSchSFRPoolInfo *)(node->node); + node = node->next; + rgSchSFRResetPoolVariables(cell, tempPool); + totalPoolInfo->CEPoolBwAvlbl = tempPool->bw; + } + + RETVOID; +} +/* LTE_ADV_FLAG_REMOVED_END */ +/** + * @brief This function appends PHICH information for frame + * + * @details + * + * Function: rgSCHUtlAddPhich + * Purpose: This function appends PHICH information for + * a subframe. + * + * Invoked by: TOM + * + * @param[in] RgSchCellCb* cell + * @param[in] RgSubFrm* subFrm + * @param[in] U8 hqFeedBack + * @param[in] U8 nDmrs + * @param[in] U8 rbStart + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef LTE_TDD +#ifdef ANSI +PUBLIC S16 rgSCHUtlAddPhich +( +RgSchCellCb *cell, +CmLteTimingInfo frm, +U8 hqFeedBack, +U8 nDmrs, +U8 rbStart, +U8 iPhich +) +#else +PUBLIC S16 rgSCHUtlAddPhich(cell, frm, hqFeedBack, nDmrs, rbStart, iPhich) +RgSchCellCb *cell; +CmLteTimingInfo frm; +U8 hqFeedBack; +U8 nDmrs; +U8 rbStart; +U8 iPhich; +#endif +#else +#ifdef ANSI +PUBLIC S16 rgSCHUtlAddPhich +( +RgSchCellCb *cell, +CmLteTimingInfo frm, +U8 hqFeedBack, +U8 nDmrs, +U8 rbStart, +Bool isForMsg3 +) +#else +PUBLIC S16 rgSCHUtlAddPhich(cell, frm, hqFeedBack, nDmrs, rbStart, isForMsg3) +RgSchCellCb *cell; +CmLteTimingInfo frm; +U8 hqFeedBack; +U8 nDmrs; +U8 rbStart; +Bool isForMsg3; +#endif +#endif +{ + S16 ret; + RgSchPhich *phich; + RgSchDlSf *dlSf; + Inst inst = cell->instIdx; + TRC2(rgSCHUtlAddPhich); + + dlSf = rgSCHUtlSubFrmGet(cell, frm); + RGSCH_PHICH_ALLOC(inst, phich,sizeof(RgSchPhich), ret); + + if(ret != ROK) + { + RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId, " rgSCHUtlAddPhich(): " + "Allocation of RgSchPhich failed"); + RETVALUE(RFAILED); + } +#ifdef LTE_TDD + RGSCH_INITPHICH(phich, hqFeedBack, nDmrs, rbStart, iPhich); +#else + RGSCH_INITPHICH(phich, hqFeedBack, nDmrs, rbStart, isForMsg3); /*SR_RACH_STATS */ +#endif + cmLListAdd2Tail(&dlSf->phichInfo.phichs, &phich->lnk); + RETVALUE(ROK); +} /* rgSCHUtlAddPhich */ + +/** + * @brief This function resets PHICH information for frame + * + * @details + * + * Function: rgSCHUtlPhichReset + * Purpose: This function initializes PHICH information for + * a subframe. It removes the list of PHICHs allocated + * in the prior use of this subframe structure. + * + * Invoked by: rgSCHUtlSubFrmPut + * + * @param[in] RgSchCellCb* cell + * @param[in] RgSubFrm* subFrm + * @return Void + * + **/ +#ifdef ANSI +PRIVATE Void rgSCHUtlPhichReset +( +RgSchCellCb *cell, +RgSchDlSf *subFrm +) +#else +PRIVATE Void rgSCHUtlPhichReset(cell, subFrm) +RgSchCellCb *cell; +RgSchDlSf *subFrm; +#endif +{ + RgSchPhichInfo *phichInfo; + RgSchPhich *phich; + + UNUSED(cell); + + TRC2(rgSCHUtlPhichReset); + + phichInfo = &subFrm->phichInfo; + while(phichInfo->phichs.first != NULLP) + { + phich = (RgSchPhich *)phichInfo->phichs.first->node; + cmLListDelFrm(&phichInfo->phichs, phichInfo->phichs.first); + RGSCH_PHICH_FREE(cell->instIdx, phich, sizeof(RgSchPhich)); + } + cmLListInit(&phichInfo->phichs); + RETVOID; +} /* rgSCHUtlPhichReset */ + + +/** + * @brief This function returns subframe data structure for a cell + * + * @details + * + * Function: rgSCHUtlSubFrmGet + * Purpose: This function resets the subframe data structure + * when the subframe is released + * + * Invoked by: scheduler + * + * @param[in] RgSubFrm subFrm + * @return Void + * + **/ +#ifdef ANSI +PUBLIC RgSchDlSf* rgSCHUtlSubFrmGet +( +RgSchCellCb *cell, +CmLteTimingInfo frm +) +#else +PUBLIC RgSchDlSf* rgSCHUtlSubFrmGet(cell, frm) +RgSchCellCb *cell; +CmLteTimingInfo frm; +#endif +{ + RgSchDlSf *sf; + U8 dlIdx; + + TRC2(rgSCHUtlSubFrmGet); + +#ifdef LTE_TDD + dlIdx = rgSCHUtlGetDlSfIdx(cell, &frm); + //RGSCH_ARRAY_BOUND_CHECK(cell->instIdx, cell->subFrms, dlIdx); + sf = cell->subFrms[dlIdx]; +#else + /* Changing the idexing + so that proper subframe is selected */ + dlIdx = (((frm.sfn & 1) * RGSCH_NUM_SUB_FRAMES) + (frm.subframe % RGSCH_NUM_SUB_FRAMES)); + RGSCH_ARRAY_BOUND_CHECK(cell->instIdx, cell->subFrms, dlIdx); + sf = cell->subFrms[dlIdx]; +#endif + /* CA dev Start */ + sf->dlIdx = dlIdx; + /* CA dev End */ + RETVALUE(sf); +} + + +/** + * @brief This function returns subframe data structure for a cell + * + * @details + * + * Function: rgSCHUtlSubFrmPut + * Purpose: This function resets the subframe data structure + * when the subframe is released + * + * Invoked by: scheduler + * + * @param[in] RgSubFrm subFrm + * @return Void + * + **/ +#ifdef ANSI +PUBLIC Void rgSCHUtlSubFrmPut +( +RgSchCellCb *cell, +RgSchDlSf *sf +) +#else +PUBLIC Void rgSCHUtlSubFrmPut(cell, sf) +RgSchCellCb *cell; +RgSchDlSf *sf; +#endif +{ + U8 i; + U8 noRaRsps; + + TRC2(rgSCHUtlSubFrmPut); + +#ifdef LTE_TDD + /* Release all the held PDCCH information */ + rgSCHUtlPdcchInit(cell, sf, sf->nCce); +#else + /* Release all the held PDCCH information */ + rgSCHUtlPdcchInit(cell, sf, cell->nCce); +#endif + rgSCHUtlPhichReset(cell, sf); + + /* Reset the bw allocated. */ + sf->bwAssigned = 0; +#ifdef LTEMAC_SPS + /* Setting allocated bandwidth to SPS bandwidth for non-SPS RB allocator */ + sf->bwAlloced = ((cell->spsCellCfg.maxSpsDlBw + + cell->rbgSize - 1)/cell->rbgSize) * cell->rbgSize; + if (sf->bwAlloced > sf->bw) + { + sf->bwAlloced = sf->bw; + } + sf->spsAllocdBw = 0; + sf->type2Start = sf->bwAlloced; + cmMemset((U8*) &sf->dlSfAllocInfo, 0, sizeof(RgSchDlSfAllocInfo)); +#else + sf->bwAlloced = 0; + /* Fix for ccpu00123918*/ + sf->type2Start = 0; + /* LTE_ADV_FLAG_REMOVED_START */ + /* dsfr_pal_fixes ** 21-March-2013 ** SKS */ + if (cell->lteAdvCb.dsfrCfg.status == RGR_ENABLE) + { + cmMemset((U8*) sf->rntpInfo.val, 0, len); + } + /* LTE_ADV_FLAG_REMOVED_END */ +#endif + sf->txDone = FALSE; + /*[ccpu00138609]-ADD-Reset the CCCH UE counter */ + sf->schdCcchUe = 0; + + /* Non DLFS scheduling using Type0 RA requires the following + * parameter's tracking */ + /* Type 2 localized allocations start from 0th RBG and onwards */ + /* Type 0 allocations start from last RBG and backwards*/ +#ifndef LTEMAC_SPS + sf->type2End = 0; +#else + sf->type2End = RGSCH_CEIL(sf->bwAlloced,cell->rbgSize); +#endif + sf->type0End = cell->noOfRbgs - 1; + /* If last RBG is of incomplete size then special handling */ + (sf->bw % cell->rbgSize == 0)? (sf->lstRbgDfct = 0) : + (sf->lstRbgDfct = cell->rbgSize - (sf->bw % cell->rbgSize)); + /* This resets the allocation for BCCH and PDCCH */ +#ifdef EMTC_ENABLE + /* TODO we need to move this reset for emtc functions */ + if(!(cell->emtcEnable)) + { + sf->bch.tb = NULLP; + sf->bch.tbSize = 0; + } +#else + sf->bch.tb = NULLP; + sf->bch.tbSize = 0; +#endif + sf->bcch.pdcch = NULLP; + sf->pcch.pdcch = NULLP; +#ifdef LTE_TDD + noRaRsps = RGSCH_MAX_TDD_RA_RSP_ALLOC; +#else + noRaRsps = RGSCH_MAX_RA_RSP_ALLOC; +#endif + for (i = 0; i < noRaRsps; i++) + { + sf->raRsp[i].pdcch = NULLP; + cmLListInit(&(sf->raRsp[i].raRspLst)); + } + /* LTE_ADV_FLAG_REMOVED_START */ + if (cell->lteAdvCb.sfrCfg.status == RGR_ENABLE) + { + rgSCHSFRUtlTotalPoolReset(cell, sf); + } + /* LTE_ADV_FLAG_REMOVED_END */ +#ifdef LTE_ADV + cmLListInit(&sf->n1PucchResLst); +#endif + + sf->cceCnt = 0; + sf->isCceFailure = FALSE; + sf->dlUlBothCmplt = 0; + RETVOID; +} + + +/** + * @brief This function computes log N (32 bit Unsigned) to the base 2 + * + * @details + * + * Function: rgSCHUtlLog32bitNbase2 + * Purpose: This function computes log N (32 bit Unsigned) to the base 2. + * For n= 0,1 ret = 0. + * + * Invoked by: Scheduler + * + * @param[in] U32 n + * @return U8 + * + **/ +#ifdef ANSI +PUBLIC U8 rgSCHUtlLog32bitNbase2 +( +U32 n +) +#else +PUBLIC U8 rgSCHUtlLog32bitNbase2(n) +U32 n; +#endif +{ + U32 b[] = {0x2, 0xc, 0xf0, 0xff00, 0xffff0000}; + U32 s[] = {1, 2, 4, 8, 16}; + S16 i; + U8 ret = 0; + + TRC2(rgSCHUtlLog32bitNbase2) + + for (i=4; i >= 0; i--) + { + if (n & b[i]) + { + n >>= s[i]; + ret |= s[i]; + } + } + RETVALUE(ret); +} + +#ifdef LTEMAC_SPS + +/** + * @brief This function is a wrapper to call scheduler specific API. + * + * @details + * + * Function: rgSCHUtlDlRelPdcchFbk + * Purpose: Calls scheduler's handler for SPS release PDCCH feedback + * information. + * + * Invoked by: DHM + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ue + * @param[in] U8 isAck + * @return Void + * + **/ +#ifdef ANSI +PUBLIC Void rgSCHUtlDlRelPdcchFbk +( +RgSchCellCb *cell, +RgSchUeCb *ue, +U8 isAck +) +#else +PUBLIC Void rgSCHUtlDlRelPdcchFbk(cell, ue, isAck) +RgSchCellCb *cell; +RgSchUeCb *ue; +U8 isAck; +#endif +{ + TRC2(rgSCHUtlDlRelPdcchFbk); + cell->sc.apis->rgSCHDlRelPdcchFbk(cell, ue, isAck); + RETVOID; +} + + + +/** + * @brief This function is a wrapper to call scheduler specific API. + * + * @details + * + * Function: rgSCHUtlDlProcAck + * Purpose: Calls scheduler's handler to process Ack + * information. + * + * Invoked by: DHM + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchDlHqProcCb *hqP + * @return Void + * + **/ +#ifdef ANSI +PUBLIC Void rgSCHUtlDlProcAck +( +RgSchCellCb *cell, +RgSchDlHqProcCb *hqP +) +#else +PUBLIC Void rgSCHUtlDlProcAck(cell, hqP) +RgSchCellCb *cell; +RgSchDlHqProcCb *hqP; +#endif +{ + TRC2(rgSCHUtlDlProcAck); + cell->sc.apis->rgSCHDlProcAck(cell, hqP); + RETVOID; +} + +/** + * @brief CRNTI CE Handler + * + * @details + * + * Function : rgSCHUtlHdlCrntiCE + * + * - Call scheduler common API + * + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ue + * @param[out] RgSchErrInfo *err + * @return Void + **/ +#ifdef ANSI +PUBLIC Void rgSCHUtlHdlCrntiCE +( +RgSchCellCb *cell, +RgSchUeCb *ue +) +#else +PUBLIC Void rgSCHUtlHdlCrntiCE(cell, ue) +RgSchCellCb *cell; +RgSchUeCb *ue; +#endif +{ + TRC2(rgSCHUtlHdlCrntiCE); + + cell->sc.apis->rgSCHHdlCrntiCE(cell, ue); + RETVOID; +} /* rgSCHUtlHdlCrntiCE */ +#endif /* LTEMAC_SPS */ + +/*********************************************************** + * + * Func : rgSCHUtlCalcTotalRegs + * + * Desc : Calculate total REGs, given a bandwidth, CFI + * and number of antennas. + * + * Ret : Total REGs (U16) + * + * Notes: Could optimise if bw values are limited + * (taken from RRC spec) by indexing values from + * a table. + * Input values are not validated. CFI is assumed + * to be 1/2/3/4. + * + * File : + * + **********************************************************/ +#ifdef ANSI +PRIVATE U16 rgSCHUtlCalcTotalRegs +( +U8 bw, +U8 cfi, +U8 numAntna, +Bool isEcp +) +#else +PRIVATE U16 rgSCHUtlCalcTotalRegs(bw, cfi, numAntna, isEcp) +U8 bw; +U8 cfi; +U8 numAntna; +Bool isEcp; +#endif +{ + U16 regs = 0; + TRC2(rgSCHUtlCalcTotalRegs); + + /*ccpu00116757- removed check for (ERRCLASS & ERRCLS_DEBUG)*/ + + if (bw <= 10) + ++cfi; + switch (cfi) + { + /* Refer 36.211 section 6.10.1.2 + * For symbols 2 and 4, the REGs per RB will be based on cyclic prefix + * and number of antenna ports. + * For symbol 1, there are 2 REGs per RB always. Similarly symbol 3 + * will have 3 REGS. + */ + case 4: + /*CR changes [ccpu00124416] - MOD*/ + if(isEcp) + { + regs = bw * RGSCH_NUM_REGS_4TH_SYM_EXT_CP; + } + else + { + regs = bw * RGSCH_NUM_REGS_4TH_SYM_NOR_CP; + } + case 3: + regs += bw * RGSCH_NUM_REGS_3RD_SYM; + case 2: + /*CR changes [ccpu00124416] - MOD using number of antenna ports*/ + regs += (numAntna == RGSCH_NUM_ANT_PORT_FOUR) ? \ + (bw * RGSCH_NUM_REGS_2ND_SYM_FOUR_ANT_PORT) : \ + (bw * RGSCH_NUM_REGS_2ND_SYM_1OR2_ANT_PORT); + default: /* case 1 */ + regs += bw * RGSCH_NUM_REGS_1ST_SYM; + } + RETVALUE(regs); +} + +/*********************************************************** + * + * Func : rgSCHUtlCalcPhichRegs + * + * Desc : Calculates number of PHICH REGs + * + * Ret : Number of PHICH REGs (U8) + * + * Notes: ng6 is Ng multiplied by 6 + * + * File : + * + **********************************************************/ +#ifdef ANSI +PRIVATE U16 rgSCHUtlCalcPhichRegs +( +U8 bw, +U8 ng6 +) +#else +PRIVATE U16 rgSCHUtlCalcPhichRegs(bw, ng6) +U8 bw; +U8 ng6; +#endif +{ + TRC2(rgSCHUtlCalcPhichRegs); + /* ccpu00115330: Corrected the calculation for number of PHICH groups*/ + RETVALUE(RGSCH_CEIL((bw * ng6) ,(8 * 6)) * RGSCH_NUM_REG_PER_PHICH_GRP); +} + +#ifdef LTE_TDD +/** + * @brief Calculates total CCEs (N_cce) + * + * @details + * + * Function: rgSCHUtlCalcNCce + * Purpose: This function calculates and returns total CCEs for a + * cell, given the following: bandwidth, Ng configuration + * (multiplied by six), cfi (actual number of control + * symbols), m factor for PHICH and number of antennas. + * + * Invoked by: Scheduler + * + * @param[in] U8 bw + * @param[in] U8 ng6 + * @param[in] U8 cfi + * @param[in] U8 mPhich + * @param[in] U8 numAntna + * @param[in] Bool isEcp + * @return N_cce (U8) + * + **/ +#ifdef ANSI +PUBLIC U8 rgSCHUtlCalcNCce +( +U8 bw, +RgrPhichNg ng, +U8 cfi, +U8 mPhich, +U8 numAntna, +Bool isEcp +) +#else +PUBLIC U8 rgSCHUtlCalcNCce(bw, ng, cfi, mPhich, numAntna, isEcp) +U8 bw; +RgrPhichNg ng; +U8 cfi; +U8 mPhich; +U8 numAntna; +Bool isEcp; +#endif +{ + U16 totalRegs; + U16 phichRegs; + U16 cceRegs; + U8 ng6; + TRC2(rgSCHUtlCalcNCce); + + /*ccpu00116757- removed check for (ERRCLASS & ERRCLS_DEBUG)*/ + + switch (ng) + { + case RGR_NG_ONESIXTH: + ng6 = 1; + break; + case RGR_NG_HALF: + ng6 = 3; + break; + case RGR_NG_ONE: + ng6 = 6; + break; + case RGR_NG_TWO: + default: + ng6 = 12; + break; + } + + totalRegs = rgSCHUtlCalcTotalRegs(bw, cfi, numAntna, isEcp); + phichRegs = rgSCHUtlCalcPhichRegs(bw, ng6); + cceRegs = totalRegs - mPhich*phichRegs - RGSCH_NUM_PCFICH_REG; + + RETVALUE((U8)(cceRegs/RGSCH_NUM_REG_PER_CCE)); +} + +#else +/** + * @brief Calculates total CCEs (N_cce) + * + * @details + * + * Function: rgSCHUtlCalcNCce + * Purpose: This function calculates and returns total CCEs for a + * cell, given the following: bandwidth, Ng configuration + * (multiplied by six), cfi (actual number of control + * symbols) and number of antennas. + * + * Invoked by: Scheduler + * + * @param[in] U8 bw + * @param[in] U8 ng6 + * @param[in] U8 cfi + * @param[in] U8 numAntna + * @return N_cce (U8) + * + **/ +#ifdef ANSI +PUBLIC U8 rgSCHUtlCalcNCce +( +U8 bw, +RgrPhichNg ng, +U8 cfi, +U8 numAntna, +Bool isEcp +) +#else +PUBLIC U8 rgSCHUtlCalcNCce(bw, ng, cfi, numAntna, isEcp) +U8 bw; +RgrPhichNg ng; +U8 cfi; +U8 numAntna; +Bool isEcp; +#endif +{ + U16 totalRegs; + U16 phichRegs; + U16 cceRegs; + U8 ng6; + TRC2(rgSCHUtlCalcNCce); + + /*ccpu00116757- removed check for (ERRCLASS & ERRCLS_DEBUG)*/ + + switch (ng) + { + case RGR_NG_ONESIXTH: + ng6 = 1; + break; + case RGR_NG_HALF: + ng6 = 3; + break; + case RGR_NG_ONE: + ng6 = 6; + break; + case RGR_NG_TWO: + default: + ng6 = 12; + break; + } + + totalRegs = rgSCHUtlCalcTotalRegs(bw, cfi, numAntna, isEcp); + phichRegs = rgSCHUtlCalcPhichRegs(bw, ng6); + cceRegs = totalRegs - phichRegs - RGSCH_NUM_PCFICH_REG; + + RETVALUE((U8)(cceRegs/RGSCH_NUM_REG_PER_CCE)); +} +#endif + +/** + * @brief Returns PHICH info associated with an uplink + * HARQ process allocation + * + * @details + * + * Function: rgSCHUtlGetPhichInfo + * Purpose: This function returns PHICH info associated with + * an uplink HARQ process allocation. PHICH info + * comprises RB start and N_dmrs. + * + * @param[in] RgSchUlHqProcCb *hqProc + * @param[out] U8 *rbStartRef + * @param[out] U8 *nDmrsRef + * @return S16 + **/ +#ifdef LTE_TDD +#ifdef ANSI +PUBLIC S16 rgSCHUtlGetPhichInfo +( +RgSchUlHqProcCb *hqProc, +U8 *rbStartRef, +U8 *nDmrsRef, +U8 *iPhich +) +#else +PUBLIC S16 rgSCHUtlGetPhichInfo(hqProc, rbStartRef, nDmrsRef, iPhich) +RgSchUlHqProcCb *hqProc; +U8 *rbStartRef; +U8 *nDmrsRef; +U8 *iPhich; +#endif +#else +#ifdef ANSI +PUBLIC S16 rgSCHUtlGetPhichInfo +( +RgSchUlHqProcCb *hqProc, +U8 *rbStartRef, +U8 *nDmrsRef +) +#else +PUBLIC S16 rgSCHUtlGetPhichInfo(hqProc, rbStartRef, nDmrsRef) +RgSchUlHqProcCb *hqProc; +U8 *rbStartRef; +U8 *nDmrsRef; +#endif +#endif +{ +/* ACC-TDD */ + S16 ret = RFAILED; + + TRC2(rgSCHUtlGetPhichInfo); + + if ((hqProc != NULLP) && (hqProc->alloc != NULLP)) + { + *rbStartRef = hqProc->alloc->grnt.rbStart; + *nDmrsRef = hqProc->alloc->grnt.nDmrs; +#ifdef LTE_TDD + *iPhich = hqProc->iPhich; +#endif + ret = ROK; + } + RETVALUE(ret); +} +#ifndef TFU_UPGRADE +/** + * @brief Returns uplink grant information required to permit + * PHY to receive data + * + * @details + * + * Function: rgSCHUtlAllocRcptInfo + * Purpose: Given an uplink allocation, this function returns + * uplink grant information which is needed by PHY to + * decode data sent from UE. This information includes: + * - RB start + * - Number of RBs + * - RV + * + * @param[in] RgSchUlAlloc *alloc + * @param[out] U8 *rbStartRef + * @param[out] U8 *numRbRef + * @param[out] U8 *rvRef + * @param[out] U16 *size + * @param[out] TfuModScheme *modType + * @param[out] Bool *isRtx + * @param[out] U8 *nDmrs + * @param[out] Bool *ndi + * @param[out] U8 *hqPId + * @return S16 + **/ +#ifdef ANSI +PUBLIC S16 rgSCHUtlAllocRcptInfo +( +RgSchUlAlloc *alloc, +CmLteRnti *rnti, +U8 *iMcsRef, +U8 *rbStartRef, +U8 *numRbRef, +U8 *rvRef, +U16 *size, +TfuModScheme *modType, +Bool *isRtx, +U8 *nDmrs, +Bool *ndi, +U8 *hqPId +) +#else +PUBLIC S16 rgSCHUtlAllocRcptInfo(alloc, rnti, iMcsRef, rbStartRef, numRbRef, + rvRef, size, modType, isRtx, nDmrs, ndi, + hqPId) +RgSchUlAlloc *alloc; +CmLteRnti *rnti; +U8 *iMcsRef; +U8 *rbStartRef; +U8 *numRbRef; +U8 *rvRef; +U16 *size; +TfuModScheme *modType; +Bool *isRtx; +U8 *nDmrs; +Bool *ndi; +U8 *hqPId; +#endif +{ + /* Modulation order for 16qam UEs would be + * min(4,modulation order in grant). Please refer to 36.213-8.6.1*/ + CmLteUeCategory ueCtgy; + + TRC2(rgSCHUtlAllocRcptInfo); +#if (ERRCLASS & ERRCLS_DEBUG) + if ((alloc == NULLP) || (alloc->hqProc == NULLP)) + { + RETVALUE(RFAILED); + } +#endif + + if ( !alloc->forMsg3 ) + { + if ( ((alloc->ue) == NULLP) || (RG_SCH_CMN_GET_UE(alloc->ue, alloc->ue->cell) == NULLP)) + { + RLOG_ARG2(L_ERROR,DBG_CELLID,alloc->ue->cell->cellId, + "Failed: ue->sch is null RNTI:%d,isRetx=%d", + alloc->rnti, alloc->grnt.isRtx); + RETVALUE(RFAILED); + } + ueCtgy = (RG_SCH_CMN_GET_UE_CTGY(alloc->ue)); + } + + *iMcsRef = alloc->grnt.iMcs; + *rbStartRef = alloc->grnt.rbStart; + *numRbRef = alloc->grnt.numRb; + *rvRef = rgRvTable[alloc->hqProc->rvIdx]; + *rnti = alloc->rnti; + *size = alloc->grnt.datSz; + *modType = (alloc->forMsg3)? alloc->grnt.modOdr: + ((ueCtgy == CM_LTE_UE_CAT_5)? + alloc->grnt.modOdr: + (RGSCH_MIN(RGSCH_QM_QPSK,alloc->grnt.modOdr))); + *isRtx = alloc->grnt.isRtx; + *nDmrs = alloc->grnt.nDmrs; + *ndi = alloc->hqProc->ndi; + *hqPId = alloc->hqProc->procId; + + RETVALUE(ROK); +} +#else +/** + * @brief Returns uplink grant information required to permit + * PHY to receive data + * + * @details + * + * Function: rgSCHUtlAllocRcptInfo + * Purpose: Given an uplink allocation, this function returns + * uplink grant information which is needed by PHY to + * decode data sent from UE. This information includes: + * - RB start + * - Number of RBs + * - RV + * + * @param[in] RgSchUlAlloc *alloc + * @param[out] U8 *rbStartRef + * @param[out] U8 *numRbRef + * @param[out] U8 *rvRef + * @param[out] U16 *size + * @param[out] TfuModScheme *modType + * @return S16 + **/ +#ifdef ANSI +PUBLIC S16 rgSCHUtlAllocRcptInfo +( +RgSchCellCb *cell, +RgSchUlAlloc *alloc, +CmLteTimingInfo *timeInfo, +TfuUeUlSchRecpInfo *recpReq +) +#else +PUBLIC S16 rgSCHUtlAllocRcptInfo(cell, alloc, timeInfo, recpReq) +RgSchCellCb *cell; +RgSchUlAlloc *alloc; +CmLteTimingInfo *timeInfo; +TfuUeUlSchRecpInfo *recpReq; +#endif +{ + TRC2(rgSCHUtlAllocRcptInfo); +#if (ERRCLASS & ERRCLS_DEBUG) + if ((alloc == NULLP) || (alloc->hqProc == NULLP)) + { + RETVALUE(RFAILED); + } +#endif + recpReq->size = alloc->grnt.datSz; + recpReq->rbStart = alloc->grnt.rbStart; + recpReq->numRb = alloc->grnt.numRb; + /* Modulation order min(4,mod in grant) for 16 qam UEs. + * Please refer to 36.213-8.6.1*/ +#ifdef FOUR_TX_ANTENNA + recpReq->modType = (TfuModScheme)((alloc->forMsg3)?alloc->grnt.modOdr: + (/*(alloc->ue->ueCatEnum == CM_LTE_UE_CAT_5)? + alloc->grnt.modOdr: *//* Chandra:TmpFx-TM500 Cat5 with Only16QAM */ + (RGSCH_MIN(RGSCH_QM_QPSK,alloc->grnt.modOdr)))); +#else + recpReq->modType = (TfuModScheme)((alloc->forMsg3)?alloc->grnt.modOdr: + ((alloc->ue->ueCatEnum == CM_LTE_UE_CAT_5)? + alloc->grnt.modOdr: + (RGSCH_MIN(RGSCH_QM_QPSK,alloc->grnt.modOdr)))); +#endif + recpReq->nDmrs = alloc->grnt.nDmrs; + recpReq->hoppingEnbld = FALSE; + recpReq->hoppingBits = 0; + recpReq->isRtx = alloc->grnt.isRtx; + recpReq->ndi = alloc->hqProc->ndi; + recpReq->rv = rgRvTable[alloc->hqProc->rvIdx]; +#ifndef LTE_TDD + recpReq->harqProcId = alloc->hqProc->procId; +#else + recpReq->harqProcId = rgSCHCmnGetUlHqProcIdx(timeInfo, cell); +#endif + /* Transmission mode is SISO till Uplink MIMO is implemented. */ + recpReq->txMode = 0; + /* This value needs to filled in in the case of frequency hopping. */ + recpReq->crntTxNb = 0; + + recpReq->mcs = alloc->grnt.iMcs; +#ifdef RG_5GTF + recpReq->rbgStart = alloc->grnt.vrbgStart; + recpReq->numRbg = alloc->grnt.numVrbg; + recpReq->xPUSCHRange = alloc->grnt.xPUSCHRange; + //TODO_SID Need to check + recpReq->nAntPortLayer = 0; + recpReq->SCID = alloc->grnt.SCID; + recpReq->PMI = alloc->grnt.PMI; + recpReq->uciWoTBFlag = alloc->grnt.uciOnxPUSCH; + if(alloc->ue) + { + recpReq->beamIndex = alloc->ue->ue5gtfCb.BeamId; + } +#endif + +#ifdef TENB_STATS + if (!alloc->forMsg3) + { + if (alloc->grnt.isRtx) + { + alloc->ue->tenbStats->stats.nonPersistent.sch[RG_SCH_CELLINDEX(alloc->ue->cell)].ulRetxOccns++; + } + else + { + alloc->ue->tenbStats->stats.nonPersistent.sch[RG_SCH_CELLINDEX(alloc->ue->cell)].ulTxOccns++; + alloc->ue->tenbStats->stats.nonPersistent.sch[RG_SCH_CELLINDEX(alloc->ue->cell)].ulSumiTbs += \ + rgSCHCmnUlGetITbsFrmIMcs(alloc->grnt.iMcs); + alloc->ue->tenbStats->stats.nonPersistent.sch[RG_SCH_CELLINDEX(alloc->ue->cell)].ulNumiTbs ++; + cell->tenbStats->sch.ulSumiTbs += \ + rgSCHCmnUlGetITbsFrmIMcs(alloc->grnt.iMcs); + cell->tenbStats->sch.ulNumiTbs ++; + } + alloc->ue->tenbStats->stats.nonPersistent.sch[RG_SCH_CELLINDEX(alloc->ue->cell)].ulPrbUsg += alloc->grnt.numRb; + cell->tenbStats->sch.ulPrbUsage[0] += alloc->grnt.numRb; + } +#endif + /* ccpu00117050 - DEL - nSrs setting at rgSCHUtlAllocRcptInfo */ + RETVALUE(ROK); +} +#endif + +#ifdef LTE_TDD +/** + * @brief This function initialises the PRACH subframe occasions + * + * @details + * + * Function: rgSCHUtlUpdPrachOcc + * Purpose: This function updates the PRACH subframes based on + * RGR configuration. + * + * Invoked by: Scheduler + * + * @param[in] RgSchCellCb *cell + * @param[in] RgrTddPrachInfo *cellCfg + * @return Void + * + **/ +#ifdef ANSI +PRIVATE Void rgSCHUtlUpdPrachOcc +( +RgSchCellCb *cell, +RgrTddPrachInfo *cellCfg +) +#else +PRIVATE Void rgSCHUtlUpdPrachOcc(cell, cellCfg) +RgSchCellCb *cell; +RgrTddPrachInfo *cellCfg; +#endif +{ + U8 idx; + U8 count = 0; + U8 size; + U8 startIdx; + U8 endIdx; + + TRC2(rgSCHUtlUpdPrachOcc) + + /* In the 1st half frame */ + if(cellCfg->halfFrm == 0) + { + startIdx = 2; + endIdx = 6; + } + /* In the 2nd half frame */ + else + { + startIdx = 6; + endIdx = 10; + } + for(idx = startIdx; idx < endIdx; idx++) + { + if(rgSchTddUlDlSubfrmTbl[cell->ulDlCfgIdx][idx] + == RG_SCH_TDD_UL_SUBFRAME) + { + if(cellCfg->ulStartSfIdx == count) + { + size = cell->rachCfg.raOccasion.size; + cell->rachCfg.raOccasion.subFrameNum[size] = idx; + cell->rachCfg.raOccasion.size++; + break; + } + count ++; + } + } + RETVOID; +} + +/** + * @brief This function initialises the PRACH occasions + * + * @details + * + * Function: rgSCHUtlPrachCfgInit + * Purpose: This function initialises the PRACH occasions based on + * RGR configuration. + * + * Invoked by: Scheduler + * + * @param[in] RgSchCellCb *cell + * @param[in] RgrCellCfg *cellCfg + * @return Void + * + **/ +#ifdef ANSI +PUBLIC Void rgSCHUtlPrachCfgInit +( +RgSchCellCb *cell, +RgrCellCfg *cellCfg +) +#else +PUBLIC Void rgSCHUtlPrachCfgInit(cell, cellCfg) +RgSchCellCb *cell; +RgrCellCfg *cellCfg; +#endif +{ + U8 idx; + U8 subfrmIdx; + U8 splFrm; + + TRC2(rgSCHUtlPrachCfgInit) + if(cellCfg->prachRscInfo.numRsc <= 0) + { + RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId, "Invalid" + "PRACH resources Configuration "); + RETVOID; + } + + /* Update SFN occasions */ + cell->rachCfg.raOccasion.sfnEnum = + cellCfg->prachRscInfo.prachInfo[0].sfn; + + cell->rachCfg.raOccasion.size = 0; + + /* Update subframe occasions */ + for(idx = 0; idx < cellCfg->prachRscInfo.numRsc; idx++) + { + if(cellCfg->prachRscInfo.prachInfo[idx].freqIdx == 0) + { + if(cellCfg->prachRscInfo.prachInfo[idx].halfFrm == 0) + { + splFrm = 1; + } + else + { + splFrm = 6; + } + if(cellCfg->prachRscInfo.prachInfo[idx].ulStartSfIdx == + RGR_TDD_SPL_UL_IDX) + { + subfrmIdx = cell->rachCfg.raOccasion.size; + cell->rachCfg.raOccasion.subFrameNum[subfrmIdx] = splFrm; + cell->rachCfg.raOccasion.size++; + } + else + { + rgSCHUtlUpdPrachOcc(cell, + &cellCfg->prachRscInfo.prachInfo[idx]); + } + } + } + RETVOID; +} + +/** + * @brief This function performs RGR cell initialization + * + * @details + * + * Function: rgSCHUtlRgrCellCfg + * Purpose: This function initialises the cell with RGR configuration + * and subframe related initialization. + * + * Invoked by: Scheduler + * + * @param[in] RgSchCellCb *cell + * @param[in] RgrCellCfg *cellCfg + * @param[in] RgSchErrInfo *errInfo + * @return Void + * + **/ +#ifdef ANSI +PUBLIC S16 rgSCHUtlRgrCellCfg +( +RgSchCellCb *cell, +RgrCellCfg *cellCfg, +RgSchErrInfo *errInfo +) +#else +PUBLIC S16 rgSCHUtlRgrCellCfg(cell, cellCfg, errInfo) +RgSchCellCb *cell; +RgrCellCfg *cellCfg; +RgSchErrInfo *errInfo; +#endif +{ + U8 i; + U8 sfn=0; + U8 sfNum = 0; + RgSchDlSf *sf; + CmLteTimingInfo frm; + U8 ulDlCfgIdx = cellCfg->ulDlCfgIdx; + U8 maxSubframes ; + U8 maxDlSubframes; + S16 ret = ROK; + U16 bw; /*!< Number of RBs in the cell */ + + TRC2(rgSCHUtlRgrCellCfg); + + cmMemset((U8 *)&frm,0,sizeof(CmLteTimingInfo)); + + /* ccpu00132657-MOD- Determining DLSF array size independent of DELTAS */ + maxDlSubframes = rgSchTddNumDlSubfrmTbl[ulDlCfgIdx][RGSCH_NUM_SUB_FRAMES-1]; + maxSubframes = 2 * maxDlSubframes; + cell->numDlSubfrms = maxSubframes; +/* ACC-TDD */ + cell->tddHqSfnCycle = -1; + cell->ulDlCfgIdx = ulDlCfgIdx; + + /* PRACH Occasions Initialization */ + rgSCHUtlPrachCfgInit(cell, cellCfg); + + /* ccpu00132658- Moved out of below for loop since the updating rbgSize and + * bw are independent of sfNum*/ + /* determine the RBG size and no of RBGs for the configured + * DL BW */ + if (cell->bwCfg.dlTotalBw > 63) + { + cell->rbgSize = 4; + } + else if (cell->bwCfg.dlTotalBw > 26) + { + cell->rbgSize = 3; + } + else if (cell->bwCfg.dlTotalBw > 10) + { + cell->rbgSize = 2; + } + else + { + cell->rbgSize = 1; + } + cell->noOfRbgs = RGSCH_CEIL(cell->bwCfg.dlTotalBw, cell->rbgSize); + + bw = cell->bwCfg.dlTotalBw; + + rgSCHUtlAllocSBuf(cell->instIdx, + (Data **)&cell->subFrms, sizeof(RgSchDlSf *) * maxSubframes); + if (cell->subFrms == NULLP) + { + RETVALUE(RFAILED); + } + + /* Create memory for each frame. */ + for(i = 0; i < maxSubframes; i++) + { + while(rgSchTddUlDlSubfrmTbl[ulDlCfgIdx][sfNum] == + RG_SCH_TDD_UL_SUBFRAME) + { + sfNum = (sfNum+1) % RGSCH_NUM_SUB_FRAMES; + } + + rgSCHUtlAllocSBuf(cell->instIdx, (Data **)&sf, sizeof(RgSchDlSf)); + if (sf == NULLP) + { + break; + } + cmMemset((U8 *)sf, 0, sizeof(*sf)); + +#ifdef LTE_ADV + if (ROK != rgSCHLaaInitDlSfCb(cell, sf)) + { + break; + } +#endif + sf->sfNum = sfNum; + sf->bw = bw; +#ifdef LTEMAC_SPS + /* Mark SPS bandwidth to be occupied */ + sf->bwAlloced = ((cellCfg->spsCfg.maxSpsDlBw + + cell->rbgSize - 1)/cell->rbgSize) * cell->rbgSize; + sf->spsAllocdBw = 0; + sf->type2End = sf->bwAlloced/cell->rbgSize; +#else + sf->bwAlloced = 0; + /* Fix for ccpu00123918*/ + sf->type2Start = 0; +#endif /* LTEMAC_SPS */ + /* Initialize the ackNakRepQ here */ +#ifdef RG_MAC_MEASGAP + cmLListInit (&(sf->ackNakRepQ)); +#endif + cell->subFrms[i] = sf; + sfNum = (sfNum+1) % RGSCH_NUM_SUB_FRAMES; + } + if (i != maxSubframes) + { + for (; i > 0; i--) + { + /* ccpu00117052 - MOD - Passing double pointer + for proper NULLP assignment*/ + rgSCHUtlFreeSBuf(cell->instIdx, + (Data **)(&(cell->subFrms[i-1])), sizeof(RgSchDlSf)); +#ifdef LTE_ADV + rgSCHLaaDeInitDlSfCb(cell, sf); +#endif + } + /* ccpu00117052 - MOD - Passing double pointer + for proper NULLP assignment*/ + rgSCHUtlFreeSBuf(cell->instIdx, + (Data **)(&(cell->subFrms)), sizeof(RgSchDlSf *) * maxSubframes); + + RETVALUE(RFAILED); + } + + if (cell->sc.apis == NULLP) + { + cell->sc.apis = &rgSchCmnApis; + } + ret = cell->sc.apis->rgSCHRgrCellCfg(cell, cellCfg, errInfo); + + if (ret != ROK) + { + /* ccpu00132286- Removed deletion of sf nodes as the deletion will be + * happening during CellDelete. Added return handling to provide negative + * confirm*/ + RETVALUE(ret); + } + + /* Release the subframes and thereby perform the initialization */ + for (i = 0; i < maxSubframes; i++) + { + if((i > 0) && (i%maxDlSubframes == 0)) + { + sfn++; + } + frm.sfn = sfn; + frm.subframe = cell->subFrms[i]->sfNum; + rgSCHUtlDlRlsSubFrm(cell, frm); + } + + RETVALUE(ret); +} + +#else + +/** + * @brief This function performs scheduler related cell creation + * + * @details + * + * Function: rgSCHUtlRgrCellCfg + * Purpose: This function creates the subframes needed for the + * cell. It then peforms init of the scheduler by calling + * scheduler specific cell init function. + * + * Invoked by: Scheduler + * + * @param[in] RgSchCellCb *cell + * @param[in] RgrCellCfg *cellCfg + * @param[in] RgSchErrInfo *errInfo + * @return Void + * + **/ +#ifdef ANSI +PUBLIC S16 rgSCHUtlRgrCellCfg +( +RgSchCellCb *cell, +RgrCellCfg *cellCfg, +RgSchErrInfo *errInfo +) +#else +PUBLIC S16 rgSCHUtlRgrCellCfg(cell, cellCfg, errInfo) +RgSchCellCb *cell; +RgrCellCfg *cellCfg; +RgSchErrInfo *errInfo; +#endif +{ + U8 i; + RgSchDlSf *sf; + CmLteTimingInfo frm; + S16 ret; + Inst inst = cell->instIdx; + /* LTE_ADV_FLAG_REMOVED_START */ + U16 len; + len = (U16)((cell->bwCfg.dlTotalBw % 8 == 0) ? (cell->bwCfg.dlTotalBw/8) : (cell->bwCfg.dlTotalBw/8 + 1)); /*KW fix for LTE_ADV */ + /* LTE_ADV_FLAG_REMOVED_END */ + TRC2(rgSCHUtlRgrCellCfg); + + cmMemset((U8 *)&frm,0,sizeof(CmLteTimingInfo)); + + /* determine the RBG size and no of RBGs for the configured + * DL BW */ + if (cell->bwCfg.dlTotalBw > 63) + { + cell->rbgSize = 4; + } + else if (cell->bwCfg.dlTotalBw > 26) + { + cell->rbgSize = 3; + } + else if (cell->bwCfg.dlTotalBw > 10) + { + cell->rbgSize = 2; + } + else + { + cell->rbgSize = 1; + } + cell->noOfRbgs = RGSCH_CEIL(cell->bwCfg.dlTotalBw, cell->rbgSize); + /* Create memory for each frame. */ + /* Changing loop limit from + RGSCH_NUM_SUB_FRAMES to RGSCH_NUM_DL_SUBFRAMES */ + for(i = 0; i < RGSCH_NUM_DL_SUBFRAMES; i++) + { + rgSCHUtlAllocSBuf(inst, (Data **)&sf, sizeof(RgSchDlSf)); + if (sf == NULLP) + { + break; + } + cmMemset((U8 *)sf, 0, sizeof(*sf)); + +#ifdef LTE_ADV + if (ROK != rgSCHLaaInitDlSfCb(cell, sf)) + { + break; + } +#endif + /* Doing MOD operation before assigning value of i */ + sf->sfNum = i % RGSCH_NUM_SUB_FRAMES; + sf->bw = cell->bwCfg.dlTotalBw; + /* Initialize the ackNakRepQ here */ +#ifdef RG_MAC_MEASGAP + cmLListInit (&(sf->ackNakRepQ)); +#endif + cell->subFrms[i] = sf; + /* LTE_ADV_FLAG_REMOVED_START */ + if (cell->lteAdvCb.dsfrCfg.status == RGR_ENABLE) + { + /*initialize the RNTP Buffer*/ + if(rgSchDSFRRntpInfoInit(&sf->rntpInfo, cell, sf->bw)) + { + RETVALUE(RFAILED); + } + } + + if (cell->lteAdvCb.sfrCfg.status == RGR_ENABLE) + { + /*initialise the pools of CC and CE*/ + if(rgSchSFRTotalPoolInit(cell, sf)) + { + RETVALUE(RFAILED); + } + } + /* LTE_ADV_FLAG_REMOVED_END */ + } + + /* LTE_ADV_FLAG_REMOVED_START */ + /* Allocate memory for "scheduled UE" Info */ + if (cell->lteAdvCb.dsfrCfg.status == RGR_ENABLE) + { + if((rgSCHUtlAllocSBuf(inst, (Data**)&(cell->rntpAggrInfo.val), + (len * sizeof(U8)))) != ROK) + { + RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,"Memory allocation FAILED for RNTP Alloc"); + RETVALUE(RFAILED); + } + cell->rntpAggrInfo.pres = PRSNT_NODEF; + cell->rntpAggrInfo.len = len; + } + /* LTE_ADV_FLAG_REMOVED_END */ + + /* Changing loop limit from + RGSCH_NUM_SUB_FRAMES to RGSCH_NUM_DL_SUBFRAMES */ + if (i != RGSCH_NUM_DL_SUBFRAMES) + { + for (; i > 0; i--) + { + /* ccpu00117052 - MOD - Passing double pointer + for proper NULLP assignment*/ + rgSCHUtlFreeSBuf(inst, (Data **)(&(cell->subFrms[i-1])), + sizeof(RgSchDlSf)); +#ifdef LTE_ADV + rgSCHLaaDeInitDlSfCb(cell, sf); +#endif + } + RETVALUE(RFAILED); + } + + if (cell->sc.apis == NULLP) + { + cell->sc.apis = &rgSchCmnApis; + } + + /* Release the subframes and thereby perform the initialization */ + for (i = 0; i < RGSCH_NUM_DL_SUBFRAMES; i++) + { + if (i >= RGSCH_NUM_SUB_FRAMES) + { + /* [ccpu00123828]-MOD-The below statement sfn += 1incorrectly modified + * the value of sfn for i>=10 thru 19. Correct way is to assign + it to one */ + frm.sfn = 1; + } + frm.subframe = i % RGSCH_NUM_SUB_FRAMES; + rgSCHUtlDlRlsSubFrm(cell, frm); + } + + ret = cell->sc.apis->rgSCHRgrCellCfg(cell, cellCfg, errInfo); + if (ret != ROK) + { + errInfo->errCause = RGSCHERR_SCH_CFG; + RETVALUE(RFAILED); + } +#ifdef EMTC_ENABLE + if(cell->emtcEnable) + { + /* TODO: Repetition framework in RGR and APP */ + if (rgSCHUtlEmtcResMngmtInit( + cell, + RGSCH_IOT_PDSCH_POOLSZ, RGSCH_IOT_PDSCH_DELTA, cellCfg->bwCfg.dlTotalBw, + RGSCH_IOT_PUSCH_POOLSZ, RGSCH_IOT_PUSCH_DELTA, RGSCH_IOT_PUSCH_MAXFREQSZ, + RGSCH_IOT_PUCCH_POOLSZ, RGSCH_IOT_PUCCH_DELTA, RGSCH_IOT_PUCCH_MAXFREQSZ) != ROK) + { + errInfo->errCause = RGSCHERR_SCH_CFG; + RETVALUE(RFAILED); + } + } +#endif + + RETVALUE(ret); +} +#endif + + +/** + * @brief This function performs the cell reconfiguration at RGR interface + * + * @details + * + * Function: rgSCHUtlRgrCellRecfg + * Purpose: This function updates the reconfigurable parameters + * on the cell control block for the scheduler. + * + * Invoked by: Scheduler + * + * @param[in] RgSchCellCb *cell + * @param[in] RgrCellCfg *cellCfg + * @param[in] RgSchErrInfo *errInfo + * @return Void + * + **/ +#ifdef ANSI +PUBLIC S16 rgSCHUtlRgrCellRecfg +( +RgSchCellCb *cell, +RgrCellRecfg *recfg, +RgSchErrInfo *err +) +#else +PUBLIC S16 rgSCHUtlRgrCellRecfg(cell, recfg, err) +RgSchCellCb *cell; +RgrCellRecfg *recfg; +RgSchErrInfo *err; +#endif +{ + TRC2(rgSCHUtlRgrCellRecfg); + RETVALUE(cell->sc.apis->rgSCHRgrCellRecfg(cell, recfg, err)); +} + + + +/** + * @brief This function returns the Y value of UE for a sub frame + * + * @details + * + * Function: rgSCHUtlFreeCell + * Purpose: This function updates the value of Y stored in the + * UE control block. It uses the previously computed + * value for computing for this subframe. + * + * Invoked by: Scheduler + * + * @param[in] RgSchCellCb *cell + * @return Void + * + **/ +#ifdef ANSI +PUBLIC S16 rgSCHUtlFreeCell +( +RgSchCellCb *cell +) +#else +PUBLIC S16 rgSCHUtlFreeCell(cell) +RgSchCellCb *cell; +#endif +{ + U8 i; + CmLListCp *lst; + RgSchPdcch *pdcch; + RgSchPdcchInfo *pdcchInfo; + RgSchPhichInfo *phichInfo; + RgSchPhich *phich; + Inst inst = cell->instIdx; + U8 maxSubframes; +#ifdef LTE_TDD + RgSchRaReqInfo *raReqInfo; + U8 idx; +#endif + TRC2(rgSCHUtlFreeCell); + +#ifdef LTE_TDD + maxSubframes = cell->numDlSubfrms; +#else + maxSubframes = RGSCH_NUM_DL_SUBFRAMES; +#endif + + + /* Invoke the index for scheduler, cell deletion */ + cell->sc.apis->rgSCHFreeCell(cell); + + /* Release the subframes allocated */ + for (i = 0; i < maxSubframes; i++) + { +#ifdef LTE_ADV + rgSCHLaaDeInitDlSfCb(cell, cell->subFrms[i]); +#endif + pdcchInfo = &cell->subFrms[i]->pdcchInfo; + /* ccpu00117052 - MOD - Passing double pointer + for proper NULLP assignment*/ + rgSCHUtlFreeSBuf(inst, (Data **)(&(pdcchInfo->map)), + (pdcchInfo->nCce + 7) >> 3); + while (pdcchInfo->pdcchs.first != NULLP) + { + pdcch = (RgSchPdcch *)pdcchInfo->pdcchs.first->node; + cmLListDelFrm(&pdcchInfo->pdcchs, pdcchInfo->pdcchs.first); + /* ccpu00117052 - MOD - Passing double pointer + for proper NULLP assignment*/ + rgSCHUtlFreeSBuf(inst, (Data **)&pdcch, sizeof(RgSchPdcch)); + } + + phichInfo = &cell->subFrms[i]->phichInfo; + while(phichInfo->phichs.first != NULLP) + { + phich = (RgSchPhich *)phichInfo->phichs.first->node; + cmLListDelFrm(&phichInfo->phichs, phichInfo->phichs.first); + RGSCH_PHICH_FREE(inst, phich, sizeof(RgSchPhich)); + } + + /* LTE_ADV_FLAG_REMOVED_START */ + /*releasing SFR pool entries*/ + rgSchSFRTotalPoolFree(&cell->subFrms[i]->sfrTotalPoolInfo, cell); + + /*releasing dsfr rntp pattern info*/ + rgSchDSFRRntpInfoFree(&cell->subFrms[i]->rntpInfo, cell, + cell->bwCfg.dlTotalBw); + /* LTE_ADV_FLAG_REMOVED_END */ + + /* ccpu00117052 - MOD - Passing double pointer + for proper NULLP assignment*/ + rgSCHUtlFreeSBuf(inst, (Data **)(&(cell->subFrms[i])), sizeof(RgSchDlSf)); + } +#ifdef LTE_TDD + /* Release the subframe pointers */ + /* ccpu00117052 - MOD - Passing double pointer + for proper NULLP assignment*/ + rgSCHUtlFreeSBuf(inst, + (Data **) (&(cell->subFrms)), sizeof(RgSchDlSf *) * maxSubframes); + + for(idx=0; idx < cell->raInfo.lstSize; idx++) + { + lst = &cell->raInfo.raReqLst[idx]; + while (lst->first != NULLP) + { + raReqInfo = (RgSchRaReqInfo *)lst->first->node; + cmLListDelFrm(lst, &raReqInfo->raReqLstEnt); + /* ccpu00117052 - MOD - Passing double pointer + for proper NULLP assignment*/ + rgSCHUtlFreeSBuf(inst,(Data **)&raReqInfo, sizeof(RgSchRaReqInfo)); + } + } + /* ccpu00117052 - MOD - Passing double pointer + for proper NULLP assignment*/ + rgSCHUtlFreeSBuf(inst, + (Data **)(&(cell->raInfo.raReqLst)), + sizeof(CmLListCp) * (cell->raInfo.lstSize)); +#endif + + /* Release allocated pdcchs */ + lst = &cell->pdcchLst; + while (lst->first != NULLP) + { + pdcch = (RgSchPdcch *)lst->first->node; + cmLListDelFrm(lst, &pdcch->lnk); +#ifdef EMTC_ENABLE + if(cell->emtcEnable) + { + rgSCHEmtcPdcchFree(cell, pdcch); + rgSCHUtlEmtcResMngmtDeinit(cell); + } +#endif + /* ccpu00117052 - MOD - Passing double pointer + for proper NULLP assignment*/ + rgSCHUtlFreeSBuf(inst,(Data **)&pdcch, sizeof(RgSchPdcch)); + } +#ifdef LTE_ADV + rgSCHLaaFreeLists(cell); +#endif + + /* LTE_ADV_FLAG_REMOVED_START */ + /* releasing RNTP Aggregation Info from CellCb*/ + rgSchDSFRRntpInfoFree(&cell->rntpAggrInfo, cell, cell->bwCfg.dlTotalBw); + /* LTE_ADV_FLAG_REMOVED_END */ + + RETVALUE(ROK); +} + + +/** + * @brief This function adds the UE to scheduler + * + * @details + * + * Function: rgSCHUtlRgrUeCfg + * Purpose: This function performs addition of UE to scheduler + * 1. First, it updates the Y table in the UE + * 2. Then, it calls the scheduler's handler for UE addition + * + * Invoked by: Scheduler + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ue + * @param[in] RgrUeCfg *cfg + * @param[in] RgSchErrInfo *err + * @return S16 + * + **/ +#ifdef ANSI +PUBLIC S16 rgSCHUtlRgrUeCfg +( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgrUeCfg *cfg, +RgSchErrInfo *err +) +#else +PUBLIC S16 rgSCHUtlRgrUeCfg(cell, ue, cfg, err) +RgSchCellCb *cell; +RgSchUeCb *ue; +RgrUeCfg *cfg; +RgSchErrInfo *err; +#endif +{ + TRC2(rgSCHUtlRgrUeCfg); + + /* Assign TM 1 as UE's default TM */ + ue->mimoInfo.txMode = RGR_UE_TM_1; + ue->txModeTransCmplt = TRUE; + cmInitTimers(&ue->txModeTransTmr, 1); + if (cfg->txMode.pres == PRSNT_NODEF) + { + /* DL MU-MIMO not supported */ + if (cfg->txMode.txModeEnum == RGR_UE_TM_5) + { + err->errCause = RGSCHERR_SCH_CFG; + RETVALUE(RFAILED); + } + ue->mimoInfo.txMode = cfg->txMode.txModeEnum; + } + ue->ul.ulTxAntSel = cfg->ulTxAntSel; + ue->mimoInfo.cdbkSbstRstrctn = cfg->ueCodeBookRstCfg; +#ifdef TFU_UPGRADE + ue->ueCatEnum = cfg->ueCatEnum; + if ((cfg->puschDedCfg.bACKIdx > 15) || + (cfg->puschDedCfg.bCQIIdx > 15) || + (cfg->puschDedCfg.bRIIdx > 15)) + { + err->errCause = RGSCHERR_SCH_CFG; + RETVALUE(RFAILED); + } + ue->ul.betaHqOffst = cfg->puschDedCfg.bACKIdx; + ue->ul.betaCqiOffst = cfg->puschDedCfg.bCQIIdx; + ue->ul.betaRiOffst = cfg->puschDedCfg.bRIIdx; +#endif + ue->csgMmbrSta = cfg->csgMmbrSta; +#ifdef RG_PFS_STATS + cmMemset((U8 *)&ue->pfsStats, 0, sizeof(RgSchPfsStats)); +#endif + /* Call the handler of the scheduler based on cell configuration */ + RETVALUE(cell->sc.apis->rgSCHRgrUeCfg(cell, ue, cfg, err)); +} +/* Start : LTEMAC_2.1_DEV_CFG */ + +/** + * @brief This function adds a service to scheduler + * + * @details + * + * Function: rgSCHUtlRgrLcCfg + * Purpose: This function performs addition of service to scheduler + * The addition is performed for each direction based + * the direction field of the configuration + * + * Invoked by: Scheduler + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ue + * @param[in] RgSchDlLcCb *dlLc + * @param[in] RgrLchCfg *cfg + * @param[in] RgSchErrInfo *err + * @return S16 + * + **/ +#ifdef ANSI +PUBLIC S16 rgSCHUtlRgrLcCfg +( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgSchDlLcCb *dlLc, +RgrLchCfg *cfg, +RgSchErrInfo *errInfo +) +#else +PUBLIC S16 rgSCHUtlRgrLcCfg(cell, ue, dlLc, cfg, errInfo) +RgSchCellCb *cell; +RgSchUeCb *ue; +RgSchDlLcCb *dlLc; +RgrLchCfg *cfg; +RgSchErrInfo *errInfo; +#endif +{ + TRC2(rgSCHUtlRgrLcCfg); + RETVALUE(cell->sc.apis->rgSCHRgrLchCfg(cell, ue, dlLc, cfg, errInfo)); +} + + +/** + * @brief This function modifies a service to scheduler + * + * @details + * + * Function: rgSCHUtlRgrLcRecfg + * Purpose: This function performs modification of a service in + * scheduler. The modification is performed for each direction + * based the direction field of the configuration + * + * Invoked by: Scheduler + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ue + * @param[in] RgSchDlLcCb *dlLc + * @param[in] RgrLchRecfg *recfg + * @param[in] RgSchErrInfo *err + * @return S16 + * + **/ +#ifdef ANSI +PUBLIC S16 rgSCHUtlRgrLcRecfg +( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgSchDlLcCb *dlLc, +RgrLchRecfg *recfg, +RgSchErrInfo *err +) +#else +PUBLIC S16 rgSCHUtlRgrLcRecfg(cell, ue, dlLc, recfg, err) +RgSchCellCb *cell; +RgSchUeCb *ue; +RgSchDlLcCb *dlLc; +RgrLchRecfg *recfg; +RgSchErrInfo *err; +#endif +{ + TRC2(rgSCHUtlRgrLcRecfg); + RETVALUE(cell->sc.apis->rgSCHRgrLchRecfg(cell, ue, dlLc, recfg, err)); +} + +/** + * @brief This function deletes a Lc in scheduler + * + * @details + * + * Function: rgSCHUtlRgrLcDel + * Purpose: This function performs deletion of Lc in scheduler + * + * Invoked by: Scheduler + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ue + * @param[in] CmLteLcId lcId + * @param[in] U8 lcgId + * @return S16 + * + **/ +#ifdef ANSI +PUBLIC S16 rgSCHUtlRgrLcDel +( +RgSchCellCb *cell, +RgSchUeCb *ue, +CmLteLcId lcId, +U8 lcgId +) +#else +PUBLIC S16 rgSCHUtlRgrLcDel(cell, ue, lcId, lcgId) +RgSchCellCb *cell; +RgSchUeCb *ue; +CmLteLcId lcId; +U8 lcgId; +#endif +{ + TRC2(rgSCHUtlRgrLcDel); + cell->sc.apis->rgSCHRgrLchDel(cell, ue, lcId, lcgId); + + RETVALUE (ROK); +} /* rgSCHUtlRgrLcDel */ + +/** + * @brief This function adds a service to scheduler + * + * @details + * + * Function: rgSCHUtlRgrLcgCfg + * Purpose: This function performs addition of service to scheduler + * The addition is performed for each direction based + * the direction field of the configuration + * + * Invoked by: Scheduler + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ue + * @param[in] RgrLchCfg *cfg + * @param[in] RgSchErrInfo *err + * @return S16 + * + **/ +#ifdef ANSI +PUBLIC S16 rgSCHUtlRgrLcgCfg +( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgrLcgCfg *cfg, +RgSchErrInfo *errInfo +) +#else +PUBLIC S16 rgSCHUtlRgrLcgCfg(cell, ue, cfg, errInfo) +RgSchCellCb *cell; +RgSchUeCb *ue; +RgrLcgCfg *cfg; +RgSchErrInfo *errInfo; +#endif +{ + TRC2(rgSCHUtlRgrLcgCfg); + RETVALUE(cell->sc.apis->rgSCHRgrLcgCfg(cell, ue, &(ue->ul.lcgArr[cfg->ulInfo.lcgId]), cfg, errInfo)); +} + + +/** + * @brief This function modifies a service to scheduler + * + * @details + * + * Function: rgSCHUtlRgrLcgRecfg + * Purpose: This function performs modification of a service in + * scheduler. The modification is performed for each direction + * based the direction field of the configuration + * + * Invoked by: Scheduler + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ue + * @param[in] RgrLcgRecfg *recfg + * @param[in] RgSchErrInfo *err + * @return S16 + * + **/ +#ifdef ANSI +PUBLIC S16 rgSCHUtlRgrLcgRecfg +( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgrLcgRecfg *recfg, +RgSchErrInfo *err +) +#else +PUBLIC S16 rgSCHUtlRgrLcgRecfg(cell, ue, recfg, err) +RgSchCellCb *cell; +RgSchUeCb *ue; +RgrLcgRecfg *recfg; +RgSchErrInfo *err; +#endif +{ + TRC2(rgSCHUtlRgrLcgRecfg); + RETVALUE(cell->sc.apis->rgSCHRgrLcgRecfg(cell, ue, &(ue->ul.lcgArr[recfg->ulRecfg.lcgId]), recfg, err)); +} /* rgSCHUtlRgrLcRecfg */ + +/** + * @brief This function modifies a service to scheduler + * + * @details + * + * Function: rgSCHUtlRgrLcgDel + * Purpose: This function performs modification of a service in + * scheduler. The modification is performed for each direction + * based the direction field of the configuration + * + * Invoked by: Scheduler + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ue + * @param[in] RgrDel *lcDelInfo + * @return S16 + * + **/ +#ifdef ANSI +PUBLIC Void rgSCHUtlRgrLcgDel +( +RgSchCellCb *cell, +RgSchUeCb *ue, +U8 lcgId +) +#else +PUBLIC Void rgSCHUtlRgrLcgDel(cell, ue, lcgId) +RgSchCellCb *cell; +RgSchUeCb *ue; +U8 lcgId; +#endif +{ + TRC2(rgSCHUtlRgrLcgDel); + cell->sc.apis->rgSCHFreeLcg(cell, ue, &ue->ul.lcgArr[lcgId]); + + /* Stack Crash problem for TRACE5 changes. added the return below . */ + RETVOID; + +} /* rgSCHUtlRgrLcgDel */ + + +/* End: LTEMAC_2.1_DEV_CFG */ + +/** + * @brief This function is a wrapper to call scheduler specific API. + * + * @details + * + * Function: rgSCHUtlDoaInd + * Purpose: Updates the DOA for the UE + * + * Invoked by: TOM + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ue + * @param[in] TfuDoaRpt *doaRpt + * @return Void + * + **/ +#ifdef ANSI +PUBLIC Void rgSCHUtlDoaInd +( +RgSchCellCb *cell, +RgSchUeCb *ue, +TfuDoaRpt *doaRpt +) +#else +PUBLIC Void rgSCHUtlDoaInd(cell, ue, doaRpt) +RgSchCellCb *cell; +RgSchUeCb *ue; +TfuDoaRpt *doaRpt; +#endif +{ + TRC2(rgSCHUtlDoaInd); + ue->mimoInfo.doa.pres = PRSNT_NODEF; + ue->mimoInfo.doa.val = doaRpt->doa; + RETVOID; +} + +/** + * @brief This function is a wrapper to call scheduler specific API. + * + * @details + * + * Function: rgSCHUtlDlCqiInd + * Purpose: Updates the DL CQI for the UE + * + * Invoked by: TOM + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ue + * @param[in] TfuDlCqiRpt *dlCqiRpt + * @param[in] CmLteTimingInfo timingInfo + * @return Void + * + **/ +#ifdef ANSI +PUBLIC Void rgSCHUtlDlCqiInd +( +RgSchCellCb *cell, +RgSchUeCb *ue, +TfuDlCqiRpt *dlCqiRpt, +CmLteTimingInfo timingInfo +) +#else +PUBLIC Void rgSCHUtlDlCqiInd(cell, ue, dlCqiRpt, timingInfo) +RgSchCellCb *cell; +RgSchUeCb *ue; +TfuDlCqiRpt *dlCqiRpt; +CmLteTimingInfo timingInfo; +#endif +{ + RgSchCellCb *sCellCb = NULLP; + TRC2(rgSCHUtlDlCqiInd); + if (dlCqiRpt->isPucchInfo) + { + sCellCb = ue->cellInfo[dlCqiRpt->dlCqiInfo.pucchCqi.cellIdx]->cell; + sCellCb->sc.apis->rgSCHDlCqiInd(sCellCb, ue, dlCqiRpt->isPucchInfo, \ + (Void *)&dlCqiRpt->dlCqiInfo.pucchCqi, timingInfo); + } + else + { + U32 idx; + for (idx = 0; idx < dlCqiRpt->dlCqiInfo.pusch.numOfCells; idx++) + { + sCellCb = ue->cellInfo[dlCqiRpt->dlCqiInfo.pusch.puschCqi[idx].cellIdx]->cell; + sCellCb->sc.apis->rgSCHDlCqiInd(sCellCb, ue, dlCqiRpt->isPucchInfo, \ + (Void *)&dlCqiRpt->dlCqiInfo.pusch.puschCqi[idx], timingInfo); + } + } + RETVOID; +} + + +#ifdef TFU_UPGRADE +/** + * @brief This function is a wrapper to call scheduler specific API. + * + * @details + * + * Function: rgSCHUtlSrsInd + * Purpose: Updates the UL SRS for the UE + * + * Invoked by: TOM + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ue + * @param[in] TfuSrsRpt* srsRpt + * @param[in] CmLteTimingInfo timingInfo + * @return Void + * + **/ +#ifdef ANSI +PUBLIC Void rgSCHUtlSrsInd +( +RgSchCellCb *cell, +RgSchUeCb *ue, +TfuSrsRpt *srsRpt, +CmLteTimingInfo timingInfo +) +#else +PUBLIC Void rgSCHUtlSrsInd(cell, ue, srsRpt, timingInfo) +RgSchCellCb *cell; +RgSchUeCb *ue; +TfuSrsRpt *srsRpt; +CmLteTimingInfo timingInfo; +#endif +{ + TRC2(rgSCHUtlSrsInd); + cell->sc.apis->rgSCHSrsInd(cell, ue, srsRpt, timingInfo); + RETVOID; +} +#endif + +/** + * @brief This function is a wrapper to call scheduler specific API. + * + * @details + * + * Function: rgSCHUtlDlTARpt + * Purpose: Reports PHY TA for a UE. + * + * Invoked by: TOM + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ue + * @return Void + * + **/ +#ifdef ANSI +PUBLIC Void rgSCHUtlDlTARpt +( +RgSchCellCb *cell, +RgSchUeCb *ue +) +#else +PUBLIC Void rgSCHUtlDlTARpt(cell, ue) +RgSchCellCb *cell; +RgSchUeCb *ue; +#endif +{ + TRC2(rgSCHUtlDlTARpt); + cell->sc.apis->rgSCHDlTARpt(cell, ue); + RETVOID; +} + + +/** + * @brief This function is a wrapper to call scheduler specific API. + * + * @details + * + * Function: rgSCHUtlDlRlsSubFrm + * Purpose: Releases scheduler Information from DL SubFrm. + * + * Invoked by: DHM + * + * @param[in] RgSchCellCb *cell + * @param[out] CmLteTimingInfo subFrm + * @return Void + * + **/ +#ifdef ANSI +PUBLIC Void rgSCHUtlDlRlsSubFrm +( +RgSchCellCb *cell, +CmLteTimingInfo subFrm +) +#else +PUBLIC Void rgSCHUtlDlRlsSubFrm(cell, subFrm) +RgSchCellCb *cell; +CmLteTimingInfo subFrm; +#endif +{ + TRC2(rgSCHUtlDlRlsSubFrm); + cell->sc.apis->rgSCHDlRlsSubFrm(cell, subFrm); + RETVOID; +} + +#ifdef TFU_UPGRADE +/** + * @brief This API is invoked to update the AperCQI trigger + * weight. + * + * @details + * + * Function : rgSCHUtlUpdACqiTrigWt + * - If HqFdbk is ACK then add up weight corresponding + * to ACK to the AcqiTrigWt. + * - If HqFdbk is NACK then add up weight corresponding + * to NACK to the AcqiTrigWt. + * - If AcqiTrigWt crosses threshold then trigger + * grant req for APERCQI to SCH. + * + * @param[in] RgSchUeCb *ue + * @param[in] U8 isAck + * + * @return Void + **/ +#ifdef ANSI +PUBLIC Void rgSCHUtlUpdACqiTrigWt +( +RgSchUeCb *ue, +RgSchUeCellInfo *cellInfo, +U8 isAck +) +#else +PUBLIC Void rgSCHUtlUpdACqiTrigWt(ue,cellInfo, isAck) +RgSchUeCb *ue; +RgSchUeCellInfo *cellInfo; +U8 isAck; +#endif +{ +#ifdef LTE_ADV + U8 triggerSet = 0; + U8 sIdx = 0; +#endif + + TRC2(rgSCHUtlUpdACqiTrigWt); + + if (isAck == TFU_HQFDB_ACK) + { + cellInfo->acqiCb.aCqiTrigWt += RG_APER_CQI_ACK_WGT; + } + else + { + cellInfo->acqiCb.aCqiTrigWt += RG_APER_CQI_NACK_WGT; + } + + if (cellInfo->acqiCb.aCqiTrigWt > RG_APER_CQI_THRESHOLD_WGT) + { + RgSchCellCb *cell = ue->cell; + RgSchErrInfo unUsed; + + if(ue->dl.reqForCqi) + { + /* Already one ACQI trigger procedure is going on + * which is not yet satisfied. Delaying this request till + * the previous is getting satisfied*/ + RETVOID; + } + + ue->dl.reqForCqi = TRUE; +#ifdef LTE_ADV + rgSchCmnSetCqiReqField(cellInfo,ue,&ue->dl.reqForCqi); + //Reset aCqiTrigWt for all the serving cells for which we have triggered ACQI + rgSCHTomUtlGetTrigSet(cell, ue, ue->dl.reqForCqi, &triggerSet); + for (sIdx = 0; sIdx < CM_LTE_MAX_CELLS; sIdx++) + { + /* The Aperiodic requested for SCell index sIdx */ + if ((triggerSet >> (7 - sIdx)) & 0x01) + { + /* The Aperiodic request for SCell index sIdx */ + ue->cellInfo[sIdx]->acqiCb.aCqiTrigWt = 0; + } + } + +#endif + /* Force SCH to send UL grant by indicating fake SR. + * If this UE already in UL SCH Qs this SR Ind will + * be ignored */ + rgSCHUtlSrRcvd(cell, ue, cell->crntTime, &unUsed); + } + + RETVOID; +} +#endif + +/** + * @brief This API is invoked to indicate scheduler of a CRC indication. + * + * @details + * + * Function : rgSCHUtlHdlUlTransInd + * This API is invoked to indicate scheduler of a CRC indication. + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ue + * @param[in] CmLteTimingInfo timingInfo + * + * @return Void + **/ +#ifdef ANSI +PUBLIC Void rgSCHUtlHdlUlTransInd +( +RgSchCellCb *cell, +RgSchUeCb *ue, +CmLteTimingInfo timingInfo +) +#else +PUBLIC Void rgSCHUtlHdlUlTransInd(cell, ue, timingInfo) +RgSchCellCb *cell; +RgSchUeCb *ue; +CmLteTimingInfo timingInfo; +#endif +{ + TRC2(rgSCHUtlHdlUlTransInd); + cell->sc.apis->rgSCHHdlUlTransInd(cell, ue, timingInfo); + RETVOID; +} +#ifdef LTEMAC_SPS +/** + * @brief This API is invoked to indicate scheduler of a CRC failure. + * + * @details + * + * Function : rgSCHUtlHdlCrcInd + * This API is invoked to indicate CRC to scheduler. + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ue + * @param[in] CmLteTimingInfo timingInfo + * + * @return Void + **/ +#ifdef ANSI +PUBLIC Void rgSCHUtlHdlCrcInd +( +RgSchCellCb *cell, +RgSchUeCb *ue, +CmLteTimingInfo timingInfo +) +#else +PUBLIC Void rgSCHUtlHdlCrcInd(cell, ue, timingInfo) +RgSchCellCb *cell; +RgSchUeCb *ue; +CmLteTimingInfo timingInfo; +#endif +{ + TRC2(rgSCHUtlHdlCrcFail); + cell->sc.apis->rgSCHUlCrcInd(cell, ue, timingInfo); + RETVOID; +} /* end of rgSCHUtlHdlCrcFailInd */ + +/** + * @brief This API is invoked to indicate scheduler of a CRC failure. + * + * @details + * + * Function : rgSCHUtlHdlCrcFailInd + * This API is invoked to indicate CRC failure to scheduler. + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ue + * @param[in] CmLteTimingInfo timingInfo + * + * @return Void + **/ +#ifdef ANSI +PUBLIC Void rgSCHUtlHdlCrcFailInd +( +RgSchCellCb *cell, +RgSchUeCb *ue, +CmLteTimingInfo timingInfo +) +#else +PUBLIC Void rgSCHUtlHdlCrcFailInd(cell, ue, timingInfo) +RgSchCellCb *cell; +RgSchUeCb *ue; +CmLteTimingInfo timingInfo; +#endif +{ + TRC2(rgSCHUtlHdlCrcFail); + cell->sc.apis->rgSCHUlCrcFailInd(cell, ue, timingInfo); + RETVOID; +} /* end of rgSCHUtlHdlCrcFailInd */ +#endif /* LTEMAC_SPS */ + + +/** + * @brief This function is a wrapper to call scheduler specific API. + * + * @details + * + * Function: rgSCHUtlDlProcAddToRetx + * Purpose: This function adds a HARQ process to retransmission + * queue. This may be performed when a HARQ ack is + * unsuccessful. + * + * Invoked by: HARQ feedback processing + * + * @param[in] RgSchCellCb* cell + * @param[in] RgSchDlHqProc* hqP + * @return Void + * + **/ +#ifdef ANSI +PUBLIC Void rgSCHUtlDlProcAddToRetx +( +RgSchCellCb *cell, +RgSchDlHqProcCb *hqP +) +#else +PUBLIC Void rgSCHUtlDlProcAddToRetx(cell, hqP) +RgSchCellCb *cell; +RgSchDlHqProcCb *hqP; +#endif +{ + TRC2(rgSCHUtlDlProcAddToRetx); + cell->sc.apis->rgSCHDlProcAddToRetx(cell, hqP); + RETVOID; +} + + +/** + * @brief This function adds a HARQ process TB to transmission + * + * @details + * + * Function: rgSCHUtlDlHqPTbAddToTx + * Purpose: This function a HarqProcess TB to the subframe + * list. + * + * Invoked by: Scheduler + * + * @param[in] RgSubFrm* subFrm + * @param[in] RgDlHqProc* hqP + * @param[in] U8 tbIdx + * @return Void + * + **/ +#ifdef ANSI +PUBLIC Void rgSCHUtlDlHqPTbAddToTx +( +RgSchDlSf *subFrm, +RgSchDlHqProcCb *hqP, +U8 tbIdx +) +#else +PUBLIC Void rgSCHUtlDlHqPTbAddToTx(subFrm, hqP, tbIdx) +RgSchDlSf *subFrm; +RgSchDlHqProcCb *hqP; +U8 tbIdx; +#endif +{ + RgSchUeCb *ue = NULLP; + RgSchCellCb *cell = hqP->hqE->cell; + /* CA Dev Start */ + /* Addition of UE to dlSf->ueLst shall be done only to UE's PCell */ + /* ue->cell will always hold PCell information */ + if (NULLP == hqP->hqPSfLnk.node) + { + if (hqP->hqE->ue) + { + ue = hqP->hqE->ue; + if(NULLP == ue->dl.dlSfHqInfo[cell->cellId][subFrm->dlIdx].dlSfUeLnk.node) + { + ue->dl.dlSfHqInfo[cell->cellId][subFrm->dlIdx].dlSfUeLnk.node = (PTR)ue; + cmLListAdd2Tail(&cell->subFrms[subFrm->dlIdx]->ueLst, + &ue->dl.dlSfHqInfo[cell->cellId][subFrm->dlIdx].dlSfUeLnk); + + ue->dl.dlSfHqInfo[cell->cellId][subFrm->dlIdx].isPuschHarqRecpPres = FALSE; + + } + + /* Add Hq proc in particular dlIdx List for this UE + This list will be used while processing feedback*/ + hqP->hqPSfLnk.node = (PTR)hqP; + cmLListAdd2Tail(&ue->dl.dlSfHqInfo[cell->cellId][subFrm->dlIdx].hqPLst,&hqP->hqPSfLnk); +#ifdef CA_DBG + { + extern U32 gSCellSchedCount,gPrimarySchedCount; + if(RG_SCH_IS_CELL_SEC(hqP->hqE->ue,hqP->hqE->cell)) + { + gSCellSchedCount++; + }else + gPrimarySchedCount++; + } +#endif + } + else if (hqP->hqE->msg4Proc == hqP) + { + /* Msg4 will be scheduled on PCELL only hence add directly to subFrm msg4HqpList */ + hqP->hqPSfLnk.node = (PTR)hqP; + cmLListAdd2Tail(&subFrm->msg4HqPLst, &hqP->hqPSfLnk); + } + } + else + { + ue = hqP->hqE->ue; + } + if((ue) && (HQ_TB_WAITING == hqP->tbInfo[tbIdx].state)) + + { + ue->dl.dlSfHqInfo[cell->cellId][subFrm->dlIdx].totalTbCnt++; + } + /*totalTbCnt will hold the total number of TBs across all harq Proc from all + * cells*/ + + hqP->subFrm = subFrm; + + /* CA Dev End */ + RETVOID; +} + + + +/** + * @brief This function removes a HARQ process TB from transmission + * + * @details + * + * Function: rgSCHUtlDlHqPTbRmvFrmTx + * Purpose: This function removes a HarqProcess TB to the subframe + * list. + * + * Invoked by: Scheduler + * + * @param[in] RgSubFrm* subFrm + * @param[in] RgDlHqProc* hqP + * @param[in] U8 tbIdx + * @param[in] Bool isRepeting + * @return Void + * + **/ +#ifdef ANSI +PUBLIC Void rgSCHUtlDlHqPTbRmvFrmTx +( +RgSchDlSf *subFrm, +RgSchDlHqProcCb *hqP, +U8 tbIdx, +Bool isRepeting +) +#else +PUBLIC Void rgSCHUtlDlHqPTbRmvFrmTx(subFrm, hqP, tbIdx, isRepeting) +RgSchDlSf *subFrm; +RgSchDlHqProcCb *hqP; +U8 tbIdx; +Bool isRepeting; +#endif +{ + RgSchCellCb *cell = NULLP; + /* Check with TDD */ + if ((isRepeting) && + (hqP->hqE->ue->ackNakRepCb.cfgRepCnt != + hqP->tbInfo[tbIdx].fbkRepCntr)) + { + cmLListDelFrm(&subFrm->ackNakRepQ, + &hqP->tbInfo[tbIdx].anRepLnk[hqP->tbInfo[tbIdx].fbkRepCntr]); + } + else + { + if (NULLP != hqP->hqPSfLnk.node) + { + /* CA dev Start */ + if (hqP->hqE->msg4Proc == hqP) + { + /* Msg4 will be scheduled on PCELL only hence delete directly from subFrm msg4HqpList */ + cmLListDelFrm(&subFrm->msg4HqPLst, &hqP->hqPSfLnk); + } + else + { + cell = hqP->hqE->cell; + /* Addition of UE to dlSf->ueLst shall be done only to UE's PCell */ + /* ue->cell will always hold PCell information */ + cmLListDelFrm(&hqP->hqE->ue->dl.dlSfHqInfo[cell->cellId][subFrm->dlIdx].hqPLst,&hqP->hqPSfLnk); + if (0 == hqP->hqE->ue->dl.dlSfHqInfo[cell->cellId][subFrm->dlIdx].hqPLst.count) + { + + cmLListDelFrm(&cell->subFrms[subFrm->dlIdx]->ueLst, + &hqP->hqE->ue->dl.dlSfHqInfo[cell->cellId][subFrm->dlIdx].dlSfUeLnk); + hqP->hqE->ue->dl.dlSfHqInfo[cell->cellId][subFrm->dlIdx].dlSfUeLnk.node = (PTR)NULLP; + hqP->hqE->ue->dl.dlSfHqInfo[cell->cellId][subFrm->dlIdx].totalTbCnt = 0; + } + } + hqP->hqPSfLnk.node = NULLP; + } + hqP->subFrm = NULLP; + } + RETVOID; +} + +#ifdef LTE_ADV +/** + * @brief Handler for accessing the existing SCellCb identified by the key + * SCellId under the CellCb. + * + * @details + * + * Function : rgSchUtlGetCellCb + * + * + * @param[in] *cellCb + * @param[in] ueId + * @return RgSchUeCb* + **/ +#ifdef ANSI +PUBLIC RgSchCellCb* rgSchUtlGetCellCb +( + Inst inst, + U16 cellId +) +#else +PUBLIC RgSchCellCb* rgSchUtlGetCellCb(inst, cellId) + Inst inst; + U16 cellId; +#endif +{ + RgSchCellCb *cellCb = NULLP; + U8 strtCellId; + + TRC2(rgSchUtlGetCellCb); + + strtCellId = rgSchCb[inst].genCfg.startCellId; + cellCb = rgSchCb[inst].cells[cellId - strtCellId]; + + RETVALUE(cellCb); + +} /* rgSchUtlGetCellCb */ + +/** + * @brief Handler for deriving the servCellidx + * + * @details + * + * Function : rgSchUtlGetServCellIdx + * + * + * @param[in] *cellId + * @param[in] RgSchUeCb *ue + * @return U8 servCellIdx + **/ +#ifdef ANSI +PUBLIC U8 rgSchUtlGetServCellIdx +( + Inst inst, + U16 cellId, + RgSchUeCb *ue +) +#else +PUBLIC U8 rgSchUtlGetServCellIdx(inst,cellId,ue) + Inst inst; + U16 cellId; + RgSchUeCb *ue; +#endif +{ + U8 servCellIdx; + U16 strtCellId; + + TRC2(rgSchUtlGetCellCb); + + strtCellId = rgSchCb[inst].genCfg.startCellId; + + servCellIdx = ue->cellIdToCellIdxMap[cellId - strtCellId]; + + RETVALUE(servCellIdx); + +} /* rgSchUtlGetCellCb */ + +/** + * @brief Handler for validating the Cell Id received secondary Cell Addition + * + * @details + * + * Function : rgSchUtlGetCellId + * + * + * @param[in] *cellCb + * @param[in] ueId + * @return RgSchUeCb* + **/ +#ifdef ANSI +PUBLIC S16 rgSchUtlVldtCellId +( + Inst inst, + U16 cellId +) +#else +PUBLIC S16 rgSchUtlVldtCellId(inst, cellId) + Inst inst; + U16 cellId; +#endif +{ + U8 strtCellId; + + TRC2(rgSchUtlVldtCellId); + + strtCellId = rgSchCb[inst].genCfg.startCellId; + if((cellId >= strtCellId) && ((cellId - strtCellId) < CM_LTE_MAX_CELLS)) + { + RETVALUE(ROK); + } + RETVALUE(RFAILED); +} /* rgSchUtlVldtCellId */ + +#endif /* LTE_ADV*/ +/** + * @brief UE reconfiguration for scheduler + * + * @details + * + * Function : rgSCHUtlRgrUeRecfg + * + * This functions updates UE specific scheduler + * information upon UE reconfiguration + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ue + * @param[int] RgrUeRecfg *ueRecfg + * @param[out] RgSchErrInfo *err + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 rgSCHUtlRgrUeRecfg +( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgrUeRecfg *ueRecfg, +RgSchErrInfo *err +) +#else +PUBLIC S16 rgSCHUtlRgrUeRecfg(cell, ue, ueRecfg, err) +RgSchCellCb *cell; +RgSchUeCb *ue; +RgrUeRecfg *ueRecfg; +RgSchErrInfo *err; +#endif +{ +/* Changes for UE Category Reconfiguration feature addition */ + RgSchCmnUe *ueSch = RG_SCH_CMN_GET_UE(ue, cell); + + TRC2(rgSCHUtlRgrUeRecfg); + + /* Changes for UE Category Reconfiguration feature addition */ + if (ueRecfg->ueRecfgTypes & RGR_UE_UECAT_RECFG) + { + ueSch->cmn.ueCat = ueRecfg->ueCatEnum-1; +#ifdef TFU_UPGRADE + ue->ueCatEnum = ueRecfg->ueCatEnum; +#endif + } + + /* DL MU-MIMO not supported */ + if (ueRecfg->ueRecfgTypes & RGR_UE_TXMODE_RECFG) + { + + if (ueRecfg->txMode.pres == PRSNT_NODEF) + { + if (ueRecfg->txMode.txModeEnum == RGR_UE_TM_5) + { + err->errCause = RGSCHERR_SCH_CFG; + RETVALUE(RFAILED); + } +#ifdef LTE_ADV + if(ue->mimoInfo.txMode != ueRecfg->txMode.txModeEnum) + { + /* Decremnt the previos A value for this cell */ + ue->f1bCsAVal -= rgSCHUtlGetMaxTbSupp(ue->mimoInfo.txMode); + /* Update A value with the new TM Mode */ + ue->f1bCsAVal += rgSCHUtlGetMaxTbSupp(ueRecfg->txMode.txModeEnum); + + + RLOG1(L_INFO,"UeReCfg A valie is %d\n",ue->f1bCsAVal); + } +#endif + ue->mimoInfo.txMode = ueRecfg->txMode.txModeEnum; + } + } +#ifdef TFU_UPGRADE + /* [ccpu00123958]-ADD- Check for PUSCH related Reconfig from the bit mask */ + if(ueRecfg->ueRecfgTypes & RGR_UE_PUSCH_RECFG) + { + /* Fix: ccpu00124012 */ + /* TODO:: Need to check if this is + mandatory to be re-configured on UE category re-configuration */ + /* ue->ul.betaHqOffst = ueRecfg->puschDedCfg.bACKIdx; + ue->ul.betaCqiOffst = ueRecfg->puschDedCfg.bCQIIdx; + ue->ul.betaRiOffst = ueRecfg->puschDedCfg.bRIIdx;*/ + } +#endif + if (ueRecfg->ueRecfgTypes & RGR_UE_ULTXANTSEL_RECFG) + { + ue->ul.ulTxAntSel = ueRecfg->ulTxAntSel; + } + if (ueRecfg->ueRecfgTypes & RGR_UE_CDBKSBST_RECFG) + { + ue->mimoInfo.cdbkSbstRstrctn = ueRecfg->ueCodeBookRstRecfg; + } + + /* Commenting here to assign garbage value when it is not set in APP. */ + //ue->accessStratumRls = ueRecfg->accessStratumRls; + RETVALUE(cell->sc.apis->rgSCHRgrUeRecfg(cell, ue, ueRecfg, err)); +} /* rgSCHUtlRgrUeRecfg */ + +/** + * @brief This function deletes a service from scheduler + * + * @details + * + * Function: rgSCHUtlFreeDlLc + * Purpose: This function is made available through a FP for + * making scheduler aware of a service being deleted from UE + * + * Invoked by: BO and Scheduler + * + * @param[in] RgSchCellCb* cell + * @param[in] RgSchUeCb* ue + * @param[in] RgSchDlLcCb* svc + * @return Void + **/ +#ifdef ANSI +PUBLIC Void rgSCHUtlFreeDlLc +( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgSchDlLcCb *svc +) +#else +PUBLIC Void rgSCHUtlFreeDlLc(cell, ue, svc) +RgSchCellCb *cell; +RgSchUeCb *ue; +RgSchDlLcCb *svc; +#endif +{ + TRC2(rgSCHUtlFreeDlLc); + cell->sc.apis->rgSCHFreeDlLc(cell, ue, svc); + + /* Stack Crash problem for TRACE5 changes. added the return below . */ + RETVOID; + +} + +/** + * @brief UE deletion for scheduler + * + * @details + * + * Function : rgSCHUtlFreeUe + * + * This functions deletes all scheduler information + * pertaining to a UE + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ue + * @return Void + **/ +#ifdef ANSI +PUBLIC Void rgSCHUtlFreeUe +( +RgSchCellCb *cell, +RgSchUeCb *ue +) +#else +PUBLIC Void rgSCHUtlFreeUe(cell, ue) +RgSchCellCb *cell; +RgSchUeCb *ue; +#endif +{ + TRC2(rgSCHUtlFreeUe); +#ifdef LTE_TDD + rgSCHUtlDelUeANFdbkInfo(ue,RGSCH_PCELL_INDEX); +#endif + cell->sc.apis->rgSCHFreeUe(cell, ue); + + /* Stack Crash problem for TRACE5 changes. added the return below . */ + RETVOID; + +} /* rgSCHUtlFreeUe */ + +/** + * @brief This function updates the scheduler with service for a UE + * + * @details + * + * Function: rgSCHUtlDlDedBoUpd + * Purpose: This function should be called whenever there is a + * change BO for a service. + * + * Invoked by: BO and Scheduler + * + * @param[in] RgSchCellCb* cell + * @param[in] RgSchUeCb* ue + * @param[in] RgSchDlLcCb* lc + * @return Void + **/ +#ifdef ANSI +PUBLIC Void rgSCHUtlDlDedBoUpd +( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgSchDlLcCb *lc +) +#else +PUBLIC Void rgSCHUtlDlDedBoUpd(cell, ue, lc) +RgSchCellCb *cell; +RgSchUeCb *ue; +RgSchDlLcCb *lc; +#endif +{ + TRC2(rgSCHUtlDlDedBoUpd); + cell->sc.apis->rgSCHDlDedBoUpd(cell, ue, lc); + RETVOID; +} +/** + * @brief Record MSG3 allocation into the UE + * + * @details + * + * Function : rgSCHUtlRecMsg3Alloc + * + * This function is invoked to update record msg3 allocation information + * in the UE when UE is detected for RaCb + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ue + * @param[in] RgSchRaCb *raCb + * + **/ +#ifdef ANSI +PUBLIC Void rgSCHUtlRecMsg3Alloc +( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgSchRaCb *raCb +) +#else +PUBLIC Void rgSCHUtlRecMsg3Alloc(cell, ue, raCb) +RgSchCellCb *cell; +RgSchUeCb *ue; +RgSchRaCb *raCb; +#endif +{ + TRC2(rgSCHUtlRecMsg3Alloc) + cell->sc.apis->rgSCHUlRecMsg3Alloc(cell, ue, raCb); + RETVOID; + +} /* rgSCHRecMsg3Alloc */ + +#ifdef RG_UNUSED +/** + * @brief Update harq process for allocation + * + * @details + * + * Function : rgSCHUtlUpdUlHqProc + * + * This function is invoked when harq process + * control block is now in a new memory location + * thus requiring a pointer/reference update. + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUlHqProcCb *curProc + * @param[in] RgSchUlHqProcCb *oldProc + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 rgSCHUtlUpdUlHqProc +( +RgSchCellCb *cell, +RgSchUlHqProcCb *curProc, +RgSchUlHqProcCb *oldProc +) +#else +PUBLIC S16 rgSCHUtlUpdUlHqProc(cell, curProc, oldProc) +RgSchCellCb *cell; +RgSchUlHqProcCb *curProc; +RgSchUlHqProcCb *oldProc; +#endif +{ + TRC2(rgSCHUtlUpdUlHqProc); + RETVALUE(cell->sc.apis->rgSCHUpdUlHqProc(cell, curProc, oldProc)); +} /* rgSCHUtlUpdUlHqProc */ +#endif +/** + * @brief UL grant for contention resolution + * + * @details + * + * Function : rgSCHUtlContResUlGrant + * + * Add UE to another queue specifically for CRNTI based contention + * resolution + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ue + * @param[out] RgSchErrInfo *err + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 rgSCHUtlContResUlGrant +( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgSchErrInfo *err +) +#else +PUBLIC S16 rgSCHUtlContResUlGrant(cell, ue, err) +RgSchCellCb *cell; +RgSchUeCb *ue; +RgSchErrInfo *err; +#endif +{ + TRC2(rgSCHUtlContResUlGrant); + + + ue->isMsg4PdcchWithCrnti = TRUE; + + RETVALUE(cell->sc.apis->rgSCHContResUlGrant(cell, ue, err)); +} /* rgSCHUtlContResUlGrant */ + +/** + * @brief SR reception handling + * + * @details + * + * Function : rgSCHUtlSrRcvd + * + * - Handles SR reception for UE + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ue + * @param[out] RgSchErrInfo *err + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 rgSCHUtlSrRcvd +( +RgSchCellCb *cell, +RgSchUeCb *ue, +CmLteTimingInfo frm, +RgSchErrInfo *err +) +#else +PUBLIC S16 rgSCHUtlSrRcvd(cell, ue, frm, err) +RgSchCellCb *cell; +RgSchUeCb *ue; +CmLteTimingInfo frm; +RgSchErrInfo *err; +#endif +{ + TRC2(rgSCHUtlSrRcvd); + RETVALUE(cell->sc.apis->rgSCHSrRcvd(cell, ue, frm, err)); +} /* rgSCHUtlSrRcvd */ + +/** + * @brief Short BSR update + * + * @details + * + * Function : rgSCHUtlUpdBsrShort + * + * This functions does requisite updates to handle short BSR reporting + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ue + * @param[in] U8 lcgId + * @param[in] U8 bsr + * @param[out] RgSchErrInfo *err + * @return Void + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC Void rgSCHUtlUpdBsrShort +( +RgSchCellCb *cell, +RgSchUeCb *ue, +U8 lcgId, +U8 bsr, +RgSchErrInfo *err +) +#else +PUBLIC Void rgSCHUtlUpdBsrShort(cell, ue, lcgId, bsr, err) +RgSchCellCb *cell; +RgSchUeCb *ue; +U8 lcgId; +U8 bsr; +RgSchErrInfo *err; +#endif +{ + TRC2(rgSCHUtlUpdBsrShort); + cell->sc.apis->rgSCHUpdBsrShort(cell, ue, &ue->ul.lcgArr[lcgId], bsr, err); + RETVOID; +} /* rgSCHUtlUpdBsrShort */ + + +/** + * @brief Truncated BSR update + * + * @details + * + * Function : rgSCHUtlUpdBsrTrunc + * + * This functions does required updates to handle truncated BSR report + * + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ue + * @param[in] U8 lcgId + * @param[in] U8 bsr + * @param[out] RgSchErrInfo *err + * @return Void + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC Void rgSCHUtlUpdBsrTrunc +( +RgSchCellCb *cell, +RgSchUeCb *ue, +U8 lcgId, +U8 bsr, +RgSchErrInfo *err +) +#else +PUBLIC Void rgSCHUtlUpdBsrTrunc(cell, ue, lcgId, bsr, err) +RgSchCellCb *cell; +RgSchUeCb *ue; +U8 lcgId; +U8 bsr; +RgSchErrInfo *err; +#endif +{ + TRC2(rgSCHUtlUpdBsrTrunc); + cell->sc.apis->rgSCHUpdBsrTrunc(cell, ue, &ue->ul.lcgArr[lcgId], bsr, err); + RETVOID; +} /* rgSCHUtlUpdBsrTrunc */ + + +/** + * @brief Long BSR update + * + * @details + * + * Function : rgSCHUtlUpdBsrLong + * + * - Update BSRs for all configured LCGs + * - Update priority of LCGs if needed + * - Update UE's position within/across uplink scheduling queues + * + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ue + * @param[in] U8 bsr0 + * @param[in] U8 bsr1 + * @param[in] U8 bsr2 + * @param[in] U8 bsr3 + * @param[out] RgSchErrInfo *err + * @return Void + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC Void rgSCHUtlUpdBsrLong +( +RgSchCellCb *cell, +RgSchUeCb *ue, +U8 bsr0, +U8 bsr1, +U8 bsr2, +U8 bsr3, +RgSchErrInfo *err +) +#else +PUBLIC Void rgSCHUtlUpdBsrLong(cell, ue, bsr0, bsr1, bsr2, bsr3, err) +RgSchCellCb *cell; +RgSchUeCb *ue; +U8 bsr0; +U8 bsr1; +U8 bsr2; +U8 bsr3; +RgSchErrInfo *err; +#endif +{ + U8 bsArr[4]; + TRC2(rgSCHUtlUpdBsrLong); + + bsArr[0] = bsr0; + bsArr[1] = bsr1; + bsArr[2] = bsr2; + bsArr[3] = bsr3; + cell->sc.apis->rgSCHUpdBsrLong(cell, ue, bsArr, err); + RETVOID; +} /* rgSCHUtlUpdBsrLong */ + +/** + * @brief EXT PHR update + * + * @details + * + * Function : rgSCHUtlUpdExtPhr + * + * Updates extended power headroom info for a UE + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ue + * @param[in] U8 phr + * @param[out] RgSchErrInfo *err + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 rgSCHUtlUpdExtPhr +( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgInfExtPhrCEInfo * extPhr, +RgSchErrInfo *err +) +#else +PUBLIC S16 rgSCHUtlUpdExtPhr(cell, ue, extPhr, err) +RgSchCellCb *cell; +RgSchUeCb *ue; +RgInfExtPhrCEInfo * extPhr; +RgSchErrInfo *err; +#endif +{ + TRC2(rgSCHUtlUpdExtPhr); + RETVALUE(cell->sc.apis->rgSCHUpdExtPhr(cell, ue, extPhr, err)); +} /* rgSCHUtlUpdExtPhr */ + + + +/** + * @brief PHR update + * + * @details + * + * Function : rgSCHUtlUpdPhr + * + * Updates power headroom info for a UE + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ue + * @param[in] U8 phr + * @param[out] RgSchErrInfo *err + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 rgSCHUtlUpdPhr +( +RgSchCellCb *cell, +RgSchUeCb *ue, +U8 phr, +RgSchErrInfo *err +) +#else +PUBLIC S16 rgSCHUtlUpdPhr(cell, ue, phr, err) +RgSchCellCb *cell; +RgSchUeCb *ue; +U8 phr; +RgSchErrInfo *err; +#endif +{ + TRC2(rgSCHUtlUpdPhr); + RETVALUE(cell->sc.apis->rgSCHUpdPhr(cell, ue, phr, err)); +} /* rgSCHUtlUpdPhr */ + + +/** + * @brief Indication of UL CQI + * + * @details + * + * Function : rgSCHUtlUlCqiInd + * + * - Updates uplink CQI information for the UE. Computes and + * stores the lowest CQI of CQIs reported in all subbands + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ue + * @param[in] TfuUlCqiRpt *ulCqiInfo + * @return Void + **/ +#ifdef ANSI +PUBLIC Void rgSCHUtlUlCqiInd +( +RgSchCellCb *cell, +RgSchUeCb *ue, +TfuUlCqiRpt *ulCqiInfo +) +#else +PUBLIC Void rgSCHUtlUlCqiInd(cell, ue, ulCqiInfo) +RgSchCellCb *cell; +RgSchUeCb *ue; +TfuUlCqiRpt *ulCqiInfo; +#endif +{ + TRC2(rgSCHUtlUlCqiInd); + cell->sc.apis->rgSCHUlCqiInd(cell, ue, ulCqiInfo); + RETVOID; +} /* rgSCHUtlUlCqiInd */ + +/** + * @brief Indication of PUCCH power adjustment + * + * @details + * + * Function : rgSCHUtlPucchDeltaPwrInd + * + * - Updates uplink CQI information for the UE. Computes and + * stores the lowest CQI of CQIs reported in all subbands + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ue + * @param[in] U8 delta + * @return Void + **/ +#ifdef ANSI +PUBLIC Void rgSCHUtlPucchDeltaPwrInd +( +RgSchCellCb *cell, +RgSchUeCb *ue, +S8 delta +) +#else +PUBLIC Void rgSCHUtlPucchDeltaPwrInd(cell, ue, delta) +RgSchCellCb *cell; +RgSchUeCb *ue; +S8 delta; +#endif +{ + TRC2(rgSCHUtlPucchDeltaPwrInd); + cell->sc.apis->rgSCHPucchDeltaPwrInd(cell, ue, delta); + RETVOID; +} /* rgSCHUtlPucchDeltaPwrInd */ + +/* Start: LTEMAC_2.1_DEV_CFG */ +/** + * @brief Ue Reset Request + * + * @details + * + * Function : rgSCHUtlUeReset + * + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ue + * @return S16 + **/ +#ifdef ANSI +PUBLIC Void rgSCHUtlUeReset +( +RgSchCellCb *cell, +RgSchUeCb *ue +) +#else +PUBLIC Void rgSCHUtlUeReset(cell, ue) +RgSchCellCb *cell; +RgSchUeCb *ue; +#endif +{ + TRC2(rgSCHUtlUeReset); + ue->remBoCnt = 0; + cell->sc.apis->rgSCHUeReset(cell, ue); + RETVOID; +} /* rgSCHUtlUeReset */ +/* End: LTEMAC_2.1_DEV_CFG */ + +/** + * @brief Returns HARQ proc for which data expected now + * + * @details + * + * Function: rgSCHUtlUlHqProcForUe + * Purpose: This function returns the harq process for + * which data is expected in the current subframe. + * It does not validate if the HARQ process + * has an allocation. + * + * Invoked by: TOM + * + * @param[in] RgSchCellCb *cell + * @param[in] CmLteTimingInfo frm + * @param[in] RgSchUeCb *ue + * @param[out] RgSchUlHqProcCb **procRef + * @return Void + **/ +#ifdef ANSI +PUBLIC Void rgSCHUtlUlHqProcForUe +( +RgSchCellCb *cell, +CmLteTimingInfo frm, +RgSchUeCb *ue, +RgSchUlHqProcCb **procRef +) +#else +PUBLIC Void rgSCHUtlUlHqProcForUe(cell, frm, ue, procRef) +RgSchCellCb *cell; +CmLteTimingInfo frm; +RgSchUeCb *ue; +RgSchUlHqProcCb **procRef; +#endif +{ + TRC2(rgSCHUtlUlHqProcForUe); + cell->sc.apis->rgSCHUlHqProcForUe(cell, frm, ue, procRef); + + /* Stack Crash problems for TRACE5 changes. added the return below */ + RETVOID; + +} + +/** + * @brief Returns first uplink allocation to send reception + * request to PHY + * + * @details + * + * Function: rgSCHUtlFirstRcptnReq(cell) + * Purpose: This function returns the first uplink allocation + * (or NULLP if there is none) in the subframe + * in which is expected to prepare and send reception + * request to PHY. + * + * Invoked by: TOM + * + * @param[in] RgSchCellCb *cell + * @return RgSchUlAlloc* + **/ +#ifdef ANSI +PUBLIC RgSchUlAlloc *rgSCHUtlFirstRcptnReq +( +RgSchCellCb *cell +) +#else +PUBLIC RgSchUlAlloc *rgSCHUtlFirstRcptnReq(cell) +RgSchCellCb *cell; +#endif +{ + TRC2(rgSCHUtlFirstRcptnReq); + RETVALUE(cell->sc.apis->rgSCHFirstRcptnReq(cell)); +} + +/** + * @brief Returns first uplink allocation to send reception + * request to PHY + * + * @details + * + * Function: rgSCHUtlNextRcptnReq(cell) + * Purpose: This function returns the next uplink allocation + * (or NULLP if there is none) in the subframe + * in which is expected to prepare and send reception + * request to PHY. + * + * Invoked by: TOM + * + * @param[in] RgSchCellCb *cell + * @return RgSchUlAlloc* + **/ +#ifdef ANSI +PUBLIC RgSchUlAlloc *rgSCHUtlNextRcptnReq +( +RgSchCellCb *cell, +RgSchUlAlloc *alloc +) +#else +PUBLIC RgSchUlAlloc *rgSCHUtlNextRcptnReq(cell, alloc) +RgSchCellCb *cell; +RgSchUlAlloc *alloc; +#endif +{ + TRC2(rgSCHUtlNextRcptnReq); + RETVALUE(cell->sc.apis->rgSCHNextRcptnReq(cell, alloc)); +} + +/** + * @brief Returns first uplink allocation to send HARQ feedback + * request to PHY + * + * @details + * + * Function: rgSCHUtlFirstHqFdbkAlloc + * Purpose: This function returns the first uplink allocation + * (or NULLP if there is none) in the subframe + * in which it is expected to prepare and send HARQ + * feedback to PHY. + * + * Invoked by: TOM + * + * @param[in] RgSchCellCb *cell + * @param[in] U8 idx + * @return RgSchUlAlloc* + **/ +#ifdef ANSI +PUBLIC RgSchUlAlloc *rgSCHUtlFirstHqFdbkAlloc +( +RgSchCellCb *cell, +U8 idx +) +#else +PUBLIC RgSchUlAlloc *rgSCHUtlFirstHqFdbkAlloc(cell, idx) +RgSchCellCb *cell; +U8 idx; +#endif +{ + TRC2(rgSCHUtlFirstHqFdbkAlloc); + RETVALUE(cell->sc.apis->rgSCHFirstHqFdbkAlloc(cell, idx)); +} + + +/** + * @brief Returns next allocation to send HARQ feedback for + * + * @details + * + * Function: rgSCHUtlNextHqFdbkAlloc(cell) + * Purpose: This function returns the next uplink allocation + * (or NULLP if there is none) in the subframe + * for which HARQ feedback needs to be sent. + * + * Invoked by: TOM + * + * @param[in] RgSchCellCb *cell + * @return RgSchUlAlloc* + **/ +#ifdef ANSI +PUBLIC RgSchUlAlloc *rgSCHUtlNextHqFdbkAlloc +( +RgSchCellCb *cell, +RgSchUlAlloc *alloc, +U8 idx +) +#else +PUBLIC RgSchUlAlloc *rgSCHUtlNextHqFdbkAlloc(cell, alloc, idx) +RgSchCellCb *cell; +RgSchUlAlloc *alloc; +U8 idx; +#endif +{ + TRC2(rgSCHUtlNextHqFdbkAlloc); + RETVALUE(cell->sc.apis->rgSCHNextHqFdbkAlloc(cell, alloc, idx)); +} + +/*********************************** +***********************************/ +/** + * @brief This API is invoked to send TFU SAP bind request to PHY. + * + * @details + * + * Function : rgSCHUtlTfuBndReq + * + * This API is invoked to send TFU SAP bind request to PHY from scheduler + * isntance. It fills in the Pst structure, spId and suId values and + * invokes bind request primitive at TFU. + * + * @param[in] Inst instId + * @param[in] SuId suId + * @param[in] SpId spId + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 rgSCHUtlTfuBndReq +( +Inst instId, +SuId suId, +SpId spId +) +#else +PUBLIC S16 rgSCHUtlTfuBndReq(instId, suId, spId) +Inst instId; +SuId suId; +SpId spId; +#endif +{ + S16 ret; + RgSchLowSapCb *tfuSap; + Pst pst; + TRC2(rgSCHUtlTfuBndReq); + + /* Get the lower SAP control block from the layer control block. */ + tfuSap = &(rgSchCb[instId].tfuSap[suId]); + (Void)cmMemcpy ((U8*)&pst, (U8*)&(tfuSap->sapCfg.sapPst), sizeof(Pst)); + if((ret = RgLiTfuSchBndReq (&pst, suId, spId)) != ROK) + { + RLOG_ARG0(L_ERROR,DBG_INSTID,instId,"rgSCHUtlTfuBndReq() Call to RgLiTfuBndReq()" + " failed"); + } + RETVALUE(ret); +} /* rgSCHUtlTfuBndReq */ + +/** + * @brief This API is invoked to send TFU SAP unbind request to PHY. + * + * @details + * + * Function : rgSCHUtlTfuUBndReq + * This API is invoked to send TFU SAP unbind request to PHY from Scheduler + * isntance. It fills in the Pst structure and spId value and invokes + * unbind request primitive at TFU. + * + * @param[in] SpId spId + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 rgSCHUtlTfuUBndReq +( +Inst inst, +RgSchLowSapCfgInfo sapCfg, +Reason reason +) +#else +PUBLIC S16 rgSCHUtlTfuUBndReq(inst, sapCfg, reason) +Inst inst; +RgSchLowSapCfgInfo sapCfg; +Reason reason; +#endif +{ + S16 ret; + Pst pst; + + TRC2(rgSCHUtlTfuUBndReq); + + /* Get the lower SAP control block from the layer control block. */ + cmMemcpy ((U8*)&pst, (U8*)&(sapCfg.sapPst), sizeof(Pst)); + if((ret = RgLiTfuSchUbndReq (&pst, sapCfg.spId, reason)) != ROK) + { + RLOG_ARG0(L_ERROR,DBG_INSTID,inst,"rgSCHUtlTfuUBndReq() Call to" + " RgLiTfuUbndReq() failed"); + } + RETVALUE(ret); + +} /* rgSCHUtlTfuUBndReq */ + +/*********************************************************** + * + * Func : rgSCHUtlResetSfAlloc + * + * Desc : Utility Function to Reset subframe allocation information. + * + * + * Ret : ROK + * RFAILED + * + * + * File : rg_utl.c + * + **********************************************************/ +#ifdef ANSI +PUBLIC S16 rgSCHUtlResetSfAlloc +( +RgInfSfAlloc *sfAlloc, +Bool resetCmnLcInfo, +Bool restAlloc +) +#else +PUBLIC S16 rgSCHUtlResetSfAlloc(sfAlloc,resetCmnLcInfo,restAlloc) +RgInfSfAlloc *sfAlloc; +Bool resetCmnLcInfo; +Bool restAlloc; +#endif +{ + TRC2(rgSCHUtlResetSfAlloc); + if(TRUE == restAlloc) + { + if(sfAlloc->ueInfo.numUes) + { + cmMemset((U8 *)sfAlloc->ueInfo.allocInfo,0x00, + (sizeof(RgInfUeAlloc)*sfAlloc->ueInfo.numUes)); + } + sfAlloc->ueInfo.numUes = 0; + sfAlloc->rarInfo.numRaRntis = 0; + sfAlloc->flowCntrlInfo.numUes = 0; + } + if(TRUE == resetCmnLcInfo) + { + sfAlloc->cmnLcInfo.bitMask = 0; + } + RETVALUE(ROK); +} + +/*********************************************************** + * + * Func : rgSCHUtlGetRlsHqAlloc + * + * Desc : Utility Function to Allocate subframe allocation information. + * + * + * Ret : ROK + * RFAILED + * + * + * File : rg_utl.c + * + **********************************************************/ +#ifdef ANSI +PUBLIC S16 rgSCHUtlGetRlsHqAlloc +( +RgSchCellCb *cell +) +#else +PUBLIC S16 rgSCHUtlGetRlsHqAlloc(cell) +RgSchCellCb *cell; +#endif +{ + U8 idx = 0; + Inst inst = cell->instIdx; + TRC2(rgSCHUtlGetRlsHqAlloc); + for(idx=0; idx < RGSCH_NUM_SUB_FRAMES; idx++) + { + cell->rlsHqArr[idx].cellId = cell->cellId; + + /* Allocating with additional location, to accommodate + TA scheduling along with maximum no of UEs per SF */ + + /* Allocate memory for "scheduled UE" Info */ + if((rgSCHUtlAllocSBuf(inst, + (Data**)&(cell->rlsHqArr[idx].ueHqInfo), + (sizeof(RgInfUeHqInfo)*RGSCH_MAX_UE_PER_DL_SF))) != ROK) + { + RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,"Memory allocation FAILED for " + "UE Alloc"); + RETVALUE(RFAILED); + } + } + + RETVALUE(ROK); + +} + +/*********************************************************** + * + * Func : rgSCHUtlPutRlsHqAlloc + * + * Desc : Utility Function to deallocate subframe allocation information. + * + * + * Ret : ROK + * RFAILED + * + * + * File : rg_utl.c + * + **********************************************************/ +#ifdef ANSI +PUBLIC S16 rgSCHUtlPutRlsHqAlloc +( +RgSchCellCb *cell +) +#else +PUBLIC S16 rgSCHUtlPutRlsHqAlloc(cell) +RgSchCellCb *cell; +#endif +{ + U8 idx = 0; + Inst inst = cell->instIdx; + TRC2(rgSCHUtlPutRlsHqAlloc); + + for(idx=0; idx < RGSCH_NUM_SUB_FRAMES; idx++) + { + /* Deallocate memory for "scheduled UE" Info */ + if (cell->rlsHqArr[idx].ueHqInfo != NULLP) + { + /* Freeing with additional location, to accommodate TA + scheduling along with maximum no of UEs per SF */ + /* ccpu00117052 - MOD - Passing double pointer + for proper NULLP assignment*/ + rgSCHUtlFreeSBuf(inst, + (Data **)(&(cell->rlsHqArr[idx].ueHqInfo)), + (sizeof(RgInfUeHqInfo)*RGSCH_MAX_UE_PER_DL_SF)); + } + } + + RETVALUE(ROK); + +} + + +/*********************************************************** + * + * Func : rgSCHUtlGetSfAlloc + * + * Desc : Utility Function to Allocate subframe allocation information. + * + * + * Ret : ROK + * RFAILED + * + * + * File : rg_utl.c + * + **********************************************************/ +#ifdef ANSI +PUBLIC S16 rgSCHUtlGetSfAlloc +( +RgSchCellCb *cell +) +#else +PUBLIC S16 rgSCHUtlGetSfAlloc(cell) +RgSchCellCb *cell; +#endif +{ + U8 idx; + U8 indx; + Inst inst = cell->instIdx; + RgSchCmnUlCell *cellUl = RG_SCH_CMN_GET_UL_CELL(cell); + TRC2(rgSCHUtlGetSfAlloc); + +#ifdef LTE_TDD + for(idx=0; idx < RGSCH_SF_ALLOC_SIZE; idx++) +#else + for(idx=0; idx < RGSCH_NUM_SUB_FRAMES; idx++) +#endif + { + cell->sfAllocArr[idx].cellId = cell->cellId; + + /* Allocating with additional location, to accommodate + TA scheduling along with maximum no of UEs per SF */ + + /* Allocate memory for "scheduled UE" Info */ + if((rgSCHUtlAllocSBuf(inst, + (Data**)&(cell->sfAllocArr[idx].ueInfo.allocInfo), + (sizeof(RgInfUeAlloc)*RGSCH_MAX_UE_PER_DL_SF))) != ROK) + { + RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,"Memory allocation FAILED for " + "UE Alloc"); + RETVALUE(RFAILED); + } + + /* Allocate memory for "scheduled RAR" Info */ + if((rgSCHUtlAllocSBuf(inst, + (Data**)&(cell->sfAllocArr[idx].rarInfo.raRntiInfo), + (sizeof(RgInfRaRntiInfo)*RGSCH_MAX_RARNTI_PER_DL_SF))) != ROK) + { + RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,"Memory allocation FAILED for " + "RARNTI"); + RETVALUE(RFAILED); + } + for(indx = 0; indx < RGSCH_MAX_RARNTI_PER_DL_SF; indx++) + { + if((rgSCHUtlAllocSBuf(inst, + (Data**)&(cell->sfAllocArr[idx].rarInfo.raRntiInfo[indx].crntiInfo), + (sizeof(RgInfCrntiInfo)* (cellUl->maxMsg3PerUlSf)))) != ROK) + { + RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,"Memory allocation FAILED for " + "RNTI"); + RETVALUE(RFAILED); + } + } + + } + +#ifdef EMTC_ENABLE + rgSCHEmtcUtlGetSfAlloc(cell); +#endif + + RETVALUE(ROK); + +} + +/*********************************************************** + * + * Func : rgSCHUtlPutSfAlloc + * + * Desc : Utility Function to deallocate subframe allocation information. + * + * + * Ret : ROK + * RFAILED + * + * + * File : rg_utl.c + * + **********************************************************/ +#ifdef ANSI +PUBLIC S16 rgSCHUtlPutSfAlloc +( +RgSchCellCb *cell +) +#else +PUBLIC S16 rgSCHUtlPutSfAlloc(cell) +RgSchCellCb *cell; +#endif +{ + U8 idx; + U8 indx; + Inst inst = cell->instIdx; + RgSchCmnUlCell *cellUl = RG_SCH_CMN_GET_UL_CELL(cell); + TRC2(rgSCHUtlPutSfAlloc); + +#ifdef LTE_TDD + for(idx=0; idx < RGSCH_SF_ALLOC_SIZE; idx++) +#else + for(idx=0; idx < RGSCH_NUM_SUB_FRAMES; idx++) +#endif + { + if (cell->sfAllocArr[idx].rarInfo.raRntiInfo != NULLP) + { + for(indx = 0; indx < RGSCH_MAX_RARNTI_PER_DL_SF; indx++) + { + if (cell->sfAllocArr[idx].rarInfo.raRntiInfo[indx].crntiInfo != NULLP) + /* ccpu00117052 - MOD - Passing double pointer + for proper NULLP assignment*/ + rgSCHUtlFreeSBuf(inst, + (Data**)(&(cell->sfAllocArr[idx].rarInfo.raRntiInfo[indx].\ + crntiInfo)), + (sizeof(RgInfCrntiInfo)* (cellUl->maxMsg3PerUlSf))); + } + /* Deallocate memory for "scheduled RAR" Info */ + /* ccpu00117052 - MOD - Passing double pointer + for proper NULLP assignment*/ + rgSCHUtlFreeSBuf(inst, + (Data**)(&(cell->sfAllocArr[idx].rarInfo.raRntiInfo)), + (sizeof(RgInfRaRntiInfo)*RGSCH_MAX_RARNTI_PER_DL_SF)); + } + /* Deallocate memory for "scheduled UE" Info */ + if (cell->sfAllocArr[idx].ueInfo.allocInfo != NULLP) + { + /* Freeing with additional location, to accommodate TA + scheduling along with maximum no of UEs per SF */ + /* ccpu00117052 - MOD - Passing double pointer + for proper NULLP assignment*/ + rgSCHUtlFreeSBuf(inst, + (Data**)(&(cell->sfAllocArr[idx].ueInfo.allocInfo)), + (sizeof(RgInfUeAlloc)*RGSCH_MAX_UE_PER_DL_SF)); + } + } + +#ifdef EMTC_ENABLE + rgSCHEmtcUtlPutSfAlloc(cell); +#endif + RETVALUE(ROK); + +} + +/*********************************************************** + * + * Func : rgSCHUtlAllocSBuf + * + * Desc : Utility Function to Allocate static buffer. + * Memory allocated is assumed contiguous. + * + * + * Ret : ROK + * RFAILED + * + * Notes: Caller doesnt need to raise the alarm in case of memory + * allocation gets failed. + * + * File : rg_utl.c + * + **********************************************************/ +#ifdef ANSI +PUBLIC S16 rgSCHUtlAllocSBuf +( +Inst inst, /* Instance of the invoking scheduler */ +Data **pData, /* Pointer of the data to be returned */ +Size size /* size */ +) +#else +PUBLIC S16 rgSCHUtlAllocSBuf(inst, pData, size) +Inst inst; /* Instance of the invoking scheduler */ +Data **pData; /* Pointer of the data to be returned */ +Size size; /* size */ +#endif +{ + /* Moving alarm diagnostics to available scope */ + + TRC2(rgSCHUtlAllocSBuf) + + /* Initialize the param to NULLP */ + *pData = NULLP; + + /* May not be necessary for data performance path */ +#ifndef NO_ERRCLS + if (size == 0) + { + RETVALUE(RFAILED); + } +#endif + + /* allocate buffer */ +#ifdef MS_MBUF_CORRUPTION /* Should be enabled when debugging mbuf corruption */ + MS_BUF_ADD_ALLOC_CALLER(); +#endif /* */ + if (SGetSBuf(rgSchCb[inst].rgSchInit.region, rgSchCb[inst].rgSchInit.pool, + pData, size) != ROK) + { + RgUstaDgn dgn; /* Alarm diagnostics structure */ + dgn.type = LRG_USTA_DGNVAL_MEM; + dgn.u.mem.region = rgSchCb[inst].rgSchInit.region; + dgn.u.mem.pool = rgSchCb[inst].rgSchInit.pool; + /* Send an alarm to Layer Manager */ + rgSCHLmmStaInd(inst, LCM_CATEGORY_RESOURCE, LCM_EVENT_SMEM_ALLOC_FAIL, + LCM_CAUSE_MEM_ALLOC_FAIL, &dgn); + RGSCHLOGERROR(inst, ERRCLS_DEBUG, ERG015, 0, "Unable to Allocate Buffer"); + RLOG_ARG0(L_ERROR,DBG_INSTID,inst, "Unable to Allocate the Buffer"); + RETVALUE(RFAILED); + } + + + /* zero out the allocated memory */ + cmMemset((U8 *)*pData, 0x00, size); + + RETVALUE(ROK); + +} /* end of rgSCHUtlAllocSBuf */ + + +/* +* +* Fun: rgSCHUtlFreeSBuf +* +* Desc: The argument to rgSCHUtlFreeSBuf() is a pointer to a block +* previously allocated by rgSCHUtlAllocSBuf() and size. It +* deallocates the memory. +* +* Ret: RETVOID +* +* Notes: None +* File: rg_utl.c +*/ +#ifdef ANSI +PUBLIC Void rgSCHUtlFreeSBuf +( +Inst inst, /* Instance of the invoking scheduler */ +Data **data, /* pointer to data */ +Size size /* size */ +) +#else +PUBLIC Void rgSCHUtlFreeSBuf(inst, data, size) +Inst inst; /* Instance of the invoking scheduler */ +Data **data; /* pointer to data */ +Size size; /* size */ +#endif +{ + + S16 ret; + + TRC2(rgSCHUtlFreeSBuf) + + if ((data == NULLP) || (*data == NULLP) || (size == 0)) + { + RETVOID; + } + + +#ifdef MS_MBUF_CORRUPTION /* Should be enabled when debugging mbuf corruption */ + MS_BUF_ADD_CALLER(); +#endif /* */ + /* Deallocate buffer */ + ret = SPutSBuf(rgSchCb[inst].rgSchInit.region, + rgSchCb[inst].rgSchInit.pool, (*data), size); + + if (ret != ROK) + { + RGSCHLOGERROR(inst, ERRCLS_DEBUG, ERG016, (ErrVal) 0, + "rgSCHUtlFreeSBuf failed.\n"); + RLOG_ARG0(L_ERROR,DBG_INSTID,inst, "rgSCHUtlFreeSBuf failed"); + RETVOID; + } + + /* ccpu00117052 - ADD - Assigning the pointer to NULLP */ + *data = NULLP; + + RETVOID; +} /* end of rgSCHUtlFreeSBuf */ + + +#ifdef RGR_SI_SCH +/* +* +* Fun: rgSCHUtlFreeWarningSiSeg +* +* Desc: This is used to deallocate Warning SI Seg. +* +* Ret: RETVOID +* +* Notes: None +* +* File: rg_utl.c +*/ +#ifdef ANSI +PUBLIC Void rgSCHUtlFreeWarningSiSeg +( +Region reg, +Pool pool, +CmLListCp *siPduLst +) +#else +PUBLIC Void rgSCHUtlFreeWarningSiSeg(reg, pool, siPduLst) +Region reg; +Pool pool; +CmLListCp *siPduLst; +#endif +{ + CmLList *node; + Buffer *pdu; + + TRC2(rgSCHUtlFreeWarningSiSeg) + + while (siPduLst->first != NULLP) + { + node = siPduLst->first; + pdu = (Buffer *)node->node; + cmLListDelFrm(siPduLst, node); + RGSCH_FREE_MSG(pdu); + SPutSBuf(reg, pool, (Data *)node,sizeof(CmLList)); + node = NULLP; + } + + RETVOID; +} /* end of rgSCHUtlFreeWarningSiSeg */ + + +/* +* +* Fun: rgSCHUtlFreeWarningSiPdu +* +* Desc: This is used to deallocate Warning SI PDU. +* +* Ret: RETVOID +* +* Notes: None +* +* File: rg_utl.c +*/ +#ifdef ANSI +PUBLIC Void rgSCHUtlFreeWarningSiPdu +( +RgSchCellCb *cell +) +#else +PUBLIC Void rgSCHUtlFreeWarningSiPdu(cell) +RgSchCellCb *cell; +#endif +{ + CmLList *node; + Buffer *pdu; + RgSchWarningSiInfo *warningSi; + RgSchWarningSiPdu *warningSiPdu; + + TRC2(rgSCHUtlFreeWarningSiPdu) + + warningSi = (RgSchWarningSiInfo *) cell->siCb.\ + siArray[cell->siCb.siCtx.siId-1].si; + /* ccpu00136659: CMAS ETWS design changes */ + CM_LLIST_FIRST_NODE(&warningSi->warningSiMsg.segLstCp, node); + if (node == NULLP) + { + RETVOID; + } + + warningSiPdu = (RgSchWarningSiPdu *)node->node; + pdu = warningSiPdu->pdu; + /* ccpu00136659: CMAS ETWS design changes */ + cmLListDelFrm(&warningSi->warningSiMsg.segLstCp, node); + RGSCH_FREE_MSG(pdu); + if(warningSi->warningSiMsg.segLstCp.count == 0) + { + /* ccpu00136659: CMAS ETWS design changes */ + cell->siCb.siArray[cell->siCb.siCtx.siId-1].si = NULLP; + rgSCHUtlRgrWarningSiCfgCfm(cell->instIdx, + rgSchCb[cell->instIdx].rgrSap->sapCfg.spId, + cell->siCb.warningSi[warningSi->idx].siId, + warningSi->warningSiMsg.transId, RGR_CFG_CFM_TX_COMPLETE); + } + + RETVOID; + +} /* end of rgSCHUtlFreeWarningSiPdu */ + + +/* +* +* Fun: rgSCHUtlGetWarningSiPdu +* +* Desc: This is used to get Warning SI PDU for Scheduling. +* +* Ret: +* +* Notes: None +* +* File: rg_utl.c +*/ +#ifdef ANSI +PUBLIC Buffer *rgSCHUtlGetWarningSiPdu +( +RgSchCellCb *cell +) +#else +PUBLIC Buffer *rgSCHUtlGetWarningSiPdu(cell) +RgSchCellCb *cell; +#endif +{ + RgSchWarningSiInfo *warningSi; + RgSchWarningSiPdu *warningSiPdu; + Buffer *pdu; + CmLList *node; + + TRC2(rgSCHUtlGetWarningSiPdu) + + warningSi = (RgSchWarningSiInfo *) cell->siCb. + siArray[cell->siCb.siCtx.siId-1].si; + /* ccpu00136659: CMAS ETWS design changes */ + CM_LLIST_FIRST_NODE(&warningSi->warningSiMsg.segLstCp, node); + if (node != NULLP) + { + warningSiPdu = (RgSchWarningSiPdu *)node->node; + pdu = warningSiPdu->pdu; + RETVALUE(pdu); + } + else + { + RETVALUE(NULLP); + } +} /* rgSCHUtlGetWarningSiPdu */ + + +/* +* +* Fun: rgSCHUtlGetMcsAndNPrb +* +* Desc: This is used to get mcs and nPrb value. +* +* Ret: +* +* Notes: None +* +* File: rg_utl.c +*/ +#ifdef ANSI +PUBLIC S16 rgSCHUtlGetMcsAndNPrb +( +RgSchCellCb *cell, +U8 *nPrb, +U8 *mcs, +MsgLen *msgLen +) +#else +PUBLIC S16 rgSCHUtlGetMcsAndNPrb(cell, nPrb, mcs, msgLen) +RgSchCellCb *cell; +U8 *nPrb; +U8 *mcs; +MsgLen *msgLen; +#endif +{ + RgSchWarningSiInfo *warningSi; + RgSchWarningSiPdu *warningSiPdu; + CmLList *node; + + TRC2(rgSCHUtlGetMcsAndNPrb) + + if(cell->siCb.siCtx.warningSiFlag == FALSE) + { + *mcs = cell->siCb.crntSiInfo.siInfo[cell->siCb.siCtx.siId-1].mcs; + *nPrb = cell->siCb.crntSiInfo.siInfo[cell->siCb.siCtx.siId-1].nPrb; + *msgLen = cell->siCb.crntSiInfo.siInfo[cell->siCb.siCtx.siId-1].msgLen; + } + else + { + warningSi = (RgSchWarningSiInfo *) cell->siCb. + siArray[cell->siCb.siCtx.siId-1].si; + /* ccpu00136659: CMAS ETWS design changes */ + CM_LLIST_FIRST_NODE(&warningSi->warningSiMsg.segLstCp, node); + if (node == NULLP) + { + RETVALUE(RFAILED); + } + + warningSiPdu = (RgSchWarningSiPdu *)node->node; + *mcs = warningSiPdu->mcs; + *nPrb = warningSiPdu->nPrb; + *msgLen = warningSiPdu->msgLen; + RETVALUE(ROK); + + } + RETVALUE(ROK); +} /* rgSCHUtlGetMcsAndNPrb */ + +/* +* +* Fun: rgSCHUtlCalMacAndPrb +* +* Desc: This is used to Calculate mcs and nPrb value for SIB1 and SIs. +* +* Ret: +* +* Notes: None +* +* File: rg_utl.c +*/ +#ifdef ANSI +PUBLIC S16 rgSCHUtlCalMcsAndNPrb +( +RgSchCellCb *cell, +U8 cfgType, +MsgLen msgLen, +U8 siId +) +#else +PUBLIC S16 rgSCHUtlCalMcsAndNPrb(cell, nPrb, mcs, msgLen) +RgSchCellCb *cell; +U8 cfgType; +MsgLen msgLen; +U8 siId; +#endif +{ + U8 mcs = 0; + U8 nPrb = 0; + + TRC2(rgSCHUtlCalMcsAndNPrb) + + /*Get the nPrb and mcs parametr values */ + if (rgSCHUtlGetAllwdCchTbSz(msgLen*8, &nPrb, &mcs) != (msgLen*8)) + { + RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId, "msgLen does " + "not match any valid TB Size"); + RETVALUE(RFAILED); + } + + + if(cfgType == RGR_SI_CFG_TYPE_SIB1 || cfgType == RGR_SI_CFG_TYPE_SIB1_PWS) + { + + if(cell->siCb.crntSiInfo.sib1Info.sib1 == NULLP) + { + cell->siCb.crntSiInfo.sib1Info.mcs = mcs; + cell->siCb.crntSiInfo.sib1Info.nPrb = nPrb; + cell->siCb.crntSiInfo.sib1Info.msgLen = msgLen; + } + else + { + cell->siCb.newSiInfo.sib1Info.mcs = mcs; + cell->siCb.newSiInfo.sib1Info.nPrb= nPrb; + cell->siCb.newSiInfo.sib1Info.msgLen = msgLen; + } + } + + + if(cfgType == RGR_SI_CFG_TYPE_SI) + { + if(cell->siCb.crntSiInfo.siInfo[siId-1].si == NULLP && + !(cell->siCb.siBitMask & RGSCH_SI_SICFG_UPD)) + { + cell->siCb.crntSiInfo.siInfo[siId-1].mcs = mcs; + cell->siCb.crntSiInfo.siInfo[siId-1].nPrb = nPrb; + cell->siCb.crntSiInfo.siInfo[siId-1].msgLen = msgLen; + } + else + { + cell->siCb.newSiInfo.siInfo[siId-1].mcs = mcs; + cell->siCb.newSiInfo.siInfo[siId-1].nPrb= nPrb; + cell->siCb.newSiInfo.siInfo[siId-1].msgLen = msgLen; + } + } + + if(cfgType == RGR_SI_CFG_TYPE_SIB8_CDMA) + { + cell->siCb.crntSiInfo.siInfo[siId-1].mcs = mcs; + cell->siCb.crntSiInfo.siInfo[siId-1].nPrb = nPrb; + cell->siCb.crntSiInfo.siInfo[siId-1].msgLen = msgLen; + } + + RETVALUE(ROK); +} +#endif + +/*********************************************************** + * + * Func : rgSCHUtlFillDgnParams + * + * Desc : Utility Function to Fill Diagonostic params. + * + * Ret : None. + * + * Notes: None. + * + * File : rg_utl.c + * + **********************************************************/ +#ifdef ANSI +PUBLIC Void rgSCHUtlFillDgnParams +( +Inst inst, +RgUstaDgn *dgn, +U8 dgnType +) +#else +PUBLIC Void rgSCHUtlFillDgnParams(inst, dgn, dgnType) +Inst inst; +RgUstaDgn *dgn; +U8 dgnType; +#endif +{ + + TRC2(rgSCHUtlFillDgnParams) + + switch(dgnType) + { + case LRG_USTA_DGNVAL_MEM: + dgn->type = (U8) LRG_USTA_DGNVAL_MEM; + dgn->u.mem.region = rgSchCb[inst].rgSchInit.region; + dgn->u.mem.pool = rgSchCb[inst].rgSchInit.pool; + break; + + default: + break; + } + + RETVOID; +} /* end of rgSCHUtlFillDgnParams */ + +/*********************************************************** + * + * Func : rgSCHUtlGetPstToLyr + * + * Desc : Utility Function to get the pst structure to post a message to MAC + * + * + * Ret : ROK + * RFAILED + * + * Notes: This function should be called while sending a msg from + * scheduler instance to MAC + * + * File : rg_utl.c + * + **********************************************************/ +#ifdef ANSI +PUBLIC Void rgSCHUtlGetPstToLyr +( +Pst *pst, +RgSchCb *schCb, +Inst macInst +) +#else +PUBLIC Void rgSCHUtlGetPstToLyr (pst, schCb, macInst) +Pst *pst; +RgSchCb *schCb; +Inst macInst; +#endif +{ + TRC2(rgSCHUtlGetPstToLyr); + + /* Only the needed params are filled */ + pst->region = schCb->rgSchInit.region; + pst->pool = schCb->rgSchInit.pool; + pst->srcInst = schCb->rgSchInit.inst+RGSCH_INST_START; + pst->srcProcId = schCb->rgSchInit.procId; + pst->dstProcId = schCb->rgSchInit.procId; + + pst->dstInst = macInst; + pst->dstEnt = ENTRG; + pst->srcEnt = ENTRG; + pst->selector = 0; + pst->prior = PRIOR0; + pst->intfVer = 0; + pst->route = RTESPEC; + + RETVOID; +} /* end of rgSCHUtlGetPstToLyr */ + +/** @brief This function fills in the common lc information to be sent to MAC + * + * @details + * + * Function: rgSCHUtlFillRgInfCmnLcInfo + * @param RgSchDlSf *sf, + * @param RgInfSfAlloc *sfAlloc, + * @param CmLteLcId lcId, + * @param Bool sendInd + * + * @return S16 + * -# ROK + * -# RFAILED + */ +#ifdef ANSI +PUBLIC S16 rgSCHUtlFillRgInfCmnLcInfo +( +RgSchDlSf *sf, +RgInfSfAlloc *sfAlloc, +CmLteLcId lcId, +Bool sendInd +) +#else +PUBLIC S16 rgSCHUtlFillRgInfCmnLcInfo(sf, sfAlloc, lcId, sendInd) +RgSchDlSf *sf; +RgInfSfAlloc *sfAlloc; +CmLteLcId lcId; +Bool sendInd; +#endif +{ + TRC2(rgSCHUtlFillRgInfCmnLcInfo); + + if((sf->bch.tbSize)&& + !(sfAlloc->cmnLcInfo.bitMask & RGINF_BCH_INFO)) + { +#ifndef RGR_SI_SCH + sfAlloc->cmnLcInfo.bchInfo.lcId = lcId; +#endif + sfAlloc->cmnLcInfo.bitMask |= RGINF_BCH_INFO; + } + else if((sf->bcch.pdcch != NULLP)&& + !(sfAlloc->cmnLcInfo.bitMask & RGINF_BCCH_INFO)) + { + sfAlloc->cmnLcInfo.bcchInfo.rnti = RGSCH_SI_RNTI; + rgSCHUtlFillPdschDciInfo(&(sfAlloc->cmnLcInfo.bcchInfo.dciInfo), + &(sf->bcch.pdcch->dci)); +#ifndef RGR_SI_SCH + sfAlloc->cmnLcInfo.bcchInfo.lcId = lcId; + sfAlloc->cmnLcInfo.bcchInfo.sndStatInd = sendInd; +#endif + sfAlloc->cmnLcInfo.bitMask |= RGINF_BCCH_INFO; + } + else if((sf->pcch.pdcch != NULLP) && + !(sfAlloc->cmnLcInfo.bitMask & RGINF_PCCH_INFO)) + { + sfAlloc->cmnLcInfo.pcchInfo.rnti = RGSCH_P_RNTI; + rgSCHUtlFillPdschDciInfo(&(sfAlloc->cmnLcInfo.pcchInfo.dciInfo), + &(sf->pcch.pdcch->dci)); + sfAlloc->cmnLcInfo.pcchInfo.lcId = lcId; + sfAlloc->cmnLcInfo.bitMask |= RGINF_PCCH_INFO; + } + RETVALUE(ROK); +} + +/** @brief This function fills in the RAR information to be sent to MAC + * + * @details + * + * Function: rgSCHUtlFillRgInfRarInfo + * + * @param RgSchCellCb *cell + * @param RgSchDlSf *sf + * @param RgInfSfAlloc *sfAlloc + * @return S16 + * -# ROK + * -# RFAILED + */ +#ifdef ANSI +PUBLIC S16 rgSCHUtlFillRgInfRarInfo +( +RgSchDlSf *sf, +RgInfSfAlloc *sfAlloc, +RgSchCellCb *cell +) +#else +PUBLIC S16 rgSCHUtlFillRgInfRarInfo(sf, sfAlloc, cell) +RgSchDlSf *sf; +RgInfSfAlloc *sfAlloc; +RgSchCellCb *cell; +#endif +{ + U8 idx; + CmLListCp *lnkLst; + CmLList *tmp; + RgSchRaCb *raCb; + RgSchUeCb *ue; + RgInfRaRntiInfo *raRntiAlloc; + U8 noRaRsps; + RgSchCmnDlCell *cellDl = RG_SCH_CMN_GET_DL_CELL(cell); + + TRC2(rgSCHUtlFillRgInfRarInfo); + +#ifdef LTE_TDD + noRaRsps = RGSCH_MAX_TDD_RA_RSP_ALLOC; +#else + noRaRsps = RGSCH_MAX_RA_RSP_ALLOC; +#endif + + for(idx =0; idx < noRaRsps; idx++) + { + if (sf->raRsp[idx].pdcch == NULLP) + { + /* No further raResp Allocations. */ + break; + } + /* Added Dl TB count for RACH Response transmission*/ +#ifdef LTE_L2_MEAS + cell->dlUlTbCnt.tbTransDlTotalCnt++; +#endif + raRntiAlloc = &(sfAlloc->rarInfo.raRntiInfo[idx]); + raRntiAlloc->raRnti = sf->raRsp[idx].raRnti; + raRntiAlloc->schdTbSz = sf->raRsp[idx].tbSz; + raRntiAlloc->numCrnti = 0; + rgSCHUtlFillPdschDciInfo(&(raRntiAlloc->dciInfo), + &(sf->raRsp[idx].pdcch->dci)); + /* RACHO : fill backoff indicator information */ + raRntiAlloc->backOffInd = sf->raRsp[idx].backOffInd; + + /* Fill for contention free UEs*/ + lnkLst = &(sf->raRsp[idx].contFreeUeLst); + CM_LLIST_FIRST_NODE(lnkLst, tmp); + while (tmp) + { + ue = (RgSchUeCb *)tmp->node; + tmp = tmp->next; + raRntiAlloc->crntiInfo[raRntiAlloc->numCrnti].tmpCrnti = ue->ueId; + raRntiAlloc->crntiInfo[raRntiAlloc->numCrnti].isContFree = TRUE; + raRntiAlloc->crntiInfo[raRntiAlloc->numCrnti].rapId = ue->ul.rarGrnt.rapId; +#ifndef MAC_5GTF_UPDATE + raRntiAlloc->crntiInfo[raRntiAlloc->numCrnti].grnt.hop = + ue->ul.rarGrnt.hop; + raRntiAlloc->crntiInfo[raRntiAlloc->numCrnti].grnt.cqiBit = + ue->ul.rarGrnt.cqiReqBit; +#endif + /* SHASHAHNK ADD RIV CALC */ + raRntiAlloc->crntiInfo[raRntiAlloc->numCrnti].grnt.rbStart = + ue->ul.rarGrnt.rbStart; + raRntiAlloc->crntiInfo[raRntiAlloc->numCrnti].grnt.numRb = + ue->ul.rarGrnt.numRb; + raRntiAlloc->crntiInfo[raRntiAlloc->numCrnti].grnt.tpc = + ue->ul.rarGrnt.tpc; + raRntiAlloc->crntiInfo[raRntiAlloc->numCrnti].grnt.iMcsCrnt = + ue->ul.rarGrnt.iMcsCrnt; + raRntiAlloc->crntiInfo[raRntiAlloc->numCrnti].ta = ue->ul.rarGrnt.ta; + raRntiAlloc->numCrnti++; + cmLListDelFrm(lnkLst, &ue->ul.rarGrnt.raRspLnk); + ue->ul.rarGrnt.raRspLnk.node = (PTR)NULLP; + } + /* Fill for contention based UEs*/ + lnkLst = &(sf->raRsp[idx].raRspLst); + + CM_LLIST_FIRST_NODE(lnkLst, tmp); + + while((NULLP != tmp) && ((RgSchRaCb *)tmp->node != NULLP)) + { + raCb = (RgSchRaCb *)tmp->node; + + raRntiAlloc->crntiInfo[raRntiAlloc->numCrnti].tmpCrnti = raCb->tmpCrnti; + raRntiAlloc->crntiInfo[raRntiAlloc->numCrnti].isContFree = FALSE; + raRntiAlloc->crntiInfo[raRntiAlloc->numCrnti].rapId = raCb->rapId; + raRntiAlloc->crntiInfo[raRntiAlloc->numCrnti].ta.pres = TRUE; + raRntiAlloc->crntiInfo[raRntiAlloc->numCrnti].ta.val = raCb->ta.val; +#ifndef MAC_5GTF_UPDATE + raRntiAlloc->crntiInfo[raRntiAlloc->numCrnti].grnt.hop = + raCb->msg3Grnt.hop; + raRntiAlloc->crntiInfo[raRntiAlloc->numCrnti].grnt.cqiBit = FALSE; +#endif + raRntiAlloc->crntiInfo[raRntiAlloc->numCrnti].grnt.rbStart = + raCb->msg3Grnt.rbStart; + raRntiAlloc->crntiInfo[raRntiAlloc->numCrnti].grnt.numRb = + raCb->msg3Grnt.numRb; + raRntiAlloc->crntiInfo[raRntiAlloc->numCrnti].grnt.tpc = + raCb->msg3Grnt.tpc; + raRntiAlloc->crntiInfo[raRntiAlloc->numCrnti].grnt.iMcsCrnt = + raCb->msg3Grnt.iMcsCrnt; + raRntiAlloc->crntiInfo[raRntiAlloc->numCrnti].grnt.delayBit = + raCb->msg3Grnt.delayBit; + /* For initial attaching UEs Aperiodic CQI need not be triggered */ + raRntiAlloc->numCrnti++; + /* Search the next node */ + CM_LLIST_NEXT_NODE(lnkLst, tmp); + } + } + sfAlloc->rarInfo.numRaRntis = idx; + /* ccpu00132314-ADD-Update the tx power allocation info + TODO-Need to add a check for max tx power per symbol */ + sfAlloc->rarInfo.txPwrOffset = cellDl->rarTxPwrOffset; + + RETVALUE(ROK); +} /* end of rgSCHUtlFillRgInfRarInfo */ + +/** @brief This function fills in the pdsch data related allocation Info + * from the pdcch DCI info. + * subframe + * + * @details + * + * Function: rgSCHUtlFillPdschDciInfo + * + * Processing steps: + * - Depending upon the DCI Format, fill the appropriate fields. + * + * @param [out] TfuPdschDciInfo *pdschDci + * @param [in] TfuDciInfo *pdcchDci + * @return S16 + * -# ROK + * -# RFAILED + */ +#ifdef ANSI +PUBLIC S16 rgSCHUtlFillPdschDciInfo +( +TfuPdschDciInfo *pdsch, +TfuDciInfo *pdcchDci +) +#else +PUBLIC S16 rgSCHUtlFillPdschDciInfo(pdsch, pdcchDci) +TfuPdschDciInfo *pdsch; +TfuDciInfo *pdcchDci; +#endif +{ + TRC2(rgSCHUtlFillPdschDciInfo) + +#ifdef EMTC_ENABLE + S16 ret = ROK; +#endif + pdsch->format = pdcchDci->dciFormat; + switch(pdcchDci->dciFormat) + { + case TFU_DCI_FORMAT_1: + pdsch->u.format1AllocInfo = pdcchDci->u.format1Info.allocInfo; + break; + case TFU_DCI_FORMAT_1A: + if (pdcchDci->u.format1aInfo.isPdcchOrder == FALSE) + { + pdsch->u.format1aAllocInfo = pdcchDci->u.format1aInfo.t.pdschInfo.allocInfo; + } + break; + case TFU_DCI_FORMAT_1B: + pdsch->u.format1bAllocInfo = pdcchDci->u.format1bInfo.allocInfo; + break; + case TFU_DCI_FORMAT_1C: + pdsch->u.format1cAllocInfo = pdcchDci->u.format1cInfo; + break; + case TFU_DCI_FORMAT_1D: + pdsch->u.format1dAllocInfo = pdcchDci->u.format1dInfo.allocInfo; + break; + case TFU_DCI_FORMAT_2: + pdsch->u.format2AllocInfo = pdcchDci->u.format2Info.allocInfo; + break; + case TFU_DCI_FORMAT_2A: + pdsch->u.format2AAllocInfo = pdcchDci->u.format2AInfo.allocInfo; + break; +#ifdef RG_5GTF + case TFU_DCI_FORMAT_B1: + pdsch->u.formatB1Info = pdcchDci->u.formatB1Info; + break; + case TFU_DCI_FORMAT_B2: + pdsch->u.formatB2Info = pdcchDci->u.formatB2Info; + break; +#endif + default: +#ifdef EMTC_ENABLE + ret = rgSCHEmtcUtlFillPdschDciInfo(pdsch, pdcchDci); + if(RFAILED == ret) + { + RETVALUE(RFAILED); + } +#else + RETVALUE(RFAILED); +#endif + } + RETVALUE(ROK); +} + +/* LTE_ADV_FLAG_REMOVED_START */ +/** + * @brief This function resets temporary variables in Pool + * @details + * + * Function: rgSchSFRResetPoolVariables + * + * Invoked by: rgSCHSFRUtlTotalPoolInit + * + * @param[in] RgSchCellCb* cell + * @param[in] RgSubFrm* subFrm + * @return Void + * + **/ +#ifdef ANSI +PUBLIC Void rgSchDSFRPwrCheck +( + RgSchDlSf *sf, + Bool *isAllUePwrHigh + ) +#else +PRIVATE Void rgSchDSFRPwrCheck(sf, isAllUePwrHigh) + RgSchDlSf *sf; + Bool *isAllUePwrHigh; + +#endif +{ + RgSchSFRPoolInfo *sfrCCPool; + + CmLListCp *l; + CmLList *n; + + TRC2(rgSchDSFRPwrCheck); + + l = &sf->sfrTotalPoolInfo.ccPool; + n = cmLListFirst(l); + while(n) + { + sfrCCPool = (RgSchSFRPoolInfo*)n->node; + if((sfrCCPool->poolstartRB == sfrCCPool->pwrHiCCRange.startRb) && + (sfrCCPool->poolendRB == sfrCCPool->pwrHiCCRange.endRb)) + { + n = cmLListNext(l); + if(n) + { + continue; + } + *isAllUePwrHigh = TRUE; + break; + } + else + break; + } +} +/* LTE_ADV_FLAG_REMOVED_END */ +/*********************************************************** + * + * Func : rgSCHUtlFillRgInfTbInfo + * + * Desc : Utility Function to fill the allocation info of each Tb + * + * + * Ret : RETVOID + * + * + * Notes: This function should be called while sending a msg from + * scheduler instance to MAC + * + * File : rg_utl.c + * + **********************************************************/ +#ifdef ANSI +PRIVATE Void rgSCHUtlFillRgInfTbInfo +( +RgSchDlHqProcCb *hqP, +RgInfUeAlloc *allocInfo, +RgSchCellCb *cell +) +#else +PRIVATE Void rgSCHUtlFillRgInfTbInfo (hqP, allocInfo, cell) +RgSchDlHqProcCb *hqP; +RgInfUeAlloc *allocInfo; +RgSchCellCb *cell; +#endif +{ + RgSchDlSf *sf; + U8 idx; + RgInfUeTbInfo *tbInfo; + U8 tbCnt; + /* LTE_ADV_FLAG_REMOVED_START */ +#ifdef TFU_UPGRADE + PRIVATE U32 tmpCnt = 0; + Bool isAllUePwrHigh = FALSE; +#endif + /* LTE_ADV_FLAG_REMOVED_END */ + RgSchDlLcCb *dlLcCb = NULLP; + U16 rlcHdrEstmt; + U8 lcId; + /* RRM_RBC_X */ +#ifdef LTE_L2_MEAS + U8 prbUsed = 0; +#endif + /* RRM_RBC_Y */ + + CmLteTimingInfo frm; + + /* Get Downlink Subframe */ + frm = cell->crntTime; + RGSCH_INCR_SUB_FRAME(frm, RG_SCH_CMN_DL_DELTA); + sf = rgSCHUtlSubFrmGet(cell, frm); + /* Setting of fillCtrlPdu flag + If both P-cell and S-cell are present, + make TRUE for P-cell and FALSE for all s-cells + For all other cases set TRUE */ +#ifdef LTE_ADV + if ((rgSchCb[cell->instIdx].genCfg.forceCntrlSrbBoOnPCel) && + !RG_SCH_CMN_IS_PCELL_HQP(hqP)) + { + allocInfo->fillCtrlPdu = FALSE; + } + else + { + allocInfo->fillCtrlPdu = TRUE; + } +#endif + + allocInfo->tbStrtIdx = -1; + + +#ifdef LTE_ADV + allocInfo->tbReqInfo.sCellHqPId = 0xff; + rgSCHLaaHndlFillRgInfTbInfo(cell, hqP, allocInfo); +#endif + + /*TODO:REEMA: Check and fill the isRetx */ + for(tbCnt = 0; tbCnt < 2; tbCnt++) + { + RgSchUeCb *ue = NULLP; + /*Changed as a result of CR timer*/ + if ((hqP->hqE->ue != NULLP)/* && + ((hqP->tbInfo[tbCnt].lchSchdData[0].lcId != 0) || \ + (hqP->tbInfo[tbCnt].schdTa.pres == PRSNT_NODEF))*/) + { + ue = hqP->hqE->ue; + allocInfo->rnti = ue->ueId; + allocInfo->doa = hqP->hqE->ue->mimoInfo.doa; + allocInfo->txMode = (TfuTxMode)(hqP->hqE->ue->mimoInfo.txMode); + allocInfo->puschRptUsd = hqP->hqE->ue->mimoInfo.puschFdbkVld; + allocInfo->puschPmiInfo = hqP->hqE->ue->mimoInfo.puschPmiInfo; + if(hqP->tbInfo[tbCnt].schdTa.pres == PRSNT_NODEF) + { + hqP->tbInfo[tbCnt].taSnt = TRUE; + } +#ifdef TFU_UPGRADE + if (RG_SCH_IS_PAPRSNT(ue,hqP->hqE->cell)) + { + /*update pA value */ + allocInfo->pa = (RG_SCH_CMN_GET_PA(ue,hqP->hqE->cell)).val; + } +#endif + + /* LTE_ADV_FLAG_REMOVED_START */ + /* If ABS is enabled, calculate resource used */ + if((0 == tbCnt) && (RGR_ENABLE == ue->cell->lteAdvCb.absCfg.status)) + { + /* For Macro count number resource used in Non-ABS SF */ + if(RGR_ABS_MUTE == ue->cell->lteAdvCb.absCfg.absPatternType) + { + if(RG_SCH_ABS_ENABLED_NONABS_SF == ue->cell->lteAdvCb.absDlSfInfo) + { + ue->cell->lteAdvCb.absLoadInfo[ue->cell->lteAdvCb.absPatternDlIdx]+= + hqP->tbInfo[tbCnt].dlGrnt.numRb; + } + } + /* For pico count number resource used in ABS SF for ABS UE */ + else if(RGR_ABS_TRANSMIT == ue->cell->lteAdvCb.absCfg.absPatternType) + { + if(RG_SCH_ABS_ENABLED_ABS_SF == ue->cell->lteAdvCb.absDlSfInfo) + { + if(TRUE == ue->lteAdvUeCb.rgrLteAdvUeCfg.isAbsUe) + { + ue->cell->lteAdvCb.absLoadInfo[ue->cell->lteAdvCb.absPatternDlIdx]+= + hqP->tbInfo[tbCnt].dlGrnt.numRb; + } + } + } + } + +#ifdef TFU_UPGRADE + /*if SFR is enabled*/ + allocInfo->isEnbSFR = (U8)RG_SCH_CMN_IS_SFR_ENB(ue->cell); /* KW fix for LTE_ADV */ + if((ue->cell->lteAdvCb.dsfrCfg.status == RGR_ENABLE) && + (ue->lteAdvUeCb.rgrLteAdvUeCfg.isUeCellEdge == FALSE)) + { + rgSchDSFRPwrCheck(sf, &isAllUePwrHigh); + } + if(isAllUePwrHigh) + { + allocInfo->pa = (U8)ue->cell->lteAdvCb.sfrCfg.pwrThreshold.pHigh; /* KW fix for LTE_ADV */ + if(tmpCnt++ == 100000) + { + RLOG_ARG2(L_DEBUG,DBG_CELLID,ue->cell->cellId, + "DSFR::ll UEs can go HIGH, PHigh(%d) for UE(%d)",allocInfo->pa, ue->ueId); + tmpCnt = 0; + } + } + else + { + if (allocInfo->isEnbSFR) + { + /*Update pA to Plow if it is cell-centred ,else pA will be pHigh*/ + if (ue->lteAdvUeCb.rgrLteAdvUeCfg.isUeCellEdge == TRUE) + { + allocInfo->pa = ue->cell->lteAdvCb.sfrCfg.pwrThreshold.pHigh; + if(tmpCnt++ == 100000) + { + RLOG_ARG2(L_DEBUG,DBG_CELLID,ue->cell->cellId, + "SFR::UE is CELL EDGE, PHigh(%d) for UE(%d)",allocInfo->pa, ue->ueId); + tmpCnt = 0; + } + + } + else + { + if(TRUE == ue->lteAdvUeCb.isCCUePHigh) + { + allocInfo->pa = ue->cell->lteAdvCb.sfrCfg.pwrThreshold.pHigh; + ue->lteAdvUeCb.isCCUePHigh = FALSE; + } + else + { + allocInfo->pa = ue->cell->lteAdvCb.sfrCfg.pwrThreshold.pLow; + if(tmpCnt++ == 100000) + { + RLOG_ARG2(L_DEBUG,DBG_CELLID,ue->cell->cellId, + "SFR::UE is CELL CENTRE, PLow(%d) for UE(%d)\n",allocInfo->pa, ue->ueId); + tmpCnt = 0; + } + } + } + } + } + /* LTE_ADV_FLAG_REMOVED_END */ +#endif + } + else + { + if (hqP->hqE->raCb) + { +#ifdef TFU_UPGRADE + RgSchCmnDlCell *cellDl = RG_SCH_CMN_GET_DL_CELL(cell); +#endif +#ifdef LTEMAC_SPS + allocInfo->pdcchRnti = hqP->hqE->raCb->tmpCrnti; +#endif + allocInfo->rnti = hqP->hqE->raCb->tmpCrnti; +#ifdef TFU_UPGRADE + /*ccpu00132314-ADD-Use a default pA value + for msg4 */ + allocInfo->pa = cellDl->msg4pAVal; +#endif + } + } + /* If TB Is scheduled for this SF */ + if(hqP->tbInfo[tbCnt].state == HQ_TB_WAITING) + { + if (allocInfo->tbStrtIdx == -1){ + allocInfo->tbStrtIdx = tbCnt; +#ifndef LTEMAC_SPS + rgSCHUtlFillPdschDciInfo(&(allocInfo->dciInfo), + &(hqP->pdcch->dci)); +#else + if (hqP->pdcch) + { + rgSCHUtlFillPdschDciInfo(&(allocInfo->dciInfo), + &(hqP->pdcch->dci)); + } + else if ((ue) && (ue->dl.spsOccPdcch.rnti == ue->spsRnti)) + { + rgSCHUtlFillPdschDciInfo(&(allocInfo->dciInfo), + &(ue->dl.spsOccPdcch.dci)); + } +#endif /* ifndef LTEMAC_SPS */ + } +#ifdef LTEMAC_SPS + if (hqP->pdcch) + { + allocInfo->pdcchRnti = hqP->pdcch->rnti; + } + else if (ue) + { + allocInfo->pdcchRnti = ue->spsRnti; + } +#endif + tbInfo = &(allocInfo->tbInfo[tbCnt]); + allocInfo->nmbOfTBs++; + allocInfo->hqProcId = hqP->procId; + allocInfo->tbInfo[tbCnt].schdTbSz = hqP->tbInfo[tbCnt].tbSz; + + tbInfo->disTb = FALSE; + if(!(hqP->tbInfo[tbCnt].txCntr)) + { +#ifdef LTE_ADV + if(!((rgSCHLaaCheckIfLAAProc(hqP)) && (TRUE == + rgSCHLaaSCellEnabled(cell)))) +#endif + { + hqP->tbInfo[tbCnt].txCntr++; + } + for(idx = 0; idx < hqP->tbInfo[tbCnt].numLch; idx++) + { + tbInfo->schdDat[idx].lcId =\ + hqP->tbInfo[tbCnt].lchSchdData[idx].lcId; + tbInfo->schdDat[idx].numBytes =\ + hqP->tbInfo[tbCnt].lchSchdData[idx].schdData; + if(hqP->hqE->ue) + { + lcId = hqP->tbInfo[tbCnt].lchSchdData[idx].lcId; + if(lcId != 0) + { + dlLcCb = hqP->hqE->ue->dl.lcCb[lcId-1]; + if(dlLcCb != NULLP) + { + RG_SCH_CMN_DL_GET_HDR_EST(dlLcCb, rlcHdrEstmt); + /* Update the totalBo with the scheduled bo */ + (hqP->hqE->ue->totalBo <= tbInfo->schdDat[idx].numBytes - rlcHdrEstmt)?\ + (hqP->hqE->ue->totalBo = 0):\ + (hqP->hqE->ue->totalBo -= tbInfo->schdDat[idx].numBytes-rlcHdrEstmt); + + /* RRM_RBC_X */ +#ifdef LTE_L2_MEAS + prbUsed = ((hqP->tbInfo[tbCnt].\ + lchSchdData[idx].schdData * + hqP->tbInfo[tbCnt].dlGrnt.numRb) / + (hqP->tbInfo[0].tbSz + hqP->tbInfo[1].tbSz)); + dlLcCb->qciCb->dlPrbCount += prbUsed; + if(dlLcCb->qciCb->qci > 0) + { + RG_SCH_CALC_GBR_UTILIZATION(cell, dlLcCb, prbUsed); + } +#endif /* RRM_RBC_Y */ + +#ifdef RG_PFS_STATS + //if(!(hqP->hqE->ue->pfsStats.lcStats[lcId-1].isLcCntSet)) + if(tbCnt == 0) + { + U8 idx = 0; + if (hqP->hqE->ue->cell == hqP->hqE->cell) + { + idx = RGSCH_PCELL_INDEX; + } + else + { + idx = RG_SCH_GET_SCELL_INDEX((hqP->hqE->ue), (hqP->hqE->cell)); + } + hqP->hqE->ue->pfsStats.lcStats[lcId-1].ueSchdOcc[idx]++; + hqP->hqE->ue->pfsStats.lcStats[lcId-1].perRefresh[ue->pfsStats.lcStats[lcId-1].lastIdx].lcSchdOcc++; + } +#endif + } + } + } + } + /* Added Dl TB count for SRB/DRB data transmission*/ +#ifdef LTE_L2_MEAS + cell->dlUlTbCnt.tbTransDlTotalCnt++; +#endif + tbInfo->ta.pres = hqP->tbInfo[tbCnt].schdTa.pres; + tbInfo->ta.val = hqP->tbInfo[tbCnt].schdTa.val; +#ifdef LTE_ADV + tbInfo->sCellActCe = hqP->tbInfo[tbCnt].schdSCellActCe; +#endif + tbInfo->numSchLch = hqP->tbInfo[tbCnt].numLch; + if(!(hqP->tbInfo[tbCnt].numLch)) + { + tbInfo->schdDat[tbInfo->numSchLch].numBytes= hqP->tbInfo[tbCnt].tbSz; + /* Fix: If only TA is scheduled, use some dummy LCID */ + if (tbInfo->ta.pres) + tbInfo->schdDat[tbInfo->numSchLch].lcId = RG_TA_LCID; + } + + tbInfo->contResCe = hqP->tbInfo[tbCnt].contResCe; + tbInfo->isReTx = FALSE; + } + else + { +#ifdef LTE_ADV + if(!((rgSCHLaaCheckIfLAAProc(hqP)) && (TRUE == + rgSCHLaaSCellEnabled(cell)))) +#endif + { + hqP->tbInfo[tbCnt].txCntr++; + } + tbInfo->isReTx = TRUE; + /* RRM_RBC_X */ + /* As per 36.314, harq retransmission also considered for + * prb utilization calculation*/ + for(idx = 0; idx < hqP->tbInfo[tbCnt].numLch; idx++) + { +#ifdef LTE_L2_MEAS + if(hqP->hqE->ue) + { + lcId = hqP->tbInfo[tbCnt].lchSchdData[idx].lcId; + if(lcId != 0) + { + dlLcCb = hqP->hqE->ue->dl.lcCb[lcId-1]; + if(dlLcCb != NULLP) + { + prbUsed = ((hqP->tbInfo[tbCnt].\ + lchSchdData[idx].schdData * + hqP->tbInfo[tbCnt].dlGrnt.numRb) / + (hqP->tbInfo[0].tbSz + hqP->tbInfo[1].tbSz)); + if(dlLcCb->qciCb->qci > 0) + { + RG_SCH_CALC_GBR_UTILIZATION(cell, dlLcCb, prbUsed); + } + } + } + } +#endif + } + /* RRM_RBC_Y */ + } + } + } +#ifdef LTE_ADV + rgSCHLaaResetDlHqProcCb(hqP); +#endif + + RETVOID; +} +/*********************************************************** + * + * Func : rgSCHUtlFillRgInfUeInfo + * + * Desc : Utility Function to fill the allocation info of Ue + * : MIMO : Filling 2TB's of each UE + * + * Ret : ROK + * RFAILED + * + * Notes: This function should be called while sending a msg from + * scheduler instance to MAC + * + * File : rg_utl.c + * + **********************************************************/ + /* CA dev Start */ +#ifdef ANSI +PUBLIC Void rgSCHUtlFillRgInfUeInfo +( +RgSchDlSf *sf, +RgSchCellCb *cell, +CmLListCp *dlDrxInactvTmrLst, +CmLListCp *dlInActvLst, +CmLListCp *ulInActvLst +) +#else +PUBLIC Void rgSCHUtlFillRgInfUeInfo (sf,cell, dlDrxInactvTmrLst, dlInActvLst, ulInActvLst) +{ +RgSchDlSf *sf; +RgSchCellCb *cell; +CmLListCp *dlDrxInactvTmrLst; +CmLListCp *dlInActvLst; +CmLListCp *ulInActvLst; +#endif +{ + RgInfSfAlloc *sfAlloc; + CmLListCp *lnkLst; /* lnkLst assignment */ + CmLList *tmp; + CmLList *hqPNode; + RgSchUeCb *ue = NULLP; + RgInfUeInfo *ueInfo = NULLP; + RgInfUeAlloc *ueAlloc = NULLP; + RgSchDlHqProcCb *hqCb = NULLP; + + /* Since Msg4 is sched only on PCELL, use cell arg's sfAllocArr */ + sfAlloc = &(cell->sfAllocArr[cell->crntSfIdx]); + ueInfo = &(sfAlloc->ueInfo); + ueAlloc = sfAlloc->ueInfo.allocInfo; + + lnkLst = &(sf->msg4HqPLst); + CM_LLIST_FIRST_NODE(lnkLst, tmp); + while(NULLP != tmp) + { + printf("5GTF_ERROR MSG4 Consolidation\n"); + hqCb = (RgSchDlHqProcCb *)(tmp->node); + CM_LLIST_NEXT_NODE(lnkLst, tmp); + + rgSCHUtlFillRgInfTbInfo(hqCb, &ueAlloc[ueInfo->numUes], cell); + + ue = hqCb->hqE->ue; + + if(ue != NULLP) + { + if((!(ue->dl.dlInactvMask & RG_HQENT_INACTIVE)) && (ue->isDrxEnabled)) + { + rgSCHUtlGetDrxSchdUesInDl(cell, ue, hqCb, &ueAlloc[ueInfo->numUes], + dlDrxInactvTmrLst, dlInActvLst, ulInActvLst); + } + } + ueInfo->numUes++; + } + + lnkLst = &(sf->ueLst); + CM_LLIST_FIRST_NODE(lnkLst, tmp); + while(NULLP != tmp) + { +#if defined (TENB_STATS) && defined (RG_5GTF) + cell->tenbStats->sch.dl5gtfPdschCons++; +#endif + ue = (RgSchUeCb *)(tmp->node); + CM_LLIST_NEXT_NODE(lnkLst, tmp); + + hqPNode = ue->dl.dlSfHqInfo[cell->cellId][sf->dlIdx].hqPLst.first; + while (hqPNode) + { + hqCb = (RgSchDlHqProcCb *)hqPNode->node; + hqPNode = hqPNode->next; + + sfAlloc = &(hqCb->hqE->cell->sfAllocArr[hqCb->hqE->cell->crntSfIdx]); + ueInfo = &(sfAlloc->ueInfo); + ueAlloc = sfAlloc->ueInfo.allocInfo; + + rgSCHUtlFillRgInfTbInfo(hqCb, &ueAlloc[ueInfo->numUes], + hqCb->hqE->cell); + + if(ue->isDrxEnabled) + { + rgSCHUtlGetDrxSchdUesInDl(cell, ue, hqCb, &ueAlloc[ueInfo->numUes], + dlDrxInactvTmrLst, dlInActvLst, ulInActvLst); + } + ueInfo->numUes++; + } +#ifdef LTE_ADV + if (rgSchCb[cell->instIdx].genCfg.isSCellActDeactAlgoEnable == TRUE) + { + /*If remaining BO is left then increment the count*/ + if(ue->totalBo > 0) + { + ue->remBoCnt++; + /* Check if trigger for Activation is met or not */ + if(rgSCHIsActvReqd(cell, ue)) + { + ue->remBoCnt = 0; + /*Passing primary cell*/ + rgSCHSCellSelectAndActDeAct(ue->cell, ue, RGR_SCELL_ACT); + } + } + else + { + /*If remaining BO is 0 then reset the count*/ + ue->remBoCnt = 0; + } + } +#endif + } + + RETVOID; +} /* end of rgSCHUtlFillRgInfUeInfo */ + /* CA dev End */ + + +/** @brief This function shall update the scheduler with the CEs and data rcvd + * + * @details + * + * Function: rgSCHUtlUpdSch + * + * Processing steps: + * - Collate the information of all the SDUs received and inform the + * scheduler rgSCHDataRcvd + * - Send Data indication to the higher layer with the dedicated data + * (rgUIMSndDedDatInd) + * - Inform scheduler with any MAC CEs if present. + * + * @param [in] RgCellCb *cellCb + * @param [in] RgUeCb *ueCb + * @param [in] RgMacPdu *pdu + * @param [in] RgSchErrInfo *err + * @return S16 + * -# ROK + * -# RFAILED + */ +#ifdef ANSI +PUBLIC S16 rgSCHUtlUpdSch +( +RgInfSfDatInd *subfrmInfo, +RgSchCellCb *cellCb, +RgSchUeCb *ueCb, +RgInfUeDatInd *pdu, +RgSchErrInfo *err +) +#else +PUBLIC S16 rgSCHUtlUpdSch (subfrmInfo, cellCb, ueCb, pdu, err) +RgInfSfDatInd *subfrmInfo; +RgSchCellCb *cellCb; +RgSchUeCb *ueCb; +RgInfUeDatInd *pdu; +RgSchErrInfo *err; +#endif +{ + + S16 ret; + TRC2(rgSCHUtlUpdSch); + +#ifdef LTEMAC_SPS + if (RGSCH_UL_SPS_ACT_PRSENT & pdu->ceInfo.bitMask) + { + /* SPS to be activated due to data on SPS LCG ID*/ + rgSCHUtlSpsActInd(cellCb, ueCb, pdu->ceInfo.spsSduSize); + } +#endif + /* TODO : Temp Fix for crash due to UL SDU corruption*/ + if (RGSCH_PHR_CE_PRSNT & pdu->ceInfo.bitMask) + { + /* PHR present */ + RGSCHCPYTIMEINFO(subfrmInfo->timingInfo, ueCb->macCeRptTime); + if ((ret = rgSCHUtlUpdPhr(cellCb, ueCb, pdu->ceInfo.ces.phr, err)) != ROK) + RETVALUE(ret); + } + /* Note: Order of indication to Sch now is + * 1st Indicate the DataInd info for each LCG's + * 2nd Update the BSR reports received along with data + * this is to make sure the effBsr is updated to the latest BSR + * received. + */ + cellCb->sc.apis->rgSCHUpdUeDataIndLcg(cellCb, ueCb, pdu); + +#ifndef MAC_5GTF_UPDATE + if (RGSCH_TRUNC_BSR_CE_PRSNT & pdu->ceInfo.bitMask) + { + RGSCHCPYTIMEINFO(subfrmInfo->timingInfo, ueCb->macCeRptTime); + /*ccpu00129922 - MOD - Deleted return value + * checking since it returns void*/ + rgSCHUtlUpdBsrTrunc (cellCb, ueCb, + (U8)(pdu->ceInfo.ces.bsr.truncBsr >> 6), + (U8)(pdu->ceInfo.ces.bsr.truncBsr & 0x3F), err); + } + else + { + if (RGSCH_SHORT_BSR_CE_PRSNT & pdu->ceInfo.bitMask) + { + RGSCHCPYTIMEINFO(subfrmInfo->timingInfo, ueCb->macCeRptTime); + /*ccpu00129922 - MOD - Deleted return value + checking since it returns void*/ + rgSCHUtlUpdBsrShort (cellCb, ueCb, + (U8)(pdu->ceInfo.ces.bsr.shortBsr >> 6), + (U8)(pdu->ceInfo.ces.bsr.shortBsr & 0x3F), err); + } + else + { + if (RGSCH_LONG_BSR_CE_PRSNT & pdu->ceInfo.bitMask) +#else + if (RGSCH_BSR_CE_PRSNT & pdu->ceInfo.bitMask) +#endif + { + RGSCHCPYTIMEINFO(subfrmInfo->timingInfo, ueCb->macCeRptTime); + /*ccpu00129922 - MOD - Deleted return value + checking since it returns void*/ + rgSCHUtlUpdBsrLong (cellCb, ueCb, + pdu->ceInfo.ces.bsr.longBsr.bs1, + pdu->ceInfo.ces.bsr.longBsr.bs2, + pdu->ceInfo.ces.bsr.longBsr.bs3, + pdu->ceInfo.ces.bsr.longBsr.bs4, + err); + } +#ifndef MAC_5GTF_UPDATE + } + + } +#endif + + RETVALUE(ROK); +} /* end of rgSCHUtlUpdSch */ +#ifdef RGR_V1 +/** + * @brief Handler for Updating Bo received in StaRsp + * + * @details + * + * Function : rgSCHUtlAddUeToCcchSduLst + * + * This function shall be invoked once it receives staRsp on CCCH + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ueCb + * @return S16 + * -# ROK + **/ +#ifdef ANSI +PUBLIC S16 rgSCHUtlAddUeToCcchSduLst +( +RgSchCellCb *cell, +RgSchUeCb *ueCb +) +#else +PUBLIC S16 rgSCHUtlAddUeToCcchSduLst(cell, ueCb) +RgSchCellCb *cell; +RgSchUeCb *ueCb; +#endif +{ + RgSchCmnDlUe *ueDl = RG_SCH_CMN_GET_DL_UE(ueCb, cell); + RgSchDlHqProcCb *hqP = (RgSchDlHqProcCb *)ueDl->proc; + TRC2(rgSCHUtlAddUeToCcchSduLst); + + /* Temp Guard: For back to back CCCH SDU BO + * twice. Hence an extra guard. If already added to scheduling + * queue or if scheduled and waiting for HQ FDBK, ignore */ + if ((ueCb->ccchSduLnk.node) || + ((!(ueCb->dl.dlInactvMask & RG_HQENT_INACTIVE)) && + ((hqP != NULLP) && (hqP->hqE->ccchSduProc)))) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,"RNTI:%d Unexpected CCCH SDU BO", + ueCb->ueId); + RETVALUE(ROK); + } + + ueCb->ccchSduLnk.node = (PTR)(ueCb); + cmLListAdd2Tail(&(cell->ccchSduUeLst), &(ueCb->ccchSduLnk)); + + RETVALUE(ROK); +} +/** + * + * @details + * + * Function : rgSCHUtlUpdtBo + * + * This function shall be invoked once it receives staRsp on CCCH + * + * @param[in] RgSchCellCb *cell + * @param[in] RgRguCmnStaRsp *staRsp + * @return S16 + * -# ROK + **/ +#ifdef ANSI +PUBLIC S16 rgSCHUtlUpdtBo +( +RgSchCellCb *cell, +RgInfCmnBoRpt *staRsp +) +#else +PUBLIC S16 rgSCHUtlUpdtBo(cell, staRsp) +RgSchCellCb *cell; +RgInfCmnBoRpt *staRsp; +#endif +{ + RgSchUeCb *ueCb; + TRC2(rgSCHUtlUpdtBo) + + + if ((ueCb = rgSCHDbmGetUeCb(cell, staRsp->u.rnti)) == NULLP) + { + /* Handle Ue fetch failure */ + RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,"Invalid UEID:%d",staRsp->u.rnti); + RETVALUE(RFAILED); + } + /* Update Bo in ueCb */ + ueCb->dlCcchInfo.bo = (U32)(staRsp->bo); +#ifdef EMTC_ENABLE + if(ueCb->isEmtcUe) + { + rgSCHUtlAddUeToEmtcCcchSduLst(cell,ueCb); + } + else +#endif + { + rgSCHUtlAddUeToCcchSduLst(cell, ueCb); + } + + RETVALUE(ROK); +} /* rgSCHUtlUpdtBo */ + +#endif +/** + * + * @details + * Function : rgSCHUtlHndlCcchBoUpdt + * + * This function shall fetch the raCb with the given rnti and ask RAM to + * update BO + * + * + * @param[in] RgSchCellCb *cell + * @param[in] RgInfCmnBoRpt *boRpt + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 rgSCHUtlHndlCcchBoUpdt +( +RgSchCellCb *cell, +RgInfCmnBoRpt *boRpt +) +#else +PUBLIC S16 rgSCHUtlHndlCcchBoUpdt(cell, boRpt) +RgSchCellCb *cell; +RgInfCmnBoRpt *boRpt; +#endif +{ + RgSchRaCb *raCb; + RgSchUeCb *ueCb; + + TRC2(rgSCHUtlHndlCcchBoUpdt); + + if ((raCb = rgSCHDbmGetRaCb(cell, boRpt->u.rnti)) == NULLP) + { +#ifdef RGR_V1 + /* CR timer implementation changes*/ + /*If no raCb, schedule ueCb, ueCb is extracted in rgSCHUtlUpdtBo*/ + RETVALUE(rgSCHUtlUpdtBo(cell, boRpt)); +#else + /* Handle RaCb fetch failure */ + RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId, + "Invalid RNTI:%d to fetch raCb",boRpt->u.rnti); + RETVALUE(RFAILED); +#endif + } + +#ifdef RGR_V1 + + /*Fix: If RaCb exists, then MSG4 is not completed yet*/ + /*Check if guard timer has expired, if not CR CE + CCCH SDU will be scheduled*/ + if((raCb->contResTmrLnk.node != NULLP) && \ + (raCb->schdLnk.node == NULLP) && (raCb->dlHqE->msg4Proc == NULLP)) + { +#ifdef EMTC_ENABLE + /*if contention resolution timer left ,Stop the Contention Resolution Guard Timer , + add in toBeSchduled list and update the Bo */ + if(TRUE == raCb->isEmtcRaCb) + { + rgSCHRamEmtcUpdtBo(cell, raCb, boRpt); + } + else +#endif + { + cmLListDelFrm(&cell->contResGrdTmrLst, &(raCb->contResTmrLnk)); + raCb->contResTmrLnk.node=NULLP; + rgSCHRamUpdtBo(cell, raCb, boRpt); + } + } + else + { + /*Fix:Guard timer has expired */ + /*Update the BO in UE CB but dont add it to the scheduling list. + *Should be added to the list after MSG4 completion*/ + if ((ueCb = rgSCHDbmGetUeCb(cell, boRpt->u.rnti)) == NULLP) + { + /* Handle Ue fetch failure */ + RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,"Invalid RNTI:%d",boRpt->u.rnti); + RETVALUE(RFAILED); + } + /* Update Bo in ueCb */ + ueCb->dlCcchInfo.bo = (U32)(boRpt->bo); + } + +#else + rgSCHRamUpdtBo(cell, raCb, boRpt); +#endif + + RETVALUE(ROK); +} /* rgSCHUtlHndlCcchBoUpdt */ + +/** + * @brief Validates BO received for BCCH or PCCH. + * + * @details + * + * Function : rgSCHUtlGetAllwdCchTbSz + * + * This function shall return the tbSz equal to or + * the nearest greater value for a given bo. + * If no such value found return -1. The nPrb value is + * accordingly set. + * + * + * @param[in] U32 bo + * @param[out] U8 *nPrb + * @return S32 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S32 rgSCHUtlGetAllwdCchTbSz +( +U32 bo, +U8 *nPrb, +U8 *mcs +) +#else +PUBLIC S32 rgSCHUtlGetAllwdCchTbSz(bo, nPrb, mcs) +U32 bo; +U8 *nPrb; +U8 *mcs; +#endif +{ + S32 lt; + S32 cn; + S32 rt; + + TRC2(rgSCHUtlGetAllwdCchTbSz); + + for (lt = 0, rt = 43; lt <= rt;) + { + cn = (lt + rt)/2; + if (rgSchUtlBcchPcchTbSzTbl[cn].tbSz == bo) + { + *nPrb = rgSchUtlBcchPcchTbSzTbl[cn].rbIndex; + *mcs = rgSchUtlBcchPcchTbSzTbl[cn].mcs; + RETVALUE(rgSchUtlBcchPcchTbSzTbl[cn].tbSz); + } + else if (rgSchUtlBcchPcchTbSzTbl[cn].tbSz < bo) + lt = cn + 1; + else + rt = cn - 1; + } + if (lt == 44) + { + RETVALUE(RFAILED); + } + *nPrb = rgSchUtlBcchPcchTbSzTbl[lt].rbIndex; + *mcs = rgSchUtlBcchPcchTbSzTbl[lt].mcs; + RETVALUE(rgSchUtlBcchPcchTbSzTbl[lt].tbSz); +} + +/** + * @brief Handler for BO Updt received for BCCH or PCCH. + * + * @details + * + * Function : rgSCHUtlHndlBcchPcchBoUpdt + * + * This function shall store the buffer and time to transmit in lcCb + * + * + * @param[in] RgSchCellCb *cell + * @param[in] RgInfCmnBoRpt *boRpt + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 rgSCHUtlHndlBcchPcchBoUpdt +( +RgSchCellCb *cell, +RgInfCmnBoRpt *boUpdt +) +#else +PUBLIC S16 rgSCHUtlHndlBcchPcchBoUpdt(cell, boUpdt) +RgSchCellCb *cell; +RgInfCmnBoRpt *boUpdt; +#endif +{ + RgSchClcDlLcCb *dlLc; + RgSchClcBoRpt *boRpt; + Inst inst = cell->instIdx; + U8 nPrb=0; + U8 mcs=0; + + TRC2(rgSCHUtlHndlBcchPcchBoUpdt); + + dlLc = rgSCHDbmGetBcchOnBch(cell); + if (dlLc == NULLP) + { + RLOG_ARG2(L_ERROR,DBG_CELLID,cell->cellId, + "No Logical Channel dlLc is NULLP for RNTI:%d LCID:%d",boUpdt->u.rnti,boUpdt->lcId); + RETVALUE(RFAILED); + } + if (boUpdt->lcId != dlLc->lcId) + { + /* Added for dropping paging Message*/ + /*suman*/ + if ((rgSCHChkBoUpdate(cell,boUpdt))== ROK) /* Checking if received BO falls within the window of 5120 subframes*/ + { + if (rgSCHUtlGetAllwdCchTbSz(boUpdt->bo*8, &nPrb, &mcs) + != (boUpdt->bo*8)) + { + RLOG_ARG3(L_ERROR,DBG_CELLID,cell->cellId,"[%ld]BO: does not match any " + "valid TB Size RNTI:%d LCID:%d", boUpdt->bo,boUpdt->u.rnti,boUpdt->lcId); + RETVALUE(RFAILED); + } + }/*end of rgSCHChkBoUpdate*/ + else + { + RETVALUE(ROK); + } + } + if ((dlLc = rgSCHDbmGetCmnLcCb(cell, boUpdt->lcId)) == NULLP) + { + /* Handle lcCb fetch failure */ + RLOG_ARG2(L_ERROR,DBG_CELLID,cell->cellId, + "LCID:%d Invalid for RNTI:%d",boUpdt->lcId,boUpdt->u.rnti); + } + + if (((rgSCHUtlAllocSBuf(inst, (Data **)(&boRpt), sizeof(RgSchClcBoRpt))) ==RFAILED) || + (!boRpt)) + { + RLOG_ARG3(L_ERROR,DBG_CELLID,cell->cellId, "Allocation of common bo %dreport " + "failed RNTI:%d LCID:%d", boUpdt->bo,boUpdt->u.rnti,boUpdt->lcId); + RETVALUE(RFAILED); + } + + boRpt->bo = boUpdt->bo; + boRpt->mcs = mcs; + boRpt->timeToTx = boUpdt->u.timeToTx; + boRpt->nPrb = nPrb; +#ifdef EMTC_ENABLE + if(cell->emtcEnable) + { + boRpt->emtcDIReason = boUpdt->emtcDIReason; + boRpt->pnb = boUpdt->pnb; + } +#endif + RG_SCH_ADD_TO_CRNT_TIME(boRpt->timeToTx, + boRpt->maxTimeToTx, cell->siCfg.siWinSize) + if((NULLP != dlLc) && (dlLc->si)) + { + boRpt->retxCnt = cell->siCfg.retxCnt; + } + else + { + boRpt->retxCnt = 0; + } + rgSCHDbmInsCmnLcBoRpt(dlLc, boRpt); + + RETVALUE(ROK); +} /* rgSCHUtlHndlBcchPcchBoUpdt */ + +/** + * @brief API for sending bind confirm from Scheduler instance to RRM + * + * @details + * + * Function: rgSCHUtlRgrBndCfm + * + * This API is invoked to send bind confirm from Scheduler instance to RRM. + * This API fills in Pst structure and SAP Ids and invokes + * bind confirm API towards RRM. + * + * @param[in] SuId suId + * @param[in] U8 status + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 rgSCHUtlRgrBndCfm +( +Inst instId, +SuId suId, +U8 status +) +#else +PUBLIC S16 rgSCHUtlRgrBndCfm(instId, suId, status) +Inst instId; +SuId suId; +U8 status; +#endif +{ + S16 ret = ROK; + + TRC2(rgSCHUtlRgrBndCfm) + + + ret = RgUiRgrBndCfm(&rgSchCb[instId].rgrSap[suId].sapCfg.sapPst, rgSchCb[instId].rgrSap[suId].sapCfg.suId, status); + if (ret != ROK) + { + RLOG_ARG0(L_ERROR,DBG_INSTID,instId,"rgSCHUtlRgrBndCfm: RgUiRgrBndCfm Failed "); + RETVALUE(ret); + } + RETVALUE(ret); +} /* rgSCHUtlRgrBndCfm*/ + +/** + * @brief API for sending bind confirm from Scheduler instance to RRM via RGM + * interface + * + * @details + * + * Function: rgSCHUtlRgmBndCfm + * + * This API is invoked to send bind confirm from Scheduler instance to RRM. + * This API fills in Pst structure and SAP Ids and invokes + * + * @param[in] SuId suId + * @param[in] U8 status + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 rgSCHUtlRgmBndCfm +( +Inst instId, +SuId suId, +U8 status +) +#else +PUBLIC S16 rgSCHUtlRgmBndCfm(instId, suId, status) +Inst instId; +SuId suId; +U8 status; +#endif +{ + S16 ret = ROK; + + TRC2(rgSCHUtlRgmBndCfm) + + + ret = RgUiRgmBndCfm(&rgSchCb[instId].rgmSap[suId].sapCfg.sapPst, rgSchCb[instId].rgmSap[suId].sapCfg.suId, status); + if (ret != ROK) + { + RLOG_ARG0(L_ERROR,DBG_INSTID,instId,"rgSCHUtlRgmBndCfm: RgUiRgrBndCfm Failed "); + RETVALUE(ret); + } + RETVALUE(ret); +} /* rgSCHUtlRgmBndCfm*/ + + + +/** + * @brief API for sending configuration confirm from Scheduler to RRM + * + * @details + * + * Function: rgSCHUtlRgrCfgCfm + * + * This API is invoked to send configuration confirm from Scheduler to RRM. + * config confirm API towards RRM. + * + * @param[in] RgrCfgTransId transId + * @param[in] U8 status + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 rgSCHUtlRgrCfgCfm +( +Inst instId, +SpId spId, +RgrCfgTransId transId, +U8 status +) +#else +PUBLIC S16 rgSCHUtlRgrCfgCfm(instId, spId, transId, status) +Inst instId; +SpId spId; +RgrCfgTransId transId; +U8 status; +#endif +{ + U8 prntTrans[RGR_CFG_TRANSID_SIZE+1]; + + TRC2(rgSCHUtlRgrCfgCfm) + + cmMemcpy((U8 *)prntTrans, (U8 *)transId.trans, RGR_CFG_TRANSID_SIZE); + prntTrans[RGR_CFG_TRANSID_SIZE] = '\0'; + + + if(RgUiRgrCfgCfm(&rgSchCb[instId].rgrSap[spId].sapCfg.sapPst, + rgSchCb[instId].rgrSap[spId].sapCfg.suId, + transId, status) != ROK) + { + RLOG_ARG0(L_ERROR,DBG_INSTID,instId,"rgSCHUtlRgrCfgCfm: RgUiRgrCfgCfm Failed "); + RETVALUE(RFAILED); + } + RETVALUE(ROK); +} /* rgSCHUtlRgrCfgCfm */ +#ifdef RGR_RRM_TICK +/** + * @brief API for sending TTI indication from Scheduler to RRM. + * + * @details + * + * Function: rgSCHUtlRgrTtiInd + * + * This API is invoked to send TTI indication from Scheduler instance to RRM. + * This API fills in Pst structure and RgrTtiIndInfo + * + * @param[in] cell RgSchCellCb + * @param[in] CmLteTimingInfo status + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 rgSCHUtlRgrTtiInd +( +RgSchCellCb *cell, +RgrTtiIndInfo *rgrTti +) +#else +PUBLIC S16 rgSCHUtlRgrTtiInd(cell, rgrTti) +RgSchCellCb *cell; +RgrTtiIndInfo *rgrTti; +#endif +{ + S16 ret = ROK; + RgSchUpSapCb *rgrSap; /*!< RGR SAP Control Block */ +#ifdef L2_L3_SPLIT + extern Bool g_usettitmr; + extern Void mtTmrHdlrPublic(void); +#endif + + TRC2(rgSCHUtlRgrTtiInd) + + + rgrSap = cell->rgrSap; + if (rgrSap->sapSta.sapState != LRG_BND) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId, + "rgSCHUtlRgrTtiInd() Upper SAP not bound (%d) ", + rgrSap->sapSta.sapState); + RETVALUE(RFAILED); + } + RgUiRgrTtiInd(&(cell->rgrSap->sapCfg.sapPst), + cell->rgrSap->sapCfg.suId, rgrTti); +#ifdef L2_L3_SPLIT + { + g_usettitmr = TRUE; + mtTmrHdlrPublic(); + } +#endif + RETVALUE(ret); +} /* rgSCHUtlRgrTtiInd*/ +#endif +/** @brief This function is called by rgMacSchSfRecpInd. This function invokes the + * scheduler with the information of the received Data and any Control Elements + * if present. + * + * @details + * + * Function: + * + * Processing steps: + * - Retrieves the RaCb with the rnti provided, if it doesnt exist + * return failure. + * - If UE exists then update the Schduler with any MAC CEs if present. + * - Invoke RAM module to do Msg3 related processing rgSCHRamProcMsg3 + * + * @param [in] RgSchCellCb *cellCb + * @param [in] RgSchUeCb *ueCb + * @param [in] CmLteRnti rnti + * @param [in] RgMacPdu *pdu + * @param [in] RgSchErrInfo *err + * @param + * @return S16 + * -# ROK + * -# RFAILED + */ +#ifdef ANSI +PUBLIC S16 rgSCHUtlProcMsg3 +( +RgInfSfDatInd *subfrmInfo, +RgSchCellCb *cellCb, +RgSchUeCb *ueCb, +CmLteRnti rnti, +RgInfUeDatInd *pdu, +RgSchErrInfo *err + ) +#else +PUBLIC S16 rgSCHUtlProcMsg3 (subfrmInfo, cellCb, ueCb, rnti, pdu, err) +RgInfSfDatInd *subfrmInfo; +RgSchCellCb *cellCb; +RgSchUeCb *ueCb; +CmLteRnti rnti; +RgInfUeDatInd *pdu; +RgSchErrInfo *err; +#endif +{ + S16 ret; + RgSchRaCb *raCb; + + TRC2(rgSCHUtlProcMsg3) + + + /* must have an raCb for this case */ + raCb = rgSCHDbmGetRaCb (cellCb, rnti); + if (raCb == NULLP) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cellCb->cellId, "RNTI:%d Received MSG3, unable to " + "find raCb",rnti); + RETVALUE(RFAILED); + } + + /* ccpu00130982: Processing CRNTI MAC CE before Short BSR, if any, such that + * effBsr of current case only will be considered in scheduling of ContResLst*/ + ret = rgSCHRamProcMsg3 (cellCb, ueCb, raCb, pdu, err); + if (ret != ROK) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cellCb->cellId,"Processing failed in the RAM " + "RNTI:%d ",rnti); + RETVALUE(ret); + } + /* if ueCb is present */ + if (ueCb != NULLP) + { + rgSCHUtlUpdSch (subfrmInfo, cellCb, ueCb, pdu, err); + } + + RETVALUE(ROK); +} +#ifdef LTEMAC_SPS +/** @brief This function is called by RgMacSchSpsRelInd. This function invokes the + * scheduler with the information of the received Data. + * + * @details + * + * Function: rgSCHUtlSpsRelInd + * + * Processing steps: + * TODO + * + * @param [in] RgSchCellCb *cellCb + * @param [in] RgSchUeCb *ueCb + * @param [in] Bool *isExplRel + * @param + * @return S16 + * -# ROK + * -# RFAILED + */ +#ifdef ANSI +PUBLIC S16 rgSCHUtlSpsRelInd +( +RgSchCellCb *cellCb, +RgSchUeCb *ueCb, +Bool isExplRel +) +#else +PUBLIC S16 rgSCHUtlSpsRelInd (cellCb, ueCb, isExplRel) +RgSchCellCb *cellCb; +RgSchUeCb *ueCb; +Bool isExplRel; +#endif +{ + TRC2(rgSCHUtlSpsRelInd); + cellCb->sc.apis->rgSCHUlSpsRelInd(cellCb, ueCb, isExplRel); + RETVALUE(ROK); +} /* end of rgSCHUtlSpsRelInd */ + + +/** @brief This function is called by RgMacSchSpsRelInd. This function invokes the + * scheduler with the information of the received Data. + * + * @details + * + * Function: rgSCHUtlSpsActInd + * + * Processing steps: + * TODO + * + * @param [in] RgSchCellCb *cellCb + * @param [in] RgSchUeCb *ueCb + * @param [in] U16 spsSduSize + * @param + * @return S16 + * -# ROK + * -# RFAILED + */ +#ifdef ANSI +PUBLIC S16 rgSCHUtlSpsActInd +( +RgSchCellCb *cellCb, +RgSchUeCb *ueCb, +U16 spsSduSize +) +#else +PUBLIC S16 rgSCHUtlSpsActInd (cellCb, ueCb, spsSduSize) +RgSchCellCb *cellCb; +RgSchUeCb *ueCb; +U16 spsSduSize; +#endif +{ + TRC2(rgSCHUtlSpsActInd); + cellCb->sc.apis->rgSCHUlSpsActInd(cellCb, ueCb, spsSduSize); + RETVALUE(ROK); +} /* end of rgSCHUtlSpsActInd */ + + +#endif /* LTEMAC_SPS */ + +#ifdef RG_PHASE_2 +/** + * @brief This API is invoked to send uplink group power control request to PHY. + * + * @details + * + * Function : rgSCHUtlTfuGrpPwrCntrlReq + * + * This API is invoked to send uplink group power control request to PHY. + * It fills in the Pst structure, spId value and invokes group power + * control request primitive at TFU. + * + * @param[in] TfuGrpPwrCntrlReqInfo *grpPwrCntrlReq + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 rgSCHUtlTfuGrpPwrCntrlReq +( +Inst inst, +S16 sapId, +TfuGrpPwrCntrlReqInfo *grpPwrCntrlReq +) +#else +PUBLIC S16 rgSCHUtlTfuGrpPwrCntrlReq(inst, sapId, grpPwrCntrlReq) +Inst inst; +S16 sapId; +TfuGrpPwrCntrlReqInfo *grpPwrCntrlReq; +#endif +{ + S16 ret; + RgSchLowSapCb *tfuSap; + Pst pst; + + TRC2(rgSCHUtlTfuGrpPwrCntrlReq); + + /* Get the lower SAP control block from the layer control block. */ + tfuSap = &(rgSchCb[inst].tfuSap[sapId]); + if (tfuSap->sapSta.sapState != LRG_BND) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,grpPwrCntrlReq->cellId, + "rgSCHUtlTfuGrpPwrCntrlReq() Lower SAP not bound (%d) ",tfuSap->sapSta.sapState); + RETVALUE(RFAILED); + } + cmMemcpy ((U8*)&pst, (U8*)&(tfuSap->sapCfg.sapPst), sizeof(Pst)); + if((ret = RgLiTfuGrpPwrCntrlReq (&pst, tfuSap->sapCfg.spId, grpPwrCntrlReq)) != ROK) + { + RLOG_ARG0(L_ERROR,DBG_CELLID,grpPwrCntrlReq->cellId, + "rgSCHUtlTfuGrpPwrCntrlReq() Call to RgLiTfuGrpPwrCntrlReq() failed"); + } + RETVALUE(ret); +} /* rgSCHUtlTfuGrpPwrCntrlReq */ +#endif + +/** + * @brief This API is invoked to send Control Info to PHY. + * + * @details + * + * Function : rgSCHUtlTfuCntrlReq + * + * This API is invoked to send Control Info to PHY. It + * fills in the Pst structure, spId value and invokes Cntrl + * request primitive at TFU. + * + * @param[in] TfuCntrlReqInfo *cntrlReq + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 rgSCHUtlTfuCntrlReq +( +Inst inst, +S16 sapId, +TfuCntrlReqInfo *cntrlReq +) +#else +PUBLIC S16 rgSCHUtlTfuCntrlReq(inst, sapId, cntrlReq) +Inst inst; +S16 sapId; +TfuCntrlReqInfo *cntrlReq; +#endif +{ + S16 ret; + RgSchLowSapCb *tfuSap; + + TRC2(rgSCHUtlTfuCntrlReq) + + /* Get the lower SAP control block from the layer control block. */ + tfuSap = &(rgSchCb[inst].tfuSap[sapId]); + +#ifndef NO_ERRCLS + if (tfuSap->sapSta.sapState != LRG_BND) + { + RLOG_ARG1(L_ERROR,DBG_INSTID,inst,"rgSCHUtlTfuCntrlReq() Lower SAP not bound (%d) ", + tfuSap->sapSta.sapState); + RGSCH_FREE_MEM(cntrlReq); + RETVALUE(RFAILED); + } +#endif + + /* Using local variable for pst is unnecessary - for optimization */ + if((ret = RgLiTfuCntrlReq(&tfuSap->sapCfg.sapPst, tfuSap->sapCfg.spId, + cntrlReq)) != ROK) + { + RLOG_ARG0(L_ERROR,DBG_INSTID,inst,"rgSCHUtlTfuCntrlReq() Call to RgLiTfuCntrlReq() failed"); + } + RETVALUE(ret); +} /* rgSCHUtlTfuCntrlReq*/ + + +/* FOR ACK NACK REP */ + +/** + * @brief This API is invoked to tell the DL Scheduler to add the UE back into + * its scheduling queues. + * + * @details + * + * Function : rgSCHUtlDlActvtUe + * + * This API is invoked from Measurement gap moduled. + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ueCb + * + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 rgSCHUtlDlActvtUe +( +RgSchCellCb *cell, +RgSchUeCb *ue +) +#else +PUBLIC S16 rgSCHUtlDlActvtUe(cell, ue) +RgSchCellCb *cell; +RgSchUeCb *ue; +#endif +{ + TRC2(rgSCHUtlDlActvtUe); + cell->sc.apis->rgSCHActvtDlUe(cell, ue); + RETVALUE(ROK); +} + +/** + * @brief This API is invoked to tell the UL Scheduler to add the UE back into + * its scheduling queues. + * + * @details + * + * Function : rgSCHUtlUlActvtUe + * + * This API is invoked from Measurement gap moduled. + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ueCb + * + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 rgSCHUtlUlActvtUe +( +RgSchCellCb *cell, +RgSchUeCb *ue +) +#else +PUBLIC S16 rgSCHUtlUlActvtUe(cell, ue) +RgSchCellCb *cell; +RgSchUeCb *ue; +#endif +{ + TRC2(rgSCHUtlUlActvtUe); + cell->sc.apis->rgSCHActvtUlUe(cell, ue); + RETVALUE(ROK); +} + +/** + * @brief This API is invoked to send Reception Request Info to PHY. + * + * @details + * + * Function : rgSCHUtlTfuRecpReq + * + * This API is invoked to send Reception Request Info to PHY. It + * fills in the Pst structure, spId value and invokes Reception + * request primitive at TFU. + * + * @param[in] TfuRecpReqInfo *recpReq + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 rgSCHUtlTfuRecpReq +( +Inst inst, +S16 sapId, +TfuRecpReqInfo *recpReq +) +#else +PUBLIC S16 rgSCHUtlTfuRecpReq(inst, sapId, recpReq) +Inst inst; +S16 sapId; +TfuRecpReqInfo *recpReq; +#endif +{ + S16 ret; + RgSchLowSapCb *tfuSap; + + TRC2(rgSCHUtlTfuRecpReq) + + /* Get the lower SAP control block from the layer control block. */ + tfuSap = &(rgSchCb[inst].tfuSap[sapId]); + +#ifndef NO_ERRCLS + if (tfuSap->sapSta.sapState != LRG_BND) + { + RLOG_ARG1(L_ERROR,DBG_INSTID,inst,"rgSCHUtlTfuRecpReq() Lower SAP not bound (%d) ", + tfuSap->sapSta.sapState); + RGSCH_FREE_MEM(recpReq); + RETVALUE(RFAILED); + } +#endif + + /* Using local variable for pst is unnecessary - for optimization */ + if((ret = RgLiTfuRecpReq(&tfuSap->sapCfg.sapPst, tfuSap->sapCfg.spId, + recpReq)) != ROK) + { + RLOG_ARG0(L_ERROR,DBG_INSTID,inst,"rgSCHUtlTfuRecpReq() Call to RgLiTfuRecpReq() failed"); + } + RETVALUE(ret); +} /* rgSCHUtlTfuRecpReq */ + + /** @brief This function Validates the SAP information received along with the + * primitive from the lower layer. + * + * Function: rgSCHUtlValidateTfuSap + * + * Validates SAP information. + * @param suId The SAP Id + * @return + * -# ROK + * -# RFAILED + */ +#ifdef ANSI +PUBLIC S16 rgSCHUtlValidateTfuSap +( +Inst inst, +SuId suId +) +#else +PUBLIC S16 rgSCHUtlValidateTfuSap(inst, suId) +Inst inst; +SuId suId; +#endif +{ + RgSchLowSapCb *tfuSap; + + TRC2(rgSCHUtlValidateTfuSap) + + if(suId >= rgSchCb[inst].numSaps) + { + RLOG_ARG0(L_ERROR,DBG_INSTID,inst, "Incorrect SuId"); + RETVALUE(RFAILED); + } + tfuSap = &(rgSchCb[inst].tfuSap[suId]); + + /* First lets check the suId */ + if( suId != tfuSap->sapCfg.suId) + { + RLOG_ARG2(L_ERROR,DBG_INSTID,inst,"Incorrect SuId. Configured (%d) Recieved (%d)", + tfuSap->sapCfg.suId, suId); + RETVALUE(RFAILED); + } + if (tfuSap->sapSta.sapState != LRG_BND) + { + RLOG_ARG1(L_ERROR,DBG_INSTID,inst,"Lower SAP not enabled SuId (%d)", + tfuSap->sapCfg.suId); + RETVALUE(RFAILED); + } + RETVALUE(ROK); +} /* end of rgSCHUtlValidateTfuSap */ + +/* +* +* Fun: rgSCHUtlAllocEventMem +* +* Desc: This function allocates event memory +* +* Ret: ROK - on success +* RFAILED - on failure +* +* Notes: None +* +* File: rg_utl.c +* +*/ +#ifdef ANSI +PUBLIC S16 rgSCHUtlAllocEventMem +( +Inst inst, +Ptr *memPtr, +Size memSize +) +#else +PUBLIC S16 rgSCHUtlAllocEventMem(inst, memPtr, memSize) +Inst inst; +Ptr *memPtr; +Size memSize; +#endif +{ + Mem sMem; + VOLATILE U32 startTime=0; + + TRC2(rgSCHUtlAllocEventMem) + + sMem.region = rgSchCb[inst].rgSchInit.region; + sMem.pool = rgSchCb[inst].rgSchInit.pool; + +#if (ERRCLASS & ERRCLS_DEBUG) + if (memSize<= 0) + { + RGSCHLOGERROR(inst, ERRCLS_INT_PAR, ERG022, memSize, + "rgAllocEventMem(): memSize invalid\n"); + RETVALUE (RFAILED); + } +#endif /* ERRCLASS & ERRCLS_DEBUG */ + /*starting Task*/ + SStartTask(&startTime, PID_SCHUTL_CMALLCEVT); + +#ifdef MS_MBUF_CORRUPTION /* Should be enabled when debugging mbuf corruption */ + MS_BUF_ADD_ALLOC_CALLER(); +#endif /* */ +#ifdef TFU_ALLOC_EVENT_NO_INIT + if(ROK != cmAllocEvntNoInit(memSize, TFU_MAX_MEMBLK_SIZE, &sMem, memPtr)) +#else + if(ROK != cmAllocEvnt(memSize, TFU_MAX_MEMBLK_SIZE, &sMem, memPtr)) +#endif /* */ + { + RLOG_ARG0(L_ERROR,DBG_INSTID,inst,"cmAllocEvnt Failed."); + RETVALUE(RFAILED); + } + /*stoping Task*/ + SStopTask(startTime, PID_SCHUTL_CMALLCEVT); + RETVALUE(ROK); +} /* end of rgSCHUtlAllocEventMem*/ + +/* +* +* Fun: rgGetEventMem +* +* Desc: This function allocates event memory +* +* Ret: ROK - on success +* RFAILED - on failure +* +* Notes: None +* +* File: rg_utl.c +* +*/ +#ifdef ANSI +PUBLIC S16 rgSCHUtlGetEventMem +( +Ptr *ptr, +Size len, +Ptr memCp +) +#else +PUBLIC S16 rgSCHUtlGetEventMem(ptr, len, memCp) +Ptr *ptr; +Size len; +Ptr memCp; +#endif +{ + S16 ret; + + TRC2(rgSCHUtlGetEventMem) +#ifdef TFU_ALLOC_EVENT_NO_INIT + ret = cmGetMemNoInit(memCp, len, (Ptr *)ptr); +#else + ret = cmGetMem(memCp, len, (Ptr *)ptr); +#endif + RETVALUE(ret); +} /* end of rgSCHUtlGetEventMem*/ + +#ifdef LTE_TDD + + +/** + * @brief Handler to allocate memory for ACK/NACk feedback information + * + * @details + * + * Function : rgSCHUtlAllocUeANFdbkInfo + * + * It allocates memory for the UE related ACK NACK information. + * + * @param[in] RgSchUeCb *ue + * @return S16 + **/ +#ifdef ANSI +PUBLIC S16 rgSCHUtlAllocUeANFdbkInfo +( +RgSchUeCb *ue, +U8 servCellIdx +) +#else +PUBLIC S16 rgSCHUtlAllocUeANFdbkInfo(ue,servCellIdx) +RgSchUeCb *ue; +U8 servCellIdx; +#endif +{ + U8 idx; + + TRC2(rgSCHUtlAllocUeANFdbkInfo); + + if (rgSCHUtlAllocSBuf(ue->cell->instIdx, + (Data **) &(ue->cellInfo[servCellIdx]->anInfo), sizeof(RgSchTddANInfo) * \ + ue->cell->ackNackFdbkArrSize) != ROK) + { + RETVALUE(RFAILED); + } + + for(idx=0; idx < ue->cell->ackNackFdbkArrSize; idx++) + { + rgSCHUtlInitUeANFdbkInfo(&ue->cellInfo[servCellIdx]->anInfo[idx]); + } + + /* Set it to the first index */ + ue->cellInfo[servCellIdx]->nextFreeANIdx = 0; + RETVALUE(ROK); +} /* rgSCHUtlAllocUeANFdbkInfo */ + +/** + * @brief Handler to release memory for ACK/NACk feedback information + * + * @details + * + * Function : rgSCHUtlDelUeANFdbkInfo + * + * It releases memory for the UE related ACK NACK information. + * + * @param[in] RgSchUeCb *ue + * @return Void + **/ +#ifdef ANSI +PUBLIC Void rgSCHUtlDelUeANFdbkInfo +( +RgSchUeCb *ue, +U8 servCellIdx +) +#else +PUBLIC Void rgSCHUtlDelUeANFdbkInfo(ue,servCellIdx) +RgSchUeCb *ue; +U8 servCellIdx; +#endif +{ + TRC2(rgSCHUtlDelUeANFdbkInfo); + + /* ccpu00117052 - MOD - Passing double pointer + for proper NULLP assignment*/ + rgSCHUtlFreeSBuf(ue->cell->instIdx, + (Data **)(&( ue->cellInfo[servCellIdx]->anInfo)), sizeof(RgSchTddANInfo) * \ + ue->cell->ackNackFdbkArrSize); + + RETVOID; +} /* rgSCHUtlDelUeANFdbkInfo */ + +/** + * @brief Handler to initialise UE ACK/NACk feedback information + * + * @details + * + * Function : rgSCHUtlInitUeANFdbkInfo + * + * It initialises UE related ACK NACK information. + * + * @param[in] RgSchTddANInfo *anFdInfo + * @return S16 + **/ +#ifdef ANSI +PUBLIC S16 rgSCHUtlInitUeANFdbkInfo +( +RgSchTddANInfo *anFdInfo +) +#else +PUBLIC S16 rgSCHUtlInitUeANFdbkInfo(anFdInfo) +RgSchTddANInfo *anFdInfo; +#endif +{ + TRC2(rgSCHUtlInitUeANFdbkInfo); + + anFdInfo->sfn = RGSCH_MAX_SFN+1; /* defensively setting invalid sfn */ + anFdInfo->subframe = 0; + anFdInfo->ulDai = RG_SCH_INVALID_DAI_VAL; + anFdInfo->dlDai = RG_SCH_INVALID_DAI_VAL; + anFdInfo->latestMIdx = RG_SCH_INVALID_M_VAL; + + RETVALUE(ROK); +} /* rgSCHUtlInitUeANFdbkInfo */ + +/** + * @brief Handler to get UE related ACK NACK feedback information + * + * @details + * + * Function : rgSCHUtlGetUeANFdbkInfo + * + * It gets the UE related ACK NACK information based on + * SFN and subframe number. + * + * @param[in] RgSchUeCb *ueCb + * @param[in] CmLteTimingInfo *time + * @return RgSchTddANInfo* + **/ +#ifdef ANSI +PUBLIC RgSchTddANInfo* rgSCHUtlGetUeANFdbkInfo +( +RgSchUeCb *ueCb, +CmLteTimingInfo *timeInfo, +U8 servCellIdx +) +#else +PUBLIC RgSchTddANInfo* rgSCHUtlGetUeANFdbkInfo(ueCb, timeInfo,servCellIdx) +RgSchUeCb *ueCb; +CmLteTimingInfo *timeInfo; +U8 servCellIdx; +#endif +{ + U8 idx; + + TRC2(rgSCHUtlGetUeANFdbkInfo); + + for (idx = 0; idx < ueCb->cell->ackNackFdbkArrSize; ++idx) + { + if( (timeInfo->sfn == ueCb->cellInfo[servCellIdx]->anInfo[idx].sfn) && + (timeInfo->subframe == ueCb->cellInfo[servCellIdx]->anInfo[idx].subframe)) + { + RETVALUE(&ueCb->cellInfo[servCellIdx]->anInfo[idx]); + } + } + + RETVALUE(NULLP); +} /* rgSCHUtlGetUeANFdbkInfo */ + +/** + * @brief To get downlink subframe index + * + * @details + * + * Function: rgSCHUtlGetDlSfIdx + * Purpose: Gets downlink subframe index based on SFN and subframe no + * + * @param[in] CmLteTimingInfo *timeInfo + * @param[in] RgSchCellCb *cell + * @return U8 + * + **/ +#ifdef ANSI +PUBLIC U8 rgSCHUtlGetDlSfIdx +( +RgSchCellCb *cell, +CmLteTimingInfo *timeInfo +) +#else +PUBLIC U8 rgSCHUtlGetDlSfIdx(cell, timeInfo) +RgSchCellCb *cell; +CmLteTimingInfo *timeInfo; +#endif +{ + U16 idx = 0; + TRC2(rgSCHUtlGetDlSfIdx); + + idx = RGSCH_NUM_SUB_FRAMES - \ + rgSchTddNumUlSubfrmTbl[cell->ulDlCfgIdx][RGSCH_NUM_SUB_FRAMES-1]; + idx = ((idx * timeInfo->sfn) + \ + rgSchTddNumDlSubfrmTbl[cell->ulDlCfgIdx][timeInfo->subframe]) - 1; + idx = idx % cell->numDlSubfrms; + + RETVALUE((U8)idx); +} + +/** + * @brief To get the next downlink subframe + * + * @details + * + * Function: rgSCHUtlGetNxtDlSfInfo + * Purpose: Gets next downlink subframe based on current DL subframe + * + * @param[in] CmLteTimingInfo curDlTime + * @param[in] RgSchCellCb *cell + * @param[in] RgSchDlSf *dlSf + * @param[in] RgSchDlSf **nxtDlsf + * @param[in] CmLteTimingInfo *nxtDlTime + * @return U8 + * + **/ +#ifdef ANSI +PUBLIC Void rgSCHUtlGetNxtDlSfInfo +( +CmLteTimingInfo curDlTime, +RgSchCellCb *cell, +RgSchDlSf *dlSf, +RgSchDlSf **nxtDlsf, +CmLteTimingInfo *nxtDlTime +) +#else +PUBLIC Void rgSCHUtlGetNxtDlSfInfo(curDlTime, cell, dlSf, nxtDlsf, nxtDlTime) +CmLteTimingInfo curDlTime; +RgSchCellCb *cell; +RgSchDlSf *dlSf; +RgSchDlSf **nxtDlsf; +CmLteTimingInfo *nxtDlTime; +#endif +{ + U16 idx = curDlTime.subframe; + U8 count = 0; + TRC2(rgSCHUtlGetNxtDlSfInfo); + + while(TRUE) + { + do + { + idx = (idx + 1) % RGSCH_NUM_SUB_FRAMES; + count++; + }while(rgSchTddUlDlSubfrmTbl[cell->ulDlCfgIdx][idx] + != RG_SCH_TDD_DL_SUBFRAME); + RG_SCH_ADD_TO_CRNT_TIME(curDlTime, (*nxtDlTime), count); + *nxtDlsf = rgSCHUtlSubFrmGet(cell, *nxtDlTime); + if(dlSf->dlFdbkInfo.subframe != (*nxtDlsf)->dlFdbkInfo.subframe) + { + break; + } + } + RETVOID; +} + +/** + * @brief To get the previous downlink subframe + * + * @details + * + * Function: rgSCHUtlGetPrevDlSfInfo + * Purpose: Gets previous downlink subframe based on current DL subframe + * + * @param[in] RgSchCellCb *cell + * @param[in] CmLteTimingInfo curDlTime + * @param[in] CmLteTimingInfo *prevDlTime + * @param[in] U8 *numSubfrm + * @return U8 + * + **/ +#ifdef ANSI +PUBLIC Void rgSCHUtlGetPrevDlSfInfo +( +RgSchCellCb *cell, +CmLteTimingInfo curDlTime, +CmLteTimingInfo *prevDlTime, +U8 *numSubfrm +) +#else +PUBLIC Void rgSCHUtlGetPrevDlSfInfo(cell, curDlTime, prevDlTime, numSubfrm) +RgSchCellCb *cell; +CmLteTimingInfo curDlTime; +CmLteTimingInfo *prevDlTime; +U8 *numSubfrm; +#endif +{ + S16 idx = curDlTime.subframe; + U8 count = 0; + TRC2(rgSCHUtlGetPrevDlSfInfo); + + do + { + idx--; + if(idx < 0) + { + idx = RGSCH_NUM_SUB_FRAMES-1; + } + count++; + }while(rgSchTddUlDlSubfrmTbl[cell->ulDlCfgIdx][idx] + != RG_SCH_TDD_DL_SUBFRAME); + *numSubfrm = count; + RGSCHDECRFRMCRNTTIME(curDlTime, (*prevDlTime), count); + RETVOID; +} + +#endif +/* Added Holes Management functions for Adaptive Re transmission */ +/******* : START *****/ +/*********************************************************** + * + * Func : rgSCHUtlUlSfInit + * + * Desc : UL subframe init. + * + * Ret : S16 + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PUBLIC S16 rgSCHUtlUlSfInit +( +RgSchCellCb *cell, +RgSchUlSf *sf, +U8 idx, +U8 maxUePerSf +) +#else +PUBLIC S16 rgSCHUtlUlSfInit(cell, sf, idx, maxUePerSf) +RgSchCellCb *cell; +RgSchUlSf *sf; +U8 idx; +U8 maxUePerSf; +#endif +{ + S16 ret=ROK; + TRC2(rgSCHUtlUlSfInit); + + sf->idx = idx; +#ifdef RG_5GTF + U8 index; +#endif + +#ifdef LTE_TDD + if(cell->ulDlCfgIdx == 0) + { + /* Store the Uplink subframe number corresponding to the idx */ + sf->ulSfIdx = rgSchTddCfg0UlSfTbl[idx%6]; + } +#endif + ret = rgSCHUtlAllocSBuf(cell->instIdx, (Data **)&sf->allocDb, + sizeof(RgSchUlAllocDb)); + if (ret != ROK) + { + RETVALUE(ret); + } + ret = rgSCHUtlUlAllocDbInit(cell, sf->allocDb, maxUePerSf); + if (ret != ROK) + { + /* ccpu00117052 - MOD - Passing double pointer + for proper NULLP assignment*/ + rgSCHUtlFreeSBuf(cell->instIdx, (Data **)(&(sf->allocDb)), + sizeof(RgSchUlAllocDb)); + RETVALUE(ret); + } + ret = rgSCHUtlAllocSBuf(cell->instIdx, (Data **)&sf->holeDb, + sizeof(RgSchUlHoleDb)); + if (ret != ROK) + { + rgSCHUtlUlAllocDbDeinit(cell, sf->allocDb); + /* ccpu00117052 - MOD - Passing double pointer + for proper NULLP assignment*/ + rgSCHUtlFreeSBuf(cell->instIdx, (Data **)(&(sf->allocDb)), + sizeof(RgSchUlAllocDb)); + RETVALUE(ret); + } + /* Initialize the hole with CFI 1 Pusch Bw Info */ + ret = rgSCHUtlUlHoleDbInit(cell, sf->holeDb, (U8)(maxUePerSf + 2), \ + 0, cell->dynCfiCb.bwInfo[1].numSb); + + if (ret != ROK) + { + rgSCHUtlUlAllocDbDeinit(cell, sf->allocDb); + /* ccpu00117052 - MOD - Passing double pointer + for proper NULLP assignment*/ + rgSCHUtlFreeSBuf(cell->instIdx, (Data **)(&(sf->allocDb)), + sizeof(RgSchUlAllocDb)); + rgSCHUtlFreeSBuf(cell->instIdx, (Data **)(&(sf->holeDb)), + sizeof(RgSchUlHoleDb)); + RETVALUE(ret); + } + cmLListInit(&sf->reTxLst); + + /* Fix ccpu00120610*/ + sf->allocCountRef = &sf->allocDb->count; + + /* initialize UL available subbands for current sub-frame */ + sf->availSubbands = cell->dynCfiCb.bwInfo[1].numSb; +#ifdef RG_5GTF + sf->numGrpPerTti = cell->cell5gtfCb.ueGrpPerTti; + sf->numUePerGrp = cell->cell5gtfCb.uePerGrpPerTti; + for(index = 0; index < MAX_5GTF_BEAMS; index++) + { + sf->sfBeamInfo[index].totVrbgAllocated = 0; + sf->sfBeamInfo[index].totVrbgRequired = 0; + sf->sfBeamInfo[index].vrbgStart = 0; + } +#endif + + RETVALUE(ret); +} + + +/*********************************************************** + * + * Func : rgSCHUtlUlSfDeinit + * + * Desc : Deinitialises a subframe + * + * Ret : Void + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PUBLIC Void rgSCHUtlUlSfDeinit +( +RgSchCellCb *cell, +RgSchUlSf *sf +) +#else +PUBLIC Void rgSCHUtlUlSfDeinit(cell, sf) +RgSchCellCb *cell; +RgSchUlSf *sf; +#endif +{ + TRC2(rgSCHUtlUlSfDeinit); + if (sf->allocDb) + { + rgSCHUtlUlAllocDbDeinit(cell, sf->allocDb); + /* ccpu00117052 - MOD - Passing double pointer + for proper NULLP assignment*/ + /* ccpu00117052 - MOD - Passing double pointer + for proper NULLP assignment*/ + rgSCHUtlFreeSBuf(cell->instIdx, (Data **)(&(sf->allocDb)), + sizeof(RgSchUlAllocDb)); + } + if (sf->holeDb) + { + rgSCHUtlUlHoleDbDeinit(cell, sf->holeDb); + /* ccpu00117052 - MOD - Passing double pointer + for proper NULLP assignment*/ + rgSCHUtlFreeSBuf(cell->instIdx, (Data **)(&(sf->holeDb)), + sizeof(RgSchUlHoleDb)); + } + RETVOID; +} + +/*********************************************************** + * + * Func : rgSCHUtlUlAllocDbInit + * + * Desc : Initialise allocation DB + * + * Ret : S16 (ROK/RFAILED) + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PRIVATE S16 rgSCHUtlUlAllocDbInit +( +RgSchCellCb *cell, +RgSchUlAllocDb *allocDb, +U8 maxAllocs +) +#else +PRIVATE S16 rgSCHUtlUlAllocDbInit(cell, allocDb, maxAllocs) +RgSchCellCb *cell; +RgSchUlAllocDb *allocDb; +U8 maxAllocs; +#endif +{ + S16 ret = rgSCHUtlUlAllocMemInit(cell, &allocDb->mem, maxAllocs); + TRC2(rgSCHUtlUlAllocDbInit); + if (ret != ROK) + { + RETVALUE(ret); + } + allocDb->count = 0; + allocDb->first = NULLP; + RETVALUE(ROK); +} + +/*********************************************************** + * + * Func : rgSCHUtlUlAllocDbDeinit + * + * Desc : Deinitialises allocation DB + * sent to UE, for a UE with accumulation disabled + * + * Ret : Void + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PRIVATE Void rgSCHUtlUlAllocDbDeinit +( +RgSchCellCb *cell, +RgSchUlAllocDb *allocDb +) +#else +PRIVATE Void rgSCHUtlUlAllocDbDeinit(cell, allocDb) +RgSchCellCb *cell; +RgSchUlAllocDb *allocDb; +#endif +{ + TRC2(rgSCHUtlUlAllocDbDeinit); + rgSCHUtlUlAllocMemDeinit(cell, &allocDb->mem); + allocDb->count = 0; + allocDb->first = NULLP; + RETVOID; +} + +/*********************************************************** + * + * Func : rgSCHUtlUlHoleDbInit + * + * Desc : Initialise hole DB + * + * Ret : S16 (ROK/RFAILED) + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PRIVATE S16 rgSCHUtlUlHoleDbInit +( +RgSchCellCb *cell, +RgSchUlHoleDb *holeDb, +U8 maxHoles, +U8 start, +U8 num +) +#else +PRIVATE S16 rgSCHUtlUlHoleDbInit(cell, holeDb, maxHoles, start, num) +RgSchCellCb *cell; +RgSchUlHoleDb *holeDb; +U8 maxHoles; +U8 start; +U8 num; +#endif +{ + S16 ret; + RgSchUlHole *hole = NULLP; + TRC2(rgSCHUtlUlHoleDbInit); + + ret = rgSCHUtlUlHoleMemInit(cell, &holeDb->mem, maxHoles, &hole); + if (ret != ROK) + { + RETVALUE(ret); + } + holeDb->count = 1; + holeDb->first = hole; + hole->start = start; + hole->num = num; + hole->prv = hole->nxt = NULLP; + RETVALUE(ROK); +} + +/*********************************************************** + * + * Func : rgSCHUtlUlHoleDbDeinit + * + * Desc : Deinitialises hole DB + * + * Ret : Void + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PRIVATE Void rgSCHUtlUlHoleDbDeinit +( +RgSchCellCb *cell, +RgSchUlHoleDb *holeDb +) +#else +PRIVATE Void rgSCHUtlUlHoleDbDeinit(cell, holeDb) +RgSchCellCb *cell; +RgSchUlHoleDb *holeDb; +#endif +{ + TRC2(rgSCHUtlUlHoleDbDeinit); + rgSCHUtlUlHoleMemDeinit(cell, &holeDb->mem); + holeDb->count = 0; + holeDb->first = NULLP; + RETVOID; +} + + +/*********************************************************** + * + * Func : rgSCHUtlUlAllocGetHole + * + * Desc : Get allocation from hole + * + * Ret : RgSchUlAlloc * + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PUBLIC RgSchUlAlloc *rgSCHUtlUlAllocGetHole +( +RgSchUlSf *sf, +U8 numSb, +RgSchUlHole *hole +) +#else +PUBLIC RgSchUlAlloc *rgSCHUtlUlAllocGetHole(sf, numSb, hole) +RgSchUlSf *sf; +U8 numSb; +RgSchUlHole *hole; +#endif +{ + TRC2(rgSCHUtlUlAllocGetHole); + if (numSb < hole->num) + { + RETVALUE(rgSCHUtlUlAllocGetPartHole(sf, numSb, hole)); + } + else + { + RETVALUE(rgSCHUtlUlAllocGetCompHole(sf, hole)); + } +} + + +/*********************************************************** + * + * Func : rgSCHUtlUlAllocGetCompHole + * + * Desc : Get an allocation corresponding to an entire hole + * + * Ret : RgSchUlAlloc * + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PUBLIC RgSchUlAlloc *rgSCHUtlUlAllocGetCompHole +( +RgSchUlSf *sf, +RgSchUlHole *hole +) +#else +PUBLIC RgSchUlAlloc *rgSCHUtlUlAllocGetCompHole(sf, hole) +RgSchUlSf *sf; +RgSchUlHole *hole; +#endif +{ + RgSchUlAlloc *alloc; + /* alloc = rgSCHUtlUlAllocGetAndIns(sf->allocDb, hole->prvAlloc, hole->nxtAlloc); */ + /* Calling rgSchCmnUlAllocGetAndIns is ok, but prv alloc needs to have nxtHole + * updated, causing another check for prv */ + RgSchUlAlloc *prv = hole->prvAlloc; + RgSchUlAlloc *nxt = hole->nxtAlloc; + TRC2(rgSCHUtlUlAllocGetCompHole); + + if (prv) + { + if (hole->start == prv->nxtHole->start) + { + prv->nxtHole = NULLP; + } + alloc = rgSCHUtlUlAllocGetAdjNxt(sf->allocDb, prv); + } + else + { + alloc = rgSCHUtlUlAllocGetFirst(sf->allocDb); + } + + RGSCH_NULL_CHECK( 0, alloc); + alloc->prvHole = NULLP; + alloc->nxtHole = NULLP; + + alloc->sbStart = hole->start; + alloc->numSb = hole->num; + + if (nxt) + { + nxt->prvHole = NULLP; + } + + rgSCHUtlUlHoleRls(sf->holeDb, hole); + + /* UL_ALLOC_CHANGES*/ + alloc->allocDbRef = (void*)sf->allocDb; + alloc->holeDbRef = (void*)sf->holeDb; + RETVALUE(alloc); +} + +/*********************************************************** + * + * Func : rgSCHUtlUlAllocGetPartHole + * + * Desc : Get an allocation corresponding to a part of a hole. + * The initial 'numSb' part of the hole shall be taken + * away for this alloc. + * + * Ret : RgSchUlAlloc * + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PUBLIC RgSchUlAlloc *rgSCHUtlUlAllocGetPartHole +( +RgSchUlSf *sf, +U8 numSb, +RgSchUlHole *hole +) +#else +PUBLIC RgSchUlAlloc *rgSCHUtlUlAllocGetPartHole(sf, numSb, hole) +RgSchUlSf *sf; +U8 numSb; +RgSchUlHole *hole; +#endif +{ + RgSchUlAlloc *alloc; + /* alloc = rgSCHUtlUlAllocGetAndIns(sf->allocDb, hole->prvAlloc, hole->nxtAlloc); */ + /* Calling rgSchCmnUlAllocGetAndIns is ok, but prv alloc needs to have nxtHole + * updated, causing another check for prv */ + RgSchUlAlloc *prv = hole->prvAlloc; + TRC2(rgSCHUtlUlAllocGetPartHole); + + if (prv) + { + if (hole->start == prv->nxtHole->start) + { + prv->nxtHole = NULLP; + } + alloc = rgSCHUtlUlAllocGetAdjNxt(sf->allocDb, prv); + } + else + { + alloc = rgSCHUtlUlAllocGetFirst(sf->allocDb); + } + + RGSCH_NULL_CHECK( 0, alloc); + alloc->prvHole = NULLP; + alloc->nxtHole = hole; + hole->prvAlloc = alloc; + + alloc->sbStart = hole->start; + alloc->numSb = numSb; + hole->start += numSb; + hole->num -= numSb; + + rgSCHUtlUlHoleDecr(sf->holeDb, hole); + + /* UL_ALLOC_CHANGES*/ + alloc->allocDbRef = (void*)sf->allocDb; + alloc->holeDbRef = (void*)sf->holeDb; + + RETVALUE(alloc); +} + +/*********************************************************** + * + * Func : rgSCHUtlUlAllocFirst + * + * Desc : Get first alloc in subframe + * + * Ret : RgSchUlAlloc * + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PUBLIC RgSchUlAlloc *rgSCHUtlUlAllocFirst +( +RgSchUlSf *sf +) +#else +PUBLIC RgSchUlAlloc *rgSCHUtlUlAllocFirst(sf) +RgSchUlSf *sf; +#endif +{ + TRC2(rgSCHUtlUlAllocFirst); + RETVALUE(sf->allocDb->first); +} + +/*********************************************************** + * + * Func : rgSCHUtlUlAllocNxt + * + * Desc : Get next alloc + * + * Ret : RgSchUlAlloc * + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PUBLIC RgSchUlAlloc *rgSCHUtlUlAllocNxt +( +RgSchUlSf *sf, +RgSchUlAlloc *alloc +) +#else +PUBLIC RgSchUlAlloc *rgSCHUtlUlAllocNxt(sf, alloc) +RgSchUlSf *sf; +RgSchUlAlloc *alloc; +#endif +{ + TRC2(rgSCHUtlUlAllocNxt); + UNUSED(sf); + RETVALUE(alloc->nxt); +} + +/*********************************************************** + * + * Func : rgSCHUtlUlAllocGetAdjNxt + * + * Desc : Get alloc which is immediately after the passed one. + * 1. Gets alloc from mem. + * 2. Inserts alloc into list (between prv and + * prv->nxt, prv is not NULLP). + * 3. Increments alloc count. + * Note 1: Holes are not dealt with here. + * Note 2: Assumes prv to be NULL. + * + * Ret : RgSchUlAlloc * + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PUBLIC RgSchUlAlloc *rgSCHUtlUlAllocGetAdjNxt +( +RgSchUlAllocDb *db, +RgSchUlAlloc *prv +) +#else +PUBLIC RgSchUlAlloc *rgSCHUtlUlAllocGetAdjNxt(db, prv) +RgSchUlAllocDb *db; +RgSchUlAlloc *prv; +#endif +{ + RgSchUlAlloc *alloc = rgSCHUtlUlAllocMemGet(&db->mem); + RgSchUlAlloc *nxt = prv->nxt; + TRC2(rgSCHUtlUlAllocGetAdjNxt); + +#if (ERRCLASS & ERRCLS_DEBUG) + if ( alloc == NULLP ) + { + RETVALUE ( NULLP ); + } +#endif + alloc->prv = prv; + alloc->nxt = nxt; + prv->nxt = alloc; + if (nxt) + { + nxt->prv = alloc; + } + + ++db->count; + + RETVALUE(alloc); +} + +/*********************************************************** + * + * Func : rgSCHUtlUlAllocGetFirst + * + * Desc : Get alloc which is to be the first one in the alloc list + * 1. Gets alloc from mem. + * 2. Inserts alloc as first element into list. + * 3. Increments alloc count. + * Note 1: Holes are not dealt with here. + * Note 2: prv to necessarily NULLP. + * + * Ret : RgSchUlAlloc * + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PUBLIC RgSchUlAlloc *rgSCHUtlUlAllocGetFirst +( +RgSchUlAllocDb *db +) +#else +PUBLIC RgSchUlAlloc *rgSCHUtlUlAllocGetFirst(db) +RgSchUlAllocDb *db; +#endif +{ + RgSchUlAlloc *alloc = rgSCHUtlUlAllocMemGet(&db->mem); + RgSchUlAlloc *nxt = db->first; + TRC2(rgSCHUtlUlAllocGetFirst); + +#if (ERRCLASS & ERRCLS_DEBUG) + if ( alloc == NULLP ) + { + RETVALUE ( NULLP ); + } +#endif + + alloc->prv = NULLP; + alloc->nxt = nxt; + if (nxt) + { + nxt->prv = alloc; + } + db->first = alloc; + + ++db->count; + + RETVALUE(alloc); +} + +/* UL_ALLOC_ENHANCEMENT */ +/*********************************************************** + * + * Func : rgSCHUtlUlHoleAddAllocation + * + * Desc : On freeing an alloc, add to hole + * + * Ret : Void + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PUBLIC Void rgSCHUtlUlHoleAddAllocation +( +RgSchUlAlloc *alloc +) +#else +PUBLIC Void rgSCHUtlUlHoleAddAllocation(alloc) +RgSchUlAlloc *alloc; +#endif +{ + /* Note: rgSchCmnUlHoleUpdAllocLnks function that is used should not exist as + * one, if such excessive branching is done (AllocNone, AllocNoPrv etc). + * The excessive branching is meant to utilise the knowledge of whether prv + * and nxt allocs exist or not. Hence for each kind (none, noprv, nonxt, + * both), there should be a rgSchCmnUlHoleUpdAllocLnks... function (such as + * rgSchCmnUlHoleUpdAllocLnksNone/NoPrv etc. */ + RgSchUlHoleDb *db = alloc->holeDbRef; + RgSchUlHole *prv = alloc->prvHole; + RgSchUlHole *nxt = alloc->nxtHole; + TRC2(rgSCHUtlUlHoleAddAllocation); + + if (prv) + { + if (nxt) + { + rgSCHUtlUlHoleJoin(db, prv, nxt, alloc); + } + else + rgSCHUtlUlHoleExtndRight(db, prv, alloc); + } + else + { + if (nxt) + { + rgSCHUtlUlHoleExtndLeft(db, nxt, alloc); + } + else + rgSCHUtlUlHoleNew(db, alloc); + } + RETVOID; +} + + +/*********************************************************** + * + * Func : rgSCHUtlUlAllocRelease + * + * Desc : Releases an uplink allocation, only take alloc ptr + * + * Ret : Void + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PUBLIC Void rgSCHUtlUlAllocRelease +( +RgSchUlAlloc *alloc +) +#else +PUBLIC Void rgSCHUtlUlAllocRelease(alloc) +RgSchUlAlloc *alloc; +#endif +{ + RgSchUlAllocDb *allocDb = alloc->allocDbRef; + RgSchUlAlloc *prv = alloc->prv; + RgSchUlAlloc *nxt = alloc->nxt; + TRC2(rgSCHUtlUlAllocRelease); + + alloc->ue = NULLP; + alloc->raCb = NULLP; + alloc->isAdaptive = FALSE; + + if (prv) + { + prv->nxt = nxt; + if (nxt) /* general case: this allocation lies btw two */ + { + nxt->prv = prv; + } + } + else + { + allocDb->first = nxt; + if (nxt) + { + nxt->prv = NULLP; + } + } + --allocDb->count; + rgSCHUtlUlHoleAddAllocation(alloc); + rgSCHUtlUlAllocMemRls(&allocDb->mem, alloc); + + RETVOID; +} + + +/*********************************************************** + * + * Func : rgSCHUtlUlAllocRls + * + * Desc : Releases an uplink allocation + * + * Ret : Void + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PUBLIC Void rgSCHUtlUlAllocRls +( +RgSchUlSf *sf, +RgSchUlAlloc *alloc +) +#else +PUBLIC Void rgSCHUtlUlAllocRls(sf, alloc) +RgSchUlSf *sf; +RgSchUlAlloc *alloc; +#endif +{ + RgSchUlAllocDb *allocDb = sf->allocDb; + RgSchUlAlloc *prv = alloc->prv; + RgSchUlAlloc *nxt = alloc->nxt; + TRC2(rgSCHUtlUlAllocRls); + + alloc->ue = NULLP; + alloc->raCb = NULLP; + alloc->isAdaptive = FALSE; + + if(allocDb->count) + { + if (prv) + { + prv->nxt = nxt; + if (nxt) /* general case: this allocation lies btw two */ + { + nxt->prv = prv; + } + } + else + { + allocDb->first = nxt; + if (nxt) + { + nxt->prv = NULLP; + } + } + --allocDb->count; + rgSCHUtlUlHoleAddAlloc(sf, alloc); + rgSCHUtlUlAllocMemRls(&allocDb->mem, alloc); + } + else + { + + printf("\nError: allocDb->count is ZERO ====\n"); + } + + //printf("\nallocDb->count:%u\n",allocDb->count); + + RETVOID; +} + +/*********************************************************** + * + * Func : rgSCHUtlUlHoleFirst + * + * Desc : Get first (largest) hole + * + * Ret : RgSchUlHole * + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PUBLIC RgSchUlHole *rgSCHUtlUlHoleFirst +( +RgSchUlSf *sf +) +#else +PUBLIC RgSchUlHole *rgSCHUtlUlHoleFirst(sf) +RgSchUlSf *sf; +#endif +{ + TRC2(rgSCHUtlUlHoleFirst); + RETVALUE(sf->holeDb->first); +} + +/*********************************************************** + * + * Func : rgSCHUtlUlHoleNxt + * + * Desc : Get next largest hole + * + * Ret : RgSchUlHole * + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PUBLIC RgSchUlHole *rgSCHUtlUlHoleNxt +( +RgSchUlSf *sf, +RgSchUlHole *hole +) +#else +PUBLIC RgSchUlHole *rgSCHUtlUlHoleNxt(sf, hole) +RgSchUlSf *sf; +RgSchUlHole *hole; +#endif +{ + TRC2(rgSCHUtlUlHoleNxt); + UNUSED(sf); + RETVALUE(hole->nxt); +} + +/*********************************************************** + * + * Func : rgSCHUtlUlHoleAddAlloc + * + * Desc : On freeing an alloc, add to hole + * + * Ret : Void + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PUBLIC Void rgSCHUtlUlHoleAddAlloc +( +RgSchUlSf *sf, +RgSchUlAlloc *alloc +) +#else +PUBLIC Void rgSCHUtlUlHoleAddAlloc(sf, alloc) +RgSchUlSf *sf; +RgSchUlAlloc *alloc; +#endif +{ + /* Note: rgSchCmnUlHoleUpdAllocLnks function that is used should not exist as + * one, if such excessive branching is done (AllocNone, AllocNoPrv etc). + * The excessive branching is meant to utilise the knowledge of whether prv + * and nxt allocs exist or not. Hence for each kind (none, noprv, nonxt, + * both), there should be a rgSchCmnUlHoleUpdAllocLnks... function (such as + * rgSchCmnUlHoleUpdAllocLnksNone/NoPrv etc. */ + RgSchUlHoleDb *db = sf->holeDb; + RgSchUlHole *prv = alloc->prvHole; + RgSchUlHole *nxt = alloc->nxtHole; + TRC2(rgSCHUtlUlHoleAddAlloc); + + if (prv) + { + if (nxt) + { + rgSCHUtlUlHoleJoin(db, prv, nxt, alloc); + } + else + rgSCHUtlUlHoleExtndRight(db, prv, alloc); + } + else + { + if (nxt) + { + rgSCHUtlUlHoleExtndLeft(db, nxt, alloc); + } + else + rgSCHUtlUlHoleNew(db, alloc); + } + + /* increment the number of subbands getting freed to total available list */ + sf->availSubbands += alloc->numSb; + + RETVOID; +} + +/*********************************************************** + * + * Func : rgSCHUtlUlHoleJoin + * + * Desc : Join two holes (due to alloc being deleted) + * + * Ret : Void + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PUBLIC Void rgSCHUtlUlHoleJoin +( +RgSchUlHoleDb *db, +RgSchUlHole *prv, +RgSchUlHole *nxt, +RgSchUlAlloc *alloc +) +#else +PUBLIC Void rgSCHUtlUlHoleJoin(db, prv, nxt, alloc) +RgSchUlHoleDb *db; +RgSchUlHole *prv; +RgSchUlHole *nxt; +RgSchUlAlloc *alloc; +#endif +{ + TRC2(rgSCHUtlUlHoleJoin); + prv->num += alloc->numSb + nxt->num; + rgSCHUtlUlHoleRls(db, nxt); + rgSCHUtlUlHoleIncr(db, prv); + rgSCHUtlUlHoleUpdAllocLnks(prv, alloc->prv, alloc->nxt); + + RETVOID; +} + +/*********************************************************** + * + * Func : rgSCHUtlUlHoleExtndRight + * + * Desc : Extend hole due to alloc coming 'after' the hole + * being deleted + * + * Ret : Void + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PUBLIC Void rgSCHUtlUlHoleExtndRight +( +RgSchUlHoleDb *db, +RgSchUlHole *prv, +RgSchUlAlloc *alloc +) +#else +PUBLIC Void rgSCHUtlUlHoleExtndRight(db, prv, alloc) +RgSchUlHoleDb *db; +RgSchUlHole *prv; +RgSchUlAlloc *alloc; +#endif +{ + TRC2(rgSCHUtlUlHoleExtndRight); + prv->num += alloc->numSb; + rgSCHUtlUlHoleIncr(db, prv); + rgSCHUtlUlHoleUpdAllocLnks(prv, alloc->prv, alloc->nxt); + RETVOID; +} + +/*********************************************************** + * + * Func : rgSCHUtlUlHoleExtndLeft + * + * Desc : Extend hole due to alloc coming 'before' the hole + * being deleted + * + * Ret : Void + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PUBLIC Void rgSCHUtlUlHoleExtndLeft +( +RgSchUlHoleDb *db, +RgSchUlHole *nxt, +RgSchUlAlloc *alloc +) +#else +PUBLIC Void rgSCHUtlUlHoleExtndLeft(db, nxt, alloc) +RgSchUlHoleDb *db; +RgSchUlHole *nxt; +RgSchUlAlloc *alloc; +#endif +{ + TRC2(rgSCHUtlUlHoleExtndLeft); + nxt->num += alloc->numSb; + nxt->start = alloc->sbStart; + rgSCHUtlUlHoleIncr(db, nxt); + rgSCHUtlUlHoleUpdAllocLnks(nxt, alloc->prv, alloc->nxt); + RETVOID; +} + +/*********************************************************** + * + * Func : rgSCHUtlUlHoleNew + * + * Desc : Create new hole due to alloc being deleted + * + * Ret : Void + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PUBLIC Void rgSCHUtlUlHoleNew +( +RgSchUlHoleDb *db, +RgSchUlAlloc *alloc +) +#else +PUBLIC Void rgSCHUtlUlHoleNew(db, alloc) +RgSchUlHoleDb *db; +RgSchUlAlloc *alloc; +#endif +{ + RgSchUlHole *hole = rgSCHUtlUlHoleMemGet(&db->mem); +#if (ERRCLASS & ERRCLS_DEBUG) + if ( hole == NULLP ) + { + RETVOID; + } +#endif + TRC2(rgSCHUtlUlHoleNew); + hole->start = alloc->sbStart; + hole->num = alloc->numSb; + ++db->count; + rgSCHUtlUlHoleIns(db, hole); + rgSCHUtlUlHoleUpdAllocLnks(hole, alloc->prv, alloc->nxt); + RETVOID; +} + +/*********************************************************** + * + * Func : rgSCHUtlUlHoleUpdAllocLnks + * + * Desc : Update alloc links in hole + * + * Ret : Void + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PUBLIC Void rgSCHUtlUlHoleUpdAllocLnks +( +RgSchUlHole *hole, +RgSchUlAlloc *prvAlloc, +RgSchUlAlloc *nxtAlloc +) +#else +PUBLIC Void rgSCHUtlUlHoleUpdAllocLnks(hole, prvAlloc, nxtAlloc) +RgSchUlHole *hole; +RgSchUlAlloc *prvAlloc; +RgSchUlAlloc *nxtAlloc; +#endif +{ + TRC2(rgSCHUtlUlHoleUpdAllocLnks); + if (prvAlloc) + { + prvAlloc->nxtHole = hole; + } + if (nxtAlloc) + { + nxtAlloc->prvHole = hole; + } + hole->prvAlloc = prvAlloc; + hole->nxtAlloc = nxtAlloc; + RETVOID; +} + + +/*********************************************************** + * + * Func : rgSCHUtlUlHoleIns + * + * Desc : Insert (newly created) hole in sorted list of holes. + * Searches linearly, beginning with the largest hole. + * + * Ret : Void + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PUBLIC Void rgSCHUtlUlHoleIns +( +RgSchUlHoleDb *db, +RgSchUlHole *hole +) +#else +PUBLIC Void rgSCHUtlUlHoleIns(db, hole) +RgSchUlHoleDb *db; +RgSchUlHole *hole; +#endif +{ + RgSchUlHole *cur; + TRC2(rgSCHUtlUlHoleIns); + + if ((cur = db->first) != NULLP) + { + RgSchUlHole *nxt; + if (cur->num < hole->num) + { + /* Add at front */ + hole->nxt = cur; + cur->prv = hole; + db->first = hole; + hole->prv = NULLP; + RETVOID; + } + + for (nxt = cur->nxt; nxt; cur = nxt, nxt = nxt->nxt) + { + if (nxt->num < hole->num) + { + /* Insert hole: cur <-> hole <-> nxt */ + cur->nxt = hole; + hole->prv = cur; + hole->nxt = nxt; + nxt->prv = hole; + RETVOID; + } + } + + /* Add at end */ + cur->nxt = hole; + hole->prv = cur; + hole->nxt = NULLP; + RETVOID; + } + + /* This is the first hole */ + db->first = hole; + hole->prv = NULLP; /* may not be needed */ + hole->nxt = NULLP; + RETVOID; +} + + +/*********************************************************** + * + * Func : rgSCHUtlUlHoleIncr + * + * Desc : hole->num has increeased, reposition in sorted + * list if needed + * + * Ret : Void + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PUBLIC Void rgSCHUtlUlHoleIncr +( +RgSchUlHoleDb *db, +RgSchUlHole *hole +) +#else +PUBLIC Void rgSCHUtlUlHoleIncr(db, hole) +RgSchUlHoleDb *db; +RgSchUlHole *hole; +#endif +{ + RgSchUlHole *cur; + TRC2(rgSCHUtlUlHoleIncr); + + if ((cur = hole->prv) != NULLP) + { + RgSchUlHole *prv; + + if (cur->num > hole->num) + { + RETVOID; + } + + /* Remove hole from current position */ + cur->nxt = hole->nxt; + if (hole->nxt) + { + hole->nxt->prv = cur; + } + + for (prv = cur->prv; prv; cur = prv, prv = prv->prv) + { + if (prv->num > hole->num) + { + /* Insert hole: prv <-> hole <-> cur */ + prv->nxt = hole; + hole->prv = prv; + hole->nxt = cur; + cur->prv = hole; + RETVOID; + } + } + + /* Add at front */ + hole->nxt = cur; + cur->prv = hole; + db->first = hole; + hole->prv = NULLP; + RETVOID; + } + RETVOID; +} + +/*********************************************************** + * + * Func : rgSCHUtlUlHoleDecr + * + * Desc : hole->num has decreeased, reposition in sorted + * list if needed + * + * Ret : Void + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PUBLIC Void rgSCHUtlUlHoleDecr +( +RgSchUlHoleDb *db, +RgSchUlHole *hole +) +#else +PUBLIC Void rgSCHUtlUlHoleDecr(db, hole) +RgSchUlHoleDb *db; +RgSchUlHole *hole; +#endif +{ + RgSchUlHole *cur; + TRC2(rgSCHUtlUlHoleDecr); + + if ((cur = hole->nxt) != NULLP) + { + RgSchUlHole *nxt; + + if (cur->num < hole->num) + { + RETVOID; + } + + /* Remove hole from current position */ + cur->prv = hole->prv; + if (hole->prv) + { + hole->prv->nxt = cur; + } + else /* no prv, so cur to replace hole as first in list */ + { + db->first = cur; + } + + for (nxt = cur->nxt; nxt; cur = nxt, nxt = nxt->nxt) + { + if (nxt->num < hole->num) + { + /* Insert hole: cur <-> hole <-> nxt */ + cur->nxt = hole; + hole->prv = cur; + hole->nxt = nxt; + nxt->prv = hole; + RETVOID; + } + } + + /* Add at end */ + cur->nxt = hole; + hole->prv = cur; + hole->nxt = NULLP; + RETVOID; + } + RETVOID; +} + +/*********************************************************** + * + * Func : rgSCHUtlUlHoleRls + * + * Desc : Releases hole. + * 1. Decrements hole count. + * 2. Deletes hole from list. + * 3. Frees hole (hole memory release). + * + * Ret : Void + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PUBLIC Void rgSCHUtlUlHoleRls +( +RgSchUlHoleDb *db, +RgSchUlHole *hole +) +#else +PUBLIC Void rgSCHUtlUlHoleRls(db, hole) +RgSchUlHoleDb *db; +RgSchUlHole *hole; +#endif +{ + RgSchUlHole *prv = hole->prv; + RgSchUlHole *nxt = hole->nxt; + TRC2(rgSCHUtlUlHoleRls); + + --db->count; + if (prv) + { + prv->nxt = nxt; + if (nxt) + { + nxt->prv = prv; + } + } + else + { + db->first = nxt; + if (nxt) + { + nxt->prv = NULLP; + } + } + + rgSCHUtlUlHoleMemRls(&db->mem, hole); + RETVOID; +} + + +/*********************************************************** + * + * Func : rgSCHUtlUlAllocMemInit + * + * Desc : Initialises alloc free pool + * + * Ret : S16 (ROK/RFAILED) + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PUBLIC S16 rgSCHUtlUlAllocMemInit +( +RgSchCellCb *cell, +RgSchUlAllocMem *mem, +U8 maxAllocs +) +#else +PUBLIC S16 rgSCHUtlUlAllocMemInit(cell, mem, maxAllocs) +RgSchCellCb *cell; +RgSchUlAllocMem *mem; +U8 maxAllocs; +#endif +{ + S16 ret; + RgSchUlAlloc *allocs; + TRC2(rgSCHUtlUlAllocMemInit); + + ret = rgSCHUtlAllocSBuf(cell->instIdx, (Data **)&allocs, + maxAllocs * sizeof(*allocs)); + if (ret != ROK) + { + RETVALUE(ret); + } + mem->allocs = allocs; + mem->maxAllocs = maxAllocs; + if (mem->maxAllocs == 1) + { + allocs[0].prv = NULLP; + allocs[0].nxt = NULLP; + } + else + { + U8 i; + allocs[0].prv = NULLP; + allocs[0].nxt = &allocs[1]; + for (i = 1; i < mem->maxAllocs - 1; ++i) + { + allocs[i].prv = &allocs[i-1]; + allocs[i].nxt = &allocs[i+1]; + } + allocs[i].prv = &allocs[i-1]; + allocs[i].nxt = NULLP; + } + mem->firstFree = &allocs[0]; + RETVALUE(ROK); +} + +/*********************************************************** + * + * Func : rgSCHUtlUlAllocMemDeinit + * + * Desc : Deinitialises alloc free pool + * + * Ret : Void + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PUBLIC Void rgSCHUtlUlAllocMemDeinit +( +RgSchCellCb *cell, +RgSchUlAllocMem *mem +) +#else +PUBLIC Void rgSCHUtlUlAllocMemDeinit(cell, mem) +RgSchCellCb *cell; +RgSchUlAllocMem *mem; +#endif +{ + TRC2(rgSCHUtlUlAllocMemDeinit); + /* ccpu00117052 - MOD - Passing double pointer + for proper NULLP assignment*/ + rgSCHUtlFreeSBuf(cell->instIdx, (Data **)(&(mem->allocs)), + mem->maxAllocs * sizeof(*mem->allocs)); + mem->maxAllocs = 0; + mem->firstFree = NULLP; + RETVOID; +} + +/*********************************************************** + * + * Func : rgSCHUtlUlHoleMemInit + * + * Desc : Initialises hole free pool. Assumes maxHoles + * to be at least 2. + * + * Ret : S16 (ROK/RFAILED) + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PUBLIC S16 rgSCHUtlUlHoleMemInit +( +RgSchCellCb *cell, +RgSchUlHoleMem *mem, +U8 maxHoles, +RgSchUlHole **holeRef +) +#else +PUBLIC S16 rgSCHUtlUlHoleMemInit(cell, mem, maxHoles, holeRef) +RgSchCellCb *cell; +RgSchUlHoleMem *mem; +U8 maxHoles; +RgSchUlHole **holeRef; +#endif +{ + S16 ret; + RgSchUlHole *holes; + TRC2(rgSCHUtlUlHoleMemInit); + + ret = rgSCHUtlAllocSBuf(cell->instIdx, (Data **)&holes, + maxHoles * sizeof(*holes)); + if (ret != ROK) + { + RETVALUE(ret); + } + + mem->holes = holes; + mem->maxHoles = maxHoles; + + /* first hole is taken up */ + holes[0].prv = NULLP; /* not needed */ + holes[0].nxt = NULLP; /* not needed */ + *holeRef = &holes[0]; + + if (mem->maxHoles == 2) + { + holes[1].prv = NULLP; /* may not be needed */ + holes[1].nxt = NULLP; /* may not be needed */ + } + else + { + U8 i; + holes[1].prv = NULLP; + holes[0].nxt = &holes[1]; + for (i = 1; i < mem->maxHoles - 1; ++i) + { + holes[i].prv = &holes[i-1]; + holes[i].nxt = &holes[i+1]; + } + holes[i].prv = &holes[i-1]; + holes[i].nxt = NULLP; + } + mem->firstFree = &holes[1]; + + RETVALUE(ROK); +} + +/*********************************************************** + * + * Func : rgSCHUtlUlHoleMemDeinit + * + * Desc : Deinitialises hole free pool + * + * Ret : Void + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PUBLIC Void rgSCHUtlUlHoleMemDeinit +( +RgSchCellCb *cell, +RgSchUlHoleMem *mem +) +#else +PUBLIC Void rgSCHUtlUlHoleMemDeinit(cell, mem) +RgSchCellCb *cell; +RgSchUlHoleMem *mem; +#endif +{ + TRC2(rgSCHUtlUlHoleMemDeinit); + /* ccpu00117052 - MOD - Passing double pointer + for proper NULLP assignment*/ + rgSCHUtlFreeSBuf(cell->instIdx, (Data **)(&(mem->holes)), + mem->maxHoles * sizeof(*mem->holes)); + mem->maxHoles = 0; + mem->firstFree = NULLP; + RETVOID; +} + +/*********************************************************** + * + * Func : rgSCHUtlUlAllocMemGet + * + * Desc : Gets an 'alloc' from the free pool + * + * Ret : RgSchUlAlloc * + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PUBLIC RgSchUlAlloc *rgSCHUtlUlAllocMemGet +( +RgSchUlAllocMem *mem +) +#else +PUBLIC RgSchUlAlloc *rgSCHUtlUlAllocMemGet(mem) +RgSchUlAllocMem *mem; +#endif +{ + RgSchUlAlloc *alloc; + TRC2(rgSCHUtlUlAllocMemGet); + +#if (ERRCLASS & ERRCLS_DEBUG) + if (mem->firstFree == NULLP) + { + RETVALUE(NULLP); + } +#endif + + alloc = mem->firstFree; + mem->firstFree = alloc->nxt; + alloc->nxt = NULLP; /* probably not needed */ + /* alloc->prv might already be NULLP, in case was needed to set it to NULLP */ + + RETVALUE(alloc); +} + +/*********************************************************** + * + * Func : rgSCHUtlUlAllocMemRls + * + * Desc : Returns an 'alloc' to the free pool + * + * Ret : + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PUBLIC Void rgSCHUtlUlAllocMemRls +( +RgSchUlAllocMem *mem, +RgSchUlAlloc *alloc +) +#else +PUBLIC Void rgSCHUtlUlAllocMemRls(mem, alloc) +RgSchUlAllocMem *mem; +RgSchUlAlloc *alloc; +#endif +{ + TRC2(rgSCHUtlUlAllocMemRls); + alloc->prv = NULLP; + + alloc->nxt = mem->firstFree; + if (mem->firstFree != NULLP) + { + mem->firstFree->prv = alloc; + } + mem->firstFree = alloc; + RETVOID; +} + +/*********************************************************** + * + * Func : rgSCHUtlUlHoleMemGet + * + * Desc : Gets a 'hole' from the free pool + * + * Ret : RgSchUlHole * + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PUBLIC RgSchUlHole *rgSCHUtlUlHoleMemGet +( +RgSchUlHoleMem *mem +) +#else +PUBLIC RgSchUlHole *rgSCHUtlUlHoleMemGet(mem) +RgSchUlHoleMem *mem; +#endif +{ + RgSchUlHole *hole; + TRC2(rgSCHUtlUlHoleMemGet); + +#if (ERRCLASS & ERRCLS_DEBUG) + if (mem->firstFree == NULLP) + { + RETVALUE(NULLP); + } +#endif + + hole = mem->firstFree; + mem->firstFree = hole->nxt; + mem->firstFree->prv = NULLP; /* may not be needed, under error class */ + hole->nxt = NULLP; /* probably not needed */ + /* hole->prv is might already be NULLP, in case was needed to set it to NULLP */ + + RETVALUE(hole); +} + +/*********************************************************** + * + * Func : rgSCHUtlUlHoleMemRls + * + * Desc : Returns a 'hole' to the free pool + * + * Ret : Void + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PUBLIC Void rgSCHUtlUlHoleMemRls +( +RgSchUlHoleMem *mem, +RgSchUlHole *hole +) +#else +PUBLIC Void rgSCHUtlUlHoleMemRls(mem, hole) +RgSchUlHoleMem *mem; +RgSchUlHole *hole; +#endif +{ + TRC2(rgSCHUtlUlHoleMemRls); + hole->prv = NULLP; + + hole->nxt = mem->firstFree; + if (mem->firstFree != NULLP) + { + mem->firstFree->prv = hole; + } + mem->firstFree = hole; + RETVOID; +} + +/** + * @brief Get an alloc from the specified position in the BW. + * + * @details + * + * Function : rgSCHUtlUlGetSpfcAlloc + * + * - Return an alloc from the specified position in the BW. + * Note: This function assumes there is always a hole + * Existing which completely has the specified + * allocation. The reason for such an assumption is + * the function's usage as of now guarantees that there + * will always be such hole. And also for efficiency. + * + * @param[in] RgSchUlSf *sf + * @param[in] U8 startSb + * @param[in] U8 numSb + * @return RgSchUlAlloc* + **/ +#ifdef ANSI +PUBLIC RgSchUlAlloc *rgSCHUtlUlGetSpfcAlloc +( +RgSchUlSf *sf, +U8 startSb, +U8 numSb +) +#else +PUBLIC RgSchUlAlloc *rgSCHUtlUlGetSpfcAlloc(sf, startSb, numSb) +RgSchUlSf *sf; +U8 startSb; +U8 numSb; +#endif +{ + RgSchUlHole *hole, *nxtHole; + RgSchUlAlloc *alloc = NULLP; + TRC2(rgSCHUtlUlGetSpfcAlloc); + + if ((hole = rgSCHUtlUlHoleFirst(sf)) == NULLP) + { + RETVALUE(NULLP); + } + do + { + nxtHole = rgSCHUtlUlHoleNxt(sf, hole); + if ((startSb >= hole->start) && + (startSb+numSb <= hole->start+hole->num)) + { + if (startSb != hole->start) + { + /* Create a new hole to accomodate Subbands between + * hole start and req alloc start */ + RgSchUlHole *newHole = rgSCHUtlUlHoleMemGet(&(sf->holeDb->mem)); + +#if (ERRCLASS & ERRCLS_DEBUG) + if ( newHole == NULLP ) + { + RETVALUE( NULLP ); + } +#endif + newHole->start = hole->start; + newHole->num = startSb - hole->start; + hole->start = startSb; + /* [ccpu00122847]-MOD- Correctly updating the hole->num */ + hole->num -= newHole->num; + ++(sf->holeDb->count); + rgSCHUtlUlHoleIns(sf->holeDb, newHole); + newHole->prvAlloc = hole->prvAlloc; + if (newHole->prvAlloc) + { + newHole->prvAlloc->nxtHole = newHole; + } + if (numSb == hole->num) + { + alloc = rgSCHUtlUlAllocGetCompHole(sf, hole); + } + else + { + alloc = rgSCHUtlUlAllocGetPartHole(sf, numSb, hole); + } + alloc->prvHole = newHole; + newHole->nxtAlloc = alloc; + } + else /* Hole start and req alloc start are same */ + { + if (numSb == hole->num) + { + alloc = rgSCHUtlUlAllocGetCompHole(sf, hole); + } + else + { + alloc = rgSCHUtlUlAllocGetPartHole(sf, numSb, hole); + } + } + break; + } + } while ((hole = nxtHole) != NULLP); + RETVALUE(alloc); +} +#ifdef LTE_L2_MEAS +/** + * @brief Validates the qci values + * + * @details + * + * Function :rgSCHUtlValidateQci + * + * @param[in] RgSchCellCb *cellCb + * @param[in] U8 numQci + * @param[out] U8 *qci + * @return S16 + * ROK + * RFAILED + **/ +#ifdef ANSI +PRIVATE S16 rgSCHUtlValidateQci +( +RgSchCellCb *cellCb, +U8 numQci, +U8 *qci +) +#else +PRIVATE S16 rgSCHUtlValidateQci(cellCb, numQci, qci) +RgSchCellCb *cellCb; +U8 numQci; +U8 *qci; +#endif +{ + U8 qciIdx; + U8 qciVal; + + TRC3(rgSCHUtlValidateQci) + + for(qciIdx = 0; qciIdx < numQci; qciIdx++) + { + qciVal = qci[qciIdx]; + if(qciVal == 0 || qciVal > 9) + { + RETVALUE(RFAILED); + } + if(qciVal != cellCb->qciArray[qciVal].qci) + { + RETVALUE(RFAILED); + } + } + + RETVALUE(ROK); +}/* rgSCHUtlValidateQci */ +/** + * @brief Validates the measurement request parameters. + * + * @details + * + * Function :rgSCHUtlValidateMeasReq + * + * @param[in] RgSchCellCb *cellCb + * @param[in] LrgSchMeasReqInfo *schL2MeasInfo + * @param[out] RgSchErrInfo *err + * @return RgSchUlAlloc* + **/ +#ifdef ANSI +PUBLIC S16 rgSCHUtlValidateMeasReq +( +RgSchCellCb *cellCb, +LrgSchMeasReqInfo *schL2MeasInfo, +RgSchErrInfo *err +) +#else +PUBLIC S16 rgSCHUtlValidateMeasReq(cellCb, schL2MeasInfo, err) +RgSchCellCb *cellCb; +LrgSchMeasReqInfo *schL2MeasInfo; +RgSchErrInfo *err; +#endif +{ + U16 measType; + S16 ret; + + TRC3(rgSCHUtlValidateMeasReq) + + measType = schL2MeasInfo->measType; + + if((measType == 0) || + measType > 2047) + { + err->errType = RGSCHERR_SCH_INVALID_MEAS_TYPE; + err->errCause = RGSCHERR_SCH_L2MEAS; + RETVALUE(RFAILED); + } + if((schL2MeasInfo->timePrd !=0) && + (measType & LRG_L2MEAS_AVG_PRB_PER_QCI_DL) && + ((schL2MeasInfo->avgPrbQciDl.numQci > LRG_MAX_QCI_PER_REQ)|| + (schL2MeasInfo->avgPrbQciDl.numQci == 0))) + { + err->errType = RGSCHERR_SCH_INVALID_PARAM_RANGE; + err->errCause = RGSCHERR_SCH_L2MEAS; + RETVALUE(RFAILED); + } + if((schL2MeasInfo->timePrd !=0) && + (measType & LRG_L2MEAS_AVG_PRB_PER_QCI_UL) && + (schL2MeasInfo->avgPrbQciUl.numQci > LRG_MAX_QCI_PER_REQ)) + { + err->errType = RGSCHERR_SCH_INVALID_PARAM_RANGE; + err->errCause = RGSCHERR_SCH_L2MEAS; + RETVALUE(RFAILED); + } + if((measType & LRG_L2MEAS_NMB_ACTV_UE_PER_QCI_DL) && + ((schL2MeasInfo->nmbActvUeQciDl.numQci > LRG_MAX_QCI_PER_REQ) || + (schL2MeasInfo->nmbActvUeQciDl.sampPrd == 0)|| + ((schL2MeasInfo->timePrd !=0)&& + (schL2MeasInfo->timePrd < schL2MeasInfo->nmbActvUeQciDl.sampPrd)) || + (schL2MeasInfo->nmbActvUeQciDl.sampPrd > LRG_MAX_SAMP_PRD))) + { + err->errType = RGSCHERR_SCH_INVALID_PARAM_RANGE; + err->errCause = RGSCHERR_SCH_L2MEAS; + RETVALUE(RFAILED); + } + if((measType & LRG_L2MEAS_NMB_ACTV_UE_PER_QCI_UL) && + ((schL2MeasInfo->nmbActvUeQciUl.numQci > LRG_MAX_QCI_PER_REQ) || + (schL2MeasInfo->nmbActvUeQciUl.sampPrd == 0)|| + ((schL2MeasInfo->timePrd !=0) && + (schL2MeasInfo->timePrd < schL2MeasInfo->nmbActvUeQciUl.sampPrd)) || + (schL2MeasInfo->nmbActvUeQciUl.sampPrd > LRG_MAX_SAMP_PRD))) + { + err->errType = RGSCHERR_SCH_INVALID_PARAM_RANGE; + err->errCause = RGSCHERR_SCH_L2MEAS; + RETVALUE(RFAILED); + } + if((schL2MeasInfo->timePrd !=0) && + (measType & LRG_L2MEAS_AVG_PRB_PER_QCI_DL)) + { + RGSCH_ARRAY_BOUND_CHECK(cellCb->instIdx, schL2MeasInfo->avgPrbQciDl.qci, \ + (schL2MeasInfo->avgPrbQciDl.numQci)); + ret = rgSCHUtlValidateQci(cellCb, schL2MeasInfo->avgPrbQciDl.numQci, + schL2MeasInfo->avgPrbQciDl.qci); + if(ret != ROK) + { + err->errType = RGSCHERR_SCH_INVALID_QCI_VAL; + err->errCause = RGSCHERR_SCH_L2MEAS; + RETVALUE(RFAILED); + } + } + RETVALUE(ROK); +}/* rgSCHUtlValidateMeasReq */ +#endif /* LTE_L2_MEAS */ +/******* : END *****/ +#ifdef RGR_SI_SCH +/** + * @brief API for sending SI configuration confirm from Scheduler to RRM + * + * @details + * + * Function: rgSCHUtlRgrSiCfgCfm + * + * This API is invoked to send SI configuration confirm from Scheduler + * to RRM. + * This API fills in Pst structure and SAP Ids and invokes + * config confirm API towards RRM. + * + * @param[in] RgrCfgTransId transId + * @param[in] U8 status + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 rgSCHUtlRgrSiCfgCfm +( +Inst instId, +SpId spId, +RgrCfgTransId transId, +U8 status +) +#else +PUBLIC S16 rgSCHUtlRgrSiCfgCfm(instId, spId, transId, status) +Inst instId; +SpId spId; +RgrCfgTransId transId; +U8 status; +#endif +{ + U8 prntTrans[RGR_CFG_TRANSID_SIZE+1]; + + TRC2(rgSCHUtlRgrSiCfgCfm) + + cmMemcpy((U8 *)prntTrans, (U8 *)transId.trans, RGR_CFG_TRANSID_SIZE); + prntTrans[RGR_CFG_TRANSID_SIZE] = '\0'; + + + if(RgUiRgrSiCfgCfm(&rgSchCb[instId].rgrSap[spId].sapCfg.sapPst, + rgSchCb[instId].rgrSap[spId].sapCfg.suId, + transId, status) != ROK) + { + RLOG_ARG0(L_ERROR,DBG_INSTID,instId,"rgSCHUtlRgrSiCfgCfm: " + "RgUiRgrSiCfgCfm Failed "); + RETVALUE(RFAILED); + } + + RETVALUE(ROK); +} /* rgSCHUtlRgrSiCfgCfm */ + + +/** + * @brief API for sending Warning SI configuration confirm from + * Scheduler to RRM + * + * @details + * + * + * This API is invoked to send Warning SI configuration confirm + * from Scheduler to RRM. + * This API fills in Pst structure and SAP Ids and invokes + * config confirm API towards RRM. + * + * @param[in] RgrCfgTransId transId + * @param[in] U8 status + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 rgSCHUtlRgrWarningSiCfgCfm +( +Inst instId, +SpId spId, +U8 siId, +RgrCfgTransId transId, +U8 status +) +#else +PUBLIC S16 rgSCHUtlRgrWarningSiCfgCfm(instId, spId, siId, transId, status) +Inst instId; +SpId spId; +U8 siId; +RgrCfgTransId transId; +U8 status; +#endif +{ + U8 prntTrans[RGR_CFG_TRANSID_SIZE+1]; + + TRC2(rgSCHUtlRgrWarningSiCfgCfm) + + cmMemcpy((U8 *)prntTrans, (U8 *)transId.trans, RGR_CFG_TRANSID_SIZE); + prntTrans[RGR_CFG_TRANSID_SIZE] = '\0'; + + + if(RgUiRgrWarningSiCfgCfm(&rgSchCb[instId].rgrSap[spId].sapCfg.sapPst, + rgSchCb[instId].rgrSap[spId].sapCfg.suId, + transId, siId, status) != ROK) + { + RLOG_ARG0(L_ERROR,DBG_INSTID,instId,"rgSCHUtlRgrSiCfgCfm: " + "RgUiRgrSiCfgCfm Failed "); + RETVALUE(RFAILED); + } + + RETVALUE(ROK); +} /* rgSCHUtlRgrWarningSiCfgCfm */ + +/*********************************************************** + * + * Func : rgSCHUtlPutSiInfo + * + * Desc : Utility Function to deallocate SI information + * + * + * RFAILED + * + * + * File : rg_utl.c + * + **********************************************************/ +#ifdef ANSI +PUBLIC Void rgSCHUtlPutSiInfo +( +RgSchCellCb *cell +) +#else +PUBLIC Void rgSCHUtlPutSiInfo(cell) +RgSchCellCb *cell; +#endif +{ + U8 idx = 0; + U32 sizeOfSiInfo = 0; + TRC2(rgSCHUtlPutSiInfo) + /*Free the buffers in crntSiInfo*/ + RGSCH_FREE_MSG(cell->siCb.crntSiInfo.mib) + RGSCH_FREE_MSG(cell->siCb.crntSiInfo.sib1Info.sib1) + + sizeOfSiInfo = sizeof(cell->siCb.crntSiInfo.siInfo)/sizeof(cell->siCb.crntSiInfo.siInfo[0]); + + for(idx=0; idx < sizeOfSiInfo; idx++) + { + RGSCH_FREE_MSG(cell->siCb.crntSiInfo.siInfo[idx].si) + } + + /*Free the buffers in newSiInfo */ + RGSCH_FREE_MSG(cell->siCb.newSiInfo.mib) + RGSCH_FREE_MSG(cell->siCb.newSiInfo.sib1Info.sib1) + + sizeOfSiInfo = sizeof(cell->siCb.newSiInfo.siInfo)/sizeof(cell->siCb.newSiInfo.siInfo[0]); + + for(idx=0; idx < sizeOfSiInfo; idx++) + { + RGSCH_FREE_MSG(cell->siCb.newSiInfo.siInfo[idx].si) + } + + RETVOID; +} +#endif /*RGR_SI_SCH */ + + + +/*********************************************************** + * + * Func : rgSCHUtlGetDrxSchdUesInDl + * + * Desc : Utility Function to fill the get the list of + * scheduled UEs. On these UE's, drx-inactivity + * timer will be started/restarted. + * + * Ret : ROK + * RFAILED + * + * Notes: + * + * File : rg_utl.c + * + **********************************************************/ +#ifdef ANSI +PUBLIC S16 rgSCHUtlGetDrxSchdUesInDl +( +RgSchCellCb *cellCb, +RgSchUeCb *ueCb, +RgSchDlHqProcCb *dlHq, +RgInfUeAlloc *allocInfo, +CmLListCp *dlDrxInactvTmrLst, +CmLListCp *dlInActvLst, +CmLListCp *ulInActvLst +) +#else +PUBLIC S16 rgSCHUtlGetDrxSchdUesInDl(cellCb, ueCb, dlHq, allocInfo, dlDrxInactvTmrLst, dlInActvLst, ulInActvLst) +RgSchCellCb *cellCb; +RgSchUeCb *ueCb; +RgSchDlHqProcCb *dlHq; +RgInfUeAlloc *allocInfo; +CmLListCp *dlDrxInactvTmrLst; +CmLListCp *dlInActvLst; +CmLListCp *ulInActvLst; +#endif +{ + Bool isNewTx = FALSE; + U8 idx; + RgSchDrxDlHqProcCb *drxHq; + RgSchDRXCellCb *drxCell = cellCb->drxCb; + RgSchDrxUeCb *drxUe; +#ifdef DEBUGP + Inst inst = cellCb->instIdx; +#endif + U8 cellIdx = ueCb->cellIdToCellIdxMap[RG_SCH_CELLINDEX(dlHq->hqE->cell)]; + U32 dlInactvMask; + U32 ulInactvMask; + + for(idx = 0; idx < allocInfo->nmbOfTBs; idx++) + { + if(allocInfo->tbInfo[idx].isReTx == FALSE) + { + isNewTx = TRUE; + /* Removing break here, since in 2 TB case if 2nd TB is proceeding with + retx then drxretx timer should be stopped.*/ + } + else + { + /*Stop the DRX retransmission timer as UE scheduled for retx. Here + * we stop the timer and inactivate the UE for both UL and DL. + * This may result in loss of one subframe for UL but this trade + * off is taken to avoid the overhead of maintaining a list of UEs + * to be inactivated in the next subframe.*/ + drxHq = RG_SCH_DRX_GET_DL_HQ(dlHq); + drxUe = RG_SCH_DRX_GET_UE(ueCb); + if(drxHq->reTxIndx != DRX_INVALID) + { + /* This condition should never occur */ + if(drxHq->reTxIndx >= RG_SCH_MAX_DRXQ_SIZE) + { + RGSCHDBGERRNEW(inst,(rgSchPBuf(inst),"[%d]UE:DRXUE RETX IDX[%d]" + "is out of bound,dlInactvMask %d,procId %d\n", ueCb->ueId, + drxHq->reTxIndx,ueCb->dl.dlInactvMask, dlHq->procId)); + } + + drxUe->drxDlInactvMaskPerCell[cellIdx] |= (RG_SCH_DRX_DLHQ_BITMASK << dlHq->procId); + drxUe->drxUlInactvMaskPerCell[cellIdx] |= (RG_SCH_DRX_DLHQ_BITMASK << dlHq->procId); + + dlInactvMask = RG_SCH_DRX_DLHQ_BITMASK << dlHq->procId; + ulInactvMask = RG_SCH_DRX_DLHQ_BITMASK << dlHq->procId; + + for(cellIdx = 0; cellIdx < CM_LTE_MAX_CELLS; cellIdx++) + { + dlInactvMask &= drxUe->drxDlInactvMaskPerCell[cellIdx]; + ulInactvMask &= drxUe->drxUlInactvMaskPerCell[cellIdx]; + } + + drxUe->drxDlInactvMask |= dlInactvMask; + drxUe->drxUlInactvMask |= ulInactvMask; + + /* if no other condition is keeping ue active, + * inactivate the Ue + */ + if(!RG_SCH_DRX_DL_IS_UE_ACTIVE(drxUe)) + { + /* BUG 2 : HARQ_RTT, changed for consistency */ + ueCb->dl.dlInactvMask |= (RG_DRX_INACTIVE); + + /* Add to DL inactive list */ + cmLListAdd2Tail(dlInActvLst,&(ueCb->dlDrxInactvLnk)); + ueCb->dlDrxInactvLnk.node = (PTR)ueCb; + } + + if(!RG_SCH_DRX_UL_IS_UE_ACTIVE(drxUe)) + { + /*BUG 2: HARQ_RTT changed for consistency */ + ueCb->ul.ulInactvMask |= (RG_DRX_INACTIVE); + + cmLListAdd2Tail(ulInActvLst,&(ueCb->ulDrxInactvLnk)); + ueCb->ulDrxInactvLnk.node = (PTR)ueCb; + } + + /* Deleting entry from HARQ RTT queue for the same HARQ proc, + * if exist. This is the special case which can happen iF UL + * scheduling is done later. */ + if(drxHq->rttIndx != DRX_INVALID) + { + cmLListDelFrm (&(cellCb->drxCb->drxQ[drxHq->rttIndx].harqRTTQ), + &(drxHq->harqRTTEnt)); + + drxHq->rttIndx = DRX_INVALID; + } + + cmLListDelFrm (&(drxCell->drxQ[drxHq->reTxIndx].harqRetxQ), + &(drxHq->harqRetxEnt)); + drxHq->reTxIndx = DRX_INVALID; + } + } + } + + if(isNewTx == TRUE) + { + if(ueCb->drxCb->raRcvd == TRUE) + { + ueCb->drxCb->raRcvd = FALSE; + + /* mark the ra bit */ + ueCb->drxCb->drxUlInactvMask |= RG_SCH_DRX_RA_BITMASK; + ueCb->drxCb->drxDlInactvMask |= RG_SCH_DRX_RA_BITMASK; + + }/*if(ra->rcvd) == TRUE */ + + if(ueCb->dlDrxInactvTmrLnk.node == NULLP) + { + cmLListAdd2Tail(dlDrxInactvTmrLst,&(ueCb->dlDrxInactvTmrLnk)); + ueCb->dlDrxInactvTmrLnk.node = (PTR)ueCb; + } + }/*if(isNewTx == TRUE) */ + + RETVALUE(ROK); +}/* rgSCHUtlGetSchdUes*/ + +/* ccpu00117452 - MOD - Changed macro name from + RGR_RRM_DLPWR_CNTRL to RGR_CQI_REPT */ +#ifdef RGR_CQI_REPT +/** + * @brief This function fills StaInd struct + * + * @details + * + * Function: rgSCHUtlFillSndStaInd + * Purpose: Fills StaInd struct and sends the + * StaInd to RRM + * + * @param[in] RgSchCellCb *cell pointer to Cell Control block + * @param[in] RgSchUeCb *ue pointer to Ue Control block + * @param[in] RgrStaIndInfo *staInfo Sta Ind struct to be filled + * @param[in] U8 numCqiRept NUmber of reports to be filled + * @return Void + * + **/ +#ifdef ANSI +PUBLIC S16 rgSCHUtlFillSndStaInd +( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgrStaIndInfo *staInfo, +U8 numCqiRept +) +#else +PUBLIC S16 rgSCHUtlFillSndStaInd(cell, ue, staInfo, numCqiRept) +RgSchCellCb *cell; +RgSchUeCb *ue; +RgrStaIndInfo *staInfo; +U8 numCqiRept; +#endif +{ + U8 idxStart; + + /* Fill StaInd for sending collated Latest N CQI rpeorts */ + /* Find index in the array from where Latest N + reports needs to be fetched. Use this value to index in the array + and copy the reports into staInfo */ + + /* Fill the Cell Id of PCC of the UE */ + staInfo->cellId = ue->cell->cellId; + staInfo->crnti = ue->ueId; + + idxStart = ue->schCqiInfo.cqiCount - numCqiRept; + + cmMemcpy ((U8*)&(staInfo->ueCqiInfo.cqiRept), + (U8*)&(ue->schCqiInfo.cqiRept[idxStart]), + numCqiRept * sizeof(RgrUeCqiRept)); + + staInfo->ueCqiInfo.numCqiRept = numCqiRept; + + ue->schCqiInfo.cqiCount = 0; + + /* Call utility function (rgSCHUtlRgrStaInd) to send rpts to RRM */ + if(rgSCHUtlRgrStaInd(cell, staInfo) != ROK) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,"Could not send " + "CQI reports for RNTI:%d",ue->ueId); + RETVALUE(RFAILED); + } + + RETVALUE(ROK); + +}/* End of rgSCHUtlFillSndStaInd */ + + + +/** + * @brief API for sending STA indication from Scheduler to RRM. + * + * @details + * + * Function: rgSCHUtlRgrStaInd + * + * This API is invoked to send STA indication from Scheduler instance to RRM. + * This API fills in Pst structure and RgrStaIndInfo + * and calls the Sta primitive API towards RRM. + * + * @param[in] cell RgSchCellCb + * @param[in] RgrStsIndInfo *rgrSta + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 rgSCHUtlRgrStaInd +( +RgSchCellCb *cell, +RgrStaIndInfo *rgrSta +) +#else +PUBLIC S16 rgSCHUtlRgrStaInd(cell, rgrSta) +RgSchCellCb *cell; +RgrStaIndInfo *rgrSta; +#endif +{ + S16 ret = ROK; + RgSchUpSapCb *rgrSap; /*!< RGR SAP Control Block */ + + TRC2(rgSCHUtlRgrStaInd) + + + rgrSap = cell->rgrSap; + if (rgrSap->sapSta.sapState != LRG_BND) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId, + "rgSCHUtlRgrStaInd() Upper SAP not bound (%d) ", + rgrSap->sapSta.sapState); + RETVALUE(RFAILED); + } + RgUiRgrStaInd(&(cell->rgrSap->sapCfg.sapPst), + cell->rgrSap->sapCfg.suId, rgrSta); + RETVALUE(ret); +} /* rgSCHUtlRgrStaInd*/ +#endif /* End of RGR_CQI_REPT */ + +/* Fix : syed HO UE does not have a valid ue->rntiLnk */ +/** + * @brief Indicates MAC to release any rnti context it has. + * + * @details + * Function : rgSCHUtlIndRntiRls2Mac + * This function indicates MAC for this rnti release. + * In case of ueId change it will indicate MAC + * about the new rnti to be updated. + * It will post a release RNTI indication to MAC. + * + * + * + * @param[in] RgSchCellCb *cell + * @param[in] CmLteRnti rnti + * @param[in] Bool ueIdChng + * @param[in] CmLteRnti newRnti + * @return Void + * -# ROK + **/ +#ifdef ANSI +PUBLIC Void rgSCHUtlIndRntiRls2Mac +( +RgSchCellCb *cell, +CmLteRnti rnti, +Bool ueIdChng, +CmLteRnti newRnti +) +#else +PUBLIC Void rgSCHUtlIndRntiRls2Mac(cell, rnti, ueIdChng, newRnti) +RgSchCellCb *cell; +CmLteRnti rnti; +Bool ueIdChng; +CmLteRnti newRnti; +#endif +{ + Pst pst; + Inst inst = cell->instIdx; + RgInfRlsRnti rntiInfo; + + TRC2(rgSCHUtlIndRntiRls2Mac) + + /* Copy the info to rntiInfo */ + rntiInfo.cellId = cell->cellId; + rntiInfo.rnti = rnti; + /* Fix : syed ueId change as part of reestablishment. + * Now SCH to trigger this. CRG ueRecfg for ueId change + * is dummy */ + rntiInfo.ueIdChng = ueIdChng; + rntiInfo.newRnti = newRnti; +#ifdef LTE_ADV + rntiInfo.isUeSCellDel = FALSE; +#endif + /* Invoke MAC to release the rnti */ + rgSCHUtlGetPstToLyr(&pst, &rgSchCb[inst], cell->macInst); + RgSchMacRlsRnti(&pst, &rntiInfo); + RETVOID; +} + +/* LTE_ADV_FLAG_REMOVED_START */ +/** + * @brief API for sending LOAD INF indication from Scheduler to RRM. + * @details + * + * Function: rgSCHUtlRgrLoadInfInd + * + * This API is invoked to send LOAD INF indication from Scheduler instance to RRM. + * This API fills in Pst structure and RgrLoadInfIndInfo + * and calls the Sta primitive API towards RRM. + * + * @param[in] cell RgSchCellCb + * @param[in] RgrLoadInfIndInfo *rgrLoadInf + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 rgSCHUtlRgrLoadInfInd +( + RgSchCellCb *cell, + RgrLoadInfIndInfo *rgrLoadInf + ) +#else +PUBLIC S16 rgSCHUtlRgrLoadInfInd(cell, rgrLoadInf) + RgSchCellCb *cell; + RgrLoadInfIndInfo *rgrLoadInf; +#endif +{ + S16 ret = ROK; + RgSchUpSapCb *rgrSap; /*!< RGR SAP Control Block */ + + TRC2(rgSCHUtlRgrLoadInfInd) + + + rgrSap = cell->rgrSap; + if (rgrSap->sapSta.sapState != LRG_BND) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId, + "rgSCHUtlRgrLoadInfInd() Upper SAP not bound (%d) ", + rgrSap->sapSta.sapState); + RETVALUE(RFAILED); + } + RgUiRgrLoadInfInd(&(cell->rgrSap->sapCfg.sapPst), + cell->rgrSap->sapCfg.suId, rgrLoadInf); + RETVALUE(ret); +} /* rgSCHUtlRgrLoadInfInd*/ +/* LTE_ADV_FLAG_REMOVED_END */ + +/* MS_FIX : syed SCH to act as MASTER in maintaining + * rnti related context. Trigger to rnti del/Chng at SCH + * will result in a Indication to MAC to release its + * RNTI context. MAC inturn indicates the context cleared + * indication to SCH, upon which SCH would set this +/** + * @brief API for sending STA indication from Scheduler to RRM. + * + * @details + * + * Function: rgSCHUtlRlsRnti + * + * This API is invoked to indicate MAC to release rnti + * + * @param[in] RgSchCellCb *cellCb + * @param[in] RgSchRntiLnk *rntiLnk, + * @param[in] Bool ueIdChngd, + * @param[in] CmLteRnti newRnti + * @return Void + **/ + +#ifdef ANSI +PUBLIC Void rgSCHUtlRlsRnti +( +RgSchCellCb *cell, +RgSchRntiLnk *rntiLnk, +Bool ueIdChngd, +CmLteRnti newRnti +) +#else +PUBLIC Void rgSCHUtlRlsRnti(cell, rntiLnk, ueIdChngd, newRnti) +RgSchCellCb *cell; +RgSchRntiLnk *rntiLnk; +Bool ueIdChngd; +CmLteRnti newRnti; +#endif +{ + + TRC2(rgSCHUtlRlsRnti) + U8 isLegacy = 0; +#ifdef EMTC_ENABLE + if(cell->emtcEnable) + { + rgSCHEmtcUtlRlsRnti(cell, rntiLnk, &isLegacy); + } +#endif + if(!isLegacy) + { + /*Add to Guard Pool*/ + cmLListAdd2Tail(&cell->rntiDb.rntiGuardPool, &rntiLnk->rntiGrdPoolLnk); + rntiLnk->rntiGrdPoolLnk.node = (PTR)rntiLnk; + } + /* Fix: syed Explicitly Inidcate MAC to release RNTI */ + rgSCHUtlIndRntiRls2Mac(cell, rntiLnk->rnti, ueIdChngd, newRnti); + + RETVOID; +} + + +/** + * @brief This function fills StaInd struct + * + * @details + * + * Function: rgSCHUtlFillSndUeStaInd + * Purpose: Fills StaInd struct and sends the + * StaInd to RRM + * + * @param[in] RgSchCellCb *cell pointer to Cell Control block + * @param[in] RgSchUeCb *ue pointer to Ue Control block + * @param[in] U8 numCqiRept NUmber of reports to be filled + * @return Void + * + **/ +#ifdef ANSI +PUBLIC S16 rgSCHUtlFillSndUeStaInd +( +RgSchCellCb *cell, +RgSchUeCb *ue, +RgrUeStaIndInfo *ueStaInfo +) +#else +PUBLIC S16 rgSCHUtlFillSndUeStaInd(cell, ue, ueStaInfo) +RgSchCellCb *cell; +RgSchUeCb *ue; +RgrUeStaIndInfo *ueStaInfo; +#endif +{ + + ueStaInfo->cellId = cell->cellId; + ueStaInfo->crnti = ue->ueId; + + /* Call utility function (rgSCHUtlRgrUeStaInd) to send rpts to RRM */ + if(rgSCHUtlRgrUeStaInd(cell, ueStaInfo) != ROK) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,"Could not send " + "UE Sta reports CRNTI:%d",ue->ueId); + RETVALUE(RFAILED); + } + + RETVALUE(ROK); + +}/* End of rgSCHUtlFillSndStaInd */ + + + +/** + * @brief API for sending STA indication from Scheduler to RRM. + * + * @details + * + * Function: rgSCHUtlRgrStaInd + * + * This API is invoked to send STA indication from Scheduler instance to RRM. + * This API fills in Pst structure and RgrStaIndInfo + * and calls the Sta primitive API towards RRM. + * + * @param[in] cell RgSchCellCb + * @param[in] RgrStsIndInfo *rgrSta + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 rgSCHUtlRgrUeStaInd +( +RgSchCellCb *cell, +RgrUeStaIndInfo *rgrUeSta +) +#else +PUBLIC S16 rgSCHUtlRgrUeStaInd(cell, rgrUeSta) +RgSchCellCb *cell; +RgrUeStaIndInfo *rgrUeSta; +#endif +{ + S16 ret = ROK; + RgSchUpSapCb *rgrSap; /*!< RGR SAP Control Block */ + + TRC2(rgSCHUtlRgrStaInd) + + + rgrSap = cell->rgrSap; + if (rgrSap->sapSta.sapState != LRG_BND) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId, + "rgSCHUtlRgrUeStaInd() Upper SAP not bound (%d) ", + rgrSap->sapSta.sapState); + RETVALUE(RFAILED); + } + RgUiRgrUeStaInd(&(cell->rgrSap->sapCfg.sapPst), + cell->rgrSap->sapCfg.suId, rgrUeSta); + RETVALUE(ret); +} /* rgSCHUtlRgrStaInd*/ + +/* RRM_RBC_X */ +/** + * @brief function to report DL and UL PRB usage to RRM. + * + * + * Function: rgSCHUtlUpdAvgPrbUsage + * This function sends the PRB usage report to + * RRM with the interval configured by RRM. + * + * @param[in] cell *RgSchCellCb + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 rgSCHUtlUpdAvgPrbUsage +( +RgSchCellCb *cell +) +#else +PUBLIC S16 rgSCHUtlUpdAvgPrbUsage(cell) +RgSchCellCb *cell; +#endif +{ + CmLteTimingInfo frm; + RgmPrbRprtInd *prbRprtInd; + S16 ret = ROK; + U32 idx; +#ifdef DBG_MAC_RRM_PRB_PRINT + static U32 count = 0; + const U32 reprotForEvery20Sec = 20000/cell->prbUsage.rprtPeriod; + + count++; +#endif + + TRC2(rgSCHUtlUpdAvgPrbUsage); + + frm = cell->crntTime; + RGSCH_INCR_SUB_FRAME(frm, RG_SCH_CMN_DL_DELTA); + + U16 numDlSf; + U16 numUlSf; +#ifdef LTE_TDD + + if(cell->prbUsage.rprtPeriod >= RGSCH_NUM_SUB_FRAMES) + { + /* Get the total number of DL and UL subframes within the reporting period*/ + numDlSf = (cell->prbUsage.rprtPeriod * + rgSchTddNumDlSubfrmTbl[cell->ulDlCfgIdx][RGSCH_NUM_SUB_FRAMES-1]) + / RGSCH_NUM_SUB_FRAMES; + numUlSf = (cell->prbUsage.rprtPeriod * + rgSchTddNumUlSubfrmTbl[cell->ulDlCfgIdx][RGSCH_NUM_SUB_FRAMES-1]) + / RGSCH_NUM_SUB_FRAMES; + } + else + { + /* Get the total number of DL and UL subframes < 10 ms interval */ + numDlSf = rgSchTddNumDlSubfrmTbl[cell->ulDlCfgIdx][frm.subframe]; + numUlSf = rgSchTddNumUlSubfrmTbl[cell->ulDlCfgIdx][frm.subframe]; + } +#else + numDlSf = cell->prbUsage.rprtPeriod; + numUlSf = cell->prbUsage.rprtPeriod; +#endif + + if(SGetSBuf(cell->rgmSap->sapCfg.sapPst.region, + cell->rgmSap->sapCfg.sapPst.pool, (Data**)&prbRprtInd, + sizeof(RgmPrbRprtInd)) != ROK) + { + RETVALUE(RFAILED); + } + + cmMemset((U8 *) &prbRprtInd->stQciPrbRpts[0], + 0, + (RGM_MAX_QCI_REPORTS * sizeof(RgmPrbRptPerQci))); + + prbRprtInd->bCellId = cell->cellId; + + if(numDlSf > 0) + { + prbRprtInd->bPrbUsageMask |= RGM_PRB_USAGE_DL; + for (idx = 0; idx < RGM_MAX_QCI_REPORTS; idx++ ) + { + prbRprtInd->stQciPrbRpts[idx].bAvgPrbDlUsage = + RGSCH_DIV_ROUND((cell->prbUsage.qciPrbRpts[idx].dlTotPrbUsed*100), + (numDlSf * cell->bwCfg.dlTotalBw)); + prbRprtInd->stQciPrbRpts[idx].bQci = cell->prbUsage.qciPrbRpts[idx].qci; + cell->prbUsage.qciPrbRpts[idx].dlTotPrbUsed = 0; + } + } + + if(numUlSf > 0) + { + prbRprtInd->bPrbUsageMask |= RGM_PRB_USAGE_UL; + for (idx = 0; idx < RGM_MAX_QCI_REPORTS; idx++ ) + { + prbRprtInd->stQciPrbRpts[idx].bAvgPrbUlUsage = + RGSCH_DIV_ROUND((cell->prbUsage.qciPrbRpts[idx].ulTotPrbUsed*100), + (numUlSf * cell->ulAvailBw)); + prbRprtInd->stQciPrbRpts[idx].bQci = cell->prbUsage.qciPrbRpts[idx].qci; + cell->prbUsage.qciPrbRpts[idx].ulTotPrbUsed = 0; + } + } + +#ifdef DBG_MAC_RRM_PRB_PRINT + if((count % reprotForEvery20Sec) == 0 ) + { + printf("\n===================================================================="); + printf("\nMAC: QCI-1[DL:UL] | QCI-2[DL:UL] | QCI-3[DL:UL] | QCI-4[DL:UL] \n"); + printf("======================================================================\n"); + printf(" [%d: %d]\t | [%d: %d]\t | [%d: %d]\t| [%d: %d]\t\n", + prbRprtInd->stQciPrbRpts[0].bAvgPrbDlUsage, + prbRprtInd->stQciPrbRpts[0].bAvgPrbUlUsage, + prbRprtInd->stQciPrbRpts[1].bAvgPrbDlUsage, + prbRprtInd->stQciPrbRpts[1].bAvgPrbUlUsage, + prbRprtInd->stQciPrbRpts[2].bAvgPrbDlUsage, + prbRprtInd->stQciPrbRpts[2].bAvgPrbUlUsage, + prbRprtInd->stQciPrbRpts[3].bAvgPrbDlUsage, + prbRprtInd->stQciPrbRpts[3].bAvgPrbUlUsage); + } +#endif + RgUiRgmSendPrbRprtInd(&(cell->rgmSap->sapCfg.sapPst), + cell->rgmSap->sapCfg.suId, prbRprtInd); + + + RETVALUE(ret); +} +/* RRM_RBC_Y */ + +/** + * @brief This function resends the Ta in case of + * max retx failure or DTX for the Ta transmitted + * + * @details + * + * Function: rgSCHUtlReTxTa + * Purpose: + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ue + * @return Void + * + **/ +#ifdef ANSI +PUBLIC Void rgSCHUtlReTxTa +( +RgSchCellCb *cellCb, +RgSchUeCb *ueCb +) +#else +PUBLIC Void rgSCHUtlReTxTa(cellCb, ueCb) +RgSchCellCb *cellCb; +RgSchUeCb *ueCb; +#endif +{ + TRC2(rgSCHUtlReTxTa) + + /* If TA Timer is running. Stop it */ + if (ueCb->taTmr.tmrEvnt != TMR_NONE) + { + rgSCHTmrStopTmr(cellCb, ueCb->taTmr.tmrEvnt, ueCb); + } + /*[ccpu00121813]-ADD-If maxretx is reached then + * use outstanding TA val for scheduling again */ + if(ueCb->dl.taCb.outStndngTa == TRUE) + { + ueCb->dl.taCb.ta = ueCb->dl.taCb.outStndngTaval; + ueCb->dl.taCb.outStndngTaval = RGSCH_NO_TA_RQD; + ueCb->dl.taCb.outStndngTa = FALSE; + + } + /* Fix : syed TA state updation missing */ + ueCb->dl.taCb.state = RGSCH_TA_TOBE_SCHEDULED; + rgSCHUtlDlTARpt(cellCb, ueCb); + + RETVOID; +} + +/* Added function for dropping Paging Message*/ +/** + * @brief Handler for BO Updt received for BCCH or PCCH. + * + * @details + * + * Function : rgSCHChkBoUpdate + * + * This function shall check for BO received falls within the scheduling window or not + * + * + * @param[in] RgSchCellCb *cell + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PRIVATE S16 rgSCHChkBoUpdate +( +RgSchCellCb *cell, +RgInfCmnBoRpt *boUpdt +) +#else +PRIVATE S16 rgSCHChkBoUpdate (cell, boUpdt) +RgSchCellCb *cell; +RgInfCmnBoRpt *boUpdt; +#endif +{ + + U32 crntTimeInSubFrms = 0; + U32 boUpdTimeInSubFrms = 0; + U32 distance = 0; + TRC2(rgSCHChkBoUpdate); + + crntTimeInSubFrms = (cell->crntTime.sfn * RGSCH_NUM_SUB_FRAMES_5G) + cell->crntTime.subframe + + RG_SCH_CMN_DL_DELTA + 2; /* As bo received will scheduled in next TTI + so incrementing with +1 more */ + boUpdTimeInSubFrms = (boUpdt->u.timeToTx.sfn * RGSCH_NUM_SUB_FRAMES_5G)+ boUpdt->u.timeToTx.subframe; + + + distance = boUpdTimeInSubFrms > crntTimeInSubFrms ? \ + boUpdTimeInSubFrms - crntTimeInSubFrms : \ + (RGSCH_MAX_SUBFRM_5G - crntTimeInSubFrms + boUpdTimeInSubFrms); + + if (distance > RGSCH_PCCHBCCH_WIN) + { + RETVALUE(RFAILED); + } + RETVALUE(ROK); + +}/*rgSCHChkBoUpdate*/ + + +#ifdef LTE_TDD +/** + * @brief Utility function to calculate the UL reTxIdx in TDD cfg0 + * + * @details + * + * Function : rgSchUtlCfg0ReTxIdx + * + * Update the reTxIdx according to the rules mentioned + * in 3GPP TS 36.213 section 8 for TDD Cfg0 + * + * @param[in] RgSchCellCb *cell + * @param[in] CmLteTimingInfo phichTime + * @param[in] U8 hqFdbkIdx + * @return U8 + **/ +#ifdef ANSI +PUBLIC U8 rgSchUtlCfg0ReTxIdx +( +RgSchCellCb *cell, +CmLteTimingInfo phichTime, +U8 hqFdbkIdx +) +#else +PUBLIC U8 rgSchUtlCfg0ReTxIdx (cell, phichTime, hqFdbkIdx) +RgSchCellCb *cell; +CmLteTimingInfo phichTime; +U8 hqFdbkIdx; +#endif +{ + U8 reTxIdx = RGSCH_INVALID_INFO; + U8 iPhich = 0; + RgSchCmnUlCell *cellUl = RG_SCH_CMN_GET_UL_CELL(cell); + RgSchUlSf *ulSf; + U8 ulSF; /* UL SF in the TDD frame */ + + TRC2(rgSchUtlCfg0ReTxIdx); + + ulSf = &cellUl->ulSfArr[hqFdbkIdx]; + ulSF = ulSf->ulSfIdx; + + /* Check for the UL SF 4 or 9 */ + if(ulSF == 9 || ulSF == 4) + { + iPhich = 1; + } + if(phichTime.subframe == 0 || phichTime.subframe == 5) + { + if(iPhich == 0) + { + /* Retx will happen according to the Pusch k table */ + reTxIdx = cellUl->schdIdx; + } + if(iPhich == 1) + { + /* Retx will happen at n+7 */ + RGSCHCMNADDTOCRNTTIME(phichTime, phichTime, 7); + /* Fetch the corresponding UL subframe Idx in UL sf array */ + reTxIdx = rgSCHCmnGetUlSfIdx(&phichTime, cell); + } + } + else if(phichTime.subframe == 1 || phichTime.subframe == 6) + { + /* Retx will happen at n+7 */ + RGSCHCMNADDTOCRNTTIME(phichTime, phichTime, 7); + /* Fetch the corresponding UL subframe Idx in UL sf array */ + reTxIdx = rgSCHCmnGetUlSfIdx(&phichTime, cell); + } + RETVALUE(reTxIdx); +} +#endif + +/** + * @brief Utility function to calculate total num of PRBs required to + * satisfy DL BO for TM1/TM2/TM6/TM7 + * + * @details + * + * Function : rgSchUtlDlCalc1CwPrb + * + * Calculate PRBs required for UE to satisfy BO in DL + * + * Note : Total calculated PRBs will be assigned to *prbReqrd + * + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ue + * @param[in] U32 bo + * @param[out] U32 *prbReqrd + * @return Void + **/ +#ifdef ANSI +PUBLIC Void rgSchUtlDlCalc1CwPrb +( +RgSchCellCb *cell, +RgSchUeCb *ue, +U32 bo, +U32 *prbReqrd +) +#else +PUBLIC Void rgSchUtlDlCalc1CwPrb(cell, ue, bo, prbReqrd) +RgSchCellCb *cell; +RgSchUeCb *ue; +U32 bo; +U32 *prbReqrd; +#endif +{ + RgSchCmnDlCell *dlCell = RG_SCH_CMN_GET_DL_CELL(cell); + RgSchCmnDlUe *dlUe = RG_SCH_CMN_GET_DL_UE(ue, cell); + U32 eff; + U32 noRes; + U8 iTbs; + U8 cfi = dlCell->currCfi; + + TRC2(rgSchUtlDlCalc1CwPrb); + + iTbs = dlUe->mimoInfo.cwInfo[0].iTbs[0]; + eff = (*(RgSchCmnTbSzEff *)(dlCell->cqiToEffTbl[0][cfi]))[iTbs]; + + /* Optimization to convert totalBo (which is in-terms of bytes) to bits + * i.e, << 3 and multiply with 1024 i.e, << 10 */ + noRes = ((U64)((bo << 3) << 10)) / (eff); + /* Get the number of RBs needed for this transmission */ + /* Number of RBs = No of REs / No of REs per RB */ + *prbReqrd = RGSCH_CEIL(noRes, dlCell->noResPerRb[cfi]); + + RETVOID; +} /* rgSchUtlDlCalc1CwPrb*/ + +/** + * @brief Utility function to calculate total num of PRBs required to + * satisfy DL BO(BO sum of all logical channels for that UE or an LC BO) + * for TM3/TM4 + * + * @details + * + * Function : rgSchUtlDlCalc2CwPrb + * + * Calculate PRBs required for UE to satisfy BO in DL + * + * Note : Total calculated PRBs will be assigned to *prbReqrd + * + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ue + * @param[in] U32 bo + * @param[out] U32 *prbReqrd + * @return Void + **/ +#ifdef ANSI +PUBLIC Void rgSchUtlDlCalc2CwPrb +( +RgSchCellCb *cell, +RgSchUeCb *ue, +U32 bo, +U32 *prbReqrd +) +#else +PUBLIC Void rgSchUtlDlCalc2CwPrb(cell, ue, bo, prbReqrd) +RgSchCellCb *cell; +RgSchUeCb *ue; +U32 bo; +U32 *prbReqrd; +#endif +{ + RgSchCmnDlCell *dlCell = RG_SCH_CMN_GET_DL_CELL(cell); + RgSchCmnDlUe *dlUe = RG_SCH_CMN_GET_DL_UE(ue, cell); + U32 eff1, eff2; + U32 noRes; + U8 noLyr1, noLyr2; + U8 iTbs1, iTbs2; + U8 cfi = dlCell->currCfi; + + TRC2(rgSchUtlDlCalc2CwPrb); + + if ((dlUe->mimoInfo.forceTD) ||/* Transmit Diversity (TD) */ + (dlUe->mimoInfo.ri < 2))/* 1 layer precoding */ + { + iTbs1 = dlUe->mimoInfo.cwInfo[0].iTbs[0]; + eff1 = (*(RgSchCmnTbSzEff *)(dlCell->cqiToEffTbl[0][cfi]))[iTbs1]; + + /* Optimization to convert totalBo (which is in-terms of bytes) to bits + * i.e, << 3 and multiply with 1024 i.e, << 10 */ + noRes = ((U64)((bo << 3) << 10)) / (eff1); + /* Get the number of RBs needed for this transmission */ + /* Number of RBs = No of REs / No of REs per RB */ + *prbReqrd = RGSCH_CEIL(noRes, dlCell->noResPerRb[cfi]); + } + else + { + noLyr1 = dlUe->mimoInfo.cwInfo[0].noLyr; + noLyr2 = dlUe->mimoInfo.cwInfo[1].noLyr; + iTbs1 = dlUe->mimoInfo.cwInfo[0].iTbs[noLyr1 - 1]; + iTbs2 = dlUe->mimoInfo.cwInfo[1].iTbs[noLyr2 - 1]; + eff1 = (*(RgSchCmnTbSzEff *)(dlCell->cqiToEffTbl[noLyr1 - 1][cfi]))[iTbs1]; + eff2 = (*(RgSchCmnTbSzEff *)(dlCell->cqiToEffTbl[noLyr2 - 1][cfi]))[iTbs2]; + + /* Optimization to convert totalBo (which is in-terms of bytes) to bits + * i.e, << 3 and multiply with 1024 i.e, << 10 */ + noRes = ((U64)((bo << 3) << 10)) / (eff1 + eff2); + /* Get the number of RBs needed for this transmission */ + /* Number of RBs = No of REs / No of REs per RB */ + *prbReqrd = RGSCH_CEIL(noRes, dlCell->noResPerRb[cfi]); + } + RETVOID; +} /* rgSchUtlDlCalc2CwPrb */ + +/** + * @brief Utility function to calculate total num of PRBs required to + * satisfy DL BO(BO sum of all logical channels for that UE or an LC BO) + * + * @details + * + * Function : rgSchUtlCalcTotalPrbReq + * + * This function calls TM specific routine to calculate PRB + * + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ue + * @param[in] U32 bo + * @param[out] U32 *prbReqrd + * @return Void + **/ +#ifdef ANSI +PUBLIC Void rgSchUtlCalcTotalPrbReq +( +RgSchCellCb *cell, +RgSchUeCb *ue, +U32 bo, +U32 *prbReqrd +) +#else +PUBLIC Void rgSchUtlCalcTotalPrbReq(cell, ue, bo, prbReqrd) +RgSchCellCb *cell; +RgSchUeCb *ue; +U32 bo; +U32 *prbReqrd; +#endif +{ + TRC2(rgSchUtlCalcTotalPrbReq); + + /* Call TM specific Prb calculation routine */ + (dlCalcPrbFunc[ue->mimoInfo.txMode - 1])(cell, ue, bo, prbReqrd); + + RETVOID; +} /* rgSchUtlCalcTotalPrbReq */ +#ifdef TFU_UPGRADE +/*********************************************************** + * + * Func : rgSCHUtlFetchPcqiBitSz + * + * + * Desc : Fetch the CQI/PMI bits for a UE based on the mode, periodicity. + * + * Ret : U8 + * ROK - Success + * + * Notes: + * + * File : + * + **********************************************************/ +#ifdef ANSI +PRIVATE U8 rgSCHUtlFetchPcqiBitSz +( + RgSchCellCb *cell, + RgSchUeCb *ueCb, + U8 numTxAnt + ) +#else +PRIVATE U8 rgSCHUtlFetchPcqiBitSz (cell, ueCb, numTxAnt) +RgSchCellCb *cell; +RgSchUeCb *ueCb; +U8 numTxAnt; +#endif +{ + U8 confRepMode; + U8 pcqiSz; + U8 ri; + RgSchUePCqiCb *cqiCb = RG_SCH_GET_UE_CELL_CQI_CB(ueCb,cell); + + TRC3(rgSCHUtlFetchPcqiBitSz); + confRepMode = cqiCb->cqiCfg.cqiSetup.prdModeEnum; + if((ueCb->mimoInfo.txMode != RGR_UE_TM_3) && + (ueCb->mimoInfo.txMode != RGR_UE_TM_4)) + { + ri =1; + } + else + { + ri = cqiCb->perRiVal; + } + switch(confRepMode) + { + case RGR_PRD_CQI_MOD10: + { + pcqiSz = 4; + } + break; + + case RGR_PRD_CQI_MOD11: + { + if(numTxAnt == 2) + { + if (ri ==1) + { + pcqiSz = 6; + } + else + { + pcqiSz = 8; + } + } + else if(numTxAnt == 4) + { + if (ri ==1) + { + pcqiSz = 8; + } + else + { + pcqiSz = 11; + } + } + else + { + /* This is number of antenna case 1. + * This is not applicable for Mode 1-1. + * So setting it to invalid value */ + pcqiSz = 0; + } + } + break; + + case RGR_PRD_CQI_MOD20: + { + if(cqiCb->isWb) + { + pcqiSz = 4; + } + else + { + pcqiSz = 4 + cqiCb->label; + } + } + break; + + case RGR_PRD_CQI_MOD21: + { + if(cqiCb->isWb) + { + if(numTxAnt == 2) + { + if (ri ==1) + { + pcqiSz = 6; + } + else + { + pcqiSz = 8; + } + } + else if(numTxAnt == 4) + { + if (ri ==1) + { + pcqiSz = 8; + } + else + { + pcqiSz = 11; + } + } + else + { + /* This might be number of antenna case 1. + * For mode 2-1 wideband case only antenna port 2 or 4 is supported. + * So setting invalid value.*/ + pcqiSz = 0; + } + } + else + { + if (ri ==1) + { + pcqiSz = 4 + cqiCb->label; + } + else + { + pcqiSz = 7 + cqiCb->label; + } + } + } + break; + + default: + pcqiSz = 0; + break; + } + + RETVALUE(pcqiSz); +} +#endif +/** + * @brief Utility function to returns the number of subbands based on the + * requested bytes. + * + * @details + * + * Function : rgSchUtlGetNumSbs + * + * Calculate the number of PRBs + * Update the subbandRequired based on the nPrbs and subband size + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ue + * @param[in] U32 *numSbs + * @return U8 + **/ +#ifdef ANSI +PUBLIC U8 rgSchUtlGetNumSbs +( +RgSchCellCb *cell, +RgSchUeCb *ue, +U32 *numSbs +) +#else +PUBLIC U8 rgSchUtlGetNumSbs (cell, ue, numSbs) +RgSchCellCb *cell; +RgSchUeCb *ue; +U32 *numSbs; +#endif +{ + U32 nPrb; + //Currently hardcoding MAX prb for each UE + nPrb = ue->ue5gtfCb.maxPrb; + (*numSbs) = RGSCH_CEIL(nPrb, MAX_5GTF_VRBG_SIZE); + RETVALUE(ROK); +} + +/** + * @brief Utility function to insert the UE node into UE Lst based on the + * number of subbands allocated for the UE for the current TTI. + * + * @details + * + * Function : rgSchUtlSortInsUeLst + * + * If subbandRequired < Min, then insert at head + * Else If subbandRequired > Max, then insert at tail + * Else, traverse the list and place the node at the appropriate place + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ue + * @return U8 + **/ +#ifdef ANSI +PUBLIC U8 rgSchUtlSortInsUeLst +( +RgSchCellCb *cell, +CmLListCp *ueLst, +CmLList *node, +U8 vrbgRequired +) +#else +PUBLIC U8 rgSchUtlSortInsUeLst (cell, ueLst, node, vrbgRequired) +RgSchCellCb *cell; +CmLListCp *ueLst; +CmLList *node; +U8 vrbgRequired; +#endif +{ + CmLList *ueInLst; + CmLList *firstUeInLst; + CmLList *lastUeInLst; + RgSchUeCb *tempUe; + RgSchCmnUlUe *ueUl; + + //firstUeInLst = cmLListFirst(ueLst); + CM_LLIST_FIRST_NODE(ueLst,firstUeInLst); + if(NULLP == firstUeInLst) + { + /* first node to be added to the list */ + cmLListAdd2Tail(ueLst, node); + } + else + { + /* Sb Required for the UE is less than the first node in the list */ + tempUe = (RgSchUeCb *)(firstUeInLst->node); + ueUl = RG_SCH_CMN_GET_UL_UE(tempUe, cell); + + if(vrbgRequired <= ueUl->vrbgRequired) + { + cmLListInsCrnt(ueLst, (node)); + } + else + { + /* Sb Required for this UE is higher than the UEs in the list */ + lastUeInLst = cmLListLast(ueLst); + tempUe = (RgSchUeCb *)(lastUeInLst->node); + if(vrbgRequired >= ueUl->vrbgRequired) + { + cmLListAdd2Tail(ueLst, (node)); + } + else + { + /* This UE needs to be in the middle. Search and insert the UE */ + ueInLst = cmLListFirst(ueLst); + do + { + tempUe = (RgSchUeCb *)(ueInLst->node); + + if(vrbgRequired <= ueUl->vrbgRequired) + { + cmLListInsCrnt(ueLst, (node)); + break; + } + + ueInLst = cmLListNext(ueLst); + + } while(NULLP != ueInLst && ueInLst != firstUeInLst); + } + } + } + + RETVALUE(ROK); +} + +/** + * @brief Function to Send LCG GBR register to MAC + * + * @details + * + * Function: rgSCHUtlBuildNSendLcgReg + * + * Handler for sending LCG GBR registration + * + * Invoked by: + * SCHD + * + * Processing Steps: + * + * @param[in] RgSchCellCb *cell + * @param[in] CmLteRnti crnti + * @param[in] U8 lcgId + * @param[in] Bool isGbr + * @return S16 + * -# ROK + **/ +#ifdef ANSI +PUBLIC S16 rgSCHUtlBuildNSendLcgReg +( +RgSchCellCb *cell, +CmLteRnti crnti, +U8 lcgId, +Bool isGbr +) +#else +PUBLIC S16 rgSCHUtlBuildNSendLcgReg(cell, crnti, lcgId, isGbr) +RgSchCellCb *cell; +CmLteRnti crnti; +U8 lcgId; +Bool isGbr; +#endif +{ + Pst pst; + RgInfLcgRegReq lcgRegReq; + + TRC3(rgSCHUtlBuildNSendLcgReg); + + cmMemset((U8*)&pst, (U8)0, sizeof(Pst)); + lcgRegReq.isGbr = isGbr; + lcgRegReq.cellId = cell->cellId; + lcgRegReq.crnti = crnti; + lcgRegReq.lcgId = lcgId; + rgSCHUtlGetPstToLyr(&pst, &rgSchCb[cell->instIdx], cell->macInst); + /* code Coverage portion of the test case */ + RgSchMacLcgReg(&pst, &lcgRegReq); + + RETVALUE(ROK); +} + +#ifdef TFU_UPGRADE +#ifdef LTE_ADV +#ifndef TFU_TDD +/** + * @brief Function to map RGR pucch type to TFU type + * + * @details + * + * Function: rgSchUtlGetFdbkMode + * + * + * Invoked by: + * SCHD + * + * Processing Steps: + * + * @param[in] RgrSchFrmt1b3TypEnum + * @return TfuAckNackMode + * -# ROK + **/ +#ifdef ANSI +PUBLIC TfuAckNackMode rgSchUtlGetFdbkMode +( +RgrSchFrmt1b3TypEnum fdbkType +) +#else +PUBLIC TfuAckNackMode rgSchUtlGetFdbkMode(fdbkType) +RgrSchFrmt1b3TypEnum fdbkType; +#endif +{ + + TfuAckNackMode mode = TFU_UCI_FORMAT_1A_1B; + + TRC2(rgSchUtlGetFdbkMode); + + switch(fdbkType) + { + case RG_SCH_UCI_FORMAT_NON_CA: + case RG_SCH_UCI_FORMAT1A_1B: + { + mode = TFU_UCI_FORMAT_1A_1B; + } + break; + case RG_SCH_UCI_FORMAT1B_CS: + { + mode = TFU_UCI_FORMAT_1B_CS; + } + break; + case RG_SCH_UCI_FORMAT3: + { + mode = TFU_UCI_FORMAT_3; + } + break; + } + RETVALUE(mode); +} +#endif /* TFU_TDD */ +#endif /* LTE_ADV */ +#endif /*TFU_UPGRADE */ + +#ifdef LTE_ADV +/** + * @brief Send Ue SCell delete to SMAC. + * + * @details + * + * Function : rgSCHUtlSndUeSCellDel2Mac + * This function populates the struct RgInfRlsRnti and + * get the pst for SMac and mark field isUeSCellDel to TRUE which + * indicates that it is a Ue SCell delete. + * + * + * + * @param[in] RgSchCellCb *cell + * @param[in] CmLteRnti rnti + * @return Void + * -# ROK + **/ +#ifdef ANSI +PUBLIC Void rgSCHUtlSndUeSCellDel2Mac +( +RgSchCellCb *cell, +CmLteRnti rnti +) +#else +PUBLIC Void rgSCHUtlSndUeSCellDel2Mac(cell, rnti) +RgSchCellCb *cell; +CmLteRnti rnti; +#endif +{ + Pst pst; + Inst inst = cell->instIdx; + RgInfRlsRnti rntiInfo; + + TRC2(rgSCHUtlSndUeSCellDel2Mac) + + RGSCHDBGINFONEW(inst,(rgSchPBuf(inst),"RNTI Release IND for UE(%d)\n", rnti)); + /* Copy the info to rntiInfo */ + rntiInfo.cellId = cell->cellId; + rntiInfo.rnti = rnti; + /* Fix : syed ueId change as part of reestablishment. + * Now SCH to trigger this. CRG ueRecfg for ueId change + * is dummy */ + rntiInfo.ueIdChng = FALSE; + rntiInfo.newRnti = rnti; + rntiInfo.isUeSCellDel = TRUE; + /* Invoke MAC to release the rnti */ + rgSCHUtlGetPstToLyr(&pst, &rgSchCb[inst], cell->macInst); + RgSchMacRlsRnti(&pst, &rntiInfo); + RETVOID; +} + +/** + * @brief Returns max TB supported by a given txMode + * + * @details + * + * Function : rgSCHUtlGetMaxTbSupp + * Max TB supported for TM Modes (1,2,5,6 and 7) is 1 + * and 2 for others + * + * + * @param[in] RgrTxMode txMode + * @return U8 maxTbCount; + * -# ROK + **/ +#ifdef ANSI +PUBLIC U8 rgSCHUtlGetMaxTbSupp +( +RgrTxMode txMode +) +#else +PUBLIC U8 rgSCHUtlGetMaxTbSupp(txMode) +RgrTxMode txMode +#endif +{ + U8 maxTbCount; + + TRC2(rgSCHUtlGetMaxTbSupp); + + /* Primary Cell */ + + switch(txMode) + { + case RGR_UE_TM_1: + case RGR_UE_TM_2: + case RGR_UE_TM_5: + case RGR_UE_TM_6: + case RGR_UE_TM_7: + maxTbCount = 1; + break; + case RGR_UE_TM_3: + case RGR_UE_TM_4: + case RGR_UE_TM_8: + case RGR_UE_TM_9: + maxTbCount = 2; + break; + default: + maxTbCount = 0; + break; + } + + RETVALUE(maxTbCount); +} + +/** + * @brief Send Ue SCell delete to SMAC. + * + * @details + * + * Function : rgSCHTomUtlGetTrigSet + * This function gets the triggerset based on cqiReq + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb ueCb + * @param[in] U8 cqiReq, + * @param[out] U8 *triggerSet + * + * @return Void + * -# ROK + **/ +#ifdef ANSI +PUBLIC Void rgSCHTomUtlGetTrigSet +( + RgSchCellCb *cell, + RgSchUeCb *ueCb, + U8 cqiReq, + U8 *triggerSet + ) +#else +PRIVATE S16 rgSCHTomUtlGetTrigSet(cell, ueCb, cqiReq, triggerSet) + RgSchCellCb *cell; + RgSchUeCb *ueCb; + U8 cqiReq; + U8 *triggerSet; +#endif +{ + RgSchUeCellInfo *pCellInfo = RG_SCH_CMN_GET_PCELL_INFO(ueCb); + switch(cqiReq) + { + case RG_SCH_APCQI_SERVING_CC: + { + /* APeriodic CQI request for Current Carrier.*/ + U8 sCellIdx = ueCb->cellIdToCellIdxMap[RG_SCH_CELLINDEX(cell)]; + *triggerSet = 1 << (7 - sCellIdx); + break; + } + case RG_SCH_APCQI_1ST_SERVING_CCS_SET: + { + *triggerSet = pCellInfo->acqiCb.aCqiCfg.triggerSet1; + break; + } + case RG_SCH_APCQI_2ND_SERVING_CCS_SET: + { + *triggerSet = pCellInfo->acqiCb.aCqiCfg.triggerSet2; + break; + } + default: + { + /* BUG */ + break; + } + } + RETVOID; +} +#endif +/** + * @brief This function updates the value of UE specific DCI sizes + * + * @details + * + * Function: rgSCHUtlUpdUeDciSize + * Purpose: This function calculates and updates DCI Sizes in bits. + * + * Invoked by: Scheduler + * + * @param[in] RgSchCellCb *cell + * @param[in] RgSchUeCb *ueCb + * @param[in] isCsi2Bit *isCsi2Bit: is 1 bit or 2 bit CSI + * @return Void + * + **/ +#ifdef ANSI +PUBLIC Void rgSCHUtlUpdUeDciSize +( +RgSchCellCb *cell, +RgSchUeCb *ueCb, +Bool isCsi2Bit +) +#else +PUBLIC Void rgSCHUtlUpdUeDciSize(cell, ueCb, isCsi2Bit) +RgSchCellCb *cell; +RgSchUeCb *ueCb; +Bool isCsi2Bit; +#endif +{ + U8 dci01aCmnSize = cell->dciSize.baseSize[TFU_DCI_FORMAT_0]; + U8 dci01aDedSize = cell->dciSize.baseSize[TFU_DCI_FORMAT_0]; + if ((ueCb->accessStratumRls >= RGR_REL_10) && (cell->bwCfg.dlTotalBw >= cell->bwCfg.ulTotalBw)) + { + dci01aCmnSize += 1; /* Resource Allocation Type DCI 0 */ + dci01aDedSize += 1; /* Resource Allocation Type DCI 0 */ + } + if (isCsi2Bit == TRUE) + { + dci01aDedSize += 2; /* 2 bit CSI DCI 0 */ + } + else + { + dci01aDedSize += 1; /* 1 bit CSI DCI 0 */ + } + + /* Common CSI is always 1 bit DCI 0 */ + dci01aCmnSize += 1; /* 1 bit CSI DCI 0 */ + + /* Compare the sizes of DCI 0 with DCI 1A and consider the greater */ + if (dci01aCmnSize < cell->dciSize.baseSize[TFU_DCI_FORMAT_1A]) + { + dci01aCmnSize = cell->dciSize.baseSize[TFU_DCI_FORMAT_1A]; + } + if (dci01aDedSize < cell->dciSize.baseSize[TFU_DCI_FORMAT_1A]) + { + dci01aDedSize = cell->dciSize.baseSize[TFU_DCI_FORMAT_1A]; + } + + /* Remove the Ambiguous Sizes as mentioned in table Table 5.3.3.1.2-1 Spec 36.212-a80 Sec 5.3.3.1.3 */ + dci01aCmnSize += rgSchDciAmbigSizeTbl[dci01aCmnSize]; + dci01aDedSize += rgSchDciAmbigSizeTbl[dci01aDedSize]; + + ueCb->dciSize.cmnSize[TFU_DCI_FORMAT_0] = dci01aCmnSize; + ueCb->dciSize.cmnSize[TFU_DCI_FORMAT_1A] = dci01aCmnSize; + + ueCb->dciSize.dedSize[TFU_DCI_FORMAT_0] = dci01aDedSize; + ueCb->dciSize.dedSize[TFU_DCI_FORMAT_1A] = dci01aDedSize; + + ueCb->dciSize.dedSize[TFU_DCI_FORMAT_1] = cell->dciSize.baseSize[TFU_DCI_FORMAT_1]; + do { + /* Spec 36.212-a80 Sec 5.3.3.1.2: If the UE is configured to decode PDCCH with CRC scrambled + * by the C-RNTI and the number of information bits in format 1 is equal to that for format 0/1A + * for scheduling the same serving cell and mapped onto the UE specific search space given by the + * C-RNTI as defined in [3], one bit of value zero shall be appended to format 1. */ + if (ueCb->dciSize.dedSize[TFU_DCI_FORMAT_1] == ueCb->dciSize.dedSize[TFU_DCI_FORMAT_1A]) + { + ueCb->dciSize.dedSize[TFU_DCI_FORMAT_1] += 1; + } + + /* Spec 36.212-a80 Sec 5.3.3.1.2: If the number of information bits in format 1 belongs + * to one of the sizes in Table 5.3.3.1.2-1, one or more zero bit(s) shall be appended + * to format 1 until the payload size of format 1 does not belong to one of the sizes in + * Table 5.3.3.1.2-1 and is not equal to that of format 0/1A mapped onto the same search space. */ + ueCb->dciSize.dedSize[TFU_DCI_FORMAT_1] += rgSchDciAmbigSizeTbl[ueCb->dciSize.dedSize[TFU_DCI_FORMAT_1]]; + } while (ueCb->dciSize.dedSize[TFU_DCI_FORMAT_1] == ueCb->dciSize.dedSize[TFU_DCI_FORMAT_1A]); + + /* Just copying the value of 2/2A to avoid multiple checks at PDCCH allocations. This values never change.*/ + ueCb->dciSize.dedSize[TFU_DCI_FORMAT_2] = cell->dciSize.size[TFU_DCI_FORMAT_2]; + ueCb->dciSize.dedSize[TFU_DCI_FORMAT_2A] = cell->dciSize.size[TFU_DCI_FORMAT_2A]; + ueCb->dciSize.noUlCcSize[TFU_DCI_FORMAT_2] = cell->dciSize.size[TFU_DCI_FORMAT_2]; + ueCb->dciSize.noUlCcSize[TFU_DCI_FORMAT_2A] = cell->dciSize.size[TFU_DCI_FORMAT_2A]; + + /* Spec 36.212-a80 Sec 5.3.3.1.3: except when format 1A assigns downlink resource + * on a secondary cell without an uplink configuration associated with the secondary cell */ + ueCb->dciSize.noUlCcSize[TFU_DCI_FORMAT_1A] = cell->dciSize.baseSize[TFU_DCI_FORMAT_1A]; + ueCb->dciSize.noUlCcSize[TFU_DCI_FORMAT_1A] += rgSchDciAmbigSizeTbl[ueCb->dciSize.noUlCcSize[TFU_DCI_FORMAT_1A]]; + ueCb->dciSize.noUlCcSize[TFU_DCI_FORMAT_1] = cell->dciSize.baseSize[TFU_DCI_FORMAT_1]; + do { + /* Spec 36.212-a80 Sec 5.3.3.1.2: If the UE is configured to decode PDCCH with CRC scrambled + * by the C-RNTI and the number of information bits in format 1 is equal to that for format 0/1A + * for scheduling the same serving cell and mapped onto the UE specific search space given by the + * C-RNTI as defined in [3], one bit of value zero shall be appended to format 1. */ + if (ueCb->dciSize.noUlCcSize[TFU_DCI_FORMAT_1] == ueCb->dciSize.noUlCcSize[TFU_DCI_FORMAT_1A]) + { + ueCb->dciSize.noUlCcSize[TFU_DCI_FORMAT_1] += 1; + } + + /* Spec 36.212-a80 Sec 5.3.3.1.2: If the number of information bits in format 1 belongs + * to one of the sizes in Table 5.3.3.1.2-1, one or more zero bit(s) shall be appended + * to format 1 until the payload size of format 1 does not belong to one of the sizes in + * Table 5.3.3.1.2-1 and is not equal to that of format 0/1A mapped onto the same search space. */ + ueCb->dciSize.noUlCcSize[TFU_DCI_FORMAT_1] += rgSchDciAmbigSizeTbl[ueCb->dciSize.noUlCcSize[TFU_DCI_FORMAT_1]]; + } while (ueCb->dciSize.noUlCcSize[TFU_DCI_FORMAT_1] == ueCb->dciSize.noUlCcSize[TFU_DCI_FORMAT_1A]); +#ifdef EMTC_ENABLE + rgSCHEmtcUtlUpdUeDciSize(cell, ueCb); +#endif +} + +/** + * @brief This function initialises the DCI Size table + * + * @details + * + * Function: rgSCHUtlCalcDciSizes + * Purpose: This function calculates and initialises DCI Sizes in bits. + * + * Invoked by: Scheduler + * + * @param[in] RgSchCellCb *cell + * @return Void + * + **/ +#ifdef ANSI +PUBLIC Void rgSCHUtlCalcDciSizes +( +RgSchCellCb *cell +) +#else +PUBLIC Void rgSCHUtlCalcDciSizes(cell) +RgSchCellCb *cell; +#endif +{ + U8 dciSize = 0; + U8 dci01aSize = 0; + U32 bits = 0, idx = 0; + + switch(TFU_DCI_FORMAT_0) /* Switch case for the purpose of readability */ + { + case TFU_DCI_FORMAT_0: + { + /* DCI 0: Spec 36.212 Section 5.3.3.1.1 */ + dciSize = 0; + /*-- Calculate resource block assignment bits need to be set + Which is ln(N(N+1)/2) 36.212 5.3.3.1 --*/ + bits = (cell->bwCfg.ulTotalBw * (cell->bwCfg.ulTotalBw + 1) / 2); + while ((bits & 0x8000) == 0) + { + bits <<= 1; + idx++; + } + bits = 16 - idx; + + dciSize = 1 /* DCI 0 bit indicator */ + \ + 1 /* Frequency hoping enable bit field */ + \ + (U8)bits /* For frequency Hopping */ + \ + 5 /* MCS */ + \ + 1 /* NDI */ + \ + 2 /* TPC */ + \ + 3 /* DMRS */ +#ifdef TFU_TDD + + \ + 2 /* UL Index Config 0 or DAI Config 1-6 */ +#endif + ; + + cell->dciSize.baseSize[TFU_DCI_FORMAT_0] = dciSize; + + /* If hoping flag is enabled */ + if (cell->bwCfg.ulTotalBw <= 49) /* Spec 36.213 Table 8.4-1, N UL_hop, if hopping is enabled */ + { + cell->dciSize.dci0HopSize = 1; + } + else + { + cell->dciSize.dci0HopSize = 2; + } + + /* Update common non-CRNTI scrambled DCI 0/1A flag */ + dci01aSize = cell->dciSize.baseSize[TFU_DCI_FORMAT_0] + 1; /* 1 bit CSI */ + } + case TFU_DCI_FORMAT_1A: + { + /* DCI 1A: Spec 36.212 Section 5.3.3.1.3 */ + dciSize = 0; + idx = 0; + /* Calculate resource block assignment bits need to be set + Which is ln(N(N+1)/2) */ + bits = (cell->bwCfg.dlTotalBw * (cell->bwCfg.dlTotalBw + 1) / 2); + while ((bits & 0x8000) == 0) + { + bits <<= 1; + idx++; + } + bits = 16 - idx; + + dciSize += 1 /* Format 1A */ + \ + 1 /* Local or Distributed */ + \ + (U8)bits /* Resource block Assignment */ + \ + 5 /* MCS */ + +#ifdef TFU_TDD + 4 /* HARQ Proc Id */ + +#else + 3 /* HARQ Proc Id */ + +#endif + 1 /* NDI */ + \ + 2 /* RV */ + \ + 2 /* TPC CMD */ +#ifdef TFU_TDD + + \ + 2 /* DAI */ +#endif + ; + cell->dciSize.baseSize[TFU_DCI_FORMAT_1A] = dciSize; + + /* If the UE is not configured to decode PDCCH with CRC scrambled by the C-RNTI, + * and the number of information bits in format 1A is less than that of format 0, + * zeros shall be appended to format 1A until the payload size equals that of format 0. */ + /* Compare the size with DCI 1A and DCI 0 and consider the greater one */ + if (dci01aSize < cell->dciSize.baseSize[TFU_DCI_FORMAT_1A]) + { + dci01aSize = cell->dciSize.baseSize[TFU_DCI_FORMAT_1A]; + } + /* If the number of information bits in format 1A belongs to one of the sizes in + * Table 5.3.3.1.2-1, one zero bit shall be appended to format 1A. */ + dci01aSize += rgSchDciAmbigSizeTbl[dci01aSize]; + cell->dciSize.size[TFU_DCI_FORMAT_1A] = cell->dciSize.size[TFU_DCI_FORMAT_0] = dci01aSize; + } + case TFU_DCI_FORMAT_1: + { + /* DCI 1: Spec 36.212 Section 5.3.3.1.2 */ + dciSize = 0; + if (cell->bwCfg.dlTotalBw > 10) + { + dciSize = 1; /* Resource Allocation header bit */ + } + + /* Resouce allocation bits Type 0 and Type 1 */ + bits = (cell->bwCfg.dlTotalBw/cell->rbgSize); + if ((cell->bwCfg.dlTotalBw % cell->rbgSize) != 0) + { + bits++; + } + + dciSize += (U8)bits /* Resource Allocation bits */ + \ + 5 /* MCS */ + +#ifdef TFU_TDD + 4 /* HARQ TDD */ + +#else + 3 /* HARQ FDD */ + +#endif + 1 /* NDI */ + \ + 2 /* Redunancy Version */ + \ + 2 /* TPC Cmd */ +#ifdef TFU_TDD + + \ + 2 /* DAI */ +#endif + ; + + + cell->dciSize.baseSize[TFU_DCI_FORMAT_1] = dciSize; + + cell->dciSize.size[TFU_DCI_FORMAT_1] = dciSize; + + do { + /* If the UE is not configured to decode PDCCH with CRC + * scrambled by the C-RNTI and the number of information bits in format 1 + * is equal to that for format 0/1A, one bit of value zero shall be appended + * to format 1. */ + if (dci01aSize == cell->dciSize.size[TFU_DCI_FORMAT_1]) + { + cell->dciSize.size[TFU_DCI_FORMAT_1] += 1; + } + + /* If the number of information bits in format 1 belongs to one of the sizes in + * Table 5.3.3.1.2-1, one or more zero bit(s) shall be appended to format 1 until + * the payload size of format 1 does not belong to one of the sizes in Table 5.3.3.1.2-1 + * and is not equal to that of format 0/1A mapped onto the same search space. */ + cell->dciSize.size[TFU_DCI_FORMAT_1] += rgSchDciAmbigSizeTbl[cell->dciSize.size[TFU_DCI_FORMAT_1]]; + } while (cell->dciSize.size[TFU_DCI_FORMAT_1] == dci01aSize); + } + case TFU_DCI_FORMAT_2: + { + /* DCI 2: Spec 36.212 Section 5.3.3.1.5 */ + dciSize = 0; + if (cell->bwCfg.dlTotalBw > 10) + { + dciSize = 1; /* Resource Allocation bit */ + } + + dciSize += (U8)bits /* Resource Allocation bits */ + \ + 2 /* TPC */ + +#ifdef TFU_TDD + 2 /* DAI */ + \ + 4 /* HARQ */ + +#else + 3 /* HARQ */ + +#endif + 1 /* CW Swap Flag */ + \ + 5 /* MCS for TB1 */+ \ + 1 /* NDI for TB1 */+ \ + 2 /* RV for TB1 */ + \ + 5 /* MCS for TB2 */+ \ + 1 /* NDI for TB2 */+ \ + 2 /* RV for TB2 */; + if (cell->numTxAntPorts == 2) + { + dciSize += 3; + } + else if (cell->numTxAntPorts == 4) + { + dciSize += 6; + } + cell->dciSize.size[TFU_DCI_FORMAT_2] = dciSize; + cell->dciSize.size[TFU_DCI_FORMAT_2] += rgSchDciAmbigSizeTbl[cell->dciSize.size[TFU_DCI_FORMAT_2]]; + } + case TFU_DCI_FORMAT_2A: + { + /* DCI 2A: Spec 36.212 Section 5.3.3.1.5A */ + dciSize = 0; + if (cell->bwCfg.dlTotalBw > 10) + { + dciSize = 1; /* Resource Allocation bit */ + } + + dciSize += (U8)bits /* Resource Allocation bits */ + \ + 2 /* TPC */ + +#ifdef TFU_TDD + 2 /* DAI */ + \ + 4 /* HARQ */ + +#else + 3 /* HARQ */ + +#endif + 1 /* CW Swap Flag */ + \ + 5 /* MCS for TB1 */+ \ + 1 /* NDI for TB1 */+ \ + 2 /* RV for TB1 */ + \ + 5 /* MCS for TB2 */+ \ + 1 /* NDI for TB2 */+ \ + 2 /* RV for TB2 */; + if (cell->numTxAntPorts == 4) + { + dciSize += 2; + } + cell->dciSize.size[TFU_DCI_FORMAT_2A] = dciSize; + cell->dciSize.size[TFU_DCI_FORMAT_2A] += \ + rgSchDciAmbigSizeTbl[cell->dciSize.size[TFU_DCI_FORMAT_2A]]; /* Spec 39.212 Table 5.3.3.1.2-1 */ + } + case TFU_DCI_FORMAT_3: + { + /* DCI 3: Spec 36.212 Section 5.3.3.1.6 */ + cell->dciSize.size[TFU_DCI_FORMAT_3] = cell->dciSize.size[TFU_DCI_FORMAT_1A] / 2; + if (cell->dciSize.size[TFU_DCI_FORMAT_3] % 2) + { + cell->dciSize.size[TFU_DCI_FORMAT_3]++; + } + } + case TFU_DCI_FORMAT_3A: + { + /* DCI 3A: Spec 36.212 Section 5.3.3.1.7 */ + cell->dciSize.size[TFU_DCI_FORMAT_3A] = cell->dciSize.size[TFU_DCI_FORMAT_1A]; + } +#ifdef EMTC_ENABLE + case TFU_DCI_FORMAT_6_0A: + { + rgSCHEmtcGetDciFrmt60ASize(cell); + } + case TFU_DCI_FORMAT_6_1A: + { + rgSCHEmtcGetDciFrmt61ASize(cell); + } +#endif + default: + { + /* DCI format not supported */ + break; + } + } +} + +/** + * @brief Handler for the CPU OvrLd related state adjustment. + * + * @details + * + * Function : rgSCHUtlCpuOvrLdAdjItbsCap + * + * Processing Steps: + * - Record dl/ulTpts + * - Adjust maxItbs to acheive target throughputs + * + * @param[in] RgSchCellCb *cell + * @return Void + **/ +#ifdef ANSI +PUBLIC Void rgSCHUtlCpuOvrLdAdjItbsCap +( + RgSchCellCb *cell +) +#else +PUBLIC Void rgSCHUtlCpuOvrLdAdjItbsCap(cell) + RgSchCellCb *cell +#endif +{ + U32 tptDelta; + + TRC3(rgSCHUtlCpuOvrLdAdjItbsCap) + + if ((cell->cpuOvrLdCntrl.cpuOvrLdIns) & (RGR_CPU_OVRLD_DL_TPT_UP | + RGR_CPU_OVRLD_DL_TPT_DOWN)) + { + /* Regulate DL Tpt for CPU overload */ + if (cell->measurements.dlTpt > cell->cpuOvrLdCntrl.tgtDlTpt) + { + tptDelta = cell->measurements.dlTpt - cell->cpuOvrLdCntrl.tgtDlTpt; + /* Upto 0.5% drift in measured vs target tpt is ignored */ + if (((tptDelta*1000)/cell->cpuOvrLdCntrl.tgtDlTpt) > 5) + { + cell->thresholds.maxDlItbs = RGSCH_MAX((cell->thresholds.maxDlItbs-1), 1); + } + } + else + { + tptDelta = cell->cpuOvrLdCntrl.tgtDlTpt - cell->measurements.dlTpt; + /* Upto 0.5% drift in measured vs target tpt is ignored */ + if (((tptDelta*1000)/cell->cpuOvrLdCntrl.tgtDlTpt) > 5) + { + cell->thresholds.maxDlItbs = RGSCH_MIN((cell->thresholds.maxDlItbs+1), RG_SCH_DL_MAX_ITBS); + } + } +#ifdef CPU_OL_DBG_PRINTS + printf("\n DL CPU OL ADJ = %lu, %lu, %d\n", cell->measurements.dlTpt, cell->cpuOvrLdCntrl.tgtDlTpt, + cell->thresholds.maxDlItbs); +#endif + } + + if ((cell->cpuOvrLdCntrl.cpuOvrLdIns) & (RGR_CPU_OVRLD_UL_TPT_UP | + RGR_CPU_OVRLD_UL_TPT_DOWN)) + { + /* Regualte DL Tpt for CPU overload */ + if (cell->measurements.ulTpt > cell->cpuOvrLdCntrl.tgtUlTpt) + { + tptDelta = cell->measurements.ulTpt - cell->cpuOvrLdCntrl.tgtUlTpt; + /* Upto 1% drift in measured vs target tpt is ignored */ + if (((tptDelta*1000)/cell->cpuOvrLdCntrl.tgtUlTpt) > 10) + { + cell->thresholds.maxUlItbs = RGSCH_MAX((cell->thresholds.maxUlItbs-1), 1); + } + } + else + { + tptDelta = cell->cpuOvrLdCntrl.tgtUlTpt - cell->measurements.ulTpt; + /* Upto 1% drift in measured vs target tpt is ignored */ + if (((tptDelta*1000)/cell->cpuOvrLdCntrl.tgtUlTpt) > 10) + { + cell->thresholds.maxUlItbs = RGSCH_MIN((cell->thresholds.maxUlItbs+1), RG_SCH_UL_MAX_ITBS); + } + } +#ifdef CPU_OL_DBG_PRINTS + printf("\n UL CPU OL ADJ = %lu, %lu, %d\n", cell->measurements.ulTpt, cell->cpuOvrLdCntrl.tgtUlTpt, + cell->thresholds.maxUlItbs); +#endif + } + + RETVOID; +} +/** + * @brief Handler for the num UE per TTI based CPU OvrLd instr updating + * + * @details + * + * Function : rgSCHUtlChkAndUpdNumUePerTtiCpuOvInstr + * + * Processing Steps: + * - Validate the config params. + * - Update numUEperTTi CPU OL related information. + * - If successful, return ROK else RFAILED. + * + * @param[in] RgSchCellCb *cell + * @param[in] U8 cnrtCpuOvrLdIns + * @return Void + **/ +#ifdef ANSI +PRIVATE Void rgSCHUtlChkAndUpdNumUePerTtiCpuOvInstr +( + RgSchCellCb *cell, + U8 crntCpuOvrLdIns +) +#else +PRIVATE S16 rgSCHUtlChkAndUpdNumUePerTtiCpuOvInstr(cell, crntCpuOvrLdIns) + RgSchCellCb *cell; + U8 crntCpuOvrLdIns; +#endif +{ + RgSchCpuOvrLdCntrlCb *cpuInstr = &(cell->cpuOvrLdCntrl); + RgSchCmnCell *cellSch; + U8 maxUeNewDlTxPerTti; + U8 maxUeNewUlTxPerTti; + U8 tmpSubFrame = 0; +#ifdef CPU_OL_DBG_PRINTS + U8 idx = 0; +#endif + U8 maxDlDecCnt; + U8 maxUlDecCnt; + + cellSch = RG_SCH_CMN_GET_CELL(cell); + + maxUeNewDlTxPerTti = cellSch->dl.maxUeNewTxPerTti; + maxUeNewUlTxPerTti = cellSch->ul.maxUeNewTxPerTti; + + /* Calculate Maximum Decremen */ + maxDlDecCnt = (10*(maxUeNewDlTxPerTti - 1))-(10-RGR_MAX_PERC_NUM_UE_PER_TTI_RED); + maxUlDecCnt = (10*(maxUeNewUlTxPerTti - 1))-(10-RGR_MAX_PERC_NUM_UE_PER_TTI_RED); + + /* Check for DL CPU Commands */ + if ( crntCpuOvrLdIns & RGR_CPU_OVRLD_DL_DEC_NUM_UE_PER_TTI ) + { + /* Decrement till 90% of maxUeNewDlTxPerTti */ + if ( cpuInstr->dlNxtIndxDecNumUeTti < maxDlDecCnt ) + { + tmpSubFrame = (cpuInstr->dlNxtIndxDecNumUeTti) % 10; + cpuInstr->dlNxtIndxDecNumUeTti++; + if ( cpuInstr->maxUeNewTxPerTti[tmpSubFrame] > 1 ) + { + cpuInstr->maxUeNewTxPerTti[tmpSubFrame]--; + } + else + { +#ifdef CPU_OL_DBG_PRINTS + printf("CPU_OL_TTI__ERROR\n"); +#endif + RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,"Invalid CPU OL"); + } + } +#ifdef CPU_OL_DBG_PRINTS + printf("dlNxtIndxDecNumUeTti = %d\n", cpuInstr->dlNxtIndxDecNumUeTti); +#endif + RLOG_ARG1(L_DEBUG,DBG_CELLID,cell->cellId,"dlNxtIndxDecNumUeTti = %d", + cpuInstr->dlNxtIndxDecNumUeTti); + } + else if ( crntCpuOvrLdIns & RGR_CPU_OVRLD_DL_INC_NUM_UE_PER_TTI ) + { + if ( cpuInstr->dlNxtIndxDecNumUeTti > 0) + { + cpuInstr->dlNxtIndxDecNumUeTti--; + tmpSubFrame = (cpuInstr->dlNxtIndxDecNumUeTti) % 10; + if ( cpuInstr->maxUeNewTxPerTti[tmpSubFrame] < maxUeNewDlTxPerTti ) + { + cpuInstr->maxUeNewTxPerTti[tmpSubFrame]++; + } + else + { +#ifdef CPU_OL_DBG_PRINTS + printf("CPU_OL_TTI__ERROR\n"); +#endif + RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,"Invalid CPU OL"); + } + } +#ifdef CPU_OL_DBG_PRINTS + printf("dlNxtIndxDecNumUeTti = %d\n", cpuInstr->dlNxtIndxDecNumUeTti); +#endif + RLOG_ARG1(L_DEBUG,DBG_CELLID,cell->cellId,"dlNxtIndxDecNumUeTti = %d", + cpuInstr->dlNxtIndxDecNumUeTti); + } + /* Check for UL CPU commands */ + if ( crntCpuOvrLdIns & RGR_CPU_OVRLD_UL_DEC_NUM_UE_PER_TTI ) + { + /* Decrement till 90% of maxUeNewDlTxPerTti */ + if ( cpuInstr->ulNxtIndxDecNumUeTti < maxUlDecCnt ) + { + tmpSubFrame = (cpuInstr->ulNxtIndxDecNumUeTti) % 10; + cpuInstr->ulNxtIndxDecNumUeTti++; + if ( cpuInstr->maxUeNewRxPerTti[tmpSubFrame] > 1 ) + { + cpuInstr->maxUeNewRxPerTti[tmpSubFrame]--; + } + else + { +#ifdef CPU_OL_DBG_PRINTS + printf("CPU_OL_TTI__ERROR\n"); +#endif + RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,"Invalid CPU OL"); + } + } +#ifdef CPU_OL_DBG_PRINTS + printf("ulNxtIndxDecNumUeTti = %d\n", cpuInstr->ulNxtIndxDecNumUeTti); +#endif + RLOG_ARG1(L_DEBUG,DBG_CELLID,cell->cellId,"dlNxtIndxDecNumUeTti = %d", + cpuInstr->dlNxtIndxDecNumUeTti); + } + else if ( crntCpuOvrLdIns & RGR_CPU_OVRLD_UL_INC_NUM_UE_PER_TTI ) + { + if ( cpuInstr->ulNxtIndxDecNumUeTti > 0) + { + cpuInstr->ulNxtIndxDecNumUeTti--; + tmpSubFrame = (cpuInstr->ulNxtIndxDecNumUeTti) % 10; + if ( cpuInstr->maxUeNewRxPerTti[tmpSubFrame] < maxUeNewUlTxPerTti ) + { + cpuInstr->maxUeNewRxPerTti[tmpSubFrame]++; + } + else + { +#ifdef CPU_OL_DBG_PRINTS + printf("CPU_OL_TTI__ERROR\n"); +#endif + RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,"Invalid CPU OL"); + } + } +#ifdef CPU_OL_DBG_PRINTS + printf("ulNxtIndxDecNumUeTti = %d\n", cpuInstr->ulNxtIndxDecNumUeTti); +#endif + RLOG_ARG1(L_DEBUG,DBG_CELLID,cell->cellId,"dlNxtIndxDecNumUeTti = %d", + cpuInstr->dlNxtIndxDecNumUeTti); + } +#ifdef CPU_OL_DBG_PRINTS + /* TODO: Debug Information - Shall be moved under CPU_OL_DBG_PRINTS */ + printf("maxUeNewDlTxPerTti = %d, maxUeNewUlTxPerTti = %d\n", maxUeNewDlTxPerTti, maxUeNewUlTxPerTti); + printf("DL Sf numUePerTti:"); + for ( idx = 0; idx < 10 ; idx ++ ) + { + printf(" %d", cpuInstr->maxUeNewTxPerTti[idx]); + } + printf("\nUL Sf numUePerTti:"); + for ( idx = 0; idx < 10 ; idx ++ ) + { + printf(" %d", cpuInstr->maxUeNewRxPerTti[idx]); + } + printf("\n"); +#endif + + RETVOID; +} /* rgSCHUtlChkAndUpdNumUePerTtiCpuOvInstr */ + +/** + * @brief Handler for the CPU OvrLd related cell Recfg. + * + * @details + * + * Function : rgSCHUtlResetCpuOvrLdState + * + * Processing Steps: + * - Validate the config params. + * - Update CPU OL related state information. + * - If successful, return ROK else RFAILED. + * + * @param[in] RgSchCellCb *cell + * @param[in] U8 cnrtCpuOvrLdIns + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 rgSCHUtlResetCpuOvrLdState +( + RgSchCellCb *cell, + U8 crntCpuOvrLdIns +) +#else +PUBLIC S16 rgSCHUtlResetCpuOvrLdState(cell, crntCpuOvrLdIns) + RgSchCellCb *cell; + U8 crntCpuOvrLdIns; +#endif +{ + U8 crntDlCpuOL=0; + U8 crntUlCpuOL=0; + RgSchCmnCell *schCmnCell = (RgSchCmnCell *)(cell->sc.sch); + U8 idx; + + TRC3(rgSCHUtlResetCpuOvrLdState) + +#ifdef CPU_OL_DBG_PRINTS + printf("\n CPU OVR LD Ins Rcvd = %d\n", (int)crntCpuOvrLdIns); +#endif + RLOG_ARG0(L_INFO,DBG_CELLID,cell->cellId,"CPU OVR LD Ins Rcvd"); + + if ( RGR_CPU_OVRLD_RESET == crntCpuOvrLdIns ) + { + /* The CPU OL instruction received with RESET (0), hence reset it */ +#ifdef CPU_OL_DBG_PRINTS + printf("rgSCHUtlResetCpuOvrLdState: RESET CPU OL instr\n"); +#endif + RLOG_ARG0(L_INFO,DBG_CELLID,cell->cellId,"RESET CPU OVR LD"); + cell->cpuOvrLdCntrl.cpuOvrLdIns = 0; + /* Reset the max UL and DL itbs to 26 */ + cell->thresholds.maxUlItbs = RG_SCH_UL_MAX_ITBS; + cell->thresholds.maxDlItbs = RG_SCH_DL_MAX_ITBS; + /* Reset the num UE per TTI intructions */ + cell->cpuOvrLdCntrl.dlNxtIndxDecNumUeTti = 0; + cell->cpuOvrLdCntrl.ulNxtIndxDecNumUeTti = 0; + for ( idx = 0; idx < 10; idx++ ) + { + cell->cpuOvrLdCntrl.maxUeNewTxPerTti[idx] = + schCmnCell->dl.maxUeNewTxPerTti; + cell->cpuOvrLdCntrl.maxUeNewRxPerTti[idx] = + schCmnCell->ul.maxUeNewTxPerTti; + } + + RETVALUE(ROK); + } + /* Check and Update numUEPer TTI based CPU overload instruction before + * going for TP based CPU OL + * TTI based intrcuctions shall be > 0xF */ + if ( crntCpuOvrLdIns > 0xF ) + { + rgSCHUtlChkAndUpdNumUePerTtiCpuOvInstr(cell, crntCpuOvrLdIns); + /* If need to have both TP and numUePerTti instrcution together in + * one command then dont return from here */ + RETVALUE(ROK); + } + + crntDlCpuOL = (crntCpuOvrLdIns & RGR_CPU_OVRLD_DL_TPT_UP) +\ + (crntCpuOvrLdIns & RGR_CPU_OVRLD_DL_TPT_DOWN); + if ((crntDlCpuOL) && (crntDlCpuOL != RGR_CPU_OVRLD_DL_TPT_UP) && + (crntDlCpuOL != RGR_CPU_OVRLD_DL_TPT_DOWN)) + { + /* Cfg validation failed. Invalid Command. Either UP/DOWN is allowed */ + RETVALUE(RFAILED); + } + crntUlCpuOL = (crntCpuOvrLdIns & RGR_CPU_OVRLD_UL_TPT_UP) +\ + (crntCpuOvrLdIns & RGR_CPU_OVRLD_UL_TPT_DOWN); + if ((crntUlCpuOL) && (crntUlCpuOL != RGR_CPU_OVRLD_UL_TPT_UP) && + (crntUlCpuOL != RGR_CPU_OVRLD_UL_TPT_DOWN)) + { + /* Cfg validation failed. Invalid Command. Either UP/DOWN is allowed */ + RETVALUE(RFAILED); + } + if ((crntDlCpuOL == 0) && (crntUlCpuOL == 0)) + { + /* Cfg validation failed. Invalid Command. Either UP/DOWN is allowed */ + RETVALUE(RFAILED); + } + + cell->cpuOvrLdCntrl.cpuOvrLdIns = crntCpuOvrLdIns; + + if (crntUlCpuOL) + { + if (crntUlCpuOL == RGR_CPU_OVRLD_UL_TPT_DOWN) + { + cell->cpuOvrLdCntrl.tgtUlTpt = cell->measurements.ulTpt - \ + (cell->measurements.ulTpt * 3 )/100; + } + else + { + cell->cpuOvrLdCntrl.tgtUlTpt = cell->measurements.ulTpt + \ + (cell->measurements.ulTpt * 2 )/100; + } + RLOG_ARG3(L_DEBUG,DBG_CELLID,cell->cellId,"CPU OVR LD UL Reset to " + "%d, %lu, %lu", (int)crntUlCpuOL, cell->cpuOvrLdCntrl.tgtUlTpt,cell->measurements.ulTpt); +#ifdef CPU_OL_DBG_PRINTS + printf("\n CPU OVR LD UL Reset to= %d, %lu, %lu\n", (int)crntUlCpuOL, cell->cpuOvrLdCntrl.tgtUlTpt, + cell->measurements.ulTpt); +#endif + } + + if (crntDlCpuOL) + { + if (crntDlCpuOL == RGR_CPU_OVRLD_DL_TPT_DOWN) + { + cell->cpuOvrLdCntrl.tgtDlTpt = cell->measurements.dlTpt - \ + (cell->measurements.dlTpt * 1 )/100; + } + else + { + cell->cpuOvrLdCntrl.tgtDlTpt = cell->measurements.dlTpt + \ + (cell->measurements.dlTpt * 1 )/100; + } + RLOG_ARG3(L_DEBUG,DBG_CELLID,cell->cellId,"CPU OVR LD DL Reset to " + "%d, %lu, %lu", (int)crntDlCpuOL, cell->cpuOvrLdCntrl.tgtDlTpt,cell->measurements.dlTpt); + +#ifdef CPU_OL_DBG_PRINTS + printf("\n CPU OVR LD DL Reset to= %d, %lu, %lu\n", (int)crntDlCpuOL, cell->cpuOvrLdCntrl.tgtDlTpt, + cell->measurements.dlTpt); +#endif + } + rgSCHUtlCpuOvrLdAdjItbsCap(cell); + RETVALUE(ROK); +} +#ifdef EMTC_ENABLE +PUBLIC S16 rgSCHUtlAddToResLst +( + CmLListCp *cp, + RgSchIotRes *iotRes + ) +{ + cmLListAdd2Tail(cp, &iotRes->resLnk); + iotRes->resLnk.node = (PTR)iotRes; + RETVALUE(ROK); +} +PUBLIC S16 rgSCHUtlDelFrmResLst +( +RgSchUeCb *ue, +RgSchIotRes *iotRes +) +{ + CmLListCp *cp = NULLP; + RgSchEmtcUeInfo *emtcUe = NULLP; + emtcUe = RG_GET_EMTC_UE_CB(ue); + if(iotRes->resType == RG_SCH_EMTC_PUCCH_RES) + { + cp = &emtcUe->ulResLst; + }else if(iotRes->resType == RG_SCH_EMTC_PDSCH_RES) + { + cp = &emtcUe->dlResLst; + }else + { + RLOG0(L_INFO, "*****restype mismatch"); + } + if(cp != NULLP ) + { + if(cp->count == 0) + { + RLOG0(L_INFO,"****error count*****\n"); + RETVALUE(ROK); + } + } + cmLListDelFrm(cp, &iotRes->resLnk); + iotRes->resLnk.node = NULLP; + RETVALUE(ROK); +} +#endif +/********************************************************************** + + End of file +**********************************************************************/ diff --git a/src/5gnrmac/rg_sch_utl_clist.c b/src/5gnrmac/rg_sch_utl_clist.c new file mode 100755 index 000000000..4cbec3c1d --- /dev/null +++ b/src/5gnrmac/rg_sch_utl_clist.c @@ -0,0 +1,317 @@ +/******************************************************************************* +################################################################################ +# Copyright (c) [2017-2019] [Radisys] # +# # +# 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. # +################################################################################ +*******************************************************************************/ + +/********************************************************************20** + + Name: common functions - linked list management + + Type: C source file + + Desc: common functions for linked lists + + File: rg_sch_utl_clist.c + +*********************************************************************21*/ + +/* header include files (.h) */ + +#include "envopt.h" /* environment options */ +#include "envdep.h" /* environment dependent */ +#include "envind.h" /* environment independent */ + +#include "gen.h" /* general layer */ +#include "ssi.h" /* system services */ + +/* header/extern include files (.x) */ + +#include "gen.x" /* general layer */ +#include "ssi.x" /* system services */ +#include "rg_sch_clist.x" /* common functions */ + + +/* Linked List functions */ + + +/* +* +* Fun: rgSCHRrCListInit +* +* Desc: initializes a linked list control pointer. +* +* Ret: ROK - ok +* +* Notes: None +* +* File: rr_clist.c +* +*/ +#ifdef ANSI +PUBLIC Void rgSCHRrCListInit +( +RgSchRrCListCp *lCp /* list control point */ +) +#else +PUBLIC Void rgSCHRrCListInit(lCp) +RgSchRrCListCp *lCp; /* list control point */ +#endif +{ + TRC2(rgSCHRrCListInit); + + lCp->first = (RgSchRrCList *)NULLP; + lCp->crnt = (RgSchRrCList *)NULLP; + lCp->count = 0; + + RETVOID; +} /* end of rgSCHRrCListInit */ + +/* LTE_ADV_FLAG_REMOVED_START */ +/* + * Fun: rgSCHRrCListAdd2Crnt + * + * Desc: adds node to linked list behind crnt. + * + * Ret: ROK - ok + * + * Notes: None + * + * File: rr_clist.c + */ +#ifdef ANSI +PUBLIC Void rgSCHRrCListAdd2Crnt +( + RgSchRrCListCp *lCp, /* list control point */ + RgSchRrCList *node /* node to be added */ + ) +#else +PUBLIC Void rgSCHRrCListAdd2Crnt(lCp, node) + RgSchRrCListCp *lCp; /* list control point */ + RgSchRrCList *node; /* node to be added */ +#endif +{ + TRC2(rgSCHRrCListAdd2Crnt); +#ifdef ERRCHK + if (lCp == (RgSchRrCListCp *)NULLP) + RETVOID; +#endif + + lCp->count++; + + if(!lCp->first) + { + node->prev = node; + node->next = node; + lCp->first = node; + + lCp->crnt = lCp->first; + + RETVOID; + } + + node->next = lCp->crnt; + node->prev = lCp->crnt->prev; + lCp->crnt->prev->next = node; + lCp->crnt->prev = node; + + RETVOID; +} +/* LTE_ADV_FLAG_REMOVED_END */ + +/* +* +* Fun: rgSCHRrCListAdd2Tail +* +* Desc: adds node to linked list after last. +* +* Ret: ROK - ok +* +* Notes: None +* +* File: rr_clist.c +* +*/ +#ifdef ANSI +PUBLIC Void rgSCHRrCListAdd2Tail +( +RgSchRrCListCp *lCp, /* list control point */ +RgSchRrCList *node /* node to be added */ +) +#else +PUBLIC Void rgSCHRrCListAdd2Tail(lCp, node) +RgSchRrCListCp *lCp; /* list control point */ +RgSchRrCList *node; /* node to be added */ +#endif +{ + TRC2(rgSCHRrCListAdd2Tail); + +#ifdef ERRCHK + if (lCp == (RgSchRrCListCp *)NULLP) + RETVOID; +#endif + + lCp->count++; + + if(!lCp->first) + { + node->prev = node; + node->next = node; + lCp->first = node; + + lCp->crnt = lCp->first; + + RETVOID; + } + + node->next = lCp->first; + node->prev = lCp->first->prev; + lCp->first->prev->next = node; + lCp->first->prev = node; + + RETVOID; +} /* end of rgSCHRrCListAdd2Tail */ + +/* +* +* Fun: rgSCHRrCListDelFrm +* +* Desc: remove node pointed to by nodePtr from list and return node. +* nodePtr could be anywhere in the list. +* - resets crnt to NULLP. +* +* Ret: pointer +* +* Notes: None +* +* File: rr_clist.c +* +*/ +#ifdef ANSI +PUBLIC RgSchRrCList *rgSCHRrCListDelFrm +( +RgSchRrCListCp *lCp, /* list control pointer */ +RgSchRrCList *node /* node to be removed */ +) +#else +PUBLIC RgSchRrCList *rgSCHRrCListDelFrm(lCp, node) +RgSchRrCListCp *lCp; /* list control pointer */ +RgSchRrCList *node; /* node to be removed */ +#endif +{ + TRC2(rgSCHRrCListDelFrm); + +#ifdef ERRCHK + if (lCp == (RgSchRrCListCp *)NULLP) + RETVALUE(NULLP); +#endif + + if(lCp->count == 0) + { + RETVALUE(NULLP); + } + if (lCp->count == 1) + { + if(lCp->first == node) + { + lCp->first = lCp->crnt = (RgSchRrCList *)NULLP; + lCp->count = 0; + node->next = node->prev = (RgSchRrCList *)NULLP; + RETVALUE(node); + } + RETVALUE(NULLP); + } + + if (lCp->first == node) + { + lCp->first->prev->next = node->next; + node->next->prev = lCp->first->prev; + lCp->first = node->next; + if(lCp->crnt == node) + { + lCp->crnt = node->next; + } + node->next = node->prev = (RgSchRrCList *)NULLP; + /* Adding this check and guarding the decrement of counter when + node is deleted with reshuffling */ + lCp->count--; + RETVALUE(node); + } + + if(node->prev && node->next) + { + node->prev->next = node->next; + node->next->prev = node->prev; + lCp->count--; + } + if(lCp->crnt == node) + { + lCp->crnt = node->next; + } + node->next = node->prev = (RgSchRrCList *)NULLP; + RETVALUE(node); +} /* end of rgSCHRrCListDelFrm */ + +/* +* +* Fun: rgSCHRrCListInsrtAtCrnt +* +* Desc: Inserting the given node at CuRRENT and Moving present CURRENT +* node to next. +* +* Ret: None +* +* Notes: None +* +* File: rr_clist.c +* +*/ +#ifdef ANSI +PUBLIC Void rgSCHRrCListInsrtAtCrnt +( +RgSchRrCListCp *lCp, /* list control pointer */ +RgSchRrCList *node /* node to be removed */ +) +#else +PUBLIC Void rgSCHRrCListInsrtAtCrnt(lCp, node) +RgSchRrCListCp *lCp; /* list control pointer */ +RgSchRrCList *node; /* node to be inserted */ +#endif +{ + RgSchRrCList *crnt; + TRC2(rgSCHRrCListInsrtAtCrnt); + +#ifdef ERRCHK + if (lCp == (RgSchRrCListCp *)NULLP) + RETVOID; +#endif + + crnt = lCp->crnt; + lCp->crnt = node; + + node->prev = crnt->prev; + crnt->prev->next = node; + node->next = crnt; + crnt->prev = node; + + lCp->count++; + + RETVOID; +} + +/********************************************************************30** + + End of file +**********************************************************************/ diff --git a/src/5gnrmac/rg_tom.c b/src/5gnrmac/rg_tom.c new file mode 100755 index 000000000..30fb50e70 --- /dev/null +++ b/src/5gnrmac/rg_tom.c @@ -0,0 +1,2711 @@ +/******************************************************************************* +################################################################################ +# Copyright (c) [2017-2019] [Radisys] # +# # +# 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. # +################################################################################ +*******************************************************************************/ + +/************************************************************************ + + Name: LTE-MAC layer + + Type: C source file + + Desc: C source code for Entry point fucntions + + File: rg_tom.c + +**********************************************************************/ + +static const char* RLOG_MODULE_NAME="MAC"; +static int RLOG_FILE_ID=237; +static int RLOG_MODULE_ID=4096; +/** @file rg_tom.c +@brief This module does processing related to handling of lower interface APIs +invoked by PHY towards MAC +*/ +/* header include files -- defines (.h) */ +#include "envopt.h" /* environment options */ +#include "envdep.h" /* environment dependent */ +#include "envind.h" /* environment independent */ +#include "gen.h" /* general layer */ +#include "ssi.h" /* system services */ +#include "cm5.h" /* common timers defines */ +#include "cm_hash.h" /* common hash list defines */ +#include "cm_llist.h" /* common linked list defines */ +#include "cm_mblk.h" /* memory management */ +#include "cm_tkns.h" /* common tokens */ +#include "cm_lte.h" /* common tokens */ +#include "rgu.h" /* RGU defines */ +#include "tfu.h" /* RGU defines */ +#include "lrg.h" /* layer management defines for LTE-MAC */ +#include "crg.h" /* layer management defines for LTE-MAC */ +#include "rg_sch_inf.h" /* layer management defines for LTE-MAC */ +#include "rg.h" /* defines and macros for MAC */ +#include "rg_env.h" /* defines and macros for MAC */ +#include "rg_err.h" /* defines and macros for MAC */ + + +/* header/extern include files (.x) */ +#include "gen.x" /* general layer typedefs */ +#include "ssi.x" /* system services typedefs */ +#include "cm5.x" /* common timers */ +#include "cm_hash.x" /* common hash list */ +#include "cm_lib.x" /* common library */ +#include "cm_llist.x" /* common linked list */ +#include "cm_mblk.x" /* memory management */ +#include "cm_tkns.x" /* common tokens */ +#include "cm_lte.x" /* common tokens */ +#include "rgu.x" /* RGU types */ +#include "tfu.x" /* RGU types */ +#include "lrg.x" /* layer management typedefs for MAC */ +#include "crg.x" /* CRG interface typedefs */ +#include "rg_sch_inf.x" /* SCH interface typedefs */ +#include "rg_prg.x" /* PRG interface typedefs */ +#include "rgm.x" /* layer management typedefs for MAC */ +#include "rgm.h" /* layer management typedefs for MAC */ +#include "rg.x" /* typedefs for MAC */ + +#ifdef MAC_RLC_UL_RBUF +#include "ss_rbuf.h" +#include "ss_rbuf.x" +#endif + +/* ADD Changes for Downlink UE Timing Optimization */ +#ifndef LTEMAC_DLUE_TMGOPTMZ +PRIVATE S16 rgTOMUtlProcDlSf ARGS(( RgDlSf *dlSf, RgCellCb *cellCb, + RgErrInfo *err)); +#else +PUBLIC S16 rgTOMUtlProcDlSf ARGS((RgDlSf *dlSf, RgCellCb *cellCb, + RgErrInfo *err)); +#endif +PRIVATE S16 rgTOMProcCrntiCEInDatInd ARGS(( +RgMacPdu *pdu, +RgUeCb *prevUeCb, +RgCellCb *cellCb, +TfuDatInfo *datInfo, +RgInfCeInfo *ceInfo, +U8 subframe +)); + +PRIVATE S16 rgTOMProcCCCHSduInDatInd ARGS(( +RgMacPdu *pdu, +RgUeCb *prevUeCb, +RgCellCb *cellCb, +TfuDatInfo *datInfo, +RgInfCeInfo *ceInfo, +U8 subframe +)); + +PUBLIC S16 rgHndlFlowCntrl +( +RgCellCb *cell, +RgInfSfAlloc *sfInfo +); + +EXTERN S16 RgUiRguFlowCntrlInd(Pst* pst, SuId suId, RguFlowCntrlInd *flowCntrlInd); +#ifdef EMTC_ENABLE +EXTERN S16 rgEmtcHndl(RgCellCb *cell,RgInfSfAlloc *sfInfo); +EXTERN S16 rgTOMEmtcUtlFillDatReqPdus(TfuDatReqInfo *datInfo, RgDlSf *dlSf, RgCellCb *cell, RgErrInfo *err); +EXTERN Void rgTOMEmtcRlsSf(RgDlSf *dlSf); +#endif +#ifdef LTE_L2_MEAS +PRIVATE Void rgTOML2MCompileActiveLCs ARGS +(( + RgCellCb *cellCb, + RgUeCb *ueCb, + RgMacPdu *pdu, + RgInfCeInfo *ceInfo + )); +PRIVATE S16 rgTOMUtlL2MStoreBufSz ARGS +(( + RgUeCb *ueCb, + RgInfCeInfo *ceInfo + )); + +PRIVATE S16 rgTomUtlPrepareL2MUlThrpInfo ARGS +(( + RgCellCb *cellCb, + RgUeCb *ueCb, + RgRguDedDatInd *dDatInd +)); + + +/* The below table takes lower values of BSR Range for a BSR value + This is to ensure that outstanding can be decrease to zero upon reception of + TB, which is not guaranteed if higher Range values are used */ + /* Note: taking value 10 for BSR index 1 */ +#ifndef MAC_5GTF_UPDATE +PRIVATE U32 rgLwrBsrTbl[64] = { + 0, 10, 10, 12, 14, 17, 19, 22, 26, + 31, 36, 42, 49, 57, 67, 78, 91, + 107, 125, 146, 171, 200, 234, 274, 321, + 376, 440, 515, 603, 706, 826, 967, 1132, + 1326, 1552, 1817, 2127, 2490, 2915, 3413, 3995, + 4677, 5476, 6411, 7505, 8787, 10287, 12043, 14099, + 16507, 19325, 22624, 26487, 31009, 36304, 42502, 49759, + 58255, 68201, 79846, 93479, 109439, 128125, 150000 +}; +#else + +PRIVATE U32 rgLwrBsrTbl[64] = { +0,10,13,16,19,23,29,35,43,53,65,80,98,120,147,181,223,274,337,414, +509,625,769,945,1162,1429,1757,2161,2657,3267,4017,4940,6074,7469, +9185,11294,13888,17077,20999,25822,31752,39045,48012,59039,72598, +89272,109774,134986,165989,204111,250990,308634,379519,466683, +573866,705666,867737,1067031,1312097,1613447,1984009,2439678, +3000000}; + +#endif + +#endif + +/* local defines */ +#define RG_TOM_INF_ALLOC(_pdu, _size, _dataPtr, _ret) {\ + _ret = cmGetMem((Ptr)&_pdu->memCp, _size, (Ptr *)&_dataPtr); \ +} + +/* global variables */ +PUBLIC U32 rgUlrate_tfu; +#ifdef EMTC_ENABLE +EXTERN U32 grgUlrate_tfu; +#endif + +/** @brief This function fills the PDSCH data of a downlink subframe + * + * @details + * + * Function: rgTOMUtlFillDatReqPdus + * + * Processing steps: + * - Fill BCCH on DLSCH data using datInfo + * - Fill PCCH on DLSCH data using datInfo + * - Fill Dedicated data on DLSCH data using datInfo + * - Fill RA RSP data using datInfo + * + * @param [out] TfuDatReqInfo *datInfo + * @param [in] RgDlSf *dlSf + * @param [in] RgCellCb *cellCb + * @param [out] RgErrInfo *err + * @return S16 + * -# ROK + * -# RFAILED + */ +#ifdef ANSI +PRIVATE S16 rgTOMUtlFillDatReqPdus +( + TfuDatReqInfo *datInfo, + RgDlSf *dlSf, + RgCellCb *cellCb, + RgErrInfo *err + ) +#else +PRIVATE S16 rgTOMUtlFillDatReqPdus(datInfo, dlSf, cellCb, err) + TfuDatReqInfo *datInfo; + RgDlSf *dlSf; + RgCellCb *cellCb; + RgErrInfo *err; +#endif +{ + S16 ret; + TfuDatReqPduInfo *datReq=NULLP; + /* Moving node declaration to limited scope for optimization */ + RgDlHqProcCb *hqCb; + U8 idx; + Inst inst = cellCb->macInst - RG_INST_START; + + TRC2(rgTOMUtlFillDatReqPdus) + + /* first lets send the BCCH data down to PHY */ + if (dlSf->bcch.tb != NULLP) + { + if ((ret = rgGetEventMem(inst,(Ptr *)&datReq, sizeof(TfuDatReqPduInfo), + &(datInfo->memCp))) != ROK) + { + err->errCause = RGERR_TOM_MEM_EXHAUST; + RLOG_ARG0(L_ERROR,DBG_CELLID,cellCb->cellId,"Memory Exhaustion "); + RETVALUE(ret); + } +#ifdef TFU_ALLOC_EVENT_NO_INIT +#ifndef L2_OPTMZ + datReq->mBuf[1] = 0; +#else + datReq->tbInfo[0].lchInfo[0].mBuf[0]=NULLP; +#endif +#endif + datReq->rnti = RG_SI_RNTI; + datReq->dciInfo = dlSf->bcch.pdcch.dci; + /* Note: SCpyMsgMsg is not done since free of unsent buffer + * has been taken care through cell delete by invoking rgTomRlsSf + * during shutdown */ + datReq->nmbOfTBs = 1; +#ifndef L2_OPTMZ + datReq->mBuf[0] = dlSf->bcch.tb; +#else + SFndLenMsg((Buffer *)dlSf->bcch.tb, &(datReq->tbInfo[0].tbSize)); + datReq->tbInfo[0].tbPres = TRUE; + datReq->tbInfo[0].lchInfo[0].mBuf[0] = dlSf->bcch.tb; + datReq->tbInfo[0].numLch = 1; + datReq->tbInfo[0].lchInfo[0].numPdu = 1; + +#ifdef TFU_ALLOC_EVENT_NO_INIT + datReq->tbInfo[1].tbPres = FALSE; + datReq->tbInfo[1].lchInfo[0].mBuf[0] = NULLP; +#endif +#endif + cmLListAdd2Tail(&datInfo->pdus, &(datReq->lnk)); + datReq->lnk.node = (PTR)datReq; +#ifdef TFU_UPGRADE + /* ccpu00132314-ADD- Adding txPower offset for the PDSCH transmission */ + datReq->txPwrOffset = dlSf->bcch.txPwrOffset; +#endif + /* Setting the pointer to NULL post transmission */ + dlSf->bcch.tb = NULLP; + } + /* Fill PCCH data */ + if (dlSf->pcch.tb != NULLP) + { + if ((ret = rgGetEventMem(inst,(Ptr *)&datReq, sizeof(TfuDatReqPduInfo), + &(datInfo->memCp))) != ROK) + { + err->errCause = RGERR_TOM_MEM_EXHAUST; + RLOG_ARG1(L_ERROR,DBG_CELLID,cellCb->cellId,"Memory Exhaustion CRNTI:%d",datReq->rnti); + RETVALUE(ret); + } +#ifdef TFU_ALLOC_EVENT_NO_INIT +#ifndef L2_OPTMZ + datReq->mBuf[1] = 0; +#endif +#endif + datReq->rnti = RG_P_RNTI; + datReq->dciInfo = dlSf->pcch.pdcch.dci; + datReq->nmbOfTBs = 1; +#ifndef L2_OPTMZ + datReq->mBuf[0] = dlSf->pcch.tb; +#else + SFndLenMsg((Buffer *)dlSf->pcch.tb, &datReq->tbInfo[0].tbSize); + datReq->tbInfo[0].tbPres = TRUE; + datReq->tbInfo[0].lchInfo[0].mBuf[0] = dlSf->pcch.tb; +#ifdef TFU_ALLOC_EVENT_NO_INIT + datReq->tbInfo[1].tbPres = FALSE; + datReq->tbInfo[1].lchInfo[0].mBuf[0] = NULLP; +#endif + datReq->tbInfo[0].numLch = 1; + datReq->tbInfo[0].lchInfo[0].numPdu = 1; +#endif + cmLListAdd2Tail(&datInfo->pdus, &(datReq->lnk)); + datReq->lnk.node = (PTR)datReq; +#ifdef TFU_UPGRADE + /* ccpu00132314-ADD- Adding txPower offset for the PDSCH transmission */ + datReq->txPwrOffset = dlSf->pcch.txPwrOffset; +#endif + dlSf->pcch.tb = NULLP; + } + + for(idx=0; idx < dlSf->numRaRsp; idx++) + { + if ((ret = rgGetEventMem(inst,(Ptr *)&datReq, sizeof(TfuDatReqPduInfo), + &(datInfo->memCp))) != ROK) + { + err->errCause = RGERR_TOM_MEM_EXHAUST; + RLOG_ARG1(L_ERROR,DBG_CELLID,cellCb->cellId,"Memory Exhaustion CRNTI:%d", + datReq->rnti); + RETVALUE(ret); + } +#ifdef TFU_ALLOC_EVENT_NO_INIT +#ifndef L2_OPTMZ + datReq->mBuf[1] = 0; +#endif +#endif + datReq->rnti = dlSf->raRsp[idx].pdcch.rnti; + datReq->dciInfo = dlSf->raRsp[idx].pdcch.dci; + datReq->nmbOfTBs = 1; +#ifndef L2_OPTMZ + datReq->mBuf[0] = dlSf->raRsp[idx].rar; +#else + SFndLenMsg((Buffer *)dlSf->raRsp[idx].rar, &datReq->tbInfo[0].tbSize); + datReq->tbInfo[0].tbPres = TRUE; + datReq->tbInfo[0].lchInfo[0].mBuf[0] = dlSf->raRsp[idx].rar; +#ifdef TFU_ALLOC_EVENT_NO_INIT + datReq->tbInfo[1].lchInfo[0].mBuf[0] = NULLP; + datReq->tbInfo[1].tbPres = FALSE; +#endif + datReq->tbInfo[0].numLch = 1; + datReq->tbInfo[0].lchInfo[0].numPdu = 1; + // prc_trace_format_string(0x40,3,"UE Id=(%d) tbSz=(%d)",datReq->rnti, datReq->tbInfo[0].tbSize); +#endif + cmLListAdd2Tail(&datInfo->pdus, &(datReq->lnk)); + datReq->lnk.node = (PTR)datReq; +#ifdef TFU_UPGRADE + /* ccpu00132314-ADD- Adding txPower offset for the PDSCH transmission */ + datReq->txPwrOffset = dlSf->raRsp[idx].txPwrOffset; +#endif + dlSf->raRsp[idx].rar = NULLP; + } + + /* Fill Dedicated UE data */ + if (dlSf->tbs.count != 0) + { + CmLList *node; + while (dlSf->tbs.first) + { + node = dlSf->tbs.first; + hqCb = (RgDlHqProcCb*)node->node; + if ((ret = rgDHMSndDatReq (cellCb, dlSf, datInfo, hqCb, err)) != ROK) + { + RLOG_ARG0(L_ERROR,DBG_CELLID,cellCb->cellId, + "DHM unable to fill DATA request"); + err->errType = RGERR_TOM_TTIIND; + continue; + } + } /* end of while */ + } + + RETVALUE(ROK); +} /* end of rgTOMUtlFillDatReqPdus*/ + +/** @brief This function does all the processing related to a single downlink + * subframe. + * + * @details + * + * Function: rgTOMUtlProcDlSf + * + * Processing steps: + * - collate control data for all UEs and send to PHY + * - collate data buffers for all UEs and send to PHY + * + * @param [in] RgDlSf *dlSf + * @param [in] RgCellCb *cellCb + * @param [out] RgErrInfo *err + * @return S16 + */ +/* ADD Changes for Downlink UE Timing Optimization */ +#ifndef LTEMAC_DLUE_TMGOPTMZ +#ifdef ANSI +PRIVATE S16 rgTOMUtlProcDlSf +( + RgDlSf *dlSf, + RgCellCb *cellCb, + RgErrInfo *err + ) +#else +PRIVATE S16 rgTOMUtlProcDlSf (dlSf, cellCb, err) + RgDlSf *dlSf; + RgCellCb *cellCb; + RgErrInfo *err; +#endif +#else +#ifdef ANSI +PUBLIC S16 rgTOMUtlProcDlSf +( + RgDlSf *dlSf, + RgCellCb *cellCb, + RgErrInfo *err + ) +#else +PUBLIC S16 rgTOMUtlProcDlSf (dlSf, cellCb, err) + RgDlSf *dlSf; + RgCellCb *cellCb; + RgErrInfo *err; +#endif +#endif +{ + S16 ret; + TfuDatReqInfo *datInfo; + Inst inst = cellCb->macInst - RG_INST_START; + + TRC2(rgTOMUtlProcDlSf); + + /* Fill Data Request Info from scheduler to PHY */ + if ((ret = rgAllocEventMem(inst,(Ptr *)&datInfo, + sizeof(TfuDatReqInfo))) != ROK) + { + RLOG_ARG0(L_ERROR,DBG_CELLID,cellCb->cellId,"Unable to Allocate TfuDatReqInfo"); + RETVALUE(ret); + } + else + { + cmLListInit(&datInfo->pdus); +#ifdef LTE_TDD + RGADDTOCRNTTIME(dlSf->schdTime, datInfo->timingInfo, TFU_DELTA); +#else + RGADDTOCRNTTIME(dlSf->schdTime, datInfo->timingInfo, TFU_DLDATA_DLDELTA); +#endif + datInfo->cellId = cellCb->cellId; + if((0 == (datInfo->timingInfo.sfn % 30)) && (0 == datInfo->timingInfo.subframe)) + { + //printf("5GTF_CHECK rgTOMUtlProcDlSf dat (%d : %d)\n", datInfo->timingInfo.sfn, datInfo->timingInfo.subframe); + } +#ifdef TFU_ALLOC_EVENT_NO_INIT + datInfo->bchDat.pres = 0; +#endif + + /* Fill BCH data */ + if (dlSf->bch.tb != NULLP) + { + datInfo->bchDat.pres = PRSNT_NODEF; + datInfo->bchDat.val = dlSf->bch.tb; + dlSf->bch.tb = NULLP; + } +#ifdef EMTC_ENABLE + /* Fill the DLSCH PDUs of BCCH, PCCH and Dedicated Channels */ + if ((ret = rgTOMEmtcUtlFillDatReqPdus(datInfo, dlSf, cellCb, err)) != ROK) + { + RG_FREE_MEM(datInfo); + RETVALUE(ret); + } +#endif + /* Fill the DLSCH PDUs of BCCH, PCCH and Dedicated Channels */ + if ((ret = rgTOMUtlFillDatReqPdus(datInfo, dlSf, cellCb, err)) != ROK) + { + RLOG_ARG0(L_ERROR,DBG_CELLID,cellCb->cellId,"Unable to send data for cell"); + RG_FREE_MEM(datInfo); + RETVALUE(ret); + } + if((datInfo->pdus.count) || (datInfo->bchDat.pres == TRUE)) + { + /* sending the data to Phy */ + if (rgLIMTfuDatReq(inst,datInfo) != ROK) + { + RLOG_ARG0(L_ERROR,DBG_CELLID,cellCb->cellId,"Unable to send data info for cell"); + } + } + else + { + /* Nothing to send: free the allocated datInfo */ + RG_FREE_MEM(datInfo); + } + } + RETVALUE(ROK); +} /* end of */ + +U32 rgMacGT; + +/** + * @brief Handler for processing TTI indication recieved from + * PHY for a cell. + * + * @details + * + * Function: rgTOMTtiInd + * + * Handler for processing TTI indication recieved from PHY + * for a cell. + * + * Invoked by: RgLiTfuTtiInd + * + * Processing Steps: + * - Get cell and update the cell's current time with the timing value given + * by PHY + * - Invoke the cmPrcTmr to process the timing queue. + * - Append the PHICH information to the downlink subframe that needs to go + * out to PHY in this subframe. + * - Invoke DHM to release the downlink subframe that occured earlier + * rgDHMRlsDlsfHqProc. + * - Invoke the TTI handler of scheduler. + * - Invoke the TTI handler of RAM module. + * - Get the downlink subframe that has to go out to PHY in this subframe + * rgSCHSubFrmGet. + * - Invoke rgTOMUtlProcTA to perform and timing advance processing. + * - Invoke rgTOMUtlProcDlSf to do further processing on the downlink + * subframe. + * - Get the downlink subframe that would occur after RG_DL_DELTA and + * invoke rgTOMUtlProcDlSfStaInd to send status indications to the higher + * layer. + * - Invoke GOM's TTI handler rgGOMTtiHndlr + * - Invoke COM's TTI handler rgCOMTtiHndlr + * + * @param[in] Inst inst + * @param[in] TfuTtiIndInfo *ttiInd + * @return S16 + * -# ROK + * -# RFAILED + **/ +#if (defined (MAC_FREE_RING_BUF) || defined (RLC_FREE_RING_BUF)) +pthread_t gMacTId = 0; +#endif +#ifdef ANSI +PUBLIC S16 rgTOMTtiInd +( +Inst inst, +TfuTtiIndInfo *ttiInfo +) +#else +PUBLIC S16 rgTOMTtiInd(inst, ttiInfo) +Inst inst; +TfuTtiIndInfo *ttiInfo; +#endif +{ + RgCellCb *cellCb; + RgErrInfo err; + RgDlSf *dlSf; +/* ADD Changes for Downlink UE Timing Optimization */ +#ifdef LTEMAC_DLUE_TMGOPTMZ + RgDlSf *prevDlSf; + CmLteTimingInfo prevTmInfo; +#endif + TfuTtiCellInfo *ttiInd = &ttiInfo->cells[0]; + + TRC2(rgTOMTtiInd); + +#ifdef MAC_FREE_RING_BUF + gMacTId = pthread_self(); +#endif + cellCb = rgCb[inst].cell; + if ((cellCb == NULLP) + ||(cellCb->cellId != ttiInd->cellId)) + { + + RLOG_ARG0(L_ERROR,DBG_CELLID,ttiInd->cellId, + "Unable to get the cellCb for cell"); + err.errType = RGERR_TOM_TTIIND; + err.errCause = RGERR_TOM_INV_CELL_ID; + RETVALUE(RFAILED); + } + RGCPYTIMEINFO(ttiInd->timingInfo, cellCb->crntTime); + if((0 == (ttiInd->timingInfo.sfn % 30)) && (0 == ttiInd->timingInfo.sfn)) + { + //printf("5GTF_CHECK rgTOMTtiInd (%d : %d)\n", ttiInd->timingInfo.sfn, ttiInd->timingInfo.subframe); + } + rgMacGT = (ttiInd->timingInfo.sfn * RG_NUM_SUB_FRAMES_5G) + ttiInd->timingInfo.subframe; +#ifdef LTE_L2_MEAS + rgL2Meas(cellCb); + /*Included to track the number of 10240 cycles completed */ + + if((cellCb->crntTime.sfn == 0) && (cellCb->crntTime.subframe==0)) + { + cellCb->ttiCycle += 1; + } + +#endif + + /*Check if we have transmitted the previous DL SF, it could be the + case that we haven't received all the DATA from RLC as yet + and thus we would not have transmitted previous DL SF yet.*/ +/* ADD Changes for Downlink UE Timing Optimization */ +#ifdef LTEMAC_DLUE_TMGOPTMZ + RGSUBFRMCRNTTIME(ttiInd->timingInfo, prevTmInfo, 1); + prevDlSf = &cellCb->subFrms[(prevTmInfo.subframe % RG_NUM_SUB_FRAMES)]; + if(FALSE == prevDlSf->txDone) + { + if (ROK != rgTOMUtlProcDlSf (prevDlSf, cellCb, &err)) + { + RLOG_ARG0(L_ERROR,DBG_CELLID,cellCb->cellId,"Unable to process " + "previous downlink subframe for cell"); + err.errType = RGERR_TOM_TTIIND; + } + + /* Mark this frame as sent */ + prevDlSf->txDone = TRUE; + + if(prevDlSf->remDatReqCnt) + { + /*We have not received 1 or more data requests from RLC, this is + error scenario. MAC & SCH need to discard the allocations for + which data request hasn't been received as yet. And MAC + needs to inform SCH about the list of UEs for which + allocation need to be discarded. */ + prevDlSf->remDatReqCnt = 0; + } + } +#endif + dlSf = &cellCb->subFrms[(ttiInd->timingInfo.subframe % RG_NUM_SUB_FRAMES)]; + + if((dlSf->txDone == TRUE) || + (!RG_TIMEINFO_SAME(ttiInd->timingInfo,dlSf->schdTime))) + { + /* MS_WORKAROUND */ +#ifndef LTEMAC_DLUE_TMGOPTMZ + TfuDatReqInfo *datInfo; + CmLteTimingInfo timingInfo; +#ifdef TFU_DL_DELTA_CHANGE + RGADDTOCRNTTIME(cellCb->crntTime, timingInfo, TFU_DLDATA_DLDELTA); +#else + RGADDTOCRNTTIME(cellCb->crntTime, timingInfo, TFU_DELTA); +#endif + /* Fill Data Request from MAC for BCH */ + if ((timingInfo.sfn % 4 == 0) && (timingInfo.subframe == 0)) + { + if (ROK != rgAllocEventMem(inst,(Ptr *)&datInfo, + sizeof(TfuDatReqInfo))) + { + RLOG_ARG0(L_ERROR,DBG_CELLID,cellCb->cellId, + "rgTOMUtlProcDlSf() Unable to Allocate TfuDatReqInfo for cell"); + RETVALUE(RFAILED); + } + else + { + cmLListInit(&datInfo->pdus); + datInfo->cellId = cellCb->cellId; + datInfo->bchDat.pres = NOTPRSNT; + datInfo->timingInfo = timingInfo; + + + /* sending the dummy data req to Phy */ + if (rgLIMTfuDatReq(inst,datInfo) != ROK) + { + RLOG_ARG0(L_ERROR,DBG_CELLID,cellCb->cellId, + "rgTOMUtlProcDlSf() Unable to send data info for cell"); + } + + } + } +#endif + /* Freeing as the part of CL Non RT Indication */ + /* TDOD : Generalize for all SOCs */ +#if !(defined(TENB_T2K3K_SPECIFIC_CHANGES) && defined(LTE_TDD)) + rgDHMFreeTbBufs(inst); +#endif + RETVALUE(ROK); + } + + /*Return if there is still some data to be received + from RLC for this DL SF. */ +/* ADD Changes for Downlink UE Timing Optimization */ +#ifdef LTEMAC_DLUE_TMGOPTMZ + if(0 != dlSf->remDatReqCnt) + { + /* Freeing as the part of CL Non RT Indication */ + /* TODO : Generalize for all SOCs and remove this flag */ +#if !(defined(TENB_T2K3K_SPECIFIC_CHANGES) && defined(LTE_TDD)) + rgDHMFreeTbBufs(inst); +#endif + RETVALUE(ROK); + } +#endif + +#ifdef XEON_SPECIFIC_CHANGES + CM_MEAS_TIME((ttiInd->timingInfo.subframe % RG_NUM_SUB_FRAMES), CM_DBG_MAC_TTI_IND, CM_DBG_MAC_DL_BR_PRC); +#endif + + if (ROK != rgTOMUtlProcDlSf (dlSf, cellCb, &err)) + { + RLOG_ARG0(L_ERROR,DBG_CELLID,ttiInd->cellId, + "Unable to process downlink subframe for cell"); + err.errType = RGERR_TOM_TTIIND; + } +#ifdef XEON_SPECIFIC_CHANGES + CM_MEAS_TIME((ttiInd->timingInfo.subframe % RG_NUM_SUB_FRAMES), CM_DBG_MAC_TTI_IND, CM_DBG_MAC_DL_AFTER_PRC); +#endif + + /* Mark this frame as sent */ + dlSf->txDone = TRUE; + + /* Freeing as the part of CL Non RT Indication */ + /* TODO : Generalize for all SOCs and remove this flag */ +#if !(defined(TENB_T2K3K_SPECIFIC_CHANGES) && defined(LTE_TDD)) + rgDHMFreeTbBufs(inst); +#endif + RETVALUE(ROK); +} /* rgTOMTtiInd */ + +/** @brief This function allocates the RgMacPdu that will be populated by DEMUX + * with the SubHeaders list and the values of the Control elements. + * + * @details + * + * Function: rgTOMUtlAllocPduEvnt + * + * Processing steps: + * @param[in] Inst inst + * @param [out] RgMacPdu **pdu + * + * @return S16 + * -# ROK + * -# RFAILED + */ +#ifdef ANSI +PRIVATE S16 rgTOMUtlAllocPduEvnt +( +Inst inst, + RgMacPdu **pdu + ) +#else +PRIVATE S16 rgTOMUtlAllocPduEvnt (inst,pdu) +Inst inst; + RgMacPdu **pdu; +#endif +{ + + Mem evntMem; + RgUstaDgn dgn; /* Alarm diagnostics structure */ + VOLATILE U32 startTime=0; + + TRC2(rgTOMUtlAllocPduEvnt); + + evntMem.region = rgCb[inst].rgInit.region; + evntMem.pool = rgCb[inst].rgInit.pool; + + /*starting Task*/ + SStartTask(&startTime, PID_TOMUTL_CMALLCEVT); + +#ifdef MS_MBUF_CORRUPTION /* Should be enabled when debugging mbuf corruption */ + MS_BUF_ADD_ALLOC_CALLER(); +#endif /* */ + + if (cmAllocEvnt (sizeof (RgMacPdu), RG_BLKSZ, &evntMem, (Ptr*)pdu) != ROK) + { + rgFillDgnParams(inst,&dgn, LRG_USTA_DGNVAL_MEM); + rgLMMStaInd(inst,LCM_CATEGORY_RESOURCE, LCM_EVENT_DMEM_ALLOC_FAIL, + LCM_CAUSE_MEM_ALLOC_FAIL, &dgn); + RLOG0(L_ERROR,"Allocation of DUX event failed"); + RETVALUE(RFAILED); + } + + /*stoping Task*/ + SStopTask(startTime, PID_TOMUTL_CMALLCEVT); + + RETVALUE(ROK); +} /* end of */ + +/** @brief This function frees up the RgMacPdu structure that has been + * populated by demux. + * + * @details + * + * Function: rgTOMUtlFreePduEvnt + * - Function frees up the RgMacPdu structure, in case of error it shall + * free up the buffer's present in the different sdu. + * + * Processing steps: + * @param [in] Inst inst + * @param [in] RgMacPdu *pdu + * @param [in] Bool *error + * @return + */ +#ifdef ANSI +PRIVATE Void rgTOMUtlFreePduEvnt +( + RgMacPdu *pdu, + Bool error + ) +#else +PRIVATE Void rgTOMUtlFreePduEvnt (pdu, error) + RgMacPdu *pdu; + Bool error; +#endif +{ + + RgMacSdu *sdu; + CmLList *node; + + TRC2(rgTOMUtlFreePduEvnt); + /* Steps of freeing up the PDU. + * 1. loop through the subHdrLst and free up all the buffers. + * 2. free up the whole event + */ + if ((error == TRUE) && (pdu->sduLst.count > 0)) + { + node = pdu->sduLst.first; + while (node) + { + sdu = (RgMacSdu*)node->node; + RG_FREE_MSG(sdu->mBuf); + node = node->next; + } + } + RG_FREE_MEM(pdu); + RETVOID; +} /* end of rgTOMUtlFreePduEvnt */ + +/** @brief This function allocates the RgMacPdu that will be populated by DEMUX + * with the SubHeaders list and the values of the Control elements. + * + * @details + * + * Function: rgTOMInfAllocPduEvnt + * + * Processing steps: + * @param [in] Inst inst + * @param [out] RgMacPdu **pdu + * + * @return S16 + * -# ROK + * -# RFAILED + */ +#ifdef ANSI +PRIVATE S16 rgTOMInfAllocPduEvnt +( +Inst inst, +RgInfSfDatInd **sfInfo + ) +#else +PRIVATE S16 rgTOMInfAllocPduEvnt (inst,sfInfo) +Inst inst; +RgInfSfDatInd **sfInfo; +#endif +{ + + Mem evntMem; + RgUstaDgn dgn; /* Alarm diagnostics structure */ + VOLATILE U32 startTime=0; + + TRC2(rgTOMInfAllocPduEvnt); + + evntMem.region = rgCb[inst].rgInit.region; + evntMem.pool = rgCb[inst].rgInit.pool; + + /*starting Task*/ + SStartTask(&startTime, PID_TOMINF_CMALLCEVT); + +#ifdef MS_MBUF_CORRUPTION /* Should be enabled when debugging mbuf corruption */ + MS_BUF_ADD_ALLOC_CALLER(); +#endif /* */ + if (cmAllocEvnt (sizeof (RgInfSfDatInd), RG_BLKSZ, &evntMem, (Ptr*)sfInfo) != ROK) + { + rgFillDgnParams(inst,&dgn, LRG_USTA_DGNVAL_MEM); + rgLMMStaInd(inst,LCM_CATEGORY_RESOURCE, LCM_EVENT_DMEM_ALLOC_FAIL, + LCM_CAUSE_MEM_ALLOC_FAIL, &dgn); + RLOG0(L_ERROR,"Allocation failed"); + RETVALUE(RFAILED); + } + + /*stoping Task*/ + SStopTask(startTime, PID_TOMINF_CMALLCEVT); + + RETVALUE(ROK); +} /* end of */ + +/** @brief This function frees up the RgMacPdu structure that has been + * populated by demux. + * + * @details + * + * Function: rgTOMInfFreePduEvnt + * - Function frees up the RgMacPdu structure, in case of error it shall + * free up the buffer's present in the different sdu. + * + * Processing steps: + * @param [in] RgMacPdu *pdu + * @param [in] Bool *error + * @return + */ +#ifdef ANSI +PRIVATE Void rgTOMInfFreePduEvnt +( +RgInfSfDatInd *sfInfo + ) +#else +PRIVATE Void rgTOMInfFreePduEvnt (sfInfo) +RgInfSfDatInd *sfInfo; +#endif +{ + TRC2(rgTOMInfFreePduEvnt); + + RG_FREE_MEM(sfInfo); + RETVOID; +} /* end of rgTOMUtlFreePduEvnt */ + +#ifdef LTE_L2_MEAS + +/** @brief This function performs the preparation of information needed to set + * L2M Scheduled UL Throughput Information for a particular UE. + * + * @details + * + * Function: rgTomUtlPrepareL2MUlThrpInfo + * This function performs the preparation of information needed to set + * L2M Scheduled UL Throughput Information for a particular UE. + * + * + * Processing steps: + * @param [in] RgCellCb *cellCb + * @param [in] RgUeCb *ueCb + * @param [out] RgRguDedDatInd *dDatInd + * @return + */ +#ifdef ANSI +PRIVATE S16 rgTomUtlPrepareL2MUlThrpInfo +( + RgCellCb *cellCb, + RgUeCb *ueCb, + RgRguDedDatInd *dDatInd + ) +#else +PRIVATE S16 rgTomUtlPrepareL2MUlThrpInfo(cellCb,ueCb,dDatInd) + RgCellCb *cellCb; + RgUeCb *ueCb; + RgRguDedDatInd *dDatInd; +#endif +{ + U8 lcId; + U8 lcgId; + U8 loop; + TRC2(rgTomUtlPrepareL2MUlThrpInfo); + + dDatInd->burstInd = RGU_L2M_UL_BURST_END; + for(loop=0;loopnumLch;loop++) + { + lcId=dDatInd->lchData[loop].lcId; + if (lcId) + { + lcgId = ueCb->ul.lcCb[lcId - 1].lcgId; + if(ueCb->ul.lcgArr[lcgId].lcgBsInfo.outStndngBs > 0) + { + dDatInd->burstInd = RGU_L2M_UL_BURST_START; + break; + } + } + } + + RETVALUE(ROK); +} /* rgTOMTtiInd */ + +#endif + +/** @brief This function is called by rgTOMDatInd. This function invokes the + * scheduler with the information of the received Data and any Control Elements + * if present. Also it generates Data indications towards the higher layers. + * + * @details + * + * Function: + * + * Processing steps: + * - Retrieves the RaCb with the rnti provided, if it doesnt exist + * return failure. + * - If UE exists then update the Schduler with any MAC CEs if present. + * - Invoke RAM module to do Msg3 related processing rgRAMProcMsg3 + * - Loop through the SDU subheaders and invoke either a common data + * indication (rgUIMSndCmnDatInd) or dedicated data indication + * (rgUIMSndDedDatInd) towards the higher layers. + * + * @param [in] RgCellCb *cellCb + * @param [in] RgUeCb *ueCb + * @param [in] CmLteRnti rnti + * @param [in] RgMacPdu *pdu + * @param [out] U32 *lcgBytes + * + * @return S16 + * -# ROK + * -# RFAILED + */ + RgUeCb *glblueCb4; + RgUeCb *glblueCb5; + +#ifdef LTEMAC_SPS +#ifdef ANSI +PRIVATE S16 rgTOMUtlProcMsg +( + RgCellCb *cellCb, + RgUeCb *ueCb, + RgMacPdu *pdu, + Bool isSpsRnti, + Bool *spsToBeActvtd, + U16 *sduSize, + U8 subframe, + U32 *lcgBytes + ) +#else +PRIVATE S16 rgTOMUtlProcMsg(cellCb, ueCb, pdu, isSpsRnti,spsToBeActvtd,sduSize, subframe, lcgBytes) + RgCellCb *cellCb; + RgUeCb *ueCb; + RgMacPdu *pdu; + Bool isSpsRnti; + Bool *spsToBeActvtd; + U16 *sduSize; + U8 subframe; + U32 *lcgBytes; +#endif +#else /* LTEMAC_SPS */ +#ifdef ANSI +PRIVATE S16 rgTOMUtlProcMsg +( + RgCellCb *cellCb, + RgUeCb *ueCb, + RgMacPdu *pdu, + U8 subframe, + U32 *lcgBytes + ) +#else +PRIVATE S16 rgTOMUtlProcMsg(cellCb, ueCb, pdu, subframe, lcgBytes) + RgCellCb *cellCb; + RgUeCb *ueCb; + RgMacPdu *pdu; + U8 subframe; + U32 *lcgByes; +#endif +#endif +{ + Inst inst = cellCb->macInst - RG_INST_START; + S16 ret; + RgRguCmnDatInd *cDatInd; + RgRguDedDatInd *dDatInd; + CmLList *node; + RgMacSdu *sdu; + MsgLen ccchSz; + MsgLen cpySz; +#ifdef LTEMAC_SPS + Pst schPst1; + RgInfSpsRelInfo relInfo; +#endif + +#ifdef LTE_L2_MEAS + U8 idx1; + U8 idx2; + RgUlSf *ulSf; + U16 totalBytesRcvd = 0; + U16 sduLen[RGU_MAX_LC] = {0}; + U8 qciVal[RGU_MAX_LC] = {0}; + U8 numPrb = 0; + +#endif + U8 lcgId; + MsgLen bufSz; + + /* Moved outside of LTE_L2_MEAS + * scope as this pointer will now be used to + * check for valid Logical Channel ID + */ + RgUlLcCb *ulLcCb; + + cDatInd = NULLP; + dDatInd = NULLP; +#ifdef LTE_L2_MEAS + ulSf = NULLP; + idx1 = 0; + idx2 = 0; +#endif +#ifdef SS_RBUF + Void *elem = NULLP; +#endif + + ulLcCb = NULLP; + + TRC2(rgTOMUtlProcMsg) + +#ifndef LTE_L2_MEAS + UNUSED(subframe); +#endif + + if(pdu->sduLst.first) + { + sdu = (RgMacSdu*)(pdu->sduLst.first->node); + glblueCb4 = ueCb; + if ((sdu->lcId == RG_CCCH_LCID)) + { + /* code for common channel dat indications */ + if ((ret = rgAllocShrablSBuf (inst,(Data**)&cDatInd, sizeof(RgRguCmnDatInd))) != ROK) + { + RETVALUE(RFAILED); + } + cDatInd->cellId = cellCb->cellId; + cDatInd->rnti = ueCb->ueId; + /* rg001.101: Corrected lcId value for common data indication */ + cDatInd->lcId = cellCb->ulCcchId; + cDatInd->pdu = sdu->mBuf; + SFndLenMsg (sdu->mBuf, &ccchSz); + /* Fix : syed Contention resolution ID copy should consider only + * 6 bytes of information from sdu->mBuf. Incase of CCCH sdu for reest + * message/psuedo reest message, ccchSz can go beyond 6 and can corrupt + * other fields of ueCb. */ + if (ccchSz >= RG_CRES_LEN) + { + SCpyMsgFix (sdu->mBuf, (MsgLen)0, RG_CRES_LEN, ueCb->contResId.resId, + &cpySz); + } +#ifdef XEON_SPECIFIC_CHANGES + CM_LOG_DEBUG(CM_LOG_ID_MAC, "CCCH SDU of size(%d) received for UE(%d) CRES[0x%x 0x%x 0x%x 0x%x 0x%x 0x%x] Time[%d %d]\n", ((S16)ccchSz), ueCb->ueId,ueCb->contResId.resId[0], ueCb->contResId.resId[1], ueCb->contResId.resId[2], ueCb->contResId.resId[3], ueCb->contResId.resId[4], ueCb->contResId.resId[5], cellCb->crntTime.sfn, cellCb->crntTime.subframe); +#endif + sdu->mBuf = NULLP; + rgUIMSndCmnDatInd(inst,cellCb->rguUlSap,cDatInd); + RETVALUE(ROK); + } /* end of common channel processing */ +#ifndef SS_RBUF + if ((ret = rgAllocShrablSBuf (inst,(Data**)&dDatInd, sizeof(RgRguDedDatInd))) != ROK) + { + RETVALUE(RFAILED); + } +#else + glblueCb5 = ueCb; + elem = SRngGetWIndx(SS_RNG_BUF_ULMAC_TO_ULRLC); + if (NULLP == elem) + { + RETVALUE(RFAILED); + } + dDatInd = (RgRguDedDatInd *)elem; + cmMemset((U8 *)dDatInd, 0x00, sizeof(RgRguDedDatInd)); +#endif + dDatInd->cellId = cellCb->cellId; + dDatInd->rnti = ueCb->ueId; + dDatInd->numLch = 0; + } +#ifdef LTE_L2_MEAS + ulSf = &cellCb->ulSf[(subframe % RG_NUM_SUB_FRAMES)]; + if(ulSf->ueUlAllocInfo != NULLP) + { + for(idx1 = 0; idx1 < ulSf->numUe; idx1++) + { + if(ulSf->ueUlAllocInfo[idx1].rnti == ueCb->ueId) + { + numPrb = ulSf->ueUlAllocInfo[idx1].numPrb; + break; + } + } + } +#endif + node = pdu->sduLst.first; + while (node) + { + sdu = (RgMacSdu*)node->node; + + ulLcCb = rgDBMGetUlDedLcCb (ueCb, sdu->lcId); + + if(ulLcCb == NULLP) + { + RLOG_ARG2(L_ERROR,DBG_CELLID,cellCb->cellId,"Unconfigured LCID:%d CRNTI:%d" + ,sdu->lcId,ueCb->ueId); + /* ccpu00128443: Fix for memory leak */ + /* Fix : syed Neccessary to set sdu->mBuf = NULLP */ + RG_FREE_MSG(sdu->mBuf); + node = node->next; + continue; + } +#ifdef RLC_STA_PROC_IN_MAC/* RLC Status PDU Processing */ + { + extern S16 kwProcDlStatusPdu(Pst *udxPst,SuId suId, + CmLteCellId cellId,CmLteRnti rnti,CmLteLcId lcId,Buffer *rlcSdu); + + if(ROK == kwProcDlStatusPdu(&(cellCb->rguDlSap->sapCfg.sapPst), + cellCb->rguDlSap->sapCfg.suId, + cellCb->cellId,ueCb->ueId,sdu->lcId,sdu->mBuf)) + { + RG_FREE_MSG(sdu->mBuf); + node = node->next; + continue; + } + } +#endif + + /* ccpu00116477- Fixed the rgUIMSndDedDatInd condition when we receive 11 sdus in the + * list we are losing 11th sdu and sending the first 10 sdus again which + * is causing the duplicate packets and eNB crashing due to access + * of the freed memory */ + if (dDatInd->numLch >= RGU_MAX_LC) + { + if ((ret = rgUIMSndDedDatInd(inst,ueCb->rguUlSap,dDatInd)) != ROK) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cellCb->cellId, + "Failed to send datIndication to RGU CRNTI:%d",ueCb->ueId); + RETVALUE(ret); + } +#ifndef SS_RBUF + if ((ret = rgAllocShrablSBuf (inst,(Data**)&dDatInd, sizeof(RgRguDedDatInd))) != ROK) + { + RETVALUE(RFAILED); + } +#else + elem = SRngGetWIndx(SS_RNG_BUF_ULMAC_TO_ULRLC); + if (NULLP == elem) + { + RETVALUE(RFAILED); + } + dDatInd = (RgRguDedDatInd *)elem; + cmMemset((U8 *)dDatInd, 0x00, sizeof(RgRguDedDatInd)); +#endif + dDatInd->cellId = cellCb->cellId; + dDatInd->rnti = ueCb->ueId; + dDatInd->numLch = 0; + } + dDatInd->lchData[dDatInd->numLch].lcId = sdu->lcId; + dDatInd->lchData[dDatInd->numLch].pdu.mBuf[dDatInd->lchData[dDatInd->numLch].pdu.numPdu] = sdu->mBuf; + dDatInd->lchData[dDatInd->numLch].pdu.numPdu++; + lcgId = ulLcCb->lcgId; + SFndLenMsg(sdu->mBuf, &bufSz); +#ifdef LTE_L2_MEAS + if(ulLcCb->measOn) + { + ueCb->ul.lcgArr[lcgId].lcgBsInfo.outStndngBs -= bufSz; + } +#endif + //if ((lcgBytes != NULLP) && (ueCb->ul.lcgArr[lcgId].isGbr == TRUE)) + if (lcgBytes != NULLP) + { + lcgBytes[lcgId] += bufSz; + } + sdu->mBuf = NULLP; + dDatInd->numLch++; +#ifdef LTEMAC_SPS + /* Check if data has come on SPS LC */ + /* KWORK_FIX: Modified the index from lcId to lcId-1 for handling lcId 10 properly */ + if (ueCb->ul.spsLcId[sdu->lcId-1] == TRUE) + { + ueCb->ul.spsDatRcvd++; + } + + if(isSpsRnti) + { + /* Data rcvd on CRNTI*/ + /* Retrieve the LCG ID of the LCID*/ + /* SPS LCG has data whose size > SID Size */ + /* Activate SPS if data recvd on SPS LCID and size > SID Packet Size */ + if((ueCb->ul.spsLcId[sdu->lcId-1] == TRUE) && + (sdu->len > RG_SPS_SID_PACKET_SIZE)) + { + *spsToBeActvtd = TRUE; + *sduSize = sdu->len; + } + } + +#endif + +#ifdef LTE_L2_MEAS + if(cellCb->qciArray[ulLcCb->qci].mask == TRUE) + { + sduLen[ulLcCb->qci] = sdu->len; + totalBytesRcvd += sdu->len; + qciVal[ulLcCb->qci] = ulLcCb->qci; + } +#endif + node = node->next; + } /* end of while for SubHeaders */ +#ifdef LTE_L2_MEAS + for(idx2 = 0; idx2 < RGU_MAX_LC; idx2++) + { + if((cellCb->qciArray[qciVal[idx2]].mask == TRUE) && + totalBytesRcvd > 0) + { + cellCb->qciArray[qciVal[idx2]].prbCount += + ((numPrb * sduLen[idx2]) / totalBytesRcvd); + } + + /* RRM_RBC_X */ + if(totalBytesRcvd > 0 && qciVal[idx2] > 0) + { + RG_UPD_GBR_PRB(cellCb, qciVal[idx2], ((numPrb * sduLen[idx2])/totalBytesRcvd)); + } + /* RRM_RBC_Y */ + } +#endif +/*Added for explicit release - start*/ +#ifdef LTEMAC_SPS + + if(isSpsRnti && dDatInd && dDatInd->numLch) + { + if(ueCb->ul.spsDatRcvd != 0) + { + ueCb->ul.explRelCntr = 0; + ueCb->ul.spsDatRcvd = 0; + } + else + { + ueCb->ul.explRelCntr++; + if (ueCb->ul.explRelCntr == ueCb->ul.explRelCnt) + { + ueCb->ul.explRelCntr = 0; + /* Indicate scheduler for explicit release */ + cmMemset((U8*)&schPst1, (U8)0, sizeof(Pst)); + rgGetPstToInst(&schPst1,inst, cellCb->schInstMap.schInst); + relInfo.cellSapId = cellCb->schInstMap.cellSapId; + relInfo.cRnti = ueCb->ueId; + relInfo.isExplRel = TRUE; + /* Release indicator is called now through the matrix in the function below */ + RgMacSchSpsRel( &schPst1, &relInfo ); + ueCb->ul.implRelCntr = 0; + } + } + } + else + { + /* SPS_FIX */ + if(ueCb->ul.spsDatRcvd != 0) + { + //ueCb->ul.implRelCntr = 0; + ueCb->ul.explRelCntr = 0; + ueCb->ul.spsDatRcvd = 0; + } + } +#endif + /*Added for explicit release - end */ + + if((dDatInd) && (dDatInd->numLch)) + { +#ifdef LTE_L2_MEAS + rgTomUtlPrepareL2MUlThrpInfo(cellCb, ueCb,dDatInd); + + RG_CALC_TTI_CNT(cellCb, dDatInd->ttiCnt); +#endif + if ((ret = rgUIMSndDedDatInd(inst,ueCb->rguUlSap,dDatInd)) != ROK) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cellCb->cellId, + "Failed to send datIndication to RGU CRNTI:%d",ueCb->ueId); + RETVALUE(ret); + } + } +#ifndef SS_RBUF + else if((dDatInd) && (0 == dDatInd->numLch)) + { + /* Free the memory allocated for dDatInd if we + * have no valid LCH PDU to send to RLC.*/ + rgFreeSharableSBuf(inst,(Data **)&dDatInd,sizeof(RgRguDedDatInd)); + } +#endif + RETVALUE(ROK); +} /* end of */ + +/** @brief This function frees up the RgMacPdu structure that has been + * populated by demux. + * + * @details + * + * Function: rgTOMUtlInsSchInfo + * - Function frees up the RgMacPdu structure, in case of error it shall + * free up the buffer's present in the different sdu. + * + * Processing steps: + * @param [in] RgMacPdu *pdu + * @param [in] Bool *error + * @return + */ +#ifdef LTEMAC_SPS +#ifdef ANSI +PRIVATE S16 rgTOMUtlInsSchInfo +( +RgMacPdu *pdu, +RgInfSfDatInd *sfInfo, +RgInfCeInfo *ceInfo, +CmLteRnti rnti, +Bool spsToBeActvtd, +U16 sduSize, +U32 *lcgBytes +) +#else +PRIVATE S16 rgTOMUtlInsSchInfo (pdu, sfInfo, ceInfo, rnti,spsToBeActvtd,sduSize, lcgBytes) +RgMacPdu *pdu; +RgInfSfDatInd *sfInfo; +RgInfCeInfo *ceInfo; +CmLteRnti rnti; +Bool spsToBeActvtd; +U16 sduSize; +U32 *lcgBytes; +#endif + +#else +#ifdef ANSI +PRIVATE S16 rgTOMUtlInsSchInfo +( +RgMacPdu *pdu, +RgInfSfDatInd *sfInfo, +RgInfCeInfo *ceInfo, +CmLteRnti rnti, +U32 *lcgBytes +) +#else +PRIVATE S16 rgTOMUtlInsSchInfo (pdu, sfInfo, ceInfo, rnti, lcgBytes) +RgMacPdu *pdu; +RgInfSfDatInd *sfInfo; +RgInfCeInfo *ceInfo; +CmLteRnti rnti; +U32 *lcgBytes; +#endif +#endif +{ + S16 ret; + RgInfUeDatInd *ueInfo; + U32 lcgId = 0; + U32 idx = 0; + + TRC2(rgTOMUtlInsSchInfo); + + RG_TOM_INF_ALLOC(sfInfo, sizeof(RgInfUeDatInd), ueInfo, ret); + + if(ROK != ret) + { + RETVALUE(RFAILED); + } + + ueInfo->rnti = rnti; + + ueInfo->ceInfo = *ceInfo; + ueInfo->ueLstEnt.node = (PTR)ueInfo; + for (lcgId = 1, idx = 0; lcgId < RGINF_MAX_LCG_PER_UE; lcgId++) + { + if (lcgBytes[lcgId] != 0) + { + /* Only GBR bytes */ + ueInfo->lcgInfo[idx].lcgId = lcgId; + ueInfo->lcgInfo[idx++].bytesRcvd = lcgBytes[lcgId]; + lcgBytes[lcgId] = 0; + } + } + cmLListAdd2Tail(&sfInfo->ueLst, &ueInfo->ueLstEnt); + RETVALUE(ROK); +} /* end of rgTOMUtlInsSchInfo */ + +#include +/** + * @brief Handler for processing data indication recieved from PHY for UEs. + * + * @details + * + * Function: rgTOMDatInd + * + * Handler for processing data indication recieved from PHY for UEs. + * + * Invoked by: RgLiTfuDatInd of LIM + * + * Processing Steps: + * For each DataInfo recieved + * - Validate the information received and retrieve cellCb + * Validate cellId, rnti + * - Call De-Mux module to decode the data rgDUXDemuxData + * - If received a CRNTI control element + * - Check if a CCCH SDU is present, if it is return failure + * - Check for the existence of UE, if its isnt present return failure. + * - Delegate the remaining processing to rgTOMUtlProcMsg3 which + * primarily informs the scheduler about the data received and + * generates Data indications towards the higher layer. + * - If only CCCH SDU is present + * - Invoke rgTOMUtlProcMsg3 for further processing. + * - If its a non-Msg3 PDU i.e. received outside of a RA procedure + * - Retrieve the UeCB + * - Validate that the received PDU contains only configured Logical + * Channels. + * - Invoke rgTOMUtlProcDatPdu for further processing. It informs the + * scheduler with the information of the received Data and generates + * DatIndications towards the higher layers. + * + * @param [in] Inst inst + * @param[in] TfuDatIndInfo *datInd + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 rgTOMDatInd +( +Inst inst, + TfuDatIndInfo *datInd + ) +#else +PUBLIC S16 rgTOMDatInd(inst,datInd) +Inst inst; + TfuDatIndInfo *datInd; +#endif +{ + S16 ret = ROK; + RgErrInfo err; + RgUeCb *ueCb; + RgUeCb *prevUeCb = NULLP; + RgCellCb *cellCb; + RgMacPdu *pdu; + RgInfSfDatInd *sfInfo; + RgInfCeInfo ceInfo; + Pst schPst; + CmLList *node; + TfuDatInfo *datInfo; + RgLowSapCb *tfuSap; + U8 subframe; +#ifdef LTEMAC_SPS + Bool isSpsRnti=FALSE; + Pst schPst1; + RgInfSpsRelInfo relInfo; + Bool spsToBeActvtd = FALSE; + U16 sduSize = 0; +#endif + U32 lcgBytes[RGINF_MAX_LCG_PER_UE]; + + + TRC2(rgTOMDatInd); +#ifdef STUB_TTI_HANDLING_5GTF + node = datInd->datIndLst.first; + for (;node; node=node->next) + { + datInfo = (TfuDatInfo*)node->node; + { + MsgLen len; + SFndLenMsg(datInfo->mBuf, &len); + rgUlrate_tfu += len; + if (rgUlrate_tfu > 100000) + { + printf("Sowmya:rgTOMDatInd datInfo->mBuf len =%d rgUlrate_tfu=%d",len,rgUlrate_tfu); + rgUlrate_tfu = 0; + } + } + } + return(RFAILED); +#endif + + cmMemset((U8 *)&lcgBytes, 0, sizeof(lcgBytes)); + + tfuSap = &(rgCb[inst].tfuSap); + ueCb = NULLP; + cellCb = rgCb[inst].cell; + if((cellCb == NULLP) || + (cellCb->cellId != datInd->cellId)) + { + + RLOG_ARG0(L_ERROR,DBG_CELLID,datInd->cellId,"Unable to get the cellCb for cell"); + RETVALUE(RFAILED); + } + /* Avoiding memset as all the fields are getting initialized further */ + + if (rgTOMInfAllocPduEvnt (inst,&sfInfo) != ROK) + { + err.errType = RGERR_TOM_DATIND; + RLOG_ARG0(L_ERROR,DBG_CELLID,datInd->cellId,"Unable to Allocate PDU for DUX cell"); + node = datInd->datIndLst.first; + RETVALUE(RFAILED); + } + cmLListInit(&sfInfo->ueLst); + sfInfo->cellId = datInd->cellId; + sfInfo->timingInfo = datInd->timingInfo; + subframe = datInd->timingInfo.subframe; + + node = datInd->datIndLst.first; + for (;node; node=node->next) + { + datInfo = (TfuDatInfo*)node->node; + { + //extern U32 ulrate_tfu; + MsgLen len; + SFndLenMsg(datInfo->mBuf, &len); +#ifdef STUB_TTI_HANDLING_5GTF + // printf("Sowmya:rgTOMDatInd datInfo->mBuf len =%d",len); +#endif + rgUlrate_tfu += len; +#ifdef EMTC_ENABLE + grgUlrate_tfu += len; +#endif + } +#ifdef STUB_TTI_HANDLING_5GTF + rgLIMUtlFreeDatIndEvnt(datInd,TRUE); +#endif + /* We shall call De-Mux to process the received buffer. We shall try and find + * out the RaCb based on the following - + * 1. If the incoming PDU contained a CCCH SDU i.e. this is message 3. + * 2. If the incoming PDU contained a CRNTI control element, i.e. we should + * have a ueCb also for this + */ + /* Lets allocate the event that needs to be passed to DUX */ + if (rgTOMUtlAllocPduEvnt (inst,&pdu) != ROK) + { + err.errType = RGERR_TOM_DATIND; + RLOG_ARG0(L_ERROR,DBG_CELLID,datInd->cellId,"Unable to Allocate PDU for DUX cell"); + rgTOMInfFreePduEvnt (sfInfo); + RETVALUE(RFAILED); + } + + if ((ret = rgDUXDemuxData (inst,pdu, &ceInfo, + &datInfo->mBuf, &err)) != ROK) + { + //exit(1); + /* Fix: sriky memory corruption precautions */ + rgTOMUtlFreePduEvnt (pdu, TRUE); + err.errType = RGERR_TOM_DATIND; + RLOG_ARG0(L_ERROR,DBG_CELLID,datInd->cellId,"DUX processing failed"); + tfuSap->sapSts.numPduDrop++; + continue; + } + /* It could be that a non-msg3 pdu contains a CRNTI Control element. We + * should check for CRNTI CE and if it exists the UECb must exist, also an + * if the CRNTI in the CE and the one with which the message came in are + * different we shall look for an raCb as well. + */ + + if (ceInfo.bitMask & RG_CCCH_SDU_PRSNT) + { + ret = rgTOMProcCCCHSduInDatInd(pdu, prevUeCb, \ + cellCb, datInfo, &ceInfo, subframe); + if (ret == RFAILED) + { + rgTOMUtlFreePduEvnt (pdu, TRUE); + err.errType = RGERR_TOM_DATIND; + tfuSap->sapSts.numPduDrop++; + continue; + } + } /* end of Msg3 processing */ + + else if (ceInfo.bitMask & RG_CRNTI_CE_PRSNT) + { + ret = rgTOMProcCrntiCEInDatInd(pdu, prevUeCb, \ + cellCb, datInfo, &ceInfo, subframe); + if (ret == RFAILED) + { + rgTOMUtlFreePduEvnt (pdu, TRUE); + err.errType = RGERR_TOM_DATIND; + tfuSap->sapSts.numPduDrop++; + continue; + } + + } /* end of CRNTI based message */ + else + { + ueCb = rgDBMGetUeCb (cellCb, datInfo->rnti); + if (ueCb == NULLP) + { +#ifdef LTEMAC_SPS + /* Try getting the UE using SPS-RNTI. */ + ueCb = rgDBMGetSpsUeCb (cellCb, datInfo->rnti); + if (ueCb != NULLP) + { + isSpsRnti = TRUE; + /* Increment implrelCntr for an empty transmission */ + if (pdu->sduLst.count == 0) + { + ueCb->ul.implRelCntr++; + if (ueCb->ul.implRelCntr == ueCb->ul.implRelCnt) + { + /* Indicate scheduler for implicit release */ + cmMemset((U8*)&schPst1, (U8)0, sizeof(Pst)); + rgGetPstToInst(&schPst1,inst, cellCb->schInstMap.schInst); + + ueCb->ul.implRelCntr = 0; + ueCb->ul.explRelCntr = 0; + relInfo.cellSapId = cellCb->schInstMap.cellSapId; + relInfo.cRnti = ueCb->ueId; + relInfo.isExplRel = FALSE; + RgMacSchSpsRel(&schPst1, &relInfo); + } + } + else + { + /* Reset the implrelCntr */ + ueCb->ul.implRelCntr = 0; + } + } + else +#endif + { + /* Perform failure if ueCb is still NULLP */ + rgTOMUtlFreePduEvnt (pdu, TRUE); + err.errType = RGERR_TOM_DATIND; + RLOG_ARG1(L_ERROR,DBG_CELLID,datInd->cellId,"RNTI:%d Unable to get the UE CB", + datInfo->rnti); + tfuSap->sapSts.numPduDrop++; + continue; + } + } +#ifdef LTE_L2_MEAS + rgTOMUtlL2MStoreBufSz(ueCb, &ceInfo); + rgTOML2MCompileActiveLCs (cellCb, ueCb, pdu, &ceInfo); +#endif +#ifdef LTEMAC_SPS + if ((ret = rgTOMUtlProcMsg(cellCb, ueCb, pdu, isSpsRnti,&spsToBeActvtd,&sduSize, subframe, (U32 *)&lcgBytes)) != ROK) +#else + if ((ret = rgTOMUtlProcMsg (cellCb, ueCb, pdu, subframe, (U32 *)&lcgBytes)) != ROK) +#endif /* LTEMAC_SPS */ + { + rgTOMUtlFreePduEvnt (pdu, TRUE); + err.errType = RGERR_TOM_DATIND; + RLOG_ARG1(L_ERROR,DBG_CELLID,datInd->cellId, + "Unable to handle Data Indication CRNTI:%d",ueCb->ueId); + tfuSap->sapSts.numPduDrop++; + continue; + } + } + + +#ifdef LTEMAC_SPS + if(rgTOMUtlInsSchInfo(pdu, sfInfo, &ceInfo, datInfo->rnti,spsToBeActvtd,sduSize, (U32 *)&lcgBytes) != ROK) +#else + if(rgTOMUtlInsSchInfo(pdu, sfInfo, &ceInfo, datInfo->rnti, (U32 *)&lcgBytes) != ROK) +#endif + + { + rgTOMInfFreePduEvnt (sfInfo); + rgTOMUtlFreePduEvnt (pdu, FALSE); + RETVALUE(RFAILED); + } + /* free up the PDU memory */ + rgTOMUtlFreePduEvnt (pdu, FALSE); + } + /* Free the allocated memory for ueUlAllocInfo here */ +#ifdef LTE_L2_MEAS + if(cellCb->ulSf[(subframe % RG_NUM_SUB_FRAMES)].ueUlAllocInfo != NULLP) + { + /*ccpu00117052 - MOD - Passing double for proper NULLP + assignment */ + rgFreeSBuf(inst,(Data **)&(cellCb->ulSf[(subframe % RG_NUM_SUB_FRAMES)].ueUlAllocInfo), + ((cellCb->ulSf[(subframe % RG_NUM_SUB_FRAMES)].numUe) * sizeof(RgUeUlAlloc))); + } +#endif + /* RRM_RBC_X */ + /* Update PRB used for all GBR QCIs to scheduler */ + cmMemcpy((U8*) &sfInfo->qcisUlPrbCnt[0], + (U8*) &cellCb->qcisUlPrbCnt[0], + (RGM_MAX_QCI_REPORTS * sizeof(U32))); + /* clear the cellCb ul prb value */ + cmMemset((U8*)&cellCb->qcisUlPrbCnt[0], 0, + (RGM_MAX_QCI_REPORTS * sizeof(U32))); + + /* RRM_RBC_Y */ + + rgGetPstToInst(&schPst, inst,cellCb->schInstMap.schInst); + sfInfo->cellSapId = cellCb->schInstMap.cellSapId; + RgMacSchSfRecp(&schPst, sfInfo); + RETVALUE(ROK); +} /* rgTOMDatInd */ + +/** + * @brief Function handles allocation for common channels i.e. BCCH-BCH, + * BCCH-DLSCH, PCCH-DLSCH. + * + * @details + * + * Function : rgHndlCmnChnl + * + * This function is invoked from RgSchMacSfAllocReq. This function handles + * allocations made for common channels like BCCH and PCCH. + * + * Processing steps: + * 1. If BCCH on BCH has been scheduled, send StatusIndication on RGU. + * 2. If PCCH is scheduled, send StatusIndication on RGU. + * 3. If BCCH on DLSCH has been scheduled and sndStatInd is TRUE, send + * StatusIndication on RGU, else copy the bcch buffer onto the downlink + * subframe. + * + * + * @param[in] RgCellCb *cell, + * @param[in] CmLteTimingInfo timingInfo, + * @param[in] RgInfCmnLcInfo *cmnLcInfo, + * @param[in/out] RgErrInfo *err, + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PRIVATE S16 rgHndlCmnChnl +( +RgCellCb *cell, +CmLteTimingInfo timingInfo, +RgInfCmnLcInfo *cmnLcInfo, +RgErrInfo *err +) +#else +PRIVATE S16 rgHndlCmnChnl(cell, timingInfo, cmnLcInfo, err) +RgCellCb *cell; +CmLteTimingInfo timingInfo; +RgInfCmnLcInfo *cmnLcInfo; +RgErrInfo *err; +#endif +{ + #if (ERRCLASS & ERRCLS_DEBUG) + RgPcchLcCb *pcch; + #endif +#ifndef RGR_SI_SCH + RgBcchDlschLcCb *bcch; +#if (ERRCLASS & ERRCLS_DEBUG) + RgBcchBchLcCb *bch; +#endif +#endif/*RGR_SI_SCH*/ + RguCStaIndInfo *staInd; + RgDlSf *dlSf; + Inst inst = cell->macInst - RG_INST_START; + + TRC2(rgHndlCmnChnl) + + dlSf = &cell->subFrms[(timingInfo.subframe % RG_NUM_SUB_FRAMES)]; + + if(cmnLcInfo->bitMask & RGINF_BCH_INFO) + { +#ifndef RGR_SI_SCH + #if (ERRCLASS & ERRCLS_DEBUG) + if(NULLP == (bch = rgDBMGetBcchOnBch(cell))) + { + RETVALUE(RFAILED); + } + if(cmnLcInfo->bchInfo.lcId != bch->lcId) + { + RETVALUE(RFAILED); + } + #endif + + if (rgAllocShrablSBuf (inst,(Data**)&staInd, sizeof(RguCStaIndInfo)) != ROK) + { + err->errCause = RGERR_TOM_MEM_EXHAUST; + RETVALUE(RFAILED); + } + staInd->cellId = cell->cellId; + staInd->rnti = RG_INVALID_RNTI; + staInd->lcId = cmnLcInfo->bchInfo.lcId; + staInd->transId = (timingInfo.sfn << 8) | (timingInfo.subframe); +/* ADD Changes for Downlink UE Timing Optimization */ +#ifdef LTEMAC_DLUE_TMGOPTMZ + dlSf->remDatReqCnt++; +#endif + if (rgUIMSndCmnStaInd (inst,cell->rguDlSap,staInd) != ROK) + { + RETVALUE(RFAILED); + } +#else + /*Store the received BCH Data in the scheduled subframe*/ + dlSf->bch.tb = cmnLcInfo->bchInfo.pdu; +#endif/*RGR_SI_SCH*/ + } + + if(cmnLcInfo->bitMask & RGINF_PCCH_INFO) + { + #if (ERRCLASS & ERRCLS_DEBUG) + if(NULLP == (pcch = rgDBMGetPcch(cell))) + { + RETVALUE(RFAILED); + } + if(cmnLcInfo->pcchInfo.lcId != pcch->lcId) + { + RETVALUE(RFAILED); + } + #endif + + dlSf->pcch.pdcch.rnti = + cmnLcInfo->pcchInfo.rnti; + dlSf->pcch.pdcch.dci = + cmnLcInfo->pcchInfo.dciInfo; +#ifdef TFU_UPGRADE + /* ccpu00132314-ADD-Fill the tx Pwr offset from scheduler */ + dlSf->pcch.txPwrOffset = cmnLcInfo->pcchInfo.txPwrOffset; +#endif + if (rgAllocShrablSBuf (inst,(Data**)&staInd, sizeof(RguCStaIndInfo)) != ROK) + { + err->errCause = RGERR_TOM_MEM_EXHAUST; + RETVALUE(RFAILED); + } + staInd->cellId = cell->cellId; + staInd->rnti = RG_INVALID_RNTI; + staInd->lcId = cmnLcInfo->pcchInfo.lcId; + staInd->transId = (timingInfo.sfn << 8) | (timingInfo.subframe); +/* ADD Changes for Downlink UE Timing Optimization */ +#ifdef LTEMAC_DLUE_TMGOPTMZ + dlSf->remDatReqCnt++; +#endif + /* for consolidated CmnStaInd calling below function from function + * rgHndlSchedUe once CmnStaInd prepared for all UEs + */ + if (rgUIMSndCmnStaInd (inst,cell->rguDlSap,staInd) != ROK) + { + RETVALUE(RFAILED); + } + } + + if(cmnLcInfo->bitMask & RGINF_BCCH_INFO) + { + dlSf->bcch.pdcch.rnti = + cmnLcInfo->bcchInfo.rnti; + dlSf->bcch.pdcch.dci = + cmnLcInfo->bcchInfo.dciInfo; +#ifdef TFU_UPGRADE + /* ccpu00132314-ADD-Fill the tx Pwr offset from scheduler */ + dlSf->bcch.txPwrOffset = cmnLcInfo->bcchInfo.txPwrOffset; +#endif +#ifndef RGR_SI_SCH + if(NULLP == + (bcch=rgDBMGetBcchOnDlsch(cell,cmnLcInfo->bcchInfo.lcId))) + { + RETVALUE(RFAILED); + } + if(TRUE == cmnLcInfo->bcchInfo.sndStatInd) + { + RG_FREE_MSG(bcch->tb); + if (rgAllocShrablSBuf (inst,(Data**)&staInd, + sizeof(RguCStaIndInfo)) != ROK) + { + err->errCause = RGERR_TOM_MEM_EXHAUST; + RETVALUE(RFAILED); + } + staInd->cellId = cell->cellId; + staInd->rnti = RG_INVALID_RNTI; + staInd->lcId = cmnLcInfo->bcchInfo.lcId; + staInd->transId = (timingInfo.sfn << 8) | (timingInfo.subframe); +/* ADD Changes for Downlink UE Timing Optimization */ +#ifdef LTEMAC_DLUE_TMGOPTMZ + dlSf->remDatReqCnt++; +#endif + if (rgUIMSndCmnStaInd (inst,cell->rguDlSap,staInd) != ROK) + { + RETVALUE(RFAILED); + } + } + else + { + SCpyMsgMsg(bcch->tb, RG_GET_MEM_REGION(rgCb[inst]), + RG_GET_MEM_POOL(rgCb[inst]), &dlSf->bcch.tb); + } +#else + /*Store the received BCCH Data in the scheduled subframe*/ + dlSf->bcch.tb = cmnLcInfo->bcchInfo.pdu; +#endif/*RGR_SI_SCH*/ + } + + RETVALUE(ROK); +} /* end of rgHndlCmnChnl */ + +/** + * @brief Function for handling allocations for dedicated channels for a + * subframe. + * + * @details + * + * Function : rgHndlSchdUe + * + * This function shall be invoked whenever scheduler is done with the + * allocations of dedicated channels for a subframe. Invoked by the function + * RgSchMacSfAllocReq. + * + * Processing steps : + * 1. Loops through the list of UE's scheduled looking for the corresponding + * ueCb/raCb. + * 2. Finds the corresponding HARQ process. + * 3. Invokes the DHM function to issue StatusIndications on RGU. + * + * + * @param[in] RgCellCb *cell, + * @param[in] CmLteTimingInfo timingInfo, + * @param[in] RgInfUeInfo *ueInfo + * @param[in/out] RgErrInfo *err + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PRIVATE S16 rgHndlSchdUe +( +RgCellCb *cell, +CmLteTimingInfo timingInfo, +RgInfUeInfo *ueInfo, +RgErrInfo *err +) +#else +PRIVATE S16 rgHndlSchdUe(cell, timingInfo, ueInfo, err) /* laa_ut_fix */ +RgCellCb *cell; +CmLteTimingInfo timingInfo; +RgInfUeInfo *ueInfo; +RgErrInfo *err; +#endif +{ + + TRC2(rgHndlSchdUe); + + if(NULLP == ueInfo->allocInfo) + { + RETVALUE(RFAILED); + } + + rgDHMSndConsolidatedStaInd(cell, ueInfo, timingInfo, err); + + RETVALUE(ROK); +} /* end of rgHndlSchdUe */ + +#ifdef LTE_L2_MEAS +/** + * @brief Function for handling Uplink allocations for Ue for a + * subframe. + * + * @details + * + * Function : rgHndlUlUeInfo + * + * @param[in] RgCellCb *cell, + * @param[in] CmLteTimingInfo timingInfo, + * @param[in] RgInfUlUeInfo *ueInfo + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PRIVATE S16 rgHndlUlUeInfo +( +RgCellCb *cell, +CmLteTimingInfo timingInfo, +RgInfUlUeInfo *ueInfo +) +#else +PRIVATE S16 rgHndlUlUeInfo(cell, timingInfo, ueInfo) +RgCellCb *cell; +CmLteTimingInfo timingInfo; +RgInfUlUeInfo *ueInfo; +#endif +{ + Inst inst = cell->macInst - RG_INST_START; + U8 idx; + RgUlSf *ulSf; + S16 ret; + + TRC2(rgHndlUlUeInfo) + + ulSf = &cell->ulSf[(timingInfo.subframe % RGSCH_NUM_SUB_FRAMES)]; + + /* rg003.301-MOD- Corrected the purifier memory leak */ + if (ulSf->numUe != ueInfo->numUes) + { + if (ulSf->ueUlAllocInfo) + { + rgFreeSBuf(inst,(Data **)&(ulSf->ueUlAllocInfo), + ulSf->numUe * sizeof(RgUeUlAlloc)); + } + } +#ifdef XEON_SPECIFIC_CHANGES + CM_MEAS_TIME((cell->crntTime.subframe % RGSCH_NUM_SUB_FRAMES), CM_DBG_MAC_TTI_IND, CM_DBG_MEAS_FREE); + CM_ADD_INFO((cell->crntTime.subframe % RGSCH_NUM_SUB_FRAMES), CM_DBG_MEAS_FREE, ulSf->numUe); +#endif + ulSf->numUe = ueInfo->numUes; + if((ulSf->ueUlAllocInfo == NULLP) && (ueInfo->numUes > 0)) + { + /* Allocate memory for ulAllocInfo */ + if((ret = rgAllocSBuf(inst,(Data**)&(cell->ulSf[(timingInfo.subframe % RGSCH_NUM_SUB_FRAMES)]. + ueUlAllocInfo), ueInfo->numUes * sizeof(RgUeUlAlloc))) != ROK) + { + RETVALUE(ret); + } + } +#ifdef XEON_SPECIFIC_CHANGES + CM_MEAS_TIME((cell->crntTime.subframe % RGSCH_NUM_SUB_FRAMES), CM_DBG_MAC_TTI_IND, CM_DBG_MEAS_ALLOC); + CM_ADD_INFO((cell->crntTime.subframe % RGSCH_NUM_SUB_FRAMES), CM_DBG_MEAS_ALLOC, ueInfo->numUes); +#endif + if (ulSf->ueUlAllocInfo != NULLP) + { + for(idx = 0; idx < ueInfo->numUes; idx++) + { + ulSf->ueUlAllocInfo[idx].rnti = ueInfo->ulAllocInfo[idx].rnti; + ulSf->ueUlAllocInfo[idx].numPrb = ueInfo->ulAllocInfo[idx].numPrb; + } + } + RGCPYTIMEINFO(timingInfo, ulSf->schdTime); + RETVALUE(ROK); +} /* end of rgHndlUlUeInfo */ +#endif +/** + * @brief Function for handling RaResp request received from scheduler to MAC + * + * @details + * + * Function : rgTOMRlsSf + * + * This function shall be invoked whenever scheduler is done with the + * allocations of random access responses for a subframe. + * This shall invoke RAM to create ueCbs for all the rapIds allocated and + * shall invoke MUX to create RAR PDUs for raRntis allocated. + * + * + * @param[in] Inst inst + * @param[in] CmLteCellId cellId, + * @param[in] CmLteTimingInfo timingInfo, + * @param[in] RaRespInfo *rarInfo + * @return S16 + * -# ROK + **/ +#ifdef ANSI +PUBLIC Void rgTOMRlsSf +( +Inst inst, +RgDlSf *dlSf +) +#else +PUBLIC Void rgTOMRlsSf(dlSf) +Inst inst; +RgDlSf *dlSf; +#endif +{ + U8 idx; + + TRC2(rgTOMRlsSf) + + if(dlSf->txDone == FALSE) + { + RLOG0(L_ERROR, "SUBFRAME Not pushed to the PHY"); + + if (dlSf->bch.tb != NULLP) + { + RG_FREE_MSG(dlSf->bch.tb); + } + if (dlSf->bcch.tb != NULLP) + { + RG_FREE_MSG(dlSf->bcch.tb); + } + if (dlSf->pcch.tb != NULLP) + { + RG_FREE_MSG(dlSf->pcch.tb); + } +#ifdef EMTC_ENABLE + rgTOMEmtcRlsSf(dlSf); +#endif + for(idx=0; idx < dlSf->numRaRsp; idx++) + { + RG_FREE_MSG(dlSf->raRsp[idx].rar); + } + } +/* ADD Changes for Downlink UE Timing Optimization */ +#ifdef LTEMAC_DLUE_TMGOPTMZ + dlSf->remDatReqCnt = 0; + /* Fix[ccpu00126310]: Tracks Data Requests from RLC for both loosely and tight coupled + RLC-MAC */ + dlSf->statIndDone = FALSE; +#endif + if (dlSf->tbs.count) + { + U8 i; + CmLList *node; + RgDlHqProcCb *hqP; + RGDBGERRNEW(inst, (rgPBuf(inst), + "Error Stale TBs in Subframes TBS list\n")); + node = dlSf->tbs.first; + while(node) + { + hqP = (RgDlHqProcCb*)node->node; + node = node->next; + if (hqP) + { + for(i=0;i< RG_MAX_TB_PER_UE;i++) + { + if (hqP->tbInfo[i].sfLnkInfo[dlSf->schdTime.subframe % 2].sf == dlSf) + { + cmLListDelFrm(&dlSf->tbs, &(hqP->tbInfo[i].sfLnkInfo[dlSf->schdTime.subframe % 2].sfLnk)); + hqP->tbInfo[i].sfLnkInfo[dlSf->schdTime.subframe % 2].sfLnk.node = NULLP; + printf("\n rgTOMRlsSf:: hqP %p \n", (Void *)hqP); + } + hqP->tbInfo[i].sfLnkInfo[dlSf->schdTime.subframe % 2].sf = NULLP; + } + } + } + } + /*arjun: check if dlSf laaTb list has to be freed???*/ + cmLListInit(&dlSf->tbs); + dlSf->txDone = FALSE; + dlSf->numRaRsp = 0; + RETVOID; +} + +/** + * @brief Function is called by the scheduler once it has completed the + * allocation for the subframe. + * + * @details + * + * Function : rgHndlFlowCntrl + * This function should fill and send Flow control + * indication to RLC + * + * + * @param[in] Pst *cell + * @param[in] RgInfSfAlloc *sfInfo Carries all the allocation + * information. + * @return S16 + * -# ROK + **/ +#ifdef ANSI +PUBLIC S16 rgHndlFlowCntrl +( +RgCellCb *cell, +RgInfSfAlloc *sfInfo +) +#else +PUBLIC S16 rgHndlFlowCntrl(cell, sfInfo) +RgCellCb *cell; +RgInfSfAlloc *sfInfo; +#endif +{ + RguFlowCntrlInd *flowCntrlInd; + Pst *pst; + U32 ueIdx; + U32 lcIdx; + TRC3(rgHndlFlowCntrl); + + pst = &cell->rguDlSap->sapCfg.sapPst; + /* flowCntrlInd is alloced in cell init time and will be re-used throughout */ + flowCntrlInd = cell->flowCntrlInd; + flowCntrlInd->cellId = sfInfo->cellId; + flowCntrlInd->numUes = sfInfo->flowCntrlInfo.numUes; + + for (ueIdx = 0; ueIdx < sfInfo->flowCntrlInfo.numUes; ueIdx++) + { + flowCntrlInd->ueFlowCntrlInfo[ueIdx].ueId = sfInfo->flowCntrlInfo.ueFlowCntrlInfo[ueIdx].ueId; + flowCntrlInd->ueFlowCntrlInfo[ueIdx].numLcs = sfInfo->flowCntrlInfo.ueFlowCntrlInfo[ueIdx].numLcs; + + for (lcIdx = 0; lcIdx < RGINF_MAX_NUM_DED_LC; lcIdx++) + { + flowCntrlInd->ueFlowCntrlInfo[ueIdx].lcInfo[lcIdx].lcId = + sfInfo->flowCntrlInfo.ueFlowCntrlInfo[ueIdx].lcInfo[lcIdx].lcId; + flowCntrlInd->ueFlowCntrlInfo[ueIdx].lcInfo[lcIdx].pktAdmitCnt = + sfInfo->flowCntrlInfo.ueFlowCntrlInfo[ueIdx].lcInfo[lcIdx].pktAdmitCnt; + + flowCntrlInd->ueFlowCntrlInfo[ueIdx].lcInfo[lcIdx].maxBo4FlowCtrl = + sfInfo->flowCntrlInfo.ueFlowCntrlInfo[ueIdx].lcInfo[lcIdx].maxBo4FlowCtrl; + } + } + RgUiRguFlowCntrlInd(pst, cell->rguDlSap->sapCfg.spId,flowCntrlInd); /* TODO: Rishi confirm if the suId and pst pointer is correct */ + RETVALUE(ROK); +} +/** + * @brief Function is called by the scheduler once it has completed the + * allocation for the subframe. + * + * @details + * + * Function : RgSchMacSfAllocReq + * + * This function shall be invoked whenever scheduler is done with the + * allocations of for a subframe. The sfInfo carries all the allocation + * details for the common channels, RA responses and dedicated channel + * allocations. + * + * Processing steps : + * 1. Reset the information present in the downlink subframe that is + * scheduled. + * 2. Handle common channel allocations + * 3. Handle RA Response allocations + * 4. Handle dedicated channel allocations. + * + * @param[in] Pst *pst + * @param[in] RgInfSfAlloc *sfInfo Carries all the allocation + * information. + * @return S16 + * -# ROK + **/ +#ifdef ANSI +PUBLIC S16 RgSchMacSfAllocReq +( +Pst *pst, +RgInfSfAlloc *sfInfo +) +#else +PUBLIC S16 RgSchMacSfAllocReq(pst, sfInfo) +Pst *pst; +RgInfSfAlloc *sfInfo; +#endif +{ + RgCellCb *cell; + RgDlSf *dlSf; + RgErrInfo err; + VOLATILE U32 startTime=0; + Inst inst; + + TRC2(RgSchMacSfAllocReq) + + RG_IS_INST_VALID(pst->dstInst); + inst = pst->dstInst - RG_INST_START; + /*starting Task*/ + SStartTask(&startTime, PID_MAC_SF_ALLOC_REQ); + + if(NULLP == sfInfo) + { + RETVALUE(RFAILED); + } + + if((cell = rgCb[inst].cell) == NULLP) + { + RLOG_ARG0(L_ERROR,DBG_CELLID,sfInfo->cellId, "No cellCb found with cell"); + RETVALUE(RFAILED); + } + + dlSf = &cell->subFrms[(sfInfo->timingInfo.subframe % RG_NUM_SUB_FRAMES)]; + + rgTOMRlsSf(inst,dlSf); + dlSf->schdTime = sfInfo->timingInfo; + +#ifdef LTE_ADV + rgLaaInitTbInfoLst(cell); +#endif + + /* Fix : syed Ignore Failure Returns and continue processing. + * Incomplete processing results in state sync loss between MAC-SCH. */ +#ifdef EMTC_ENABLE + if(TRUE == cell->emtcEnable) + { + rgEmtcHndl(cell, sfInfo); + } +#endif + rgHndlCmnChnl(cell, sfInfo->timingInfo, &sfInfo->cmnLcInfo, &err); + + rgHndlRaResp(cell, sfInfo->timingInfo, &sfInfo->rarInfo, &err); + +#ifdef LTE_ADV +#ifdef XEON_SPECIFIC_CHANGES + CM_MEAS_TIME((cell->crntTime.subframe % RG_NUM_SUB_FRAMES), CM_DBG_MAC_TTI_IND, CM_DBG_MAC_B4_UE_SCHD); +#endif + rgHndlSchdUe(cell, sfInfo->timingInfo, &sfInfo->ueInfo, &err); +#ifdef XEON_SPECIFIC_CHANGES + CM_MEAS_TIME((cell->crntTime.subframe % RG_NUM_SUB_FRAMES), CM_DBG_MAC_TTI_IND, CM_DBG_MAC_UE_SCHD); +#endif + rgLaaChkAndReqTbs(dlSf,cell, inst); + +#else + rgHndlSchdUe(cell, sfInfo->timingInfo, &sfInfo->ueInfo, &err); +#endif + +#ifdef LTE_L2_MEAS + if(rgHndlUlUeInfo(cell, sfInfo->ulUeInfo.timingInfo, + &sfInfo->ulUeInfo) != ROK) + { + RETVALUE(RFAILED); + } +#endif +#ifdef XEON_SPECIFIC_CHANGES + CM_MEAS_TIME((cell->crntTime.subframe % RG_NUM_SUB_FRAMES), CM_DBG_MAC_TTI_IND, CM_DBG_MAC_MEAS); +#endif + /* Fix[ccpu00126310]: Tracks Data Requests from RLC for both loosely and tight coupled + RLC-MAC */ + + + /* Added the handling for pushing down + * TFU Data request in the retransmission only scenario.*/ +#ifdef LTEMAC_DLUE_TMGOPTMZ + dlSf->statIndDone = TRUE; + /* Fix [ccpu00126310]: Tracks Data Requests from RLC for both loosely and tight coupled + RLC-MAC */ + if(!(dlSf->txDone) && +#ifdef LTE_ADV + (TRUE == rgLaaChkAllRxTbs(dlSf)) && +#endif + (0 == dlSf->remDatReqCnt) && (dlSf->statIndDone) && + (RG_TIMEINFO_SAME(cell->crntTime, dlSf->schdTime))) + { + /*This is the case of rettransmission, so no need + * to wait for TTI Ind to push TFU Data Request. Send + * it right away.*/ + if (ROK != rgTOMUtlProcDlSf (dlSf, cell, &err)) + { + RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,"Unable to process downlink subframe for cell"); + err.errType = RGERR_ROM_DEDDATREQ; + } + /* Mark this frame as sent */ + dlSf->txDone = TRUE; + } +#endif + if (sfInfo->flowCntrlInfo.numUes > 0) + { + rgHndlFlowCntrl(cell,sfInfo); + } + /*stoping Task*/ + SStopTask(startTime, PID_MAC_SF_ALLOC_REQ); + RETVALUE(ROK); +} /* end of RgSchMacSfAllocReq */ +/** + * @brief Handler for processing data indication recieved from PHY for UEs. + * + * @details + * + * Function: rgTOMProcCrntiCEInDatInd + * + * Handler for processing data indication recieved from PHY for UEs. + * + * Invoked by: RgLiTfuDatInd of LIM + * + * Processing Steps: + * For each DataInfo recieved + * - If received a CRNTI control element + * - Check if a CCCH SDU is present, if it is return failure + * - Check for the existence of UE, if its isnt present return failure. + * - Delegate the remaining processing to rgTOMUtlProcMsg3 which + * primarily informs the scheduler about the data received and + * generates Data indications towards the higher layer. + * + * @param RgMacPdu *pdu, + * @param RgUeCb *prevUeCb, + * @param RgCellCb *cellCb, + * @param TfuDatInfo *datInfo, + * @param RgInfCeInfo *ceInfo + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PRIVATE S16 rgTOMProcCrntiCEInDatInd +( +RgMacPdu *pdu, +RgUeCb *prevUeCb, +RgCellCb *cellCb, +TfuDatInfo *datInfo, +RgInfCeInfo *ceInfo, +U8 subframe +) +#else +PRIVATE S16 rgTOMProcCrntiCEInDatInd( pdu, prevUeCb, cellCb, datInfo, ceInfo, subframe) +RgMacPdu *pdu; +RgUeCb *prevUeCb; +RgCellCb *cellCb; +TfuDatInfo *datInfo; +RgInfCeInfo *ceInfo; +U8 subframe; +#endif +{ + RgUeCb *ueCb = NULLP; + Inst inst = cellCb->macInst - RG_INST_START; + + +#ifdef LTEMAC_SPS + Bool spsToBeActvtd; + U16 sduSize; +#endif + + TRC2(rgTOMProcCrntiCEInDatInd) + +#ifndef LTE_L2_MEAS + UNUSED(subframe); +#endif + + ueCb = rgDBMGetUeCbFromRachLst (cellCb, datInfo->rnti); + + if (ueCb == NULLP) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cellCb->cellId, + "RNTI:%d Received MSG3 with CRNTI,unable to find ueCb", ceInfo->ces.cRnti); + RETVALUE(RFAILED); + } + + prevUeCb = rgDBMGetUeCb (cellCb, ceInfo->ces.cRnti); + if (prevUeCb == NULLP) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cellCb->cellId, + "RNTI:%d Received MSG3 with CRNTI,unable to find ueCb", ceInfo->ces.cRnti); + RETVALUE(RFAILED); + } + RLOG_ARG2(L_DEBUG,DBG_CELLID,cellCb->cellId, + "CRNTI CE(%d) received through tmpCrnti(%d)", + ceInfo->ces.cRnti, datInfo->rnti); + rgDBMDelUeCbFromRachLst(cellCb, ueCb); + rgRAMFreeUeCb(inst,ueCb); + ueCb = prevUeCb; +#ifdef LTEMAC_SPS + if ((rgTOMUtlProcMsg(cellCb, ueCb, pdu, FALSE,&spsToBeActvtd,&sduSize, subframe, NULLP)) != ROK) +#else + if ((rgTOMUtlProcMsg (cellCb, ueCb, pdu, subframe, NULLP)) != ROK) +#endif /* LTEMAC_SPS */ + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cellCb->cellId, + "RNTI:%d Processing for MSG3 failed",datInfo->rnti); + RETVALUE(RFAILED); + } + RETVALUE(ROK); +} +/** + * @brief Handler for processing data indication recieved from PHY for UEs. + * + * @details + * + * Function: rgTOMProcCCCHSduInDatInd + * + * Handler for processing data indication recieved from PHY for UEs. + * + * Invoked by: RgLiTfuDatInd of LIM + * + * Processing Steps: + * For each DataInfo recieved + * - If only CCCH SDU is present + * - Invoke rgTOMUtlProcMsg3 for further processing. + * - If its a non-Msg3 PDU i.e. received outside of a RA procedure + * - Retrieve the UeCB + * - Validate that the received PDU contains only configured Logical + * Channels. + * - Invoke rgTOMUtlProcDatPdu for further processing. It informs the + * scheduler with the information of the received Data and generates + * DatIndications towards the higher layers. + * + * @param TfuDatIndInfo *datInd + * @param RgMacPdu *pdu, + * @param RgUeCb *prevUeCb, + * @param RgCellCb *cellCb, + * @param TfuDatInfo *datInfo, + * @param RgInfCeInfo *ceInfo + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PRIVATE S16 rgTOMProcCCCHSduInDatInd +( +RgMacPdu *pdu, +RgUeCb *prevUeCb, +RgCellCb *cellCb, +TfuDatInfo *datInfo, +RgInfCeInfo *ceInfo, +U8 subframe +) +#else +PRIVATE S16 rgTOMProcCCCHSduInDatInd( pdu, prevUeCb, cellCb, datInfo, ceInfo, subframe) +RgMacPdu *pdu; +RgUeCb *prevUeCb; +RgCellCb *cellCb; +TfuDatInfo *datInfo; +RgInfCeInfo *ceInfo; +U8 subframe; +#endif +{ + RgUeCb *ueCb = NULLP; + Inst inst = cellCb->macInst - RG_INST_START; + +#ifdef LTEMAC_SPS + Bool spsToBeActvtd; + U16 sduSize; +#endif + + + TRC2(rgTOMProcCCCHSduInDatInd) + +#ifndef LTE_L2_MEAS + UNUSED(subframe); +#endif + + if (ceInfo->bitMask & RG_CRNTI_CE_PRSNT) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cellCb->cellId, + "CRNTI:%d Received MSG3 with CCCH",ceInfo->ces.cRnti); + RETVALUE(RFAILED); + } + + ueCb = rgDBMGetUeCbFromRachLst (cellCb, datInfo->rnti); + + if (ueCb == NULLP) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cellCb->cellId, + "RNTI:%d Processing for MSG3 failed", datInfo->rnti); + RETVALUE(RFAILED); + } + /* Fix: syed Drop any duplicate Msg3(CCCH Sdu) */ + if (ueCb->dl.hqEnt.numHqProcs) + { + /* HqE is already initialized by a previuos Msg3 */ + RLOG_ARG1(L_ERROR,DBG_CELLID,cellCb->cellId,"RNTI:%d Processing for MSG3 failed. Duplicate " + "MSG3 received. Dropping", datInfo->rnti); + RETVALUE(RFAILED); + } + + if(rgDHMHqEntInit(inst,&ueCb->dl.hqEnt, + cellCb->maxDlHqProcPerUe) != ROK) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cellCb->cellId,"RNTI:%d Harq Initialization failed ", + datInfo->rnti); + RETVALUE(RFAILED); + } + RLOG_ARG1(L_DEBUG,DBG_CELLID,cellCb->cellId, + "CCCH SDU received through tmpCrnti(%d)",datInfo->rnti); +#ifdef LTEMAC_SPS + if ((rgTOMUtlProcMsg(cellCb, ueCb, pdu, FALSE,&spsToBeActvtd,&sduSize, subframe, NULLP)) != ROK) +#else + if ((rgTOMUtlProcMsg (cellCb, ueCb, pdu, subframe, NULLP)) != ROK) +#endif /* LTEMAC_SPS */ + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cellCb->cellId,"RNTI:%d Processing for MSG3 failed", + datInfo->rnti); + RETVALUE(RFAILED); + } + RETVALUE(ROK); +} + +#ifdef LTE_L2_MEAS + +/** @brief This function captures the BSR value from Control Element + * Info structure and updates the effective Buffer size into the + * corresponding LCG ID. + * + * @details + * + * Function: rgTOMUtlL2MStoreBufSz + * + * Processing steps: + * - update/append the Data structure based on BSR type + * + * @param [in] RgUeCb *ueCb + * @param [in] RgInfCeInfo *ceInfo + * @return S16 + */ + +#ifdef ANSI +PRIVATE S16 rgTOMUtlL2MStoreBufSz +( + RgUeCb *ueCb, + RgInfCeInfo *ceInfo + ) +#else +PRIVATE S16 rgTOMUtlL2MStoreBufSz (ueCb, ceInfo) + RgUeCb *ueCb; + RgInfCeInfo *ceInfo; +#endif +{ + U8 lcgId; + U8 bsr; + TRC2(rgTOMUtlL2MStoreBufSz); + + if(ceInfo->bitMask & RG_TRUNC_BSR_CE_PRSNT) + { + lcgId = ((ceInfo->ces.bsr.truncBsr >> 6) & 0x03); + bsr = ceInfo->ces.bsr.truncBsr & 0x3F; + ueCb->ul.lcgArr[lcgId].lcgBsInfo.outStndngBs = rgLwrBsrTbl[bsr]; + } + else if(ceInfo->bitMask & RG_SHORT_BSR_CE_PRSNT) + { + lcgId = ((ceInfo->ces.bsr.shortBsr >> 6) & 0x03); + bsr = ceInfo->ces.bsr.shortBsr & 0x3F; + ueCb->ul.lcgArr[lcgId].lcgBsInfo.outStndngBs = rgLwrBsrTbl[bsr]; + + } + else if(ceInfo->bitMask & RG_LONG_BSR_CE_PRSNT) + { + ueCb->ul.lcgArr[0].lcgBsInfo.outStndngBs = rgLwrBsrTbl[ceInfo->ces.bsr.longBsr.bs1]; + ueCb->ul.lcgArr[1].lcgBsInfo.outStndngBs = rgLwrBsrTbl[ceInfo->ces.bsr.longBsr.bs2]; + ueCb->ul.lcgArr[2].lcgBsInfo.outStndngBs = rgLwrBsrTbl[ceInfo->ces.bsr.longBsr.bs3]; + ueCb->ul.lcgArr[3].lcgBsInfo.outStndngBs = rgLwrBsrTbl[ceInfo->ces.bsr.longBsr.bs4]; + } + RETVALUE(ROK); +} /* end of rgTOMUtlL2MStoreBufSz*/ + +/** @brief : Compiles list of LCs received in UL data for DTCH RBs + * + * @details + * + * @param [in] RgCellCb *cellCb + * @param [in] RgUeCb *ueCb + * @param [in] CmLteRnti rnti + * @param [in] RgMacPdu *pdu + * @param + * @return S16 + * -# ROK + * -# RFAILED + */ +#ifdef ANSI +PRIVATE Void rgTOML2MCompileActiveLCs +( + RgCellCb *cellCb, + RgUeCb *ueCb, + RgMacPdu *pdu, + RgInfCeInfo *ceInfo + ) +#else +PRIVATE Void rgTOML2MCompileActiveLCs(cellCb, ueCb, pdu, ceInfo) + RgCellCb *cellCb; + RgUeCb *ueCb; + RgMacPdu *pdu; + RgInfCeInfo *ceInfo; +#endif +{ + CmLList *node; + RgMacSdu *sdu; + RgUlLcCb *ulLcCb; + + TRC2(rgTOML2MCompileActiveLCs) + + node = pdu->sduLst.first; + while (node) + { + sdu = (RgMacSdu*)node->node; + + if ((ulLcCb = rgDBMGetUlDedLcCb(ueCb, sdu->lcId)), ulLcCb != NULLP) + { + if (ulLcCb->lcgId != 0) + { + ceInfo->bitMask |= RG_ACTIVE_LC_PRSNT; + ceInfo->ulActLCs[ulLcCb->lcId - 1] = TRUE; + } + } + node = node->next; + } + +} /* end of */ + + + +#endif +/********************************************************************** + + End of file +**********************************************************************/ diff --git a/src/5gnrmac/rg_uhm.c b/src/5gnrmac/rg_uhm.c new file mode 100755 index 000000000..1c7d9774b --- /dev/null +++ b/src/5gnrmac/rg_uhm.c @@ -0,0 +1,166 @@ +/******************************************************************************* +################################################################################ +# Copyright (c) [2017-2019] [Radisys] # +# # +# 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. # +################################################################################ +*******************************************************************************/ + +/************************************************************************ + + Name: LTE-MAC layer + + Type: C source file + + Desc: C source code for Entry point fucntions + + File: rg_uhm.c + +**********************************************************************/ + +/** @file rg_uhm.c +@brief This module handles uplink harq related functionality in MAC. +*/ + +/* header include files -- defines (.h) */ +#include "envopt.h" /* environment options */ +#include "envdep.h" /* environment dependent */ +#include "envind.h" /* environment independent */ + +#include "gen.h" /* general */ +#include "ssi.h" /* system services */ + +#include "cm_lte.h" /* Common LTE */ +#include "cm_tkns.h" /* Common Token Defines */ +#include "cm_llist.h" /* Common Link List Defines */ +#include "cm_hash.h" /* Common Hash List Defines */ +#include "cm_mblk.h" /* memory management */ + +#include "rg_env.h" /* MAC Environment Defines */ +#include "tfu.h" /* TFU Interface defines */ +#include "crg.h" /* CRG Interface defines */ +#include "rgu.h" /* RGU Interface defines */ +#include "rg_sch_inf.h" /* TFU Interface defines */ +#include "lrg.h" /* LRG Interface defines */ + +#include "rg.h" /* MAC defines */ +#include "rg_err.h" /* MAC error defines */ + +/* header/extern include files (.x) */ +#include "gen.x" /* general */ +#include "ssi.x" /* system services */ +#include "cm5.x" /* system services */ +#include "cm_lte.x" /* Common LTE */ +#include "cm_tkns.x" /* Common Token Definitions */ +#include "cm_llist.x" /* Common Link List Definitions */ +#include "cm_lib.x" /* Common Library Definitions */ +#include "cm_hash.x" /* Common Hash List Definitions */ +#include "cm_mblk.x" /* memory management */ + +#include "tfu.x" /* TFU Interface defines */ +#include "crg.x" /* CRG Interface includes */ +#include "rgu.x" /* RGU Interface includes */ +#include "rg_sch_inf.x" /* SCH Interface defines */ +#include "rg_prg.x" /* PRG Interface defines */ +#include "lrg.x" /* LRG Interface includes */ + +#include "rg.x" /* MAC includes */ + +/* local defines */ + +/* local typedefs */ + +/* local externs */ + +/* forward references */ + +/** + * @brief Handler for initializing the HARQ entity. + * + * @details + * + * Function: rgUHMCrgUeCfg + * + * Invoked by: CRG + * + * Processing Steps: + * - Initialize maxHqRetx + * + * @param[in] *cellCb + * @param[in,out] *ueCb + * @param[in] *ueCfg + * @param[out] *err + * @return Void + **/ +#ifdef ANSI +PUBLIC Void rgUHMCrgUeCfg +( +RgCellCb *cellCb, +RgUeCb *ueCb, +CrgUeCfg *ueCfg +) +#else +PUBLIC Void rgUHMCrgUeCfg(cellCb, ueCb, ueCfg) +RgCellCb *cellCb; +RgUeCb *ueCb; +CrgUeCfg *ueCfg; +#endif +{ + TRC2(rgUHMCrgUeCfg); + + ueCb->ul.hqEnt.maxHqRetx = (ueCfg->ueUlHqCfg.maxUlHqTx - 1); + RETVOID; +} /* rgUHMCrgUeCfg */ + +/** + * @brief Handler for re-initializing the HARQ entity. + * + * @details + * + * Function: rgUHMCrgUeRecfg + * + * Invoked by: CRG + * + * Processing Steps: + * - Re-initialize maxHqRetx + * + * @param[in] *cellCb + * @param[in,out] *ueCb + * @param[in] *ueCfg + * @param[out] *err + * @return Void + **/ +#ifdef ANSI +PUBLIC Void rgUHMCrgUeRecfg +( +RgCellCb *cellCb, +RgUeCb *ueCb, +CrgUeRecfg *ueRecfg +) +#else +PUBLIC Void rgUHMCrgUeRecfg(cellCb, ueCb, ueRecfg) +RgCellCb *cellCb; +RgUeCb *ueCb; +CrgUeRecfg *ueRecfg; +#endif +{ + TRC2(rgUHMCrgUeRecfg); + + ueCb->ul.hqEnt.maxHqRetx = (ueRecfg->ueUlHqRecfg.maxUlHqTx - 1); + RETVOID; +} /* rgUHMCrgUeCfg */ + +/********************************************************************** + + End of file +**********************************************************************/ diff --git a/src/5gnrmac/rg_uim.c b/src/5gnrmac/rg_uim.c new file mode 100755 index 000000000..add49a0fe --- /dev/null +++ b/src/5gnrmac/rg_uim.c @@ -0,0 +1,1396 @@ +/******************************************************************************* +################################################################################ +# Copyright (c) [2017-2019] [Radisys] # +# # +# 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. # +################################################################################ +*******************************************************************************/ + +/************************************************************************ + + Name: LTE-MAC layer + + Type: C source file + + Desc: C source code for Entry point fucntions + + File: rg_uim.c + +**********************************************************************/ + +/** @file rg_uim.c. +@brief This module acts as an interface handler for upper interface and +manages Pst and Sap related information for upper interface APIs. +*/ + +static const char* RLOG_MODULE_NAME="MAC"; +static int RLOG_MODULE_ID=4096; +static int RLOG_FILE_ID=178; + +/* header include files -- defines (.h) */ + +/* header/extern include files (.x) */ +/* header include files (.h) */ +#include "envopt.h" /* environment options */ +#include "envdep.h" /* environment dependent */ +#include "envind.h" /* environment independent */ +#include "gen.h" /* general layer */ +#include "ssi.h" /* system services */ +#include "cm5.h" /* common timers defines */ +#include "cm_hash.h" /* common hash list defines */ +#include "cm_llist.h" /* common linked list defines */ +#include "cm_mblk.h" /* memory management */ +#include "cm_tkns.h" /* common tokens */ +#include "cm_lte.h" +#include "crg.h" /* CRG defines */ +#include "lrg.h" /* layer management defines for LTE-MAC */ +#include "tfu.h" +#include "rgu.h" +#include "rg_sch_inf.h" +#include "rg_env.h" /* customizable defines and macros for MAC */ +#include "rg.h" /* defines and macros for MAC */ +#include "rg_err.h" /* RG error defines */ + +/* header/extern include files (.x) */ + +#include "gen.x" /* general layer typedefs */ +#include "ssi.x" /* system services typedefs */ +#include "cm5.x" /* common timers */ +#include "cm_hash.x" /* common hash list */ +#include "cm_lib.x" /* common library */ +#include "cm_llist.x" /* common linked list */ +#include "cm_mblk.x" /* memory management */ +#include "cm_tkns.x" /* common tokens */ +#include "cm_lte.x" +#include "crg.x" /* CRG types */ +#include "lrg.x" /* layer management typedefs for MAC */ +#include "tfu.x" +#include "rgu.x" +#include "rg_sch_inf.x" +#include "rg_prg.x" /* PRG interface typedefs*/ +#include "rg.x" /* typedefs for MAC */ + +#include "ss_rbuf.h" +#include "ss_rbuf.x" + +/* local defines */ + +/* local typedefs */ + +/* local externs */ + +/* forward references */ + +#if defined(SPLIT_RLC_DL_TASK) && defined(RLC_MAC_STA_RSP_RBUF) +PUBLIC S16 rgBatchProc(Void); +#endif +PUBLIC U8 rgRguDlSap; +PUBLIC U8 rgRguUlSap; +/** + * @brief Handler for Bind request. + * + * @details + * + * Function : RgUiRguBndReq + * + * This function handles the bind request from MAC Service User. + * + * + * @param[in] Pst *pst + * @param[in] SuId suId + * @param[in] SpId spId + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 RgUiRguBndReq +( +Pst *pst, +SuId suId, +SpId spId +) +#else +PUBLIC S16 RgUiRguBndReq(pst, suId, spId) +Pst *pst; +SuId suId; +SpId spId; +#endif +{ + Inst inst; + S16 ret = ROK; + Pst tmpPst; /* Temporary Post Structure */ + RgUstaDgn dgn; /* Alarm diagnostics structure */ + + TRC3(RgUiRguBndReq) + + + RG_IS_INST_VALID(pst->dstInst); + inst = pst->dstInst - RG_INST_START; + + tmpPst.prior = pst->prior; + tmpPst.route = pst->route; + tmpPst.selector = pst->selector; + tmpPst.region = rgCb[inst].rgInit.region; + tmpPst.pool = rgCb[inst].rgInit.pool; + tmpPst.srcProcId = rgCb[inst].rgInit.procId; + tmpPst.srcEnt = rgCb[inst].rgInit.ent; + tmpPst.srcInst = rgCb[inst].rgInit.inst; + tmpPst.event = EVTNONE; + tmpPst.dstProcId = pst->srcProcId; + tmpPst.dstEnt = pst->srcEnt; + tmpPst.dstInst = pst->srcInst; + + if(spId == rgCb[inst].rguSap[spId].sapCfg.spId) + { + /* Check the state of the SAP */ + switch (rgCb[inst].rguSap[spId].sapSta.sapState) + { + case LRG_NOT_CFG: /* SAP Not configured */ + RGDBGINFO(inst,(rgPBuf(inst), "SAP Not Configured\n")); + rgFillDgnParams(inst,&dgn, LRG_USTA_DGNVAL_MEM); + ret = rgLMMStaInd(inst,LCM_CATEGORY_INTERFACE,LRG_NOT_CFG, + LCM_CAUSE_INV_SAP, &dgn); + RLOG0(L_DEBUG,"SAP Not Configured"); + ret = RgUiRguBndCfm(&tmpPst, suId, CM_BND_NOK); + break; + case LRG_UNBND: /* SAP is not bound */ + RLOG0(L_DEBUG,"SAP Not yet bound"); + rgCb[inst].rguSap[spId].sapSta.sapState = LRG_BND; + rgCb[inst].rguSap[spId].sapCfg.suId = suId; + /* Send Bind Confirm with status as SUCCESS */ + /*T2K - Passing spId as it is required to access the SAP CB*/ + ret = rgUIMRguBndCfm(inst,spId, CM_BND_OK); + /* Indicate to Layer manager */ + rgFillDgnParams(inst,&dgn, LRG_USTA_DGNVAL_MEM); + ret = rgLMMStaInd(inst,LCM_CATEGORY_INTERFACE,LRG_EVENT_RGUSAP_ENB, + LCM_CAUSE_UNKNOWN, &dgn); + break; + case LRG_BND: /* SAP is already bound*/ + RLOG0(L_DEBUG,"SAP already bound"); + /*T2K - Passing spId as it is required to access the SAP CB*/ + ret = rgUIMRguBndCfm(inst,spId, CM_BND_OK); + break; + default: /* Should Never Enter here */ +#if (ERRCLASS & ERRCLS_ADD_RES) + RGLOGERROR(inst,ERRCLS_INT_PAR, ERG008, (ErrVal)rgCb[inst].rguSap[spId].sapSta.sapState, + "Invalid SAP State:RgUiRguBndReq failed\n"); +#endif + /*T2K - Passing spId as it is required to access the SAP CB*/ + ret = rgUIMRguBndCfm(inst,spId, CM_BND_NOK); + break; + } + } + else + { +#if (ERRCLASS & ERRCLS_ADD_RES) + RGLOGERROR(inst,ERRCLS_INT_PAR, ERG009, (ErrVal)rgCb[inst].rguSap[spId].sapCfg.spId, + "Invalid SAP Id:RgUiRguBndReq failed\n"); +#endif + /*T2K - Passing spId as it is required to access the SAP CB*/ + ret = rgUIMRguBndCfm(inst,spId, CM_BND_NOK); + } + RETVALUE(ret); +} /* RgUiRguBndReq */ + + +/** + * @brief Handler for Unbind request. + * + * @details + * + * Function : RgUiRguUbndReq + * + * This function handles the unbind request from MAC Service User. + * + * + * @param[in] Pst *pst + * @param[in] SpId spId + * @param[in] Reason reason + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 RgUiRguUbndReq +( +Pst *pst, +SpId spId, +Reason reason +) +#else +PUBLIC S16 RgUiRguUbndReq(pst, spId, reason) +Pst *pst; +SpId spId; +Reason reason; +#endif +{ + Inst inst; + TRC3(RgUiRguUbndReq) + + + RG_IS_INST_VALID(pst->dstInst); + inst = pst->dstInst - RG_INST_START; + /* SAP Id validation */ + if (spId == rgCb[inst].rguSap[spId].sapCfg.spId) + { + switch(rgCb[inst].rguSap[spId].sapSta.sapState) + { + case LRG_BND: /* SAP is already bound*/ + RLOG0(L_DEBUG,"SAP already bound"); + /* setting SAP state to UN BOUND */ + rgCb[inst].rguSap[spId].sapSta.sapState = LRG_UNBND; + break; + default: +#if (ERRCLASS & ERRCLS_ADD_RES) + RLOG1(L_ERROR,"Invalid SAP State:%d RgUiRguUbndReq failed", + rgCb[inst].rguSap[spId].sapSta.sapState); + +#endif + break; + } + } + else + { +#if (ERRCLASS & ERRCLS_ADD_RES) + RGLOGERROR(inst,ERRCLS_INT_PAR, ERG011, (ErrVal)rgCb[inst].rguSap[spId].sapCfg.spId, + "Invalid SAP Id:RgUiRguUbndReq failed\n"); +#endif + RETVALUE(RFAILED); + } + RETVALUE(ROK); +} /* RgUiRguUbndReq */ +/** + * @brief API for sending bind confirm from MAC to RLC + * + * @details + * + * Function: rgUIMRguBndCfm + * + * This API is invoked to send bind confirm from MAC to RLC. + * This API fills in Pst structure and SAP Ids and invokes + * bind confirm API towards RLC. + * + * @param[in] Inst inst + * @param[in] SuId suId + * @param[in] U8 status + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 rgUIMRguBndCfm +( +Inst inst, +SpId spId, +U8 status +) +#else +PUBLIC S16 rgUIMRguBndCfm(inst,spId, status) +Inst inst; +SpId spId; +U8 status; +#endif +{ + S16 ret = ROK; + + TRC2(rgUIMRguBndCfm) + + + ret = RgUiRguBndCfm(&rgCb[inst].rguSap[spId].sapCfg.sapPst, + rgCb[inst].rguSap[spId].sapCfg.suId, status); + if (ret != ROK) + { + + RLOG0(L_ERROR,"RgUiRguBndCfm Failed "); + RETVALUE(ret); + } + RETVALUE(ret); +} /* rgUIMRguBndCfm*/ + + +/** + * @brief Handler for dedicated DatReq from RGU + * + * @details + * + * Function : RgUiRguDDatReq + * + * This function validates SAP and invokes ROM for further processing + * + * @param[in] Pst *pst + * @param[in] SpId spId + * @param[in] RguDDatReqInfo *datReq + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 RgUiRguDDatReq +( +Pst *pst, +SpId spId, +RguDDatReqInfo *datReq +) +#else +PUBLIC S16 RgUiRguDDatReq(pst, spId, datReq) +Pst *pst; +SpId spId; +RguDDatReqInfo *datReq; +#endif +{ + S16 ret = ROK; + Inst inst; +#ifndef NO_ERRCLS + U32 id; + U32 id1; + U32 id2; + U32 id3; +#endif + + TRC3(RgUiRguDDatReq) + + + RG_IS_INST_VALID(pst->dstInst); + inst = pst->dstInst - RG_INST_START; +#ifndef NO_ERRCLS + if (datReq == NULLP) + { + RLOG0(L_ERROR,"Input Message Buffer is NULL"); + RETVALUE(RFAILED); + } + + if(rgCb[inst].rguSap[spId].sapCfg.spId == spId) + { + switch (rgCb[inst].rguSap[spId].sapSta.sapState) + { + case LRG_BND: /* SAP is bound */ + RLOG0(L_DEBUG,"SAP is already bound"); + break; + default: /* Should never reach here */ +#if (ERRCLASS & ERRCLS_ADD_RES) + RLOG1(L_ERROR,"Invalid SAP State:%d RgUiRguDDatReq failed", + rgCb[inst].rguSap[spId].sapSta.sapState); +#endif +#ifndef L2_OPTMZ + for(id3 = 0; id3 < datReq->nmbOfUeGrantPerTti; id3++) + { + RG_DROP_RGUDDATREQ_MBUF(datReq->datReq[id3]); + } +#endif + RETVALUE(RFAILED); + } + } + else + { +#if (ERRCLASS & ERRCLS_ADD_RES) + RGLOGERROR(inst,ERRCLS_INT_PAR, ERG013, (ErrVal)spId, + "Invalid SAP Id:RgUiRguDDatReq failed\n"); +#endif +#ifndef L2_OPTMZ + for(id3 = 0; id3 < datReq->nmbOfUeGrantPerTti; id3++) + { + RG_DROP_RGUDDATREQ_MBUF(datReq->datReq[id3]); + } +#endif + RETVALUE(RFAILED); + } + + /* Update RGU SAP statistics for received sdu count */ + /*ccpu00118201 - ADD - Send trace only when its enabled*/ + if(rgCb[inst].rgInit.trc) + { + for(id3 = 0; id3 < datReq->nmbOfUeGrantPerTti; id3++) + { + RguDDatReqPerUe *datReqPerUe = &datReq->datReq[id3]; + for (id = 0; id < datReqPerUe->nmbOfTbs; id++) + { + for (id1 = 0; id1 < datReqPerUe->datReqTb[id].nmbLch; id1++) + { + /* rgCb.rguSap.sapSts.numPduRcvd is updated by + * rgROMDedDatReq -> rgUpdtRguDedSts function + * So numPduRcvd updation is commented here */ + /* rgCb.rguSap.sapSts.numPduRcvd += + datReq->datReqTb[id].lchData[id1].pdu.numPdu; */ + for (id2 = 0; id2 < datReqPerUe->datReqTb[id].lchData[id1].pdu.numPdu; id2++) + { + RG_SEND_TRC_IND(inst,datReqPerUe->datReqTb[id]. + lchData[id1].pdu.mBuf[id2], EVTRGUDDATREQ); + } + } + } + } + } +#endif + + /* Call Ownership module for further processing */ + ret = rgROMDedDatReq(inst,datReq); + SPutStaticBuffer(pst->region, pst->pool, (Data *)datReq,sizeof(RguDDatReqInfo), SS_SHARABLE_MEMORY); + datReq = NULLP; + RETVALUE(ret); +} /* RgUiRguDDatReq */ + + +/** + * @brief Handler for common DatReq from RGU + * + * @details + * + * Function : RgUiRguCDatReq + * + * This function validates SAP invokes ROM for further processing + * + * @param[in] Pst *pst + * @param[in] SpId spId + * @param[in] RguCDatReqInfo *datReq + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 RgUiRguCDatReq +( +Pst *pst, +SpId spId, +RguCDatReqInfo *datReq +) +#else +PUBLIC S16 RgUiRguCDatReq(pst, spId, datReq) +Pst *pst; +SpId spId; +RguCDatReqInfo *datReq; +#endif +{ + Inst inst; + S16 ret = ROK; + + TRC3(RgUiRguCDatReq) + + + RG_IS_INST_VALID(pst->dstInst); + inst = pst->dstInst - RG_INST_START; +#ifndef NO_ERRCLS + if (datReq == NULLP) + { + RLOG0(L_ERROR,"Input Message Buffer is NULL"); + RETVALUE(RFAILED); + } + + if(rgCb[inst].rguSap[spId].sapCfg.spId == spId) + { + switch (rgCb[inst].rguSap[spId].sapSta.sapState) + { + case LRG_BND: /* SAP is bound */ + RLOG0(L_DEBUG,"SAP is already bound"); + break; + default: /* Should never reach here */ +#if (ERRCLASS & ERRCLS_ADD_RES) + RLOG1(L_ERROR,"Invalid SAP State:%d RgUiRguCDatReq failed", + rgCb[inst].rguSap[spId].sapSta.sapState); +#endif + RETVALUE(RFAILED); + } + } + else + { +#if (ERRCLASS & ERRCLS_ADD_RES) + RLOG1(L_ERROR,"Invalid SAP Id:%d RgUiRguCDatReq failed ",spId); +#endif + RETVALUE(RFAILED); + } +#endif + + /* Update RGU SAP statistics for received sdu count */ + /* rgCb.rguSap.sapSts.numPduRcvd is updated by + * rgROMCmnDatReq ->rgUpdtRguCmnSts function + * So numPduRcvd updation is commented here */ + /* rgCb.rguSap.sapSts.numPduRcvd++; */ + + ret = rgROMCmnDatReq(inst,datReq); + /*ccpu00118201 - ADD - Send trace only when its enabled*/ + if(rgCb[inst].rgInit.trc) + { + RG_SEND_TRC_IND(inst,datReq->pdu, EVTRGUCDATREQ); + } + if (ret == RFAILED) + { + RG_DROP_RGUCDATREQ_MBUF(datReq); + } + ret = SPutStaticBuffer(pst->region, pst->pool,(Data *)datReq,sizeof(RguCDatReqInfo) , SS_SHARABLE_MEMORY); + datReq = NULLP; + RETVALUE(ret); +} /* RgUiRguCDatReq */ + + +/** + * @brief Handler for dedicated StaRsp from RGU + * + * @details + * + * Function : RgUiRguDStaRsp + * + * This function validates SAP and invokes ROM for further processing + * + * @param[in] Pst *pst + * @param[in] SpId spId + * @param[in] RguDStaRspInfo *staRsp + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 RgUiRguDStaRsp +( +Pst *pst, +SpId spId, +RguDStaRspInfo *staRsp +) +#else +PUBLIC S16 RgUiRguDStaRsp(pst, spId, staRsp) +Pst *pst; +SpId spId; +RguDStaRspInfo *staRsp; +#endif +{ + Inst inst; + + S16 ret = ROK; + VOLATILE U32 startTime = 0; + + TRC3(RgUiRguDStaRsp) + + RG_IS_INST_VALID(pst->dstInst); + inst = pst->dstInst - RG_INST_START; + /*starting Task*/ + SStartTask(&startTime, PID_MAC_STA_RSP); + + ret = rgROMDedStaRsp(inst,staRsp); + if (ret != ROK) + { + RLOG_ARG0(L_ERROR,DBG_CELLID,staRsp->cellId, + "Processing Of Status Response Failed"); + } + + + /*stoping Task*/ + SStopTask(startTime, PID_MAC_STA_RSP); + RETVALUE(ret); +} /* RgUiRguDStaRsp */ + + +/** + * @brief Handler for common StaRsp from RGU + * + * @details + * + * Function : RgUiRguCStaRsp + * + * This function validates SAP and invokes ROM + * for further processing + * + * + * @param[in] Pst *pst + * @param[in] SpId spId + * @param[in] RguCStaRspInfo *staRsp + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 RgUiRguCStaRsp +( +Pst *pst, +SpId spId, +RguCStaRspInfo *staRsp +) +#else +PUBLIC S16 RgUiRguCStaRsp(pst, spId, staRsp) +Pst *pst; +SpId spId; +RguCStaRspInfo *staRsp; +#endif +{ + Inst inst; + S16 ret = ROK; + + TRC3(RgUiRguCStaRsp) + + + RG_IS_INST_VALID(pst->dstInst); + inst = pst->dstInst - RG_INST_START; +#ifndef NO_ERRCLS + if (staRsp == NULLP) + { + RLOG0(L_ERROR,"Input Response Buffer is NULL"); + RETVALUE(RFAILED); + } + + if (spId == rgCb[inst].rguSap[spId].sapCfg.spId) + { + switch (rgCb[inst].rguSap[spId].sapSta.sapState) + { + case LRG_BND: /* SAP is bound */ + RLOG0(L_DEBUG,"SAP is already bound"); + break; + default: /* Should never reach here */ +#if (ERRCLASS & ERRCLS_ADD_RES) + RLOG1(L_ERROR,"Invalid SAP State:%d RgUiRguCStaRsp failed", + rgCb[inst].rguSap[spId].sapSta.sapState); +#endif + RETVALUE(RFAILED); + } + } + else + { +#if (ERRCLASS & ERRCLS_ADD_RES) + RLOG1(L_ERROR,"Invalid SAP Id:%d RgUiRguCStaRsp failed",spId); +#endif + RETVALUE(RFAILED); + } +#endif + + ret = rgROMCmnStaRsp(inst,staRsp); + if (ret != ROK) + { + RLOG_ARG0(L_ERROR,DBG_CELLID,staRsp->cellId,"Processing Of Status Response Failed"); + RETVALUE(ret); + } + + ret = SPutStaticBuffer(pst->region, pst->pool, (Data *)staRsp,sizeof(RguCStaRspInfo) , SS_SHARABLE_MEMORY); + staRsp = NULLP; + RETVALUE(ret); +} /* RgUiRguCStaRsp */ + +#ifdef LTE_L2_MEAS + +/** + * @brief Handler for L2M MeasReq from RGU + * + * @details + * + * Function :RgUiRguL2MUlThrpMeasReq + * + * This function validates SAP and invokes ROM for further processing + * + * @param[in] Pst *pst + * @param[in] SpId spId + * @param[in] RguL2MUlThrpMeasReqInfo *measReq + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 RgUiRguL2MUlThrpMeasReq +( +Pst *pst, +SpId spId, +RguL2MUlThrpMeasReqInfo *measReq +) +#else +PUBLIC S16 RgUiRguL2MUlThrpMeasReq(pst, spId, measReq) +Pst *pst; +SpId spId; +RguL2MUlThrpMeasReqInfo *measReq; +#endif +{ + Inst inst; + + S16 ret = ROK; + + TRC3(RgUiRguL2MUlThrpMeasReq) + + + RG_IS_INST_VALID(pst->dstInst); + inst = pst->dstInst - RG_INST_START; +#ifndef NO_ERRCLS + if (measReq == NULLP) + { + RLOG0(L_ERROR,"Input Response Buffer is NULL"); + RETVALUE(RFAILED); + } + + if (spId == rgCb[inst].rguSap[spId].sapCfg.spId) + { + switch (rgCb[inst].rguSap[spId].sapSta.sapState) + { + case LRG_BND: /* SAP is bound */ + RLOG0(L_DEBUG,"SAP is already bound"); + break; + default: /* Should never reach here */ +#if (ERRCLASS & ERRCLS_ADD_RES) + RLOG1(L_ERROR,"Invalid SAP State:%d RgUiRguL2MUlThrpMeasReq failed", + rgCb[inst].rguSap[spId].sapSta.sapState); +#endif + RETVALUE(RFAILED); + } + } + else + { +#if (ERRCLASS & ERRCLS_ADD_RES) + RLOG1(L_ERROR,"Invalid SAP Id:%d RgUiRguL2MUlThrpMeasReq failed",spId); +#endif + RETVALUE(RFAILED); + } +#endif + + ret = rgROML2MUlThrpMeasReq(inst,measReq); + if (ret != ROK) + { + RLOG_ARG0(L_ERROR,DBG_CELLID,measReq->cellId,"Processing Of Meas Request Failed"); + } + + SPutStaticBuffer(pst->region, pst->pool, (Data *)measReq,sizeof(RguL2MUlThrpMeasReqInfo) , SS_SHARABLE_MEMORY); + measReq= NULLP; + RETVALUE(ret); +} /* RgUiRguL2MUlThrpMeasReq */ +#endif + +/** + * @brief Handler for sending staInd to dedicated logical channels of a UE + * + * @details + * + * Function : rgUIMSndDedStaInd + * + * This function fills SAP and Pst information to send the staInd to + * a UE. + * + * + * @param[in] Inst inst + * @param[in] RgUpSapCb *rguSap + * @param[in] RgRguDedStaInd *staInd + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 rgUIMSndDedStaInd +( +Inst inst, +RgUpSapCb *rguSap, +RgRguDedStaInd *staInd +) +#else +PUBLIC S16 rgUIMSndDedStaInd(inst,rguSap,staInd) +Inst inst; +RgUpSapCb *rguSap; +RgRguDedStaInd *staInd; +#endif +{ + S16 ret = ROK; + + TRC2(rgUIMSndDedStaInd) + + RGDBGPRM(inst,(rgPBuf(inst),"rgUIMSndDedStaInd(): staInd = %p;\n", (void *)staInd)); + + ret = RgUiRguDStaInd(&(rguSap->sapCfg.sapPst), rguSap->sapCfg.suId, + staInd); + if (ret != ROK) + { + RLOG_ARG0(L_ERROR,DBG_CELLID,staInd->cellId,"RgUiRguDStaInd Failed"); + RETVALUE(ret); + } + RETVALUE(ret); +} /* rgUIMSndDedStaInd */ + + +/** + * @brief Handler for sending staInd to a common logical channel. + * + * @details + * + * Function : rgUIMSndCmnStaInd + * + * This function fills SAP and Pst information to send the staInd to + * a common logical channel. + * + * + * @param[in] Inst inst + * @param[in] RgUpSapCb *rguSap + * @param[in] RgRguCmnStaInd *staInd + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 rgUIMSndCmnStaInd +( +Inst inst, +RgUpSapCb *rguDlSap, +RgRguCmnStaInd *staInd +) +#else +PUBLIC S16 rgUIMSndCmnStaInd(inst,rguDlSap,staInd) +Inst inst, +RgUpSapCb *rguDlSap, +RgRguCmnStaInd *staInd; +#endif +{ + S16 ret = ROK; + + + TRC2(rgUIMSndCmnStaInd) + + + ret = RgUiRguCStaInd(&(rguDlSap->sapCfg.sapPst), rguDlSap->sapCfg.suId, + staInd); + if (ret != ROK) + { + RLOG_ARG0(L_ERROR,DBG_CELLID,staInd->cellId,"RgUiRguCStaInd Failed"); + RETVALUE(ret); + } + RETVALUE(ret); +} /* rgUIMSndCmnStaInd */ + + +/** + * @brief Handler for sending datInd to dedicated logical channels of a UE + * + * @details + * + * Function : rgUIMSndDedDatInd + * + * This function fills SAP and Pst information to send the datInd to + * a UE. + * + * + * @param[in] Inst inst + * @param[in] RgUpSapCb *rguUlSap + * @param[in] RgRguDedDatInd *datInd + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 rgUIMSndDedDatInd +( +Inst inst, +RgUpSapCb *rguUlSap, +RgRguDedDatInd *datInd +) +#else +PUBLIC S16 rgUIMSndDedDatInd(datInd) +Inst inst; +RgUpSapCb *rguUlSap; +RgRguDedDatInd *datInd; +#endif +{ + S16 ret = ROK; + + + TRC2(rgUIMSndDedDatInd) + + + rguUlSap->sapSts.numPduTxmit += datInd->numLch; +#ifndef SS_RBUF + ret = RgUiRguDDatInd(&(rguUlSap->sapCfg.sapPst), rguUlSap->sapCfg.suId, + datInd); + if (ret != ROK) + { + RLOG_ARG0(L_ERROR,DBG_CELLID,datInd->cellId,"RgUiRguDdatInd Failed"); + RETVALUE(ret); + } +#else + SRngIncrWIndx(SS_RNG_BUF_ULMAC_TO_ULRLC); + SsRngInfoTbl[SS_RNG_BUF_ULMAC_TO_ULRLC].pktRate++; +#endif + RETVALUE(ret); +} /* rgUIMSndDedDatInd */ + + +/** + * @brief Handler for sending datInd to a common logical channel. + * + * @details + * + * Function : rgUIMSndCmnDatInd + * + * This function fills SAP and Pst information to send the datInd to + * a common logical channel. + * + * + * @param[in] Inst inst + * @param[in] RgUpSapCb *rguSap + * @param[in] RgRguCmnDatInd *datInd + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 rgUIMSndCmnDatInd +( +Inst inst, +RgUpSapCb *rguUlSap, +RgRguCmnDatInd *datInd +) +#else +PUBLIC S16 rgUIMSndCmnDatInd(datInd) +Inst inst; +RgUpSapCb *rguUlSap; +RgRguCmnDatInd *datInd; +#endif +{ + S16 ret = ROK; + + TRC2(rgUIMSndCmnDatInd) + + + RGDBGPRM(inst,(rgPBuf(inst),"rgUIMSndCmnDatInd(): staInd = %p;\n", (void *)datInd)); + + rguUlSap->sapSts.numPduTxmit++; + + RGDBGPRM(inst,(rgPBuf(inst),"rgUIMSndCmnDatInd suId = %d\n", rguUlSap->sapCfg.suId)); + ret = RgUiRguCDatInd(&(rguUlSap->sapCfg.sapPst), rguUlSap->sapCfg.suId, + datInd); + if (ret != ROK) + { + RGDBGERRNEW(inst,(rgPBuf(inst),"RgUiRguCDatInd Failed\n")); + RLOG_ARG0(L_ERROR,DBG_CELLID,datInd->cellId,"RgUiRguCDatInd Failed"); + RETVALUE(ret); + } + RETVALUE(ret); +} /* rgUIMSndCmnDatInd */ + +/** + + * @brief API for bind request from RRC towards MAC. + * + * @details + * + * Function: RgUiCrgBndReq + * + * This API is invoked by RRC towards MAC to bind CRG SAP. + * These API validates the Pst, spId, suId and sends the bind confirm to RRC. + * + * + * @param[in] Pst *pst + * @param[in] SuId suId + * @param[in] SpId spId + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 RgUiCrgBndReq +( +Pst *pst, +SuId suId, +SpId spId +) +#else +PUBLIC S16 RgUiCrgBndReq(pst, suId, spId) +Pst *pst; +SuId suId; +SpId spId; +#endif +{ + S16 ret = ROK; + Pst tmpPst; /* Temporary Post Structure */ + RgUstaDgn dgn; /* Alarm diagnostics structure */ + Inst inst; + + TRC3(RgUiCrgBndReq) + + + RG_IS_INST_VALID(pst->dstInst); + inst = pst->dstInst - RG_INST_START; + + tmpPst.prior = pst->prior; + tmpPst.route = pst->route; + tmpPst.selector = pst->selector; + tmpPst.region = rgCb[inst].rgInit.region; + tmpPst.pool = rgCb[inst].rgInit.pool; + tmpPst.srcProcId = rgCb[inst].rgInit.procId; + tmpPst.srcEnt = rgCb[inst].rgInit.ent; + tmpPst.srcInst = rgCb[inst].rgInit.inst; + tmpPst.event = EVTNONE; + tmpPst.dstProcId = pst->srcProcId; + tmpPst.dstEnt = pst->srcEnt; + tmpPst.dstInst = pst->srcInst; + + + if(spId == rgCb[inst].crgSap.sapCfg.spId) + { + /* Check the state of the SAP */ + switch (rgCb[inst].crgSap.sapSta.sapState) + { + case LRG_NOT_CFG: /* SAP Not configured */ + + rgFillDgnParams(inst,&dgn, LRG_USTA_DGNVAL_MEM); + ret = rgLMMStaInd(inst,LCM_CATEGORY_INTERFACE,LRG_NOT_CFG, + LCM_CAUSE_INV_SAP, &dgn); + RLOG0(L_DEBUG,"SAP Not Configured"); + ret = RgUiCrgBndCfm(&tmpPst, suId, CM_BND_NOK); + break; + case LRG_UNBND: /* SAP is not bound */ + RLOG0(L_DEBUG,"SAP Not yet bound"); + + rgCb[inst].crgSap.sapSta.sapState = LRG_BND; + rgCb[inst].crgSap.sapCfg.suId = suId; + /* Send Bind Confirm with status as SUCCESS */ + ret = rgUIMCrgBndCfm(inst,suId, CM_BND_OK); + /* Indicate to Layer manager */ + rgFillDgnParams(inst,&dgn, LRG_USTA_DGNVAL_MEM); + ret = rgLMMStaInd(inst,LCM_CATEGORY_INTERFACE,LRG_EVENT_CRGSAP_ENB, + LCM_CAUSE_UNKNOWN, &dgn); + break; + case LRG_BND: /* SAP is already bound*/ + RLOG0(L_DEBUG,"SAP is already bound"); + + ret = rgUIMCrgBndCfm(inst,suId, CM_BND_OK); + break; + default: /* Should Never Enter here */ +#if (ERRCLASS & ERRCLS_ADD_RES) + RLOG1(L_ERROR,"Invalid SAP State:%d RgUiCrgBndReq failed", + rgCb[inst].crgSap.sapSta.sapState); +#endif + ret = rgUIMCrgBndCfm(inst,suId, CM_BND_NOK); + break; + } + } + else + { +#if (ERRCLASS & ERRCLS_ADD_RES) + RLOG1(L_ERROR,"Invalid SAP Id:%d RgUiCrgBndReq failed", + rgCb[inst].crgSap.sapCfg.spId); +#endif + ret = rgUIMCrgBndCfm(inst,suId, CM_BND_NOK); + } + RETVALUE(ret); +} /* RgUiCrgBndReq */ + + +/** + * @brief API for unbind request from RRC towards MAC. + * + * @details + * + * Function: RgUiCrgUbndReq + * + * This API is invoked by RRC towards MAC to unbind CRG SAP. + * These API validates the Pst, spId, suId and sends the bind confirm to RRC. + * + * + * @param[in] Pst *pst + * @param[in] SuId suId + * @param[in] Reason reason + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 RgUiCrgUbndReq +( +Pst *pst, +SpId spId, +Reason reason +) +#else +PUBLIC S16 RgUiCrgUbndReq(pst, spId, reason) +Pst *pst; +SpId spId; +Reason reason; +#endif +{ + Inst inst; + TRC3(RgUiCrgUbndReq) + + + RG_IS_INST_VALID(pst->dstInst); + inst = pst->dstInst - RG_INST_START; + /* SAP Id validation */ + if (spId == rgCb[inst].crgSap.sapCfg.spId) + { + switch(rgCb[inst].crgSap.sapSta.sapState) + { + case LRG_BND: /* SAP is already bound*/ + /* setting SAP state to UN BOUND */ + RLOG0(L_DEBUG, "SAP is already bound"); + + rgCb[inst].crgSap.sapSta.sapState = LRG_UNBND; + break; + default: +#if (ERRCLASS & ERRCLS_ADD_RES) + RLOG1(L_ERROR,"Invalid SAP State:%d RgUiCrgUbndReq failed", + rgCb[inst].crgSap.sapSta.sapState); +#endif + RETVALUE(RFAILED); + } + } + else + { +#if (ERRCLASS & ERRCLS_ADD_RES) + RLOG1(L_ERROR,"Invalid SAP Id:%d RgUiCrgUbndReq failed", + rgCb[inst].crgSap.sapCfg.spId); +#endif + RETVALUE(RFAILED); + } + RETVALUE(ROK); +} /* RgUiCrgUbndReq */ + +/** + * @brief API for sending bind confirm from MAC to RRC + * + * @details + * + * Function: rgUIMRgrBndCfm + * + * This API is invoked to send bind confirm from MAC to RRC. + * This API fills in Pst structure and SAP Ids and invokes + * bind confirm API towards RRC. + * + * @param[in] Inst inst + * @param[in] SuId suId + * @param[in] U8 status + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 rgUIMCrgBndCfm +( +Inst inst, +SuId suId, +U8 status +) +#else +PUBLIC S16 rgUIMCrgBndCfm(inst,suId, status) +Inst inst; +SuId suId; +U8 status; +#endif +{ + TRC2(rgUIMCrgBndCfm) + + + if(RgUiCrgBndCfm(&(rgCb[inst].crgSap.sapCfg.sapPst), rgCb[inst].crgSap.sapCfg.suId, status) != ROK) + { + RLOG0(L_ERROR,"RgUiCrgBndCfm Failed "); + RETVALUE(RFAILED); + } + + RETVALUE(ROK); +} /* rgUIMCrgBndCfm*/ + +/** + * @brief API for configuration request from RRC towards MAC. + * + * @details + * + * Function: RgUiCrgCfgReq + * + * This API is invoked by RRC towards MAC to configure MAC. + * These API validates the Pst, spId, suId and transfers the config request + * specific information to corresponding ownership module (COM) API. + * + * + * @param[in] Pst *pst + * @param[in] SpId spId + * @param[in] CrgCfgTransId transId + * @param[in] CrgCfgReqInfo *cfgReqInfo + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 RgUiCrgCfgReq +( +Pst *pst, +SpId spId, +CrgCfgTransId transId, +CrgCfgReqInfo *cfgReqInfo +) +#else +PUBLIC S16 RgUiCrgCfgReq(pst, spId, transId, cfgReqInfo) +Pst *pst; +SpId spId; +CrgCfgTransId transId; +CrgCfgReqInfo *cfgReqInfo; +#endif +{ + Inst inst; + S16 ret = ROK; + U8 cfmStatus = 0x00ff; + U8 prntTrans[CRG_CFG_TRANSID_SIZE+1]; + + TRC3(RgUiCrgCfgReq); + + RG_IS_INST_VALID(pst->dstInst); + inst = pst->dstInst - RG_INST_START; + /* Ensuring transId is always Null terminated. */ + cmMemcpy((U8 *)prntTrans, (U8 *)transId.trans, CRG_CFG_TRANSID_SIZE); + prntTrans[CRG_CFG_TRANSID_SIZE] = '\0'; + + + /* CrgCfgReqInfo Validation for NULLP */ + if (cfgReqInfo == NULLP) + { + RLOG0(L_ERROR,"Input Param crgReqInfo is NULL "); + rgUIMCrgCfgCfm(inst,transId, cfmStatus); + RETVALUE(RFAILED); + } + + /* Upper SAP Id and State validation */ + if (spId == rgCb[inst].crgSap.sapCfg.spId) + { + switch(rgCb[inst].crgSap.sapSta.sapState) + { + case LRG_BND: /* SAP is already bound */ + RLOG0(L_DEBUG,"SAP is already bound"); + break; + default: /* Should never reach here */ +#if (ERRCLASS & ERRCLS_ADD_RES) + RLOG1(L_ERROR,"Invalid SAP State:%d RgUiCrgCfgReq failed", + rgCb[inst].crgSap.sapSta.sapState); +#endif + SPutSBuf (pst->region, pst->pool, (Data *)cfgReqInfo, + sizeof(CrgCfgReqInfo)); + cfgReqInfo = NULLP; + + rgUIMCrgCfgCfm(inst,transId, cfmStatus); + RETVALUE(RFAILED); + } + } + else + { +#if (ERRCLASS & ERRCLS_ADD_RES) + RLOG1(L_ERROR,"Invalid SAP Id:%d RgUiCrgCfgReq failed", + rgCb[inst].crgSap.sapCfg.spId); +#endif + SPutSBuf (pst->region, pst->pool, (Data *)cfgReqInfo, + sizeof(CrgCfgReqInfo)); + cfgReqInfo = NULLP; + rgUIMCrgCfgCfm(inst,transId, cfmStatus); + RETVALUE(RFAILED); + } + ret = rgCOMCfgReq(inst,transId, cfgReqInfo); + SPutSBuf (pst->region, pst->pool, (Data *)cfgReqInfo, + sizeof(CrgCfgReqInfo)); + cfgReqInfo = NULLP; + if (ret != ROK) + { + RLOG0(L_ERROR,"Configuration Request Handling Failed "); + RETVALUE(RFAILED); + } + + RETVALUE(ROK); +} /* RgUiCrgCfgReq */ + +/** + * @brief API for sending configuration confirm from MAC to RRC + * + * @details + * + * Function: rgUIMCrgCfgCfm + * + * This API is invoked to send configuration confirm from MAC to RRC. + * This API fills in Pst structure and SAP Ids and invokes + * config confirm API towards RRC. + * + * @param[in] Inst inst + * @param[in] CrgCfgTransId transId + * @param[in] U8 status + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PUBLIC S16 rgUIMCrgCfgCfm +( +Inst inst, +CrgCfgTransId transId, +U8 status +) +#else +PUBLIC S16 rgUIMCrgCfgCfm(inst,transId, status) +Inst inst; +CrgCfgTransId transId; +U8 status; +#endif +{ + S16 ret = ROK; + U8 prntTrans[CRG_CFG_TRANSID_SIZE+1]; + + TRC2(rgUIMCrgCfgCfm) + + cmMemcpy((U8 *)prntTrans, (U8 *)transId.trans, CRG_CFG_TRANSID_SIZE); + prntTrans[CRG_CFG_TRANSID_SIZE] = '\0'; + + + ret = RgUiCrgCfgCfm(&(rgCb[inst].crgSap.sapCfg.sapPst), rgCb[inst].crgSap.sapCfg.suId, transId, status); + if (ret != ROK) + { + RLOG0(L_ERROR,"RgUiCrgCfgCfm Failed "); + RETVALUE(ret); + } + + RETVALUE(ret); +} /* rgUIMCrgCfgCfm */ +#if defined(SPLIT_RLC_DL_TASK) && defined(RLC_MAC_STA_RSP_RBUF) + +#ifdef ANSI +PUBLIC S16 rgBatchProc +( +Void +) +#else +PUBLIC S16 rgBatchProc() +Void; +#endif +{ +/* Read from Ring Buffer and process RLC BO Update */ + Pst pst = {0}; + SpId spId = 0; + RguDStaRspInfo *staRsp; + U32 elmIndx = 0; +#ifndef LTE_ADV +/* Fill pst */ + pst.srcProcId = 1; + pst.dstProcId = 1; + pst.dstEnt = ENTRG; + pst.dstInst = 0; + pst.srcEnt = ENTKW; + pst.srcInst = 1; + pst.prior = PRIOR0; + pst.route = RTESPEC; + pst.event = EVTRGUDSTARSP; + pst.region = 0; + pst.pool = 0; + pst.selector = 2; /*SM_SELECTOR_LC */ +#else +#endif + + elmIndx = (U32)SRngGetRIndx(SS_RNG_BUF_DLRLC_TO_DLMAC); + while(NULLP != elmIndx) + { + staRsp = (RguDStaRspInfo *)elmIndx; +#ifdef LTE_ADV + pst = staRsp->post; +#endif + RgUiRguDStaRsp(&pst, spId, staRsp); + + elmIndx = NULLP; + staRsp = NULLP; + SRngIncrRIndx(SS_RNG_BUF_DLRLC_TO_DLMAC); + + if((elmIndx = (U32)SRngGetRIndx(SS_RNG_BUF_DLRLC_TO_DLMAC)) == NULLP) + break; + } + RETVALUE(ROK); +} +#endif + +/********************************************************************** + + End of file +**********************************************************************/ diff --git a/src/5gnrmac/rg_utl.c b/src/5gnrmac/rg_utl.c new file mode 100755 index 000000000..df681c668 --- /dev/null +++ b/src/5gnrmac/rg_utl.c @@ -0,0 +1,1623 @@ +/******************************************************************************* +################################################################################ +# Copyright (c) [2017-2019] [Radisys] # +# # +# 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. # +################################################################################ +*******************************************************************************/ + +/************************************************************************ + + Name: LTE-MAC layer + + Type: C source file + + Desc: C source code for Entry point fucntions + + File: rg_utl.c + +**********************************************************************/ + +/** @file rg_utl.c +@brief This file implements utility functions for LTE MAC +*/ + +static const char* RLOG_MODULE_NAME="MAC"; +static int RLOG_MODULE_ID=4096; +static int RLOG_FILE_ID=179; + +/* header include files (.h) */ +#include "envopt.h" /* environment options */ +#include "envdep.h" /* environment dependent */ +#include "envind.h" /* environment independent */ + +#include "gen.h" /* general */ +#include "ssi.h" /* system services */ +#include "cm_tkns.h" /* Common Token Defines */ +#include "cm_llist.h" /* Common Link List Defines */ +#include "cm_hash.h" /* Common Hash List Defines */ +#include "cm_mblk.h" /* common memory link list library */ +#include "cm_lte.h" /* Common LTE */ + +#include "rg_env.h" /* MAC Environment Defines */ +#include "crg.h" /* CRG Interface defines */ +#include "rgu.h" /* RGU Interface defines */ +#include "tfu.h" /* TFU Interface defines */ +#include "rg_sch_inf.h" /* RGR Interface defines */ +#include "lrg.h" /* LRG Interface defines */ + +#include "rg_prg.h" /* PRG(MAC-MAC) Interface includes */ +#include "rg.h" /* MAC defines */ +#include "rg_err.h" /* MAC error defines */ + +/* header/extern include files (.x) */ +#include "gen.x" /* general */ +#include "ssi.x" /* system services */ +#include "cm5.x" /* Timer */ +#include "cm_tkns.x" /* Common Token Definitions */ +#include "cm_llist.x" /* Common Link List Definitions */ +#include "cm_lib.x" /* Common Library Definitions */ +#include "cm_hash.x" /* Common Hash List Definitions */ +#include "cm_mblk.x" /* common memory link list library */ +#include "cm_lte.x" /* Common LTE */ + +#include "crg.x" /* CRG Interface includes */ +#include "rgu.x" /* RGU Interface includes */ +#include "tfu.x" /* TFU Interface includes */ +#include "rg_sch_inf.x" /* RGR Interface includes */ +#include "lrg.x" /* LRG Interface includes */ +#include "rg_prg.x" /* PRG(MAC-MAC) Interface includes */ + +#include "rg.x" /* MAC includes */ + +/* local defines */ +#define RG_NON_MIMO_IDX 0 + +/* local typedefs */ + +/* local externs */ + +/* forward references */ +PRIVATE S16 rgUtlHndlCrntiChng ARGS(( + Inst inst, + RgCellCb *cell, + CmLteRnti rnti, + CmLteRnti newRnti + )); +PRIVATE Void rgUtlHndlCrntiRls ARGS(( + RgCellCb *cell, + RgInfRlsRnti *rlsRnti + )); + +PUBLIC S16 rgDelUeFrmAllSCell ARGS(( + RgCellCb *cell, + RgUeCb *ue + )); + +#ifdef LTE_ADV +PRIVATE S16 rgUtlSndCrntiChngReq2AllSMacs ARGS(( + RgCellCb *cell, + CmLteRnti rnti, + CmLteRnti newRnti + )); +#endif +/*********************************************************** + * + * Func : rgAllocShrablSBuf + * + * Desc : Utility Function to Allocate static buffer which is + * sharable among different layers if YYYY flag is enabled. + * else it allocates from normal static region + * Memory allocated is assumed contiguous. + * + * + * Ret : ROK + * RFAILED + * + * Notes: Caller doesnt need to raise the alarm in case of memory + * allocation gets failed. + * + * File : rg_utl.c + * + **********************************************************/ +#ifdef ANSI +PUBLIC S16 rgAllocShrablSBuf +( +Inst inst, +Data **pData, /* Pointer of the data to be returned */ +Size size /* size */ +) +#else +PUBLIC S16 rgAllocShrablSBuf(inst,pData, size) +Inst inst; +Data **pData; /* Pointer of the data to be returned */ +Size size; /* size */ +#endif +{ + RgUstaDgn dgn; /* Alarm diagnostics structure */ + + TRC2(rgAllocShrablSBuf) + + /* Initialize the param to NULLP */ + *pData = NULLP; + + if (size == 0) + { + RETVALUE(RFAILED); + } + + /* allocate buffer */ + if (SGetStaticBuffer(rgCb[inst].rgInit.region, rgCb[inst].rgInit.pool, pData, size, 0) != ROK) + { + dgn.type = LRG_USTA_DGNVAL_MEM; + dgn.u.mem.region = rgCb[inst].rgInit.region; + dgn.u.mem.pool = rgCb[inst].rgInit.pool; + /* Send an alarm to Layer Manager */ + rgLMMStaInd(inst,LCM_CATEGORY_RESOURCE, LCM_EVENT_SMEM_ALLOC_FAIL, + LCM_CAUSE_MEM_ALLOC_FAIL, &dgn); + RGLOGERROR(inst,ERRCLS_DEBUG, ERG028, 0, "Unable to Allocate Buffer"); + RETVALUE(RFAILED); + } + +#ifndef ALIGN_64BIT + RGDBGINFO(inst,(rgPBuf(inst), "SGetSBuf(Region (%d), Pool (%d), Size (%ld)), Data (0x%p))\n", + rgCb[inst].rgInit.region, rgCb[inst].rgInit.pool, size, *pData)); +#else + RGDBGINFO(inst,(rgPBuf(inst), "SGetSBuf(Region (%d), Pool (%d), Size (%d)), Data (0x%p))\n", + rgCb[inst].rgInit.region, rgCb[inst].rgInit.pool, size, *pData)); +#endif + + /* zero out the allocated memory */ + cmMemset((U8 *)*pData, 0x00, size); + + RETVALUE(ROK); + +} /* end of rgAllocSBuf */ + + +/*********************************************************** + * + * Func : rgAllocSBuf + * + * Desc : Utility Function to Allocate static buffer. + * Memory allocated is assumed contiguous. + * + * + * Ret : ROK + * RFAILED + * + * Notes: Caller doesnt need to raise the alarm in case of memory + * allocation gets failed. + * + * File : rg_utl.c + * + **********************************************************/ +#ifdef ANSI +PUBLIC S16 rgAllocSBuf +( +Inst inst, +Data **pData, /* Pointer of the data to be returned */ +Size size /* size */ +) +#else +PUBLIC S16 rgAllocSBuf(inst,pData, size) +Inst inst; +Data **pData; /* Pointer of the data to be returned */ +Size size; /* size */ +#endif +{ + RgUstaDgn dgn; /* Alarm diagnostics structure */ + + TRC2(rgAllocSBuf) + + /* Initialize the param to NULLP */ + *pData = NULLP; + + if (size == 0) + { + RETVALUE(RFAILED); + } + + /* allocate buffer */ +#ifdef MS_MBUF_CORRUPTION /* Should be enabled when debugging mbuf corruption */ + MS_BUF_ADD_ALLOC_CALLER(); +#endif /* */ + if (SGetSBuf(rgCb[inst].rgInit.region, rgCb[inst].rgInit.pool, pData, size) != ROK) + { + dgn.type = LRG_USTA_DGNVAL_MEM; + dgn.u.mem.region = rgCb[inst].rgInit.region; + dgn.u.mem.pool = rgCb[inst].rgInit.pool; + /* Send an alarm to Layer Manager */ + rgLMMStaInd(inst,LCM_CATEGORY_RESOURCE, LCM_EVENT_SMEM_ALLOC_FAIL, + LCM_CAUSE_MEM_ALLOC_FAIL, &dgn); + RGLOGERROR(inst,ERRCLS_DEBUG, ERG028, 0, "Unable to Allocate Buffer"); + RETVALUE(RFAILED); + } + + /* zero out the allocated memory */ + cmMemset((U8 *)*pData, 0x00, size); + + RETVALUE(ROK); + +} /* end of rgAllocSBuf */ + +/* +* +* Fun: rgFreeSharableSBuf +* +* Desc: The argument to rgFreeSBuf() is a pointer to a block +* previously allocated by rgAllocSBuf() and size. It +* deallocates the memory. +* +* Ret: RETVOID +* +* Notes: ccpu00117052 - MOD- changed the Data parameter from +* pointer to address of pointer so that +* the freed memory could be set to NULLP +* +* File: rg_utl.c +*/ +#ifdef ANSI +PUBLIC Void rgFreeSharableSBuf +( +Inst inst, +Data **data, /* address of pointer to data */ +Size size /* size */ +) +#else +PUBLIC Void rgFreeSharableSBuf(inst,data, size) +Inst inst; +Data **data; /* address of pointer to data */ +Size size; /* size */ +#endif +{ + + S16 ret; + + TRC2(rgFreeSharableBuf) + + if ((data == NULLP) || (*data == NULLP) || (size == 0)) + { + RETVOID; + } + + /* Deallocate buffer */ + ret = SPutStaticBuffer(rgCb[inst].rgInit.region, rgCb[inst].rgInit.pool, *data, size, SS_SHARABLE_MEMORY); + + if (ret != ROK) + { + RETVOID; + } + + *data = NULLP; + + RETVOID; + +} /* end of rgFreeSharableBuf */ + + + +/* +* +* Fun: rgFreeSBuf +* +* Desc: The argument to rgFreeSBuf() is a pointer to a block +* previously allocated by rgAllocSBuf() and size. It +* deallocates the memory. +* +* Ret: RETVOID +* +* Notes: ccpu00117052 - MOD- changed the Data parameter from +* pointer to address of pointer so that +* the freed memory could be set to NULLP +* +* File: rg_utl.c +*/ +#ifdef ANSI +PUBLIC Void rgFreeSBuf +( +Inst inst, +Data **data, /* address of pointer to data */ +Size size /* size */ +) +#else +PUBLIC Void rgFreeSBuf(inst,data, size) +Inst inst; +Data **data; /* address of pointer to data */ +Size size; /* size */ +#endif +{ + + S16 ret; + + TRC2(rgFreeSBuf) + + if ((data == NULLP) || (*data == NULLP) || (size == 0)) + { + RETVOID; + } + + +#ifdef MS_MBUF_CORRUPTION /* Should be enabled when debugging mbuf corruption */ + MS_BUF_ADD_CALLER(); +#endif /* */ + /* Deallocate buffer */ + ret = SPutSBuf(rgCb[inst].rgInit.region, rgCb[inst].rgInit.pool, *data, size); + + if (ret != ROK) + { + RGLOGERROR(inst,ERRCLS_DEBUG, ERG029, (ErrVal) 0, "rgFreeSBuf failed.\n"); + RETVOID; + } + + *data = NULLP; + + RETVOID; + +} /* end of rgFreeSBuf */ + + +/*********************************************************** + * + * Func : rgGetMsg + * + * Desc : Utility Function to Allocate message buffer. + * + * + * Ret : ROK + * RFAILED + * + * Notes: Caller doesnt need to raise the alarm in case of memory + * allocation gets failed. + * + * File : rg_utl.c + * + **********************************************************/ +#ifdef ANSI +PUBLIC S16 rgGetMsg +( +Inst inst, +Buffer **mBuf /* Message Buffer pointer be returned */ +) +#else +PUBLIC S16 rgGetMsg(inst,mBuf) +Inst inst; +Buffer **mBuf; /* Message Buffer pointer be returned */ +#endif +{ + S16 ret; + + TRC2(rgGetMsg) + +#ifdef MS_MBUF_CORRUPTION /* Should be enabled when debugging mbuf corruption */ + MS_BUF_ADD_ALLOC_CALLER(); +#endif /* */ + ret = SGetMsg(RG_GET_MEM_REGION(rgCb[inst]), RG_GET_MEM_POOL(rgCb[inst]), mBuf); + + if (ROK != ret) + { + /* Moving diagnostics structure to limited scope for optimization */ + RgUstaDgn dgn; /* Alarm diagnostics structure */ + + rgFillDgnParams(inst,&dgn, LRG_USTA_DGNVAL_MEM); + + /* Send an alarm to Layer Manager */ + rgLMMStaInd(inst,LCM_CATEGORY_RESOURCE, LCM_EVENT_DMEM_ALLOC_FAIL, + LCM_CAUSE_MEM_ALLOC_FAIL, &dgn); + RGLOGERROR(inst,ERRCLS_DEBUG, ERG030, 0, "Unable to Allocate Buffer"); + RETVALUE(RFAILED); + } + + RETVALUE(ROK); + +} /* end of rgGetMsg */ + + +/*********************************************************** + * + * Func : rgFillDgnParams + * + * Desc : Utility Function to Fill Diagonostic params. + * + * Ret : None. + * + * Notes: None. + * + * File : rg_utl.c + * + **********************************************************/ +#ifdef ANSI +PUBLIC Void rgFillDgnParams +( +Inst inst, +RgUstaDgn *dgn, +U8 dgnType +) +#else +PUBLIC Void rgFillDgnParams(inst,dgn, dgnType) +Inst inst; +RgUstaDgn *dgn; +U8 dgnType; +#endif +{ + + TRC2(rgFillDgnParams) + + switch(dgnType) + { + case LRG_USTA_DGNVAL_MEM: + dgn->type = (U8) LRG_USTA_DGNVAL_MEM; + dgn->u.mem.region = rgCb[inst].rgInit.region; + dgn->u.mem.pool = rgCb[inst].rgInit.pool; + break; + + default: + break; + } + + RETVOID; +} /* end of rgFillDgnParams */ + + +/*********************************************************** + * + * Func : rgUpdtRguDedSts + * + * Desc : Utility Function to update rgu sap statistics for dedicated + * DatReqs. + * + * + * Ret : ROK + * RFAILED + * + * Notes: + * + * File : rg_utl.c + * + **********************************************************/ +#ifdef ANSI +PUBLIC Void rgUpdtRguDedSts +( +Inst inst, +RgUpSapCb *rguDlSap, +U8 stsType, /* Statistics type to update */ +RgRguDedDatReq *datReq /* DatReq pointer */ +) +#else +PUBLIC Void rgUpdtRguDedSts(inst,rguDlSap,stsType, datReq) +Inst inst; +RgUpSapCb *rguDlSap; +U8 stsType; /* Statistics type to update */ +RgRguDedDatReq *datReq; /* DatReq pointer */ +#endif +{ + U8 idx1,idx2; + U32 idx; + + + TRC2(rgUpdtRguDedSts) + + + switch(stsType) + { + case RG_RGU_SDU_RCVD: + for(idx = 0; idx < datReq->nmbOfUeGrantPerTti; idx++) + { + RguDDatReqPerUe *datReqPerUe = &datReq->datReq[idx]; + for (idx1 = 0; idx1 < datReqPerUe->nmbOfTbs; idx1++) + { + for(idx2 = 0; idx2 < datReqPerUe->datReqTb[idx1].nmbLch; idx2++) + { + rguDlSap->sapSts.numPduRcvd += + datReqPerUe->datReqTb[idx1].lchData[idx2].pdu.numPdu; + } + } + } + + break; + case RG_RGU_SDU_DROP: + for(idx = 0; idx < datReq->nmbOfUeGrantPerTti; idx++) + { + RguDDatReqPerUe *datReqPerUe = &datReq->datReq[idx]; + for (idx1 = 0; idx1 < datReqPerUe->nmbOfTbs; idx1++) + { + for(idx2 = 0; idx2 < datReqPerUe->datReqTb[idx1].nmbLch; idx2++) + { + rguDlSap->sapSts.numPduRcvd += + datReqPerUe->datReqTb[idx1].lchData[idx2].pdu.numPdu; + rguDlSap->sapSts.numPduDrop += + datReqPerUe->datReqTb[idx1].lchData[idx2].pdu.numPdu; + } + } + } + + break; + } + + RETVOID; +} /* rgUpdtRguDedSts */ + + +/*********************************************************** + * + * Func : rgUpdtRguCmnSts + * + * Desc : Utility Function to update rgu sap statistics for common + * DatReqs. + * + * + * Ret : ROK + * RFAILED + * + * Notes: + * + * File : rg_utl.c + * + **********************************************************/ +#ifdef ANSI +PUBLIC Void rgUpdtRguCmnSts +( +Inst inst, +RgUpSapCb *rguDlSap, +U8 stsType /* Statistics type to update */ +) +#else +PUBLIC Void rgUpdtRguCmnSts(inst,rguDlSap,stsType) +Inst inst; +RgUpSapCb *rguDlSap; +U8 stsType; /* Statistics type to update */ +#endif +{ + TRC2(rgUpdtRguCmnSts) + + + + switch(stsType) + { + case RG_RGU_SDU_RCVD: + rguDlSap->sapSts.numPduRcvd ++; + break; + case RG_RGU_SDU_DROP: + rguDlSap->sapSts.numPduRcvd ++; + rguDlSap->sapSts.numPduDrop ++; + break; + } + + RETVOID; +} /* rgUpdtRguCmnSts */ + + +/*********************************************************** + * + * Func : rgUpdtCellCnt + * + * Desc : Utility Function to update cell count. It gives number of active + * cells + * + * + * Ret : ROK + * RFAILED + * + * Notes: This function should be called only after cell is added/deleted + * from the globlal hashlist + * + * File : rg_utl.c + * + **********************************************************/ +#ifdef ANSI +PUBLIC Void rgUpdtCellCnt +( +Inst inst, +U8 updtType +) +#else +PUBLIC Void rgUpdtCellCnt(inst,updtType) +Inst inst; +U8 updtType; +#endif +{ + TRC2(rgUpdtCellCnt); + + switch (updtType) + { + case RG_CFG_ADD: + rgCb[inst].genSts.numCellCfg++; + break; + case RG_CFG_DEL: + rgCb[inst].genSts.numCellCfg--; + break; + default: + break; + } + + RETVOID; +} /* rgUpdtCellCnt */ + + +/*********************************************************** + * + * Func : rgUpdtUeCnt + * + * Desc : Utility Function to update ue count. It gives number of active + * Ues. + * + * + * Ret : ROK + * RFAILED + * + * Notes: This function should be called only after ue is added/deleted + * from the globlal hashlist + * + * File : rg_utl.c + * + **********************************************************/ +#ifdef ANSI +PUBLIC Void rgUpdtUeCnt +( +Inst inst, +U8 updtType +) +#else +PUBLIC Void rgUpdtUeCnt (inst,updtType) +Inst inst; +U8 updtType; +#endif +{ + TRC2(rgUpdtUeCnt); + + switch (updtType) + { + case RG_CFG_ADD: + rgCb[inst].genSts.numUeCfg++; + break; + case RG_CFG_DEL: + rgCb[inst].genSts.numUeCfg--; + break; + default: + break; + } + RETVOID; +} /* rgUpdtUeCnt */ + +/* +* +* Fun: rgAllocEventMem +* +* Desc: This function allocates event memory +* +* Ret: ROK - on success +* RFAILED - on failure +* +* Notes: None +* +* File: rg_utl.c +* +*/ +#ifdef ANSI +PUBLIC S16 rgAllocEventMem +( +Inst inst, +Ptr *memPtr, +Size memSize +) +#else +PUBLIC S16 rgAllocEventMem(inst,memPtr, memSize) +Inst inst; +Ptr *memPtr; +Size memSize; +#endif +{ + Mem sMem; + VOLATILE U32 startTime=0; + + TRC2(rgAllocEventMem) + + sMem.region = rgCb[inst].rgInit.region; + sMem.pool = rgCb[inst].rgInit.pool; + +#if (ERRCLASS & ERRCLS_DEBUG) + if (memSize<= 0) + { + RGLOGERROR(inst,ERRCLS_INT_PAR, ERG031, memSize, + "rgAllocEventMem(): memSize invalid\n"); + RETVALUE (RFAILED); + } +#endif /* ERRCLASS & ERRCLS_DEBUG */ + + + /*starting Task*/ + SStartTask(&startTime, PID_MACUTL_CMALLCEVT); + +#ifdef MS_MBUF_CORRUPTION /* Should be enabled when debugging mbuf corruption */ + MS_BUF_ADD_ALLOC_CALLER(); +#endif /* */ +#ifdef TFU_ALLOC_EVENT_NO_INIT + if(ROK != cmAllocEvntNoInit(memSize, TFU_MAX_MEMBLK_SIZE, &sMem, memPtr)) +#else + if(ROK != cmAllocEvnt(memSize, TFU_MAX_MEMBLK_SIZE, &sMem, memPtr)) +#endif /* */ + { + RLOG0(L_ERROR,"cmAllocEvnt Failed"); + RETVALUE(RFAILED); + } + + /*stoping Task*/ + SStopTask(startTime, PID_MACUTL_CMALLCEVT); + + RETVALUE(ROK); +} /* end of rgAllocEventMem*/ + +/* +* +* Fun: rgGetEventMem +* +* Desc: This function allocates event memory +* +* Ret: ROK - on success +* RFAILED - on failure +* +* Notes: None +* +* File: rg_utl.c +* +*/ +#ifdef ANSI +PUBLIC S16 rgGetEventMem +( +Inst inst, +Ptr *ptr, +Size len, +Ptr memCp +) +#else +PUBLIC S16 rgGetEventMem(inst,ptr, len, memCp) +Inst inst; +Ptr *ptr; +Size len; +Ptr memCp; +#endif +{ + S16 ret; + + TRC2(rgGetEventMem) +#ifdef TFU_ALLOC_EVENT_NO_INIT + ret = cmGetMemNoInit(memCp, len, (Ptr *)ptr); +#else + ret = cmGetMem(memCp, len, (Ptr *)ptr); +#endif /* */ + RETVALUE(ret); +} /* end of rgGetEventMem*/ + +/*********************************************************** + * + * Func : rgGetPstToInst + * + * Desc : Utility Function to get the pst structure to post a message to + * scheduler instance + * + * + * Ret : ROK + * RFAILED + * + * Notes: This function should be called while sending a msg from + * MAC to a scheduler instance + * + * File : rg_utl.c + * + **********************************************************/ +#ifdef ANSI +PUBLIC Void rgGetPstToInst +( +Pst *pst, +Inst srcInst, +Inst dstInst +) +#else +PUBLIC Void rgGetPstToInst (pst, srcInst, dstInst) +Pst *pst; +Inst srcInst; +Inst dstInst; +#endif +{ + TRC2(rgGetPstToInst); + + pst->srcEnt = rgCb[srcInst].rgInit.ent; + pst->srcInst = rgCb[srcInst].rgInit.inst; + pst->srcProcId = rgCb[srcInst].rgInit.procId; + pst->region = rgCb[srcInst].rgInit.region; + pst->pool = rgCb[srcInst].rgInit.pool; + + pst->dstProcId = rgCb[dstInst].rgInit.procId; + pst->dstEnt = rgCb[dstInst].rgInit.ent; + pst->dstInst = dstInst; + pst->selector = 0; + pst->prior = PRIOR0; + pst->intfVer = 0; + pst->route = RTESPEC; + + RETVOID; +} /* end of rgGetPstToInst */ + +/*********************************************************** + * + * Func : RgSchMacLcgRegReq + * + * Desc : Utility Function to register the set of GBR LCG. + * Invoked at the time of LCG configuration/Reconfiguration at Schedular. + * + * Processing Steps: + * - Fetch the ueCb using the crnti given in lcInfo + * - Store the if LCG is GBR or not. + * + * Ret : ROK + * RFAILED + * + * Notes: This function should be called at the time of LCG + * configuration/Reconfiguration at Schedular. + * + * + * File : rg_utl.c + * + **********************************************************/ +#ifdef ANSI +PUBLIC S16 RgSchMacLcgRegReq +( +Pst *pst, +RgInfLcgRegReq *lcgRegReq +) +#else +PUBLIC S16 RgSchMacLcgRegReq (pst, lcgRegReq) +Pst *pst; +RgInfLcgRegReq *lcgRegReq; +#endif +{ + Inst inst; + RgCellCb *cell = NULLP; + RgUeCb *ue; + + TRC2(RgSchMacLcgRegReq); + + RG_IS_INST_VALID(pst->dstInst); + inst = pst->dstInst - RG_INST_START; + cell = rgCb[inst].cell; + /* Fetch the cell and then the UE */ + if((cell == NULLP) || + (cell->cellId != lcgRegReq->cellId)) + { + + RLOG_ARG0(L_ERROR,DBG_CELLID,lcgRegReq->cellId,"Cell does not exist "); + RETVALUE(RFAILED); + } + + if ((ue = rgDBMGetUeCb(cell, lcgRegReq->crnti)) == NULLP) + { + RLOG_ARG1(L_ERROR, DBG_CELLID,cell->cellId,"CRNTI:%d does not exist", + lcgRegReq->crnti); + RETVALUE(RFAILED); + } + ue->ul.lcgArr[lcgRegReq->lcgId].isGbr = lcgRegReq->isGbr; + + RETVALUE(ROK); +} /* end of RgSchMacLcgRegReq */ + +#ifdef LTEMAC_SPS + +/*********************************************************** + * + * Func : RgSchMacUlSpsResetReq + * + * Desc : Utility Function to reset SPS params for a UE + * + * Processing Steps: + * - Fetch the ueCb using the crnti + * - reset implRelCnt and explRelCnt + * + * Ret : ROK + * RFAILED + * + * File : rg_utl.c + * + **********************************************************/ +#ifdef ANSI +PUBLIC S16 RgSchMacUlSpsResetReq +( +Pst *pst, +RgInfUlSpsReset *ulSpsResetInfo +) +#else +PUBLIC S16 RgSchMacUlSpsResetReq (pst, lcInfo) +Pst *pst; +RgInfUlSpsReset *ulSpsResetInfo; +#endif +{ + Inst inst; + RgCellCb *cell = NULLP; + RgUeCb *ue; + + TRC2(RgSchMacUlSpsResetReq); + + RG_IS_INST_VALID(pst->dstInst); + inst = pst->dstInst - RG_INST_START; + cell = rgCb[inst].cell; + /* Fetch the cell and then the UE */ + if((cell == NULLP)|| + (cell->cellId != ulSpsResetInfo->cellId)) + { + + RLOG_ARG0(L_ERROR, DBG_CELLID,ulSpsResetInfo->cellId,"Cell does not exist "); + RETVALUE(RFAILED); + } + + if ((ue = rgDBMGetUeCb(cell, ulSpsResetInfo->crnti)) == NULLP) + { + RLOG_ARG1(L_ERROR, DBG_CELLID,cell->cellId,"CRNTI:%d does not exist", + ulSpsResetInfo->crnti); + RETVALUE(RFAILED); + } + + ue->ul.implRelCntr = 0; + ue->ul.explRelCntr = 0; + + RETVALUE(ROK); +} /* end of RgSchMacUlSpsResetReq */ + + + + +/*********************************************************** + * + * Func : RgSchMacSpsLcRegReq + * + * Desc : Utility Function to register the set of uplink SPS logical + * channels for a SPS UE. + * Invoked at the time of activation of a UE for UL-SPS. + * Whenever there is data on these LCs MAC shall inform scheduler + * + * Processing Steps: + * - Fetch the ueCb using the crnti given in lcInfo + * - Store the sps-rnti and set the bits corresponding to the + * logical channel ids in ueUlCb->spsLcMask. + * + * Ret : ROK + * RFAILED + * + * Notes: This function should be called at the time UL SPS is activated + * for a UE at scheduler + * + * + * File : rg_utl.c + * + **********************************************************/ +#ifdef ANSI +PUBLIC S16 RgSchMacSpsLcRegReq +( +Pst *pst, +RgInfSpsLcInfo *lcInfo +) +#else +PUBLIC S16 RgSchMacSpsLcRegReq (pst, lcInfo) +Pst *pst; +RgInfSpsLcInfo *lcInfo; +#endif +{ + Inst inst; + RgCellCb *cell= NULLP; + RgUeCb *ue; + U8 idx; + + TRC2(RgSchMacSpsLcRegReq); + + RG_IS_INST_VALID(pst->dstInst); + inst = pst->dstInst - RG_INST_START; + cell = rgCb[inst].cell; + /* Fetch the cell and then the UE */ + if((cell == NULLP) || + (cell->cellId != lcInfo->cellId)) + { + + RLOG_ARG0(L_ERROR,DBG_CELLID,lcInfo->cellId, "Cell does not exist "); + RETVALUE(RFAILED); + } + + if ((ue = rgDBMGetUeCb(cell, lcInfo->crnti)) == NULLP) + { + RLOG_ARG1(L_ERROR, DBG_CELLID,cell->cellId,"CRNTI:%d does not exist", + lcInfo->crnti); + RETVALUE(RFAILED); + } + + /* Store the sps-rnti and SPS LC information in the UE */ + ue->spsRnti = lcInfo->spsRnti; + for (idx=0; idx < lcInfo->spsLcCnt; idx++) + { + /* KWORK_FIX: Modified the index from lcId to lcId-1 for handling lcId 10 properly */ + ue->ul.spsLcId[(lcInfo->spsLcId[idx])-1] = TRUE; + } + ue->ul.implRelCnt = lcInfo->implRelCnt; + ue->ul.explRelCnt = ue->ul.implRelCnt + 1; /*(lcInfo->implRelCnt * lcInfo->spsPrd);*/ + + /* Insert the UE into SPS UE List */ + if (rgDBMInsSpsUeCb(cell, ue) == RFAILED) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId, + "Ue insertion into SPS list failed SPS CRNTI:%d", ue->spsRnti); + RETVALUE(RFAILED); + } + + RETVALUE(ROK); +} /* end of RgSchMacSpsLcRegReq */ + + +/*********************************************************** + * + * Func : RgSchMacSpsLcDeregReq + * + * Desc : Utility Function to deregister the set of uplink SPS + * logical channels for a UE. + * Invoked at the time of release of UL-SPS for an activated UE. + * + * Processing Steps: + * - Fetch the ueCb using the crnti given + * - Reset the bits corresponding to the logical channel ids in + * ueUlCb->spsLcMask. + * + * Ret : ROK + * RFAILED + * + * Notes: This function should be called at the time UL SPS is released + * for a UE at scheduler + * + * + * File : rg_utl.c + * + **********************************************************/ +#ifdef ANSI +PUBLIC S16 RgSchMacSpsLcDeregReq +( +Pst *pst, +CmLteCellId cellId, +CmLteRnti crnti +) +#else +PUBLIC S16 RgSchMacSpsLcDeregReq (pst, cellId, crnti) +Pst *pst; +CmLteCellId cellId; +CmLteRnti crnti; +#endif +{ + Inst inst; + RgCellCb *cell = NULLP; + RgUeCb *ue; + + TRC2(RgSchMacSpsLcDeregReq); + + RG_IS_INST_VALID(pst->dstInst); + inst = pst->dstInst - RG_INST_START; + cell = rgCb[inst].cell; + /* Fetch the cell and then the UE */ + if((cell == NULLP) || + (cell->cellId != cellId)) + { + + RLOG_ARG0(L_ERROR,DBG_CELLID,cellId, "Cell does not exist "); + RETVALUE(RFAILED); + } + + if ((ue = rgDBMGetUeCb(cell, crnti)) == NULLP) + { + RLOG_ARG1(L_ERROR, DBG_CELLID,cellId,"CRNTI:%d Ue does not exist", crnti); + RETVALUE(RFAILED); + } + + /* No need to reset the SPS LC Ids as they will not be looked at*/ + + /* Delete UE from the SPS UE List */ + rgDBMDelSpsUeCb(cell, ue); + + RETVALUE(ROK); +} /* end of RgSchMacSpsLcDeregReq */ + +#endif /* LTEMAC_SPS */ + +/** + * @brief Function for handling CRNTI change request + * received from scheduler to MAC. + * + * @details + * + * Function : rgUtlHndlCrntiChng + * + * - Delete old UE from the list. + * - Update the new rnti and re-insert the UE in the list. + * + * + * @param[in] Inst inst + * @param[in] RgCellCb *cell, + * @param[in] CmLteRnti rnti, + * @param[in] CmLteRnti newRnti + * @return S16 + * -# ROK + * -# RFAILED + **/ +#ifdef ANSI +PRIVATE S16 rgUtlHndlCrntiChng +( +Inst inst, +RgCellCb *cell, +CmLteRnti rnti, +CmLteRnti newRnti +) +#else +PRIVATE S16 rgUtlHndlCrntiChng(inst,cell, rnti, newRnti) +Inst inst; +RgCellCb *cell; +CmLteRnti rnti; +CmLteRnti newRnti; +#endif +{ + RgUeCb *ue = NULLP; + RgUeCb *newUe = NULLP; + + TRC3(rgUtlHndlCrntiChng) + + ue = rgDBMGetUeCb(cell, rnti); + newUe = rgDBMGetUeCbFromRachLst(cell, newRnti); + if ((ue == NULLP) || (newUe == NULLP)) + { + RLOG_ARG4(L_ERROR,DBG_CELLID,cell->cellId, + "RNTI:%d Failed to get UECB[%lu:%lu] or NEW RNTI:%d", + rnti, ((PTR)ue), ((PTR)newUe), newRnti); + RETVALUE(RFAILED); + } +#ifdef XEON_SPECIFIC_CHANGES + CM_LOG_DEBUG(CM_LOG_ID_MAC, "MAC:UE[%d] id changed to %d\n", rnti, newRnti); +#endif + rgDBMDelUeCb(cell, ue); + + ue->ueId = newRnti; + + cmMemcpy((U8*)&(ue->contResId), (U8*)&(newUe->contResId), + sizeof(newUe->contResId)); + /* Fix : syed MSG4 might be RETXing need to store the + * HARQ context. */ + rgDHMFreeUe(inst,&ue->dl.hqEnt); + ue->dl.hqEnt = newUe->dl.hqEnt; + + rgDBMInsUeCb(cell, ue); + + rgDBMDelUeCbFromRachLst(cell, newUe); + rgFreeSBuf(inst,(Data **)&newUe, sizeof(*newUe)); + + RETVALUE(ROK); +} /* end of rgUtlHndlCrntiChng */ + +#ifdef LTE_ADV +/** + * @brief Function for handling UE release for SCELL + * triggered from SCH to MAC. + * + * @details + * + * Function : rgDelUeFrmAllSCell + * + * - This Function should be invoked by PCell of UE + * - Remove the UE context from SCELL corresponding to rnti. + * + * @param[in] Inst *macInst, + * @param[in] RgUeCb *ue + * @return ROK is SUCCESS + **/ +#ifdef ANSI +PUBLIC S16 rgDelUeFrmAllSCell +( +RgCellCb *cell, +RgUeCb *ue +) +#else +PUBLIC S16 rgDelUeFrmAllSCell(cell, ue) +RgCellCb *cell; +RgUeCb *ue; +#endif +{ + Inst inst = cell->macInst - RG_INST_START; + U8 idx = 0; + Inst sCellInstIdx; + Pst dstInstPst; + RgPrgUeSCellDelInfo ueSCellDelInfo; + + TRC2(rgDelUeFrmAllSCell) + + /* To Delete the SCells if exisits for that UE */ + for(idx = 0; idx < RG_MAX_SCELL_PER_UE ; idx++) + { + if(TRUE == ue->sCelInfo[idx].isSCellAdded) + { + sCellInstIdx = ue->sCelInfo[idx].macInst - RG_INST_START; + + rgGetPstToInst(&dstInstPst, inst, sCellInstIdx); + ueSCellDelInfo.ueId = ue->ueId; + ueSCellDelInfo.sCellId = ue->sCelInfo[idx].sCellId; + + /* Filling same ueId in newRnti so that SMAC will check if newRnti + *and old UeId is same that means its a UeSCell delete request*/ + ueSCellDelInfo.newRnti = ue->ueId; + + RgPrgPMacSMacUeSCellDel(&dstInstPst, &ueSCellDelInfo); + ue->sCelInfo[idx].isSCellAdded = FALSE; + } /* loop of if */ + } /* loop of for */ + + RETVALUE(ROK); +} /* rgDelUeFrmAllSCell */ + +/** + * @brief Function to validate AddSCellCfg. + * + * @details + * + * Function : rgUtlVltdAddSCellCfg + * + * + * @param[in] ueSCellCb secondary cell CB for validation + * @param[in] cell cell control block + * @param[in] inst instance number to fetch rgCb instance + * @return S16 + * -# ROK + **/ +#ifdef ANSI +PUBLIC S16 rgUtlVltdAddSCellCfg +( + RgPrgUeSCellCfgInfo *ueSCellCb, + RgCellCb *cell, + Inst inst +) +#else +PUBLIC S16 rgUtlVltdAddSCellCfg(ueSCellCb, cell, inst) + RgPrgUeSCellCfgInfo *ueSCellCb; + RgCellCb *cell; + Inst inst; +#endif +{ + S16 ret = ROK; + + TRC3(rgUtlVltdAddSCellCfg) + + /* To Validate the CellID presence */ + if((cell == NULLP) || + (cell->cellId != ueSCellCb->cellId)) + { + RGDBGERRNEW(inst, (rgPBuf(inst), + "[%d]Sec Cell does not exit %d\n", + ueSCellCb->ueId, ueSCellCb->cellId)); + ret = RFAILED; + } +#ifdef TENB_MULT_CELL_SUPPRT + if((ueSCellCb->rguDlSapId > rgCb[inst].numRguSaps) || + (ueSCellCb->rguUlSapId > rgCb[inst].numRguSaps)) + { + RGDBGERRNEW(inst,(rgPBuf(inst), "Invald Sap Id: DL %d UL %d for ueId %d failed\n", + ueSCellCb->rguDlSapId, + ueSCellCb->rguUlSapId, + ueSCellCb->cellId)); + ret = RFAILED; + } +#endif + RETVALUE(ret); +} /* rgUtlVltdAddSCellCfg */ + +/** + * @brief Function to build CrntiChangeReq and send to all SMACs. + * + * @details + * + * Function : rgUtlSndCrntiChngReq2AllSMacs + * + * - This Function should be invoked by PCell of UE + * - It sends RgPrgPMacSMacUeSCellDelReq to all SMACs with newRnti sent + * by SCH. SMAC will check if newRnti is not equal to old UeId then it + * do only UeId change else it will delete the UeScell context + * + * @param[in] cell Cell CB to get Ue control block + * @param[in] rnti Ue Identifier used to fill in UeId Change req + * @param[in] newRnti UE new identifier, to be used in UeId Change req + * @return S16 + * -# ROK + **/ +#ifdef ANSI +PRIVATE S16 rgUtlSndCrntiChngReq2AllSMacs +( +RgCellCb *cell, +CmLteRnti rnti, +CmLteRnti newRnti +) +#else +PRIVATE S16 rgUtlSndCrntiChngReq2AllSMacs(cell, rnti, newRnti) +RgCellCb *cell; +CmLteRnti rnti; +CmLteRnti newRnti; +#endif +{ + Inst inst = cell->macInst - RG_INST_START; + Inst sCellInstIdx; + Pst dstInstPst; + RgPrgUeSCellDelInfo ueIdChngReq; + RgUeCb *ue; + U8 idx; +#ifdef L2_OPTMZ +TfuDelDatReqInfo delDatReq; +#endif + + TRC2(rgUtlSndCrntiChngReq2AllSMacs) + + /* use newRnti to get UeCb in PMac because rnti is already changed in PMac*/ + ue = rgDBMGetUeCb(cell, newRnti); + if (ue == NULLP) + { + RGDBGERRNEW(inst,(rgPBuf(inst),"[%d]RNTI:Failed to get ueCb \ + newRnti=%d\n", rnti, newRnti)); + RETVALUE(RFAILED); + } + /* For all added SCells, prepare and send ueIdChngReq */ + for(idx = 0; idx < RG_MAX_SCELL_PER_UE ; idx++) + { + if(TRUE == ue->sCelInfo[idx].isSCellAdded) + { + sCellInstIdx = ue->sCelInfo[idx].macInst - RG_INST_START; + + rgGetPstToInst(&dstInstPst, inst, sCellInstIdx); + /* fill old rnti*/ + ueIdChngReq.ueId = rnti; + ueIdChngReq.sCellId = ue->sCelInfo[idx].sCellId; + + /* Filling newRnti so that SMAC can check if old ueId and new UeId + *(newRnti) is different then its a UeId change request from PMAC. + * RgPrgPMacSMacUeSCellDelReq is being reused for UeId change req + * from PMAC to SMAC*/ + ueIdChngReq.newRnti = newRnti; + + /* Re-using UeSCellDelReq API for UeId change*/ + RgPrgPMacSMacUeSCellDel(&dstInstPst, &ueIdChngReq); +#ifdef L2_OPTMZ + /* Sending delDatReq to CL to clear the Pdus for old UeId present in CL*/ + delDatReq.cellId = ueIdChngReq.sCellId; + delDatReq.ueId = ueIdChngReq.ueId; + rgLIMTfuDelDatReq(sCellInstIdx, &delDatReq); +#endif + + } /* loop of if */ + } /* loop of for */ + + RETVALUE(ROK); +} /* rgUtlSndCrntiChngReq2AllSMacs */ + +#endif /* LTE_ADV */ + +/** + * @brief Function for handling CRNTI Context release + * triggered from SCH to MAC. + * + * @details + * + * Function : rgUtlHndlCrntiRls + * + * - Remove the UE context from MAC corresponding to rnti. + * + * + * @param[in] RgCellCb *cell, + * @param[in] CmLteRnti rnti + * @return Void + **/ +#ifdef ANSI +PRIVATE Void rgUtlHndlCrntiRls +( +RgCellCb *cell, +RgInfRlsRnti *rlsRnti +) +#else +PRIVATE Void rgUtlHndlCrntiRls(cell, rlsRnti) +RgCellCb *cell; +CmLteRnti *rlsRnti; +#endif +{ + Inst inst = cell->macInst - RG_INST_START; + RgUeCb *ue = NULLP; +#ifdef LTEMAC_SPS + RgUeCb *spsUeCb = NULLP; +#endif + + TRC3(rgUtlHndlCrntiRls) + + if ((ue = rgDBMGetUeCb(cell, rlsRnti->rnti)) == NULLP) + { + /* Check in RachLst */ + if((ue=rgDBMGetUeCbFromRachLst (cell, rlsRnti->rnti)) != NULLP) + { + /* Delete Ue from the UE list */ + rgDBMDelUeCbFromRachLst(cell, ue); + + /* Free Ue */ + rgRAMFreeUeCb(inst,ue); + } + else + { + RLOG_ARG1(L_WARNING,DBG_CELLID,cell->cellId, + "RNTI:%d No ueCb found in RachLst",rlsRnti->rnti); + } + } + else + { +#ifdef LTE_ADV + if(FALSE == rlsRnti->isUeSCellDel) + { + rgDelUeFrmAllSCell(cell, ue); + } +#endif /* LTE_ADV */ + + /* Delete Ue from the UE list */ + rgDBMDelUeCb(cell, ue); +#ifdef LTEMAC_SPS + spsUeCb = rgDBMGetSpsUeCb (cell, ue->spsRnti); + if (spsUeCb) + { + rgDBMDelSpsUeCb(cell, spsUeCb); + } +#endif + + /* Free Ue */ + rgCFGFreeUeCb(cell, ue); + /* MS_REMOVE : syed Check in RachLst */ + { + if((ue=rgDBMGetUeCbFromRachLst (cell, rlsRnti->rnti)) != NULLP) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId, + "RNTI:%d STALE UE is still present", rlsRnti->rnti); + } + } + } + + RETVOID; +} /* end of rgUtlHndlCrntiRls */ + +/** + * @brief Function for handling RaResp request received from scheduler to MAC. + * + * @details + * + * Function : RgSchMacRlsRntiReq + * + * This function shall be invoked whenever scheduler is done with the + * allocations of random access responses for a subframe. + * This shall invoke RAM to create ueCbs for all the rapIds allocated and + * shall invoke MUX to create RAR PDUs for raRntis allocated. + * + * + * @param[in] CmLteCellId cellId, + * @param[in] CmLteTimingInfo timingInfo, + * @param[in] RaRespInfo *rarInfo + * @return S16 + * -# ROK + **/ +#ifdef ANSI +PUBLIC S16 RgSchMacRlsRntiReq +( +Pst *pst, +RgInfRlsRnti *rlsRnti +) +#else +PUBLIC S16 RgSchMacRlsRntiReq(pst, rlsRnti) +Pst *pst; +RgInfRlsRnti *rlsRnti; +#endif +{ + Pst schPst; + RgInfUeDelInd ueDelInd; + Inst macInst; + RgCellCb *cell; +#ifdef L2_OPTMZ +TfuDelDatReqInfo delDatReq; +#endif + + TRC3(RgSchMacRlsRntiReq) + + RG_IS_INST_VALID(pst->dstInst); + macInst = pst->dstInst - RG_INST_START; + cell = rgCb[macInst].cell; + + if(NULLP == rlsRnti) + { + RETVALUE(RFAILED); + } + + if((cell == NULLP) || + (cell->cellId != rlsRnti->cellId)) + { + + RLOG_ARG1(L_ERROR,DBG_CELLID,rlsRnti->cellId, + "No cellCb found with cellId for RNTI:%d", + rlsRnti->rnti); + RETVALUE(RFAILED); + } + /* Fix : syed Clearing UE context when SCH indicates to do so + * UE DEL from CRG interface is now dummy. */ + if (rlsRnti->ueIdChng) + { + /* Fix : syed ueId change as part of reestablishment. + * Now SCH to trigger this. CRG ueRecfg for ueId change + * is dummy */ + if (rgUtlHndlCrntiChng(macInst,cell, rlsRnti->rnti, rlsRnti->newRnti) != ROK) + { + RLOG_ARG2(L_ERROR,DBG_CELLID,rlsRnti->cellId, + "CRNTI change failed for RNTI:%d new RNTI:%d", + rlsRnti->rnti,rlsRnti->newRnti); + RETVALUE(RFAILED); + } + +#ifdef LTE_ADV + /*PMAC_Reest: Prepare CrntiChngReq and then send to all SMACs to change + *rnti in all Scells + */ + if(rgUtlSndCrntiChngReq2AllSMacs(cell, rlsRnti->rnti, rlsRnti->newRnti) != ROK) + { + /* TODO: do we need to send DelInd to SCH in failure case*/ + RETVALUE(RFAILED); + } +#endif +#ifdef L2_OPTMZ + /* Sending delDatReq to CL to clear the Pdus for old UeId present in CL*/ + delDatReq.cellId = cell->cellId; + delDatReq.ueId = rlsRnti->rnti; + rgLIMTfuDelDatReq(macInst, &delDatReq); +#endif + } + else + { + rgUtlHndlCrntiRls(cell, rlsRnti); + } + /* Fix : syed Send delete confirmation to SCH */ + /* Send RgMacSchUeDelInd to SCH only if it is Rnti release to PMAC. + * Basically dont send DelInd to SCH incase of Ue SCell Del*/ +#ifdef LTE_ADV + if(FALSE == rlsRnti->isUeSCellDel) +#endif + { + ueDelInd.cellSapId = cell->schInstMap.cellSapId; + ueDelInd.cellId = rlsRnti->cellId; + ueDelInd.rnti = rlsRnti->rnti; + rgGetPstToInst(&schPst,macInst, cell->schInstMap.schInst); + RgMacSchUeDel(&schPst, &ueDelInd); + } + + RETVALUE(ROK); +} /* end of RgSchMacRlsRntiReq */ + +#ifdef L2_OPTMZ +#ifdef ANSI +PUBLIC Bool RgUtlIsTbMuxed +( + TfuDatReqTbInfo *tb +) +#else +PUBLIC Bool RgUtlIsTbMuxed() + TfuDatReqTbInfo *tb +#endif +{ + MsgLen len = 0; + SFndLenMsg(tb->macHdr, &len); + RETVALUE(len?TRUE : FALSE); +} +#endif + +/********************************************************************** + + End of file +**********************************************************************/ diff --git a/src/5gnrrlc/kw.h b/src/5gnrrlc/kw.h new file mode 100755 index 000000000..709d6bede --- /dev/null +++ b/src/5gnrrlc/kw.h @@ -0,0 +1,1097 @@ +/******************************************************************************* +################################################################################ +# Copyright (c) [2017-2019] [Radisys] # +# # +# 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. # +################################################################################ +*******************************************************************************/ + +/********************************************************************20** + + Name: LTE RLC file + + Type: C include file + + Desc: This file contain the hash definations for RLC + + File: kw.h + +*********************************************************************21*/ +/** @file kw.h +@brief RLC Hash definitions +*/ + +#ifndef __KWH__ +#define __KWH__ +#include "rl_interface.h" +#include "rl_common.h" + + +#define KWLAYERNAME "LTE RLC" /* Layer Name */ + +#define EKWxxx 1 +#define EMG099 1 +#define EMG102 2 +#define EMG103 3 +#define EMG104 4 + +/* RLC-SPLIT Activity */ +#define KW_ONE 1 +#define KW_BIT0 0x01 +#define KW_BIT1 0x02 +#define KW_BIT2 0x04 +#define KW_BIT3 0x08 + +#define KW_2K_BYTE 2048 + +/* RLC RB flag bits */ +#define KW_RB_REESTABLISH_DL KW_BIT0 +#define KW_RB_REESTABLISH_UL KW_BIT1 +#define KW_RB_DELETE_DL KW_BIT2 +#define KW_RB_DELETE_UL KW_BIT3 + + +#define KW_MOD_1024 0x3FF /* used for MOD 1024 */ + + + +/************************************************************************ + * SAP States + ************************************************************************/ + +#define KW_SAP_NOT_CFG 0 /*!< SAP Not Configured */ +#define KW_SAP_CFG 1 /*!< SAP Configured but not not bound */ +#define KW_SAP_BND 2 /*!< SAP Bound */ +#define KW_SAP_BINDING 3 /*!< SAP Bind initiated */ +#define KW_SAP_UBND 4 /*!< SAP Unbind */ + +#define KW_MAX_SAP_BND_RETRY 3 /*!< Maximum SAP Bin Retries */ + +#define KW_MAX_UE 0xffffffff /*!< Maximum number of UEs. */ + +/* Maximum number of Saps */ +#define KW_MAX_UDXSAPS 1 /*!< Maximum number of UDX Saps */ +#define KW_MAX_KWUSAPS 2 /*!< Maximum number of KWU Saps. */ +#define KW_MAX_CKWSAPS 1 /*!< Maximum number of CKW Saps. */ +/*MCELL changes*/ +#define KW_MAX_RGUSAPS 4//5 /*!< Maximum number of RGU Saps. */ + +#define KW_MAX_RGUSAP_TMR 1 /*!< Maximum number of RGU SAP Timers. */ + +#define KW_UI_RRC 0 /*!< Upper interface RRC sap Id. */ +#define KW_UI_PDCP 1 /*!< Upper interface PDCP sap Id. */ + +#ifdef LTE_L2_MEAS +/* TODO. This works for FDD only. For TDD the array dimension + * should be changed according to the number of Harq Procs */ +#define KW_MAX_TB_PER_UE 64 /*!< Maximum number of tbCb for UE */ +#define KW_INVALID_TBID KW_MAX_TB_PER_UE +#endif +/******************************************************************************* + * Memory related Defines + ******************************************************************************/ +#ifdef MCCABE_COV +/* Allocate function */ +#define KW_ALLOC(_cb,_buf, _size) \ +{ \ + SGetSBuf(_cb->init.region, _cb->init.pool, (Data **)&_buf, \ + (Size) _size); \ + cmMemset((U8 *)(_buf), 0, _size); \ +} + +#define KW_RMV_SDU(_cb,_sduQ,_sdu) \ +{ \ + SPutMsg(_sdu->mBuf); \ + cmLListDelFrm(_sduQ,&_sdu->lstEnt); \ + KW_FREE_WC(_cb,_sdu, sizeof(KwSdu)); \ +} + +#define KW_FREE(_cb,_buf, _size) \ +{ \ + (Void) SPutSBuf(_cb->init.region, _cb->init.pool, \ + (Data *) _buf, (Size) _size); \ + _buf = NULLP; \ +} + +#define KW_FREE_BUF(_buf) \ +{ \ + SPutMsg(_buf); \ + _buf = NULLP; \ +} + +#else + +#define KW_FREE_SHRABL_BUF(_region, _pool,_buf, _size) \ +{ \ + if (_buf != NULLP) \ + { \ + (Void) SPutStaticBuffer(_region, _pool, \ + (Data *) _buf, (Size) _size, 0); \ + _buf = NULLP; \ + } \ +} + +#define KW_FREE_SHRABL_BUF_WC(_region, _pool,_buf, _size) \ +{ \ + (Void) SPutStaticBuffer(_region, _pool, \ + (Data *) _buf, (Size) _size, 0); \ + _buf = NULLP; \ +} + +#define KW_ALLOC_SHRABL_BUF_WC(_region, _pool,_buf, _size) \ +{ \ + SGetStaticBuffer(_region, _pool, (Data **)&_buf, \ + (Size) _size, 0); \ +} + +#define KW_ALLOC_SHRABL_BUF(_region, _pool,_buf, _size) \ +{ \ + if (SGetStaticBuffer(_region, _pool, (Data **)&_buf, \ + (Size) _size, 0) == ROK) \ + { \ + cmMemset((U8 *)(_buf), 0, _size); \ + } \ + else \ + { \ + (_buf) = NULLP; \ + } \ +} +/* Allocate function */ +#define KW_ALLOC(_cb,_buf, _size) \ +{ \ + if (SGetSBuf(_cb->init.region, _cb->init.pool, (Data **)&_buf, \ + (Size) _size) == ROK) \ + { \ + cmMemset((U8 *)(_buf), 0, _size); \ + } \ + else \ + { \ + (_buf) = NULLP; \ + } \ +} + +#define KW_ALLOC_WC(_cb,_buf, _size) \ + SGetSBuf(_cb->init.region, _cb->init.pool, (Data **)&_buf, (Size) _size) + +#define KW_RMV_SDU(_cb,_sduQ,_sdu) \ +{ \ + if(_sdu->mBuf) \ + { \ + SPutMsg(_sdu->mBuf); \ + } \ + cmLListDelFrm(_sduQ,&_sdu->lstEnt); \ + KW_FREE(_cb,_sdu, sizeof(KwSdu)); \ +} + +#define KW_FREE(_cb,_buf, _size) \ +{ \ + if (_buf != NULLP) \ + { \ + (Void) SPutSBuf(_cb->init.region, _cb->init.pool, \ + (Data *) _buf, (Size) _size); \ + _buf = NULLP; \ + } \ +} + +#define KW_FREE_BUF(_buf) \ +{ \ + if (_buf != NULLP) \ + { \ + SPutMsg(_buf); \ + } \ + _buf = NULLP; \ +} +#endif + + + + +#define KW_FREE_WC(_cb,_buf, _size) \ +{ \ + (Void) SPutSBuf(_cb->init.region, _cb->init.pool, \ + (Data *) _buf, (Size) _size); \ + _buf = NULLP; /*assigning NULLP after free*/ \ +} + +/* kw002.201 Freeing from region of pst */ +#define KW_PST_FREE(_region, _pool, _buf, _size) \ +{ \ + if (_buf != NULLP) \ + { \ + (Void) SPutSBuf(_region, _pool, \ + (Data *) _buf, (Size) _size); \ + _buf = NULLP; \ + } \ +} + +#ifdef XEON_SPECIFIC_CHANGES +#ifdef SS_LOCKLESS_MEMORY +#define KW_SHRABL_STATIC_BUF_FREE(_region, _pool, _buf, _size) \ +{ \ + if (_buf != NULLP) \ + { \ + (Void) SPutStaticBuffer(_region, _pool, \ + (Data *) _buf, (Size) _size, 0); \ + _buf = NULLP; \ + } \ +} + +#define KW_SHRABL_STATIC_BUF_ALLOC(_region, _pool, _buf, _size) \ +{ \ + SGetStaticBuffer(_region, _pool, (Data **)&_buf, \ + (Size) _size, 0); \ +} + +#else + +#define KW_SHRABL_STATIC_BUF_FREE(_region, _pool, _buf, _size) \ +{ \ + if (_buf != NULLP) \ + { \ + (Void) SPutSBuf(_region, _pool, \ + (Data *) _buf, (Size) _size); \ + _buf = NULLP; \ + } \ +} + +#define KW_SHRABL_STATIC_BUF_ALLOC(_region, _pool, _buf, _size) \ +{ \ + SGetSBuf(_region, _pool, (Data **)&_buf, \ + (Size) _size); \ +} +#endif /* SS_LOCKLESS_MEMORY */ + +#else + +#define KW_SHRABL_STATIC_BUF_FREE(_region, _pool, _buf, _size) \ +{ \ + if (_buf != NULLP) \ + { \ + (Void) SPutStaticBuffer(_region, _pool, \ + (Data *) _buf, (Size) _size, 0); \ + _buf = NULLP; \ + } \ +} + +#define KW_SHRABL_STATIC_BUF_ALLOC(_region, _pool, _buf, _size) \ +{ \ + SGetStaticBuffer(_region, _pool, (Data **)&_buf, \ + (Size) _size, 0); \ +} +#endif + +#define KW_FREE_BUF_WC(_buf) SPutMsg((_buf)); + +#define KW_MEM_CPY(_dst, _src, _size) cmMemcpy((U8*)_dst, (U8 *)_src, _size); + +#define KW_MEM_ZERO(_buf, _size) cmMemset((U8 *)(_buf), 0, _size); + +#define KW_GET_MEM_REGION(_cb) (_cb->init.region) + +#define KW_GET_MEM_POOL(_cb) (_cb->init.pool) + +#define KW_GET_MEM_POOL_ADDRESS(_cb) (&_cb->init.pool) + +/* Memset to value */ +#define KW_MEM_SET(_arg, _val, _size) cmMemset((U8 *)_arg, (U8)_val, _size); + +/* Alarms */ +/* Send an alarm for sapId events */ +/* kw005.201 added support for L2 Measurement */ +#ifdef LTE_L2_MEAS +#define KW_GETSDUIDX(_sduIdx) \ +{\ + _sduIdx = (((_sduIdx)+1) % KW_L2MEAS_MAX_OUTSTNGSDU);\ +} +#define KW_SEND_SAPID_ALARM(_cb,_sapId, _evnt, _cause) \ +{ \ + kwLmmSendAlarm(_cb,LCM_CATEGORY_INTERFACE, _evnt, _cause, _sapId, 0, 0); \ +} +#define KW_SEND_UEID_ALARM(_cb,_ueId, _qci, _evnt, _cause) \ +{ \ + kwLmmSendAlarm(_cb,LCM_CATEGORY_INTERFACE, _evnt, _cause, 0, _ueId, _qci); \ +} +#else /* LTE_L2_MEAS */ +#define KW_SEND_SAPID_ALARM(_cb,_sapId, _evnt, _cause) \ +{ \ + kwLmmSendAlarm(_cb,LCM_CATEGORY_INTERFACE, _evnt, _cause, _sapId, 0); \ +} +#define KW_SEND_UEID_ALARM(_cb,_ueId, _evnt, _cause) \ +{ \ + kwLmmSendAlarm(_cb,LCM_CATEGORY_INTERFACE, _evnt, _cause, 0, _ueId); \ +} +#endif /* LTE_L2_MEAS */ + +/******************************************************************************* + * Common Defines + ******************************************************************************/ + +/* RLC Configuration parameters */ +#define KW_MAX_UL_LI (2 * KW_MAX_LI) +/*macro KW_MAX_DL_LI is moved to kw_env.h file */ +#define KW_MAX_DAT KW_MAXIMUM_DAT +/*macro KW_MAX_PDU is moved to kw_env.h file */ +#define KW_MAX_RB_PER_CELL 10 +#define KW_MAX_SRB_PER_UE 3 +#define KW_MAX_DRB_PER_UE 32 +#define KW_MAX_LCH_PER_UE 12 +#define KW_MAX_LCH_PER_CELL 6 +#define KW_MAX_NUM_RB 24 +#define KW_MAX_UE 0xffffffff +#define KW_UE_LIST_BUCKET_SIZE 128 +#define KW_CELL_LIST_BUCKET_SIZE 10 +#define KW_TRANS_ID_LST_BKT_SIZE 10 +#define KW_MAX_RB 32 + +/* Direction defines */ +#define KW_DIR_UL 1 /*!< Unlink direction */ +#define KW_DIR_DL 2 /*!< Downlink direction */ +#define KW_DIR_BOTH 3 /*!< Both Downlink and Unlink */ + +#define KW_DEF_SEQ_NUM 0 /**< Sequence number to pick in case of duplicate + entries in hash list searches*/ + +/** + * @def KW_MIN + * + * Macro to find the miniumum of two numbers + * + * @param[in] x First number + * @param[in] y Second number + * +*/ +#define KW_MIN(x,y) (x) < (y) ? (x) : (y) + +/** + * @def KW_GET_KWCB + * + * Macro to the RLC instance + * + * @param[in] _inst Instance Id + * +*/ +#define KW_GET_KWCB(_inst) kwCb[_inst] + +#define KW_ADD_SDU 1 /*!< Add SDU. */ +#define KW_DEL_SDU 2 /*!< Delete SDU. */ + +#define KW_CFM_NOK 0 /*!< Do not send DatCfm */ +#define KW_CFM_OK 1 /*!< Send DatCfm */ + +/* Set the unsolictated Status flag */ +#define KW_SET_USTA_FLAG(_kwCb, _value) \ +{ \ + _kwCb->init.usta = _value; \ +} + +/* Macros to get the init parameters */ +#define KW_GET_DBG_MASK(_kwCb) (_kwCb->init.dbgMask) +#define KW_GET_LMPST_MEM_POOL(_kwCb) (_kwCb->init.lmPst.pool) +#define KW_GET_LMPST_MEM_REGION(_kwCb) (_kwCb->init.lmPst.region) + +/* Macros for configuration module */ +#define KW_CFG_FILL_CFG_CFM(_entCfm, _rbId, _rbType, _status, _reason) \ +{ \ + _entCfm->rbId = _rbId; \ + _entCfm->rbType = _rbType; \ + _entCfm->status.status = _status; \ + _entCfm->status.reason = _reason; \ +} + +/** + * @def KW_VALIDATE_UE_RBID + * + * This macro validates whether the _rbId passed is valid or not. It checks + * if the _rbId is within the maximum value depending on the _rbType. + * Returns TRUE if valid else FALSE + * + * @param[in] _rbType Type of the Radio Bearer; SRB or DRB + * @param[in] _rbId RB Id of the RB to be validated + * +*/ +#define KW_VALIDATE_UE_RBID(_rbType, _rbId) \ + ((_rbType == CM_LTE_SRB && _rbId < KW_MAX_SRB_PER_UE) || \ + (_rbType == CM_LTE_DRB && _rbId < KW_MAX_DRB_PER_UE)) + +/******************************************************************************* + * UIM Defines + ******************************************************************************/ +#if (ERRCLASS & ERRCLS_INT_PAR) +#define KW_VALDATE_SAP(_cb,_chkSpId, _sap, _ret) \ +{ \ + if (_chkSpId != _sap->spId) \ + { \ + KWLOGERROR(_cb,ERRCLS_DEBUG, EKWxxx, (ErrVal) RFAILED, \ + "Sap Id Validation Failed."); \ + _ret = RFAILED; \ + } \ + /* SAP state validation */ \ + if(_sap->state != KW_SAP_BND) \ + { \ + KWLOGERROR(_cb,ERRCLS_INT_PAR, EKWXXX, (ErrVal) RFAILED, \ + "Sap State Invalid."); \ + KW_SEND_SAPID_ALARM(_cb,0, LCM_EVENT_UI_INV_EVT, LCM_CAUSE_INV_STATE); \ + _ret = RFAILED; \ + } \ +} +#else /* ERRCLASS & ERRCLS_INT_PAR */ +#define KW_VALDATE_SAP(_cb,_chkSpId, _sap, _ret) \ +{ \ + /* SAP state validation */ \ + if(_sap->state != KW_SAP_BND) \ + { \ + KWLOGERROR(_cb,ERRCLS_INT_PAR, EKWXXX, (ErrVal) RFAILED, \ + "Sap State Invalid."); \ + KW_SEND_SAPID_ALARM(_cb,0, LCM_EVENT_UI_INV_EVT, LCM_CAUSE_INV_STATE); \ + _ret = RFAILED; \ + } \ +} +#endif /* ERRCLASS & ERRCLS_INT_PAR */ + +/******************************************************************************* + * Timer Defines + ******************************************************************************/ +#define KW_TMR_LEN 10 +#define KW_MAX_UM_TMR 1 +#define KW_MAX_AM_TMR 3 +#define KW_EVT_UMUL_REORD_TMR 1 +#define KW_EVT_AMUL_REORD_TMR 2 +#define KW_EVT_AMUL_STA_PROH_TMR 3 +#define KW_EVT_AMDL_POLL_RETX_TMR 4 +#define KW_EVT_WAIT_BNDCFM 5 +/* kw005.201 added support for L2 Measurement */ +#ifdef LTE_L2_MEAS +#define KW_EVT_L2_TMR 6 +#endif /* LTE_L2_MEAS */ + +/******************************************************************************* + * DBM Defines + ******************************************************************************/ +/** + * @def KW_DBM_GET_RBCB_FROM_UECB + * + * This macro makes _rbCb point to the RB in _ueCb based on the passed + * _rbId and _rbType. _rbCb can point to NULLP + * + * @param[in] _rbId RB Id of the RB to be fetched + * @param[in] _rbType Type of the RB, SRB or DRB + * @param[in] _ueCb Pointer to the UECb for which to get the RB + * @param[out] _rbCb Pointer to the found RbCb + * +*/ +#define KW_DBM_GET_RBCB_FROM_UECB(_rbId, _rbType, _ueCb, _rbCb) \ + (_rbCb) = ((_rbType) == CM_LTE_SRB) ? (_ueCb)->srbCb[(_rbId)] : \ + (_ueCb)->drbCb[(_rbId)]; +/** + * @def KW_DBM_GET_CELL_RBCB + * + * This macro makes _rbCb point to the RB in the _rbCbLst. + * _rbCb can point to NULLP + * + * @param[in] _rbId RB Id of the RB to be fetched + * @param[in] _rbCbLst Pointer to array of RBCbs + * @param[out] _rbCb Pointer to the found RbCb + * +*/ +#define KW_DBM_GET_CELL_RBCB(_rbId, _rbCbLst, _rbCb) \ + (_rbCb) = (_rbCbLst)[(_rbId)]; + +/******************************************************************************* + * UMM Defines + ******************************************************************************/ +#define KW_UMDL rbCb->m.umDl +#define KW_UMUL rbCb->m.umUl + +/* Sequence Number length defines */ +#define KW_UM_CFG_5BIT_SN_LEN 1 /**< UM 5-bit Sequence number length + in bytes*/ +#define KW_UM_CFG_10BIT_SN_LEN 2 /**< UM 10-bit Sequence number length + in bytes*/ +/* 5GNR */ +/* Sequence Number length defines */ +#define KW_AM_CFG_12BIT_SN_LEN 1 /**< AM 12-bit Sequence number length + in bytes*/ +#define KW_AM_CFG_18BIT_SN_LEN 2 /**< AM 18-bit Sequence number length + in bytes*/ + +/** + * @def KW_RMV_MAC_HDR_SZ + * + * If PDU size is greater than 127, MAC header would be 3 bytes else 2 bytes + * + * @param[in,out] _pduSz Size of the pdu + * +*/ +#define KW_RMV_MAC_HDR_SZ(_pduSz) (_pduSz) -= ((_pduSz) > 127) ? 3 : 2; + +/** + * @def KW_UM_GET_VALUE + * + * This macro is used to calculate the value of UM state variables used + * in comparisons. VR(UH) - UM Window Size is taken as the base modulus. + * Returns the modifed value + * + * @param[in] _val Value of the state variable + * @param[in] _kwUmUl Um Uplink control block + * +*/ +#define KW_UM_GET_VALUE(_val,_kwUmUl) \ + (((_val) - ((_kwUmUl).vrUh - (_kwUmUl).umWinSz)) & ((_kwUmUl).modBitMask)) + +/******************************************************************************* + * AMM Defines + ******************************************************************************/ +#define AMDL rbCb->m.amDl +#define AMUL rbCb->m.amUl + +/* PDU Types */ +#define KW_DATA_PDU 1 +#define KW_CNTRL_PDU 0 + +#define KW_FI_FIRST_SEG 0x02 +#define KW_FI_LAST_SEG 0x01 +#define KW_SI_FIRST_SEG 0x01 +#define KW_SI_LAST_SEG 0x02 +#define KW_SI_MID_SEG 0x03 + +#define KW_POLL_SET 0x40 /* 01000000 */ +#define KW_POLL_UNSET 0xbf /* 10111111 */ +#define KW_AM_WIN_SZ 512 +#define KW_MAX_NACK_CNT 100 +/*KW_MAX_CNTRL_FIELDS (Maximum size of Status Pdu) + * = MAX_NACK_CNT * sizeof(NACK_SN,E1,E2,E3,soStart,soEnd, nackRange) + * for 18 bit SN + Fixed Header*/ +#define KW_MAX_CNTRL_FIELDS ((KW_MAX_NACK_CNT * 8) + 3) + +/* Each LI(Length Indicator) holds approx 1+1/2 byte and some other fields thus keeping Header Size equal to twice of MAX LI */ +/* 5GNR_RLC: Need to change value of HDRSZ as per number of PDUs going in one datReq */ +#define KW_MAX_HDRSZ 5 +#define KW_AM_PDU_FIXED_HDRSZ 2 +#define KW_AM_PDU_12BIT_SN_HDRSZ 2 +#define KW_AM_PDU_18BIT_SN_HDRSZ 3 +#define KW_AM_SEG_12BIT_SN_WITH_SO_HDRSZ 4 +#define KW_AM_SEG_18BIT_SN_WITH_SO_HDRSZ 5 +#define KW_AM_SEG_12BIT_SN_WITHOUT_SO_HDRSZ 2 +#define KW_AM_SEG_18BIT_SN_WITHOUT_SO_HDRSZ 3 +#define KW_EXTN_HDRSZ 2 +#define KW_CNTRL_PDU_FIXED_HDRSZ 3 +#define KW_MAC_HDR_SZ2 2 +#define KW_MAC_HDR_SZ3 3 +#define KW_BYTE_LEN 8 +#define KW_2BYTE_LEN 16 +#define KW_E1_LEN 1 +#define KW_NACK_E1E2_LEN 12 +#define KW_SO_LEN 15 +#define KW_DC_LEN 1 +#define KW_CPT_LEN 3 +#define KW_RF_LEN 1 +#define KW_P_LEN 1 +#define KW_FI_LEN 2 +#define KW_SI_LEN 2 +#define KW_E_LEN 1 +#define KW_SN_LEN 10 +#define KW_SN_LEN_12BITS 12 +#define KW_SN_LEN_18BITS 18 +#define KW_LSF_LEN 1 +#define KW_LI_LEN 11 +#define KW_STA_PDU_R_BITS_ACKSN_12BITS 7 /* 5GNR : Num Reserved bits in STATUS PDU */ +#define KW_STA_PDU_R_BITS_ACKSN_18BITS 1 +#define KW_STA_PDU_R_BITS_NACKSN_12BITS 1 +#define KW_STA_PDU_R_BITS_NACKSN_18BITS 3 +#define KW_NACK_RANGE_LEN 8 +#define KW_SO_LEN_5GNR 16 + +#define KW_DC_POS 0x80 +#define KW_DC_SHT 7 +#define KW_POLL_POS 0x40 /* 5GNR */ +#define KW_POLL_SHT 6 /* 5GNR */ +#define KW_SI_POS 0x30 /* 5GNR */ +#define KW_SI_SHT 4 /* 5GNR */ +#define KW_SN_POS_12BIT 0x0F +#define KW_SN_POS_18BIT 0x03 +#define KW_AM_GET_WIN_SZ(_snLen) ((KW_AM_CFG_12BIT_SN_LEN == (_snLen)) ? (2048) : (131072)) /* 5GNR */ +#define KW_RCV_BUF_BIN_SIZE 512 /* Could be increased to avoid the search time. + with the memory trade-off */ +#define KW_TX_BUF_BIN_SIZE 512 /* Could be increased to avoid the search time. + with the memory trade-off */ + +#define KW_SDU_LST 1 +#define KW_SEG_LST 2 +#define KW_RETX_LST 3 +#define KW_ALL_BYTES_MISSING 0xffff + +#define KW_MAX_PDU_MAP 30 /*!< Maximum PDU Map. */ + +#define KW_LLIST_FIRST_SDU(lstCp, nod) \ +{ \ + CmLList *tmpNode; \ + /*CM_LLIST_FIRST_NODE(&(lstCp), tmpNode);*/ \ + /*if (tmpNode != NULLP)*/ \ + if((tmpNode=cmLListFirst(&lstCp))) \ + nod = (KwSdu *)tmpNode->node; \ + else \ + nod = NULLP; \ +} + + +#define KW_LLIST_FIRST_SEG(lstCp, nod) \ +{ \ + CmLList *tmpNode; \ + /*CM_LLIST_FIRST_NODE(&(lstCp), tmpNode);*/ \ + /*if (tmpNode != NULLP)*/ \ + if((tmpNode=cmLListFirst(&lstCp))) \ + nod = (KwSeg *)tmpNode->node; \ + else \ + nod = NULLP; \ +} + + +#define KW_LLIST_FIRST_RETX(lstCp, nod) \ +{ \ + CmLList *tmpNode; \ + /*CM_LLIST_FIRST_NODE(&(lstCp), tmpNode);*/ \ + /*if (tmpNode != NULLP)*/ \ + if((tmpNode=cmLListFirst(&lstCp))) \ + nod = (KwRetx *)tmpNode->node; \ + else \ + nod = NULLP; \ +} + +#define KW_LLIST_NEXT_SDU(lstCp, nod) \ +{ \ + CmLList *tmpNode; \ + /*CM_LLIST_NEXT_NODE(&(lstCp), tmpNode);*/ \ + /*if (tmpNode != NULLP) */ \ + if((tmpNode = cmLListNext(&lstCp))) \ + nod = (KwSdu *)tmpNode->node; \ + else \ + nod = NULLP; \ +} + + +#define KW_LLIST_NEXT_SEG(lstCp, nod) \ +{ \ + CmLList *tmpNode; \ + (lstCp).crnt = &((nod)->lstEnt); \ + /*CM_LLIST_NEXT_NODE(&(lstCp), tmpNode);*/ \ + /*if (tmpNode != NULLP)*/ \ + if((tmpNode = cmLListNext(&lstCp))) \ + nod = (KwSeg *)tmpNode->node; \ + else \ + nod = NULLP; \ +} + + +#define KW_LLIST_NEXT_RETX(lstCp, nod) \ +{ \ + CmLList *tmpNode; \ + /*CM_LLIST_NEXT_NODE(&(lstCp), tmpNode);*/ \ + /*if (tmpNode != NULLP) */ \ + if ((tmpNode = cmLListNext(&lstCp))) \ + nod = (KwRetx *)tmpNode->node; \ + else \ + nod = NULLP; \ +} + + +#define KW_LLIST_LAST_RETX(lstCp, nod) \ +{ \ + CmLList *tempNode = NULLP; \ + cmLListLast(&lstCp); \ + tempNode = cmLListCrnt(&lstCp); \ + if (tempNode != NULLP) \ + nod = (KwRetx *)tempNode->node; \ + else \ + nod = NULLP; \ +} + +#define KW_LLIST_LAST_SEG(lstCp, nod) \ +{ \ + CmLList *tempNode = NULLP; \ + cmLListLast(&lstCp); \ + tempNode = cmLListCrnt(&lstCp); \ + if (tempNode != NULLP) \ + nod = (KwSeg *)tempNode->node; \ + else \ + nod = NULLP; \ +} + +#define KW_LLIST_LAST_SDU(lstCp, nod) \ +{ \ + CmLList *tempNode = NULLP; \ + cmLListLast(&lstCp); \ + tempNode = cmLListCrnt(&lstCp); \ + if (tempNode != NULLP) \ + nod = (KwSdu *)tempNode->node; \ + else \ + nod = NULLP; \ +} + +#define CM_LLIST_INS_AFT_CRNT(lstCp, nod) \ +{ \ + CmLList *nodeToIns = &nod->lstEnt;\ + nodeToIns->node = (PTR) nod;\ + cmLListInsAfterCrnt(&lstCp, nodeToIns); \ +} + +#define CM_LLIST_INS_BEF_CRNT(lstCp, nod) \ +{ \ + CmLList *nodeToIns = &nod->lstEnt; \ + nodeToIns->node = (PTR) nod; \ + cmLListInsCrnt(&lstCp, nodeToIns); \ +} + +#define KW_LLIST_DEL_RECBUF(_recBuf) \ +{ \ + KwSeg *_seg = NULLP; \ + KW_LLIST_FIRST_SEG(_recBuf->segLst, _seg); \ + while (_seg) \ + { \ + cmLListDelFrm(&_recBuf->segLst, &_seg->lstEnt); \ + KW_FREE(_seg, sizeof(KwSeg)); \ + KW_LLIST_NEXT_SEG(_recBuf->segLst, _seg); \ + } \ +} + +#define MODAMT(x, y, z,_snModMask) \ +{ \ + y = (x - z) & _snModMask; \ +} + +#define MODAMR(x, y, z , _snModMask) \ +{ \ + y = (x - z) & (_snModMask); \ +} + +/** + * @def KW_AM_IS_TRANS_WIN_STALLED + * + * This macro is used to check if the AM transmit window is stalled or not. + * The tramist window is stalled when the distance between txNext and txNextAck + * is greater than equal to Window Size. Actually it should never be greater + * than Window Size. + * Returns TRUE if the window is stalled else FALSE + * + * @param[in] _amDl AM Downlink control block + * +*/ +#define KW_AM_IS_TRANS_WIN_STALLED(_amDl) \ + ((((_amDl)->txNext - (_amDl)->txNextAck) & _amDl->snModMask) >= (KW_AM_GET_WIN_SZ(_amDl->snLen))) + +#ifdef TENB_STATS +#define KW_AM_TRANS_WIN_SIZE(_amDl) \ + (((_amDl)->txNext - (_amDl)->txNextAck) & _amDl->snModMask) +#endif + +#define KW_AM_IS_POLL_BIT_SET(_amDl) \ + (AMDL.pollSn == ((AMDL.txNext - 1) & AMDL.snModMask)) + +#define KW_FILL_CNTRL_INFO(cntrlInfo, _val, _len, _idx, _eb)\ +{ \ + cntrlInfo.val = _val; \ + cntrlInfo.len = _len; \ + cntrlInfo.idx = _idx; \ + cntrlInfo.emtBits = _eb; \ +} +#define KW_FILL_PREV_IDX(cntrlInfo, _e1Idx, _e1eb, _idx, _eb) \ +{ \ + _e1Idx = cntrlInfo.e1Idx; \ + _e1eb = cntrlInfo.e1eb; \ + _idx = cntrlInfo.idx; \ + _eb = cntrlInfo.emtBits; \ +} + +#define KW_FILL_HDR_ARGS(hdrInfo, _val, _len) \ +{ \ + hdrInfo.val = _val; \ + hdrInfo.len = _len; \ +} + +/* kw003.201 - This macro provides the header size other than the */ +/* fixed header of 2 bytes for each AMD PDU or 4 bytes*/ +/* for an AM PDU segment */ +#define KW_AM_EXTN_HDRSZ(_numLi, _eHdrSz) \ +{ \ + if ((_numLi - 1) % 2) \ + { \ + _eHdrSz = ((3 * (_numLi - 2)) >> 1) + 2; \ + } \ + else \ + { \ + _eHdrSz = (3 * (_numLi - 1)) >> 1; \ + } \ +} + +/* Update poll bit in the buffer */ +#define KW_UPD_POLL_BIT(_gCb, _retx, _poll) \ +{ \ + U8 fHdr; \ + \ + if (_poll != _retx->amHdr.p) \ + { \ + /* Get the first byte of the buffer */ \ + SRemPreMsg((Data *)&fHdr, _retx->seg); \ + if (_poll == TRUE) \ + { \ + fHdr = fHdr | KW_POLL_SET; \ + } \ + else \ + { \ + fHdr = fHdr & KW_POLL_UNSET; \ + } \ + /* Concatenated updated hdr to the mBuf */ \ + SAddPreMsg ((Data)fHdr, _retx->seg); \ + } \ + /* Update poll bit in the hdrInfo */ \ + _retx->amHdr.p = _poll; \ +} + +#define KW_AM_ELIMINATE_EXTN_HDR(_pduSz, _sduSz, _numLi) \ +{ \ + if ( (_pduSz > _sduSz) && (_sduSz < 2048) ) \ + { \ + _pduSz -= (_numLi % 2) ? 1 : 2; \ + } \ +} +/** + * @def KW_AM_CHK_SN_WITHIN_RECV_WINDOW + * + * This macro is used to check if a Sequence Number falls within the AM + * reception window or not. + * The condition is VR(R) <= SN < VR(MR), which are subtracting the base + * modulus becomes 0 <= (SN - VR(R)) % SNLen < (VR(MR) - VR(R)) % SnLen + * NOTE: Careful with the parantheses + * + * Returns TRUE if within the window; FALSE otherwise + * + * @param[in] _sn The sequence number to be checked + * @param[in] _amUl AM Uplink control block + * +*/ +#define KW_AM_CHK_SN_WITHIN_RECV_WINDOW(_sn, _amUl) \ + ((((_sn) - (_amUl->rxNext)) & (_amUl->snModMask)) < (((_amUl->vrMr) - (_amUl->rxNext)) & (_amUl->snModMask))) + +#define KW_POWER(x, y) x << (y-1); + +#ifndef L2_OPTMZ +#define kwCpyMsg(_cb,x, y) \ + (SAddMsgRef((x), KW_GET_MEM_REGION(_cb), KW_GET_MEM_POOL(_cb), (y))) +#else +/* L2 optimization for mUe/Tti: Removing dup buf*/ +#define kwCpyMsg(_cb,x, y) \ + (SIncMsgRef((x), KW_GET_MEM_REGION(_cb), KW_GET_MEM_POOL(_cb), (y))) +#endif + +// printf("Copy Msg %x \n",x); + +/******************************************************************************* + * Debugging Defines + ******************************************************************************/ +#define KW_DBG_SUB_MASK DBGMASK_MI /**< Use for sub-mask */ +#define KW_DBGMASK_DETAIL (KW_DBG_SUB_MASK << 0) /**< Parameters, It will give + in depth info */ +#define KW_DBGMASK_BRIEF (KW_DBG_SUB_MASK << 1) /**< Info, It will give info at + entry and exit places along + with certain state changes */ +#define KW_DBGMASK_ERROR (KW_DBG_SUB_MASK << 2) /**< Error information */ +#define KW_DBGMASK_FATAL (KW_DBG_SUB_MASK << 3) /**< FATAL errors like memory + resource failure etc., */ + +#define KW_DBG_MDL_MASK (KW_DBG_SUB_MASK << 4) + +#define KW_DBGMASK_TM (KW_DBG_MDL_MASK << 0) /**< TM */ +#define KW_DBGMASK_UM (KW_DBG_MDL_MASK << 1) /**< UM */ +#define KW_DBGMASK_AM (KW_DBG_MDL_MASK << 2) /**< AM */ +#define KW_DBGMASK_DL (KW_DBG_MDL_MASK << 3) /**< DL */ +#define KW_DBGMASK_UL (KW_DBG_MDL_MASK << 4) /**< UL */ +#define KW_DBGMASK_CFG (KW_DBG_MDL_MASK << 5) /**< CFG */ +#define KW_DBGMASK_LMM (KW_DBG_MDL_MASK << 6) /**< LMM */ +#define KW_DBGMASK_INF (KW_DBG_MDL_MASK << 7) /**< UI, LI */ +#define KW_DBGMASK_DUT (KW_DBG_MDL_MASK << 8) /**< DBM, UTL, TMR */ +#define KW_DBGMASK_MBUF_PRNT (KW_DBG_MDL_MASK << 9) /**< MBUF, useful in + integrated + testing */ +#define KW_DBGMASK_MEM_INFO (KW_DBG_MDL_MASK << 10) /**< Print SSI memory + information*/ +#define KW_DBGMASK_UDX (KW_DBG_MDL_MASK << 11) /**< UDX interface */ + +#ifdef DEBUGP +#define KW_PRNT_BORDER \ +do \ +{ \ + KW_PRNT((_kwPBuf, "\n==========================\n")); \ +}while(0) + +#define KW_PRNT_HLINE(_cb,_pMsg) \ +{ \ + sprintf((_cb)->init.prntBuf, "[RLC_LAYER: %s:%d]::", __FILE__, __LINE__); \ + SPrint((_cb)->init.prntBuf); \ + KW_PRNT_TSTAMP(_cb); \ + sprintf((_cb)->init.prntBuf, _pMsg); \ + SPrint((_cb)->init.prntBuf); \ +} + +#define KW_PRNT(_cb,_prntbuf) \ +{ \ + sprintf _prntbuf; \ + SPrint(_cb->init.prntBuf); \ +} + +#define KW_PRINT_TO_BUFFER(_cb,...) \ +{ \ + snprintf((_cb)->init.prntBuf, PRNTSZE, "[%s]::", __func__); \ + SPrint((_cb)->init.prntBuf); \ + snprintf(_cb->init.prntBuf, PRNTSZE,__VA_ARGS__); \ + SPrint(_cb->init.prntBuf); \ +} + +#define KW_PRNT_TSTAMP(_cb) \ +{ \ + S8 _buf[60]; \ + DateTime dt; \ + cmMemset((U8 *)(&dt), 0, sizeof(DateTime)); \ + SGetDateTime(&dt); \ + sprintf(_buf, "date: %02d/%02d/%04d time: %02d:%02d:%02d", \ + (int)dt.month,(int)dt.day,(int)dt.year + 1900, \ + (int)dt.hour,(int)dt.min,(int)dt.sec); \ + KW_PRNT(_cb,(_cb->init.prntBuf,("[%s]", _buf))); \ +} + +#define KW_PRNT_MBUF(_cb,_mBufPtr) \ +do \ +{ \ + if(_cb->init.dbgMask & (KW_DBGMASK_MBUF_PRNT)) \ + { \ + KW_PRNT_HLINE(_cb,("\nMessage Buffer Contents:\n")); \ + SPrntMsg ((Buffer *)_mBufPtr, 0, 0); \ + } \ +}while(0) + +#define KW_PRNT_MEMINFO(_cb) \ +do \ +{ \ + U32 _memInfo; \ + if(_cb->init.dbgMask & (KW_DBGMASK_MEM_INFO)) \ + { \ + KW_PRNT_HLINE(_cb,("\nMemory Information:\n")); \ + SRegInfoShow(0, &_memInfo); \ + } \ +}while(0) + +#define KWDBGP_INTERNAL(_cb,_mask,...) \ +do \ +{ \ + if (!((_cb->init.dbgMask & _mask) ^ _mask)) \ + { \ + KW_PRINT_TO_BUFFER(_cb, __VA_ARGS__); \ + } \ +}while(0) + +#define KWDBGP_ERROR(_cb, ...) \ + KWDBGP_INTERNAL(_cb,(KW_DBGMASK_ERROR | KW_MODULE),__VA_ARGS__) + +#define KWDBGP_DETAIL(_cb, ...) \ + KWDBGP_INTERNAL(_cb,(KW_DBGMASK_DETAIL | KW_MODULE),__VA_ARGS__) + +#define KWDBGP_BRIEF(_cb, ...) \ + KWDBGP_INTERNAL(_cb,(KW_DBGMASK_BRIEF | KW_MODULE),__VA_ARGS__) + +#else /* DEBUGP */ +#define KW_PRNT_HLINE(_cb,_pMsg) +#define KW_PRNT(_cb,_prntbuf) +#define KW_PRNT_TSTAMP(_cb) +#define KW_PRNT_MBUF(_cb,_mBufPtr) +#define KW_PRNT_MEMINFO(_cb) +#define KWDBGP(_cb,_mask, _arg) +#define KWDBGP_ERROR(_cb, ...) +#define KWDBGP_DETAIL(_cb, ...) +#define KWDBGP_BRIEF(_cb, ...) +#endif /* DEBUGP */ + +/******************************************************************************* + * LMM Defines + ******************************************************************************/ +#define KW_LMM_RB_STS_INC(_cb) (_cb)->genSts.numOfRb++; + +#define KW_LMM_RB_STS_DEC(_cb) (_cb)->genSts.numOfRb--; + +#if defined(SS_MULTICORE_SUPPORT) && defined(SS_M_PROTO_REGION) +#define KW_FILL_SAP_HELPER(_Sap, _cfg, _gCb)\ +{\ + _Sap->pst.selector = _cfg->selector; \ + _Sap->pst.route = _cfg->route; \ + _Sap->pst.prior = _cfg->priority; \ + _Sap->pst.region = _gCb->init.region;\ + _Sap->pst.pool = _gCb->init.pool;\ + _Sap->pst.dstProcId = _cfg->procId; \ + _Sap->pst.dstEnt = _cfg->ent; \ + _Sap->pst.dstInst = _cfg->inst; \ + _Sap->pst.srcProcId = _gCb->init.procId; \ + _Sap->pst.srcEnt = _gCb->init.ent; \ + _Sap->pst.srcInst = _gCb->init.inst; \ + _Sap->pst.event = EVTNONE; \ + _Sap->spId = _cfg->sapId; \ + _Sap->state = KW_SAP_CFG; \ +} +#else /* defined(SS_MULTICORE_SUPPORT) && defined(SS_M_PROTO_REGION) */ +#define KW_FILL_SAP_HELPER(_Sap, _cfg, _gCb)\ +{\ + _Sap->pst.selector = _cfg->selector; \ + _Sap->pst.route = _cfg->route; \ + _Sap->pst.prior = _cfg->priority; \ + _Sap->pst.region = _cfg->mem.region;\ + _Sap->pst.pool = _cfg->mem.pool;\ + _Sap->pst.dstProcId = _cfg->procId;\ + _Sap->pst.dstEnt = _cfg->ent;\ + _Sap->pst.dstInst = _cfg->inst;\ + _Sap->pst.srcProcId = _gCb->init.procId;\ + _Sap->pst.srcEnt = _gCb->init.ent;\ + _Sap->pst.srcInst = _gCb->init.inst;\ + _Sap->pst.event = EVTNONE;\ + _Sap->spId = _cfg->sapId;\ + _Sap->state = KW_SAP_CFG;\ +} +#endif + +/******************************************************************************* + * UDX Defines + ******************************************************************************/ +#define KW_GET_DL_SAPCB(_cb, _rbCb) (_cb->u.dlCb->udxDlSap + _rbCb->udxSapId) +#define KW_GET_UDX_SAP(_cb) (_cb->u.ulCb->udxUlSap) + +/* kw005.201 added support for L2 Measurement */ +#ifdef LTE_L2_MEAS +#define KW_L2_MAX_TIMERS 1 +#define KW_QCI_LIST_BUCKET_SIZE 10 +#define KW_TB_LIST_BUCKET_SIZE 10 +#define KW_MAX_L2MEAS_EVT 10 +/* L2 Measurement index to be used in rbCb to store measData */ +#define KW_L2MEAS_ACT_UE 0 +#define KW_L2MEAS_DL_DELAY 1 +#define KW_L2MEAS_DL_DISC 2 +#define KW_L2MEAS_UU_LOSS 3 +#define KW_L2MEAS_DL_IP 4 +#define KW_L2MEAS_UL_IP 5 +#endif /* LTE_L2_MEAS */ + +#define KW_RDWR_LOCK(_lockPtr) +#define KW_RDWR_UNLOCK(_lockPtr) +#define KW_TIME_DIFF(t1,t2) \ + (t1yetToConst == FALSE) \ + {\ + Buffer *_pduInfo; \ + SSegMsg((_retx)->seg, (_retx)->hdrSz, &_pduInfo); \ + KW_FREE_BUF((_retx)->seg); \ + (_retx)->seg = _pduInfo; \ + }\ + (_rbCb)->m.amDl.estHdrSz -= retx->hdrSz;\ +} while(0) + +/* private function declarations */ + +PRIVATE Void kwResegRetxPdus ARGS ((KwCb *gCb, + KwDlRbCb *rbCb, + KwDatReq *kwDatReq)); + +PRIVATE Void kwRemRetxPdu ARGS ((KwCb *gCb, + KwDlRbCb *rbCb, + KwRetx *retx)); + +PRIVATE Void kwAmmCreateStatusPdu ARGS ((KwCb *gCb, + KwDlRbCb *rbCb, + KwDatReq *kwDatReq)); + +PRIVATE Void kwAmmDlMarkPduForReTx ARGS ((KwCb *gCb, + KwDlRbCb *rbCb, + KwRetx *retx)); + +PRIVATE Void kwAmmDlProcessSuccessfulTxPdu ARGS((KwCb *gCb, + KwDlRbCb *rbCb, + KwSn sn, + KwuDatCfmInfo **datCfm)); + +PRIVATE Void kwAmmDlSetTxNextAck ARGS((KwAmDl *amDl, KwSn sn)); + +PRIVATE Void kwAmmDlCheckAndStopPollTmr ARGS((KwCb *gCb, + KwDlRbCb *rbCb, + KwSn mAckSn)); + +PRIVATE Void kwAssembleSdus ARGS ((KwCb *gCb, + KwDlRbCb *rbCb, + KwDatReq *kwDatReq)); + +PRIVATE Bool kwAmmDlCheckAndSetPoll ARGS ((KwCb *gCb, + KwDlRbCb *rbCb, + Bool newPdu, + MsgLen bufSz)); + +PRIVATE Void kwAmmCreatePdu ARGS ((KwCb *gCb, + KwDlRbCb *rbCb, + KwAmHdr *amHdr, + KwDlPduInfo *pduInfo, + Buffer *pdu)); + +PRIVATE Void kwAmmSndStaInd ARGS ((KwCb *gCb,KwDlRbCb *rbCb, KwRetx *retx)); + +PRIVATE Void kwGetNxtRetx ARGS ((KwCb *gCb, KwRetx **retx)); + +PRIVATE Void kwConstructAmHdr ARGS ((KwAmHdr *amHdr, + U8 *hdr, + U8 snLen, + U16 *idx)); + +PRIVATE Void kwAmmDlUpdateTxAndReTxBufForAckSn ARGS ((KwCb *gCb, + KwDlRbCb *rbCb, + KwSn mAckSn, + CmLList *retx, + KwuDatCfmInfo **datCfm)); + +PRIVATE Void kwAmmDlMoveFrmTxtoRetxBuffer ARGS ((KwCb *gCb, + KwAmDl *amDl, + KwRetx **retx, + KwSn sn)); + +PRIVATE Void kwAmmDlCheckIsSDUDelivered ARGS((KwCb *gCb, + KwDlRbCb *rbCb, + KwSduMap *sduMap, + KwuDatCfmInfo **datCfm)); + +PRIVATE Void kwAmmAddPduToRetxLst ARGS((KwAmDl *amDl, + KwRetx *retx)); + +PRIVATE Void kwAmmDlMoveSduByteSegFrmTxtoRetxBuffer ARGS( +( +KwCb *gCb, +KwAmDl *amDl, +KwRetx **retx, +KwDlPduInfo *pduInfo +)); + +PRIVATE Void kwAmmDlHndlStatus4SduByteSegInTxBuf ARGS( +( +KwCb *gCb, +KwDlRbCb *rbCb, +KwNackInfo *nackSnInfo, +KwRetx **retx, +KwuDatCfmInfo **datCfm +)); + +PRIVATE Void kwAmmDlUpdateTxAndReTxBufForNackSn ARGS( +( + KwCb *gCb, + KwDlRbCb *rbCb, + KwNackInfo *nackSnInfo, + CmLList **retxNode, + KwuDatCfmInfo **datCfm + )); + +PRIVATE Void KwDlAmmGetNackSnInfoFrmNackRangeIdx ARGS( +( +KwAmDl *amDl, +KwNackInfo *nackInfo, +CmLList *retxNode, +KwNackInfo *nackSnInfo, +U8 idx +)); + +PRIVATE Void kwAmmDlUpdTxAndReTxBufForLessThanNackSn ARGS( +( +KwCb *gCb, +KwDlRbCb *rbCb, +KwSn sn, +KwSn mNackSn, +CmLList **retxNode, +KwuDatCfmInfo **datCfm +)); +/***************************************************************************** + + AM Module contains the following funcitons: + + - kwAmmQSdu + - kwAmmProcessSdus + - kwAmmDlAssembleCntrlInfo + - kwResegRetxPdus + - kwAssembleSdus + - kwAmmDlCheckAndSetPoll + - kwAmmProcessPdus + - kwDlmHndlStaRsp + - kwTriggerStatus + - kwReassembleSdus + +*******************************************************************************/ +/** @addtogroup ammode */ +/*@{*/ + +/** + * @brief Function to send a Status Response to MAC for a dedicated logical + * channel + * + * @details + * Function calculates the current bo and send a Status response for the + * dedicated logical channel if the bo is non zero + * + * @param[in] gCb RLC instance control block + * @param[in] rbCb Radio Bearer control block + * @param[in] amDl AM downlink control block + * + * @return Void +*/ +#ifdef ANSI +PUBLIC Void kwAmmSendDStaRsp +( +KwCb *gCb, +KwDlRbCb *rbCb, +KwAmDl *amDl +) +#else +PUBLIC Void kwAmmSendDStaRsp(gCb, rbCb, amDl) +KwCb *gCb; +KwDlRbCb *rbCb; +KwAmDl *amDl; +#endif +{ + S32 bo = kwAmmCalculateBo(amDl); + + if(bo) + { + kwUtlSndDStaRsp(gCb, rbCb, bo, amDl->estHdrSz, amDl->cntrlBo ?TRUE:FALSE,amDl->cntrlBo); + } + + RETVOID; +} + +/** + * @brief Function to check if the pollSn is acked and stop the poll timer + * + * @param[in] gCb RLC instance control block + * @param[in] rbCb Radio Bearer control block + * @param[in] mAckSn The last received ACKSN. The base modulus value should + * be passed + * + * @return Void +*/ +#ifdef ANSI +PRIVATE Void kwAmmDlCheckAndStopPollTmr +( +KwCb *gCb, +KwDlRbCb *rbCb, +KwSn mAckSn +) +#else +PRIVATE Void kwAmmDlCheckAndStopPollTmr(gCb, rbCb, mAckSn) +KwCb *gCb; +KwDlRbCb *rbCb; +KwSn mAckSn; +#endif +{ + KwSn mPollSn; + + MODAMT(rbCb->m.amDl.pollSn, mPollSn, rbCb->m.amDl.txNextAck,rbCb->m.amDl.snModMask); + + if (mPollSn <= mAckSn) + { + if (kwChkTmr(gCb, (PTR)rbCb, KW_EVT_AMDL_POLL_RETX_TMR)) + { + kwStopTmr(gCb, (PTR)rbCb, KW_EVT_AMDL_POLL_RETX_TMR); + } + } + + RETVOID; +} + +/** + * @brief Function to set VT(A) and VT(MS). Calculates the VT(MS) from VT(A) + * + * @param[in,out] amDl AM downlink control block + * @param[in]sn Sequence number to be set as VT(A) + * + * @return Void +*/ +#ifdef ANSI +PRIVATE Void kwAmmDlSetTxNextAck +( +KwAmDl *amDl, +KwSn sn +) +#else +PRIVATE Void kwAmmDlSetTxNextAck(amDl, sn) +KwAmDl *amDl; +KwSn sn +#endif +{ + amDl->txNextAck = sn; + + RETVOID; +} + +/** + * @brief Function to process a successfully re-transmitted PDU/segment + * + * @details + * Checks if the SDU has been completely delivered or not. Removes the PDU + * from the re-transmission buffer + * + * @param[in] gCb RLC instance control block + * @param[in] rbCb Downlink Radio Bearer control block + * @param[in] retx The PDU/segment which was successfully re-transmitted + * + * @return Void +*/ +#ifdef ANSI +PRIVATE Void kwAmmDlProcessSuccessfulReTx +( +KwCb *gCb, +KwDlRbCb *rbCb, +KwRetx *retx, +KwuDatCfmInfo **datCfm +) +#else +PRIVATE Void kwAmmDlProcessSuccessfulReTx(gCb, rbCb, retx, datCfm) +KwCb *gCb; +KwDlRbCb *rbCb; +KwRetx *retx; +KwuDatCfmInfo **datCfm; +#endif +{ + kwAmmDlCheckIsSDUDelivered(gCb, rbCb, &(retx->sduMap), datCfm); + + kwRemRetxPdu(gCb, rbCb, retx); + + RETVOID; +} + +/** + * @brief Handler to Move the PDU from txBuf to re-transmission buffer + * + * @details + * This function is used to move the PDU from the txBuf to re-transmit buffer + * + * @param[in]KwCb *gCb RLC instance control block + * @param[in]KwAmDl *amDl AM Downlink Control Block + * @param[in]KwRetx **retx node in the reTx buffer to be moved to, allocated by + * this function + * @param[in]KwDlPduInfo *pduInfo TX PDU which needs to be moved + * + * @return Void + * + */ + +#ifdef ANSI +PRIVATE Void kwAmmDlMoveSduByteSegFrmTxtoRetxBuffer +( +KwCb *gCb, +KwAmDl *amDl, +KwRetx **retx, +KwDlPduInfo *pduInfo +) +#else +PRIVATE Void kwAmmDlMoveSduByteSegFrmTxtoRetxBuffer(gCb, amDl, retx, pduInfo) +KwCb *gCb; +KwAmDl *amDl; +KwRetx **retx; +KwDlPduInfo *pduInfo; +#endif +{ + TRC2(kwAmmDlMoveSduByteSegFrmTxtoRetxBuffer); + + + KW_ALLOC_WC(gCb,*retx, sizeof(KwRetx)); + +#if (ERRCLASS & ERRCLS_ADD_RES) + if (*retx == NULLP) + { + RLOG0(L_FATAL, "Memory allocation failed"); + RETVOID; + } +#endif /* ERRCLASS & ERRCLS_RES */ + + (*retx)->seg = pduInfo->pdu; + (*retx)->segSz = pduInfo->pduSz; + /* MS_FIX for DL stall */ + (*retx)->soEnd = (pduInfo->amHdr.so + pduInfo->pduSz - 1); + + (*retx)->hdrSz = pduInfo->hdrSz; + (*retx)->retxCnt = 1; + (*retx)->yetToConst = 0; + (*retx)->pendingReTrans = TRUE; + + /* initialize the list pointer to 0 instead of memset */ + (*retx)->lstEnt.next = 0; + (*retx)->lstEnt.prev = 0; + /* copy the sdu maps */ + KW_MEM_CPY(&((*retx)->sduMap), + &pduInfo->sduMap, + sizeof(KwSduMap)); + + KW_MEM_CPY(&((*retx)->amHdr), &pduInfo->amHdr, sizeof(KwAmHdr)); + kwAmmAddPduToRetxLst(amDl, (*retx)); + + /* Update the BO appropriately */ + amDl->retxBo += (*retx)->segSz; + amDl->estHdrSz += (*retx)->hdrSz; + + gRlcStats.amRlcStats.numDLRetransPdus++; + + RETVOID; +} /*kwAmmDlMoveSduByteSegFrmTxtoRetxBuffer */ + +/** + * @brief Function to handle Status of Sdu byte segment for a nackSn + * + * @details + * This function is used to move the PDU from the txBuf to re-transmit buffer + * + * @param[in]KwCb *gCb RLC instance control block + * @param[in]KwDlRbCb *rbCb AM Downlink Control Block + * @param[in]KwNackInfo *nackSnInfo Nack Information of a NACK_SN + * @param[in]KwRetx **retx node in the reTx buffer to be moved to, allocated by + * this function + * @param[in]KwuDatCfmInfo **datCfm Ptr to datCfm + * + * @return Void + * + */ + +#ifdef ANSI +PRIVATE Void kwAmmDlHndlStatus4SduByteSegInTxBuf +( +KwCb *gCb, +KwDlRbCb *rbCb, +KwNackInfo *nackSnInfo, +KwRetx **retx, +KwuDatCfmInfo ** datCfm +) +#else +PRIVATE Void kwAmmDlHndlStatus4SduByteSegInTxBuf(gCb, rbCb, nackSnInfo, retx, datCfm) +( +KwCb *gCb; +KwDlRbCb *rbCb; +KwNackInfo *nackSnInfo; +KwRetx **retx; +KwuDatCfmInfo **datCfm; +) +#endif +{ + KwTx *txBuf=NULLP; + CmLList *lnk; + CmLList *nextLnk; + + TRC2(kwAmmDlHndlStatus4SduByteSegInTxBuf) + + txBuf = kwUtlGetTxBuf(AMDL.txBufLst, nackSnInfo->sn); + if (txBuf == NULLP) + { + RETVOID; + } + lnk = txBuf->pduLst.first; + while(lnk) + { + KwDlPduInfo *pduInfo = (KwDlPduInfo *)(lnk->node); + KwSn pduSoEnd = (pduInfo->amHdr.so + pduInfo->sduMap.sduSz - 1); + + /* If So of Sdu byte segment(pduInfo/seg) is < status pdu + soStart that means it's ACKED*/ + if(pduSoEnd < nackSnInfo->soStart) + { + kwAmmDlCheckIsSDUDelivered(gCb, + rbCb, + &(pduInfo->sduMap), + datCfm); + + } + else if (pduSoEnd <= nackSnInfo->soEnd) + { + /* Move Sdu byte segment from TX buf to retx buf*/ + kwAmmDlMoveSduByteSegFrmTxtoRetxBuffer(gCb, + &rbCb->m.amDl, + retx, + pduInfo); + } + else + { + lnk = lnk->next; + continue; + } + nextLnk = lnk->next; + /* Delete node from the txBuf Pdu lst */ + cmLListDelFrm(&txBuf->pduLst, lnk); + KW_FREE_WC(gCb, pduInfo, sizeof(KwDlPduInfo)); + lnk = nextLnk; + } + if(!txBuf->pduLst.count) + { + /*No more Sdu byte segment are left. Hence delete txBuf*/ + kwUtlDelTxBuf(AMDL.txBufLst, txBuf,gCb); + } + + RETVOID; +} + +/** + * @brief Function to handle Status of Sdu byte segment for a nackSn + * + * @details + * This function is used to move the PDU from the txBuf to re-transmit buffer + * + * @param[in]KwCb *gCb RLC instance control block + * @param[in]KwDlRbCb *rbCb AM Downlink Control Block + * @param[in]KwNackInfo *nackSnInfo Nack Information of a NACK_SN + * @param[in]KwRetx **retx node in the reTx buffer to be moved to, allocated by + * this function + * @param[in]KwuDatCfmInfo **datCfm Ptr to datCfm + * + * @return Void + * + */ +#ifdef ANSI +PRIVATE Void kwAmmDlUpdateTxAndReTxBufForNackSn +( + KwCb *gCb, + KwDlRbCb *rbCb, + KwNackInfo *nackSnInfo, + CmLList **retxNode, + KwuDatCfmInfo **datCfm + ) +#else +PRIVATE Void kwAmmDlUpdateTxAndReTxBufForNackSn(gCb, rbCb, nackSnInfo, retxNode, datCfm) +( + KwCb *gCb; + KwDlRbCb *rbCb; + KwNackInfo *nackSnInfo; + CmLList **retxNode; + KwuDatCfmInfo **datCfm; + ) +#endif +{ + KwTx *txBuf; + KwRetx *retx; + + TRC2(kwAmmDlUpdateTxAndReTxBufForNackSn) + + /* Now process the NACK_SN received. Now the NACK_SN is */ + /* either the first element of RETX or is in TX array */ + /* To remove the remaining acks from the pdu byte segments */ + + /* if the NACK_SN is in the transmit buffer, move it to the re- + transmit buffer */ + txBuf = kwUtlGetTxBuf(AMDL.txBufLst, nackSnInfo->sn); + if (txBuf != NULLP) + { + if(nackSnInfo->isSegment) + { + /* Go through all the AMD PDUs of a particular SN + and check if segment is ACKED if yes then mark succesfully sent, + if segment is NACKed then move it to to retx lst */ + kwAmmDlHndlStatus4SduByteSegInTxBuf(gCb, rbCb, nackSnInfo, &retx, datCfm); + } + else + { + /*e2= 0 and e3= 0: Move complete PDU from TX buf to retx buf*/ + kwAmmDlMoveFrmTxtoRetxBuffer(gCb, + &rbCb->m.amDl, + &retx, + nackSnInfo->sn); + } + +#if (ERRCLASS & ERRCLS_ADD_RES) + if(retx) +#endif + { + (*retxNode) = retx->lstEnt.next; + } + + RETVOID; + } + + /* process the pdus/segments in the re-transmit buffer with + this NACK_SN */ + while (*retxNode) + { + retx = (KwRetx *)((*retxNode)->node); + if (retx->amHdr.sn != nackSnInfo->sn) + { + break; + } + if ((nackSnInfo->isSegment) && + ((retx->soEnd < nackSnInfo->soStart) /*|| (retx->amHdr.so > soEnd)*/)) + { + RLOG_ARG3(L_DEBUG, DBG_RBID, rbCb->rlcId.rbId, + "kwHndlStaRsp: Handle ACK for byte segment, Its " + "sn = %d UEID:%d CELLID:%d", + nackSnInfo->sn, + rbCb->rlcId.ueId, + rbCb->rlcId.cellId); + RLOG_ARG4(L_DEBUG, DBG_RBID, rbCb->rlcId.rbId, + "soStart and soEnd = %d, %d, UEID:%d CELLID:%d", + retx->amHdr.so, retx->soEnd, + rbCb->rlcId.ueId, + rbCb->rlcId.cellId); + + (*retxNode) = (*retxNode)->next; + kwAmmDlProcessSuccessfulReTx(gCb,rbCb, retx, datCfm); + } + else if((!nackSnInfo->isSegment) || (retx->soEnd <= nackSnInfo->soEnd)) + { + /* This case covers the NACKED segments and also the case */ + /* when there are segments and the entire SN is nacked. */ + /* This case also covers the case of nonsegmented retx PDU*/ + + (*retxNode) = (*retxNode)->next; + /* Mark the retx PDU we found for further retransmission */ + kwAmmDlMarkPduForReTx(gCb, rbCb, retx); + } + else + { + /* If we are here that means this segment and segments after this are ACKed*/ + break; + } + } /* end of retxNode while loop*/ + RETVOID; +} + +/** + * @brief Function to get nack Sn information from nackRange index + * + * @details + * This function is used to get nack Sn information from nackRange index + * +* @param[in]KwAmDl *amDl, +* @param[in]KwUdxStaPdu *StaPdu, +* @param[in]KwNackInfo *nackSnInfo, +* @param[in]KwRetx *retx; +* @param[in]KwSn sn, +* @param[in]U8 idx + * + * @return Void + * + */ +#ifdef ANSI +PRIVATE Void KwDlAmmGetNackSnInfoFrmNackRangeIdx +( +KwAmDl *amDl, +KwNackInfo *nackInfo, +CmLList *retxNode, +KwNackInfo *nackSnInfo, +U8 idx +) +#else +PRIVATE Void KwDlAmmGetNackSnInfoFrmNackRangeIdx(amDl, nackInfo, retxNode, nackSnInfo, idx) +( +KwAmDl *amDl; +KwNackInfo *nackInfo; +CmLList *retxNode; +KwNackInfo *nackSnInfo; +U8 idx; +) +#endif +{ + KwTx *txBuf; + KwRetx *retx; + CmLList *node; + + TRC2(KwDlAmmGetNackSnInfoFrmNackRangeIdx) + + nackSnInfo->isSegment = FALSE; + + if((!nackInfo->isSegment) || (!idx && nackSnInfo->nackRange && (!nackInfo->soStart))) + { + nackSnInfo->soStart = 0; + nackSnInfo->soEnd = 0; + RETVOID; + } + txBuf = kwUtlGetTxBuf(amDl->txBufLst, nackSnInfo->sn); + if(txBuf != NULLP) + { + node = txBuf->pduLst.first; + while(node) + { + KwDlPduInfo *pduInfo = (KwDlPduInfo *)(node->node); + U16 pduSoEnd = pduInfo->amHdr.so + pduInfo->sduMap.sduSz - 1; + if((!idx) && (pduInfo->amHdr.so == nackInfo->soStart)) + { + nackSnInfo->isSegment = TRUE; + nackSnInfo->soStart = pduInfo->amHdr.so; + nackSnInfo->soEnd = pduSoEnd; + break; + } + else if((idx == nackSnInfo->nackRange - 1) && \ + (pduSoEnd == nackInfo->soEnd)) + { + nackSnInfo->isSegment = TRUE; + nackSnInfo->soStart = pduInfo->amHdr.so; + nackSnInfo->soEnd = pduSoEnd; + break; + } + node = node->next; + } + } + if(!nackSnInfo->isSegment) + { + while (retxNode) + { + retx = (KwRetx *)(retxNode->node); + if(retx->amHdr.sn != nackSnInfo->sn) + { + break; + } + if((!idx) && (retx->amHdr.so == nackInfo->soStart)) + { + nackSnInfo->isSegment = TRUE; + nackSnInfo->soStart = retx->amHdr.so; + nackSnInfo->soEnd = retx->soEnd; + break; + } + else if((idx == nackSnInfo->nackRange - 1) && \ + (retx->soEnd == nackInfo->soEnd)) + { + nackSnInfo->isSegment = TRUE; + nackSnInfo->soStart = retx->amHdr.so; + nackSnInfo->soEnd = retx->soEnd; + break; + } + retxNode = retxNode->next; + } + } +} + +/** + * @brief Function to update transmission buffers and send confimations to + * PDCP on the reception of Status PDU + * + * @details + * First processes the NACKs received + * -# Removes the pdus which are acked by each of the NACK SN from the + * transmission and re-transmission buffer + * -# If NACKed SN in in the transmisson buffer, moves it to re-transmission + * buffer + * -# Removes PDU segments of the NACKed SN which have been successfully + * received by the other end. For the un-successful ones, marks them for + * re-transmission + * -# When PDUs/segments are removed from the buffer, indicates to upper + * layer if the SDU is completely delivered + * -# Removes the PDUs/segments which are acked by the ACK_SN but not by the + * NACK_SNs + * + * @param[in] gCb RLC Instance control block + * @param[in] rbCb Downlink Radio Bearer control block + * @param[in] pStaPdu The decoded Status Pdu + * + * @return Void +*/ +#ifdef ANSI +PUBLIC Void kwAmmDlHndlStatusPdu +( +KwCb *gCb, +KwDlRbCb *rbCb, +KwUdxStaPdu *pStaPdu +) +#else +PUBLIC Void kwAmmDlHndlStatusPdu(gCb, rbCb, pStaPdu) +KwCb *gCb; +KwDlRbCb *rbCb; +KwUdxStaPdu *pStaPdu; +#endif +{ + KwSn mAckSn; + S32 oldRetxBo; + CmLList *retxNode; + KwuDatCfmInfo* datCfm; + KwKwuSapCb *kwuSap; + KwSn mTxNext; + + TRC2(kwAmmDlHndlStatusPdu) + kwStatusPduCnt++; + + kwuSap = gCb->u.dlCb->kwuDlSap + KW_UI_PDCP; + /* store the re-transmission bo, to check if it changes due to the + processing of the status pdu */ + oldRetxBo = AMDL.retxBo; + + /* Allocate memory for datCfm Info */ + KW_SHRABL_STATIC_BUF_ALLOC(kwuSap->pst.region, kwuSap->pst.pool, datCfm, sizeof(KwuDatCfmInfo)); + +#if (ERRCLASS & ERRCLS_ADD_RES) + if (datCfm == NULLP) + { + RLOG_ARG2(L_FATAL,DBG_RBID,rbCb->rlcId.rbId, + "Memory allocation failed UEID:%d CELLID:%d", + rbCb->rlcId.ueId, + rbCb->rlcId.cellId); + KW_SHRABL_STATIC_BUF_FREE(kwuSap->pst.region, kwuSap->pst.pool, datCfm, sizeof(KwuDatCfmInfo)); + RETVOID; + } +#endif /* ERRCLASS & ERRCLS_RES */ + + datCfm->numSduIds = 0; + datCfm->rlcId = rbCb->rlcId; + + MODAMT(pStaPdu->ackSn, mAckSn, AMDL.txNextAck,AMDL.snModMask); + MODAMT(AMDL.txNext,mTxNext, AMDL.txNextAck,AMDL.snModMask); + + if(mAckSn > mTxNext) + { + RLOG_ARG4(L_WARNING,DBG_RBID, rbCb->rlcId.rbId, + "Invalid ACK SN = %d received. Current Vta =%d" + "UEID:%d CELLID:%d", + pStaPdu->ackSn, + AMDL.txNextAck, + rbCb->rlcId.ueId, + rbCb->rlcId.cellId); +/* KW_SHRABL_STATIC_BUF_ALLOC(kwuSap->pst.region, kwuSap->pst.pool, datCfm, sizeof(KwuDatCfmInfo)); */ + KW_SHRABL_STATIC_BUF_FREE(kwuSap->pst.region, kwuSap->pst.pool, datCfm, sizeof(KwuDatCfmInfo)); + RETVOID; + } + + /* Venki - stopping the poll retx timer */ + /*Stop PollRetx Tmr */ + kwAmmDlCheckAndStopPollTmr(gCb, rbCb, mAckSn); + + /* Set the first node in retx list to retxNode */ + retxNode = AMDL.retxLst.first; + + /* If NACK exists in control PDU */ + if (pStaPdu->nackCnt) + { + KwSn sn; + KwNackInfo nackSnInfo; + KwSn mNackSn; + KwSn txNextAck; + KwSn transWinStartSn = AMDL.txNextAck; /*used to track the SN from which + to start processing the transmission + buffer */ + U32 idx = 0; + + /* if any NACKs then txNextAck should be equal to the first NACK_SN*/ + txNextAck = pStaPdu->nackInfo[0].sn; + + kwStatusNcnt += pStaPdu->nackCnt; + + /* For NACKs */ + while (idx < pStaPdu->nackCnt) + { + nackSnInfo.isSegment = pStaPdu->nackInfo[idx].isSegment; + nackSnInfo.nackRange = pStaPdu->nackInfo[idx].nackRange; + nackSnInfo.sn = pStaPdu->nackInfo[idx].sn; + + RLOG_ARG3(L_DEBUG,DBG_RBID, rbCb->rlcId.rbId, + "kwHndlStaRsp: NACK SN = %d UEID:%d CELLID:%d", + nackSnInfo.sn, + rbCb->rlcId.ueId, + rbCb->rlcId.cellId); + + nackSnInfo.soStart = pStaPdu->nackInfo[idx].soStart; + nackSnInfo.soEnd = pStaPdu->nackInfo[idx].soEnd; + + /* e2 is used as a boolean indicating presence of SOStart or SOEnd */ + + sn = transWinStartSn; + + /* move transWinStartSn to nackSnInfo.sn + 1, as the pdu's before that + will be removed from the buffer */ + transWinStartSn = (nackSnInfo.sn + (nackSnInfo.nackRange ?\ + (nackSnInfo.nackRange - 1) : 0) + 1) & AMDL.snModMask; + + /* Clear the acked SNs from the retx list */ + MODAMT(nackSnInfo.sn, mNackSn, AMDL.txNextAck,AMDL.snModMask); + + if ((mNackSn > mAckSn) || (mNackSn >= mTxNext)) + { + /* Erroneous NACK_SN, we should raise an error towards L3 */ + RLOG_ARG2(L_ERROR,DBG_RBID, rbCb->rlcId.rbId, + "Status Pdu is not correct UEID:%d CELLID:%d", + rbCb->rlcId.ueId, + rbCb->rlcId.cellId); + KW_SHRABL_STATIC_BUF_FREE(kwuSap->pst.region, kwuSap->pst.pool, datCfm, sizeof(KwuDatCfmInfo)); + RETVOID; + } + + /* clear all the SNs < NACK_SN from re-transmission list */ + kwAmmDlUpdTxAndReTxBufForLessThanNackSn(gCb, rbCb, sn, mNackSn, + &retxNode, &datCfm); + + if(!nackSnInfo.nackRange) + { + kwAmmDlUpdateTxAndReTxBufForNackSn(gCb, rbCb, &nackSnInfo, &retxNode, &datCfm); + gRlcStats.amRlcStats.numRlcAmCellNackRx++; + } + else + { + U8 idx1 = 0; + /* Update issegment, soStart, soEnd ,sn in nackSnInfo and handle + * nack sn*/ + do + { + KwDlAmmGetNackSnInfoFrmNackRangeIdx(&AMDL, &pStaPdu->nackInfo[idx], + retxNode, &nackSnInfo, idx1); + + kwAmmDlUpdateTxAndReTxBufForNackSn(gCb, rbCb, &nackSnInfo, + &retxNode, &datCfm); + nackSnInfo.sn = ((nackSnInfo.sn + 1) & (AMDL.snModMask)); + gRlcStats.amRlcStats.numRlcAmCellNackRx++; + + }while((++idx1) < (nackSnInfo.nackRange)); + } + + idx++; + } /* End of nackCnt while loop */ + + /* Remove the PDUs with are further acked by the ACK_SN after taking + care of all the NACK_SN related acknowledgments*/ + kwAmmDlUpdateTxAndReTxBufForAckSn(gCb,rbCb, mAckSn, retxNode, &datCfm); + + /* Update txNextAck */ + kwAmmDlSetTxNextAck(&AMDL,txNextAck); + } + else + { + kwStatusAckCnt++; + /* For All ACKs */ + RLOG_ARG2(L_UNUSED,DBG_RBID, rbCb->rlcId.rbId, + "kwHndlStaRsp: Received All ACKS UEID:%d CELLID:%d", + rbCb->rlcId.ueId, + rbCb->rlcId.cellId); + + /* For the remaining ACKs after last nackSn */ + kwAmmDlUpdateTxAndReTxBufForAckSn(gCb,rbCb, mAckSn, retxNode, &datCfm); + + /* update txNextAck */ + kwAmmDlSetTxNextAck(&AMDL, pStaPdu->ackSn); + } + + if(datCfm->numSduIds != 0) + { + if(datCfm->numSduIds > 1024) + { + RLOG_ARG4(L_DEBUG,DBG_RBID,datCfm->rlcId.rbId, + "Sending [%lu] SDU Cfms to PDCP & [%lu] lost for" + "UEID:%d CELLID:%d", + datCfm->numSduIds, + datCfm->numSduIds-1024, + rbCb->rlcId.ueId, + rbCb->rlcId.cellId); + datCfm->numSduIds = 1024; + } + kwSduSndCnt += datCfm->numSduIds; + /* Sap control block */ + KwUiKwuDatCfm(&kwuSap->pst, kwuSap->suId, datCfm); + } + else + { + KW_SHRABL_STATIC_BUF_FREE(kwuSap->pst.region, kwuSap->pst.pool, datCfm, sizeof(KwuDatCfmInfo)); + } + + /* Fix for memory corruption */ + KW_LLIST_FIRST_RETX(AMDL.retxLst, AMDL.nxtRetx); + /* BO update, if retransmission BO has changed. AMDL.retxBo would have + canged inside the above called functions */ + if (oldRetxBo != AMDL.retxBo) + { + kwAmmSendDStaRsp(gCb, rbCb, &AMDL); + } + + RETVOID; +} + +/** + * @brief Function to calculate the current buffer occupancy + * + * @details + * Function to calculate the current bo depending on the control, + * re-transmit, transmit bo's and the state of the transmit window. + * If the transmit window is stalled, then the transmit bo is not + * taken into account + * + * @param[in] amDl AM mode donwlink control block + * + * @return S16 + * Calculated bo +*/ +#ifdef ANSI +PUBLIC S32 kwAmmCalculateBo +( +KwAmDl *amDl +) +#else +PUBLIC S32 kwAmmCalculateBo(amDl) +KwAmDl *amDl; +#endif +{ + S32 bo; + + /* Make sure non of the bo's are negative */ + if (amDl->bo < 0) + { + amDl->bo = 0; + } + + if (amDl->cntrlBo < 0) + { + amDl->cntrlBo = 0; + } + + if (amDl->retxBo < 0) + { + amDl->retxBo = 0; + } + + bo = amDl->cntrlBo + amDl->retxBo; + + /* if window is not stalled then add the transmit bo also */ + if (! KW_AM_IS_TRANS_WIN_STALLED(amDl)) + { + bo += amDl->bo; + } + + return bo; +} +U32 kwRxSdu; + +/** + * @brief Handler to queue the SDUs received from PDCP + * + * @details + * This function is invoked by UIM to queue the SDU received from PDCP in the + * SDU queue of the corresponding RbCb. It also updates the BO and report the + * same to MAC. + * - Allocate memory for and assign received buffer to the SDU + * - Add SDU in the sduQ of KwAmDl + * - Calculate bo with the buffer received + * - Accumulate bo with retransmission bo and control pdu's bo if available + * - Estimate the header size for the bo; Fill in StaRspInfo and send it + * to MAC + * + * @param[in] gCb RLC Instance control block + * @param[in] rbCb RB control block + * @param[in] mBuf Sdu to be queued + * @param[in] datReq Ptr to the datReq sent from PDCP + * + * @return Void + * -# RETVOID +*/ +#ifdef ANSI +PUBLIC Void kwAmmQSdu +( +KwCb *gCb, +KwDlRbCb *rbCb, +Buffer *mBuf, +KwuDatReqInfo *datReq +) +#else +PUBLIC Void kwAmmQSdu(gCb, rbCb, mBuf, datReq) +KwCb *gCb; +KwDlRbCb *rbCb; +Buffer *mBuf; +KwuDatReqInfo *datReq; +#endif +{ + KwSdu *sdu; +#ifdef LTE_L2_MEAS +#ifndef L2_L3_SPLIT +#ifdef TENB_STATS + U32 kwWinSz; +#endif +#endif +#endif + TRC2(kwAmmQSdu) + + /* Allocate sdu */ + KW_ALLOC_WC(gCb,sdu, sizeof(KwSdu)); + +#if (ERRCLASS & ERRCLS_ADD_RES) + if (sdu == NULLP) + { + RLOG_ARG2(L_FATAL,DBG_RBID,rbCb->rlcId.rbId, + "Memory allocation failed UEID:%d CELLID:%d", + rbCb->rlcId.ueId, + rbCb->rlcId.cellId); + RETVOID; + } +#endif /* ERRCLASS & ERRCLS_RES */ + + KW_UPD_L2_DL_TOT_SDU_STS(gCb,rbCb); + /* Discard new changes starts */ + kwUtlGetCurrTime(&sdu->arrTime); + /* Discard new changes ends */ + /* Assign values to sdu */ + SFndLenMsg(mBuf, &sdu->sduSz); + + sdu->mBuf = mBuf; + sdu->actSz = sdu->sduSz; + sdu->mode.am.sduId = datReq->sduId; + /* initialize values for AM mode to 0 */ + sdu->mode.am.rcvdSz = 0; + sdu->mode.am.isSegmented = 0; +#ifndef RGL_SPECIFIC_CHANGES +#ifdef MSPD +{ +extern U32 dlrate_kwu; +dlrate_kwu += sdu->sduSz; +} +#endif +#endif + /* Update nxtTx to point to the added sdu if this is the first SDU in the + * queue */ + if (AMDL.nxtTx == NULLP) + { + RLOG_ARG2(L_UNUSED,DBG_RBID, rbCb->rlcId.rbId, + "kwAmmQSdu: Received SDU will be transmitted next" + "UEID:%d CELLID:%d", + rbCb->rlcId.ueId, + rbCb->rlcId.cellId); + AMDL.nxtTx = sdu; + } + + /* Add sdu to the sdu list */ + cmLListAdd2Tail(&AMDL.sduQ, &sdu->lstEnt); + sdu->lstEnt.node = (PTR)sdu; +#ifdef LTE_L2_MEAS +#ifndef L2_L3_SPLIT +#ifdef TENB_STATS + if (rbCb->ueCb->tenbStats) + { + if (AMDL.sduQ.count > rbCb->ueCb->tenbStats->stats.nonPersistent.rlc.dlMaxPktsInSduQ) + { + rbCb->ueCb->tenbStats->stats.nonPersistent.rlc.dlMaxPktsInSduQ = AMDL.sduQ.count; + } + kwWinSz = KW_AM_TRANS_WIN_SIZE(&AMDL); + if (kwWinSz > rbCb->ueCb->tenbStats->stats.nonPersistent.rlc.dlMaxWindowSz) + { + rbCb->ueCb->tenbStats->stats.nonPersistent.rlc.dlMaxWindowSz = kwWinSz; + } + } +#endif +#endif +#endif + /* Update BO and estimate header size for the current BO */ + AMDL.bo = AMDL.bo + sdu->sduSz; + if(AMDL.snLen == KW_AM_CFG_12BIT_SN_LEN) + { + AMDL.estHdrSz += 2; + } + else + { + AMDL.estHdrSz += 3; + } +#ifdef LTE_L2_MEAS_RLC + /* Update numActUe if it is not active */ + if((rbCb->rbL2Cb.measOn & LKW_L2MEAS_ACT_UE) && + (rbCb->ueCb->numActRb[rbCb->qci] == 0)) + { + rbCb->ueCb->numActRb[rbCb->qci]++; + gCb.kwL2Cb.numActUe[rbCb->qci]++; + } +#endif + + if(!kwDlUtlIsReestInProgress(rbCb)) + { + kwAmmSendDStaRsp(gCb, rbCb, &AMDL); + } + + RETVOID; +} + +/** + * + * @brief Private handler to construct control PDU + * + * @details + * This function sets the pduSz correctly after eliminating the fixed + * header sizes and the MAC header size. It copies the already prepared + * STATUS PDU to the data to be sent to MAC. + * + * @param[in] gCb RLC instance control block + * @param[in] rbCb Downlink RB control block + * @param[in] kwdatReq DatReq to be sent to MAC + * + * @return Void + * + */ +#ifdef ANSI +PRIVATE Void kwAmmDlAssembleCntrlInfo +( +KwCb *gCb, +KwDlRbCb *rbCb, +KwDatReq *kwDatReq +) +#else +PRIVATE Void kwAmmDlAssembleCntrlInfo(gCb, rbCb, kwDatReq) +KwCb *gCb; +KwDlRbCb *rbCb; +KwDatReq *kwDatReq; +#endif +{ + KwUdxDlSapCb *sapCb; + MsgLen macHdrEstmt; + + TRC2(kwAmmDlAssembleCntrlInfo) + + macHdrEstmt = (rbCb->m.amDl.cntrlBo < 256) ? + KW_MAC_HDR_SZ2 : KW_MAC_HDR_SZ3; + /* Eliminate fixed hdr size (14bits including ACK_SN) */ + if (kwDatReq->pduSz >= (KW_CNTRL_PDU_FIXED_HDRSZ + macHdrEstmt)) + { + /* Check the TB size whether it is sufficcient enough to fit the + status Pdu into it otherwise make arrangement such that it can fit + into in a way of possible NACks*/ + /* ccpu00135743 : fix for MAC Hdr size calc */ + kwDatReq->pduSz -= macHdrEstmt; + + /* Create the status Pdu with the required NACKs */ + kwAmmCreateStatusPdu(gCb,rbCb,kwDatReq); + + sapCb = KW_GET_DL_SAPCB(gCb, rbCb); + KwDlUdxStaProhTmrStart(&(gCb->u.dlCb->udxDlSap->pst), + sapCb->suId, &(rbCb->rlcId)); + + /* Update number of pdus in pduInfo */ + kwDatReq->pduInfo.mBuf[kwDatReq->pduInfo.numPdu] = AMDL.mBuf; + kwDatReq->pduInfo.numPdu++; + gRlcStats.amRlcStats.numDLStaPduSent++; + + KW_FREE_SHRABL_BUF(gCb->u.dlCb->udxDlSap->pst.region, + gCb->u.dlCb->udxDlSap->pst.pool, + AMDL.pStaPdu, + sizeof(KwUdxDlStaPdu)); + + AMDL.pStaPdu = NULLP; + AMDL.mBuf = NULLP; + gRlcStats.amRlcStats.numDLStaPduSent++; + } + + RETVOID; +} + +/** + * @brief Handler to form the PDUs with the size indicated by MAC + * + * @details + * This function is invoked by UTL with the PDU size indicated by + * MAC (after eliminating MAC header size). It assembles control + * Info / data (New SDUs / Retx PDUs), check if polling needs to be + * set for the data PDU and returns PDU(s) and updated BO with + * estimated header size to be sent to MAC. + * + * - Check if the control BO is available and call kwAssembleCntrlInfo + * to assemble control Information + * - Check if the pdu size is available to form PDUs from retransmission + * buffer and call kwResegRetxPdus + * - Check if the pdu size is available and assemble SDUs from sduQ + * if exist, using kwAssembleSdus + * - PDU Info and bo are filled in and then sent to MAC from the + * utility function + * + * @param[in] gCb RLC instance control block + * @param[in] rbCb RB control block + * @param[in] kwdatReq DatReq to be sent to MAC + * @param[in] fillCtrlPdu Indicates whether cntrl PDU to be filled or not + * + * @return Void + * + */ +#ifdef ANSI +PUBLIC Void kwAmmProcessSdus +( +KwCb *gCb, +KwDlRbCb *rbCb, +KwDatReq *kwDatReq, +Bool fillCtrlPdu +) +#else +PUBLIC Void kwAmmProcessSdus(gCb, rbCb, kwDatReq,fillCtrlPdu) +KwCb *gCb; +KwDlRbCb *rbCb; +KwDatReq *kwDatReq; +Bool fillCtrlPdu; +#endif +{ + TRC2(kwAmmProcessSdus) + + + /* Assemble control information. fillCtrlPdu parameter check is added for CA + * It is used to force cntrl Pdu scheduling on PCell. for Non CA case this + * flag will always be TRUE. In CA case, for PCELL it is TRUE and for SCEll + * it is FALSE */ + + if ((AMDL.cntrlBo != 0) +#ifdef LTE_ADV + && (fillCtrlPdu) +#endif + ) + { + kwDatReq->boRep.staPduPrsnt = TRUE; + kwDatReq->boRep.staPduBo = AMDL.cntrlBo; + + if (AMDL.pStaPdu != NULLP) + { + kwAmmDlAssembleCntrlInfo (gCb, rbCb, kwDatReq); + } + else + { + RLOG_ARG2(L_ERROR, DBG_RBID, rbCb->rlcId.rbId, + "Miscomputation of control Bo. UEID:%d CELLID:%d", + rbCb->rlcId.ueId, + rbCb->rlcId.cellId); + } + AMDL.cntrlBo = 0; + } + + /* Retransmit PDUs /portions of PDUs available in retxLst */ + if ((kwDatReq->pduSz > 0) && (AMDL.nxtRetx != NULLP)) + { + kwResegRetxPdus (gCb,rbCb, kwDatReq); + } + + /* Assemble SDUs to form new PDUs */ + if ((kwDatReq->pduSz > 0) && (AMDL.nxtTx != 0)) + { + kwAssembleSdus(gCb,rbCb, kwDatReq); + } + + if (AMDL.nxtRetx != NULLP) + { + kwDatReq->boRep.oldestSduArrTime = AMDL.nxtRetx->sduMap.sdu->arrTime; + } + else if (AMDL.nxtTx != NULLP) + { + kwDatReq->boRep.oldestSduArrTime = AMDL.nxtTx->arrTime; + } + /* Accumulate bo */ + kwDatReq->boRep.bo = kwAmmCalculateBo(&AMDL); + kwDatReq->boRep.staPduBo = AMDL.cntrlBo; + + /* Hdr estimation is moved to kwAmmCreatePDu */ + kwDatReq->boRep.estHdrSz = AMDL.estHdrSz; + + if(kwDatReq->pduSz > 0) + { + gRlcStats.amRlcStats.numDLBytesUnused += kwDatReq->pduSz; + } + RETVOID; +} + +/** + * @brief Private handler split a PDU/segment into two + * + * @details + * Its a private function called by kwResegRetxPdu to split a segment + * or a retransmit PDU into two segments splitting at the passed size. + * This function is called only for those PDUs that dont have any LIs. + * + * @param[in] gCb RLC instance control block + * @param[in] rbCb RB control block + * @param[in,out] crnt The PDU to be split, first part of split pdu remians + * in this + * @param[out] next The second part of the split pdu + * @param[in] size The size witin crnt, at which to split + * + * @return Void + * + */ +#ifdef ANSI +PRIVATE Void kwSplitPdu +( +KwCb *gCb, +KwDlRbCb *rbCb, +KwRetx *crnt, +KwRetx *next, +U16 size +) +#else +PRIVATE Void kwSplitPdu(gCb, rbCb, crnt, next, size) +KwCb *gCb; +KwDlRbCb *rbCb; +KwRetx *crnt; +KwRetx *next; +U16 size; +#endif +{ + U8 si; + KwAmDl *amDl = &AMDL; + + TRC2(kwSplitPdu) + /* Set the SN for the new segment */ + next->amHdr.sn = crnt->amHdr.sn; + + /* Set the protocol specific fields appropriately */ + si = crnt->amHdr.si; + crnt->amHdr.si = si | KW_SI_FIRST_SEG; + next->amHdr.si = si | KW_SI_LAST_SEG; + + crnt->amHdr.p = 0; + + /* Update seg size */ + next->segSz = crnt->segSz - size; + crnt->segSz = size; + + /* Set the SO fields appropriately */ + /* MS_FIX for DL stall */ + next->soEnd = crnt->soEnd; + + /* Set the SO fields appropriately */ + /* SO of next will be after the end of current */ + next->amHdr.so = crnt->amHdr.so + crnt->segSz; + /* SO End of current will be one less than the start of next */ + crnt->soEnd = next->amHdr.so - 1; + + /* intialize the other fields in the amHdr of next to 0 */ + next->amHdr.p = 0; + next->amHdr.dc = 0; + + /* This macro is called for No LI case - one SDU */ + /* Update the size of SDU in each node's sduMap */ + next->sduMap.sdu = crnt->sduMap.sdu; + crnt->sduMap.sduSz = crnt->segSz; + next->sduMap.sduSz = next->segSz; + + /* Segment the payload into two parts based on the size passed */ + SSegMsg(crnt->seg, size, &next->seg); + next->retxCnt = crnt->retxCnt; + next->yetToConst = TRUE; + next->pendingReTrans = crnt->pendingReTrans; + + /* Compute the header size and update the BO appropriately */ + if(amDl->snLen == KW_AM_CFG_12BIT_SN_LEN) + { + next->hdrSz = KW_AM_SEG_12BIT_SN_WITH_SO_HDRSZ; + if(crnt->amHdr.si == KW_SI_FIRST_SEG) + { + crnt->hdrSz = KW_AM_SEG_12BIT_SN_WITHOUT_SO_HDRSZ; + } + else + { + crnt->hdrSz = KW_AM_SEG_12BIT_SN_WITH_SO_HDRSZ; + } + } + else + { + next->hdrSz = KW_AM_SEG_18BIT_SN_WITH_SO_HDRSZ; + if(crnt->amHdr.si == KW_SI_FIRST_SEG) + { + crnt->hdrSz = KW_AM_SEG_18BIT_SN_WITHOUT_SO_HDRSZ; + } + else + { + crnt->hdrSz = KW_AM_SEG_18BIT_SN_WITH_SO_HDRSZ; + } + } + + /* Add the next to the retx list */ + AMDL.retxLst.crnt = &crnt->lstEnt; + CM_LLIST_INS_AFT_CRNT(AMDL.retxLst, next); + AMDL.nxtRetx = next; + amDl->estHdrSz += next->hdrSz; + + RETVOID; +} + +/** + * @brief Private handler to retransmit PDUs or PDU segments + * + * @details + * Its a private function called by kwProcessSdus, to create the + * PDUs / its segments from the retransmission buffer available in RbCb. + * + * - Eliminate the fixed header size and MAC header size while + * forming PDUs/segments + * - While pdusize is available and retxBuf has data (pdu or portion + * of pdu) to be sent, form the pdu as it is if it matches with the + * pdusize else segment the PDUs/portion of PDUs + * - Call kwAmmDlCheckAndSetPoll function to check and set the poll bit as + * required + * - Concatenate data and header info and fill pduInfo + * - Update retxCnt and send indication to PDCP if it reaches maxRetx + * threshold + * + * @param[in] gCb RLC instance control block + * @param[in] rbCb RB control block + * @param[in] kwdatReq DatReq to be sent to MAC + * + * @return Void + * + */ +#ifdef ANSI +PRIVATE Void kwResegRetxPdus +( +KwCb *gCb, +KwDlRbCb *rbCb, +KwDatReq *kwDatReq +) +#else +PRIVATE Void kwResegRetxPdus(gCb, rbCb, kwDatReq) +KwCb *gCb; +KwDlRbCb *rbCb; +KwDatReq *kwDatReq; +#endif +{ + KwAmDl *amDl; + KwRetx *retx; + U8 hdr[KW_MAX_HDRSZ]; + U16 idx; + Buffer *pdu; + MsgLen pduSz; +#ifdef LTE_L2_MEAS + U16 sduIdx; + KwL2MeasTb *l2MeasTb; + KwlchInfo *lchInfo; + U8 numSdus; +#endif + + TRC2(kwResegRetxPdus) + + + amDl = &AMDL; +#ifdef LTE_L2_MEAS + /* TODO : This shoould be taken care in new Trasmissions */ + /* This lchInfo should be retrieved there */ + l2MeasTb = kwUtlGetCurMeasTb(gCb, rbCb); + if (l2MeasTb == NULLP) + { + RETVOID; + } + /* TODO : This lcid needs to be searched in case of normal Tx */ + /* In retx here, its fine as this will be higher priority */ + lchInfo = &l2MeasTb->lchInfo[l2MeasTb->numLchInfo]; + if (l2MeasTb->numLchInfo >= KW_MAX_ACTV_DRB) + { + RETVOID; + } + l2MeasTb->numLchInfo++; + lchInfo->lcId = rbCb->lch.lChId; + lchInfo->numSdus = 0; +#endif + + while ((kwDatReq->pduSz > 0) && (amDl->nxtRetx != NULLP)&& + (kwDatReq->pduInfo.numPdu < KW_MAX_PDU)) + { + U16 tmpSz; + + retx = amDl->nxtRetx; + /* kw003.201 : Add header size to seg size to determine if the */ + /* the segment can be completed within the allocation */ + /* kw003.201 - Eliminate MAC Header Size based on bites needed */ + tmpSz = KW_MIN((retx->segSz + retx->hdrSz), kwDatReq->pduSz); + pduSz = (retx->segSz + retx->hdrSz); + /* 5GNR_RLC: length field in 5GNR MAC Hdr is 8/16 btis*/ + kwDatReq->pduSz -= (tmpSz < 255) ? KW_MAC_HDR_SZ2 : KW_MAC_HDR_SZ3; + + /* kw003.201 - We should have at least one more than basic header */ + if (kwDatReq->pduSz <= retx->hdrSz) + { + RETVOID; + } + kwGetNxtRetx(gCb, &(amDl->nxtRetx)); + + /* Send retx buf without segmentation */ + if (kwDatReq->pduSz >= pduSz) + { + U8 pollBit; + + RLOG_ARG2(L_DEBUG,DBG_RBID,rbCb->rlcId.rbId, + "kwResegRetxPdus: Send retx buf without segmentation " + "UEID:%d CELLID:%d", + rbCb->rlcId.ueId, + rbCb->rlcId.cellId); + + if (retx->yetToConst) + { + /* Construct hdr with the available hdr values */ + kwConstructAmHdr(&retx->amHdr, hdr, amDl->snLen, &idx); + /* Add header to the pdu/segment */ + SAddPreMsgMultInOrder(hdr, idx + 1, retx->seg); + retx->yetToConst = FALSE; + } + + /* kw003.201 - Check if poll bit needs to be set. Retx size does */ + /* not affect the poll bit so it is being passed as zero */ + pollBit = kwAmmDlCheckAndSetPoll(gCb,rbCb, FALSE, 0); + KW_UPD_POLL_BIT(gCb, retx, pollBit); + + kwDatReq->pduSz -= pduSz; + AMDL.estHdrSz -= retx->hdrSz; +#ifdef LTE_L2_MEAS + + if (rbCb->rlcId.rbType == CM_LTE_DRB) + { + numSdus = 0; + for (sduIdx = lchInfo->numSdus ; + ((numSdus < retx->numSdu) && (sduIdx < KW_L2MEAS_SDUIDX)) ; + sduIdx++, numSdus++) + { + lchInfo->sduInfo[sduIdx].arvlTime = retx->sduMap[numSdus].sdu->arrTime; + lchInfo->sduInfo[sduIdx].isRetxPdu = TRUE; /* TODO : for later use */ + } + lchInfo->numSdus += numSdus; + } +#endif + } + else + { + KwRetx *tNode; + + /* Segment this pdu / portion of pdu. Insert this segment into */ + /* retxLst and update offset */ + RLOG_ARG2(L_DEBUG,DBG_RBID,rbCb->rlcId.rbId, + "kwResegRetxPdus: Segment retx buf UEID:%d CELLID:%d", + rbCb->rlcId.ueId, + rbCb->rlcId.cellId); + + /* Eliminate fixed header size if the pdu is segmented for the */ + /* first time */ + if(amDl->snLen == KW_AM_CFG_12BIT_SN_LEN) + { + if(retx->amHdr.si < KW_SI_LAST_SEG) + { + kwDatReq->pduSz -= KW_AM_SEG_12BIT_SN_WITHOUT_SO_HDRSZ; + } + else + { + kwDatReq->pduSz -= KW_AM_SEG_12BIT_SN_WITH_SO_HDRSZ; + } + } + else + { + if(retx->amHdr.si < KW_SI_LAST_SEG) + { + kwDatReq->pduSz -= KW_AM_SEG_18BIT_SN_WITHOUT_SO_HDRSZ; + } + else + { + kwDatReq->pduSz -= KW_AM_SEG_18BIT_SN_WITH_SO_HDRSZ; + } + } + if (kwDatReq->pduSz <= 0) + { + RETVOID; + } + + /* Allocate memory for tracking a new segment */ + KW_ALLOC_WC(gCb,tNode, sizeof(KwRetx)); +#if (ERRCLASS & ERRCLS_ADD_RES) + if (tNode == NULLP) + { + RLOG_ARG2(L_FATAL,DBG_RBID,rbCb->rlcId.rbId, + "Memory allocation failed UEID:%d CELLID:%d", + rbCb->rlcId.ueId, + rbCb->rlcId.cellId); + RETVOID; + } +#endif /* ERRCLASS & ERRCLS_RES */ + + /* initialize the list pointer to 0 instead of memset */ + tNode->lstEnt.next = 0; + tNode->lstEnt.prev = 0; + + /* Segment header and data */ + KW_AM_RMV_HDR(gCb, rbCb, retx); + + /* kw003.201 - Split the payload and update other fields */ + kwSplitPdu(gCb,rbCb, retx, tNode, kwDatReq->pduSz); + +#ifdef LTE_L2_MEAS + numSdus = 0; + /* ccpu00143043 */ + sduIdx = lchInfo->numSdus; + for (numSdus = 0, sduIdx = lchInfo->numSdus; + ((numSdus < retx->numSdu) && (sduIdx < KW_L2MEAS_SDUIDX)); + numSdus++, sduIdx++) + { + lchInfo->sduInfo[sduIdx].arvlTime = + retx->sduMap[numSdus].sdu->arrTime; + lchInfo->sduInfo[sduIdx].isRetxPdu = TRUE; + } + lchInfo->numSdus = sduIdx; + if ((retx->amHdr.lsf == 0) && (lchInfo->numSdus > 0)) + { + lchInfo->numSdus--; + } +#endif + /* Construct hdr with the available hdr values */ + kwConstructAmHdr(&retx->amHdr, hdr, amDl->snLen, &idx); + SAddPreMsgMultInOrder(hdr, idx + 1, retx->seg); + + retx->hdrSz = idx + 1; + + /* Poll bit need not be set for this seg, since its second */ + /* half remains in retxLst */ + KW_UPD_POLL_BIT(gCb, retx, FALSE); + retx->yetToConst = FALSE; + kwDatReq->pduSz = 0; + } + + kwCpyMsg(gCb,retx->seg, &pdu); + + /* Update pduInfo */ + kwDatReq->pduInfo.mBuf[kwDatReq->pduInfo.numPdu] = pdu; + kwDatReq->pduInfo.numPdu++; + /* kw005.201 ccpu00117318, updating the statistics */ + gCb->genSts.pdusRetx += 1; + gRlcStats.amRlcStats.numRlcAmCellRetxPdu++; + retx->soEnd = retx->amHdr.so + retx->segSz - 1; + retx->pendingReTrans = FALSE; + amDl->retxBo -= retx->segSz; + } +#ifndef ALIGN_64BIT + RLOG_ARG3(L_DEBUG,DBG_RBID,rbCb->rlcId.rbId, + "kwResegRetxPdus: retxBo after resegmentation = %ld" + "UEID:%d CELLID:%d", + amDl->retxBo, + rbCb->rlcId.ueId, + rbCb->rlcId.cellId); +#else + RLOG_ARG3(L_DEBUG,DBG_RBID,rbCb->rlcId.rbId, + "kwResegRetxPdus: retxBo after resegmentation = %d " + "UEID:%d CELLID:%d", + amDl->retxBo, + rbCb->rlcId.ueId, + rbCb->rlcId.cellId); +#endif + + RETVOID; +} + + +/** + * @brief Private handler to assemble SDUs to form new data PDU(s) + * + * @details + * Its a private function called by kwProcessSdus, to create the new data + * PDUs from the SDU queue of RbCb. + * + * - While pdusize is available, segment/concatenate SDUs or else if it + * matches the pdu size form PDUs accordingly. + * - RLC header and MAC header size are eliminated while forming the PDUs + * - Call kwAmmDlCheckAndSetPoll function to check and set the poll bit + * as required + * - Concatenate data and header info and fill pduInfo + * + * @param[in] rbCb RB control block + * @param[in] kwdatReq DatReq to be sent to MAC + * + * @return Void + * + */ +#ifdef ANSI +PRIVATE Void kwAssembleSdus +( +KwCb *gCb, +KwDlRbCb *rbCb, +KwDatReq *kwDatReq +) +#else +PRIVATE Void kwAssembleSdus (gCb, rbCb, kwDatReq) +KwCb *gCb; +KwDlRbCb *rbCb; +KwDatReq *kwDatReq; +#endif +{ + Buffer *pdu = NULLP; + MsgLen macGrntSz = kwDatReq->pduSz; + KwAmDl *amDl = &AMDL; + KwSdu *sdu = amDl->nxtTx; + KwSduMap sduMap; + Bool nxtTxUpd = FALSE; + KwuDiscSduInfo *discSduInfo = NULLP; + KwKwuSapCb* kwuSap = gCb->u.dlCb->kwuDlSap + KW_UI_PDCP; +#ifdef LTE_L2_MEAS + KwContSduLst contSduLst; /*Contained sduLst */ + S32 dataVol = amDl->bo; + U32 *totMacGrant = &kwDatReq->totMacGrant; + KwL2MeasDlIpTh *dlIpThPut = &rbCb->l2MeasIpThruput.dlIpTh; + U8 *sduIdx = &dlIpThPut->lastSduIdx; + Bool newIdx; + Bool isSduSegmented; + S32 oldBo; + KwlchInfo lchInfo; + KwlchInfo *dstLchInfo; + U32 segSduCnt = 0; + U32 lchIdx; + U32 numSdus = 0; + U32 currSduIdx = 0; + KwL2MeasTb *l2MeasTb; +#endif + /* Discard new changes starts */ + Ticks timeDiff = 0; + Ticks curTime = 0; + U8 numNewPdu = 0; + KwTx *txBuf = NULLP; + /* Discard new changes ends */ + VOLATILE U32 startTime = 0; + U32 hdrEstmt; + U32 fixedHdrSz; + U32 pduSz; + KwAmHdr *amHdr = NULLP; + KwDlPduInfo *pduInfo = NULLP; + + TRC2(kwAssembleSdus) + + +#ifdef LTE_L2_MEAS + contSduLst.numSdus = 0; + contSduLst.lcId = rbCb->lch.lChId; + oldBo = amDl->bo; + lchInfo.lcId = rbCb->lch.lChId; + lchInfo.numSdus = 0; +#endif + /* Discard new changes starts */ + /* Allocate memory for discSdu Info */ + KW_SHRABL_STATIC_BUF_ALLOC(kwuSap->pst.region, + kwuSap->pst.pool, + discSduInfo, + sizeof(KwuDiscSduInfo)); + +#if (ERRCLASS & ERRCLS_ADD_RES) + if (discSduInfo == NULLP) + { + RLOG_ARG2(L_FATAL,DBG_RBID,rbCb->rlcId.rbId, + "Memory allocation failed UEID:%d CELLID:%d", + rbCb->rlcId.ueId, + rbCb->rlcId.cellId); + RETVOID; + } +#endif /* ERRCLASS & ERRCLS_RES */ + + discSduInfo->numSduIds = 0; + discSduInfo->rlcId = rbCb->rlcId; + + kwUtlGetCurrTime(&curTime); + amDl->sduQ.crnt = &sdu->lstEnt; + /* Eliminate fixed header size */ + /*5GNR: value of KW_AM_PDU_FIXED_HDRSZ will be 2 or 3 depending on SN Size*/ + if(amDl->snLen == KW_AM_CFG_12BIT_SN_LEN) + { + fixedHdrSz = KW_AM_PDU_12BIT_SN_HDRSZ; + } + else + { + fixedHdrSz = KW_AM_PDU_18BIT_SN_HDRSZ; + } + + while ((macGrntSz > fixedHdrSz) && (sdu != NULLP) && + (kwDatReq->pduInfo.numPdu < KW_MAX_PDU) && + (numNewPdu < KW_MAX_NEW_DL_PDU)) + { +#ifdef LTE_L2_MEAS + isSduSegmented = sdu->mode.am.isSegmented; +#endif + /* Discard new changes starts */ + if ((sdu->mode.am.isSegmented == FALSE) && (rbCb->discTmrInt > 0) && \ + (rbCb->rlcId.rbType == CM_LTE_DRB)) + { + //leftAmSdus[rbCb->qci]--; + timeDiff = KW_TIME_DIFF(curTime,sdu->arrTime); + if (timeDiff > rbCb->discTmrInt) + { + CmLList* nxtNode; + /*starting Task*/ + SStartTask(&startTime, PID_RLC_AMM_DISC_SDUS); +#ifdef LTE_L2_MEAS + KW_UPD_L2_DL_DISC_SDU_STS(gCb,rbCb); + /* TODO need to send disc cfm to pdcp */ +#endif + /* Update bo for boReport */ + amDl->bo -= sdu->sduSz; + + /* Get next sdu for assembly */ + nxtNode = sdu->lstEnt.next; + + /* store the info for sending it to PDCP */ + if(discSduInfo->numSduIds > 500) + { + RLOG_ARG2(L_ERROR,DBG_RBID, rbCb->rlcId.rbId, + "This is a big error, we shouldn't be here" + "UEID:%d CELLID:%d", + rbCb->rlcId.ueId, + rbCb->rlcId.cellId); + break; + } + + discSduInfo->sduIds[discSduInfo->numSduIds] = sdu->mode.am.sduId; + discSduInfo->numSduIds++; + + cmLListDelFrm(&amDl->sduQ, &sdu->lstEnt); + + kwUtlAddSduToBeFreedQueue(gCb, sdu); + kwUtlRaiseDlCleanupEvent(gCb); + + /* We need to restore the crnt in the linked list which + * would have become NULL in the DelFrm above */ + amDl->sduQ.crnt = nxtNode; + + if(nxtNode) + sdu = (KwSdu*)nxtNode->node; + else + sdu = NULLP; + + /*stopping Task*/ + SStopTask(startTime, PID_RLC_AMM_DISC_SDUS); + continue; + } + } + nxtTxUpd = FALSE; + +#ifdef LTE_L2_MEAS + newIdx = FALSE; +#endif + /** kw003.201 - Check for window stall when you are + * creating a new PDU + */ + if (KW_AM_IS_TRANS_WIN_STALLED(amDl)) + { + //int *a = NULLP; + printf("\n Window stalled \n"); + gRlcStats.amRlcStats.numRlcAmCellWinStall++; + //*a = 10; + break; + } + + hdrEstmt = fixedHdrSz; + + if (sdu->mode.am.isSegmented) + { + /* Adding two byte for SO */ + hdrEstmt += 2; + } + /* Eliminate MAC header */ + /* ccpu00135743 : Fix for MAC Hdr size calculation */ + /*5GNR: value of mac hdr length field changed to 8/16bits */ + pduSz = KW_MIN(macGrntSz, (sdu->sduSz + hdrEstmt)); + hdrEstmt += (pduSz < 255) ? KW_MAC_HDR_SZ2 : KW_MAC_HDR_SZ3; + + macGrntSz -= hdrEstmt; + /* kw005.201 Check for PDU Size is large enough. + * Fix for ccpu00118973 + * */ + if(macGrntSz <= 0) + { + break; + } + + /* Dont create new txBuf for segmented SDU */ + if (!sdu->mode.am.isSegmented) + { + /* Update txBuf */ + KW_ALLOC_WC(gCb,txBuf, sizeof(KwTx)); + + cmLListInit(&txBuf->pduLst); + +#if (ERRCLASS & ERRCLS_ADD_RES) + if (txBuf == NULLP) + { + U32 avblMem = 0; + SRegInfoShow(gCb->init.region, &avblMem); + RLOG_ARG2(L_FATAL,DBG_RBID,rbCb->rlcId.rbId, + "Memory allocation failed UEID:%d CELLID:%d", + rbCb->rlcId.ueId, + rbCb->rlcId.cellId); + RETVOID; + } +#endif /* ERRCLASS & ERRCLS_RES */ + + kwUtlStoreTxBuf(amDl->txBufLst, txBuf, amDl->txNext); + } + else + { + txBuf = kwUtlGetTxBuf(amDl->txBufLst, amDl->txNext); + } + + KW_ALLOC_WC(gCb,pduInfo, sizeof(KwDlPduInfo)); +#if (ERRCLASS & ERRCLS_ADD_RES) + if (pduInfo == NULLP) + { + U32 avblMem = 0; + SRegInfoShow(gCb->init.region, &avblMem); + RLOG_ARG2(L_FATAL,DBG_RBID,rbCb->rlcId.rbId, + "Memory allocation failed UEID:%d CELLID:%d", + rbCb->rlcId.ueId, + rbCb->rlcId.cellId); + RETVOID; + } +#endif /* ERRCLASS & ERRCLS_RES */ + + /*Initialize DL segment structure */ + pduInfo->lstEnt.next = NULLP; + pduInfo->lstEnt.prev = NULLP; + pduInfo->lstEnt.node = NULLP; + + pduInfo->pdu = NULLP; + pduInfo->amHdr.dc = 0; + pduInfo->amHdr.p = 0; + pduInfo->amHdr.si = 0; + pduInfo->amHdr.so = 0; + + pduInfo->amHdr.sn = amDl->txNext; + + if (macGrntSz >= sdu->sduSz) + { + pdu = sdu->mBuf; + sdu->mBuf = NULLP; + /* Update Framing Info */ + if (sdu->mode.am.isSegmented) + { + /*5GNR RLC: SN should be same for all segment of a SDU*/ + pduInfo->amHdr.sn = sdu->mode.am.sn; + pduInfo->amHdr.si = KW_SI_LAST_SEG; /* binary 10 */ + pduInfo->amHdr.so = sdu->actSz - sdu->sduSz; + sdu->mode.am.isSegmented = FALSE; + + + gRlcStats.amRlcStats.numRlcAmCellSduTx++; + //printf("\n 5GNRLOG: last segment of lcId %d SduId %u So %u macGrntSz %u sduActSz %u sdu->sduSz %u\n", + // rbCb->lch.lChId, sdu->mode.am.sduId, pduInfo->amHdr.so, macGrntSz, sdu->actSz, sdu->sduSz); + } + else + { + gRlcStats.amRlcStats.numRlcAmCellSduTx++; + } + amHdr = &pduInfo->amHdr; + /* Create PDU with hdr and data */ + kwAmmCreatePdu(gCb,rbCb, amHdr, pduInfo, pdu); + + //printf("\n Segmentation not required case: numPdu %d pdu %p \n",kwDatReq->pduInfo.numPdu, pdu); + +#ifdef LTE_L2_MEAS_RLC + kwUtlUpdSduSnMap(rbCb, sdu, kwDatReq, TRUE); +#endif /* LTE_L2_MEAS */ + + /* kw005.201 ccpu00117318, updating the statistics */ + kwUtlIncrementKwuStsSduTx(gCb->u.dlCb->kwuDlSap + rbCb->kwuSapId); +#ifdef LTE_L2_MEAS + if(KW_MEAS_IS_DL_ANY_MEAS_ON_FOR_RB(gCb,rbCb)) + { + if(isSduSegmented) + { + *sduIdx = dlIpThPut->lastSduIdx; + } + else + { + KW_GETSDUIDX(*sduIdx); + newIdx = TRUE; + } + kwUtlUpdateContainedSduLst(*sduIdx, &contSduLst); + kwUtlUpdateOutStandingSduLst(dlIpThPut, *sduIdx, sdu->actSz, + sdu->mode.am.sduId, newIdx); + /* Update the arrival time for each SDU */ + /* ccpu00143043 */ + if ( lchInfo.numSdus < KW_L2MEAS_SDUIDX) + { + lchInfo.sduInfo[lchInfo.numSdus].arvlTime = sdu->arrTime; + lchInfo.numSdus++; + } + } +#endif + sduMap.sduSz = sdu->sduSz; + } + else + { + /* Segmentation + * Allocate buffer for next PDU + * Remove the segmented portion from SDUQ + * Calculate the hdr with LI for SDU */ + + Buffer *remSeg = NULLP; + + //printf("\n SDU segmentation case: numPdu %d pdu %p \n", kwDatReq->pduInfo.numPdu, pdu); +#ifdef LTE_L2_MEAS + if(KW_MEAS_IS_DL_IP_MEAS_ON_FOR_RB(gCb,rbCb) || + KW_MEAS_IS_DL_DELAY_MEAS_ON_FOR_RB(gCb,rbCb) || + KW_MEAS_IS_DL_UU_LOSS_MEAS_ON_FOR_RB(gCb,rbCb) ) + { + /* If actual size of the sdu is equal to msgLen + * then it is first segment of the SDU */ + if(sdu->actSz == sdu->sduSz) + { + KW_GETSDUIDX(*sduIdx); + newIdx = TRUE; + } + else + { + *sduIdx = dlIpThPut->lastSduIdx; + } + kwUtlUpdateContainedSduLst(*sduIdx, &contSduLst); + kwUtlUpdateOutStandingSduLst(dlIpThPut, *sduIdx, sdu->actSz, + sdu->mode.am.sduId, newIdx); + if(KW_MEAS_IS_DL_UU_LOSS_MEAS_ON_FOR_RB(gCb,rbCb)) + { + /* If actual size of the sdu is equal to msgLen + * then it is first segment of the SDU */ + if(sdu->actSz == sdu->sduSz) + { + segSduCnt++; + } + } + } +#endif + + /* Segment the SDU to the size of the PDU and update header Info */ + SSegMsg(sdu->mBuf, macGrntSz, &remSeg); + pdu = sdu->mBuf; + sdu->mBuf = remSeg; + + /* Update SI and SN */ + if (sdu->mode.am.isSegmented) + { + /*5GNR RLC: SN should be same for all segment of a SDU. + * Sdu was already segmented and segmenting again*/ + pduInfo->amHdr.sn = sdu->mode.am.sn; + pduInfo->amHdr.si = KW_SI_MID_SEG; /* binary 11 */ + pduInfo->amHdr.so = sdu->actSz - sdu->sduSz; + + //printf("\n 5GNRLOG: mid segment of lcId %d SduId %u So %u macGrntSz %u sduActSz %u sdu->sduSz %u\n", + // rbCb->lch.lChId, sdu->mode.am.sduId, txBuf->amHdr.so, macGrntSz, sdu->actSz, sdu->sduSz); + } + else + { + /*5GNR RLC: This means it is the first*/ + pduInfo->amHdr.si = KW_SI_FIRST_SEG; /* binary 01 */ + /*5GNR_RLC: Store SN so that in sub-seqent SDU segments will use this SN*/ + sdu->mode.am.sn = pduInfo->amHdr.sn; + pduInfo->amHdr.so = 0; + + //printf("\n 5GNRLOG: First segment of lcId %d SduId %u So %u macGrntSz %u sduActSz %u sdu->sduSz %u\n", + // rbCb->lch.lChId, sdu->mode.am.sduId, txBuf->amHdr.so, macGrntSz, sdu->actSz, sdu->sduSz); + } + + amHdr = &pduInfo->amHdr; + /* Create PDU with hdr and data */ + kwAmmCreatePdu(gCb,rbCb, amHdr, pduInfo, pdu); + + sdu->mode.am.isSegmented = TRUE; + sdu->sduSz -= macGrntSz; + sduMap.sduSz = macGrntSz; + +#ifdef LTE_L2_MEAS_RLC + kwUtlUpdSduSnMap(rbCb, sdu, kwDatReq, FALSE); +#endif /* LTE_L2_MEAS */ + + amDl->nxtTx = sdu; + nxtTxUpd = TRUE; + } + + /* Update bo for boReport */ + amDl->bo -= sduMap.sduSz; + + sduMap.sdu = sdu; + + /* Update pduInfo */ + kwDatReq->pduInfo.mBuf[kwDatReq->pduInfo.numPdu] = pdu; + kwDatReq->pduInfo.numPdu++; + numNewPdu++; + /* kw005.201 ccpu00117318, updating the statistics */ + gCb->genSts.pdusSent++; + gRlcStats.amRlcStats.numRlcAmCellSduBytesTx = gRlcStats.amRlcStats.numRlcAmCellSduBytesTx + sduMap.sduSz; + /* Update the RLC Tx buffer with the new PDU info */ + KW_MEM_CPY(&pduInfo->sduMap, &sduMap, sizeof(KwSduMap)); + pdu = NULLP; + + macGrntSz -= sduMap.sduSz; + /* Get next sdu for assembly */ + KW_LLIST_NEXT_SDU(amDl->sduQ, sdu); + + } /*End of pduSz loop */ + + kwDatReq->pduSz = macGrntSz; + /* Updating nxtTx to sdu in the Q */ + if (!nxtTxUpd) + amDl->nxtTx = sdu; + +#ifdef LTE_L2_MEAS + if(KW_MEAS_IS_DL_ANY_MEAS_ON_FOR_RB(gCb,rbCb) && + (rbCb->rlcId.rbType == CM_LTE_DRB)) + { + numSdus = 0; + currSduIdx = 0; + l2MeasTb = kwUtlGetCurMeasTb(gCb, rbCb); + kwUtlUpdateBurstSdus(gCb, rbCb, &contSduLst, dataVol, *totMacGrant); + if ((lchInfo.numSdus != 0) && (l2MeasTb != NULLP)) + { + for (lchIdx = 0; ((lchIdx < l2MeasTb->numLchInfo) + && (lchIdx < KW_MAX_ACTV_DRB )); lchIdx++) + { + if (l2MeasTb->lchInfo[lchIdx].lcId == rbCb->lch.lChId) + { + /* Lch Info already added in Retx procedure */ + break; + } + } + if (lchIdx < KW_MAX_ACTV_DRB) + { + if (lchIdx == l2MeasTb->numLchInfo) + { + l2MeasTb->lchInfo[lchIdx].lcId = rbCb->lch.lChId; + l2MeasTb->lchInfo[lchIdx].numSdus = 0; + l2MeasTb->numLchInfo++; + } + dstLchInfo = &l2MeasTb->lchInfo[lchIdx]; + currSduIdx = l2MeasTb->lchInfo[lchIdx].numSdus; + while ((numSdus < lchInfo.numSdus) && (currSduIdx < KW_L2MEAS_SDUIDX)) + { + dstLchInfo->sduInfo[currSduIdx].arvlTime = lchInfo.sduInfo[numSdus].arvlTime; + dstLchInfo->sduInfo[currSduIdx].isRetxPdu = FALSE; + numSdus++; + currSduIdx++; + } + l2MeasTb->lchInfo[lchIdx].numSdus += numSdus; + } + } + /* Fix Klock warning */ + if(l2MeasTb != NULLP) + { + l2MeasTb->txSegSduCnt += segSduCnt; + } + } + *totMacGrant -= (oldBo - amDl->bo); +#endif + + if(discSduInfo->numSduIds != 0) + { + /* Sap control block */ + KwUiKwuDiscSduCfm(&kwuSap->pst, kwuSap->suId, discSduInfo); + } + else + { + KW_SHRABL_STATIC_BUF_FREE(kwuSap->pst.region, kwuSap->pst.pool, discSduInfo, sizeof(KwuDiscSduInfo)); + } + + +#ifndef ALIGN_64BIT + RLOG_ARG3(L_UNUSED,DBG_RBID,rbCb->rlcId.rbId, + "kwAssembleSdus: BO after assembly = %ld UEID:%d CELLID:%d", + amDl->bo, + rbCb->rlcId.ueId, + rbCb->rlcId.cellId); +#else + RLOG_ARG3(L_UNUSED,DBG_RBID,rbCb->rlcId.rbId, + "kwAssembleSdus: BO after assembly = %d UEID:%d CELLID:%d", + amDl->bo, + rbCb->rlcId.ueId, + rbCb->rlcId.cellId); +#endif + + RETVOID; +} + +/** + * @brief Private handler to check if the poll bit needs to be set for data PDU + * + * @details + * Its a private function called by kwProcessSdus, to checks if the + * polling bit needs to be set for any RLC data PDU and updates the + * same. + * - For the new PDUs, if the counters exceed the configured + * pduWoPoll/byteWoPoll values, return poll bit. + * - For the PDUs/portion of PDUs, if the SDU list / retxBuf is + * empty, return poll bit. + * - Update the pollPdu, pollByte counters and Poll_SN; start staProhTmr + * + * @param[in] rCb RLC instance control block + * @param[in] rbCb RB control block + * @param[in] newPdu Flag to indicate if its a new AMD PDU. + * @param[in] bufSz Length of the PDU + * + * @return Bool + * -# 1 - To set the poll bit + * -# 0 - Poll bit is not set + * + */ +#ifdef ANSI +PRIVATE Bool kwAmmDlCheckAndSetPoll +( +KwCb *gCb, +KwDlRbCb *rbCb, +Bool newPdu, +MsgLen bufSz +) +#else +PRIVATE Bool kwAmmDlCheckAndSetPoll(gCb, rbCb, newPdu, bufSz) +KwCb *gCb; +KwDlRbCb *rbCb; +Bool newPdu; +MsgLen bufSz; +#endif +{ + Bool pollBit = FALSE; + KwAmDl *amDl = &(rbCb->m.amDl); + + TRC2(kwAmmDlCheckAndSetPoll) + + + /* If it's a new PDU increment PDU without poll and bytes without poll + and check if they cross the configured number of poll pdu and poll bytes*/ + if (newPdu) + { + amDl->pduWoPoll++; + /* Patch kw004.201 */ + amDl->byteWoPoll += bufSz; + + if (((amDl->pollPdu != -1) && (amDl->pduWoPoll >= amDl->pollPdu)) || + ((amDl->pollByte != -1) && (amDl->byteWoPoll >= amDl->pollByte))) + { + pollBit = TRUE; + } + } + + /* Check if both tx/retx buffer are empty or if tx window is stalled */ + if (((amDl->nxtTx == NULLP) && (amDl->nxtRetx == NULLP)) || + KW_AM_IS_TRANS_WIN_STALLED(amDl)) + { + pollBit = TRUE; + } + + if (pollBit) + { + amDl->pduWoPoll = 0; + amDl->byteWoPoll = 0; + + amDl->pollSn = (amDl->txNext - 1) & amDl->snModMask; + + RLOG_ARG3(L_UNUSED,DBG_RBID,rbCb->rlcId.rbId, + "kwAmmDlCheckAndSetPoll: Poll SN = %d UEID:%d CELLID:%d", + amDl->pollSn, + rbCb->rlcId.ueId, + rbCb->rlcId.cellId); + + /* kw005.201: Fix for poll retransmission timer. + * Timer is stopped if it is already running and + * then starting the timer. Fixes crs + * ccpu00117216 and ccpu00118284 . + * */ + if( TRUE == kwChkTmr(gCb,(PTR)rbCb,KW_EVT_AMDL_POLL_RETX_TMR) ) + { + kwStopTmr(gCb,(PTR)rbCb, KW_EVT_AMDL_POLL_RETX_TMR); + } + + kwStartTmr(gCb,(PTR)rbCb, KW_EVT_AMDL_POLL_RETX_TMR); + } + + RETVALUE(pollBit); +} + +/** + * @brief Private handler to create AMD PDU + * + * @details + * This function constructs header and concatenate it with the data for + * the PDU. It also updates the txBuf with the created PDU. + * + * @param[in] gCB RLC instance control block + * @param[in] rbCb Downlink RB control block + * @param[in] amHdr AM header + * @param[in] KwDlPduInfo Pointer to PduInfo + * @param[in] pdu PDU buffer + * + * @return Void + * + */ +#ifdef ANSI +PRIVATE Void kwAmmCreatePdu +( +KwCb *gCb, +KwDlRbCb *rbCb, +KwAmHdr *amHdr, +KwDlPduInfo *pduInfo, +Buffer *pdu +) +#else +PRIVATE Void kwAmmCreatePdu(gCb, rbCb, pduInfo, amHdr, pdu) +KwCb *gCb; +KwDlRbCb *rbCb; +KwAmHdr *amHdr; +KwDlPduInfo *pduInfo; +Buffer *pdu; +#endif +{ + U8 hdr[KW_MAX_HDRSZ]; + U16 idx; + KwTx *txBuf; + MsgLen pduSz; + KwAmDl *amDl = &(rbCb->m.amDl); + + TRC2(kwAmmCreatePdu) + + + /* Update sn */ + amHdr->sn = amDl->txNext; + + /*5GNR RLC: Increment txNext only if no segmentation of it is a last segment */ + if((!amHdr->si) || (amHdr->si == KW_SI_LAST_SEG)) + { + //printf("\n 5GNRLOG: no segment/last seg SDU with lcId %d Sn %u txNext %u So %u\n", + // rbCb->lch.lChId, amHdr->sn, amDl->txNext, amHdr->so); + amDl->txNext = (amDl->txNext + 1) & amDl->snModMask; + } + + /* Update hdr Info */ + SFndLenMsg(pdu, &pduSz); + + /* passing newPDU = TRUE*/ + amHdr->p = kwAmmDlCheckAndSetPoll(gCb,rbCb, TRUE, pduSz); + + /* Construct header with the available hdr Info, set isSegment to FALSE */ + kwConstructAmHdr(amHdr, hdr, amDl->snLen, &idx); + + /* Concatenate hdr and data */ + SAddPreMsgMultInOrder(hdr, idx+1, pdu); + + txBuf = kwUtlGetTxBuf(amDl->txBufLst, amHdr->sn); + kwCpyMsg(gCb,pdu,&(pduInfo->pdu)); + pduInfo->pduSz = pduSz; + pduInfo->hdrSz = idx+1; + + /*Update estHdrSz. deduct current hdrSz */ + amDl->estHdrSz -= pduInfo->hdrSz; + /* Reestimate estHdrSz for mid and last seg */ + if(amHdr->si & 0x1) + { + amDl->estHdrSz += ((amHdr->si == KW_SI_MID_SEG)? pduInfo->hdrSz : (pduInfo->hdrSz + 2)); + } + + cmLListAdd2Tail(&txBuf->pduLst, &pduInfo->lstEnt); + pduInfo->lstEnt.node = (PTR)pduInfo; + + gCb->genSts.bytesSent += pduSz; + + RETVOID; +} + +/** + * @brief Private handler to remove the retx PDU from the rbCb + * + * @details + * This function releases a retx PDU stored on DL portion of rbCb. + * It also updates the BO if wtForAck flag is not set which implies + * that it is not sent out yet. + * + * @param[in] gCb RLC instance control block + * @param[in] retx retransmit PDU to be removed + * @param[in] rbCb Radio Bearer Control Block + * + * @return Void + * + */ +#ifdef ANSI +PRIVATE Void kwRemRetxPdu +( +KwCb *gCb, +KwDlRbCb *rbCb, +KwRetx *retx +) +#else +PRIVATE Void kwRemRetxPdu(gCb, rbCb, retx) +KwCb *gCb; +KwDlRbCb *rbCb; +KwRetx *retx; +#endif +{ + TRC2(kwRemRetxPdu) + + cmLListDelFrm(&AMDL.retxLst, &retx->lstEnt); + + if( AMDL.retxLst.count == 0) + { + AMDL.nxtRetx = NULLP; + } + + if(retx->pendingReTrans == TRUE) + { + AMDL.retxBo -= retx->segSz; + AMDL.estHdrSz -= retx->hdrSz; + } + + kwUtlAddReTxPduToBeFreedQueue(gCb, retx); + kwUtlRaiseDlCleanupEvent(gCb); + + RETVOID; +} + +/** + * @brief Private handler to mark a retx PDU for further retransmission + * + * @details + * This function sets a retx PDU that has not been ACKed in the + * received Status PDU for futher retransmission. If the retransmission + * limit is reached, it releases the retx PDU and informs the higher + * layers about the same. + * + * @param[in] gCb RLC instance control block + * @param[in] retx retransmit PDU to be removed + * @param[in] rbCb Radio Bearer Control Block + * + * @return Void + * + */ +#ifdef ANSI +PRIVATE Void kwAmmDlMarkPduForReTx +( +KwCb *gCb, +KwDlRbCb *rbCb, +KwRetx *retx +) +#else +PRIVATE Void kwAmmDlMarkPduForReTx(*gCb, rbCb, retx) +KwCb *gCb; +KwDlRbCb *rbCb; +KwRetx *retx; +#endif +{ + TRC2(kwAmmDlMarkPduForReTx) + if (AMDL.maxReTxReached == TRUE) + { + RETVOID; + } + + if(retx->pendingReTrans == FALSE) + { + retx->pendingReTrans = TRUE; + ++retx->retxCnt; + + AMDL.retxBo += retx->segSz; + AMDL.estHdrSz += retx->hdrSz; + + if (retx->retxCnt > AMDL.maxRetx) + { + /* RLC_DL_MAX_RETX fix */ + /* Marking the RB stalled for DL scheduling. This is to avoid unnecessary */ + /* preparation of RLC PDUs and adding the same to Tx Buffer */ + /* This condition is to avoid sending StaIndication more than once */ + if (TRUE != rbCb->m.amDl.maxReTxReached) + { + rbCb->m.amDl.maxReTxReached = TRUE; + rbCb->m.amDl.bo = 0; + rbCb->m.amDl.cntrlBo = 0; + rbCb->m.amDl.retxBo = 0; + /* Sending BO update to SCH */ + kwUtlSndDStaRsp(gCb, rbCb, 0,0,0,0); + kwAmmSndStaInd(gCb, rbCb, retx); + gRlcStats.amRlcStats.numDLMaxRetx++; + } + + kwRemRetxPdu(gCb,rbCb, retx); + + RETVOID; + } + + + if (AMDL.nxtRetx == NULLP) + { + AMDL.nxtRetx = retx; + } + + gRlcStats.amRlcStats.numDLRetransPdus++; + } + + + RETVOID; +} + +/** + * @brief Private handler to check if SDU is completely deliverd and + * send higher layers data confirmation + * + * @details + * This function sends higher layers data confirmation for SDUs which + * have been successfully delivered to the peer RLC entity. + * + * @param[in] gCb RLC instance control block + * @param[in] rbCb Radio Bearer Control Block + * @param[in] sduLst List of SDUs that were part of the PDU + * @param[in] numSdu Number of SDUs in the list + * + * @return Void + * + */ +#ifdef ANSI +PRIVATE Void kwAmmDlCheckIsSDUDelivered +( +KwCb *gCb, +KwDlRbCb *rbCb, +KwSduMap *sduMap, +KwuDatCfmInfo **datCfm +) +#else +PRIVATE Void kwAmmDlCheckIsSDUDelivered(gCb, rbCb, sduMap, datCfm) +KwCb *gCb; +KwDlRbCb *rbCb; +KwSduMap *sduMap; +KwuDatCfmInfo **datCfm; +#endif +{ + KwSdu *sdu; + + TRC2(kwAmmDlCheckIsSDUDelivered) + + sdu = sduMap->sdu; + + sdu->mode.am.rcvdSz += sduMap->sduSz; + + /* send a dat cfm if all the bytes of the sdu have been received */ + if (sdu->mode.am.rcvdSz == sdu->actSz) + { + /* Send DatCfm for this sdu */ + if((*datCfm)->numSduIds < KWU_MAX_DAT_CFM) + { + (*datCfm)->sduIds[(*datCfm)->numSduIds++] = sdu->mode.am.sduId; + } + else + { + /* This is an error that should never happen, we should resize + * the #define to a larger value or check why we need to + * send so many confirms in one go + * Confrims to PDCP are being dropped in this case + */ + KwKwuSapCb *kwuSap; + kwuSap = gCb->u.dlCb->kwuDlSap + KW_UI_PDCP; + KwUiKwuDatCfm(&kwuSap->pst, kwuSap->suId, *datCfm); + + KW_SHRABL_STATIC_BUF_ALLOC(kwuSap->pst.region, kwuSap->pst.pool, *datCfm, sizeof(KwuDatCfmInfo)); + +#if (ERRCLASS & ERRCLS_ADD_RES) + if (*datCfm == NULLP) + { + RLOG_ARG2(L_FATAL,DBG_RBID,rbCb->rlcId.rbId, + "Memory allocation failed UEID:%d CELLID:%d", + rbCb->rlcId.ueId, + rbCb->rlcId.cellId); + RETVOID; + } +#endif /* ERRCLASS & ERRCLS_RES */ + + (*datCfm)->numSduIds = 0; + (*datCfm)->rlcId = rbCb->rlcId; + /* ccpu00135618: say total 1026 sduIds to copy the 1025 sduId after + * new allocation of datCfm */ + (*datCfm)->sduIds[(*datCfm)->numSduIds++] = sdu->mode.am.sduId; + } + + /* Remove SDU from the sduQ */ + cmLListDelFrm(&AMDL.sduQ, &sdu->lstEnt); + kwUtlAddSduToBeFreedQueue(gCb, sdu); + kwUtlRaiseDlCleanupEvent(gCb); + } + + RETVOID; +} + +/** + * @brief Private handler to mark a PDU successful. + * + * @details + * This function is called when we receive a STATUS pdu that marks + * a PDU as successful. It releases the PDU from RLC entity and + * informs PDCP of successful SDUs delivered as a result of this PDU. + * + * @param[in] gCb RLC instance control block + * @param[in] rbCb Radio Bearer Control Block + * @param[in] sn SN that is successfully delivered to the peer + * + * @return Void + * + */ +#ifdef ANSI +PRIVATE Void kwAmmDlProcessSuccessfulTxPdu +( +KwCb *gCb, +KwDlRbCb *rbCb, +KwSn sn, +KwuDatCfmInfo **datCfm +) +#else +PRIVATE Void kwAmmDlProcessSuccessfulTxPdu(gCb, rbCb, sn, datCfm) +KwCb *gCb; +KwDlRbCb *rbCb; +KwSn sn; +KwuDatCfmInfo **datCfm; +#endif +{ + TRC2(kwAmmDlProcessSuccessfulTxPdu) + CmLList *pduNode; + + KwTx *txBuf = kwUtlGetTxBuf(AMDL.txBufLst, sn); + + if (txBuf == NULLP) + { + RETVOID; + } + pduNode = txBuf->pduLst.first; + while(pduNode) + { + KwDlPduInfo *pduInfo = (KwDlPduInfo *)(pduNode->node); + kwAmmDlCheckIsSDUDelivered(gCb, + rbCb, + &(pduInfo->sduMap), + datCfm); + pduNode = pduNode->next; + } + + kwUtlAddTxPduToBeFreedQueue(gCb, txBuf); + kwUtlRaiseDlCleanupEvent(gCb); + /* so that it is not processed again */ + kwUtlRemovTxBuf(AMDL.txBufLst, txBuf, gCb); + + RETVOID; +} + +/** + * @brief Handler to send Status Indication to PDCP + * + * @details + * This function is used to send status indication to PDCP when the + * maximum retransmission threshold value is reached for a PDU. + * + * @param[in] gCb RLC instance control block + * @param[in] rbCb RB control block + * @param[in] retx The PDU/segment that failed max re-transmissions + * + * @return Void + * + */ +#ifdef ANSI +PRIVATE Void kwAmmSndStaInd +( +KwCb *gCb, +KwDlRbCb *rbCb, +KwRetx *retx +) +#else +PRIVATE Void kwAmmSndStaInd(gCb, rbCb, retx) +KwCb *gCb; +KwDlRbCb *rbCb; +KwRetx *retx; +#endif +{ + KwuStaIndInfo *staInd; + KwKwuSapCb *kwuSap; + + TRC2(kwAmmSndStaInd); + + + /* Sap control block */ + kwuSap = gCb->u.dlCb->kwuDlSap + KW_UI_PDCP; + + /* Allocate memory for staInd Info */ + KW_SHRABL_STATIC_BUF_ALLOC(kwuSap->pst.region, kwuSap->pst.pool, staInd, sizeof(KwuStaIndInfo)); + +#if (ERRCLASS & ERRCLS_ADD_RES) + if (staInd == NULLP) + { + RLOG_ARG2(L_FATAL,DBG_RBID,rbCb->rlcId.rbId, + "Memory allocation failed UEID:%d CELLID:%d", + rbCb->rlcId.ueId, + rbCb->rlcId.cellId); + RETVOID; + } +#endif /* ERRCLASS & ERRCLS_RES */ + + /* Fill staInd Info */ + KW_MEM_CPY(&staInd->rlcId, &rbCb->rlcId, sizeof(CmLteRlcId)); + + staInd->numSdu = 1; + staInd->sduId[0] = retx->sduMap.sdu->mode.am.sduId; + +#ifdef KW_PDCP +#else + KwUiKwuStaInd(&kwuSap->pst, kwuSap->suId, staInd); +#endif /* KW_PDCP */ + + RETVOID; +} + +/** + * @brief Handler to get the next node to be retransmitted from retxLst + * + * @details + * This function is used to get the next node to be retransmitted + * from the retxLst + * + * @param[in] gCb RLC instance control block + * @param[in] retx The PDU/segment after which to find a node to be + * retransmitted + * + * @return Void + * + */ +#ifdef ANSI +PRIVATE Void kwGetNxtRetx +( +KwCb *gCb, +KwRetx **retx +) +#else +PRIVATE Void kwGetNxtRetx(gCb, retx) +KwCb *gCb; +KwRetx **retx; +#endif +{ + CmLList *tNode; + + TRC2(kwGetNxtRetx); + + do + { + tNode = &((*retx)->lstEnt); + tNode = tNode->next; + + if (tNode) + { + *retx = (KwRetx *)tNode->node; + } + else + { + *retx = NULLP; + RETVOID; + } + }while((*retx)->pendingReTrans == FALSE); + + RETVOID; +} + +/** + * @brief Handler to process the re-establishment request received from UIM + * + * @param[in] gCb RLC instance control block + * @param[in] rlcId Identity of the RB in the UE/Cell for which + * re-establishment is to be done + * @param[in] rbCb Downlink RB control block (rbCb is freed in this + * function) + * + * @return Void + * + */ +#ifdef ANSI +PUBLIC Void kwAmmDlReEstablish +( +KwCb *gCb, +CmLteRlcId rlcId, +KwDlRbCb *rbCb +) +#else +PUBLIC Void kwAmmDlReEstablish(gCb, rlcId, rbCb) +KwCb *gCb; +CmLteRlcId rlcId; +KwDlRbCb *rbCb; +#endif +{ + /* create a new AM DL RB, reset it and replace in the UeCb*/ + KwDlUeCb *ueCb; + KwDlRbCb *resetRb; + KwAmDl* newAmDl; + KwAmDl* oldAmDl; + KW_ALLOC(gCb, resetRb, sizeof(KwDlRbCb)); + + /* ccpu00135170 Removing KLOCK warning */ + if(resetRb == NULLP) + { + RETVOID; + } + + KW_MEM_CPY(resetRb, rbCb, sizeof(KwDlRbCb)); + KW_MEM_SET(&resetRb->m.amDl, 0 , sizeof(KwAmDl)); + +/* AGHOSH changes start */ + /* restore the old AM values */ + newAmDl = &resetRb->m.amDl; + oldAmDl = &rbCb->m.amDl; + + newAmDl->pollPdu = oldAmDl->pollPdu; + newAmDl->pollByte = oldAmDl->pollByte; + newAmDl->maxRetx = oldAmDl->maxRetx; + newAmDl->snLen = oldAmDl->snLen; + newAmDl->snModMask = oldAmDl->snModMask; + newAmDl->pollRetxTmrInt = oldAmDl->pollRetxTmrInt; + rbCb->boUnRprtdCnt = (U32)0; + rbCb->lastRprtdBoToMac = (U32)0; + cmInitTimers(&(resetRb->m.amDl.pollRetxTmr), 1); +/* AGHOSH changes end */ + + if (ROK != kwDbmFetchDlUeCb(gCb,rlcId.ueId, rlcId.cellId, &ueCb)) + { + RLOG_ARG2(L_ERROR,DBG_CELLID, rlcId.cellId, + "UeId [%d]: UeCb not found RBID;%d", + rlcId.ueId, + rlcId.rbId); + RETVOID; + } + + if(rlcId.rbType == CM_LTE_SRB) + { + ueCb->srbCb[rlcId.rbId] = resetRb; + } + else + { + ueCb->drbCb[rlcId.rbId] = resetRb; + } + /* update into the logical channel array also */ + ueCb->lCh[rbCb->lch.lChId - 1].dlRbCb = resetRb; + + if((resetRb->rlcId.rbType == CM_LTE_SRB) + &&(resetRb->rlcId.rbId == 1)) + { + /* To stop the traffic on SRB2 and other DRBs*/ + kwDlUtlSetReestInProgressForAllRBs(gCb, ueCb); + } + else + { + kwDlUtlSetReestInProgressForRB(gCb, resetRb); + } + + /* allocate the TX array again */ +#ifndef LTE_TDD + U32 hashIndex; + KW_ALLOC(gCb, + resetRb->m.amDl.txBufLst, + (KW_TX_BUF_BIN_SIZE * sizeof(CmLListCp))); + for(hashIndex = 0; hashIndex < KW_TX_BUF_BIN_SIZE; hashIndex++) + { + cmLListInit(&(resetRb->m.amDl.txBufLst[hashIndex])); + } +#endif + /* send the old rb of deletion */ + kwAmmFreeDlRbCb(gCb,rbCb); + + + /* TODO: for now we are re-settting the re-establishment flag here + this needs to be fixed + There should be a proper intreface to resume the RBs */ + if(rlcId.rbType == CM_LTE_SRB) + { + kwDlUtlResetReestInProgress(ueCb->srbCb[rlcId.rbId]); + } + else + { + kwDlUtlResetReestInProgress(ueCb->drbCb[rlcId.rbId]); + } + + RETVOID; +} + +/** + * @brief Handler to discard a SDU. + * + * @details + * This function is used to discard a SDU after receiving + * the Discard Request from UIM. The SDU is discarded if its + * available and is not mapped to any PDU yet. + * + * @param[in] gCb RLC instance control block + * @param[in] rbCb RB control block + * @param[in] sduId Sdu ID of the SDU to be discarded + * + * @return S16 + * -# ROK In case of successful discard + * -# RFAILED In case the SDU is not found or already mapped + */ +#ifdef ANSI +PUBLIC S16 kwAmmDiscSdu +( +KwCb *gCb, +KwDlRbCb *rbCb, +U32 sduId +) +#else +PUBLIC S16 kwAmmDiscSdu(gCb, rbCb, sduId) +KwCb *gCb; +KwDlRbCb *rbCb; +U32 sduId; +#endif +{ + TRC2(kwAmmDiscSdu); + RETVALUE(RFAILED); +} + +/** + * @brief Handler for Poll retransmit timer expiry + * + * @details + * This function is used to handle events upon expiry of Poll + * retransmit timer. + * + * @param[in] gCb RLC instance control block + * @param[in] rbCb Downlink RB control block + * + * @return Void + */ +#ifdef ANSI +PUBLIC Void kwAmmPollRetxTmrExp +( +KwCb *gCb, +KwDlRbCb *rbCb +) +#else +PUBLIC Void kwAmmPollRetxTmrExp(gCb, rbCb) +KwCb *gCb; +KwDlRbCb *rbCb; +#endif +{ + KwRetx *retx; + KwAmDl *amDl = &(rbCb->m.amDl); + KwSn sn; + KwTx *txBuf; + TRC2(kwAmmPollRetxTmrExp); + + + /* kw003.201 - Correcting the logic for determmining whether to do */ + /* any transmission of PDU. As per the spec section */ + /* 5.2.2.3, if there is any to transmit or retransmit, */ + /* do nothing. Else, pick up the VT(S) -1 for retx */ + /* We have nothing to transmit if window is stalled or */ + /* there are no SDUs to be transmitted or if there are */ + /* PDUs to be retransmitted. */ + if(CM_LTE_SRB == rbCb->rlcId.rbType) + { + gRlcStats.amRlcStats.numDLPollTimerExpiresSrb++; + } + else + { + gRlcStats.amRlcStats.numDLPollTimerExpiresDrb++; + } + + if (((amDl->nxtTx == NULLP) && (amDl->nxtRetx == NULLP)) || + KW_AM_IS_TRANS_WIN_STALLED(amDl)) + { + sn = (amDl->txNext - 1) & amDl->snModMask; + txBuf = kwUtlGetTxBuf(amDl->txBufLst, sn); + + if (txBuf != NULLP) + { + kwAmmDlMoveFrmTxtoRetxBuffer(gCb,amDl, &retx, sn); + + if (AMDL.nxtRetx == NULLP) + { + AMDL.nxtRetx = retx; + } + + kwAmmSendDStaRsp(gCb, rbCb, &AMDL); + RETVOID; + } + /* Get the last node in retxLst */ + KW_LLIST_LAST_RETX(amDl->retxLst, retx); + + /* Unset wtForAck flag for the NACK PDUs */ + if (retx != NULLP) + { + kwAmmDlMarkPduForReTx(gCb, rbCb, retx); + kwAmmSendDStaRsp(gCb, rbCb, &AMDL); + } + } + + RETVOID; +} + +/** + * @brief Handler to update Acks for the remaining PDUs after the last accessed + * NACK PDU. + * + * @details + * This function is used to handle ACKs for the PDUs remaining after the + * last accessed NACK PDU, It updates the txBuf/retxBuf for the ACKs and + * sends DatCfm to PDCP for the same. + * + * @param[in] gCb RLC instance control block + * @param[in] rbCb Downlink Radio Bearer control block + * @param[in] mAckSn The ACK SN after doing the base modulus + * @param[in] rextNode Next node in the re-transmission buffer + * + * @return Void + * + */ + +#ifdef ANSI +PRIVATE Void kwAmmDlUpdateTxAndReTxBufForAckSn +( +KwCb *gCb, +KwDlRbCb *rbCb, +KwSn mAckSn, +CmLList *retxNode, +KwuDatCfmInfo **datCfm +) +#else +PRIVATE Void kwAmmDlUpdateTxAndReTxBufForAckSn(gCb, rbCb, mAckSn, retxNode, datCfm) +KwCb *gCb; +KwDlRbCb *rbCb; +KwSn mAckSn; +CmLList *retxNode; +KwuDatCfmInfo **datCfm; +#endif +{ + KwSn mSn; + KwSn sn; + KwRetx *retx; + KwTx *txBuf; + + TRC2(kwAmmDlUpdateTxAndReTxBufForAckSn); + + /* Remove pdus/segs from retxLst */ + while (retxNode) + { + retx = (KwRetx *)(retxNode->node); + retxNode = retxNode->next; + MODAMT(retx->amHdr.sn, mSn, AMDL.txNextAck,AMDL.snModMask); + if (mSn < mAckSn) + { + kwAmmDlProcessSuccessfulReTx(gCb,rbCb, retx, datCfm); + } + } + + /* For the remaining; pdus not acknowldeged by the NACK_SN but being + acknowledged by the ACK_SN*/ + /* start from the starting of the transmission window and remove till just + before ACK_SN*/ + mSn = 0; /* same as MODAMT(AMDL.txNextAck, mSn, AMDL.txNextAck);*/ + sn = AMDL.txNextAck; + while(mSn < mAckSn) + { + txBuf = kwUtlGetTxBuf(AMDL.txBufLst, sn); + if (txBuf != NULLP) + { + RLOG_ARG3(L_UNUSED,DBG_RBID,rbCb->rlcId.rbId, + "kwAmmDlUpdateTxAndReTxBufForAckSn: ACK for PDU " + "with sn = %ld UEID:%ld CELLID:%ld", + sn, + rbCb->rlcId.ueId, + rbCb->rlcId.cellId); + + kwAmmDlProcessSuccessfulTxPdu(gCb,rbCb, sn, datCfm); + } + + sn = (sn + 1) & AMDL.snModMask; + MODAMT(sn, mSn, AMDL.txNextAck,AMDL.snModMask); + } + + RETVOID; +} + +/** + * @brief Handler to update Acks for the remaining PDUs after the last accessed + * NACK PDU. + * + * @details + * This function is used to handle ACKs for the PDUs remaining after the + * last accessed NACK PDU, It updates the txBuf/retxBuf for the ACKs and + * sends DatCfm to PDCP for the same. + * + * @param[in] gCb RLC instance control block + * @param[in] rbCb Downlink Radio Bearer control block + * @param[in] mAckSn The ACK SN after doing the base modulus + * @param[in] rextNode Next node in the re-transmission buffer + * + * @return Void + * + */ +#ifdef ANSI +PRIVATE Void kwAmmDlUpdTxAndReTxBufForLessThanNackSn +( +KwCb *gCb, +KwDlRbCb *rbCb, +KwSn sn, +KwSn mNackSn, +CmLList **retxNode, +KwuDatCfmInfo **datCfm +) +#else +PRIVATE Void kwAmmDlUpdTxAndReTxBufForLessThanNackSn(gCb, rbCb, sn, mNackSn, retxNode, datCfm) +KwCb *gCb; +KwDlRbCb *rbCb; +KwSn sn; +KwSn mNackSn; +CmLList **retxNode; +KwuDatCfmInfo **datCfm; +#endif +{ + KwSn mSn; + KwRetx *retx; + KwTx *txBuf=NULLP; + + TRC2(kwAmmDlUpdTxAndReTxBufForLessThanNackSn); + + while (*retxNode) + { + retx = (KwRetx *)((*retxNode)->node); + MODAMT(retx->amHdr.sn, mSn, AMDL.txNextAck,AMDL.snModMask); + if (mSn < mNackSn) + { + (*retxNode) = (*retxNode)->next; + kwAmmDlProcessSuccessfulReTx(gCb,rbCb, retx, datCfm); + } + else + { + break; + } + } + + /* Remove all pdus with SN < NACK_SN from the transmission buffer */ + MODAMT(sn, mSn, AMDL.txNextAck,AMDL.snModMask); + while (mSn < mNackSn) + { + /* this if check seems redundant,why should mSn ever be mTxSn + (which actually is VT(A) */ + txBuf = kwUtlGetTxBuf(AMDL.txBufLst, sn); + if ((txBuf != NULLP)) + { + RLOG_ARG3(L_DEBUG,DBG_RBID, rbCb->rlcId.rbId, + "kwHndlStaRsp: Handle ACK (sn = %d) UEID:%d CELLID:%d", + sn, + rbCb->rlcId.ueId, + rbCb->rlcId.cellId); + + /* Remove pdus from txBuf */ + kwAmmDlProcessSuccessfulTxPdu(gCb,rbCb, sn, datCfm); + } + + sn = (sn + 1) & AMDL.snModMask; + MODAMT(sn, mSn, AMDL.txNextAck,AMDL.snModMask); + } + + RETVOID; +} + + +/** + * @brief Handler to form construct AM header + * + * @details + * This function is used to construct am header with the available header + * elements. + * + * @param[in] gCb RLC instance control block + * @param[in] amHdr AM Header + * @param[in] isSeg Check for Segmentation of PDU + * @param[in] hdr Header field + * @param[in] idx Index + * + * @return Void + * + */ +#ifdef ANSI +PRIVATE Void kwConstructAmHdr +( +KwAmHdr *amHdr, +U8 *hdr, +U8 snLen, +U16 *idx +) +#else +PRIVATE Void kwConstructAmHdr(amHdr, hdr, snLen, idx) +KwAmHdr *amHdr; +U8 *hdr; +U8 snLen; +U16 *idx; +#endif +{ + TRC2(kwConstructAmHdr); + + *idx = 0; + hdr[0] = KW_DATA_BITMASK; + + hdr[0] = hdr[0] | (amHdr->p << 6); + hdr[0] = hdr[0] | ((amHdr->si & 0x3) << 4); + if(snLen == KW_AM_CFG_12BIT_SN_LEN) + { + hdr[0] = hdr[0] | (U8)((amHdr->sn & 0xF00) >> 8); + hdr[1] = (U8)(amHdr->sn & 0x0FF); + (*idx)++; + } + else + { + hdr[0] = hdr[0] | (U8)((amHdr->sn & 0x30000) >> 16); + hdr[1] = (U8)((amHdr->sn & 0xFF00) >> 8); + (*idx)++; + hdr[2] = (U8)(amHdr->sn & 0xFF); + (*idx)++; + } + + if ((amHdr->si == KW_SI_MID_SEG) || (amHdr->si == KW_SI_LAST_SEG)) + { + (*idx)++; + hdr[(*idx)] = (U8)((amHdr->so & 0xFF00)>> 8); + (*idx)++; + hdr[(*idx)] = (U8)(amHdr->so & 0xFF); + } + + RETVOID; +} + +/** + * @brief This function adds a retx PDU to list of retx PDUs + * + * @details + * kw003.201 - Poll expiry may cause an SN to be added to retx + * out of sequence and hence all additions to retx + * must validate that they are added in sequence + * + * @param[in] amDl AM Downlink Control Block + * @param[in] retx Retransmit PDU + * + * @return Void + * + */ +#ifdef ANSI +PRIVATE Void kwAmmAddPduToRetxLst +( +KwAmDl *amDl, +KwRetx *retx +) +#else +PRIVATE Void kwAmmAddPduToRetxLst(amDl, retx) +KwAmDl *amDl; +KwRetx *retx; +#endif +{ + CmLList *node; + KwRetx *tRetx; + KwSn tMSn; + KwSn retxMSn; + + TRC2(kwAmmAddPduToRetxLst); + + node = amDl->retxLst.last; + MODAMT(retx->amHdr.sn, retxMSn, amDl->txNextAck,amDl->snModMask); + while(node != NULLP) + { + tRetx = (KwRetx *)(node->node); + MODAMT(tRetx->amHdr.sn, tMSn, amDl->txNextAck,amDl->snModMask); + if (tMSn > retxMSn) + { + node = node->prev; + } + else + { + break; + } + } + if (node) + { + amDl->retxLst.crnt = node; + cmLListInsAfterCrnt(&amDl->retxLst, &retx->lstEnt); + retx->lstEnt.node = (PTR)retx; + } + else + { + amDl->retxLst.crnt = amDl->retxLst.first; + cmLListInsCrnt(&amDl->retxLst, &retx->lstEnt); + retx->lstEnt.node = (PTR)retx; + } + + if (amDl->nxtRetx == NULLP) + { + amDl->nxtRetx = retx; + } + + RETVOID; +} + +/** + * @brief Handler to Move the PDU from txBuf to re-transmission buffer + * + * @details + * This function is used to move the PDU from the txBuf to re-transmit buffer + * + * @param[in] gCb RLC instance control block + * @param[in] amDl AM Downlink Control Block + * @param[in] retx node in the reTx buffer to be moved to, allocated by + * this function + * @param[in] sn SN in the tx buffer which needs to be moved + * + * @return Void + * + */ + +#ifdef ANSI +PRIVATE Void kwAmmDlMoveFrmTxtoRetxBuffer +( +KwCb *gCb, +KwAmDl *amDl, +KwRetx **retx, +KwSn sn +) +#else +PRIVATE Void kwAmmDlMoveFrmTxtoRetxBuffer(gCb, amDl, retx, sn) +KwCb *gCb; +KwAmDl *amDl; +KwRetx **retx; +KwSn sn; +#endif +{ + KwTx* txBuf = kwUtlGetTxBuf(amDl->txBufLst, sn); + TRC2(kwAmmDlMoveFrmTxtoRetxBuffer); + + if (txBuf == NULLP) + { + RETVOID; + } + while(txBuf->pduLst.first) + { + KwDlPduInfo *pduInfo = (KwDlPduInfo *)(txBuf->pduLst.first->node); + KW_ALLOC_WC(gCb,*retx, sizeof(KwRetx)); + +#if (ERRCLASS & ERRCLS_ADD_RES) + if (*retx == NULLP) + { + RLOG0(L_FATAL, "Memory allocation failed"); + RETVOID; + } +#endif /* ERRCLASS & ERRCLS_RES */ + + /* Move Sdu byte segment from TX buf to retx buf*/ + kwAmmDlMoveSduByteSegFrmTxtoRetxBuffer(gCb, + amDl, + retx, + pduInfo); + + /* Delete node from the txBuf Pdu lst */ + cmLListDelFrm(&txBuf->pduLst, txBuf->pduLst.first); + KW_FREE_WC(gCb, pduInfo, sizeof(KwDlPduInfo)); + } + /* Remove PDU from txBuf */ + kwUtlDelTxBuf(amDl->txBufLst, txBuf,gCb); + + RETVOID; +} + + + +/* + * @brief + * function to free/release the Acknowledged mode RBCB buffers + * + * @details + * This primitive Frees the Acknowledged Mode RbCb transmission Buffer, + * retransmission Buffer and reciption Buffers + * + * @param [in] gCb - RLC instance control block + * @param [in] rbCb - Downlink RB Control Block + * + * @return Void + */ +#ifdef ANSI +PUBLIC Void kwAmmFreeDlRbCb +( +KwCb *gCb, +KwDlRbCb *rbCb +) +#else +PUBLIC Void kwAmmFreeDlRbCb(gCb,rbCb) +KwCb *gCb; +KwDlRbCb *rbCb; +#endif +{ + /* stop the re-transmission timer */ + if(TRUE == kwChkTmr(gCb,(PTR)rbCb,KW_EVT_AMDL_POLL_RETX_TMR)) + { + kwStopTmr(gCb,(PTR)rbCb, KW_EVT_AMDL_POLL_RETX_TMR); + } + + /* store the entire Rb pointer */ + rbCb->rlsLnk.node = (PTR)rbCb; + cmLListAdd2Tail(&gCb->u.dlCb->toBeFreed.rbLst, &rbCb->rlsLnk); + + /* the sdu queue */ + cmLListCatLList(&(gCb->u.dlCb->toBeFreed.sduLst),&(rbCb->m.amDl.sduQ)); + + kwUtlRaiseDlCleanupEvent(gCb); + + RETVOID; +} + +/** + * @brief Handler to create STATUS Pdu + * + * @details + * This function is used to create status pdu + * + * @param[in] gCb RLC instance control block + * @param[in] rbCb Downlink RB control block + * @param[in] kwDatReq The data to be passed to MAC + * + * @return Void + * + */ +#ifdef ANSI +PRIVATE Void kwAmmCreateStatusPdu +( +KwCb *gCb, +KwDlRbCb *rbCb, +KwDatReq *kwDatReq +) +#else +PRIVATE Void kwAmmCreateStatusPdu(gCb, rbCb, kwDatReq) +KwCb *gCb; +KwDlRbCb *rbCb; +KwDatReq *kwDatReq; +#endif +{ + KwSn sn; /* sequence number */ + KwSn ack_sn; /* Ack sequence number */ + Buffer *mBuf; /* control pdu buffer */ + MsgLen cntrlPduSz; /* control pdu size */ + U8 cntrlPdu[KW_MAX_CNTRL_FIELDS]; /* control pdu to be added to mBuf */ + KwUdxDlStaPdu *pStaPdu; + U16 bytesToEncode = 0; /* bytes required to encode the STATUS PDU */ + U16 encIdx = 0; + U16 prevEncIdx = 0; + KwNackInfo *kwNackInfo; + U16 nkCnt = 0; + + TRC2(kwAmmCreateStatusPdu) + + + pStaPdu = AMDL.pStaPdu; + + + /* D/C| CPT| */ + /* 0 - Control + 1 - Data */ + cntrlPdu[0] = 0x00; + cntrlPdu[2] = 0x00; + + /* ACK SN Field will be set in the end based on available Grant */ + + encIdx = bytesToEncode = 3; /* Num Octets before NACK SN info encoding*/ + + ack_sn = pStaPdu->ackSn; + + if (rbCb->m.amDl.snLen == KW_AM_CFG_12BIT_SN_LEN) + { + + /* If alteast one NACK SN Info then set the E1 field */ + if (pStaPdu->nackCount) + { + /* 12 BIT SN CASE: + In Third Octet: + 7 6 5 4 3 2 1 0 + E1 R R R R R R R + */ + cntrlPdu[2] = 0x80; + } + + for(nkCnt = 0;nkCnt < pStaPdu->nackCount; nkCnt++) + { + sn = pStaPdu->nackInfo[nkCnt].sn; + + kwNackInfo = &(pStaPdu->nackInfo[nkCnt]); + + bytesToEncode += 2; /* 2 Octets for NACK SN */ + + /* Check if E2 : isSegment is set */ + if (kwNackInfo->isSegment) + { + bytesToEncode += 4; /* 4 Octets: SOstart, SOend */ + } + + /* Check if E3 : nackRange is set */ + if (kwNackInfo->nackRange) + { + bytesToEncode += 1; /* 1 Octet: NACK range */ + } + + /* Check if this NACK info can be accomodated in the Grant */ + if( kwDatReq->pduSz >= bytesToEncode) + { + /* If there is a NACK SN before this then set its + E1 bit */ + if(prevEncIdx) + { + /* NACKSN E1 E2 E3 R */ + cntrlPdu[prevEncIdx + 1] |= 0x8; + } + + /* 12 BIT Nack SN encode */ + cntrlPdu[encIdx] = (sn & 0xFF0) >> 4; + + /* Next Octet */ + cntrlPdu[encIdx + 1] = (sn & 0xF) << 4; + + if (kwNackInfo->isSegment) + { + /*Set E2 Bit */ + cntrlPdu[encIdx + 1] |= 0x4; + + + /* Add soStart and soEnd */ + /* SOstart */ + cntrlPdu[encIdx + 2] = (kwNackInfo->soStart) >> 8; + cntrlPdu[encIdx + 3] = kwNackInfo->soStart & 0xFF; + + /* SOend */ + cntrlPdu[encIdx + 4] = (kwNackInfo->soEnd) >> 8; + cntrlPdu[encIdx + 5] = kwNackInfo->soEnd & 0xFF; + } + + if (kwNackInfo->nackRange) + { + /*Set E3 Bit */ + cntrlPdu[encIdx + 1] |= 0x2; + if(kwNackInfo->isSegment) + { + cntrlPdu[encIdx + 6] = kwNackInfo->nackRange; + } + else + { + cntrlPdu[encIdx + 2] = kwNackInfo->nackRange; + } + } + + gRlcStats.amRlcStats.numDLNacksInStaPdu++; + } + /* Set ACK SN now */ + else + { + ack_sn = kwNackInfo->sn; + + /* Not even one nack can be accomodated */ + if (nkCnt == 0) + { + cntrlPdu[2] = 0x0; + } + + break; + } + + prevEncIdx = encIdx; + encIdx = bytesToEncode; + + }/* Loop is done for the NackCount */ + + /* set ACK SN */ + { + + RLOG_ARG3(L_UNUSED,DBG_RBID,rbCb->rlcId.rbId, + "kwAssembleCntrlInfo: ACK PDU's SN = %d" + "UEID:%d CELLID:%d", + ack_sn, + rbCb->rlcId.ueId, + rbCb->rlcId.cellId); + + cntrlPdu[0] |= (ack_sn & 0xF00)>> 8; + cntrlPdu[1] = (U8)ack_sn; + } + + } + else if (rbCb->m.amDl.snLen == KW_AM_CFG_18BIT_SN_LEN) + { + /* If alteast one NACK SN Info then set the E1 field */ + if (pStaPdu->nackCount) + { + /* 12 BIT SN CASE: + In Third Octet: + 7 6 5 4 3 2 1 0 + ACKSN E1 R + */ + cntrlPdu[2] = 0x2; + } + + for(nkCnt = 0;nkCnt < pStaPdu->nackCount; nkCnt++) + { + sn = pStaPdu->nackInfo[nkCnt].sn; + + kwNackInfo = &(pStaPdu->nackInfo[nkCnt]); + + bytesToEncode += 3; /* 3 Octets for NACK SN */ + + /* Check if E2 : isSegment is set */ + if (kwNackInfo->isSegment) + { + bytesToEncode += 4; /* 4 Octets: SOstart, SOend */ + } + + /* Check if E3 : nackRange is set */ + if (kwNackInfo->nackRange) + { + bytesToEncode += 1; /* 1 Octet: NACK range */ + } + + /* Check if this NACK info can be accomodated in the Grant */ + if( kwDatReq->pduSz >= bytesToEncode) + { + /* If there is a NACK SN before this then set its + E1 bit */ + if(prevEncIdx) + { + /* NACKSN E1 E2 E3 R R R */ + cntrlPdu[prevEncIdx + 2] |= 0x20; + } + + /* 18 BIT Nack SN encode */ + cntrlPdu[encIdx] = (U8)((sn & 0x3FC00) >> 10); + + /* Next Octet */ + cntrlPdu[encIdx + 1] = (U8)((sn & 0x3FC) >> 2); + + /* Next Octet */ + cntrlPdu[encIdx + 2] = (U8)((sn & 0x3)<< 6); + + if (kwNackInfo->isSegment) + { + /* NACKSN E1 E2 E3 R R R */ + /*Set E2 Bit */ + cntrlPdu[encIdx + 2] |= 0x10; + + + /* Add soStart and soEnd */ + /* SOstart */ + cntrlPdu[encIdx + 3] = (kwNackInfo->soStart) >> 8; + cntrlPdu[encIdx + 4] = (U8)kwNackInfo->soStart; + + /* SOend */ + cntrlPdu[encIdx + 5] = (kwNackInfo->soEnd) >> 8; + cntrlPdu[encIdx + 6] = (U8)(kwNackInfo->soEnd); + } + + if (kwNackInfo->nackRange) + { + /* NACKSN E1 E2 E3 R R R */ + /*Set E3 Bit */ + cntrlPdu[encIdx + 2] |= 0x08; + + if (kwNackInfo->isSegment) + { + cntrlPdu[encIdx + 7] = kwNackInfo->nackRange; + } + else + { + cntrlPdu[encIdx + 3] = kwNackInfo->nackRange; + } + } + + gRlcStats.amRlcStats.numDLNacksInStaPdu++; + } + /* Set ACK SN now */ + else + { + ack_sn = kwNackInfo->sn; + + /* Not even one nack can be accomodated */ + if (nkCnt == 0) + { + cntrlPdu[2] &= 0xFD; + } + + break; + } + + prevEncIdx = encIdx; + encIdx = bytesToEncode; + + }/* Loop is done for the NackCount */ + + /* set ACK SN */ + { + + RLOG_ARG3(L_UNUSED,DBG_RBID,rbCb->rlcId.rbId, + "kwAssembleCntrlInfo: ACK PDU's SN = %d" + "UEID:%d CELLID:%d", + ack_sn, + rbCb->rlcId.ueId, + rbCb->rlcId.cellId); + + + cntrlPdu[0] |= (ack_sn & 0x3C000) >> 14; + cntrlPdu[1] = (ack_sn & 0x3FC0) >> 6; + cntrlPdu[2] |= (ack_sn & 0x3F)<< 2; + } + + } + else + { + /* ERROR Log */ + RLOG_ARG3(L_ERROR,DBG_RBID,rbCb->rlcId.rbId, + "kwAssembleCntrlInfo:Conf SN LEN %d is INVALID !!!! UEID:%d CELLID:%d", + rbCb->m.amDl.snLen, + rbCb->rlcId.ueId, + rbCb->rlcId.cellId); + } + + +#ifndef L2_OPTMZ + SGetMsg(KW_GET_MEM_REGION(gCb), KW_GET_MEM_POOL(gCb),&mBuf); +#else + mBuf = (Buffer *)kwAmmStaPduList[kwAmmStaPduListCnt++]; + SResetMBuf(mBuf); + if(kwAmmStaPduListCnt > 511) + kwAmmStaPduListCnt = 0; +#endif + + cntrlPduSz = encIdx; + SAddPstMsgMult (cntrlPdu, cntrlPduSz, mBuf); + + kwDatReq->pduSz -= cntrlPduSz; + /* Add mBuf to AMDL.mBuf */ + AMDL.mBuf = mBuf; + + RETVOID; +} + +#ifdef RLC_STA_PROC_IN_MAC/* RLC Status PDU Processing */ + +S16 kwProcDlStatusPdu(Pst *udxPst,SuId suId, + CmLteCellId cellId,CmLteRnti rnti,CmLteLcId lcId,Buffer *rlcSdu); + +#ifdef ANSI +PRIVATE Void rgAmmExtractElmnt +( +KwCb *gCb, +Buffer *pdu, +KwExtHdr *hdrInfo +) +#else +PRIVATE Void rgAmmExtractElmnt(gCb, pdu, hdrInfo) +KwCb *gCb; +Buffer *pdu; +KwExtHdr *hdrInfo; +#endif +{ + U8 hdr; + U8 pLen = hdrInfo->pLen; + U8 len = (U8)hdrInfo->len; + U16 val; + U8 tHdr; + U8 fLen; + U8 rLen; + /* U8 rLen1 = 0; */ + U16 tVal; + + TRC2(kwAmmExtractElmnt); + + hdr = hdrInfo->hdr; + + if (pLen == 0) + { + SRemPreMsg(&hdr, pdu); + pLen = 8; + } + tHdr = hdr; + if (len <= 8) + { + val = tHdr >> (KW_BYTE_LEN - (len)); + hdr = hdr << len; + pLen -= len; + } + else /*if (len > 8) */ + { + fLen = pLen; + val = tHdr; + val = val >> (KW_BYTE_LEN - fLen); + val = val << (len - fLen); + rLen = len - fLen; + SRemPreMsg(&hdr, pdu); + tHdr = hdr; + if (rLen <= 8) + { + hdr = hdr >> (KW_BYTE_LEN - rLen); + val = val | hdr; + hdr = tHdr << rLen; + pLen = (KW_BYTE_LEN - rLen); + } + else + { + rLen = rLen - KW_BYTE_LEN; + tVal = hdr; + tVal = tVal << rLen; + val = val | tVal; + + SRemPreMsg(&hdr, pdu); + tHdr = hdr; + hdr = hdr >> (KW_BYTE_LEN - rLen); + val = val | hdr; + hdr = tHdr << rLen; + pLen = (KW_BYTE_LEN - rLen); + } + } + + hdrInfo->pLen = pLen; + hdrInfo->hdr = hdr; + hdrInfo->val = val; + + RETVOID; +} + + + + +#ifdef ANSI +PRIVATE Void rgAmmUlHndlStatusPdu +( +Pst *udxPst, +SuId suId, +KwCb *gCb, +KwDlRbCb *rbCb, +Buffer *cntrlPdu, +U8 *fByte +) +#else +PRIVATE Void rgAmmUlHndlStatusPdu(udxPst,suId,gCb, rbCb, cntrlPdu, fByte) +Pst *udxPst; +SuId suId; +KwCb *gCb; +KwDlRbCb *rbCb; +Buffer *cntrlPdu; +U8 *fByte; +#endif +{ + U8 e1; + KwExtHdr hdrInfo; + KwUdxStaPdu *pStaPdu; + U8 e3; /* NACK RANGE : 5GNR */ + U32 snLen; + U32 snRange; + U32 resrvdBitsAckSn; + U32 resrvdBitsNackSn; + + + TRC2(rgAmmUlHndlStatusPdu) + + KWDBGP_BRIEF(gCb, "rgAmmUlHndlStatusPdu(rbCb, cntrlPdu, fByte) \n"); + + KW_MEM_ZERO(&hdrInfo, sizeof(KwExtHdr)); + + /* Extract the Control PDU */ + hdrInfo.hdr = (*fByte << 1); + hdrInfo.pLen = 4; + + /* D/C has been shifted in the calling function */ + if (hdrInfo.hdr & 0xE0) + { + KWDBGP_ERROR(gCb, "rgAmmUlHndlStatusPdu: Reserved value for CPT received \n"); + RETVOID; + } + + KW_ALLOC_SHRABL_BUF(udxPst->region, + udxPst->pool, + pStaPdu, + sizeof(KwUdxStaPdu)); + +#if (ERRCLASS & ERRCLS_ADD_RES) + /* Memory allocation failure can not be expected */ + if(!pStaPdu) + { + RETVOID; + } +#endif + + if (rbCb->m.amDl.snLen == KW_AM_CFG_12BIT_SN_LEN) + { + snLen = 12; + resrvdBitsAckSn = KW_STA_PDU_R_BITS_ACKSN_12BITS; + resrvdBitsNackSn = KW_STA_PDU_R_BITS_NACKSN_12BITS; + } + else if (rbCb->m.amDl.snLen == KW_AM_CFG_18BIT_SN_LEN) + { + snLen = 18; + resrvdBitsAckSn = KW_STA_PDU_R_BITS_ACKSN_18BITS; + resrvdBitsNackSn = KW_STA_PDU_R_BITS_NACKSN_18BITS; + } + else + { + snLen = KW_SN_LEN; + resrvdBitsAckSn = 0; + resrvdBitsAckSn = 0; + } + + pStaPdu->nackCnt = 0; + /* For CPT */ + hdrInfo.hdr = hdrInfo.hdr << KW_CPT_LEN; + + /* ACK Sn */ + hdrInfo.len = KW_SN_LEN; + rgAmmExtractElmnt(gCb, cntrlPdu, &hdrInfo); + pStaPdu->ackSn = hdrInfo.val; + + /* Check if NACK Exists */ + hdrInfo.len = KW_E1_LEN; + rgAmmExtractElmnt(gCb, cntrlPdu, &hdrInfo); + e1 = (U8)hdrInfo.val; + KWDBGP_DETAIL(gCb, "rgAmmUlHndlStatusPdu: ACK SN = %d \n", pStaPdu->ackSn); + + /* Extract the Reserved Bits after ACK SN field */ + hdrInfo.len = resrvdBitsAckSn; + rgAmmExtractElmnt(gCb, cntrlPdu, &hdrInfo); + + + /* If NACK exists in control PDU */ + /* For ACKs and NACKs */ + while (e1 && (pStaPdu->nackCnt < KW_MAX_NACK_CNT)) + { + hdrInfo.len = snLen; + rgAmmExtractElmnt(gCb, cntrlPdu, &hdrInfo); + pStaPdu->nackInfo[pStaPdu->nackCnt].sn = hdrInfo.val; + + hdrInfo.len = KW_E1_LEN; + rgAmmExtractElmnt(gCb, cntrlPdu, &hdrInfo); + e1 = (U8)hdrInfo.val; + + /* Extract e2 */ + /* hdrInfo.len = KW_E1_LEN; --> previusly stored value (for e1) is + already present*/ + rgAmmExtractElmnt(gCb, cntrlPdu, &hdrInfo); + /* e2 = (U8) hdrInfo.val;*/ + + /* Store e2 value */ + pStaPdu->nackInfo[pStaPdu->nackCnt].isSegment = (U8) hdrInfo.val; + + /* Extract e3 : 5GNR */ + /* hdrInfo.len = KW_E1_LEN; --> previusly stored value (for e1) is + already present*/ + rgAmmExtractElmnt(gCb, cntrlPdu, &hdrInfo); + e3 = (U8) hdrInfo.val; + + /* Extract Reserved Bits after NACK SN */ + hdrInfo.len = resrvdBitsNackSn; + rgAmmExtractElmnt(gCb, cntrlPdu, &hdrInfo); + + /* Test for resegmentation */ + if (pStaPdu->nackInfo[pStaPdu->nackCnt].isSegment) + { + hdrInfo.len = KW_SO_LEN_5GNR; /* 5GNR : SO Len 16 Bits */ + rgAmmExtractElmnt(gCb, cntrlPdu, &hdrInfo); + pStaPdu->nackInfo[pStaPdu->nackCnt].soStart = hdrInfo.val; + + rgAmmExtractElmnt(gCb, cntrlPdu, &hdrInfo); + pStaPdu->nackInfo[pStaPdu->nackCnt].soEnd = hdrInfo.val; + + KWDBGP_DETAIL(gCb, + "rgAmmUlHndlStatusPdu: soStart and soEnd = %d %d \n", + pStaPdu->nackInfo[pStaPdu->nackCnt].soStart, + pStaPdu->nackInfo[pStaPdu->nackCnt].soEnd); + } + else + { + hdrInfo.len = 0; + pStaPdu->nackInfo[pStaPdu->nackCnt].soStart = 0; + pStaPdu->nackInfo[pStaPdu->nackCnt].soEnd = 0; + + } + /* NACK RANGE Field is SET */ + if (e3) + { + /* Extract NACK range field */ + hdrInfo.len = KW_NACK_RANGE_LEN; + rgAmmExtractElmnt(gCb, cntrlPdu, &hdrInfo); + snRange = (U8)hdrInfo.val; + + pStaPdu->nackInfo[pStaPdu->nackCnt].nackRange = snRange; + + } + pStaPdu->nackCnt++; + } + + gRlcStats.amRlcStats.numULStaPduRcvd++; + gRlcStats.amRlcStats.numULNackInStaPduRcvd += pStaPdu->nackCnt; + + /* In case we have reached the MAX NACK CNT, then we should modify the ACK_SN + to the last NACK SN + 1 and discard the original ACK_SN*/ + if(pStaPdu->nackCnt == KW_MAX_NACK_CNT) + { + pStaPdu->ackSn = (pStaPdu->nackInfo[KW_MAX_NACK_CNT-1].sn + 1) & amDl->snModMask; + } + + + /* Parse & send Status PDU to RLC-DL */ + //KwUlUdxStaUpdReq(&(sapCb->pst), sapCb->spId, &rbCb->rlcId, pStaPdu); + KwUlUdxStaUpdReq(udxPst, suId, &rbCb->rlcId, pStaPdu); + + RETVOID; +} + +PUBLIC S16 kwProcDlStatusPdu(Pst *udxPst,SuId suId, + CmLteCellId cellId,CmLteRnti rnti,CmLteLcId lcId,Buffer *rlcSdu) +{ + KwDlRbCb *rbCb = NULLP; + KwDlUeCb *ueCb = NULLP; + U8 fByte; + U8 temp; + S16 retVal = RFAILED; + KwCb *gCb; + Pst dlRlcPst = *udxPst; + + gCb = KW_GET_KWCB(1); /* DL RLC instance */ + + if( ROK != kwDbmFetchDlUeCb(gCb,rnti,cellId,&(ueCb))) + { + printf("\n RLC UECb Not found...\n"); + RETVALUE(RFAILED); + } + + + rbCb = ueCb->lCh[lcId - 1].dlRbCb; + + /* Skip if mode is not AM */ + if((rbCb == NULLP) || (rbCb->mode != CM_LTE_MODE_AM)) + { + RETVALUE(RFAILED); + } + + if(ROK != SExamMsg((Data *)(&fByte), + rlcSdu, 0)) + { + printf("\n Failure in Rlc Hdr SExamMsg\n"); + RETVALUE(RFAILED); + } + + if(KW_CNTRL_PDU == ((fByte & KW_DC_POS) >> KW_DC_SHT)) + { + SRemPreMsg(&temp, rlcSdu); + dlRlcPst.selector = 1;/* LWLC*/ + rgAmmUlHndlStatusPdu(&dlRlcPst,suId,gCb, rbCb, rlcSdu, &fByte); + retVal = ROK; + } + + RETVALUE(retVal); +} + + +#endif + + +/*@}*/ + + +/********************************************************************30** + + End of file +**********************************************************************/ diff --git a/src/5gnrrlc/kw_amm_ul.c b/src/5gnrrlc/kw_amm_ul.c new file mode 100755 index 000000000..f7ef2bfce --- /dev/null +++ b/src/5gnrrlc/kw_amm_ul.c @@ -0,0 +1,2303 @@ +/******************************************************************************* +################################################################################ +# Copyright (c) [2017-2019] [Radisys] # +# # +# 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. # +################################################################################ +*******************************************************************************/ + +/********************************************************************20** + + Name: RLC - AM module file + + Type: C source file + + Desc: Source code for Acknowledged Mode Module functions such as, + + Transmission of data/control PDUs + Retransmission (Feedback in terms of status) + Polling + Assemble SDUs + Reception - reordering + Duplicate detection for byte segments + Reassemble SDUs + + File: kw_amm_ul.c + +*********************************************************************21*/ +static const char* RLOG_MODULE_NAME="AMM"; +static int RLOG_MODULE_ID=2048; +static int RLOG_FILE_ID=190; + +/* header include files (.h) */ +#include "envopt.h" /* environment options */ +#include "envdep.h" /* environment dependent */ +#include "envind.h" /* environment independent */ + +#include "gen.h" /* general */ +#include "ssi.h" /* system services */ +#include "cm5.h" /* common timer defines */ +#include "cm_tkns.h" /* common tokens defines */ +#include "cm_mblk.h" /* common memory allocation library defines */ +#include "cm_llist.h" /* common link list defines */ +#include "cm_hash.h" /* common hash list defines */ +#include "cm_lte.h" /* common LTE defines */ +#include "lkw.h" /* LKW defines */ +#include "ckw.h" /* CKW defines */ +#include "kwu.h" /* KWU defines */ +#include "rgu.h" /* RGU defines */ +#include "kw_udx.h" +#include "kw_err.h" /* Err defines */ +#include "kw_env.h" /* RLC environment options */ + +#include "kw.h" /* RLC defines */ +#include "kw_ul.h" + +/* extern (.x) include files */ +#include "gen.x" /* general */ +#include "ssi.x" /* system services */ + +#include "cm5.x" /* common timer library */ +#include "cm_tkns.x" /* common tokens */ +#include "cm_mblk.x" /* common memory allocation */ +#include "cm_llist.x" /* common link list */ +#include "cm_hash.x" /* common hash list */ +#include "cm_lte.x" /* common LTE includes */ +#include "cm_lib.x" /* common memory allocation library */ +#include "lkw.x" /* LKW */ +#include "ckw.x" /* CKW */ +#include "kwu.x" /* KWU */ +#include "rgu.x" /* RGU */ + +#include "kw.x" +#include "kw_ul.x" +#include "kw_udx.x" + +/* Variable for logging, declared in cl */ +#ifndef RGL_SPECIFIC_CHANGES +#ifndef TENB_ACC +#ifndef LTE_PAL_ENB +extern U32 ulrate_rgu; +#endif +#endif +#endif +#ifndef RGL_SPECIFIC_CHANGES +#ifndef TENB_ACC +#ifndef TENB_T2K3K_SPECIFIC_CHANGES +#ifndef LTE_PAL_ENB +extern U32 isMemThreshReached(Region region); +#endif +#else +#ifndef LTE_PAL_ENB +extern U32 isMemThreshReached(Region region); +#endif +#endif +#endif +#endif +/** @file gp_amm_ul.c +@brief RLC Acknowledged Mode Uplink Module +**/ +#define KW_MODULE (KW_DBGMASK_AM | KW_DBGMASK_UL) /* for debugging purpose */ + +/* private function declarations */ + +PRIVATE Void kwAmmUlAssembleCntrlInfo ARGS ((KwCb *gCb, KwUlRbCb *rbCb)); + +PRIVATE S16 kwAmmExtractHdr ARGS ((KwCb *gCb, + KwUlRbCb *rbCb, + Buffer *pdu, + KwAmHdr *amHdr, + U8 *fByte)); + +PRIVATE Bool kwAmmUlPlacePduInRecBuf ARGS ((KwCb *gCb, + Buffer *pdu, + KwUlRbCb *rbCb, + KwAmHdr *amHdr)); + +PRIVATE Void kwAmmTriggerStatus ARGS ((KwCb *gCb, + KwUlRbCb *rbCb, + KwSn sn, + Bool discFlg)); + +PRIVATE S16 kwAmmUlReassembleSdus ARGS ((KwCb *gCb, + KwUlRbCb *rbCb, + KwAmRecBuf *recBuf)); + +PRIVATE Void kwAmmProcPduOrSeg ARGS ((KwCb *gCb, + KwUlRbCb *rbCb, + KwAmHdr *amHdr, + Buffer *pdu)); + +PRIVATE Void kwAmmUpdExpByteSeg ARGS ((KwCb *gCb,KwAmUl *amUl, KwSeg* newSeg)); + +PRIVATE Void kwAmmExtractElmnt ARGS ((KwCb *gCb, Buffer *pdu, KwExtHdr *hdrInfo)); + +PRIVATE Void kwAmmUlHndlStatusPdu ARGS ((KwCb *gCb, + KwUlRbCb *rbCb, + Buffer *cntrlPdu, + U8 *fByte)); + +/****************************************************************************** + + AM Module contains the following funcitons: + + - kwAmmProcessSdus + - kwAmmUlAssembleCntrlInfo + - kwResegRetxPdus + - kwAssembleSdus + - kwChkandSetPoll + - kwAmmProcessPdus + - kwAmmUlHndlStatusPdu + - kwAmmTriggerStatus + - kwAmmUlReassembleSdus + +*******************************************************************************/ +/** @addtogroup ammode */ +/*@{*/ + +/** + * @brief Private function to fill NACK information in status Pdu as per 5GNR + * + * @param[in] rbCb Ul RbCb + * @param[in] sn Sequence number of the PDU for which the NACK + * @param[in] isSegment TRUE means NACK for segment; FALSE for PDU + * @param[in] soStart SOStart + * @param[in] soEnd SOEnd + * @param[out] statusPdu status Pdu holder to be filled + * @param[in] prevNackSn It holds previous nack Sn + * + * @return S16 + * The number of bytes required to encode this NACK information + * + */ +#ifdef ANSI +PRIVATE S16 kwAmmUlSetNackInfo +( +KwUlRbCb *rbCb, +KwSn sn, +Bool isSegment, +U16 soStart, +U16 soEnd, +KwUdxDlStaPdu *statusPdu, +KwSn *prevNackSn +) +#else +PRIVATE S16 kwAmmUlSetNackInfo(rbCb, sn, isSegment, soStart, statusPdu, prevNackSn) +KwUlRbCb *rbCb; +KwSn sn; +Bool isSegment; +U16 soStart; +U16 soEnd; +KwUdxDlStaPdu *statusPdu, +KwSn *prevNackSn; +#endif +{ + KwNackInfo *nackInfo = (statusPdu->nackInfo + statusPdu->nackCount); + S16 sizeToBeEncd = 0; /* Status PDu size to be encoded */ + + TRC2(kwAmmUlSetNackInfo) + + /* In following cases we should increment the nackCnt & fill new NACK_SN info: + * 1) First NACK_SN of the statusdPdu + * 2) NACK_SN is not continuous with previous + * 3) NACK_SN is same as previuos but segments are not continuous + * 4) NACK_SN is continuous with previous but previous NACK_SN segments + * are not missing in sequence till end + */ + if((*prevNackSn == 0xffffffff) || ((((*prevNackSn) + 1) & AMUL.snModMask) != sn) || + (((*prevNackSn) == sn) && (((nackInfo->soEnd + 1) != soStart))) || + ((nackInfo->isSegment) && (((*prevNackSn) + 1) == sn) && (nackInfo->soEnd != KW_ALL_BYTES_MISSING))) + { + if(nackInfo->nackRange) + { + if((nackInfo->soEnd) && (!nackInfo->soStart)) + { + /*First nack_sn of this nackRange not segmented but last is segmented */ + sizeToBeEncd = 5; /*32 for soStart and soEnd and 8 for nackRange */ + } + else + { + /*First nack_sn of this nackRange was segmented */ + sizeToBeEncd = 1; /*8 for nackRange */ + } + } + + if(*prevNackSn != 0xffffffff) + { + /* Increment nackCount as this sn is continous */ + statusPdu->nackCount++; + nackInfo = statusPdu->nackInfo + statusPdu->nackCount; + } + + nackInfo->sn = sn; + nackInfo->isSegment = isSegment; + nackInfo->soStart = soStart; + nackInfo->soEnd = soEnd; + nackInfo->nackRange = 0; + + if(isSegment) + { + sizeToBeEncd += ((AMUL.snLen == KW_AM_CFG_12BIT_SN_LEN)?6:7); /* NACK,E1,E2,Sostart,SoEnd */ + } + else + { + sizeToBeEncd += ((AMUL.snLen == KW_AM_CFG_12BIT_SN_LEN)?2:3); /* NACK,E1,E2 */ + } + } + else + { + if(!(nackInfo->nackRange)) + { + nackInfo->nackRange++; + } + /* This case means there are continuous SNs/Segments. If it is the next + * Sn then increment nackRnage. if same SN but different segment then + * dont increment nackRange */ + if((((*prevNackSn) + 1) & AMUL.snModMask) == sn) + { + nackInfo->nackRange++; + } + + /* If NackRange is reached to max value then increment statusPdu->nackCount*/ + if(nackInfo->nackRange == 255) + { + statusPdu->nackCount++; + if(nackInfo->isSegment) + { + sizeToBeEncd = 1; /* return only nackRangeSize*/ + } + else if (isSegment) + { + /* First SN was not segmented of this nackRange but last SN is segmented */ + sizeToBeEncd = 5; /* return size of soSatrt + soEnd + nackRnage */ + } + } + + if(isSegment) + { + nackInfo->isSegment = isSegment; + nackInfo->soEnd = soEnd; + } + else if(nackInfo->isSegment) + { + nackInfo->soEnd = KW_ALL_BYTES_MISSING; + } + else + { + nackInfo->soStart = 0; + nackInfo->soEnd = 0; + } + + } + *prevNackSn = sn; + + RETVALUE(sizeToBeEncd); +} + +/** + * @brief Private handler to gather information required to create the STATUS + * PDU + * + * @details + * Scans the reception buffer and copies information to the UdxDlStaPdu + * structure about SN's and segments not yet received. This data is + * sent to the DL instance so that it can create an appropriate (depending + * on the grants from MAC) STATUS PDU and send it to MAC. + * + * @param[in] gCb RLC instance control block + * @param[in] rbCb Uplink RB control block + * + * @return Void + * + */ +#ifdef ANSI +PRIVATE Void kwAmmUlAssembleCntrlInfo +( +KwCb *gCb, +KwUlRbCb *rbCb +) +#else +PRIVATE Void kwAmmUlAssembleCntrlInfo(gCb, rbCb) +KwCb *gCb; +KwUlRbCb *rbCb; +#endif +{ + KwUdxDlStaPdu *pStatusPdu; + KwNackInfo *nackInfo; + KwSn sn; /* sequence number */ + KwSn mSn; /* Mod val of sequence number */ + KwSn rxHighestStatus; /* Mod val of rxHighestStatus */ + KwSeg *seg; /* pdu segment */ + U16 nackCnt = 0; /* Index for staPdu */ + U16 seqSo; /* segmment offset */ + KwUdxUlSapCb *sapCb; + U16 staPduEncSize = 3; /* size that would be of the encoded + STATUS PDU, it is in bits; 15 for + first fixed part of STATUS PDU */ + KwAmRecBuf *recBuf = NULLP; + KwSn prevNackSn = 0xffffffff; + + TRC2(kwAmmUlAssembleCntrlInfo) + + + sapCb = KW_GET_UDX_SAP(gCb); + + KW_ALLOC_SHRABL_BUF(sapCb->pst.region, + sapCb->pst.pool, + pStatusPdu, + sizeof(KwUdxDlStaPdu)); + +#if (ERRCLASS & ERRCLS_ADD_RES) + /* Memory allocation failure can not be expected */ + if(!pStatusPdu) + { + RETVOID; + } +#endif + + sn = AMUL.rxNext; + MODAMR(sn, mSn, AMUL.rxNext, AMUL.snModMask); + MODAMR(AMUL.rxHighestStatus, rxHighestStatus, AMUL.rxNext, AMUL.snModMask); + + recBuf = kwUtlGetRecBuf(AMUL.recBufLst, sn); + + while (mSn < rxHighestStatus ) + { + /* For missing PDUs */ + if ((NULLP == recBuf) && nackCnt < KW_MAX_NACK_CNT ) + { + RLOG_ARG3(L_DEBUG,DBG_RBID,rbCb->rlcId.rbId, + "Missing PDU's SN = %d UEID:%d CELLID:%d", + sn, + rbCb->rlcId.ueId, + rbCb->rlcId.cellId); + staPduEncSize += kwAmmUlSetNackInfo(rbCb, + sn, + FALSE, /* isSegment */ + 0, /* SOStart */ + 0, /* SOEnd */ + pStatusPdu, + &prevNackSn); + } + else if (recBuf && (recBuf->pdu == NULLP) && + (recBuf->segLst.count > 0)) + { + /* Scan through the byte segments of PDU and add this sn + with soStart and soEnd info to staPdu */ + + seqSo = 0; + KW_LLIST_FIRST_SEG(recBuf->segLst, seg); + while (seg != NULLP && nackCnt < KW_MAX_NACK_CNT) + { + /* For missing byte segments */ + if (seg->amHdr.so != seqSo) + { + staPduEncSize += kwAmmUlSetNackInfo(rbCb, + sn, + TRUE, + seqSo, + seg->amHdr.so - 1, + pStatusPdu, + &prevNackSn); + + RLOG_ARG3(L_DEBUG,DBG_RBID,rbCb->rlcId.rbId, + "Missing byte segment's" + " SN:%d UEID:%d CELLID:%d", + sn, + rbCb->rlcId.ueId, + rbCb->rlcId.cellId); + RLOG_ARG4(L_DEBUG,DBG_RBID,rbCb->rlcId.rbId, + "soStart and soEnd = %d, %d UEID:%d CELLID:%d", + seqSo, + seg->amHdr.so - 1, + rbCb->rlcId.ueId, + rbCb->rlcId.cellId); + } + + seqSo = seg->soEnd + 1; + KW_LLIST_NEXT_SEG(recBuf->segLst, seg); + } + + /* Check if the last segment is missing */ + KW_LLIST_LAST_SEG(recBuf->segLst, seg); + if ((seg != NULLP) && + (seg->amHdr.si != KW_SI_LAST_SEG && nackCnt < KW_MAX_NACK_CNT)) + { + staPduEncSize += kwAmmUlSetNackInfo(rbCb, + sn, + TRUE, + seqSo, + KW_ALL_BYTES_MISSING, + pStatusPdu, + &prevNackSn); + + RLOG_ARG3(L_DEBUG,DBG_RBID,rbCb->rlcId.rbId, + "kwAmmUlAssembleCntrlInfo: Missing (last) byte " + "segment's SN:%d UEID:%d CELLID:%d", + sn, + rbCb->rlcId.ueId, + rbCb->rlcId.cellId); + RLOG_ARG4(L_DEBUG,DBG_RBID,rbCb->rlcId.rbId, + "soStart and soEnd = %d, %d UEID:%d CELLID:%d", + seqSo, + KW_ALL_BYTES_MISSING, + rbCb->rlcId.ueId, + rbCb->rlcId.cellId); + } + } + + + sn = (sn + 1) & (AMUL.snModMask); /* MOD 1024 */ + MODAMR(sn, mSn, AMUL.rxNext, AMUL.snModMask); + + /* Get the received Buffer the updated/next SN */ + recBuf = kwUtlGetRecBuf(AMUL.recBufLst, sn); + + /* Find the next missing sequence number if nackCnt reaches maximum and + still Reordering window has some missing AMDPDUs / AMDPDU segments. The + next missing sequence number will be considered as the ack sequnece + number in the status pdu.*/ + if((nackCnt == KW_MAX_NACK_CNT) && + ((recBuf == NULLP) || + ((recBuf->pdu == NULLP) && + (recBuf->segLst.count > 0)))) + { + break; + } + } + + /*Unfortunately i have write below peice of code here because kwAmmsetNackInfo() + * don't know that this is the last nackSn with nackRange*/ + nackInfo = &(pStatusPdu->nackInfo[pStatusPdu->nackCount]); + if(nackInfo->nackRange) + { + if((nackInfo->soEnd) && (!nackInfo->soStart)) + { + /*First nack_sn of this nackRange not segmented but last is segmented */ + staPduEncSize += 5; /*32 for soStart and soEnd and 8 for nackRange */ + } + else + { + /*First nack_sn of this nackRange was segmented */ + staPduEncSize += 1; /*8 for nackRange */ + } + } + /* nackCount is used as an index to nackInfo array but in status Pdu it + * should be equal to number nackInfo that are filled. hence incrementing by 1*/ + if(prevNackSn != 0xffffffff) + { + pStatusPdu->nackCount++; + } + /* Update ACK SN with the last sn for which feedback is not assembled */ + if ( mSn == rxHighestStatus) + { + pStatusPdu->ackSn = AMUL.rxHighestStatus; + } + else + { + pStatusPdu->ackSn = sn; + } + + RLOG_ARG3(L_UNUSED,DBG_RBID,rbCb->rlcId.rbId, + "kwAmmUlAssembleCntrlInfo: ACK PDU's SN = %d" + "UEID:%d CELLID:%d", + pStatusPdu->ackSn, + rbCb->rlcId.ueId, + rbCb->rlcId.cellId); + + pStatusPdu->controlBo = staPduEncSize; /*Its already in bytes */ + + AMUL.staTrg = FALSE; + AMUL.gatherStaPduInfo = FALSE; + + + if (KwUlUdxStaPduReq(&sapCb->pst, + sapCb->spId, + &rbCb->rlcId, + pStatusPdu) != ROK) + { + RLOG_ARG2(L_ERROR,DBG_RBID,rbCb->rlcId.rbId, + "Failed to Send Sta Pdu UEID:%d CELLID:%d", + rbCb->rlcId.ueId, + rbCb->rlcId.cellId); + KW_FREE_SHRABL_BUF_WC(sapCb->pst.region, + sapCb->pst.pool, + pStatusPdu, + sizeof(KwUdxDlStaPdu)); + } + + RETVOID; +} + +#ifdef XEON_SPECIFIC_CHANGES +extern U32 gRlcDatIndUL; +#endif + +#ifdef T2K_TRIGGER_RLC_REEST +PUBLIC U32 drpRlcDrbPack; +#endif +/** + * @brief Handler to process the PDUs received from MAC and send it to PDCP + * + * @details + * This function is invoked by UTL with the PDU(s) received from MAC. + * It reorders the received data PDUs and trigger status report as + * needed. Reassembles the SDUs in sequence and send it to PDCP. + * It also processes the control PDU + * + * @param[in] gCb RLC instance control block + * @param[in] rbCb RB control block + * @param[out] pduInfo PDU Info received from MAC + * + * @return Void + * + */ +#ifdef LTE_L2_MEAS +#ifdef ANSI +PUBLIC Void kwAmmProcessPdus +( +KwCb *gCb, +KwUlRbCb *rbCb, +KwPduInfo *pduInfo, +U32 ttiCnt +) +#else +PUBLIC Void kwAmmProcessPdus(gCb, rbCb, pduInfo, ulTimeInfo) +KwCb *gCb; +KwUlRbCb *rbCb; +KwPduInfo *pduInfo; +U32 ttiCnt; +#endif +#else +#ifdef ANSI +PUBLIC Void kwAmmProcessPdus +( +KwCb *gCb, +KwUlRbCb *rbCb, +KwPduInfo *pduInfo +) +#else +PUBLIC Void kwAmmProcessPdus(gCb, rbCb, pduInfo) +KwCb *gCb; +KwUlRbCb *rbCb; +KwPduInfo *pduInfo; +#endif +#endif +{ + Buffer *pdu; + KwAmUl *amUl; + KwAmHdr amHdr; + U8 numPdu = 0; + U8 numPduToProcess; + KwSn sn; + KwSn tSn; + KwSn mSn; + U8 fByte; + Bool discFlg; +#ifdef LTE_L2_MEAS_RLC + MsgLen rlcSduSz; /*Holds length of Rlc Sdu*/ +#endif /* LTE_L2_MEAS */ + + TRC2(kwAmmProcessPdus) + + + amUl = &AMUL; + + numPduToProcess = KW_MIN(pduInfo->numPdu, RGU_MAX_PDU); + RLOG_ARG4(L_UNUSED,DBG_RBID,rbCb->rlcId.rbId, + "numPdu[%ld],numPduToProcess[%ld] UEID:%ld CELLID:%ld", + numPdu, + numPduToProcess, + rbCb->rlcId.ueId, + rbCb->rlcId.cellId); + + //printf ("++++++++++++ 5GNRLOG numPduToProcess %d \n", numPduToProcess); + while (numPdu < numPduToProcess) + { + //printf ("++++++++++++ 5GNRLOG processing pdu %d \n", numPdu); + discFlg = FALSE; + pdu = pduInfo->mBuf[numPdu++]; + + if (! pdu) + { + + RLOG_ARG2(L_ERROR,DBG_RBID,rbCb->rlcId.rbId, + "Null Pdu UEID:%d CELLID:%d", + rbCb->rlcId.ueId, + rbCb->rlcId.cellId); + gCb->genSts.errorPdusRecv++; + break; + } +#ifndef RGL_SPECIFIC_CHANGES +#ifndef TENB_ACC +#ifndef LTE_PAL_ENB + MsgLen len; + SFndLenMsg(pdu, &len); + ulrate_rgu += len; +#endif +#endif +#endif + /* Extract AM PDU/SEG header Info */ + KW_MEM_ZERO(&amHdr, sizeof(KwAmHdr)); + /* Avoided the allocation of amHdr and sending + a single pointer */ + if (kwAmmExtractHdr(gCb, rbCb, pdu, &amHdr, &fByte) != ROK) + { + RLOG_ARG2(L_ERROR,DBG_RBID,rbCb->rlcId.rbId, + "Header Extraction Failed UEID:%d CELLID:%d", + rbCb->rlcId.ueId, + rbCb->rlcId.cellId); + KW_FREE_BUF(pdu); + gCb->genSts.errorPdusRecv++; + continue; + } + /* Check if its a control PDU */ + if (amHdr.dc == 0) + { + kwAmmUlHndlStatusPdu(gCb, rbCb, pdu, &fByte); + KW_FREE_BUF(pdu); + continue; + } + if((amHdr.si == KW_SI_LAST_SEG) && (!amHdr.so)) + { + RLOG_ARG3(L_UNUSED,DBG_RBID,rbCb->rlcId.rbId, + "kwAmmProcessPdus: Dropping PDU because SO can't be zero for last segment sn:%u " + "UEID:%d CELLID:%d", + amHdr.sn, + rbCb->rlcId.ueId, + rbCb->rlcId.cellId); + KW_FREE_BUF(pdu); + continue; + } +#ifndef RGL_SPECIFIC_CHANGES +#ifdef LTE_TDD +#ifndef TENB_ACC +#ifndef TENB_T2K3K_SPECIFIC_CHANGES +#ifndef LTE_PAL_ENB + /* Changed the condition to TRUE from ROK */ + if(isMemThreshReached(kwCb[0]->init.region) == TRUE) + { + extern U32 rlculdrop; + rlculdrop++; + KW_FREE_BUF(pdu); + continue; + } +#endif +#else +#ifndef LTE_PAL_ENB + /*ccpu00142274 - UL memory based flow control*/ + if(isMemThreshReached(kwCb[0]->init.region) != ROK) + { + extern U32 rlculdrop; + rlculdrop++; + KW_FREE_BUF(pdu); + continue; + } +#endif +#endif +#endif +#endif +#endif + +#ifdef T2K_TRIGGER_RLC_REEST + if(drpRlcDrbPack > 1000) + { + if(rbCb->rlcId.rbType == CM_LTE_DRB) + { + KW_FREE_BUF(pdu); + continue; + } + } + drpRlcDrbPack++; +#endif + /* Reordering data PDU */ + sn = amHdr.sn; + if (kwAmmUlPlacePduInRecBuf(gCb,pdu, rbCb, &amHdr) == TRUE) + { + KwAmRecBuf *recBuf; + Bool tmrRunning; + KwSn tVrMr; + KwSn mrxNextHighestRcvd; + +#ifdef LTE_L2_MEAS + kwUtlCalUlIpThrPut(gCb, rbCb, pdu, ttiCnt); +#endif /* LTE_L2_MEAS */ + + /* Update rxNextHighestRcvd */ + MODAMR(sn, mSn, amUl->rxNext, amUl->snModMask); + MODAMR(amUl->rxNextHighestRcvd, mrxNextHighestRcvd, amUl->rxNext, amUl->snModMask); + if (mSn >= mrxNextHighestRcvd) + { + amUl->rxNextHighestRcvd = ((sn + 1) & (amUl->snModMask)); + + RLOG_ARG3(L_UNUSED,DBG_RBID,rbCb->rlcId.rbId, + "kwAmmProcessPdus: Updated rxNextHighestRcvd = %d UEID:%d CELLID:%d", + amUl->rxNextHighestRcvd, + rbCb->rlcId.ueId, + rbCb->rlcId.cellId); + } + + recBuf = kwUtlGetRecBuf(amUl->recBufLst, sn); + if ((NULLP != recBuf) && ( recBuf->allRcvd)) + { + /* deliver the reassembled RLC SDU to upper layer, + But not removed from the table */ + kwAmmUlReassembleSdus(gCb, rbCb, recBuf); + recBuf->isDelvUpperLayer = TRUE; + + MODAMR(amUl->vrMr, tVrMr, amUl->rxNext, amUl->snModMask); + + /* Update rxHighestStatus */ + if (sn == amUl->rxHighestStatus) + { + tSn = (sn + 1) & (amUl->snModMask) ; /* MOD (2 Pwr SN LEN- 1) */ + + recBuf = kwUtlGetRecBuf(amUl->recBufLst, tSn); + /* Scan through till the upper edge of the window */ + MODAMR(tSn, mSn, amUl->rxNext, amUl->snModMask); + while (mSn <= tVrMr) + { + if ((NULLP == recBuf) || (!recBuf->allRcvd)) + { + RLOG_ARG3(L_UNUSED,DBG_RBID,rbCb->rlcId.rbId, + "kwAmmProcessPdus: Updated rxHighestStatus:%d " + "UEID:%d CELLID:%d", + tSn, + rbCb->rlcId.ueId, + rbCb->rlcId.cellId); + + amUl->rxHighestStatus = tSn; + break; + } + tSn = (tSn + 1) & (amUl->snModMask); /* MOD (2 Pwr SN LEN- 1) */ + recBuf = kwUtlGetRecBuf(amUl->recBufLst, tSn); + mSn++; + } + } + + + /* Update rxNext */ + if (sn == amUl->rxNext) + { + tSn = sn; + recBuf = kwUtlGetRecBuf(amUl->recBufLst, tSn); + MODAMR(tSn, mSn, amUl->rxNext, amUl->snModMask); + /* Scan through till the upper edge of the window */ + while (mSn <= tVrMr) + { + if ((NULLP != recBuf) && (recBuf->allRcvd) && + (TRUE == recBuf->isDelvUpperLayer)) + { + /* RecBuf should remove from table + since PDU is already sent to upper layer */ + recBuf->isDelvUpperLayer = FALSE; + kwUtlDelRecBuf(amUl->recBufLst, recBuf, gCb); + } + else + { + amUl->rxNext = tSn; + amUl->vrMr = (amUl->rxNext + (KW_AM_GET_WIN_SZ(amUl->snLen))) & (amUl->snModMask); + break; + } + tSn = (tSn + 1) & (amUl->snModMask); + recBuf = kwUtlGetRecBuf(amUl->recBufLst, tSn); + mSn++; + } + } + } + + /* Check if reOrdTmr is running and update rxNextStatusTrig accordingly */ + tmrRunning = kwChkTmr(gCb,(PTR)rbCb, KW_EVT_AMUL_REORD_TMR); + if (tmrRunning) + { + Bool snInWin = KW_AM_CHK_SN_WITHIN_RECV_WINDOW(amUl->rxNextStatusTrig, amUl); + + if ( (amUl->rxNextStatusTrig == amUl->rxNext) || ( (!snInWin) && + (amUl->rxNextStatusTrig != amUl->vrMr) ) ) + { + kwStopTmr(gCb,(PTR)rbCb, KW_EVT_AMUL_REORD_TMR); + tmrRunning = FALSE; + } + } + + if (!tmrRunning) + { + if (amUl->rxNextHighestRcvd > amUl->rxNext) + { + kwStartTmr(gCb,(PTR)rbCb, KW_EVT_AMUL_REORD_TMR); + amUl->rxNextStatusTrig = amUl->rxNextHighestRcvd; + + RLOG_ARG3(L_DEBUG,DBG_RBID,rbCb->rlcId.rbId, + "kwAmmProcessPdus: Updated rxNextStatusTrig = %d UEID:%d CELLID:%d", + amUl->rxNextStatusTrig, + rbCb->rlcId.ueId, + rbCb->rlcId.cellId); + } + } + } + else + { + discFlg = TRUE; + gRlcStats.amRlcStats.numULPdusDiscarded++; + } + + if (amHdr.p) + { + kwAmmTriggerStatus(gCb,rbCb, sn, discFlg); + } + } + +#ifdef LTE_L2_MEAS + kwUtlCalUlIpThrPutIncTTI(gCb, rbCb,ttiCnt); +#endif /* LTE_L2_MEAS */ + gCb->genSts.pdusRecv += pduInfo->numPdu; + if (amUl->gatherStaPduInfo) + { + kwAmmUlAssembleCntrlInfo(gCb,rbCb); + } + + RETVOID; +} + + +/** + * @brief Private handler to extract header Information of the PDU + * + * @details + * This function extracts the header elements of the PDU and store them + * in db for future reference. + * + * fByte - is the first byte removed from the PDU as part of calling + * functions + * + * @param[in] gCb RLC instance control block + * @param[in] rbCb Uplink RB control block + * @param[in] pdu Received PDU + * @param[out] amHdr Pointer to the extracted AM header + * @param[out] fByte First byte removed from the PDU + * + * @return S16 + * -# ROK + * -# RFAILED + * + */ +#ifdef ANSI +PRIVATE S16 kwAmmExtractHdr +( +KwCb *gCb, +KwUlRbCb *rbCb, +Buffer *pdu, +KwAmHdr *amHdr, +U8 *fByte +) +#else +PRIVATE S16 kwAmmExtractHdr(gCb, rbCb, pdu, amHdr, fByte) +KwCb *gCb; +KwUlRbCb *rbCb; +Buffer *pdu; +KwAmHdr *amHdr; +U8 *fByte; +#endif +{ + U8 snByte; + KwSn sn = 0; + MsgLen pduSz; + KwExtHdr hdrInfo; + + TRC2(kwAmmExtractHdr) + + + KW_MEM_ZERO(&hdrInfo, sizeof(KwExtHdr)); + + /* Extract fixed part of the header */ + SFndLenMsg(pdu,&pduSz); + SRemPreMsg(fByte, pdu); + amHdr->dc = (*fByte & KW_DC_POS) >> KW_DC_SHT; + if (KW_CNTRL_PDU == amHdr->dc) + { + //printf ("++++++++++++ 5GNRLOG HDR extracted CTRL : \n"); + RETVALUE(ROK); + } + + amHdr->p = (*fByte & KW_POLL_POS) >> KW_POLL_SHT; + + amHdr->si = (*fByte & KW_SI_POS) >> KW_SI_SHT; + + /* 12 BIT SN */ + if (rbCb->m.amUl.snLen == KW_AM_CFG_12BIT_SN_LEN) + { + SRemPreMsg(&snByte, pdu); + sn = (KwSn)(((*fByte & KW_SN_POS_12BIT) << KW_BYTE_LEN ) | snByte); + amHdr->sn = sn; + } + else if (rbCb->m.amUl.snLen == KW_AM_CFG_18BIT_SN_LEN) + { + SRemPreMsg(&snByte, pdu); + sn = (KwSn)(((*fByte & KW_SN_POS_18BIT) << KW_BYTE_LEN ) | snByte); + + SRemPreMsg(&snByte, pdu); + sn = ((sn << KW_BYTE_LEN) | snByte); + + amHdr->sn = sn; + } + if ((amHdr->si != 0) && (amHdr->si != 0x01)) + { + hdrInfo.len = KW_SO_LEN_5GNR; + kwAmmExtractElmnt(gCb, pdu, &hdrInfo); + amHdr->so = hdrInfo.val; + pduSz -= 2; + } + + //printf ("++++++++++++ 5GNRLOG HDR extracted DATA : sn %d \n", sn); + RETVALUE(ROK); +} + +#ifdef OLD +/** + * @brief Private handler to extract header Information of the PDU + * + * @details + * This function extracts the header elements of the PDU and store them + * in db for future reference. + * + * fByte - is the first byte removed from the PDU as part of calling + * functions + * + * @param[in] gCb RLC instance control block + * @param[in] rbCb Uplink RB control block + * @param[in] pdu Received PDU + * @param[out] amHdr Pointer to the extracted AM header + * @param[out] fByte First byte removed from the PDU + * + * @return S16 + * -# ROK + * -# RFAILED + * + */ +#ifdef ANSI +PRIVATE S16 kwAmmExtractHdrOld +( +KwCb *gCb, +Buffer *pdu, +KwAmHdr *amHdr, +U8 *fByte +) +#else +PRIVATE S16 kwAmmExtractHdrOld(gCb, pdu, amHdr, fByte) +KwCb *gCb; +Buffer *pdu; +KwAmHdr *amHdr; +U8 *fByte; +#endif +{ + U8 e; + U8 snByte; + U16 sn; + MsgLen pduSz; + MsgLen totalSz = 0; + KwExtHdr hdrInfo; + + TRC2(kwAmmExtractHdrOld) + + + KW_MEM_ZERO(&hdrInfo, sizeof(KwExtHdr)); + + /* Extract fixed part of the header */ + SFndLenMsg(pdu,&pduSz); + SRemPreMsg(fByte, pdu); + amHdr->dc = (*fByte & KW_DC_POS) >> KW_DC_SHT; + if (KW_CNTRL_PDU == amHdr->dc) + { + RETVALUE(ROK); + } + /* kw002.201 : Changed the extraction of hdr elements to avoid */ + /* function calls */ + amHdr->rf = (*fByte & KW_RF_POS) >> KW_RF_SHT; + amHdr->p = (*fByte & KW_POLL_POS) >> KW_POLL_SHT; + amHdr->fi = (*fByte & KW_FI_POS) >> KW_FI_SHT; + e = amHdr->e = (*fByte & KW_E_POS)>> KW_E_SHT; + + SRemPreMsg(&snByte, pdu); + sn = (U16)(((*fByte & KW_SN_POS) << KW_BYTE_LEN ) | snByte); + amHdr->sn = sn; + if (amHdr->rf == 1) + { + /* Extract extn part of the header */ + hdrInfo.len = KW_LSF_LEN; + kwAmmExtractElmnt(gCb, pdu, &hdrInfo); + amHdr->lsf = (U8)hdrInfo.val; + + hdrInfo.len = KW_SO_LEN; + kwAmmExtractElmnt(gCb, pdu, &hdrInfo); + amHdr->so = hdrInfo.val; + pduSz -= 2; + } + + amHdr->numLi = 0; + /* Extract LIs */ + while (e && (amHdr->numLi < KW_MAX_UL_LI)) + { + hdrInfo.len = KW_E_LEN; + kwAmmExtractElmnt(gCb, pdu, &hdrInfo); + e = amHdr->e = (U8)hdrInfo.val; + + /* Extract LI value*/ + hdrInfo.len = KW_LI_LEN; + kwAmmExtractElmnt(gCb, pdu, &hdrInfo); + /* li = hdrInfo.val;*/ + + /* check if LI is zero */ + if (! hdrInfo.val) + { + RLOG0(L_ERROR, "Received LI as 0"); + RETVALUE(RFAILED); + } + + /* store the extracted LI value */ + amHdr->li[amHdr->numLi++] = hdrInfo.val; + totalSz += hdrInfo.val; /* incrment the size by LI value */ + } + + /*ccpu00122597:PDU is dropped if liCnt exceeds KW_MAX_LI*/ + if(e && (amHdr->numLi >= KW_MAX_UL_LI)) + { + RLOG2(L_ERROR,"LI Count [%u] exceeds Max LI Count[%u]", + amHdr->numLi, KW_MAX_UL_LI); + RETVALUE(RFAILED); + } + + /* first 2 bytes + Add one for Odd LI*/ + pduSz -= ( amHdr->numLi + (amHdr->numLi >> 1) + 2 + (amHdr->numLi & 1) ); + + if ( totalSz >= pduSz ) + { + RLOG3(L_ERROR,"SN [%d]:Corrupted PDU as TotSz[%lu] PduSz[%lu] ", + amHdr->sn, totalSz, pduSz); + RETVALUE(RFAILED); + } + + RETVALUE(ROK); +} +#endif + +/** + * @brief Private handler to process the status PDU + * + * @details + * Private handler invokded by kwAmmProcessPdus to process the + * control PDU (status report) received from its peer RLC entity. + * + * - Decode the values from the received control pdu + * - Create a KwUdxStaPdu structure, copy the values onto it and + * send it to the DL instance for further processing + * + * @param[in] gCb RLC instance control block + * @param[in] rbCb Uplink RB control block + * @param[in] cntrlPdu Control PDU received from MAC + * @param[in] fByte First byte already removed from the STATUS PDU + * + * @return Void + * + */ +#ifdef ANSI +PRIVATE Void kwAmmUlHndlStatusPdu +( +KwCb *gCb, +KwUlRbCb *rbCb, +Buffer *cntrlPdu, +U8 *fByte +) +#else +PRIVATE Void kwAmmUlHndlStatusPdu(gCb, rbCb, cntrlPdu, fByte) +KwCb *gCb; +KwUlRbCb *rbCb; +Buffer *cntrlPdu; +U8 *fByte; +#endif +{ + U8 e1; + KwExtHdr hdrInfo; + KwUdxStaPdu *pStaPdu; + KwUdxUlSapCb *sapCb; + U8 e3; /* NACK RANGE : 5GNR */ + U32 snLen; + U32 snRange; + U32 resrvdBitsAckSn=0; + U32 resrvdBitsNackSn=0; + + TRC2(kwAmmUlHndlStatusPdu) + + + KW_MEM_ZERO(&hdrInfo, sizeof(KwExtHdr)); + + /* Extract the Control PDU */ + hdrInfo.hdr = (*fByte << 1); + hdrInfo.pLen = 4; + + /* D/C has been shifted in the calling function */ + if (hdrInfo.hdr & 0xE0) + { + RLOG_ARG2(L_ERROR,DBG_RBID,rbCb->rlcId.rbId, + "Reserved value for CPT received UEID:%d CELLID:%d", + rbCb->rlcId.ueId, + rbCb->rlcId.cellId); + + RETVOID; + } + + sapCb = KW_GET_UDX_SAP(gCb); + + KW_ALLOC_SHRABL_BUF(sapCb->pst.region, + sapCb->pst.pool, + pStaPdu, + sizeof(KwUdxStaPdu)); + +#if (ERRCLASS & ERRCLS_ADD_RES) + /* Memory allocation failure can not be expected */ + if(!pStaPdu) + { + RETVOID; + } +#endif + + if (rbCb->m.amUl.snLen == KW_AM_CFG_12BIT_SN_LEN) + { + snLen = 12; + resrvdBitsAckSn = KW_STA_PDU_R_BITS_ACKSN_12BITS; + resrvdBitsNackSn = KW_STA_PDU_R_BITS_NACKSN_12BITS; + } + else if (rbCb->m.amUl.snLen == KW_AM_CFG_18BIT_SN_LEN) + { + snLen = 18; + resrvdBitsAckSn = KW_STA_PDU_R_BITS_ACKSN_18BITS; + resrvdBitsNackSn = KW_STA_PDU_R_BITS_NACKSN_18BITS; + } + else + { + snLen = KW_SN_LEN; + resrvdBitsAckSn = 0; + resrvdBitsAckSn = 0; + } + + pStaPdu->nackCnt = 0; + /* For CPT */ + hdrInfo.hdr = hdrInfo.hdr << KW_CPT_LEN; + + /* ACK Sn */ + hdrInfo.len = snLen; + kwAmmExtractElmnt(gCb, cntrlPdu, &hdrInfo); + pStaPdu->ackSn = hdrInfo.val; + + //printf ("++++++++++++ 5GNRLOG HNDL STATUS acksn %d : \n", pStaPdu->ackSn); + /* Check if NACK Exists */ + hdrInfo.len = KW_E1_LEN; + kwAmmExtractElmnt(gCb, cntrlPdu, &hdrInfo); + e1 = (U8)hdrInfo.val; + RLOG_ARG3(L_UNUSED,DBG_RBID,rbCb->rlcId.rbId, + "kwAmmUlHndlStatusPdu: ACK SN = %d UEID:%d CELLID:%d", + pStaPdu->ackSn, + rbCb->rlcId.ueId, + rbCb->rlcId.cellId); + + /* Extract the Reserved Bits after ACK SN field */ + hdrInfo.len = resrvdBitsAckSn; + kwAmmExtractElmnt(gCb, cntrlPdu, &hdrInfo); + + /* If NACK exists in control PDU */ + /* For ACKs and NACKs */ + while (e1 && (pStaPdu->nackCnt < KW_MAX_NACK_CNT)) + { + hdrInfo.len = snLen; + kwAmmExtractElmnt(gCb, cntrlPdu, &hdrInfo); + pStaPdu->nackInfo[pStaPdu->nackCnt].sn = hdrInfo.val; + + hdrInfo.len = KW_E1_LEN; + kwAmmExtractElmnt(gCb, cntrlPdu, &hdrInfo); + e1 = (U8)hdrInfo.val; + + /* Extract e2 */ + /* hdrInfo.len = KW_E1_LEN; --> previusly stored value (for e1) is + already present*/ + kwAmmExtractElmnt(gCb, cntrlPdu, &hdrInfo); + /* e2 = (U8) hdrInfo.val;*/ + + /* Store e2 value */ + pStaPdu->nackInfo[pStaPdu->nackCnt].isSegment = (U8) hdrInfo.val; + + /* Extract e3 : 5GNR */ + /* hdrInfo.len = KW_E1_LEN; --> previusly stored value (for e1) is + already present*/ + kwAmmExtractElmnt(gCb, cntrlPdu, &hdrInfo); + e3 = (U8) hdrInfo.val; + + /* Extract Reserved Bits after NACK SN */ + hdrInfo.len = resrvdBitsNackSn; + kwAmmExtractElmnt(gCb, cntrlPdu, &hdrInfo); + + /* Test for resegmentation */ + if (pStaPdu->nackInfo[pStaPdu->nackCnt].isSegment) + { + hdrInfo.len = KW_SO_LEN_5GNR; /* 5GNR : SO Len 16 Bits */ + kwAmmExtractElmnt(gCb, cntrlPdu, &hdrInfo); + pStaPdu->nackInfo[pStaPdu->nackCnt].soStart = hdrInfo.val; + + kwAmmExtractElmnt(gCb, cntrlPdu, &hdrInfo); + pStaPdu->nackInfo[pStaPdu->nackCnt].soEnd = hdrInfo.val; + + RLOG_ARG4(L_DEBUG,DBG_RBID,rbCb->rlcId.rbId, + "kwAmmUlHndlStatusPdu: soStart and soEnd = %d %d" + "UEID:%d CELLID:%d", + pStaPdu->nackInfo[pStaPdu->nackCnt].soStart, + pStaPdu->nackInfo[pStaPdu->nackCnt].soEnd, + rbCb->rlcId.ueId, + rbCb->rlcId.cellId); + } + else + { + hdrInfo.len = 0; + pStaPdu->nackInfo[pStaPdu->nackCnt].soStart = 0; + pStaPdu->nackInfo[pStaPdu->nackCnt].soEnd = 0; + + } + /* NACK RANGE Field is SET */ + if (e3) + { + /* Extract NACK range field */ + hdrInfo.len = KW_NACK_RANGE_LEN; + kwAmmExtractElmnt(gCb, cntrlPdu, &hdrInfo); + snRange = (U8)hdrInfo.val; + + pStaPdu->nackInfo[pStaPdu->nackCnt].nackRange = snRange; + + } + pStaPdu->nackCnt++; + } + + gRlcStats.amRlcStats.numULStaPduRcvd++; + gRlcStats.amRlcStats.numULNackInStaPduRcvd += pStaPdu->nackCnt; + + /* In case we have reached the MAX NACK CNT, then we should modify the ACK_SN + to the last NACK SN + 1 and discard the original ACK_SN*/ + if(pStaPdu->nackCnt == KW_MAX_NACK_CNT) + { + pStaPdu->ackSn = (pStaPdu->nackInfo[KW_MAX_NACK_CNT-1].sn + 1) & (rbCb->m.amUl.snModMask); + } + + + /* Parse & send Status PDU to RLC-DL */ + KwUlUdxStaUpdReq(&(sapCb->pst), sapCb->spId, &rbCb->rlcId, pStaPdu); + + RETVOID; +} + +/** + * @brief Private handler to release all stored segments + * + * @details + * Private handler invokded by kwAmmUlPlacePduInRecBuf to release the + * stored segements in case a complete PDU is received later. + * + * @param[in] gCb RLC instance control block + * @param[in] recBuf Buffer that stores a received PDU or segments + * + * @return Void + * + */ +#ifdef ANSI +PRIVATE Void kwAmmUlRlsAllSegs +( +KwCb *gCb, +KwAmRecBuf *recBuf +) +#else +PRIVATE Void kwAmmUlRlsAllSegs(gCb,recBuf) +KwCb *gCb; +KwAmRecBuf *recBuf; +#endif +{ + KwSeg *seg; + + TRC2(kwAmmUlRlsAllSegs) + + KW_LLIST_FIRST_SEG(recBuf->segLst, seg); + while (seg != NULLP) + { + KW_FREE_BUF_WC(seg->seg); + cmLListDelFrm(&(recBuf->segLst),&(seg->lstEnt)); + KW_FREE_WC(gCb,seg, sizeof(KwSeg)); + KW_LLIST_FIRST_SEG(recBuf->segLst, seg); + } + + RETVOID; +} + +/** + * @brief Private handler to store the received segment + * + * @details + * Private handler invokded by kwAmmUlPlacePduInRecBuf to add a received + * segment in reception buffer of a RBCB. + * - It is responsible for detecting duplicate segments + * - Adding it at appropriate position in the received buffer + * - Calling ExpByteSeg to set expSo field in the receiver buffer + * + * @param[in] gCb RLC instance control block + * @param[in] rbCb Radio Bearer Contro Block + * @param[in] amHdr AM Header received + * @param[in] pdu Buffer received other than the headers + * @param[in] pduSz size of the PDU buffer received + * + * @return Bool + * -#TRUE Successful insertion into the receiver buffer + * -#FALSE Possibly a duplicate segment + */ +#ifdef ANSI +PRIVATE Bool kwAmmAddRcvdSeg +( +KwCb *gCb, +KwUlRbCb *rbCb, +KwAmHdr *amHdr, +Buffer *pdu, +U16 pduSz +) +#else +PRIVATE Bool kwAmmAddRcvdSeg(gCb, rbCb, amHdr, pdu, pduSz) +KwCb *gCb; +KwUlRbCb *rbCb; +KwAmHdr *amHdr; +Buffer *pdu; +U16 pduSz; +#endif +{ + KwAmRecBuf *recBuf = NULLP; + KwSeg *seg; + KwSeg *tseg; + U16 soEnd; /* Holds the SoEnd of received segment */ + U16 expSo = 0; /* Expected SO */ + + TRC2(kwAmmAddRcvdSeg) + + soEnd = amHdr->so + pduSz - 1; + recBuf = kwUtlGetRecBuf(AMUL.recBufLst, amHdr->sn); + + if (NULLP == recBuf) + { + KW_ALLOC(gCb,recBuf, sizeof(KwAmRecBuf)); +#if (ERRCLASS & ERRCLS_ADD_RES) + if (recBuf == NULLP) + { + RLOG_ARG2(L_FATAL,DBG_RBID,rbCb->rlcId.rbId, + "Memory allocation failed UEID:%d CELLID:%d", + rbCb->rlcId.ueId, + rbCb->rlcId.cellId); + + KW_FREE_BUF(pdu); + RETVALUE(FALSE); + } +#endif /* ERRCLASS & ERRCLS_RES */ + kwUtlStoreRecBuf(AMUL.recBufLst, recBuf, amHdr->sn); + } + else + { + if (recBuf->allRcvd == TRUE) + { + KW_FREE_BUF(pdu); + RETVALUE(FALSE); + } + } + + recBuf->isDelvUpperLayer = FALSE; + /* kw003.201 - Move past the segments that are different than the */ + /* one received. */ + KW_LLIST_FIRST_SEG(recBuf->segLst, seg); + while ((seg != NULLP) && (seg->amHdr.so < amHdr->so)) + { + expSo = seg->amHdr.so + seg->segSz; + KW_LLIST_NEXT_SEG(recBuf->segLst, seg); + } + + /* The received segment should start after the end of previous seg */ + if (expSo > amHdr->so) + { + /* This is a duplicate segment */ + gRlcStats.amRlcStats.numRlcAmCellDupPduRx++; + KW_FREE_BUF(pdu); + RETVALUE(FALSE); + } + + if ((seg) && (seg->amHdr.so <= soEnd)) + { + /* This is a duplicate segment */ + gRlcStats.amRlcStats.numRlcAmCellDupPduRx++; + KW_FREE_BUF(pdu); + RETVALUE(FALSE); + } + + /* If we have come this far, we have to add this segment to the */ + /* reception buffer as we either have eliminated duplicates or */ + /* have found none. */ + KW_ALLOC_WC(gCb,tseg, sizeof(KwSeg)); +#if (ERRCLASS & ERRCLS_ADD_RES) + if (tseg == NULLP) + { + RLOG_ARG2(L_FATAL,DBG_RBID,rbCb->rlcId.rbId, + "Memory allocation failed UEID:%d CELLID:%d", + rbCb->rlcId.ueId, + rbCb->rlcId.cellId); + KW_FREE_BUF(pdu); + RETVALUE(FALSE); + } +#endif /* ERRCLASS & ERRCLS_RES */ + + tseg->seg = pdu; + tseg->segSz = pduSz; + KW_MEM_CPY(&tseg->amHdr, amHdr, sizeof(KwAmHdr)); + recBuf->amHdr.si = amHdr->si; + recBuf->amHdr.sn = amHdr->sn; + tseg->soEnd = soEnd; + if (seg == NULLP) + { + cmLListAdd2Tail(&recBuf->segLst, &tseg->lstEnt); + } + else + { + recBuf->segLst.crnt = &seg->lstEnt; + cmLListInsCrnt(&recBuf->segLst, &tseg->lstEnt); + } + tseg->lstEnt.node = (PTR)tseg; + kwAmmUpdExpByteSeg(gCb,&AMUL,tseg); + + RETVALUE(TRUE); +} + +/** + * @brief Private handler to place the PDU in the reception buffer + * + * @details + * This function checks if the received PDU's SN falls within the + * receiving window, after which it places the same in the reception + * buffer if its not a duplicate. + * + * @param[in] gCb RLC instance control block + * @param[in] pdu Received PDU + * @param[in] rbCb Uplink AM Radio Bearer + * @param[out] amUl AM UL Info + * + * @return Bool + * -# TRUE + * -# FALSE + * + */ +#ifdef ANSI +PRIVATE Bool kwAmmUlPlacePduInRecBuf +( +KwCb *gCb, +Buffer *pdu, +KwUlRbCb *rbCb, +KwAmHdr *amHdr +) +#else +PRIVATE Bool kwAmmUlPlacePduInRecBuf(gCb, pdu, rbCb, amHdr) +KwCb *gCb; +Buffer *pdu; +KwUlRbCb *rbCb; +KwAmHdr *amHdr; +#endif +{ + KwSn sn; + MsgLen pduSz; + KwAmUl *amUl = &(rbCb->m.amUl); + + TRC2(kwAmmUlPlacePduInRecBuf) + + + sn = amHdr->sn; + SFndLenMsg(pdu, &pduSz); + + gCb->genSts.bytesRecv += pduSz; + gRlcStats.amRlcStats.numRlcAmCellSduBytesRx += pduSz; + if (!KW_AM_CHK_SN_WITHIN_RECV_WINDOW(sn, amUl)) + { + gRlcStats.amRlcStats.numRlcAmCellDropOutWinRx++; + RLOG_ARG3(L_UNUSED,DBG_RBID,rbCb->rlcId.rbId, + "kwAmmUlPlacePduInRecBuf: SN %d outside the window" + "UEID:%d CELLID:%d", + sn, + rbCb->rlcId.ueId, + rbCb->rlcId.cellId); + + gCb->genSts.unexpPdusRecv++; + KW_FREE_BUF(pdu); + RETVALUE(FALSE); + } + + if (amHdr->si == 0) + { + KwAmRecBuf *recBuf = kwUtlGetRecBuf(amUl->recBufLst, sn); + + /* We received a complete PDU. Either we already have it, in which */ + /* case we just ignore the new PDU and discard it. Otherwise, */ + /* store the received PDU in the reception buffer */ + if (NULLP == recBuf) + { + KW_ALLOC(gCb, recBuf, sizeof(KwAmRecBuf)); +#if (ERRCLASS & ERRCLS_ADD_RES) + if (recBuf == NULLP) + { + RLOG_ARG2(L_FATAL,DBG_RBID,rbCb->rlcId.rbId, + "Memory allocation failed UEID:%d CELLID:%d", + rbCb->rlcId.ueId, + rbCb->rlcId.cellId); + KW_FREE_BUF(pdu); + RETVALUE(FALSE); + } +#endif /* ERRCLASS & ERRCLS_RES */ + kwUtlStoreRecBuf(AMUL.recBufLst, recBuf, sn); + } + else if (recBuf->allRcvd != TRUE) + { + kwAmmUlRlsAllSegs(gCb,recBuf); + } + else + { + gRlcStats.amRlcStats.numRlcAmCellDupPduRx++; + gCb->genSts.unexpPdusRecv++; + KW_FREE_BUF(pdu); + RETVALUE(FALSE); + } + recBuf->isDelvUpperLayer = FALSE; + recBuf->pdu = pdu; + recBuf->pduSz = pduSz; + recBuf->allRcvd = TRUE; + gRlcStats.amRlcStats.numRlcAmCellSduRx++; + KW_MEM_CPY(&recBuf->amHdr, amHdr, sizeof(KwAmHdr)); + RETVALUE(TRUE); + } + else + { + /* We received a segment. We need to add that to the existing */ + /* segments, if any. */ + RETVALUE(kwAmmAddRcvdSeg(gCb,rbCb, amHdr, pdu, pduSz)); + } +} + +/** + * @brief Private handler to trigger status report + * + * @details + * Private handler invokded by kwAmmProcessPdus to check if the + * status report need to be sent, and update the status trigger + * flag accordingly based on status prohibit timer. + * + * - Check if the received pdu's sn is less than rxHighestStatus, set the + * staTrg flag. + * - If staProhTmr is not running, calculate cntrlBo, else it'll be + * updated at the expiry of staProhTmr. + * - Expiry of reOrdTmr also will set staTrg flag. + * + * @param[in] gCb RLC instance control block + * @param[in] rbCb Uplink RB control block + * @param[in] sn Sequence number of the pdu based on which to check if + * status needs to be triggered + * @param[in] discFlg Whether this pdu was discarded or not + * + * @return Void + * + */ +#ifdef ANSI +PRIVATE Void kwAmmTriggerStatus +( +KwCb *gCb, +KwUlRbCb *rbCb, +KwSn sn, +Bool discFlg +) +#else +PRIVATE Void kwAmmTriggerStatus(gCb,rbCb, sn, discFlg) +KwCb *gCb; +KwUlRbCb *rbCb; +KwSn sn; +Bool discFlg; +#endif +{ + Bool tmrRunning; + KwSn tSn; + KwSn tVrMr; + KwSn trxHighestStatus; + KwAmUl *amUl = &(rbCb->m.amUl); + + TRC2(kwAmmTriggerStatus) + + + MODAMR(amUl->vrMr, tVrMr, amUl->rxNext, amUl->snModMask); + MODAMR(amUl->rxHighestStatus, trxHighestStatus, amUl->rxNext, amUl->snModMask); + MODAMR(sn , tSn, amUl->rxNext, amUl->snModMask); + + /* kw005.201 Product CR ccpu00117114 * + * The "=" in the 2nd condition is removed */ + if ((discFlg) || (tSn < trxHighestStatus) || (tSn >= tVrMr)) + { + RLOG_ARG2(L_UNUSED,DBG_RBID,rbCb->rlcId.rbId, + "kwAmmTriggerStatus: Set Status Trigger UEID:%d CELLID:%d", + rbCb->rlcId.ueId, + rbCb->rlcId.cellId); + + amUl->staTrg = TRUE; + amUl->gatherStaPduInfo = FALSE; + + /* Check if staProhTmr is running */ + tmrRunning = kwChkTmr(gCb,(PTR) rbCb, KW_EVT_AMUL_STA_PROH_TMR); + + if (!tmrRunning) + { + amUl->gatherStaPduInfo = TRUE; + } + } + + RETVOID; +} + +/** + * @brief Private handler to reassemble from a segment or a PDU + * + * @details + * Private handler invokded by kwAmmReassembleSdus with either a + * PDU or a segment of a PDU. This is also called in the case of + * reestablishment and hence out of sequence joining is also to + * be supported + * + * + * @param[in] gCb RLC instance control block + * @param[in] rbCb Uplink RB control block + * @param[in] amHdr AM header received for this segment/PDU + * @param[in] pdu PDU to be reassembled + * + * @return Void + * + */ +#ifdef ANSI +PRIVATE Void kwAmmProcPduOrSeg +( +KwCb *gCb, +KwUlRbCb *rbCb, +KwAmHdr *amHdr, +Buffer *pdu +) +#else +PRIVATE Void kwAmmProcPduOrSeg(gCb, rbCb, amHdr, pdu) +KwCb *gCb; +KwUlRbCb *rbCb; +KwAmHdr *amHdr; +Buffer *pdu; +#endif +{ + + TRC2(kwAmmProcPduOrSeg) + + if ((AMUL.expSn != amHdr->sn) || (AMUL.expSo != amHdr->so)) + { + /* Release the existing partial SDU as we have PDUs or */ + /* segments that are out of sequence */ + rbCb->m.amUl.isOutOfSeq = TRUE; + KW_FREE_BUF(AMUL.partialSdu); + } + + //if (amHdr->fi & KW_FI_FIRST_SEG) + if (amHdr->si == 0x01) + {/* first Segment of the SDU */ + if (AMUL.partialSdu != NULLP) + { /* Some old SDU may be present */ + KW_FREE_BUF_WC(AMUL.partialSdu); + } + AMUL.partialSdu = pdu; + pdu = NULLP; + } + else if(amHdr->si == 0x03) + {/* Middle or last segment of the SUD */ + SCatMsg(AMUL.partialSdu,pdu, M1M2); + KW_FREE_BUF_WC(pdu); + pdu = NULLP; + } + else if (amHdr->si == 0x02) + { + SCatMsg(pdu,AMUL.partialSdu,M2M1); + KW_FREE_BUF_WC(AMUL.partialSdu); + } + + if (pdu != NULLP) + { + AMUL.partialSdu = NULLP; + kwUtlSndDatInd(gCb,rbCb, pdu); + } + + RETVOID; +} + +/** + * + * @brief Private handler to reassemble SDUs + * + * @details + * Private handler invokded by kwAmmProcessPdus with the PDU + * from the reception buffer in sequence to reassemble SDUs and + * send it to PDCP. + * + * - With the stored header info, FI and LSF segment / concatenate + * PDUs or byte segments of PDUs to get the associated SDU. + * + * @param[in] rbCb RB control block + * @param[in] pdu PDU to be reassembled + * + * @return S16 + * -# ROK + * -# RFAILED + * + */ +#ifdef ANSI +PRIVATE S16 kwAmmUlReassembleSdus +( +KwCb *gCb, +KwUlRbCb *rbCb, +KwAmRecBuf *recBuf +) +#else +PRIVATE S16 kwAmmUlReassembleSdus(gCb, rbCb, recBuf) +KwCb *gCb; +KwUlRbCb *rbCb; +KwAmRecBuf *recBuf; +#endif +{ + KwSeg *seg; + + TRC2(kwAmmUlReassembleSdus) + //if (recBuf->amHdr.rf == 0) + if (recBuf->amHdr.si == 0) + { + /* This is a PDU */ + kwAmmProcPduOrSeg(gCb,rbCb, &recBuf->amHdr, recBuf->pdu); + /* Assign NULLP to recBuf->pdu as this PDU is sent to PDCP */ + recBuf->pdu = NULLP; + AMUL.expSn = (recBuf->amHdr.sn + 1) & (AMUL.snModMask); /* MOD 1024 */ + AMUL.expSo = 0; + } + else + { + /* This is a set of segments */ + KW_LLIST_FIRST_SEG(recBuf->segLst, seg); + AMUL.expSn = recBuf->amHdr.sn; + AMUL.expSo = 0; + while(seg) + { + kwAmmProcPduOrSeg(gCb,rbCb, &seg->amHdr, seg->seg); + AMUL.expSo = seg->soEnd + 1; + + cmLListDelFrm(&(recBuf->segLst),&(seg->lstEnt)); + KW_FREE_WC(gCb, seg, sizeof(KwSeg)); + + KW_LLIST_FIRST_SEG(recBuf->segLst, seg); + } + AMUL.expSn = (recBuf->amHdr.sn + 1) & (AMUL.snModMask); /* MOD 1024 */ + AMUL.expSo = 0; + } + + RETVALUE(ROK); +} + +/** + * @brief Handler to process the re-establishment request received from UIM + * + * @param[in] gCb RLC instance control block + * @param[in] rlcId RLC identifier + * @param[in] sendReEst Whether to send back restablishment complete or not + * @param[in] rbCb Uplink RB control block + * + * @return Void + * + */ +#ifdef ANSI +PUBLIC Void kwAmmUlReEstablish +( +KwCb *gCb, +CmLteRlcId rlcId, +Bool sendReEst, +KwUlRbCb *rbCb +) +#else +PUBLIC Void kwAmmUlReEstablish(gCb, rlcId, sendReEst, rbCb) +KwCb *gCb; +CmLteRlcId rlcId; +Bool sendReEst; +KwUlRbCb *rbCb; +#endif +{ + KwSn sn; + KwSn mSn; + KwSn mVrMr; + +#ifndef KW_PDCP + KwKwuSapCb *kwKwSap; +#endif + KwAmRecBuf *recBuf = NULLP; + + TRC2(kwAmmUlReEstablish); + + + sn = AMUL.rxNext; + + MODAMR(AMUL.vrMr, mVrMr, AMUL.rxNext, AMUL.snModMask); + MODAMR(sn, mSn, AMUL.rxNext, AMUL.snModMask); + + /* Reassemble SDUs from PDUs with SN less than upper edge of the window */ + while (mSn < mVrMr) + { + recBuf = kwUtlGetRecBuf(AMUL.recBufLst, sn); + if (NULLP != recBuf) + { + if (recBuf->allRcvd == TRUE) + { + kwAmmUlReassembleSdus(gCb,rbCb, recBuf); + } + else + { + /* Remove PDU and segments */ + if(recBuf->pdu) + { + KW_FREE_BUF_WC(recBuf->pdu); + } + /* Release all the segments*/ + kwAmmUlRlsAllSegs(gCb,recBuf); + } + kwUtlDelRecBuf(AMUL.recBufLst, recBuf, gCb); + } + sn = (sn + 1) & (AMUL.snModMask); /* MOD 1024 */ + MODAMR(sn, mSn, AMUL.rxNext, AMUL.snModMask); + } + /* Discard remaining PDUs and bytesegments in recBuf */ + + /* Stop all timers and reset variables */ + if(TRUE == kwChkTmr(gCb,(PTR)rbCb,KW_EVT_AMUL_REORD_TMR)) + { + kwStopTmr(gCb,(PTR)rbCb, KW_EVT_AMUL_REORD_TMR); + } + if(TRUE == kwChkTmr(gCb,(PTR)rbCb,KW_EVT_AMUL_STA_PROH_TMR)) + { + kwStopTmr(gCb,(PTR)rbCb, KW_EVT_AMUL_STA_PROH_TMR); + } + + AMUL.rxNext = 0; + AMUL.rxNextHighestRcvd = 0; + AMUL.rxNextStatusTrig = 0; + rbCb->m.amUl.vrMr = (rbCb->m.amUl.rxNext + KW_AM_GET_WIN_SZ(rbCb->m.amUl.snLen)) & (rbCb->m.amUl.snModMask); + AMUL.rxHighestStatus = 0; + AMUL.staTrg = FALSE; + AMUL.gatherStaPduInfo = FALSE; + AMUL.expSn = 0; + AMUL.expSo = 0; + if (AMUL.partialSdu != NULLP) + { + KW_FREE_BUF(AMUL.partialSdu); + } + kwKwSap = gCb->u.ulCb->kwuUlSap + KW_UI_PDCP; + + if(sendReEst) + { + KwUiKwuReEstCmpInd(&kwKwSap->pst, kwKwSap->suId, rlcId); + rbCb->m.amUl.isOutOfSeq = FALSE; + } + + RETVOID; +} + +/** + * @brief Handler for reorder timer expiry + * + * @details + * This function is used to handle events upon expiry of reorder timer + * + * @param[in] gCb RLC instance control block + * @param[in] rbCb RB control block + * + * @return Void + * + */ + +#ifdef ANSI +PUBLIC Void kwAmmReOrdTmrExp +( +KwCb *gCb, +KwUlRbCb *rbCb +) +#else +PUBLIC Void kwAmmReOrdTmrExp(rbCb) +KwCb *gCb; +KwUlRbCb *rbCb; +#endif +{ + KwAmUl *amUl = &(rbCb->m.amUl); + KwSn sn; + KwSn mSn; + KwSn mVrMr; + KwSn mrxHighestStatus; + KwSn mrxNextHighestRcvd; + Bool tmrRunning = FALSE; + KwAmRecBuf *recBuf = NULLP; + + TRC2(kwAmmReOrdTmrExp); + + + /* Update rxHighestStatus */ + sn = amUl->rxNextStatusTrig; + + MODAMR(sn, mSn, amUl->rxNext, amUl->snModMask); + MODAMR(amUl->vrMr, mVrMr, amUl->rxNext, amUl->snModMask); + recBuf = kwUtlGetRecBuf(AMUL.recBufLst, sn); + + while (mSn < mVrMr) + { + if ((recBuf == NULLP) || + ((recBuf != NULLP) && (!recBuf->allRcvd)) ) + { + amUl->rxHighestStatus = sn; + amUl->staTrg = TRUE; + amUl->gatherStaPduInfo = FALSE; + + /* Check if staProhTmr is running */ + tmrRunning = kwChkTmr(gCb,(PTR) rbCb, KW_EVT_AMUL_STA_PROH_TMR); + + if (!tmrRunning) + { + gRlcStats.amRlcStats.numULReOrdTimerExpires++; + amUl->gatherStaPduInfo = TRUE; + kwAmmUlAssembleCntrlInfo(gCb, rbCb); + } + + break; + } + sn = (sn + 1) & (amUl->snModMask); + MODAMR(sn, mSn, amUl->rxNext, amUl->snModMask); + } + + /* Update rxNextStatusTrig */ + MODAMR(amUl->rxNextHighestRcvd, mrxNextHighestRcvd, amUl->rxNext, amUl->snModMask); + MODAMR(amUl->rxHighestStatus, mrxHighestStatus, amUl->rxNext, amUl->snModMask); + if (mrxNextHighestRcvd > mrxHighestStatus) + { + kwStartTmr(gCb,(PTR)rbCb, KW_EVT_AMUL_REORD_TMR); + amUl->rxNextStatusTrig = amUl->rxNextHighestRcvd; + } + + RETVOID; +} /* kwAmmReOrdTmrExp */ + +/** + * @brief Handler for status prohibit timer expiry + * + * @details + * This function is used to handle events upon expiry of status prohibit + * timer + * + * @param[in] gCb RLC instance control block + * @param[in] rbCb RB control block + * + * @return Void + * + */ + +#ifdef ANSI +PUBLIC Void kwAmmStaProTmrExp +( +KwCb *gCb, +KwUlRbCb *rbCb +) +#else +PUBLIC Void kwAmmStaProTmrExp(gCb, rbCb) +KwCb *gCb; +KwUlRbCb *rbCb; +#endif +{ + KwAmUl *amUl = &(rbCb->m.amUl); + + TRC2(kwAmmStaProTmrExp); + + + amUl->gatherStaPduInfo = FALSE; + + if (amUl->staTrg == TRUE) + { + amUl->gatherStaPduInfo = TRUE; + /* kw002.201 : Sending StaRsp after StaProhibit tmr expiry */ + kwAmmUlAssembleCntrlInfo(gCb,rbCb); + } + + RETVOID; +} /* kwAmmStaProTmrExp */ + +/** + * @brief Handler to extract an element of AM Header + * + * @details + * This function is used to extract an element of AM header. + * + * @param[in] pdu The pdu to be decoded + * @param[in,out] hdrInfo Container to hold the decoded info + * + * @return Void + * + */ + +#ifdef ANSI +PRIVATE Void kwAmmExtractElmnt +( +KwCb *gCb, +Buffer *pdu, +KwExtHdr *hdrInfo +) +#else +PRIVATE Void kwAmmExtractElmnt(gCb, pdu, hdrInfo) +KwCb *gCb; +Buffer *pdu; +KwExtHdr *hdrInfo; +#endif +{ + U8 hdr; + U8 pLen = hdrInfo->pLen; + U8 len = (U8)hdrInfo->len; + U32 val; + U8 tHdr; + U8 fLen; + U8 rLen; + /* U8 rLen1 = 0; */ + U16 tVal; + + TRC2(kwAmmExtractElmnt); + + hdr = hdrInfo->hdr; + + if (pLen == 0) + { + SRemPreMsg(&hdr, pdu); + pLen = 8; + } + tHdr = hdr; + if (len <= 8) + { + val = tHdr >> (KW_BYTE_LEN - (len)); + hdr = hdr << len; + pLen -= len; + } + else /*if (len > 8) */ + { + fLen = pLen; + val = tHdr; + val = val >> (KW_BYTE_LEN - fLen); + val = val << (len - fLen); + rLen = len - fLen; + SRemPreMsg(&hdr, pdu); + tHdr = hdr; + if (rLen <= 8) + { + hdr = hdr >> (KW_BYTE_LEN - rLen); + val = val | hdr; + hdr = tHdr << rLen; + pLen = (KW_BYTE_LEN - rLen); + } + else + { + rLen = rLen - KW_BYTE_LEN; + tVal = hdr; + tVal = tVal << rLen; + val = val | tVal; + + SRemPreMsg(&hdr, pdu); + tHdr = hdr; + hdr = hdr >> (KW_BYTE_LEN - rLen); + val = val | hdr; + hdr = tHdr << rLen; + pLen = (KW_BYTE_LEN - rLen); + } + } + + hdrInfo->pLen = pLen; + hdrInfo->hdr = hdr; + hdrInfo->val = val; + + RETVOID; +} + +/** + * @brief Handler to updated expected byte seg + * + * @details + * This function is used to update expected byte segment. The next segment + * expected is indicated by the SO of the segment which is expected. Intially + * the segment with SO 0 is expected and then in order. When all the segments + * are received (which would happen when an expected SO is encountered + * with LSF set) the allRcvd flag is set to TRUE + * + * @param[in] gCb RLC instance control block + * @param[in] amUl AM Uplink Control Block + * @param[in] seg Newly received segment + * + * @return Void + * + */ + +#ifdef ANSI +PRIVATE Void kwAmmUpdExpByteSeg +( +KwCb *gCb, +KwAmUl *amUl, +KwSeg *seg +) +#else +PRIVATE Void kwAmmUpdExpByteSeg(gCb, amUl, seg) +KwCb *gCb; +KwAmUl *amUl; +KwSeg *seg; +#endif +{ + U16 newExpSo; /* The new expected SO */ + KwSn sn = seg->amHdr.sn; + Bool lstRcvd=FALSE; + KwAmRecBuf *recBuf = NULLP; + + TRC2(kwAmmUpdExpByteSeg); + + + recBuf = kwUtlGetRecBuf(amUl->recBufLst, sn); + if ((recBuf == NULLP) || (recBuf && (seg->amHdr.so != recBuf->expSo))) + { + RETVOID; + } + + newExpSo = seg->soEnd + 1; + recBuf->expSo = newExpSo; + //lstRcvd = seg->amHdr.lsf; + if(seg->amHdr.si == 0x2) + { + lstRcvd = TRUE; + } + /* kw003.201 - This should update seg with the one after newSeg */ + KW_LLIST_NEXT_SEG(recBuf->segLst, seg); + while(seg) + { + /* keep going ahead as long as the expectedSo match with the header so + else store the expSo for later checking again */ + if(seg->amHdr.si == 0x2) + { + lstRcvd = TRUE; + } + if (seg->amHdr.so == newExpSo) + { + newExpSo = seg->soEnd + 1; + recBuf->expSo = newExpSo; + //lstRcvd = seg->amHdr.lsf; + KW_LLIST_NEXT_SEG(recBuf->segLst, seg); + } + else + { + recBuf->expSo = newExpSo; + RETVOID; + } + } + if (lstRcvd == TRUE) + { + recBuf->allRcvd = TRUE; + gRlcStats.amRlcStats.numRlcAmCellSduRx++; + } + + RETVOID; +} + +/** + * @brief + * Function to release/free the Acknowledged Mode Module RbCb buffers + * + * @details + * This primitive Frees the AM RbCb transmission Buffer, retransmission + * Buffer and reciption Buffers + * + * @param [in] gCb - RLC instance Control Block + * @param [in] rbCb - RB Control Block + * + * @return void + */ +#ifdef ANSI +PUBLIC Void kwAmmFreeUlRbCb +( +KwCb *gCb, +KwUlRbCb *rbCb +) +#else +PUBLIC Void kwAmmFreeUlRbCb(gCb,rbCb) +KwCb *gCb; +KwUlRbCb *rbCb; +#endif +{ + KwSn curSn = 0; /* Sequence number of PDU */ + KwSn windSz; /* PDU window size */ + KwAmRecBuf *recBuf = NULLP; + + TRC2(kwAmmFreeUlRbCb) + + + windSz = (KW_AM_GET_WIN_SZ(rbCb->m.amUl.snLen)) << 1; + + if(TRUE == kwChkTmr(gCb,(PTR)rbCb,KW_EVT_AMUL_REORD_TMR)) + { + kwStopTmr(gCb,(PTR)rbCb, KW_EVT_AMUL_REORD_TMR); + } + if(TRUE == kwChkTmr(gCb,(PTR)rbCb,KW_EVT_AMUL_STA_PROH_TMR)) + { + kwStopTmr(gCb,(PTR)rbCb, KW_EVT_AMUL_STA_PROH_TMR); + } + + + /* on the first loop winSz is always greater than zero + while( ( curSn < windSz ) hence changing to do while */ + do + { + recBuf = kwUtlGetRecBuf(rbCb->m.amUl.recBufLst, curSn); + if ( recBuf != NULLP ) + { + if (recBuf->pdu != NULLP) + { + KW_FREE_BUF_WC(recBuf->pdu); + } + /* Release all the segments */ + kwAmmUlRlsAllSegs(gCb,recBuf); + kwUtlDelRecBuf(rbCb->m.amUl.recBufLst, recBuf, gCb); + } + curSn++; + }while ( curSn < windSz ); + +#ifndef LTE_TDD + KW_FREE_WC(gCb,rbCb->m.amUl.recBufLst, (KW_RCV_BUF_BIN_SIZE * sizeof(CmLListCp))); + rbCb->m.amUl.recBufLst = NULLP; +#endif + + if(rbCb->m.amUl.partialSdu != NULLP) + { + KW_FREE_BUF_WC(rbCb->m.amUl.partialSdu); + } + RETVOID; +} /* kwAmmFreeUlRbCb */ + + +/*@}*/ + + +/********************************************************************30** + + End of file +**********************************************************************/ diff --git a/src/5gnrrlc/kw_cfg_dl.c b/src/5gnrrlc/kw_cfg_dl.c new file mode 100755 index 000000000..27f37d57b --- /dev/null +++ b/src/5gnrrlc/kw_cfg_dl.c @@ -0,0 +1,1669 @@ +/******************************************************************************* +################################################################################ +# Copyright (c) [2017-2019] [Radisys] # +# # +# 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. # +################################################################################ +*******************************************************************************/ + +/********************************************************************20** + + Name: LTE RLC - Configuration Manager file + + Type: C source file + + Desc: It contains the following configuraiton primtives + for different actions + -- kwCfgValdtEntCfg + -- kwCfgFillRbCb + -- kwCfgRbInit + -- kwCfgAddRb + -- kwCfgReCfgRb + -- kwCfgDelRb + -- kwCfgReEstRb + -- kwCfgDelUe + + File: kw_cfg_dl.c + +*********************************************************************21*/ +static const char* RLOG_MODULE_NAME="CFG"; +static int RLOG_MODULE_ID=2048; +static int RLOG_FILE_ID=191; + +/** @file kw_cfg_dl.c +@brief RLC Downlink Configuration Module +**/ + + +/* header (.h) include files */ +#include "envopt.h" /* environment options */ +#include "envdep.h" /* environment dependent */ +#include "envind.h" /* environment independent */ + +#include "gen.h" /* general */ +#include "ssi.h" /* system services */ +#include "cm5.h" /* common timer defines */ +#include "cm_tkns.h" /* common tokens defines */ +#include "cm_mblk.h" /* common memory allocation library defines */ +#include "cm_llist.h" /* common link list defines */ +#include "cm_hash.h" /* common hash list defines */ +#include "cm_lte.h" /* common LTE defines */ +#include "lkw.h" /* LKW defines */ +#include "ckw.h" /* CKW defines */ +#include "kwu.h" /* KWU defines */ +#include "rgu.h" /* RGU defines */ +#include "kw_err.h" /* RLC error options */ +#include "kw_env.h" /* RLC environment options */ +#include "kw.h" /* RLC defines */ +#include "kw_udx.h" +#include "kw_dl.h" + +/* extern (.x) include files */ +#include "gen.x" /* general */ +#include "ssi.x" /* system services */ + +#include "cm5.x" /* common timer library */ +#include "cm_tkns.x" /* common tokens */ +#include "cm_mblk.x" /* common memory allocation */ +#include "cm_llist.x" /* common link list */ +#include "cm_hash.x" /* common hash list */ +#include "cm_lte.x" /* common LTE includes */ +#include "cm_lib.x" /* common memory allocation library */ +#include "lkw.x" /* LKW */ +#include "ckw.x" /* CKW */ +#include "kwu.x" /* KWU */ +#include "rgu.x" /* RGU */ + +#include "kw.x" +#include "kw_udx.x" +#include "kw_dl.x" + +#define KW_MODULE KW_DBGMASK_CFG +/*Added for adding new Ue in onging L2 Meas*/ +#ifdef LTE_L2_MEAS +/** + * + * @brief Handle modification of UE ID for L2 Meas data structs + * + * + * @param[in] ueId ue ID + * + * @return S16 + * -# ROK + * -# RFAILED + * +*/ +PRIVATE S16 kwHdlMeasDlUeIdChg(KwCb *gCb, U8 cellId,U8 oldUeId, U8 newUeId) +{ + KwL2MeasEvtCb *measEvtCb = NULLP; + KwL2MeasCb *measCb = NULLP; + U16 cntr; + U16 ueIdx = 0; + + for(cntr = 0; cntr < LKW_MAX_L2MEAS; cntr++) + { + measEvtCb = &(gCb->u.dlCb->kwL2Cb.kwL2EvtCb[cntr]); + measCb = &(measEvtCb->measCb); + + + if(measCb->measType & LKW_L2MEAS_DL_IP ) + { + + for(ueIdx = 0; ueIdx < measCb->val.ipThMeas.numUes; ueIdx++) + { + if((measCb->val.ipThMeas.ueInfoLst[ueIdx].ueId) == oldUeId) + { + measCb->val.ipThMeas.ueInfoLst[ueIdx].ueId = newUeId; + break; + } + } + } + } + RETVALUE(ROK); +} + +/** + * + * @brief Handler to delete an UE's L2 Meas ctxt + * +* + * @param[in] ueId ue ID + * + * @return S16 + * -# ROK + * -# RFAILED + * +*/ +PRIVATE S16 kwDelFrmDlL2Meas(KwCb *gCb, U8 cellId,U8 ueId) +{ + KwL2MeasEvtCb *measEvtCb = NULLP; + KwL2MeasCb *measCb = NULLP; + U16 cntr; + U16 ueIdx = 0; + + + for(cntr = 0; cntr < LKW_MAX_L2MEAS; cntr++) + { + measEvtCb = &gCb->u.dlCb->kwL2Cb.kwL2EvtCb[cntr]; + measCb = &(measEvtCb->measCb); + + + if(measCb->measType & LKW_L2MEAS_DL_IP ) + { + + for(ueIdx = 0; ((ueIdx < measCb->val.ipThMeas.numUes) && + (ueIdx < gCb->genCfg.maxUe)); ueIdx++) + { + if((measCb->val.ipThMeas.ueInfoLst[ueIdx].ueId) == ueId) + { + measCb->val.ipThMeas.ueInfoLst[ueIdx].isValid = FALSE; + if (measCb->val.ipThMeas.numUes-1 == ueIdx) + { + measCb->val.ipThMeas.numUes--; + } + break; + } + } + } + } + + RETVALUE(ROK); +} + + +PRIVATE S16 kwAddToDlL2Meas(KwCb *gCb, KwDlRbCb *kwRbCb,U8 cellId,U8 ueId) +{ + KwL2MeasEvtCb *measEvtCb = NULLP; + KwL2MeasCb *measCb = NULLP; + U16 cntr; + U16 cntr1; + U16 ueIdx = 0; + U16 qciIdx = 0; + U16 *numQci; + #ifndef XEON_SPECIFIC_CHANGES + U8 freeIdx = gCb->genCfg.maxUe; + #else + U16 freeIdx = LKW_MAX_UE; + #endif + + + for(cntr = 0; cntr < LKW_MAX_L2MEAS; cntr++) + { + measEvtCb = &gCb->u.dlCb->kwL2Cb.kwL2EvtCb[cntr]; + measCb = &(measEvtCb->measCb); + + freeIdx = gCb->genCfg.maxUe; + + if(measCb->measType & + (LKW_L2MEAS_ACT_UE | LKW_L2MEAS_UU_LOSS | LKW_L2MEAS_DL_DELAY)) + { + for(cntr1 =0;((cntr1 < measCb->val.nonIpThMeas.numQci) && + (cntr1 < LKW_MAX_QCI));cntr1++) + { + if(measCb->val.nonIpThMeas.qci[cntr1] != kwRbCb->qci) + { + measCb->val.nonIpThMeas.qci[cntr1] = kwRbCb->qci; + gCb->u.dlCb->kwL2Cb.measOn[kwRbCb->qci] |=measCb->measType; + break; + } + } + } + + if(((kwRbCb->rbL2Cb.measOn & measCb->measType) == LKW_L2MEAS_NONE)) + { + if (measCb->measType & LKW_L2MEAS_ACT_UE) + { + if((kwRbCb->mode == CM_LTE_MODE_UM) && + (kwRbCb->dir & KW_DIR_DL )) + { + if (kwRbCb->m.umDl.sduQ.count) + { + if (kwRbCb->ueCb->numActRb[kwRbCb->qci] == 0) + { + kwRbCb->ueCb->numActRb[kwRbCb->qci]++; + gCb->u.dlCb->kwL2Cb.numActUe[kwRbCb->qci]++; + } + } + } + else if (kwRbCb->mode == CM_LTE_MODE_AM) + { + if ((kwRbCb->m.amDl.cntrlBo) || + (kwRbCb->m.amDl.retxBo) || + (kwRbCb->m.amDl.bo)) + { + if (kwRbCb->ueCb->numActRb[kwRbCb->qci] == 0) + { + kwRbCb->ueCb->numActRb[kwRbCb->qci]++; + gCb->u.dlCb->kwL2Cb.numActUe[kwRbCb->qci]++; + } + } + } + } + } + if((measCb->measType & LKW_L2MEAS_DL_IP)) + { + + for(ueIdx = 0; ((ueIdx < measCb->val.ipThMeas.numUes) && + (ueIdx < gCb->genCfg.maxUe)); ueIdx++) + { + if ((freeIdx == gCb->genCfg.maxUe) && + (measCb->val.ipThMeas.ueInfoLst[ueIdx].isValid == FALSE)) + { + freeIdx = ueIdx; + continue; + } + if((measCb->val.ipThMeas.ueInfoLst[ueIdx].ueId) == ueId) + { + break; + } + } + + if (ueIdx == measCb->val.ipThMeas.numUes) + { + if (gCb->genCfg.maxUe == measCb->val.ipThMeas.numUes) + { + RETVALUE(RFAILED); + } + if (gCb->genCfg.maxUe == freeIdx) + { + measCb->val.ipThMeas.numUes++; + } + else + { + ueIdx = freeIdx; + } + measCb->val.ipThMeas.ueInfoLst[ueIdx].isValid = TRUE; + cmMemset((U8 *)&measCb->val.ipThMeas.ueInfoLst[ueIdx].measData[0],0x00,(sizeof(KwL2Cntr) *LKW_MAX_QCI)); + measCb->val.ipThMeas.ueInfoLst[ueIdx].numQci = 0; + } + measCb->val.ipThMeas.ueInfoLst[ueIdx].ueId = ueId; + measCb->val.ipThMeas.ueInfoLst[ueIdx].cellId = cellId; + numQci = &(measCb->val.ipThMeas.ueInfoLst[ueIdx].numQci); + + for (qciIdx =0; ((qciIdx < *numQci) && + (qciIdx < LKW_MAX_QCI)) ; qciIdx++) + { + if (measCb->val.ipThMeas.ueInfoLst[ueIdx].qci[qciIdx] == kwRbCb->qci) + { + break; + } + } + + /* Fix Klock Warning */ + if ((qciIdx == *numQci) && (qciIdx < LKW_MAX_QCI)) + { + measCb->val.ipThMeas.ueInfoLst[ueIdx].qci[qciIdx] = kwRbCb->qci; + (*numQci)++; + } + + kwUtlPlcMeasDatInL2Sts(&measCb->val.ipThMeas.ueInfoLst[ueIdx].measData[kwRbCb->qci], + &kwRbCb->rbL2Cb, measCb->measType); + } + else if (measCb->measType & + (LKW_L2MEAS_DL_DISC | LKW_L2MEAS_DL_DELAY | LKW_L2MEAS_UU_LOSS)) + { + kwUtlPlcMeasDatInL2Sts(&measCb->val.nonIpThMeas.measData[kwRbCb->qci], + &kwRbCb->rbL2Cb, measCb->measType); + measCb->val.nonIpThMeas.qci[kwRbCb->qci] = kwRbCb->qci; + measCb->val.nonIpThMeas.measData[kwRbCb->qci].totDrbsPerQci++; + } + kwRbCb->rbL2Cb.measOn |= measCb->measType; + } + RETVALUE(ROK); +}/*kwAddToDlL2Meas*/ +#endif /*LTE_L2_MEAS*/ + +/** + * @brief + * This primitive fills the RbCb + * + * @param [in] gCb - RLC Instance Control Block + * @param [out] rbCb - RB Control Block + * @param [out] ueCb - UE Control Block + * @param [in] entCfg - RLC Entity configuration + * + * @return S16 + * -#ROK + * -#RFAILED + */ +#ifdef ANSI +PRIVATE S16 kwCfgFillDlRbCb +( +KwCb *gCb, +KwDlRbCb *rbCb, +KwDlUeCb *ueCb, +CkwEntCfgInfo *entCfg +) +#else +PRIVATE S16 kwCfgFillDlRbCb(gCb,rbCb,entCfg) +KwCb *gCb; +KwDlRbCb *rbCb; +KwDlUeCb *ueCb; +CkwEntCfgInfo *entCfg; +#endif +{ + TRC3(kwCfgFillDlRbCb) + + RLOG_ARG3(L_DEBUG,DBG_RBID,entCfg->rbId, + "kwCfgFillRbCb(ueId(%d),cellId(%d) rbType(%d))", + rbCb->rlcId.ueId, + rbCb->rlcId.cellId, + entCfg->rbType); + + /* Initialize according to entMode */ + switch (entCfg->entMode) + { + case CM_LTE_MODE_TM: + { + rbCb->lch.lChId = entCfg->lCh[0].lChId; + rbCb->lch.lChType = entCfg->lCh[0].type; + rbCb->dir = entCfg->dir; + break; + } + + case CM_LTE_MODE_UM: + { + rbCb->lch.lChId = entCfg->lCh[0].lChId; + rbCb->lch.lChType = entCfg->lCh[0].type; + rbCb->dir = entCfg->dir; + rbCb->m.umDl.snLen = entCfg->m.umInfo.dl.snLen; + if (entCfg->m.umInfo.dl.snLen == KW_UM_CFG_5BIT_SN_LEN) + rbCb->m.umDl.modBitMask = 0x1f; + else + rbCb->m.umDl.modBitMask = 0x3ff; + + ueCb->lCh[rbCb->lch.lChId - 1].dlRbCb = rbCb; + + break; + } + case CM_LTE_MODE_AM: + { + /* Down Link Information + * indx = 0 as Down Link */ + rbCb->lch.lChId = entCfg->lCh[0].lChId; + rbCb->lch.lChType = entCfg->lCh[0].type; + rbCb->dir = KW_DIR_BOTH; + rbCb->m.amDl.pollPdu = entCfg->m.amInfo.dl.pollPdu; + rbCb->m.amDl.pollByte = entCfg->m.amInfo.dl.pollByte; + rbCb->m.amDl.maxRetx = entCfg->m.amInfo.dl.maxRetx; + rbCb->m.amDl.pollRetxTmrInt = entCfg->m.amInfo.dl.pollRetxTmr; + rbCb->m.amDl.snLen = entCfg->m.amInfo.dl.snLen; + + if(KW_AM_CFG_12BIT_SN_LEN == rbCb->m.amDl.snLen) + { + rbCb->m.amDl.snModMask = (1 << KW_SN_LEN_12BITS) - 1; /* 5GNR */ + } + else + { + rbCb->m.amDl.snModMask = (1 << KW_SN_LEN_18BITS) - 1; /* 5GNR */ + } + + cmInitTimers(&(rbCb->m.amDl.pollRetxTmr), 1); + + + ueCb->lCh[rbCb->lch.lChId - 1].dlRbCb = rbCb; + +#ifndef LTE_TDD + U32 hashIndex; + KW_ALLOC(gCb, + rbCb->m.amDl.txBufLst, + (KW_TX_BUF_BIN_SIZE * sizeof(CmLListCp))); + for(hashIndex = 0; hashIndex < KW_TX_BUF_BIN_SIZE; hashIndex++) + { + cmLListInit(&(rbCb->m.amDl.txBufLst[hashIndex])); + } +#endif + break; + } + default: + { + RLOG_ARG2(L_ERROR,DBG_RBID,entCfg->rbId, + "Invalid RB Mode ueId(%d),cellId(%d)", + rbCb->rlcId.ueId, + rbCb->rlcId.cellId); + RETVALUE(RFAILED); + } + } + rbCb->mode = entCfg->entMode; + rbCb->discTmrInt = entCfg->discardTmr; + + RETVALUE(ROK); +} + + +/** + * @brief This primitive Initializes the RB Cb + * + * @param [in] gCb - RLC Instance Control Block + * @param [out] rbCb - RB Control Block + * @param [in] ptr - Void pointer + * @param [in] entCfg - Entity Configuration + * + * @return S16 + * -#ROK + * -#RFAILED + */ +#ifdef ANSI +PRIVATE S16 kwCfgUpdateDlRb +( +KwCb *gCb, +KwDlRbCb *rbCb, +void *ptr, +CkwEntCfgInfo *entCfg +) +#else +PRIVATE S16 kwCfgUpdateDlRb(gCb,rbCb, ptr, entCfg) +KwCb *gCb; +KwDlRbCb *rbCb; +void *ptr; +CkwEntCfgInfo *entCfg; +#endif +{ + TRC3(kwCfgUpdateDlRb) + + if (rbCb->mode != entCfg->entMode) + { + RLOG_ARG4(L_ERROR,DBG_RBID,rbCb->rlcId.rbId, + "RB Mode Mismatch : exp [%d] rcv [%d] UEID:%d CELLID:%d", + rbCb->mode, + entCfg->entMode, + rbCb->rlcId.ueId, + rbCb->rlcId.cellId); + RETVALUE(CKW_CFG_REAS_RB_MODE_MIS); + } + + switch (rbCb->mode) + { + case CM_LTE_MODE_TM: + { + KwDlCellCb *cellCb = (KwDlCellCb *)ptr; + + rbCb->dir = entCfg->dir; + rbCb->lch.lChId = entCfg->lCh[0].lChId; + rbCb->lch.lChType = entCfg->lCh[0].type; + + cellCb->lCh[rbCb->lch.lChId - 1].dlRbCb = rbCb; + break; + } + + case CM_LTE_MODE_UM: + { + KwDlUeCb *ueCb = (KwDlUeCb *)ptr; + + if (entCfg->lCh[0].type == CM_LTE_LCH_DCCH) + { + RETVALUE(CKW_CFG_REAS_LCHTYPE_MIS); + } + ueCb->lCh[rbCb->lch.lChId - 1].dlRbCb = NULLP; + ueCb->lCh[entCfg->lCh[0].lChId - 1].dlRbCb = rbCb; + + rbCb->lch.lChId = entCfg->lCh[0].lChId; + rbCb->lch.lChType = entCfg->lCh[0].type; + rbCb->dir = entCfg->dir; + break; + } + + case CM_LTE_MODE_AM: + { + KwDlUeCb *ueCb = (KwDlUeCb *)ptr; + + ueCb->lCh[rbCb->lch.lChId - 1].dlRbCb = NULLP; + ueCb->lCh[entCfg->lCh[1].lChId - 1].dlRbCb = rbCb; + + /* Down Link */ + rbCb->lch.lChId = entCfg->lCh[1].lChId; + rbCb->lch.lChType = entCfg->lCh[1].type; + rbCb->m.amDl.pollRetxTmrInt = entCfg->m.amInfo.dl.pollRetxTmr; + rbCb->m.amDl.pollPdu = entCfg->m.amInfo.dl.pollPdu; + rbCb->m.amDl.pollByte = entCfg->m.amInfo.dl.pollByte; + rbCb->m.amDl.maxRetx = entCfg->m.amInfo.dl.maxRetx; + + break; + } + } + +/* AGHOSH */ + rbCb->discTmrInt = entCfg->discardTmr; +/* AGHOSH */ + RETVALUE(CKW_CFG_REAS_NONE); +} + + +/** + * @brief + * This primitive adds new RB in Ue/Cell Cb. + * + * @details + * This function does following steps - + * - If UE ID is 0 then + * - Check for CELL CB is present + * - If yes, Check for RB ID + * - If RB ID is present Status Indication with reason + * - Else, Create New RB CB in CELL CB + * - If no Create New CELL CB and RB CB + * - Else, + * - Check for UE CB is present + * - If yes Check for RB ID + * - If RB ID is present Status Indication with reason + * - Else, Create New RB CB in UE CB + * - If no Create New UE CB and RB CB + * - Fill entity confirmation + * + * @param [in] gCb - RLC Instance Control Block + * @param [in] ueId - UE Identifier + * @param [in] cellId - CELL Identifier + * @param [in] entCfg - Entity Configuration to be done. + * @param [out] entCfm - Entity Confirmation. + * + * @return S16 + * -# ROK + * -# RFAILED + */ +#ifdef ANSI +PUBLIC S16 kwCfgAddDlRb +( +KwCb *gCb, +CmLteRnti ueId, +CmLteCellId cellId, +CkwEntCfgInfo *entCfg, +CkwEntCfgCfmInfo *entCfm +) +#else +PUBLIC S16 kwCfgAddDlRb(gCb,ueId, cellId, entCfg, entCfm) +KwCb *gCb; +CmLteRnti ueId; +CmLteCellId cellId; +CkwEntCfgInfo *entCfg; +CkwEntCfgCfmInfo *entCfm; +#endif +{ + KwDlUeCb *ueCb = NULLP; /* UE Control Block */ + KwDlCellCb *cellCb; /* Cell Control Block */ + KwDlRbCb *kwRbCb; /* KW RB Control Block */ + U8 reason; /* Rb Identifier */ + + TRC3(kwCfgAddDlRb) + + RLOG_ARG3(L_DEBUG,DBG_RBID,entCfg->rbId, + "kwCfgAddRb(cellId(%d),UEID:%d cfgType(%d))", + cellId, + ueId, + entCfg->cfgType); + + if (cellId == 0) + { + /* Fill entCfm structure */ + KW_CFG_FILL_CFG_CFM(entCfm, entCfg->rbId, entCfg->rbType, CKW_CFG_CFM_NOK, + CKW_CFG_REAS_CELL_UNKWN); + RLOG_ARG1(L_ERROR,DBG_RBID,entCfg->rbId, + "Add DLRb,CellId is 0 for UEID:%d", + ueId); + RETVALUE(RFAILED); + } + if ((entCfg->rguSapId >= gCb->genCfg.maxRguSaps) || (entCfg->rguSapId < 0)) + { + KWDBGP_ERROR(gCb, "kwCfgAddDlRb(ueId(%u), cellId(%u), Invalid rguSapId (%d)\n", + ueId, cellId, entCfg->rguSapId); + RETVALUE(RFAILED); + } + + + /* Process Adding new RB */ + if (ueId == 0) + { + if(entCfg->rbId >= KW_MAX_RB_PER_CELL) + { + /* Fill entCfm structure */ + KW_CFG_FILL_CFG_CFM(entCfm, entCfg->rbId, entCfg->rbType, + CKW_CFG_CFM_NOK, + CKW_CFG_REAS_RB_UNKWN); + RLOG_ARG3(L_ERROR,DBG_RBID,entCfg->rbId, + "Invalid RbId ,Max is [%d] CELLID:%d UEID:%d", + KW_MAX_RB_PER_CELL, + cellId, + ueId); + RETVALUE(RFAILED); + } + + if (((entCfg->lCh[0].type == CM_LTE_LCH_BCCH) || + (entCfg->lCh[0].type == CM_LTE_LCH_PCCH) || + (entCfg->lCh[0].type == CM_LTE_LCH_CCCH)) && + (entCfg->entMode == CM_LTE_MODE_TM)) + { + /* Cell CB present */ + kwDbmFetchDlCellCb(gCb, cellId, &cellCb); + if(cellCb) + { + /* Get rbCb from cellCb->rbCb List */ + if (( cellCb->rbCb[entCfg->rbId] != NULLP)) + { + /* Fill entCfm structure */ + KW_CFG_FILL_CFG_CFM(entCfm, entCfg->rbId, entCfg->rbType, + CKW_CFG_CFM_NOK, + CKW_CFG_REAS_RB_PRSNT); + RLOG_ARG2(L_WARNING, DBG_CELLID,cellId, + "RbId [%d] already exists UEID:%d", + entCfg->rbId, + ueId); + RETVALUE(RFAILED); + } + } + else /* Cell CB UNKNOWN */ + { + /* Create CELL CB */ + if ( ROK != kwDbmCreateDlCellCb(gCb,cellId, &cellCb)) + { + /* Fill entCfm structure */ + KW_CFG_FILL_CFG_CFM(entCfm, entCfg->rbId, entCfg->rbType, + CKW_CFG_CFM_NOK, + CKW_CFG_REAS_CELL_CREAT_FAIL); + RLOG_ARG2(L_ERROR,DBG_CELLID,cellId, + "cellCb Creation failed RBID:%d UEID:%d", + entCfg->rbId, + ueId); + RETVALUE(RFAILED); + } + } + + /* Validate LChId */ + if(entCfg->lCh[0].lChId <= 0) + { + RLOG_ARG3(L_ERROR,DBG_LCID,entCfg->lCh[0].lChId , + "Invalid LcId CELLID:%d UEID:%d RBID:%d", + cellId, + ueId, + entCfg->rbId); + /* Fill entCfm structure */ + KW_CFG_FILL_CFG_CFM(entCfm, entCfg->rbId, entCfg->rbType, + CKW_CFG_CFM_NOK, CKW_CFG_REAS_INVALID_LCHID); + RETVALUE(RFAILED); + } + + /* Create RB CB */ + KW_ALLOC(gCb,kwRbCb, sizeof (KwDlRbCb)); + if (!kwRbCb) + { + RLOG_ARG2(L_FATAL,DBG_UEID,ueId, + "Memory allocation failed for rbId:%d CELLID:%d", + entCfg->rbId, + ueId); + /* Fill entCfm structure */ + KW_CFG_FILL_CFG_CFM(entCfm, entCfg->rbId, entCfg->rbType, + CKW_CFG_CFM_NOK, CKW_CFG_REAS_RB_CREAT_FAIL); + RETVALUE(RFAILED); + } + kwRbCb->rlcId.rbId = entCfg->rbId; + cellCb->rbCb[entCfg->rbId] = kwRbCb; + KW_LMM_RB_STS_INC(gCb); + cellCb->lCh[entCfg->lCh[0].lChId - 1].dlRbCb = kwRbCb; + } + else + { + reason= (entCfg->entMode != CM_LTE_MODE_TM)? CKW_CFG_REAS_RB_MODE_MIS: + CKW_CFG_REAS_LCHTYPE_MIS; + /* Fill entCfm structure */ + KW_CFG_FILL_CFG_CFM(entCfm, entCfg->rbId, entCfg->rbType, + CKW_CFG_CFM_NOK, reason); + RETVALUE(RFAILED); + } + } + else + { + if (!(KW_VALIDATE_UE_RBID(entCfg->rbType, entCfg->rbId))) + { + /* Fill entCfm structure */ + KW_CFG_FILL_CFG_CFM(entCfm, entCfg->rbId, entCfg->rbType, CKW_CFG_CFM_NOK, + CKW_CFG_REAS_RB_UNKWN); + RLOG_ARG2(L_ERROR,DBG_RBID, entCfg->rbId, + "Invalid RbId for RbType[%d] UEID:%d", + entCfg->rbType, + ueId); + RETVALUE(RFAILED); + } + if ((((entCfg->lCh[0].type == CM_LTE_LCH_DCCH) && + (entCfg->entMode != CM_LTE_MODE_UM) && + (CM_LTE_SRB == entCfg->rbType)) || + ((entCfg->lCh[0].type == CM_LTE_LCH_DTCH) && + (CM_LTE_DRB == entCfg->rbType))) && + (entCfg->entMode != CM_LTE_MODE_TM)) + { + /* UE CB present */ + if ( kwDbmFetchDlUeCb(gCb,ueId, cellId, &ueCb) == ROK) + { + /* Get rbCb from ueCb->rbCb list */ + KW_DBM_GET_RBCB_FROM_UECB(entCfg->rbId, entCfg->rbType, ueCb, kwRbCb); + + if(( kwRbCb != NULLP)) + { + /* Fill entCfm structure */ + KW_CFG_FILL_CFG_CFM(entCfm, entCfg->rbId, entCfg->rbType, CKW_CFG_CFM_NOK, + CKW_CFG_REAS_RB_PRSNT); + RLOG_ARG2(L_WARNING, DBG_UEID, ueId, + "CellId[%u]:rbId [%d] already exists", + cellId, + entCfg->rbId); + RETVALUE(RFAILED); + } + } + else /* UE CB UNKNOWN */ + { + /* Create UE CB */ + if ( kwDbmCreateDlUeCb(gCb,ueId, cellId, &ueCb) != ROK) + { + /* Fill entCfm structure */ + KW_CFG_FILL_CFG_CFM(entCfm, entCfg->rbId, entCfg->rbType, CKW_CFG_CFM_NOK, + CKW_CFG_REAS_UE_CREAT_FAIL); + RLOG_ARG2(L_WARNING, DBG_CELLID,cellId, + "UeId [%u]:ueCb Creation Failed RBID:%d", + ueId, + entCfg->rbId); + RETVALUE(RFAILED); + } + } + + /* Validate LChId for UM and AM modes */ + if ((entCfg->lCh[0].lChId <= 0) || + ((entCfg->entMode == CM_LTE_MODE_AM)&& + (entCfg->lCh[1].lChId <= 0))) + { + /* Fill entCfm structure */ + KW_CFG_FILL_CFG_CFM(entCfm, entCfg->rbId, entCfg->rbType, + CKW_CFG_CFM_NOK, CKW_CFG_REAS_INVALID_LCHID); + RETVALUE(RFAILED); + } + + /* Create RB CB */ + KW_ALLOC(gCb,kwRbCb, sizeof (KwDlRbCb)); + if (kwRbCb == NULL) + { + /* Fill entCfm structure */ + KW_CFG_FILL_CFG_CFM(entCfm, entCfg->rbId, entCfg->rbType,CKW_CFG_CFM_NOK, + CKW_CFG_REAS_RB_CREAT_FAIL); + RLOG_ARG2(L_FATAL,DBG_UEID,ueId, + "Memory allocation failed RBID:%d CELLID:%d", + entCfg->rbId, + cellId); + RETVALUE(RFAILED); + } + + /* copy the RB Cb into UECb */ + kwRbCb->rlcId.rbId = entCfg->rbId; + if(entCfg->rbType == CM_LTE_SRB) + ueCb->srbCb[entCfg->rbId] = kwRbCb; + else + ueCb->drbCb[entCfg->rbId] = kwRbCb; + + KW_LMM_RB_STS_INC(gCb); + + } + else + { + if (entCfg->entMode == CM_LTE_MODE_TM) + { + reason = CKW_CFG_REAS_RB_MODE_MIS; + } + else + { + reason = CKW_CFG_REAS_LCHTYPE_MIS; + } + + /* Fill entCfm structure */ + KW_CFG_FILL_CFG_CFM(entCfm, entCfg->rbId, entCfg->rbType, CKW_CFG_CFM_NOK, reason); + RETVALUE(RFAILED); + } + } + + + kwRbCb->rlcId.cellId = cellId; + kwRbCb->rlcId.ueId = ueId; + kwRbCb->rlcId.rbType = entCfg->rbType; + kwRbCb->inst = gCb->init.inst; +#ifdef TENB_MULT_CELL_SUPPRT + kwRbCb->rguSapId = entCfg->rguSapId; +#endif + + + /* Fill RB CB */ + if (kwCfgFillDlRbCb(gCb,kwRbCb, ueCb, entCfg) != ROK) + { + /* Fill entCfm structure */ + KW_CFG_FILL_CFG_CFM(entCfm, entCfg->rbId, entCfg->rbType, CKW_CFG_CFM_NOK, + CKW_CFG_REAS_RB_CREAT_FAIL); + + /* Delete RB CB created */ + KW_FREE(gCb,kwRbCb, sizeof(KwDlRbCb)); + RLOG_ARG2(L_ERROR,DBG_RBID, entCfg->rbId, + "Filling of RbCb failed UEID:%d CELLID:%d", + ueId, + cellId); + RETVALUE(RFAILED); + } + kwRbCb->qci = entCfg->qci; +#ifdef LTE_L2_MEAS + kwRbCb->ueCb = ueCb; + if (entCfg->lCh[0].type == CM_LTE_LCH_DTCH) + { + /* ccpu00129778 */ + kwAddToDlL2Meas(gCb, kwRbCb,cellId,ueId); + } +#endif /* LTE_L2_MEAS */ + + /* Fill entCfm structure */ + KW_CFG_FILL_CFG_CFM(entCfm, entCfg->rbId, entCfg->rbType, CKW_CFG_CFM_OK, CKW_CFG_REAS_NONE); + + RETVALUE(ROK); +} + + +/** + * @brief + * This primitive reconfigures the existing RB in Ue/Cell Cb. + * + * @details + * This primitive executes following steps in reconfiguration of existing + * RB - + * - If UE ID is 0 then + * - Check for CELL CB is present + * - If yes, Check for RB ID + * - If RB ID is present Reconfigure the RB CB + * - Else, Status Indication with Reason + * - Else, Status Indication with Reason + * - Else, + * - Check for UE CB is present + * - If yes, Check for RB ID + * - If RB ID is prenset Reconfigure the CELL CB + * - Else, Status Indication with Reason + * - Else, Status Indication with Reason + * - Fill entity confirmation + * + * @param [in] gCb - RLC Instance Control Block + * @param [in] ueId - UE Identifier + * @param [in] cellId - CELL Identifier + * @param [in] entCfg - Entity Configuration to be done. + * @param [out] entCfm - Entity Confirmation + * + * @return S16 + * -#ROK + * -#RFAILED + */ +#ifdef ANSI +PUBLIC S16 kwCfgReCfgDlRb +( +KwCb *gCb, +CmLteRnti ueId, +CmLteCellId cellId, +CkwEntCfgInfo *entCfg, +CkwEntCfgCfmInfo *entCfm +) +#else +PUBLIC S16 kwCfgReCfgDlRb(gCb,ueId, cellId, entCfg, entCfm) +KwCb *gCb; +CmLteRnti ueId; +CmLteCellId cellId; +CkwEntCfgInfo *entCfg; +CkwEntCfgCfmInfo *entCfm; +#endif +{ + KwDlRbCb *rbCb; /* RB Control Block */ + KwDlRbCb tRbCb; /* KW RB Control Block */ + KwDlCellCb *cellCb; /* Cell Control Block */ + KwDlUeCb *ueCb; /* Ue Control Block */ + U8 ret; + + TRC3(kwCfgReCfgDlRb) + + RLOG_ARG3(L_DEBUG,DBG_UEID,ueId, + "kwCfgReCfgRb(cellId(%d), cfgType(%d)) RBID:%d", + cellId, entCfg->cfgType,entCfg->rbId); + + + /* Check for UeCb or CellCb */ + if (ueId == 0) + { + if(entCfg->rbId >= KW_MAX_RB_PER_CELL) + { + /* Fill entCfm structure */ + KW_CFG_FILL_CFG_CFM(entCfm, entCfg->rbId, entCfg->rbType, CKW_CFG_CFM_NOK, + CKW_CFG_REAS_RB_UNKWN); + RLOG_ARG3(L_ERROR,DBG_RBID,entCfg->rbId, + "Invalid RbId , Max is [%d] UEID:%d CELLID:%d", + KW_MAX_RB_PER_CELL, + ueId, + cellId); + RETVALUE(RFAILED); + } + /* Get cellCb */ + kwDbmFetchDlCellCb(gCb,cellId, &cellCb); + if(!cellCb) + { + /* Fill entCfm structure */ + KW_CFG_FILL_CFG_CFM(entCfm, entCfg->rbId, entCfg->rbType, CKW_CFG_CFM_NOK, + CKW_CFG_REAS_CELL_UNKWN); + RLOG_ARG3(L_ERROR,DBG_CELLID,cellId, + "CellCb not found ueId:%d RBID:%d CELLID:%d", + ueId, + entCfg->rbId, + cellId); + RETVALUE(RFAILED); + } + + /* Get rbCb */ + KW_DBM_GET_CELL_RBCB(entCfg->rbId, cellCb->rbCb, rbCb); + + if (!rbCb) + { + /* Fill entCfm structure */ + KW_CFG_FILL_CFG_CFM(entCfm, entCfg->rbId, entCfg->rbType, CKW_CFG_CFM_NOK, + CKW_CFG_REAS_RB_UNKWN); + RLOG_ARG2(L_ERROR,DBG_UEID,ueId, + "CELLID:%d RBID:%d not found", + cellId, + entCfg->rbId); + RETVALUE(RFAILED); + } + + /* Take backup of rbCb before updating. + * Because in failure case restore original rbCb + */ + cmMemcpy((U8 *)&tRbCb, (U8 *)rbCb, sizeof(KwDlRbCb)); + + /* Update rbCb */ + ret = kwCfgUpdateDlRb(gCb,rbCb, cellCb,entCfg); + if (ret != ROK) + { + /* Fill entCfm structure */ + KW_CFG_FILL_CFG_CFM(entCfm, + entCfg->rbId, + entCfg->rbType, + CKW_CFG_CFM_NOK, + ret); + + RLOG_ARG2(L_ERROR,DBG_UEID,ueId, + "CELLID:%u RBID:%d updation failed", + cellId, + entCfg->rbId); + cmMemcpy((U8*)rbCb, (U8 *)&tRbCb, sizeof(KwDlRbCb)); + + RETVALUE(ret); + } + } + else + { + if (!(KW_VALIDATE_UE_RBID(entCfg->rbType, entCfg->rbId))) + { + /* Fill entCfm structure */ + KW_CFG_FILL_CFG_CFM(entCfm, entCfg->rbId, entCfg->rbType, CKW_CFG_CFM_NOK, + CKW_CFG_REAS_RB_UNKWN); + RLOG_ARG3(L_ERROR,DBG_UEID,ueId, + "CELLID:%d Invalid RBID:%d for RbType[%d]", + cellId, + entCfg->rbId, + entCfg->rbType); + RETVALUE(RFAILED); + } + /* Get ueCb */ + ret = kwDbmFetchDlUeCb(gCb,ueId, cellId, &ueCb); + if (ret != ROK) + { + /* Fill entCfm structure */ + KW_CFG_FILL_CFG_CFM(entCfm, entCfg->rbId, entCfg->rbType, + CKW_CFG_CFM_NOK, CKW_CFG_REAS_UE_UNKWN); + RLOG_ARG2(L_ERROR,DBG_CELLID, cellId, + "UEID:%d UeCb not found RBID:%d", + ueId, + entCfg->rbId); + RETVALUE(ret); + } + + /* Get rbCb */ + KW_DBM_GET_RBCB_FROM_UECB(entCfg->rbId, entCfg->rbType, ueCb, rbCb); + + if ( rbCb == NULLP) + { + /* Fill entCfm structure */ + KW_CFG_FILL_CFG_CFM(entCfm, entCfg->rbId, entCfg->rbType, CKW_CFG_CFM_NOK, + CKW_CFG_REAS_RB_UNKWN); + RLOG_ARG2(L_ERROR, DBG_UEID,ueId, + "CELLID:%d RBID:%d not found", + cellId, + entCfg->rbId); + RETVALUE(ret); + } + + /* Take backup of rbCb before updating. + * Because in failure case restore original rbCb + */ + cmMemcpy((U8 *)&tRbCb, (U8 *)rbCb, sizeof(KwDlRbCb)); + + /* Update rbCb */ + ret = kwCfgUpdateDlRb(gCb,rbCb,ueCb, entCfg); + if (ret != CKW_CFG_REAS_NONE) + { + /* Fill entCfm structure */ + KW_CFG_FILL_CFG_CFM(entCfm, entCfg->rbId, entCfg->rbType, CKW_CFG_CFM_NOK, + ret); + RLOG_ARG2(L_ERROR,DBG_UEID,ueId, + "CELLID:%d RBID:%d updation failed", + cellId, + entCfg->rbId); + cmMemcpy((U8*)rbCb, (U8 *)&tRbCb, sizeof(KwDlRbCb)); + + RETVALUE(ret); + } + } + + /* Fill entCfm structure */ + KW_CFG_FILL_CFG_CFM(entCfm, entCfg->rbId, entCfg->rbType, CKW_CFG_CFM_OK, CKW_CFG_REAS_NONE); + + RETVALUE(ROK); +} + + +/** + * @brief This primitive deletes the existing RB in Ue/Cell Cb. + * + * @details + * - If UE ID is 0 then + * - Check for CELL CB is present + * - If yes, Check for RB ID + * - If RB ID is prenset Delete the RB CB + * - If there is no RB CB exist in CELL CB then Delete CELL CB. + * - Else, Status Indication with Reason + * - Else, Status Indication with Reason + * - Else, + * - Check for UE CB is present + * - If yes, Check for RB ID + * - If RB ID is prenset Delete the RB CB + * - If there is no RB CB exist in UE CB then Delete UE CB. + * - Else, Status Indication with Reason + * - Else, Status Indication with Reason + * - Fill entity confirmation + * + * @param [in] gCb - RLC Instance Control Block + * @param [in] ueId - UE Identifier + * @param [in] cellId - CELL Identifier + * @param [in] entCfg - Entity Configuration to be done. + * @param [out] entCfm - Entity Confirmation + * + * @return S16 + * -#ROK + * -#RFAILED + */ +#ifdef ANSI +PUBLIC S16 kwCfgDelDlRb +( +KwCb *gCb, +CmLteRnti ueId, +CmLteCellId cellId, +CkwEntCfgInfo *entCfg, +CkwEntCfgCfmInfo *entCfm +) +#else +PUBLIC S16 kwCfgDelRb(gCb,ueId, cellId, entCfg, entCfm) +KwCb *gCb; +CmLteRnti ueId; +CmLteCellId cellId; +CkwEntCfgInfo *entCfg; +CkwEntCfgCfmInfo *entCfm; +#endif +{ + S16 ret; /* Return Value */ + KwDlUeCb *ueCb; /* UE Control Block */ + KwDlCellCb *cellCb; /* UE Control Block */ + KwDlRbCb *kwRbCb; /* KW RB Control Block */ + + TRC3(kwCfgDelDlRb) + + RLOG_ARG3(L_DEBUG,DBG_UEID,ueId, + "kwCfgDelRb(RBID(%d), cellId(%d), cfgType(%d))", + entCfg->rbId, + cellId, + entCfg->cfgType); + + ret = ROK; + + /* Get cellCb and delete rbCb from it */ + if (ueId == 0) + { + if(entCfg->rbId >= KW_MAX_RB_PER_CELL) + { + /* Fill entCfm structure */ + KW_CFG_FILL_CFG_CFM(entCfm, entCfg->rbId, entCfg->rbType, + CKW_CFG_CFM_NOK, CKW_CFG_REAS_RB_UNKWN); + RLOG_ARG3(L_ERROR,DBG_RBID,entCfg->rbId , + "Invalid RbId, Max is [%d] UEID:%d CELLID:%d", + KW_MAX_RB_PER_CELL, + ueId, + cellId); + RETVALUE(RFAILED); + } + /* Get cellCb */ + kwDbmFetchDlCellCb(gCb,cellId, &cellCb); + if (!cellCb) + { + /* Fill entCfm structure */ + KW_CFG_FILL_CFG_CFM(entCfm, entCfg->rbId, entCfg->rbType, + CKW_CFG_CFM_NOK, CKW_CFG_REAS_RB_UNKWN); + RLOG_ARG2(L_ERROR,DBG_CELLID,cellId, + "CellCb not found UEID:%d RBID:%d", + ueId, + entCfg->rbId); + RETVALUE(ret); + } + + /* Get rbCb */ + KW_DBM_GET_CELL_RBCB(entCfg->rbId, cellCb->rbCb, kwRbCb); + + if ( kwRbCb == NULLP) + { + /* Fill entCfm structure */ + KW_CFG_FILL_CFG_CFM(entCfm, entCfg->rbId, entCfg->rbType, + CKW_CFG_CFM_NOK, CKW_CFG_REAS_RB_UNKWN); + RLOG_ARG2(L_ERROR, DBG_UEID,ueId, + "CellId[%u]:RbId[%d] not found", + cellId, + entCfg->rbId); + RETVALUE(ret); + } + + /* Assign NULLP to rbCb in rbCbLst */ + cellCb->rbCb[entCfg->rbId] = NULLP; + + /* Assign NULLP to dlRbCb/ulRbCb. + * Delete Hashlist allocated for it if any */ + cellCb->lCh[kwRbCb->lch.lChId - 1].dlRbCb = NULLP; + KW_FREE(gCb,kwRbCb, sizeof(KwDlRbCb)); /*Vartika: Mem leak fix */ + } + /* Get ueCb and delete rbCb from it */ + else + { + if (!(KW_VALIDATE_UE_RBID(entCfg->rbType, entCfg->rbId))) + { + /* Fill entCfm structure */ + KW_CFG_FILL_CFG_CFM(entCfm, entCfg->rbId, entCfg->rbType, + CKW_CFG_CFM_NOK, CKW_CFG_REAS_RB_UNKWN); + RLOG_ARG3(L_ERROR,DBG_RBID, entCfg->rbId, + "Invalid RbId for RbType[%d] UEID:%d CELLID:%d", + entCfg->rbType, + ueId, + cellId); + RETVALUE(RFAILED); + } + + /* Get ueCb */ + ret = kwDbmFetchDlUeCb(gCb,ueId, cellId, &ueCb); + if (ret != ROK) + { + /* Fill entCfm structure */ + KW_CFG_FILL_CFG_CFM(entCfm, entCfg->rbId, entCfg->rbType, + CKW_CFG_CFM_NOK, CKW_CFG_REAS_UE_UNKWN); + RLOG_ARG2(L_ERROR,DBG_CELLID, cellId, + "UeId [%d]: UeCb not found RBID:%d", + ueId, + entCfg->rbId); + RETVALUE(ret); + } + + /* Get rbCb */ + KW_DBM_GET_RBCB_FROM_UECB(entCfg->rbId, entCfg->rbType, ueCb, kwRbCb); + + if ( kwRbCb == NULLP) + { + /* Fill entCfm structure */ + KW_CFG_FILL_CFG_CFM(entCfm, entCfg->rbId, entCfg->rbType, CKW_CFG_CFM_NOK, + CKW_CFG_REAS_RB_UNKWN); + RLOG_ARG2(L_ERROR, DBG_UEID,ueId, + "CellId[%u]:RbId[%d] not found", + cellId, + entCfg->rbId); + RETVALUE(ret); + } + + ueCb->lCh[kwRbCb->lch.lChId - 1].dlRbCb = NULLP; + +#ifdef LTE_L2_MEAS + KW_UPD_L2_DECR_NONIP_PER_QCI_RB_COUNT(gCb, kwRbCb); +#endif + /* Free the Buffers of RbCb */ + if( CM_LTE_MODE_UM == kwRbCb->mode) + { + kwUmmFreeDlRbCb(gCb,kwRbCb); + /* Delete RbCb */ + KW_FREE(gCb,kwRbCb, sizeof(KwDlRbCb)); + } + else if( CM_LTE_MODE_AM == kwRbCb->mode) + { + kwAmmFreeDlRbCb(gCb,kwRbCb); + } + + /* Assign NULLP to rbCb in rbCbLst */ + if ( entCfg->rbType == CM_LTE_SRB ) + { + ueCb->srbCb[entCfg->rbId] = NULLP; + } + else + { + ueCb->drbCb[entCfg->rbId] = NULLP; + } + } + + KW_LMM_RB_STS_DEC(gCb); + + /* Fill entCfm structure */ + KW_CFG_FILL_CFG_CFM(entCfm, entCfg->rbId, entCfg->rbType, CKW_CFG_CFM_OK, + CKW_CFG_REAS_NONE); + + RETVALUE(ret); +} + + +/** + * @brief This primitive re-establish the existing RB in Ue/Cell Cb. + * + * @details + * - If UE ID is 0 then + * - Check for CELL CB is present + * - If yes, Check for RB ID + * - If RB ID is prenset initialize the parameters of the RB CB + * - Else, Status Indication with Reason + * - Else, Status Indication with Reason + * - Else, + * - Check for UE CB is present + * - If yes, Check for RB ID + * - If RB ID is prenset initialize the parameters of the RB CB + * - Else, Status Indication with Reason + * - Else, Status Indication with Reason + * - Fill entity confirmation + * + * @param [in] gCb - RLC Instance Control Block + * @param [in] ueId - UE Identifier + * @param [in] cellId - CELL Identifier + * @param [in] entCfg - Entity Configuration to be done. + * @param [out] entCfm - Entity Confirmation + * + * @return S16 + * -# ROK + * -# RFAILED + */ +#ifdef ANSI +PUBLIC S16 kwCfgReEstDlRb +( +KwCb *gCb, +CmLteRnti ueId, +CmLteCellId cellId, +Bool sndReEstInd, +CkwEntCfgInfo *entCfg, +CkwEntCfgCfmInfo *entCfm +) +#else +PUBLIC S16 kwCfgReEstDlRb(gCb,ueId, cellId,sndReEstInd,entCfg, entCfm) +KwCb *gCb; +CmLteRnti ueId; +CmLteCellId cellId; +Bool sndReEstInd; +CkwEntCfgInfo *entCfg; +CkwEntCfgCfmInfo *entCfm; +#endif +{ + KwDlRbCb *rbCb; /* RB Control Block */ + CmLteRlcId rlcId; /* RLC Identifier */ + + TRC3(kwCfgReEstDlRb) + + RLOG_ARG3(L_DEBUG,DBG_RBID,entCfg->rbId, + "kwCfgReEstDlRb(ueId(%d), cellId(%d), cfgType(%d))", + ueId, + cellId, + entCfg->cfgType); + + /* Get rlcId */ + rlcId.ueId = ueId; + rlcId.cellId = cellId; + rlcId.rbId = entCfg->rbId; + rlcId.rbType = entCfg->rbType; + + kwDbmFetchDlRbCbByRbId(gCb,&rlcId, &rbCb); + if (rbCb == NULLP) + { + /* Fill entCfm structure */ + KW_CFG_FILL_CFG_CFM(entCfm, entCfg->rbId, rlcId.rbType, CKW_CFG_CFM_NOK, + CKW_CFG_REAS_RB_UNKWN); + RLOG_ARG2(L_ERROR, DBG_UEID,ueId, + "CellId[%u]:RbId[%d] not found", + cellId, + entCfg->rbId); + RETVALUE(RFAILED); + } + + rbCb->rlcId.ueId = ueId; + + switch (rbCb->mode) + { + case CM_LTE_MODE_TM: + { + kwDlTmmReEstablish(gCb,rbCb); + break; + } + + case CM_LTE_MODE_UM: + { + kwDlUmmReEstablish(gCb,rlcId,sndReEstInd,rbCb); + break; + } + + case CM_LTE_MODE_AM: + { + kwAmmDlReEstablish(gCb, rlcId, rbCb); + break; + } + } + + /* Fill entCfm structure */ + KW_CFG_FILL_CFG_CFM(entCfm, entCfg->rbId, entCfg->rbType, + CKW_CFG_CFM_OK, CKW_CFG_REAS_NONE); + + RETVALUE(ROK); +} + + +/** + * @brief This primitive deletes the RBs in Ue Cb. + * + * @details + * - If UE ID is 0 then + * - Status Indication with Reason + * - Else, + * - Check for UE CB is present + * - If yes, Delete all RB CB in UE CB and Delete UE CB also. + * - Else, Status Indication with Reason + * - Fill entity confirmation + * + * @param [in] gCb - RLC Instance Control Block + * @param [in] ueId - UE Identifier + * @param [in] cellId - CELL Identifier + * @param [in] entCfg - Entity Configuration to be done. + * @param [out] entCfm - Entity Confirmation + * + * @return S16 + * -#ROK + * -#RFAILED + */ +#ifdef ANSI +PUBLIC S16 kwCfgDelDlUe +( +KwCb *gCb, +CmLteRnti ueId, +CmLteCellId cellId, +CkwEntCfgInfo *entCfg, +CkwEntCfgCfmInfo *entCfm +) +#else +PUBLIC S16 kwCfgDelDlUe(ueId, cellId, entCfg, entCfm) +KwCb *gCb; +CmLteRnti ueId; +CmLteCellId cellId; +CkwEntCfgInfo *entCfg; +CkwEntCfgCfmInfo *entCfm; +#endif +{ + S16 ret; /* Return Value */ + KwDlUeCb *ueCb; /* UE Control Block */ + + TRC3(kwCfgDelUe) + + RLOG_ARG3(L_DEBUG,DBG_RBID,entCfg->rbId, + "kwCfgDelUe(ueId(%d), cellId(%d), cfgType(%d))", + ueId, + cellId, + entCfg->cfgType); + + ret = ROK; + + /* Check for ueId is present or not */ + if ( ueId == 0 ) + { + /* Fill entCfm structure */ + KW_CFG_FILL_CFG_CFM(entCfm, entCfg->rbId, entCfg->rbType, + CKW_CFG_CFM_NOK, CKW_CFG_REAS_UE_UNKWN); + RLOG_ARG2(L_ERROR,DBG_RBID,entCfg->rbId, + "ueId(%d), cellId(%d)", + ueId, + cellId); + RETVALUE(RFAILED); + } + + /* Fetch Ue Cb */ + ret = kwDbmFetchDlUeCb(gCb,ueId, cellId, &ueCb); + if (ret != ROK) + { + /* Fill entCfm structure */ + KW_CFG_FILL_CFG_CFM(entCfm, entCfg->rbId, entCfg->rbType, + CKW_CFG_CFM_NOK, CKW_CFG_REAS_UE_UNKWN); + RLOG_ARG2(L_ERROR,DBG_CELLID, cellId, + "UEID:%d UeCb not found RBID:%d", + ueId, + entCfg->rbId); + RETVALUE(RFAILED); + } + +#ifdef LTE_L2_MEAS + kwDelFrmDlL2Meas(gCb,cellId,ueId); + kwDbmDelAllDlL2MeasTbFrmUe(gCb,ueCb); +#endif + /* Delete Ue Cb */ + kwDbmDelDlUeCb(gCb,ueCb, FALSE); + + /* Fill entCfm structure */ + KW_CFG_FILL_CFG_CFM(entCfm, entCfg->rbId, entCfg->rbType, + CKW_CFG_CFM_OK, CKW_CFG_REAS_NONE); + + RETVALUE(ROK); +} + + +/** + * @brief This primitive deletes the RBs in Ue Cb. + * + * @details + * - If CELL ID is 0 then + * - Status Indication with Reason + * - Else, + * - Check for CELL CB is present + * - If yes, Delete all RB CB in CELL CB and Delete CELL CB also. + * - Else, Status Indication with Reason + * - Fill entity confirmation + * + * @param [in] cellId - CELL Identifier + * @param [in] entCfg - Entity Configuration to be done. + * @param [out] entCfm - Entity Confirmation + * + * @return S16 + * -#ROK + * -#RFAILED + */ +#ifdef ANSI +PUBLIC S16 kwCfgDelDlCell +( +KwCb *gCb, +CmLteCellId cellId, +CkwEntCfgInfo *entCfg, +CkwEntCfgCfmInfo *entCfm +) +#else +PUBLIC S16 kwCfgDelCell(gCb,cellId, entCfg, entCfm) +KwCb *gCb; +CmLteCellId cellId; +CkwEntCfgInfo *entCfg; +CkwEntCfgCfmInfo *entCfm; +#endif +{ + KwDlCellCb *cellCb; /* UE Control Block */ + U8 rbId; /* RB Identifier */ + + TRC3(kwCfgDelCell) + + RLOG_ARG2(L_DEBUG,DBG_RBID,entCfg->rbId, + "kwCfgDelCell( cellId(%d), cfgType(%d)", + cellId, + entCfg->cfgType); + + cellCb = NULLP; + rbId = entCfg->rbId; + + /* Check for ueId is present or not */ + if ( cellId == 0 ) + { + /* Fill entCfm structure */ + KW_CFG_FILL_CFG_CFM(entCfm, rbId, entCfg->rbType, CKW_CFG_CFM_NOK, + CKW_CFG_REAS_CELL_UNKWN); + RLOG_ARG1(L_DEBUG,DBG_RBID,entCfg->rbId, + "cellId is 0 (%d) ", + cellId); + RETVALUE(RFAILED); + } + + /* Fetch Ue Cb */ + kwDbmFetchDlCellCb(gCb,cellId, &cellCb); + if (!cellCb) + { + /* Fill entCfm structure */ + KW_CFG_FILL_CFG_CFM(entCfm, rbId, entCfg->rbType, CKW_CFG_CFM_NOK, + CKW_CFG_REAS_CELL_UNKWN); + RLOG_ARG1(L_ERROR, DBG_CELLID,cellId, + "CellCb not found for RBID:%d", + entCfg->rbId); + RETVALUE(RFAILED); + } + + /* Delete Ue Cb */ + kwDbmDelDlCellCb(gCb,cellCb); + + /* Fill entCfm structure */ + /* kw005.201 added support for L2 Measurement */ + KW_CFG_FILL_CFG_CFM(entCfm, rbId, entCfg->rbType, CKW_CFG_CFM_OK, + CKW_CFG_REAS_NONE); + + RETVALUE(ROK); +} + +/** + * @brief This primitive changes the ueId of Ue Cb. + * + * @details + * - If oldUeId and newUeId are + * - Confirm the Status with Reason + * - If UeId not present + * - Confirm the Status with Reason + * - Create New UeCb + * - Copy rbCbs from old UeCb to new UeCb + * - Delete old UeCb + * - Fill entity confirmation + * + * @param [in] ueInfo - Old UE Information + * @param [in] newUeInfo - New UE Information + * @param [out] status - Status + * + * @return S16 + * -# ROK + * -# RFAILED + */ +#ifdef ANSI +PUBLIC S16 kwCfgDlUeIdChng +( +KwCb *gCb, +CkwUeInfo *ueInfo, +CkwUeInfo *newUeInfo, +CmStatus *status +) +#else +PUBLIC S16 kwCfgDlUeIdChng(gCb,ueInfo,newUeInfo,status) +KwCb *gCb; +CkwUeInfo *ueInfo; +CkwUeInfo *newUeInfo; +CmStatus *status; +#endif +{ + KwDlUeCb *ueCb; +/*kw004.201 Adding of Missing Trace in LTE RLC PDCP*/ + TRC3(kwCfgUeIdChng) + + if ( (ueInfo->ueId == newUeInfo->ueId) && + (ueInfo->cellId == newUeInfo->cellId)) + { + status->reason = CKW_CFG_REAS_SAME_UEID; + status->status = CKW_CFG_CFM_NOK; + RLOG_ARG2(L_ERROR,DBG_CELLID,ueInfo->cellId, + "Old UeId[%d] same as new UeId[%d]", + ueInfo->ueId, + newUeInfo->ueId); + RETVALUE(RFAILED); + } + + if(ROK == kwDbmFetchDlUeCb(gCb,newUeInfo->ueId, newUeInfo->cellId, &ueCb)) + { + RLOG_ARG1(L_ERROR, DBG_CELLID, newUeInfo->cellId, + "NewUeId[%d]:ueCb already exists", + newUeInfo->ueId); + status->reason = CKW_CFG_REAS_UE_EXISTS; + status->status = CKW_CFG_CFM_NOK; + RETVALUE(RFAILED); + } + + if(ROK != kwDbmFetchDlUeCb(gCb,ueInfo->ueId, ueInfo->cellId, &ueCb)) + { + + RLOG_ARG1(L_ERROR,DBG_CELLID,ueInfo->cellId, + "UeId [%d]: UeCb not found", + ueInfo->ueId); + status->reason = CKW_CFG_REAS_UE_UNKWN; + status->status = CKW_CFG_CFM_NOK; + RETVALUE(RFAILED); + } + +#ifdef LTE_L2_MEAS + kwHdlMeasDlUeIdChg(gCb, ueInfo->cellId, ueInfo->ueId, newUeInfo->ueId); +#endif + if(ROK != cmHashListDelete(&(gCb->u.dlCb->ueLstCp), (PTR) ueCb)) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,ueInfo->cellId, + "UeId[%u] HashList Deletion Failed", + ueInfo->ueId); + status->reason = CKW_CFG_REAS_UE_CREAT_FAIL; + status->status = CKW_CFG_CFM_NOK; + RETVALUE(RFAILED); + } + + /* update the hash key with new values */ + ueCb->ueId = newUeInfo->ueId; + ueCb->cellId = newUeInfo->cellId; + + if(ROK != cmHashListInsert(&(gCb->u.dlCb->ueLstCp), + (PTR)ueCb, (U8 *)&(ueCb->ueId), + (U16) sizeof(CmLteRnti))) + + { + RLOG_ARG1(L_ERROR,DBG_CELLID,newUeInfo->cellId, + "UeId[%u] HashList Insertion Failed", + newUeInfo->ueId); + status->reason = CKW_CFG_REAS_UE_CREAT_FAIL; + status->status = CKW_CFG_CFM_NOK; + RETVALUE(RFAILED); + } + + RETVALUE(ROK); +} + +/********************************************************************30** + + End of file +**********************************************************************/ diff --git a/src/5gnrrlc/kw_cfg_ul.c b/src/5gnrrlc/kw_cfg_ul.c new file mode 100755 index 000000000..c55f6a35a --- /dev/null +++ b/src/5gnrrlc/kw_cfg_ul.c @@ -0,0 +1,1477 @@ +/******************************************************************************* +################################################################################ +# Copyright (c) [2017-2019] [Radisys] # +# # +# 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. # +################################################################################ +*******************************************************************************/ + +/********************************************************************20** + + Name: LTE RLC - Configuration Manager file + + Type: C source file + + Desc: It contains the following configuraiton primtives + for different actions + -- kwCfgValdtEntCfg + -- kwCfgFillRbCb + -- kwCfgRbInit + + File: kw_cfg_ul.c + +*********************************************************************21*/ +static const char* RLOG_MODULE_NAME="CFG"; +static int RLOG_MODULE_ID=2048; +static int RLOG_FILE_ID=192; +/** @file kw_cfg_ul.c +@brief RLC Uplink Configuration Module +**/ + + +/* header (.h) include files */ +#include "envopt.h" /* environment options */ +#include "envdep.h" /* environment dependent */ +#include "envind.h" /* environment independent */ + +#include "gen.h" /* general */ +#include "ssi.h" /* system services */ +#include "cm5.h" /* common timer defines */ +#include "cm_tkns.h" /* common tokens defines */ +#include "cm_mblk.h" /* common memory allocation library defines */ +#include "cm_llist.h" /* common link list defines */ +#include "cm_hash.h" /* common hash list defines */ +#include "cm_lte.h" /* common LTE defines */ +#include "lkw.h" /* LKW defines */ +#include "ckw.h" /* CKW defines */ +#include "kwu.h" /* KWU defines */ +#include "rgu.h" /* RGU defines */ +#include "kw_err.h" /* RLC error options */ +#include "kw_env.h" /* RLC environment options */ +#include "kw.h" /* RLC defines */ +#include "kw_ul.h" + +/* extern (.x) include files */ +#include "gen.x" /* general */ +#include "ssi.x" /* system services */ + +#include "cm5.x" /* common timer library */ +#include "cm_tkns.x" /* common tokens */ +#include "cm_mblk.x" /* common memory allocation */ +#include "cm_llist.x" /* common link list */ +#include "cm_hash.x" /* common hash list */ +#include "cm_lte.x" /* common LTE includes */ +#include "cm_lib.x" /* common memory allocation library */ +#include "lkw.x" /* LKW */ +#include "ckw.x" /* CKW */ +#include "kwu.x" /* KWU */ +#include "rgu.x" /* RGU */ + +#include "kw.x" +#include "kw_ul.x" +#ifdef TENB_STATS +#ifdef L2_L3_SPLIT +#include "l2_tenb_stats.x" /* Total EnodeB Stats declarations */ +#endif +#endif +PUBLIC S16 kwValidateRbCfgParams (KwCb *gCb, CmLteRnti ueId, CmLteCellId cellId, + CkwEntCfgInfo *cfgToValidate, CmStatus *status); +#define KW_MODULE KW_DBGMASK_CFG +#ifdef LTE_L2_MEAS +/** + * + * @brief Handle modification of UE ID for L2 Meas data structs + * + * + * @param[in] ueId ue ID + * + * @return S16 + * -# ROK + * -# RFAILED + * +*/ +PRIVATE S16 kwHdlMeasUlUeIdChg(KwCb *gCb, U8 cellId,U8 oldUeId, U8 newUeId) +{ + KwL2MeasCb *measCb = NULLP; + U16 cntr; + U16 ueIdx = 0; + + for(cntr = 0; cntr < LKW_MAX_L2MEAS; cntr++) + { + measCb = &(gCb->u.ulCb->kwL2Cb.kwL2EvtCb[cntr].measCb); + + if( measCb->measType & LKW_L2MEAS_UL_IP) + { + + for(ueIdx = 0; ueIdx < measCb->val.ipThMeas.numUes; ueIdx++) + { + if((measCb->val.ipThMeas.ueInfoLst[ueIdx].ueId) == oldUeId) + { + measCb->val.ipThMeas.ueInfoLst[ueIdx].ueId = newUeId; + break; + } + } + } + } + RETVALUE(ROK); +} + +/** + * + * @brief Handler to delete an UE's L2 Meas ctxt + * +* + * @param[in] ueId ue ID + * + * @return S16 + * -# ROK + * -# RFAILED + * +*/ +PRIVATE S16 kwDelFrmUlL2Meas(KwCb *gCb, U8 cellId,U8 ueId) +{ + KwL2MeasCb *measCb = NULLP; + U16 cntr; + U16 ueIdx = 0; + + for(cntr = 0; cntr < LKW_MAX_L2MEAS; cntr++) + { + measCb = &(gCb->u.ulCb->kwL2Cb.kwL2EvtCb[cntr].measCb); + + + if( measCb->measType & LKW_L2MEAS_UL_IP) + { + + for(ueIdx = 0; ueIdx < measCb->val.ipThMeas.numUes; ueIdx++) + { + if((measCb->val.ipThMeas.ueInfoLst[ueIdx].ueId) == ueId) + { + measCb->val.ipThMeas.ueInfoLst[ueIdx].isValid = FALSE; + if (measCb->val.ipThMeas.numUes-1 == ueIdx) + { + measCb->val.ipThMeas.numUes--; + } + break; + } + } + + + + { + U32 myIdx =0; + S16 ret; /* Return value */ + KwUlUeCb *ueCb = NULL; + + for (myIdx = 0; myIdx < measCb->val.ipThMeas.numUes; myIdx++) + { + ueCb = NULL; + ret = kwDbmFetchUlUeCb(gCb, measCb->val.ipThMeas.ueInfoLst[myIdx].ueId, cellId, &ueCb); + } + } + + } + } + + RETVALUE(ROK); +} + + +PRIVATE S16 kwAddToUlL2Meas(KwCb *gCb, KwUlRbCb *kwRbCb,U8 cellId,U8 ueId) +{ + KwL2MeasCb *measCb = NULLP; + U16 cntr; + U16 cntr1; + U16 ueIdx = 0; + U16 qciIdx = 0; + U16 *numQci; + #ifndef XEON_SPECIFIC_CHANGES + U8 freeIdx = gCb->genCfg.maxUe; + #else + U16 freeIdx = LKW_MAX_UE; + #endif + + for(cntr = 0; cntr < LKW_MAX_L2MEAS; cntr++) + { + measCb = &(gCb->u.ulCb->kwL2Cb.kwL2EvtCb[cntr].measCb); + + freeIdx = gCb->genCfg.maxUe; + + if(measCb->measType & LKW_L2MEAS_ACT_UE ) + { + for(cntr1 =0;cntr1val.nonIpThMeas.numQci;cntr1++) + { + if(measCb->val.nonIpThMeas.qci[cntr1] != kwRbCb->qci) + { + measCb->val.nonIpThMeas.qci[cntr1] = kwRbCb->qci; + gCb->u.ulCb->kwL2Cb.measOn[kwRbCb->qci] |=measCb->measType; + break; + } + } + } + + if(((kwRbCb->rbL2Cb.measOn & measCb->measType) == LKW_L2MEAS_NONE)) + { +#ifdef LTE_L2_MEAS_RLC + if (measCb->measType & LKW_L2MEAS_ACT_UE) + { + if((kwRbCb->mode == CM_LTE_MODE_UM) && + (kwRbCb->dir & KW_DIR_DL )) + { + if (kwRbCb->m.um.umDl.sduQ.count) + { + if (kwRbCb->ueCb->numActRb[kwRbCb->qci] == 0) + { + kwRbCb->ueCb->numActRb[kwRbCb->qci]++; + gCb->u.ulCb->kwL2Cb.numActUe[kwRbCb->qci]++; + } + } + } + else if (kwRbCb->mode == CM_LTE_MODE_AM) + { + if ((kwRbCb->m.am.amDl.cntrlBo) || + (kwRbCb->m.am.amDl.retxBo) || + (kwRbCb->m.am.amDl.bo)) + { + if (kwRbCb->ueCb->numActRb[kwRbCb->qci] == 0) + { + kwRbCb->ueCb->numActRb[kwRbCb->qci]++; + gCb->u.ulCb->kwL2Cb.numActUe[kwRbCb->qci]++; + } + } + } + } +#endif + } + if((measCb->measType & LKW_L2MEAS_UL_IP)) + { + + for(ueIdx = 0; ueIdx < measCb->val.ipThMeas.numUes; ueIdx++) + { + if ((freeIdx == gCb->genCfg.maxUe) && + (measCb->val.ipThMeas.ueInfoLst[ueIdx].isValid == FALSE)) + { + freeIdx = ueIdx; + continue; + } + if((measCb->val.ipThMeas.ueInfoLst[ueIdx].ueId) == ueId) + { + break; + } + } + + if (ueIdx == measCb->val.ipThMeas.numUes) + { + if (gCb->genCfg.maxUe == measCb->val.ipThMeas.numUes) + { + RETVALUE(RFAILED); + } + if (gCb->genCfg.maxUe == freeIdx) + { + measCb->val.ipThMeas.numUes++; + } + else + { + ueIdx = freeIdx; + } + measCb->val.ipThMeas.ueInfoLst[ueIdx].isValid = TRUE; + cmMemset((U8 *)&measCb->val.ipThMeas.ueInfoLst[ueIdx].measData[0],0x00,(sizeof(KwL2Cntr) *LKW_MAX_QCI)); + measCb->val.ipThMeas.ueInfoLst[ueIdx].numQci = 0; + } + measCb->val.ipThMeas.ueInfoLst[ueIdx].ueId = ueId; + measCb->val.ipThMeas.ueInfoLst[ueIdx].cellId = cellId; + numQci = &(measCb->val.ipThMeas.ueInfoLst[ueIdx].numQci); + + for (qciIdx =0; qciIdx < *numQci; qciIdx++) + { + if (measCb->val.ipThMeas.ueInfoLst[ueIdx].qci[qciIdx] == kwRbCb->qci) + { + break; + } + } + + if (qciIdx == *numQci) + { + measCb->val.ipThMeas.ueInfoLst[ueIdx].qci[qciIdx] = kwRbCb->qci; + (*numQci)++; + } + + kwUtlPlcMeasDatInL2Sts(&measCb->val.ipThMeas.ueInfoLst[ueIdx].measData[kwRbCb->qci], + &kwRbCb->rbL2Cb, measCb->measType); + } + kwRbCb->rbL2Cb.measOn |= measCb->measType; + } + RETVALUE(ROK); +}/*kwAddToDlL2Meas*/ +#endif /*LTE_L2_MEAS*/ + +/** + * @brief + * This primitive fills the RbCb + * + * @param [in] gCb - RLC Instance Control Block + * @param [out] rbCb - RB Control Block + * @param [out] ueCb - UE Control Block + * @param [in] entCfg - RLC Entity configuration + * + * @return S16 + * -#ROK + * -#RFAILED + */ +#ifdef ANSI +PRIVATE S16 kwCfgFillUlRbCb +( +KwCb *gCb, +KwUlRbCb *rbCb, +KwUlUeCb *ueCb, +CkwEntCfgInfo *entCfg +) +#else +PRIVATE S16 kwCfgFillUlRbCb(gCb,rbCb, ueCb, entCfg) +KwCb *gCb; +KwUlRbCb *rbCb; +KwUlUeCb *ueCb; +CkwEntCfgInfo *entCfg; +#endif +{ + TRC3(kwCfgFillUlRbCb) + + RLOG_ARG3(L_DEBUG,DBG_UEID,rbCb->rlcId.ueId, + "kwCfgFillRbCb(cellId(%d), rbId(%d), rbType(%d))", + rbCb->rlcId.cellId, + entCfg->rbId, + entCfg->rbType); + + /* Initialize according to entMode */ + switch (entCfg->entMode) + { + case CM_LTE_MODE_TM: + { + rbCb->lch.lChId = entCfg->lCh[0].lChId; + rbCb->lch.lChType = entCfg->lCh[0].type; + rbCb->dir = entCfg->dir; + break; + } + case CM_LTE_MODE_UM: + { + rbCb->lch.lChId = entCfg->lCh[0].lChId; + rbCb->lch.lChType = entCfg->lCh[0].type; + + rbCb->dir = entCfg->dir; + + rbCb->m.umUl.snLen = entCfg->m.umInfo.ul.snLen; + + /* the bitmask for SN = 10 is 0x3ff and for SN = 5 is 0x1f */ + rbCb->m.umUl.modBitMask = (rbCb->m.umUl.umWinSz << 1) - 1; + + rbCb->m.umUl.reOrdTmrInt = + entCfg->m.umInfo.ul.reOrdTmr; + cmInitTimers(&(rbCb->m.umUl.reOrdTmr), 1); + ueCb->lCh[rbCb->lch.lChId - 1].ulRbCb = rbCb; + break; + } + case CM_LTE_MODE_AM: + { + /* Down Link Information + * indx = 1 as Up Link */ + rbCb->lch.lChId = entCfg->lCh[1].lChId; + rbCb->lch.lChType = entCfg->lCh[1].type; + rbCb->dir = KW_DIR_BOTH; + + rbCb->m.amUl.staProhTmrInt = entCfg->m.amInfo.ul.staProhTmr; + rbCb->m.amUl.reOrdTmrInt = entCfg->m.amInfo.ul.reOrdTmr; + + rbCb->m.amUl.snLen = entCfg->m.amInfo.ul.snLen; /* 5GNR */ + + if(KW_AM_CFG_12BIT_SN_LEN == rbCb->m.amUl.snLen) + { + rbCb->m.amUl.snModMask = (1 << KW_SN_LEN_12BITS) - 1; /* 5GNR */ + } + else + { + rbCb->m.amUl.snModMask = (1 << KW_SN_LEN_18BITS) - 1; /* 5GNR */ + } + + cmInitTimers(&(rbCb->m.amUl.reOrdTmr), 1); + cmInitTimers(&(rbCb->m.amUl.staProhTmr), 1); + + rbCb->m.amUl.vrMr = rbCb->m.amUl.rxNext + (KW_AM_GET_WIN_SZ(rbCb->m.amUl.snLen)); + + ueCb->lCh[rbCb->lch.lChId - 1].ulRbCb = rbCb; + + break; + } + default: + { + RLOG_ARG2(L_ERROR,DBG_UEID,rbCb->rlcId.ueId, + "INVALID RB Mode cellId(%d), rbId(%d)", + rbCb->rlcId.cellId, + entCfg->rbId); + RETVALUE(RFAILED); + } + } + rbCb->mode = entCfg->entMode; + + RETVALUE(ROK); +} + + +/** + * @brief This primitive Initializes the RB Cb + * + * @param [in] gCb - RLC Instance Control Block + * @param [out] rbCb - RB Control Block + * @param [in] ptr - Void pointer + * @param [in] entCfg - Entity Configuration + * + * @return S16 + * -#ROK + * -#RFAILED + */ +#ifdef ANSI +PRIVATE S16 kwCfgUpdateUlRb +( +KwCb *gCb, +KwUlRbCb *rbCb, +void *ptr, +CkwEntCfgInfo *entCfg +) +#else +PRIVATE S16 kwCfgUpdateUlRb(gCb,rbCb, ptr, entCfg) +KwCb *gCb; +KwUlRbCb *rbCb; +void *ptr; +CkwEntCfgInfo *entCfg; +#endif +{ + TRC3(kwCfgUpdateUlRb) + + switch (rbCb->mode) + { + case CM_LTE_MODE_TM: + { + KwUlCellCb *cellCb = (KwUlCellCb *)ptr; + rbCb->dir = entCfg->dir; + rbCb->lch.lChId = entCfg->lCh[0].lChId; + rbCb->lch.lChType = entCfg->lCh[0].type; + + cellCb->lCh[rbCb->lch.lChId - 1].ulRbCb = rbCb; + break; + } + case CM_LTE_MODE_UM: + { + KwUlUeCb *ueCb = (KwUlUeCb *)ptr; + ueCb->lCh[rbCb->lch.lChId - 1].ulRbCb = NULLP; + kwCfgFillUlRbCb(gCb,rbCb, ueCb, entCfg); + break; + } + case CM_LTE_MODE_AM: + { + KwUlUeCb *ueCb = (KwUlUeCb *)ptr; + + ueCb->lCh[rbCb->lch.lChId - 1].ulRbCb = NULLP; + ueCb->lCh[entCfg->lCh[1].lChId - 1].ulRbCb = rbCb; + /* Up Link */ + rbCb->lch.lChId = entCfg->lCh[1].lChId; + rbCb->lch.lChType = entCfg->lCh[1].type; + rbCb->m.amUl.staProhTmrInt = entCfg->m.amInfo.ul.staProhTmr; + rbCb->m.amUl.reOrdTmrInt = entCfg->m.amInfo.ul.reOrdTmr; + break; + } + } + RETVALUE(CKW_CFG_REAS_NONE); +} + + +/** + * @brief + * This primitive validates uplink Add RB Configuration and reserve memory + * for RB creation. + * + * @param [in] gCb - RLC Instance Control Block + * @param [in] ueId - UE Identifier + * @param [in] cellId - CELL Identifier + * @param [in] cfgToValidate - Entity Configuration needs to be validated. + * @param [out] status - status of configuration + * + * @return S16 + * -# ROK + * -# RFAILED + */ +#ifdef ANSI +PUBLIC S16 kwValidateRbCfgParams +( +KwCb *gCb, +CmLteRnti ueId, +CmLteCellId cellId, +CkwEntCfgInfo *cfgToValidate, +CmStatus *status +) +#else +PUBLIC S16 kwValidateRbCfgParams(gCb,ueId, cellId, cfgToValidate, status) +KwCb *gCb; +CmLteRnti ueId; +CmLteCellId cellId; +CkwEntCfgInfo *cfgToValidate; +CmStatus *status; +#endif +{ + if (cellId == 0) + { + status->reason = CKW_CFG_REAS_CELL_UNKWN; + RETVALUE (RFAILED); + } + if ((cfgToValidate->rguSapId >= gCb->genCfg.maxRguSaps) || (cfgToValidate->rguSapId < 0)) + { + KWDBGP_ERROR(gCb, "kwValidateRbCfgParams ueId (%u) cellId (%u) Invalid rguSapId (%d))\n", + ueId, cellId, cfgToValidate->rguSapId); + status->reason = CKW_CFG_REAS_INVALID_RGUSAP; + RETVALUE(RFAILED); + } + + if((CKW_CFG_ADD == cfgToValidate->cfgType) || + (CKW_CFG_MODIFY == cfgToValidate->cfgType)) + { + /* Validate LChId for UM and AM modes */ + if ((cfgToValidate->lCh[0].lChId <= 0) || + ((cfgToValidate->entMode == CM_LTE_MODE_AM) && + (cfgToValidate->lCh[1].lChId <= 0))) + { + status->reason = CKW_CFG_REAS_INVALID_LCHID; + RETVALUE(RFAILED); + } + if((cfgToValidate->entMode == CM_LTE_MODE_UM) && + (cfgToValidate->m.umInfo.ul.snLen != KW_UM_CFG_5BIT_SN_LEN) && + (cfgToValidate->m.umInfo.ul.snLen != KW_UM_CFG_10BIT_SN_LEN)) + { + RLOG_ARG2(L_ERROR,DBG_UEID,ueId, + "CellId[%u]:UM Mode RB[%d],Invalid SN Len[%d]", + cfgToValidate->rbId, + cfgToValidate->m.umInfo.ul.snLen); + status->reason = CKW_CFG_REAS_INVALID_SNLEN; + RETVALUE(RFAILED); + } + /* Process Adding new RB */ + if (ueId == 0) + { + if(cfgToValidate->rbId >= KW_MAX_RB_PER_CELL) + { + status->reason = CKW_CFG_REAS_RB_UNKWN; + RETVALUE(RFAILED); + } + + if ((cfgToValidate->lCh[0].type != CM_LTE_LCH_CCCH) && + (cfgToValidate->entMode != CM_LTE_MODE_TM)) + { + status->reason= (cfgToValidate->entMode != CM_LTE_MODE_TM)? CKW_CFG_REAS_RB_MODE_MIS: + CKW_CFG_REAS_LCHTYPE_MIS; + RETVALUE(RFAILED); + } + } + else + { + if (!(KW_VALIDATE_UE_RBID(cfgToValidate->rbType, cfgToValidate->rbId))) + { + status->reason = CKW_CFG_REAS_RB_UNKWN; + RETVALUE(RFAILED); + } + + if(cfgToValidate->entMode == CM_LTE_MODE_TM) + { + status->reason = CKW_CFG_REAS_LCHTYPE_MIS; + RETVALUE(RFAILED); + } + if (!(((cfgToValidate->lCh[0].type == CM_LTE_LCH_DCCH) && + (cfgToValidate->entMode != CM_LTE_MODE_UM))|| + (cfgToValidate->lCh[0].type == CM_LTE_LCH_DTCH)) ) + { + status->reason = CKW_CFG_REAS_RB_MODE_MIS; + RETVALUE(RFAILED); + } + } + } + else /* cfgType is CKW_CFG_DELETE */ + { + if (ueId == 0) + { + if(cfgToValidate->rbId >= KW_MAX_RB_PER_CELL) + { + status->reason = CKW_CFG_REAS_RB_UNKWN; + RETVALUE(RFAILED); + } + + } + else + { + if (!(KW_VALIDATE_UE_RBID(cfgToValidate->rbType, cfgToValidate->rbId))) + { + status->reason = CKW_CFG_REAS_RB_UNKWN; + RETVALUE(RFAILED); + } + } + } + RETVALUE(ROK); +} + + +/** + * @brief + * This primitive validates uplink Add RB Configuration and reserve memory + * for RB creation. + * + * @param [in] gCb - RLC Instance Control Block + * @param [in] cfgToValidate - Entity Configuration needs to be validated. + * @param [out] cfgEntData - Configuration Temporary Data Entity + * @param [out] cfgTmpData - Configuration Temporary Data + * + * @return S16 + * -# ROK + * -# RFAILED + */ +#ifdef ANSI +PUBLIC S16 kwCfgValidateUlRb +( +KwCb *gCb, +CkwEntCfgInfo *cfgToValidate, +KwUlEntTmpData *cfgEntData, +KwUlCfgTmpData *cfgTmpData +) +#else +PUBLIC S16 kwCfgValidateUlRb(gCb,cfgToValidate, cfgEntData, cfgTmpData) +KwCb *gCb; +CkwEntCfgInfo *cfgToValidate; +KwUlEntTmpData *cfgEntData; +KwUlCfgTmpData *cfgTmpData; +#endif +{ + TRC3(kwCfgValidateUlRb) + + RLOG_ARG2(L_DEBUG,DBG_UEID,cfgTmpData->ueId, + "cellId(%d), cfgType(%d)", + cfgTmpData->cellId, + cfgToValidate->cfgType); + + if(ROK != kwValidateRbCfgParams(gCb, + cfgTmpData->ueId, + cfgTmpData->cellId, + cfgToValidate, + &cfgEntData->entUlCfgCfm.status)) + { + RETVALUE(RFAILED); + } + + cfgEntData->entUlCfgCfm.status.reason = CKW_CFG_REAS_NONE; + switch(cfgToValidate->cfgType) + { + case CKW_CFG_ADD: + { + if (cfgTmpData->ueId == 0) + { + /* Cell Cb is added if it not present , it is not roll backed if the + * configuration fails */ + kwDbmFetchUlCellCb(gCb,cfgTmpData->cellId, &cfgTmpData->cellCb); + if(!cfgTmpData->cellCb) + { + /* cell cb does not exist we need to create a new one */ + KW_ALLOC(gCb,cfgTmpData->cellCb, sizeof(KwUlCellCb)); + if(!cfgTmpData->cellCb) + { + RLOG_ARG1(L_FATAL,DBG_UEID,cfgTmpData->ueId, + "Memory allocation failure CELLID:%d", + cfgTmpData->cellId); + cfgEntData->entUlCfgCfm.status.reason = CKW_CFG_REAS_CELL_CREAT_FAIL; + RETVALUE(RFAILED); + } + kwDbmAddUlCellCb(gCb, cfgTmpData->cellId, cfgTmpData->cellCb); + } + else + { + if (( cfgTmpData->cellCb->rbCb[cfgToValidate->rbId] != NULLP)) + { + cfgEntData->entUlCfgCfm.status.reason = CKW_CFG_REAS_RB_PRSNT;; + RETVALUE(RFAILED); + } + } + + KW_ALLOC(gCb,cfgEntData->rbCb, sizeof (KwUlRbCb)); + if (!cfgEntData->rbCb) + { + cfgEntData->entUlCfgCfm.status.reason = CKW_CFG_REAS_RB_CREAT_FAIL; + RETVALUE(RFAILED); + } + } + else + { + /* Ue Cb is added if it not present , it is not roll backed if the + * configuration fails */ + kwDbmFetchUlUeCb(gCb,cfgTmpData->ueId, cfgTmpData->cellId, &cfgTmpData->ueCb); + if(!cfgTmpData->ueCb) + { + KW_ALLOC(gCb,cfgTmpData->ueCb, sizeof(KwUlUeCb)); + if(!cfgTmpData->ueCb) + { + RLOG_ARG1(L_FATAL,DBG_UEID,cfgTmpData->ueId, + "Memory allocation failure CELLID:%d", + cfgTmpData->cellId); + cfgEntData->entUlCfgCfm.status.reason = CKW_CFG_REAS_UE_CREAT_FAIL; + RETVALUE(RFAILED); + } + kwDbmAddUlUeCb(gCb, cfgTmpData->ueId, cfgTmpData->cellId, cfgTmpData->ueCb); + } + else + { + KW_DBM_GET_RBCB_FROM_UECB(cfgToValidate->rbId, + cfgToValidate->rbType, + cfgTmpData->ueCb, + cfgEntData->rbCb); + if(cfgEntData->rbCb != NULLP) + { + cfgEntData->entUlCfgCfm.status.reason = CKW_CFG_REAS_RB_PRSNT;; + RETVALUE(RFAILED); + } + } + KW_ALLOC(gCb,cfgEntData->rbCb, sizeof (KwUlRbCb)); + if (!cfgEntData->rbCb) + { + cfgEntData->entUlCfgCfm.status.reason = CKW_CFG_REAS_RB_CREAT_FAIL; + RETVALUE(RFAILED); + } + } + /*Allocating the memory for receive buffer */ + if(CM_LTE_MODE_UM == cfgToValidate->entMode) + { + U16 winLen; + + + cfgEntData->rbCb->m.umUl.umWinSz = KW_POWER(2, + ((cfgToValidate->m.umInfo.ul.snLen *5)-1)); + winLen = cfgEntData->rbCb->m.umUl.umWinSz << 1; + KW_ALLOC(gCb, + cfgEntData->rbCb->m.umUl.recBuf, + (winLen * sizeof(KwUmRecBuf*))); + } + else if(CM_LTE_MODE_AM == cfgToValidate->entMode) + { +#ifndef LTE_TDD + U32 hashIndex; + KW_ALLOC(gCb, + cfgEntData->rbCb->m.amUl.recBufLst, + (KW_RCV_BUF_BIN_SIZE * sizeof(CmLListCp ))); + for(hashIndex = 0; hashIndex < KW_RCV_BUF_BIN_SIZE; hashIndex++) + { + cmLListInit(&(cfgEntData->rbCb->m.amUl.recBufLst[hashIndex])); + } +#endif + } + break; + } + case CKW_CFG_MODIFY: + case CKW_CFG_DELETE: + { + if (cfgTmpData->ueId == 0) + { + /* Try to get the CellCb if it already exists */ + kwDbmFetchUlCellCb(gCb,cfgTmpData->cellId, &cfgTmpData->cellCb); + if(!cfgTmpData->cellCb) + { + RLOG_ARG1(L_ERROR, DBG_CELLID,cfgTmpData->cellId, + "CellCb not found UEID:%d", + cfgTmpData->ueId); + /*how can a modify request come for a cell which does not exist*/ + cfgEntData->entUlCfgCfm.status.reason = CKW_CFG_REAS_CELL_UNKWN; + RETVALUE(RFAILED); + } + + cfgEntData->rbCb = cfgTmpData->cellCb->rbCb[cfgToValidate->rbId]; + if (!cfgEntData->rbCb) + { + /* something is wrong the rbId for this cell does not exist */ + cfgEntData->entUlCfgCfm.status.reason = CKW_CFG_REAS_RB_UNKWN; + RETVALUE(RFAILED); + } + RETVALUE(ROK); + } + else + { + kwDbmFetchUlUeCb(gCb,cfgTmpData->ueId, cfgTmpData->cellId, &cfgTmpData->ueCb); + if(!cfgTmpData->ueCb) + { + RLOG_ARG1(L_ERROR,DBG_CELLID, cfgTmpData->cellId, + "UeId [%d]: UeCb not found", + cfgTmpData->ueId); + cfgEntData->entUlCfgCfm.status.reason = CKW_CFG_REAS_UE_UNKWN; + RETVALUE(RFAILED); + } + + /* Get rbCb */ + KW_DBM_GET_RBCB_FROM_UECB(cfgToValidate->rbId, + cfgToValidate->rbType, + cfgTmpData->ueCb, + cfgEntData->rbCb); + if ( cfgEntData->rbCb == NULLP) + { + cfgEntData->entUlCfgCfm.status.reason = CKW_CFG_REAS_RB_UNKWN; + RETVALUE(RFAILED); + } + RETVALUE(ROK); + } + break; + } + } + + if(cfgToValidate->cfgType == CKW_CFG_MODIFY) + { + if(cfgToValidate->entMode != cfgEntData->rbCb->mode) + { + cfgEntData->entUlCfgCfm.status.reason = CKW_CFG_REAS_RB_MODE_MIS; + RETVALUE(RFAILED); + } + + if(cfgToValidate->m.umInfo.ul.snLen != cfgEntData->rbCb->m.umUl.snLen) + { + cfgEntData->entUlCfgCfm.status.reason = CKW_CFG_REAS_SNLEN_MIS; + RETVALUE(RFAILED); + } + } + RETVALUE(ROK); +} + + +/** + * @brief + * This primitive roll back the RB Configuration + * + * @param [in] gCb - RLC Instance Control Block + * @param [in] ueId - UE Identifier + * @param [in] cfg - Configuration entity. + * @param [out] cfgEntData - Configuration Temporary Data Entity + * + * @return S16 + * -# ROK + * -# RFAILED + */ +#ifdef ANSI +PUBLIC S16 kwCfgRollBackUlRb +( +KwCb *gCb, +CmLteRnti ueId, +CkwEntCfgInfo *cfg, +KwUlEntTmpData *cfgEntData +) +#else +PUBLIC S16 kwCfgRollBackUlRb(gCb, cfg, cfgEntData) +( +KwCb *gCb; +CmLteRnti ueId; +CkwEntCfgInfo *cfg; +KwUlEntTmpData *cfgEntData; +) +#endif +{ + TRC3(kwCfgRollBackUlRb) + + if(CKW_CFG_ADD == cfg->cfgType) + { + if(CM_LTE_MODE_UM == cfg->entMode) + { + KW_FREE(gCb, + cfgEntData->rbCb->m.umUl.recBuf, + (cfgEntData->rbCb->m.umUl.umWinSz << 1) * sizeof(KwUmRecBuf*)); + } + else if(CM_LTE_MODE_AM == cfg->entMode) + { +#ifndef LTE_TDD + KW_FREE(gCb,cfgEntData->rbCb->m.amUl.recBufLst, (KW_RCV_BUF_BIN_SIZE * sizeof(CmLListCp))); +#endif + } + KW_FREE(gCb,cfgEntData->rbCb, sizeof(KwUlRbCb)); + } + + RETVALUE(ROK); +} + + +/** + * @brief + * This primitive apply RB Configuration. + * + * @param [in] gCb - RLC Instance Control Block + * @param [in] cfgToAply - Configuration to be applied + * @param [out] cfgEntData - Configuration Temporary Data Entity + * @param [out] cfgTmpData - Configuration Temporary Data + * + * @return S16 + * -# ROK + * -# RFAILED + */ +#ifdef ANSI +PUBLIC Void kwCfgApplyUlRb +( +KwCb *gCb, +CkwEntCfgInfo *cfgToAply, +KwUlEntTmpData *cfgEntData, +KwUlCfgTmpData *cfgTmpData +) +#else +PUBLIC Void kwCfgApplyUlRb(gCb, cfgToApply, cfgEntData, cfgTmpData) +( +KwCb *gCb; +CkwEntCfgInfo *cfgToAply; +KwUlEntTmpData *cfgEntData; +KwUlCfgTmpData *cfgTmpData; +) +#endif +{ + TRC3(kwCfgApplyUlRb) + + switch(cfgToAply->cfgType) + { + case CKW_CFG_ADD: + { + /* copy the RB Cb into UeCb */ + cfgEntData->rbCb->rlcId.rbId = cfgToAply->rbId; + if (cfgTmpData->ueId == 0) + { + cfgTmpData->cellCb->rbCb[cfgToAply->rbId] = cfgEntData->rbCb; + cfgTmpData->cellCb->lCh[cfgToAply->lCh[0].lChId -1].ulRbCb = cfgEntData->rbCb; + } + else + { + if(cfgToAply->rbType == CM_LTE_SRB) + { + cfgTmpData->ueCb->srbCb[cfgToAply->rbId] = cfgEntData->rbCb; + } + else + { + cfgTmpData->ueCb->drbCb[cfgToAply->rbId] = cfgEntData->rbCb; + } + } + + KW_LMM_RB_STS_INC(gCb); + + cfgEntData->rbCb->rlcId.cellId = cfgTmpData->cellId; + cfgEntData->rbCb->rlcId.ueId = cfgTmpData->ueId; + cfgEntData->rbCb->rlcId.rbType = cfgToAply->rbType; + cfgEntData->rbCb->inst = gCb->init.inst; + + /* Fill RB CB */ + kwCfgFillUlRbCb(gCb, + cfgEntData->rbCb, + cfgTmpData->ueCb, + cfgToAply); + +#ifdef LTE_L2_MEAS + cfgEntData->rbCb->qci = cfgToAply->qci; + cfgEntData->rbCb->ueCb = cfgTmpData->ueCb; + if (cfgToAply->lCh[1].type == CM_LTE_LCH_DTCH) + { + /* ccpu00129778 */ + kwAddToUlL2Meas(gCb, cfgEntData->rbCb, + cfgTmpData->cellId,cfgTmpData->ueId); + } +#endif /* LTE_L2_MEAS */ + break; + } + case CKW_CFG_MODIFY: + { + if(cfgTmpData->ueId == 0) + { + kwCfgUpdateUlRb(gCb, + cfgEntData->rbCb, + (void *)cfgTmpData->cellCb, + cfgToAply); + } + else + { + kwCfgUpdateUlRb(gCb, + cfgEntData->rbCb, + (void*)cfgTmpData->ueCb, + cfgToAply); + } + break; + } + case CKW_CFG_DELETE: + { + if (cfgTmpData->ueId == 0) + { + cfgTmpData->cellCb->rbCb[cfgToAply->rbId] = NULLP; + cfgTmpData->cellCb->lCh[cfgEntData->rbCb->lch.lChId - 1].ulRbCb = + NULLP; + } + else + { + cfgTmpData->ueCb->lCh[cfgEntData->rbCb->lch.lChId - 1].ulRbCb = + NULLP; + + /* Free the Buffers of RbCb */ + if( CM_LTE_MODE_UM == cfgEntData->rbCb->mode ) + { + kwUmmFreeUlRbCb(gCb, cfgEntData->rbCb); + } + else if(CM_LTE_MODE_AM == cfgEntData->rbCb->mode) + { + kwAmmFreeUlRbCb(gCb,cfgEntData->rbCb); + } + + /* Assign NULLP to rbCb in rbCbLst */ + if ( cfgToAply->rbType == CM_LTE_SRB ) + { + cfgTmpData->ueCb->srbCb[cfgToAply->rbId] = NULLP; + } + else + { + cfgTmpData->ueCb->drbCb[cfgToAply->rbId] = NULLP; + } + } + /* Delete RbCb */ + KW_FREE(gCb,cfgEntData->rbCb, sizeof(KwUlRbCb)); + + KW_LMM_RB_STS_DEC(gCb); + break; + } + } + RETVOID; +} + + +/** + * @brief + * This primitive validates uplink Delete UE request + * for RB creation. + * + * @param [in] gCb - RLC Instance Control Block + * @param [in] cfgToValidate - Entity Configuration to be validated. + * @param [out] cfgEntData - Configuration Temporary Data Entity + * @param [out] cfgTmpData - Configuration Temporary Data + * + * @return S16 + * -# ROK + * -# RFAILED + */ +#ifdef ANSI +PUBLIC S16 kwCfgValidateDelUlUe +( +KwCb *gCb, +CkwEntCfgInfo *cfgToValidate, +KwUlEntTmpData *cfgEntData, +KwUlCfgTmpData *cfgTmpData +) +#else +PUBLIC S16 kwCfgValidateDelUlUe(gCb,cfgToValidate, cfgEntData,cfgTmpData) +KwCb *gCb; +CkwEntCfgInfo *cfgToValidate; +KwUlEntTmpData *cfgEntData; +KwUlCfgTmpData *cfgTmpData; +#endif +{ + TRC3(kwCfgValidateDelUlUe) + + RLOG_ARG2(L_DEBUG,DBG_UEID,cfgTmpData->ueId, + "cellId(%d), cfgType(%d)", + cfgTmpData->cellId,cfgToValidate->cfgType); + + /* Check for ueId is present or not */ + if ( cfgTmpData->ueId == 0 ) + { + cfgEntData->entUlCfgCfm.status.reason = CKW_CFG_REAS_UE_UNKWN;; + RLOG_ARG1(L_ERROR,DBG_UEID,cfgTmpData->ueId, + "UeId is 0 for CELLID;%d", + cfgTmpData->cellId); + RETVALUE(RFAILED); + } + + /* Fetch Ue Cb */ + if(ROK != kwDbmFetchUlUeCb(gCb,cfgTmpData->ueId, cfgTmpData->cellId, &cfgTmpData->ueCb)) + { + RLOG_ARG1(L_ERROR,DBG_CELLID, cfgTmpData->cellId, + "UeId [%d]: UeCb not found", + cfgTmpData->ueId); + cfgEntData->entUlCfgCfm.status.reason = CKW_CFG_REAS_UE_UNKWN;; + RETVALUE(RFAILED); + } + RETVALUE(ROK); +} + + +/** + * @brief + * This primitive apply Uplink Delete Ue request + * + * @param [in] gCb - RLC Instance Control Block + * @param [in] cfgTmpData - Configuration Temporary Data + * + * @return S16 + * -# ROK + */ +#ifdef ANSI +PUBLIC Void kwCfgApplyDelUlUe +( +KwCb *gCb, +KwUlCfgTmpData *cfgTmpData +) +#else +PUBLIC Void kwCfgApplyDelUlUe(gCb, cfgTmpData) +( +KwCb *gCb; +KwUlCfgTmpData *cfgTmpData; +) +#endif +{ + TRC3(kwCfgApplyDelUlUe) + +#ifdef LTE_L2_MEAS + kwDelFrmUlL2Meas(gCb,cfgTmpData->cellId,cfgTmpData->ueId); +#endif + kwDbmDelUlUeCb(gCb,cfgTmpData->ueCb, FALSE); + RETVOID; +} + + +/** + * @brief + * This primitive validates uplink Delete UE request + * for RB creation. + * + * @param [in] gCb - RLC Instance Control Block + * @param [in] ueId - UE Identifier + * @param [in] cfgToValidate - Entity Configuration to be done. + * @param [in] cfgEntData - Configuration Temporary Data Entity + * @param [in] cfgTmpData - Configuration Temporary Data + * + * @return S16 + * -# ROK + * -# RFAILED + */ +#ifdef ANSI +PUBLIC S16 kwCfgValidateDelUlCell +( +KwCb *gCb, +CmLteCellId cellId, +CkwEntCfgInfo *cfgToValidate, +KwUlEntTmpData *cfgEntData, +KwUlCfgTmpData *cfgTmpData +) +#else +PUBLIC S16 kwCfgValidateDelUlCell(gCb, cellId, cfgToValidate, cfgTmpData) +KwCb *gCb; +CmLteCellId cellId; +CkwEntCfgInfo *cfgToValidate; +KwUlEntTmpData *cfgEntData; +KwUlCfgTmpData *cfgTmpData; +#endif +{ + TRC3(kwCfgValidateDelUlCell) + + RLOG_ARG1(L_DEBUG,DBG_CELLID,cellId ,"cfgType(%d)", + cfgToValidate->cfgType); + + cfgTmpData->cellCb = NULLP; + + /* Check for cellId is present or not */ + if ( cellId == 0 ) + { + cfgEntData->entUlCfgCfm.status.reason = CKW_CFG_REAS_CELL_UNKWN;; + RLOG_ARG0(L_ERROR,DBG_CELLID,cellId , "CellId is 0"); + RETVALUE(RFAILED); + } + + /* Fetch Cell Cb */ + kwDbmFetchUlCellCb(gCb,cellId, &cfgTmpData->cellCb); + if (!cfgTmpData->cellCb) + { + cfgEntData->entUlCfgCfm.status.reason = CKW_CFG_REAS_CELL_UNKWN;; + RLOG_ARG0(L_ERROR, DBG_CELLID,cellId, "CellCb not found"); + RETVALUE(RFAILED); + } + RETVALUE(ROK); +} + + +/** + * @brief + * This primitive apply Uplink Delete Ue request + * + * @param [in] gCb - RLC Instance Control Block + * @param [in] cfgEntData - Temporary Data maintained for a transaction + * + * @return S16 + * -# ROK + */ +#ifdef ANSI +PUBLIC Void kwCfgApplyDelUlCell +( +KwCb *gCb, +KwUlCfgTmpData *cfgInfo +) +#else +PUBLIC Void kwCfgApplyDelUlCell(gCb, cfgEntData) +( +KwCb *gCb; +KwUlCfgTmpData *cfgInfo; +) +#endif +{ + TRC3(kwCfgApplyDelUlCell) + + kwDbmDelUlCellCb(gCb,cfgInfo->cellCb); + RETVOID; +} + +/** + * @brief + * This primitive validates reestablishment of RB. + * + * @param [in] gCb - RLC Instance Control Block + * @param [in] ueId - UE Identifier + * @param [in] cellId - CELL Identifier + * @param [in] cfgToValidate - Entity Configuration to be done. + * @param [out] cfgEntData - Configuration Temporary Data Entity + * + * @return S16 + * -# ROK + * -# RFAILED + */ +#ifdef ANSI +PUBLIC S16 kwCfgValidateReEstRb +( +KwCb *gCb, +CmLteRnti ueId, +CmLteCellId cellId, +CkwEntCfgInfo *cfgToValidate, +KwUlEntTmpData *cfgEntData +) +#else +PUBLIC S16 kwCfgValidateReEstRb(gCb,ueId, cellId, cfgToValidate, cfgEntData) +KwCb *gCb; +CmLteRnti ueId; +CmLteCellId cellId; +CkwEntCfgInfo *cfgToValidate; +KwUlEntTmpData *cfgEntData; +#endif +{ + CmLteRlcId rlcId; /* RLC Identifier */ + TRC3(kwCfgValidateReEstRb) + + RLOG_ARG2(L_DEBUG, DBG_UEID,ueId, + "cellId(%d) RBID:%d", + cellId, + cfgToValidate->rbId); + + /* Get rlcId */ + rlcId.ueId = ueId; + rlcId.cellId = cellId; + rlcId.rbId = cfgToValidate->rbId; + rlcId.rbType = cfgToValidate->rbType; + + kwDbmFetchUlRbCbByRbId(gCb,&rlcId, &cfgEntData->rbCb); + if (cfgEntData->rbCb == NULLP) + { + RLOG_ARG2(L_WARNING, DBG_UEID,ueId, + "CellId [%u]: rbId [%d] not found", + cellId, + cfgToValidate->rbId); + cfgEntData->entUlCfgCfm.status.reason = CKW_CFG_REAS_RB_UNKWN; + RETVALUE(RFAILED); + } + + RETVALUE(ROK); +} + + + +/** + * @brief + * This primitive apply reestablishment of RB. + * + * @param [in] gCb - RLC Instance Control Block + * @param [in] ueId - UE Identifier + * @param [in] cellId - CELL Identifier + * @param [in] sndReEstInd - ReEstablish Indication Flag + * @param [in] cfgEntData - Configuration Temporary Data Entity + * + * @return S16 + * -# ROK + */ +#ifdef ANSI +PUBLIC Void kwCfgApplyReEstUlRb +( +KwCb *gCb, +CmLteRnti ueId, +CmLteCellId cellId, +Bool sndReEstInd, +KwUlEntTmpData *cfgEntData +) +#else +PUBLIC Void kwCfgApplyReEstUlRb(gCb, ueId, cellId, sndReEstInd, cfgEntData) +( +KwCb *gCb; +CmLteRnti ueId; +CmLteCellId cellId; +Bool sndReEstInd; +KwUlEntTmpData *cfgEntData; +) +#endif +{ + CmLteRlcId rlcId; /* RLC Identifier */ + TRC3(kwCfgApplyReEstUlRb) + + rlcId.ueId = ueId; + rlcId.cellId = cellId; + rlcId.rbId = cfgEntData->entUlCfgCfm.rbId; + rlcId.rbType = cfgEntData->entUlCfgCfm.rbType; + cfgEntData->rbCb->rlcId.ueId = ueId; + switch (cfgEntData->rbCb->mode) + { + case CM_LTE_MODE_TM: + { + kwTmmUlReEstablish(gCb,cfgEntData->rbCb); + break; + } + + case CM_LTE_MODE_UM: + { + kwUmmUlReEstablish(gCb,&rlcId,cfgEntData->rbCb); + break; + } + + case CM_LTE_MODE_AM: + { + kwAmmUlReEstablish(gCb,rlcId,sndReEstInd,cfgEntData->rbCb); + break; + } + } + RETVOID; +} + +/** + * @brief + * This primitive validates reestablishment of RB. + * + * @param [in] gCb - RLC Instance Control Block + * @param [in] ueInfo - UE Identifier + * @param [in] newUeInfo - CELL Identifier + * @param [in] cfgTmpData - Configuration Temporary Data + * + * @return S16 + * -# ROK + * -# RFAILED + */ +#ifdef ANSI +PUBLIC S16 kwCfgValidateUeIdChng +( +KwCb *gCb, +CkwUeInfo *ueInfo, +CkwUeInfo *newUeInfo, +KwUlCfgTmpData *cfgTmpData +) +#else +PUBLIC S16 kwCfgValidateUeIdChng(gCb,ueInfo,newUeInfo,cfgTmpData) +KwCb *gCb; +CkwUeInfo *ueInfo; +CkwUeInfo *newUeInfo; +KwUlCfgTmpData *cfgTmpData; +#endif +{ + KwUlUeCb *ueCb; + TRC3(kwCfgValidateUeIdChng) + +#define CFM_STATUS cfgTmpData->cfgEntData[0].entUlCfgCfm.status + if ( (ueInfo->ueId == newUeInfo->ueId) && + (ueInfo->cellId == newUeInfo->cellId)) + { + CFM_STATUS.reason = CKW_CFG_REAS_SAME_UEID; + CFM_STATUS.status = CKW_CFG_CFM_NOK; + RETVALUE(RFAILED); + } + + if(ROK == kwDbmFetchUlUeCb(gCb,newUeInfo->ueId, newUeInfo->cellId, &ueCb)) + { + RLOG_ARG1(L_ERROR, DBG_CELLID, newUeInfo->cellId, + "NewUeId[%d]:ueCb already exists", + newUeInfo->ueId); + CFM_STATUS.reason = CKW_CFG_REAS_UE_EXISTS; + CFM_STATUS.status = CKW_CFG_CFM_NOK; + RETVALUE(RFAILED); + } + + if(ROK != kwDbmFetchUlUeCb(gCb,ueInfo->ueId, ueInfo->cellId, + &cfgTmpData->ueCb)) + { + RLOG_ARG1(L_ERROR,DBG_CELLID, ueInfo->cellId, + "UeId [%d]: UeCb not found", + ueInfo->ueId); + CFM_STATUS.reason = CKW_CFG_REAS_UE_UNKWN; + CFM_STATUS.status = CKW_CFG_CFM_NOK; + RETVALUE(RFAILED); + } +#undef CFM_STATUS + RETVALUE(ROK); +} + + + +/** + * @brief + * This primitive apply reestablishment of RB. + * + * @param [in] gCb - RLC Instance Control Block + * @param [in] ueInfo - UE Identifier + * @param [in] newUeInfo - CELL Identifier + * @param [in] cfgTmpData - Configuration Temporary Data + * + * @return S16 + * -# ROK + */ +#ifdef ANSI +PUBLIC Void kwCfgApplyUlUeIdChng +( +KwCb *gCb, +CkwUeInfo *ueInfo, +CkwUeInfo *newUeInfo, +KwUlCfgTmpData *cfgTmpData +) +#else +PUBLIC Void kwCfgApplyUlUeIdChng(gCb, ueId, cellId, cfgTmpData) +( +KwCb *gCb; +CkwUeInfo *ueInfo, +CkwUeInfo *newUeInfo, +KwUlCfgTmpData *cfgTmpData; +) +#endif +{ + TRC3(kwCfgApplyUlUeIdChng) + +#ifdef LTE_L2_MEAS + kwHdlMeasUlUeIdChg(gCb, ueInfo->cellId, ueInfo->ueId, newUeInfo->ueId); +#endif + cmHashListDelete(&(gCb->u.ulCb->ueLstCp), (PTR) cfgTmpData->ueCb); + /* update the hash key with new values */ + cfgTmpData->ueCb->ueId = newUeInfo->ueId; + cfgTmpData->ueCb->cellId =newUeInfo->cellId; + if(ROK != cmHashListInsert(&(gCb->u.ulCb->ueLstCp), + (PTR)cfgTmpData->ueCb, + (U8 *)&(cfgTmpData->ueCb->ueId), + (U16) sizeof(CmLteRnti))) + + { + RLOG_ARG1(L_ERROR,DBG_CELLID,newUeInfo->cellId, + "UeId[%u] HashList Insertion Failed", + newUeInfo->ueId); + } + + RETVOID; +} +/********************************************************************30** + + End of file +**********************************************************************/ diff --git a/src/5gnrrlc/kw_dbm_dl.c b/src/5gnrrlc/kw_dbm_dl.c new file mode 100755 index 000000000..bb4da26ac --- /dev/null +++ b/src/5gnrrlc/kw_dbm_dl.c @@ -0,0 +1,929 @@ +/******************************************************************************* +################################################################################ +# Copyright (c) [2017-2019] [Radisys] # +# # +# 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. # +################################################################################ +*******************************************************************************/ + +/********************************************************************20** + + Name: RLC - Database module file + + Type: C source file + + Desc: Source code for Database Module functions such as, + + - kwDbmInit + - kwDbmDeInit + - kwDbmCreateRbCb + - kwDbmFetchRbCb + - kwDbmUpdateRbCb + - kwDbmDelRbCb + - kwDbmDelAllRb + - kwDbmCreateUeCb + - kwDbmFetchUeCb + - kwDbmUpdateUeCb + - kwDbmDelUeCb + - kwDbmDelAllUe + - kwDbmDelMeasEvtCb + - kwDbmCreateCellCb + - kwDbmFetchCellCb + - kwDbmUpdateCellCb + - kwDbmDelCellCb + - kwDbmDelAllCell + - kwDbmShutdown + + File: kw_dbm_dl.c + +*********************************************************************21*/ +static const char* RLOG_MODULE_NAME="DBM"; +static int RLOG_MODULE_ID=2048; +static int RLOG_FILE_ID=193; + + +/* header (.h) include files */ +#include "envopt.h" /* environment options */ +#include "envdep.h" /* environment dependent */ +#include "envind.h" /* environment independent */ + +#include "gen.h" /* general */ +#include "ssi.h" /* system services */ +#include "cm5.h" /* common timer defines */ +#include "cm_tkns.h" /* common tokens defines */ +#include "cm_mblk.h" /* common memory allocation library defines */ +#include "cm_llist.h" /* common link list defines */ +#include "cm_hash.h" /* common hash list defines */ +#include "cm_lte.h" /* common LTE defines */ +#include "lkw.h" /* LKW defines */ +#include "ckw.h" /* CKW defines */ +#include "kwu.h" /* KWU defines */ +#include "rgu.h" /* RGU defines */ +#include "kw_err.h" /* Err defines */ +#include "kw_env.h" /* RLC environment options */ + +#include "kw.h" /* RLC defines */ +#include "kw_udx.h" +#include "kw_dl.h" + +/* extern (.x) include files */ +#include "gen.x" /* general */ +#include "ssi.x" /* system services */ + +#include "cm5.x" /* common timer library */ +#include "cm_tkns.x" /* common tokens */ +#include "cm_mblk.x" /* common memory allocation */ +#include "cm_llist.x" /* common link list */ +#include "cm_hash.x" /* common hash list */ +#include "cm_lte.x" /* common LTE includes */ +#include "cm_lib.x" /* common memory allocation library */ +#include "lkw.x" /* LKW */ +#include "ckw.x" /* CKW */ +#include "kwu.x" /* KWU */ +#include "rgu.x" /* RGU */ + +#include "kw.x" +#include "kw_udx.x" +#include "kw_dl.x" + + +#ifdef TENB_STATS +EXTERN TSL2UeStatsCb* TSL2MapUeStatsBlk (U16 rnti); +#endif +/** + * @file gp_dbm_dl.c + * @brief RLC Downlink database module +*/ +#define KW_MODULE KW_DBGMASK_DUT + + +/** + * @brief Handler to initialize hash list + * + * @details + * This function initializes the UeCb, CellCb hash lists + * + * @return S16 + * -# ROK + * -# RFAILED +*/ +#ifdef ANSI +PUBLIC S16 kwDbmDlInit +( +KwCb *gCb +) +#else +PUBLIC S16 kwDbmDlInit(gCb) +KwCb *gCb; +#endif +{ + TRC3(kwDbmDlInit) + + /* Initialize ueCb Hash List */ + if(ROK != cmHashListInit(&(gCb->u.dlCb->ueLstCp), + (U16) KW_UE_LIST_BUCKET_SIZE, + (U16) 0, + (Bool) FALSE, + (U16) CM_HASH_KEYTYPE_CONID, + KW_GET_MEM_REGION(gCb), + KW_GET_MEM_POOL(gCb))) + { + RLOG0(L_ERROR, "UeLstCp Initialization Failed"); + RETVALUE(RFAILED); + } + + /* Initialize cellCb Hash List */ + if(ROK != cmHashListInit(&(gCb->u.dlCb->cellLstCp), + (U16) KW_CELL_LIST_BUCKET_SIZE, + (U16) 0, + (Bool) FALSE, + (U16) CM_HASH_KEYTYPE_CONID, + KW_GET_MEM_REGION(gCb), + KW_GET_MEM_POOL(gCb))) + { + cmHashListDeinit(&gCb->u.dlCb->ueLstCp); + RLOG0(L_ERROR, "CellLstCp Initialization Failed"); + RETVALUE(RFAILED); + } + +/* kw005.201 added support for L2 Measurement */ +#ifdef LTE_L2_MEAS_RLC + /* Initialize qcI Hash List */ + if(ROK != cmHashListInit(&(kwCb.kwL2Cb.qciHlCp), + (U16) KW_QCI_LIST_BUCKET_SIZE, + (U16) 0, + (Bool) TRUE, + (U16) CM_HASH_KEYTYPE_DEF, + kwCb.init.region, + kwCb.init.pool)) + { + cmHashListDeinit(&gCb->u.dlCb->cellLstCp); + cmHashListDeinit(&gCb->u.dlCb->ueLstCp); + RLOG0(L_ERROR, "kwDbmInit: cmHashListInit Failed for kwCb.qciHlCp"); + RETVALUE(RFAILED); + } + + /* Initialize tbHlCp Hash List */ + if(ROK != cmHashListInit(&(kwCb.kwL2Cb.tbHlCp), + (U16) KW_TB_LIST_BUCKET_SIZE, + (U16) 0, + (Bool) FALSE, + (U16) CM_HASH_KEYTYPE_DEF, + kwCb.init.region, + kwCb.init.pool)) + { + cmHashListDeinit(&kwCb.kwL2Cb.qciHlCp); + cmHashListDeinit(&gCb->u.dlCb->cellLstCp); + cmHashListDeinit(&gCb->u.dlCb->ueLstCp); + RLOG0(L_ERROR, "kwDbmInit: cmHashListInit Failed for kwCb.tbHlCp"); + RETVALUE(RFAILED); + } +#endif /* LTE_L2_MEAS */ + + RETVALUE(ROK); +} /* kwDbmDlInit */ + + +/** + * @brief Handler to De initialize hash list + * + * @param[in] gCb RLC Instance Control Block + * + * @return Void +*/ +#ifdef ANSI +PUBLIC Void kwDbmDlDeInit +( +KwCb *gCb +) +#else +PUBLIC Void kwDbmDlDeInit(gCb) +KwCb *gCb; +#endif +{ + TRC3(kwDbmDlDeInit); + + + /* De Initialize ueCb Hash List */ + cmHashListDeinit(&(gCb->u.dlCb->ueLstCp)); + + /* De Initialize cellCb Hash List */ + cmHashListDeinit(&(gCb->u.dlCb->cellLstCp)); + +/* kw005.201 added support for L2 Measurement */ +#ifdef LTE_L2_MEAS_RLC + /* De Initialize qciCb Hash List */ + cmHashListDeinit(&(kwCb.kwL2Cb.qciHlCp)); + + /* De Initialize tbHlCp Hash List */ + cmHashListDeinit(&(kwCb.kwL2Cb.tbHlCp)); + +#endif /* LTE_L2_MEAS */ + + RETVOID; +} /* kwDbmDlDeInit */ + + +/** + * @brief Handler to fetch rbCb by the rlcId + * + * @details + * This function is invoked by CFG to fetch rbCb from the cellCb/ueCb in + * the upper interface (CKW/KWU). + * + * @param[in] gCb RLC Instance Control Block + * @param[in] rlcId RLC Identifier + * @param[out] rbCb RB Control Block + * + * @return Void +*/ +#ifdef ANSI +PUBLIC Void kwDbmFetchDlRbCbByRbId +( +KwCb *gCb, +CmLteRlcId *rlcId, +KwDlRbCb **rbCb +) +#else +PUBLIC Void kwDbmFetchDlRbCbByRbId(gCb, rlcId, rbCb) +KwCb *gCb; +CmLteRlcId *rlcId; +KwDlRbCb **rbCb; +#endif +{ + TRC3(kwDbmFetchDlRbCbByRbId) + + *rbCb= NULLP; + + /* Check for UE CB or CELL CB */ + if (rlcId->ueId == 0) + { + KwDlCellCb *cellCb; + + if(rlcId->rbId >= KW_MAX_RB_PER_CELL) + { + RLOG_ARG3(L_ERROR,DBG_RBID,rlcId->rbId , + "Invalid RbId, Max is [%d] UEID:%d CELLID:%d", + KW_MAX_RB_PER_CELL, + rlcId->ueId, + rlcId->cellId); + RETVOID; + } + + kwDbmFetchDlCellCb(gCb,rlcId->cellId, &cellCb); + if(!cellCb) + { + RLOG_ARG2(L_ERROR,DBG_CELLID,rlcId->cellId, + "CellCb not found UEID:%d RBID:%d", + rlcId->ueId, + rlcId->rbId); + RETVOID; + } + + *rbCb = cellCb->rbCb[rlcId->rbId]; + } + else + { + KwDlUeCb *ueCb; + if (!(KW_VALIDATE_UE_RBID(rlcId->rbType, rlcId->rbId))) + { + RLOG_ARG3(L_ERROR,DBG_RBID, rlcId->rbId, + "Invalid RbId for RbType[%d] RBID:%d CELLID:%d", + rlcId->rbType, + rlcId->ueId, + rlcId->cellId); + RETVOID; + } + + if (ROK != kwDbmFetchDlUeCb(gCb,rlcId->ueId, rlcId->cellId, &ueCb)) + { + RLOG_ARG2(L_ERROR,DBG_CELLID, rlcId->cellId, + "UeId [%d]: UeCb not found RBID:%d", + rlcId->ueId, + rlcId->rbId); + RETVOID; + } + + KW_DBM_GET_RBCB_FROM_UECB(rlcId->rbId, rlcId->rbType, ueCb, *rbCb); + } + + RETVOID; +} /* kwDbmFetchDlRbCbByRbId */ + + +/** + * @brief Handler to fetch rbCb from Local Channel Id + * + * @details + * This function is invoked by CFG to fetch rbCb from the cellCb/ueCb + * from local Channel Id (CKW/KWU). + * + * @param[in] gCb - RLC Instance Control Block + * @param[in] cellId - CELL Identifier + * @param[in] ueId - UE Identifier + * @param[in] lcId - Logical Channel Identifier + * @param[out] rbCb - RB Control Block + * + * @return Void + * +*/ +#ifdef ANSI +PUBLIC Void kwDbmFetchDlRbCbFromLchId +( +KwCb *gCb, +CmLteRnti ueId, +CmLteCellId cellId, +CmLteLcId lcId, +KwDlRbCb **rbCb +) +#else +PUBLIC Void kwDbmFetchDlRbCbFromLchId(gCb, ueId, cellId, lcId, rbCb) +KwCb *gCb; +CmLteRnti ueId; +CmLteCellId cellId; +CmLteLcId lcId; +KwDlRbCb **rbCb; +#endif +{ + KwDlUeCb *ueCb; + + TRC3(kwDbmFetchDlRbCbFromLchId) + + + /* Check for UE CB or CELL CB */ + if (ueId == 0) + { + KwDlCellCb *cellCb; + + kwDbmFetchDlCellCb(gCb, cellId, &cellCb); + if(!cellCb) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cellId,"CellCb not found UEID:%d",ueId); + RETVOID; + } + + *rbCb = cellCb->lCh[lcId - 1].dlRbCb; + RETVOID; + } + + if (kwDbmFetchDlUeCb(gCb, ueId, cellId, &ueCb) != ROK) + { + RLOG_ARG1(L_ERROR,DBG_CELLID, cellId,"UeId [%d]: UeCb not found",ueId); + RETVOID; + } + + *rbCb = ueCb->lCh[lcId - 1].dlRbCb; + + RETVOID; +} /* kwDbmFetchDlRbCbFromLchId */ + + +/** + * @brief Handler to delete RbCb + * + * @details + * This function is invoked by CFG to remove RbCb from Ue/Cell hashlist + * + * @param[in] gCb - RLC Instance Control Block + * @param[in] rbCbLst - Rb Cb List + * @param[in] numRbCb - Number of rbCbs + * + * @return Void + * +*/ +#ifdef ANSI +PUBLIC Void kwDbmDelAllDlRb +( +KwCb *gCb, +KwDlRbCb **rbCbLst, +U8 numRbCb +) +#else +PUBLIC Void kwDbmDelAllDlRb(gCb, rbCbLst, numRbCb) +KwCb *gCb; +KwDlRbCb **rbCbLst; +U8 numRbCb; +#endif +{ + U32 idx; + + TRC3(kwDbmDelAllDlRb) + + + for (idx = 0; idx < numRbCb; idx++) + { + if (rbCbLst[idx] != NULLP) + { +#ifdef LTE_L2_MEAS + KW_UPD_L2_DECR_NONIP_PER_QCI_RB_COUNT(gCb, (rbCbLst[idx])); +#endif + if( CM_LTE_MODE_UM == rbCbLst[idx]->mode) + { + kwUmmFreeDlRbCb(gCb,rbCbLst[idx]); + + KW_FREE (gCb,rbCbLst[idx], sizeof (KwDlRbCb)); + } + else if( CM_LTE_MODE_AM == rbCbLst[idx]->mode) + { + kwAmmFreeDlRbCb(gCb,rbCbLst[idx]); + } + /* ccpu00136940 */ + else if(CM_LTE_MODE_TM == rbCbLst[idx]->mode) + { + cmLListCatLList(&(gCb->u.dlCb->toBeFreed.sduLst),&(rbCbLst[idx]->m.tm.sduQ)); + KW_FREE (gCb,rbCbLst[idx], sizeof (KwDlRbCb)); + } + + } + + } + + RETVOID; +} /* kwDbmDelAllDlRb */ + + +/** + * @brief Handler to create an UeCb + * + * @details + * This function is invoked by CFG to create UeCb and insert into the + * Ue hashlist of KwCb. + * + * @param[in] gCb RLC Instance Control Block + * @param[in] ueId UE Identifier + * @param[in] cellId Cell Identifier + * @param[in] ueCb UE Control Block + * + * @return S16 + * -# ROK + * -# RFAILED + * +*/ +#ifdef ANSI +PUBLIC S16 kwDbmCreateDlUeCb +( +KwCb *gCb, +CmLteRnti ueId, +CmLteCellId cellId, +KwDlUeCb **ueCb +) +#else +PUBLIC S16 kwDbmCreateDlUeCb(gCb,ueId, cellId, ueCb) +KwCb *gCb; +CmLteRnti ueId; +CmLteCellId cellId; +KwDlUeCb **ueCb; +#endif +{ + KwDlUeCb *tUeCb; + + TRC3(kwDbmCreateDlUeCb) + + + KW_ALLOC(gCb,*ueCb, sizeof(KwDlUeCb)); + +#if (ERRCLASS & ERRCLS_ADD_RES) + if (*ueCb == NULLP) + { + RLOG_ARG1(L_FATAL,DBG_UEID,ueId, + "Memory allocation failed cellID:%d", + cellId); + RETVALUE(RFAILED); + } +#endif /* ERRCLASS & ERRCLS_ADD_RES */ + + tUeCb = *ueCb; + tUeCb->ueId = ueId; + tUeCb->cellId = cellId; + + if (ROK != cmHashListInsert(&(gCb->u.dlCb->ueLstCp), + (PTR)tUeCb, + (U8 *)&(tUeCb->ueId), + (U16) sizeof(CmLteRnti))) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cellId, + "UeId[%u] HashList Insertion Failed", + ueId); + RETVALUE(RFAILED); + } + /* kw005.201 ccpu00117318, updating the statistics */ + gCb->genSts.numUe++; + + + RETVALUE(ROK); +} /* kwDbmCreateUeCb */ + + +/** + * @brief Handler to Fetch an UeCb + * + * @details + * This function is invoked by CFG to fetch UeCb from the Ue hashlist + * of KwCb. + * + * @param[in] gCb RLC Instance Control Block + * @param[in] ueId UE Identifier + * @param[in] cellId Cell Identifier + * @param[out] ueCb UE Control Block + * + * @return S16 + * -# ROK + * -# RFAILED +*/ +#ifdef ANSI +PUBLIC S16 kwDbmFetchDlUeCb +( +KwCb *gCb, +CmLteRnti ueId, +CmLteCellId cellId, +KwDlUeCb **ueCb +) +#else +PUBLIC S16 kwDbmFetchDlUeCb(gCb,ueId, cellId, ueCb) +KwCb *gCb; +CmLteRnti ueId; +CmLteCellId cellId; +KwDlUeCb **ueCb; +#endif +{ + + TRC3(kwDbmFetchDlUeCb) + + + RETVALUE(cmHashListFind(&(gCb->u.dlCb->ueLstCp), + (U8 *)&(ueId), + sizeof(CmLteRnti), + KW_DEF_SEQ_NUM, + (PTR *) ueCb)); +} /* kwDbmFetchDlUeCb */ + + +/** + * @brief Handler to delete an UeCb + * + * @details + * This function is invoked by CFG to delete UeCb from the Ue hashlist + * of KwCb. + * + * + * @param[in] gCb RLC Instance Control Block + * @param[in] ueCb UE Control Block + * @param[in] abrtFlag Abort Flag + * + * @return Void + * +*/ +#ifdef ANSI +PUBLIC Void kwDbmDelDlUeCb +( +KwCb *gCb, +KwDlUeCb *ueCb, +Bool abortFlag +) +#else +PUBLIC Void kwDbmDelDlUeCb(gCb,eCb, abortFlag) +KwCb *gCb; +KwDlUeCb *ueCb; +Bool abortFlag; +#endif +{ + TRC3(kwDbmDelDlUeCb) + + +#if (!defined(KW_PDCP) || !(defined(PJ_SEC_ASYNC) || defined(PJ_CMP_ASYNC))) + UNUSED(abortFlag); +#endif /* (!defined(KW_PDCP) || ! (defined(PJ_SEC_ASYNC) || + defined(PJ_CMP_ASYNC)))*/ + + /* Delete all logical channels */ + KW_MEM_ZERO(ueCb->lCh,sizeof(KwDlLch) * KW_MAX_LCH_PER_UE); + + /* Delete all SRB RbCbs in UeCb */ + kwDbmDelAllDlRb(gCb,ueCb->srbCb, KW_MAX_SRB_PER_UE); + + /* Delete all DRB RbCbs in UeCb */ + kwDbmDelAllDlRb(gCb,ueCb->drbCb, KW_MAX_DRB_PER_UE); + + /* Delete ueCb entry from ueLstCp */ + if(ROK != cmHashListDelete(&(gCb->u.dlCb->ueLstCp), (PTR) ueCb)) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,ueCb->cellId, + "UeId[%u] HashList Insertion Failed", + ueCb->ueId); + } + /* kw005.201 ccpu00117318, updating the statistics */ + gCb->genSts.numUe--; + + /* Deallocate ueCb */ + KW_FREE(gCb,ueCb, sizeof(KwDlUeCb)); + + RETVOID; +} /* kwDbmDelUeCb */ + + +/** + * @brief Handler to delete all UeCbs + * + * @details + * This function is invoked by CFG to delete all UeCbs from the Ue + * hashlist of KwCb. + * + * @param[in] gCb RLC Instance Control Block + * + * @return Void +*/ +#ifdef ANSI +PUBLIC Void kwDbmDelAllDlUe +( +KwCb *gCb +) +#else +PUBLIC Void kwDbmDelAllDlUe(gCb) +KwCb *gCb; +#endif +{ + KwDlUeCb *ueCb = NULLP; + + TRC3(kwDbmDelAllDlUe) + + + /* Until no more ueCb is ueLstCp hash list get and delete ueCb */ + while (ROK == cmHashListGetNext(&(gCb->u.dlCb->ueLstCp), + (PTR) ueCb, + (PTR *)&ueCb)) + { + /* Delete ueCb */ + kwDbmDelDlUeCb(gCb,ueCb, TRUE); + + ueCb = NULLP; + } + + RETVOID; +} /* kwDbmDelAllUe */ + +/* kw005.201 added support for L2 Measurement */ +#ifdef LTE_L2_MEAS +#ifdef ANSI +PUBLIC Void kwDbmDelAllDlL2MeasTbFrmUe +( +KwCb *gCb, +KwDlUeCb *ueCb +) +#else +PUBLIC Void kwDbmDelAllDlL2MeasTbFrmUe(gCb,ueCb) +KwCb *gCb; +KwDlUeCb *ueCb; +#endif +{ + U8 tbIdx; + KwL2MeasTb *l2MeasTb = NULLP; + for(tbIdx = 0; tbIdx < KW_MAX_TB_PER_UE; tbIdx++) + { + l2MeasTb = ueCb->l2MeasTbCb[tbIdx]; + if(l2MeasTb != NULLP) + { + KW_FREE(gCb,l2MeasTb, sizeof(KwL2MeasTb)); + ueCb->l2MeasTbCb[tbIdx] = NULLP; + } + } + RETVOID; +}/* End of kwDbmDelL2MeasTb */ +#endif /* LTE_L2_MEAS */ + +/** + * @brief Handler to create CellCb + * + * @details + * This function is invoked by CFG to create CellCb and insert into + * the Cell hashlist of KwCb. + * + * @param[in] gCb RLC Instance Control Block + * @param[in] cellId Cell Identifier + * @param[in] cellCb Cell Control Block + * + * @return S16 + * -# ROK + * -# RFAILED +*/ +#ifdef ANSI +PUBLIC S16 kwDbmCreateDlCellCb +( +KwCb *gCb, +CmLteCellId cellId, +KwDlCellCb **cellCb +) +#else +PUBLIC S16 kwDbmCreateDlCellCb(gCb,cellId, cellCb) +KwCb *gCb; +CmLteCellId cellId; +KwDlCellCb **cellCb; +#endif +{ + KwDlCellCb *tCellCb; + + TRC3(kwDbmCreateDlCellCb) + + KW_ALLOC(gCb,*cellCb, sizeof(KwDlCellCb)); +#if (ERRCLASS & ERRCLS_ADD_RES) + if (*cellCb == NULLP) + { + RLOG_ARG0(L_FATAL, DBG_CELLID,cellId,"Memory allocation failed"); + RETVALUE(RFAILED); + } +#endif /* ERRCLASS & ERRCLS_ADD_RES */ + + tCellCb = *cellCb; + tCellCb->cellId = cellId; + + if(ROK != cmHashListInsert(&(gCb->u.dlCb->cellLstCp), + (PTR) tCellCb, + (U8 *)&(tCellCb->cellId), + (U16) sizeof(CmLteCellId))) + { + RLOG_ARG0(L_ERROR,DBG_CELLID,cellId,"HashList Insertion Failed"); + RETVALUE(RFAILED); + } + + RETVALUE(ROK); +} /* kwDbmCreateDlCellCb */ + + +/** + * @brief Handler to Fetch an CellCb + * + * @details + * This function is invoked by CFG to fetch UeCb from the Ue hashlist + * of KwCb. + * + * @param[in] gCb RLC Instance Control Block + * @param[in] cellId Cell Identifier + * @param[out] cellCb UE Control Block + * + * @return S16 + * -# ROK + * -# RFAILED + * +*/ +#ifdef ANSI +PUBLIC S16 kwDbmFetchDlCellCb +( +KwCb *gCb, +CmLteCellId cellId, +KwDlCellCb **cellCb +) +#else +PUBLIC S16 kwDbmFetchDlCellCb(gCb,cellId, cellCb) +KwCb *gCb; +CmLteCellId cellId; +KwDlCellCb **cellCb; +#endif +{ + TRC3(kwDbmFetchDlCellCb) + + + *cellCb = NULLP; + + if(ROK != cmHashListFind(&(gCb->u.dlCb->cellLstCp), + (U8 *)&(cellId), + sizeof(CmLteCellId), + KW_DEF_SEQ_NUM, + (PTR*) cellCb)) + { + RLOG_ARG0(L_ERROR,DBG_CELLID, cellId,"CellCb not found"); + RETVALUE(RFAILED); + } + + RETVALUE(ROK); +} /* kwDbmFetchCellCb */ + + +/** + * @brief Handler to delete CellCb + * + * @details + * This function is invoked by CFG to delete CellCb from the Cell hashlist + * of KwCb. + * + * @param[in] gCb RLC Instance Control Block + * @param[in] cellCb Cell Control Block + * + * @return Void +*/ +#ifdef ANSI +PUBLIC Void kwDbmDelDlCellCb +( +KwCb *gCb, +KwDlCellCb *cellCb +) +#else +PUBLIC Void kwDbmDelDlCellCb(gCb,cellCb) +KwCb *gCb; +KwDlCellCb *cellCb; +#endif +{ + TRC3(kwDbmDelDlCellCb) + + + /* Delete all rbCbs in cellCb */ + kwDbmDelAllDlRb(gCb,cellCb->rbCb, KW_MAX_RB_PER_CELL); + + /* Delete cellCb entry in hash list cellLstCp */ + if(ROK != cmHashListDelete(&(gCb->u.dlCb->cellLstCp), (PTR) cellCb)) + { + RLOG_ARG0(L_ERROR,DBG_CELLID,cellCb->cellId,"HashList Deletion Failed"); + } + + /* Deallocate cellCb */ + KW_FREE(gCb, cellCb, sizeof(KwDlCellCb)); + + RETVOID; +} /* kwDbmDelCellCb */ + + +/** + * @brief Handler to delete all UeCbs + * + * @details + * This function is invoked by CFG to delete all UeCbs from the Ue + * hashlist of KwCb. + * @param[in] gCb RLC Instance Control Block + * + * @return Void +*/ +#ifdef ANSI +PUBLIC Void kwDbmDelAllDlCell +( +KwCb *gCb +) +#else +PUBLIC Void kwDbmDelAllDlCell(gCb) +KwCb *gCb; +#endif +{ + KwDlCellCb *cellCb = NULLP; + + TRC3(kwDbmDelAllDlCell) + + + /* Until no more cellCb is ueLstCp hash list get and delete cellCb */ + while (ROK == cmHashListGetNext(&(gCb->u.dlCb->cellLstCp), + (PTR) cellCb, + (PTR *)&cellCb)) + { + kwDbmDelDlCellCb(gCb, cellCb); + + cellCb = NULLP; + } + + RETVOID; +} /* kwDbmDelAllDlCell */ + + +/** + * @brief Handler to delete all UeCbs and CellCbs + * + * @details + * This function is invoked by LMM to delete all UeCbs from the Ue + * hashlist of KwCb and cellCbs from the Cell hashlist of kwCb. + * + * @param[in] gCb RLC Instance Control Block + * + * @return Void +*/ +#ifdef ANSI +PUBLIC S16 kwDbmDlShutdown +( +KwCb *gCb +) +#else +PUBLIC S16 kwDbmDlShutdown(gCb) +KwCb *gCb; +#endif +{ + TRC3(kwDbmDlShutdown) + + kwDbmDelAllDlCell(gCb); + + kwDbmDelAllDlUe(gCb); + + kwDbmDlDeInit(gCb); + + + RETVALUE(ROK); +} /* kwDbmShutdown */ + + +/********************************************************************30** + + End of file +**********************************************************************/ diff --git a/src/5gnrrlc/kw_dbm_ul.c b/src/5gnrrlc/kw_dbm_ul.c new file mode 100755 index 000000000..2cbb23628 --- /dev/null +++ b/src/5gnrrlc/kw_dbm_ul.c @@ -0,0 +1,990 @@ +/******************************************************************************* +################################################################################ +# Copyright (c) [2017-2019] [Radisys] # +# # +# 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. # +################################################################################ +*******************************************************************************/ + +/********************************************************************20** + + Name: RLC - Database module file + + Type: C source file + + Desc: Source code for Database Module functions such as, + + File: kw_dbm_ul.c + +*********************************************************************21*/ +static const char* RLOG_MODULE_NAME="DBM"; +static int RLOG_MODULE_ID=2048; +static int RLOG_FILE_ID=194; + + +/* header (.h) include files */ +#include "envopt.h" /* environment options */ +#include "envdep.h" /* environment dependent */ +#include "envind.h" /* environment independent */ + +#include "gen.h" /* general */ +#include "ssi.h" /* system services */ +#include "cm5.h" /* common timer defines */ +#include "cm_tkns.h" /* common tokens defines */ +#include "cm_mblk.h" /* common memory allocation library defines */ +#include "cm_llist.h" /* common link list defines */ +#include "cm_hash.h" /* common hash list defines */ +#include "cm_lte.h" /* common LTE defines */ +#include "lkw.h" /* LKW defines */ +#include "ckw.h" /* CKW defines */ +#include "kwu.h" /* KWU defines */ +#include "rgu.h" /* RGU defines */ +#include "kw_err.h" /* Err defines */ +#include "kw_env.h" /* RLC environment options */ + +#include "kw.h" /* RLC defines */ +#include "kw_ul.h" + +/* extern (.x) include files */ +#include "gen.x" /* general */ +#include "ssi.x" /* system services */ + +#include "cm5.x" /* common timer library */ +#include "cm_tkns.x" /* common tokens */ +#include "cm_mblk.x" /* common memory allocation */ +#include "cm_llist.x" /* common link list */ +#include "cm_hash.x" /* common hash list */ +#include "cm_lte.x" /* common LTE includes */ +#include "cm_lib.x" /* common memory allocation library */ +#include "lkw.x" /* LKW */ +#include "ckw.x" /* CKW */ +#include "kwu.x" /* KWU */ +#include "rgu.x" /* RGU */ + +#include "kw.x" +#include "kw_ul.x" + +/** + * @file gp_dbm_ul.c + * @brief RLC Uplink database module +*/ + +#define KW_MODULE KW_DBGMASK_DUT + + +/** + * @brief Handler to initialize hash list + * + * @details + * This function initializes the UeCb, CellCb and transactions hash lists + * + * @param[in] gCb RLC instance control block + * + * @return S16 + * -# ROK + * -# RFAILED +*/ +#ifdef ANSI +PUBLIC S16 kwDbmUlInit +( +KwCb *gCb +) +#else +PUBLIC S16 kwDbmUlInit(gCb) +KwCb *gCb; +#endif +{ + TRC3(kwUlDbmInit) + + /* Initialize ueCb Hash List */ + if(ROK != cmHashListInit(&(gCb->u.ulCb->ueLstCp), + (U16) KW_UE_LIST_BUCKET_SIZE, + (U16) 0, + (Bool) FALSE, + (U16) CM_HASH_KEYTYPE_CONID, + KW_GET_MEM_REGION(gCb), + KW_GET_MEM_POOL(gCb))) + { + RLOG0(L_ERROR, "UeLstCp Initialization Failed"); + RETVALUE(RFAILED); + } + + /* Initialize cellCb Hash List */ + if(ROK != cmHashListInit(&(gCb->u.ulCb->cellLstCp), + (U16) KW_CELL_LIST_BUCKET_SIZE, + (U16) 0, + (Bool) FALSE, + (U16) CM_HASH_KEYTYPE_CONID, + KW_GET_MEM_REGION(gCb), + KW_GET_MEM_POOL(gCb))) + { + cmHashListDeinit(&gCb->u.ulCb->ueLstCp); + RLOG0(L_ERROR, "CellLstCp Initialization Failed"); + RETVALUE(RFAILED); + } + + if(ROK != cmHashListInit(&(gCb->u.ulCb->transIdLstCp), + (U16) KW_TRANS_ID_LST_BKT_SIZE, + (U16) 0, + (Bool) FALSE, + (U16) CM_HASH_KEYTYPE_CONID, + KW_GET_MEM_REGION(gCb), + KW_GET_MEM_POOL(gCb))) + { + cmHashListDeinit(&gCb->u.ulCb->ueLstCp); + cmHashListDeinit(&gCb->u.ulCb->cellLstCp); + RLOG0(L_ERROR, "transIdLstCp Initialization Failed"); + RETVALUE(RFAILED); + } + +/* kw005.201 added support for L2 Measurement */ +#ifdef LTE_L2_MEAS + /* Initialize qcI Hash List */ +#endif /* LTE_L2_MEAS */ + + RETVALUE(ROK); +} /* kwDbmUlInit */ + + +/** + * @brief Handler to De initialize hash list + * + * @param[in] gCb RLC Instance Control Block + * + * @return Void +*/ +#ifdef ANSI +PUBLIC Void kwDbmUlDeInit +( +KwCb *gCb +) +#else +PUBLIC Void kwDbmUlDeInit(gCb) +KwCb *gCb; +#endif +{ + TRC3(kwDbmUlDeInit); + + + /* De Initialize ueCb Hash List */ + cmHashListDeinit(&(gCb->u.ulCb->ueLstCp)); + + /* De Initialize cellCb Hash List */ + cmHashListDeinit(&(gCb->u.ulCb->cellLstCp)); + + /* De Initialize transaction Hash List */ + cmHashListDeinit(&(gCb->u.ulCb->transIdLstCp)); +/* kw005.201 added support for L2 Measurement */ +#ifdef LTE_L2_MEAS_RLC + /* De Initialize qciCb Hash List */ + cmHashListDeinit(&(kwCb.kwL2Cb.qciHlCp)); +#endif /* LTE_L2_MEAS */ + + RETVOID; +} /* kwDbmDeInit */ + + +/** + * @brief Handler to fetch rbCb by the rlcId + * + * @details + * This function is invoked by CFG to fetch rbCb from the cellCb/ueCb in + * the upper interface (CKW/KWU). + * + * @param[in] gCb RLC Instance Control Block + * @param[in] rlcId RLC Identifier + * @param[out] rbCb RB Control Block + * + * @return Void +*/ +#ifdef ANSI +PUBLIC Void kwDbmFetchUlRbCbByRbId +( +KwCb *gCb, +CmLteRlcId *rlcId, +KwUlRbCb **rbCb +) +#else +PUBLIC Void kwDbmFetchUlRbCbByRbId(gCb, rlcId, rbCb) +KwCb *gCb; +CmLteRlcId *rlcId; +KwUlRbCb **rbCb; +#endif +{ + TRC3(kwDbmFetchUlRbCbByRbId) + + *rbCb= NULLP; + + /* Check for UE CB or CELL CB */ + if (rlcId->ueId == 0) + { + KwUlCellCb *cellCb; + + if(rlcId->rbId >= KW_MAX_RB_PER_CELL) + { + RLOG_ARG3(L_ERROR,DBG_RBID,rlcId->rbId , + "Invalid RbId, cellId:%d UEID:%d Max is [%d]", + rlcId->cellId, + rlcId->ueId, + KW_MAX_RB_PER_CELL); + RETVOID; + } + + kwDbmFetchUlCellCb(gCb,rlcId->cellId, &cellCb); + if(!cellCb) + { + RLOG_ARG2(L_ERROR,DBG_CELLID,rlcId->cellId, + "CellCb not found RBID:%d UEID:%d", + rlcId->rbId, + rlcId->ueId); + RETVOID; + } + + *rbCb = cellCb->rbCb[rlcId->rbId]; + } + else + { + KwUlUeCb *ueCb; + + if (!(KW_VALIDATE_UE_RBID(rlcId->rbType, rlcId->rbId))) + { + RLOG_ARG3(L_ERROR,DBG_RBID, rlcId->rbId, + "Invalid RbId for RbType[%d] CELLID:%d UEID:%d", + rlcId->rbType, + rlcId->cellId, + rlcId->ueId); + RETVOID; + } + + if (kwDbmFetchUlUeCb(gCb,rlcId->ueId, rlcId->cellId, &ueCb) != ROK) + { + RLOG_ARG2(L_ERROR,DBG_CELLID, rlcId->cellId, + "UeId [%d]: UeCb not found RBID:%d", + rlcId->ueId, + rlcId->rbId); + RETVOID; + } + + KW_DBM_GET_RBCB_FROM_UECB(rlcId->rbId, rlcId->rbType, ueCb, *rbCb); + } + RETVOID; +} /* kwDbmFetchUlRbCbByRbId */ + + +/** + * @brief Handler to fetch rbCb from Local Channel Id + * + * @details + * This function is invoked by CFG to fetch rbCb from the cellCb/ueCb + * from local Channel Id (CKW/KWU). + * + * @param[in] gCb - RLC Instance Control Block + * @param[in] cellId - CELL Identifier + * @param[in] ueId - UE Identifier + * @param[in] lcId - Logical Channel Identifier + * @param[out] rbCb - RB Control Block + * + * @return Void + * +*/ +#ifdef ANSI +PUBLIC Void kwDbmFetchUlRbCbFromLchId +( +KwCb *gCb, +CmLteRnti ueId, +CmLteCellId cellId, +CmLteLcId lcId, +KwUlRbCb **rbCb +) +#else +PUBLIC Void kwDbmFetchUlRbCbFromLchId(gCb, ueId, cellId, lcId, rbCb) +KwCb *gCb; +CmLteRnti ueId; +CmLteCellId cellId; +CmLteLcId lcId; +KwUlRbCb **rbCb; +#endif +{ + KwUlUeCb *ueCb; + + TRC3(kwDbmFetchUlRbCbFromLchId) + + + *rbCb = NULLP; + + /* Check for UE CB or CELL CB */ + if (ueId == 0) + { + KwUlCellCb *cellCb; + + kwDbmFetchUlCellCb(gCb,cellId, &cellCb); + if(!cellCb) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cellId,"CellCb not found UEID:%d",ueId); + RETVOID; + } + + *rbCb = cellCb->lCh[lcId - 1].ulRbCb; + RETVOID; + } + + if (kwDbmFetchUlUeCb(gCb,ueId, cellId, &ueCb) != ROK) + { + RLOG_ARG1(L_ERROR,DBG_CELLID, cellId,"UeId [%d]: UeCb not found",ueId); + RETVOID; + } + + *rbCb = ueCb->lCh[lcId - 1].ulRbCb; + + RETVOID; +} /* kwDbmFetchRbCbFromLchId */ + + +/** + * @brief Handler to delete RbCb + * + * @details + * This function is invoked by CFG to remove RbCb from Ue/Cell hashlist + * + * @param[in] gCb - RLC Instance Control Block + * @param[in] rbCbLst - Rb Cb List + * @param[in] numRbCb - Number of rbCbs + * + * @return Void + * +*/ +#ifdef ANSI +PUBLIC Void kwDbmDelAllUlRb +( +KwCb *gCb, +KwUlRbCb **rbCbLst, +U8 numRbCb +) +#else +PUBLIC Void kwDbmDelAllUlRb(gCb, rbCbLst, numRbCb) +KwCb *gCb; +KwUlRbCb **rbCbLst; +U8 numRbCb; +#endif +{ + U32 idx; /* Index */ + + TRC3(kwDbmDelAllUlRb) + + + for (idx = 0; idx < numRbCb; idx++) + { + if (rbCbLst[idx] != NULLP) + { + /* Free the Buffers of RbCb */ + if( CM_LTE_MODE_UM == rbCbLst[idx]->mode ) + { + kwUmmFreeUlRbCb(gCb,rbCbLst[idx]); + } + else if(CM_LTE_MODE_AM == rbCbLst[idx]->mode) + { + kwAmmFreeUlRbCb(gCb,rbCbLst[idx]); + } + + KW_FREE (gCb,rbCbLst[idx], sizeof (KwUlRbCb)); + } + } + + RETVOID; +} /* kwDbmDelAllRb */ + + +/** + * @brief Handler to create an UeCb + * + * @details + * This function is invoked by CFG to create UeCb and insert into the + * Ue hashlist of KwCb. + * + * @param[in] gCb RLC Instance Control Block + * @param[in] ueId UE Identifier + * @param[in] cellId Cell Identifier + * @param[in] ueCb UE Control Block + * + * @return S16 + * -# ROK + * -# RFAILED + * +*/ +#ifdef ANSI +PUBLIC S16 kwDbmAddUlUeCb +( +KwCb *gCb, +CmLteRnti ueId, +CmLteCellId cellId, +KwUlUeCb *ueCb +) +#else +PUBLIC S16 kwDbmAddUlUeCb(gCb, ueId, cellId, ueCb) +KwCb *gCb; +CmLteRnti ueId; +CmLteCellId cellId; +KwUlUeCb *ueCb; +#endif +{ + TRC3(kwDbmAddUlUeCb) + + + ueCb->ueId = ueId; + ueCb->cellId = cellId; + + if(ROK != cmHashListInsert(&(gCb->u.ulCb->ueLstCp), + (PTR)ueCb, + (U8 *)&(ueCb->ueId), + (U16) sizeof(CmLteRnti))) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cellId, + "UeId[%u] HashList Insertion Failed", + ueId); + RETVALUE(RFAILED); + } + /* kw005.201 ccpu00117318, updating the statistics */ + gCb->genSts.numUe++; + + + RETVALUE(ROK); +} + + +/** + * @brief Handler to add a transaction + * + * @details + * This function adds a transaction. + * + * @param[in] gCb RLC Instance Control Block + * @param[in] cfg Configuration information + * + * @return S16 + * -# ROK + * -# RFAILED + * +*/ +#ifdef ANSI +PUBLIC S16 kwDbmAddUlTransaction +( +KwCb *gCb, +KwUlCfgTmpData *cfg +) +#else +PUBLIC S16 kwDbmAddUlTransaction(gCb, cfg) +KwCb *gCb; +KwUlCfgTmpData *cfg; +#endif +{ + TRC3(kwDbmAddUlTransaction) + +#ifndef ALIGN_64BIT + RLOG1(L_DEBUG, "(transId(%ld)", cfg->transId); +#else + RLOG1(L_DEBUG, "(transId(%d))", cfg->transId); +#endif + + RETVALUE(cmHashListInsert(&(gCb->u.ulCb->transIdLstCp), + (PTR)cfg, + (U8 *)&(cfg->transId), + (U16) sizeof(cfg->transId))); +} + + +/** + * @brief Handler to find a transaction + * + * @details + * This function find transaction using transaction Id + * + * + * @param[in] gCb RLC Instance Control Block + * @param[in] transId Transaction Id + * @param[out] cfg Configuration information attached to this transaction + * + * @return S16 + * -# ROK + * -# RFAILED + * +*/ +#ifdef ANSI +PUBLIC S16 kwDbmFindUlTransaction +( +KwCb *gCb, +U32 transId, +KwUlCfgTmpData **cfg +) +#else +PUBLIC S16 kwDbmFindUlTransaction(gCb, cfg) +KwCb *gCb; +U32 transId; +KwUlCfgTmpData **cfg; +#endif +{ + TRC3(kwDbmFindUlTransaction) + + if(ROK != cmHashListFind(&(gCb->u.ulCb->transIdLstCp), + (U8 *) &transId, + sizeof (transId), + KW_DEF_SEQ_NUM,(PTR *) cfg)) + { + RLOG1(L_ERROR,"TransId [%ld] not found",transId); + RETVALUE(RFAILED); + } + RETVALUE(ROK); +} + + +/** + * + * @brief Handler to delete a transaction + * + * @details + * This function deletes a transaction + * + * + * @param[in] gCb RLC Instance Control Block + * @param[in] cfg Configuration information + * + * @return S16 + * -# ROK + * -# RFAILED + * +*/ +#ifdef ANSI +PUBLIC S16 kwDbmDelUlTransaction +( +KwCb *gCb, +KwUlCfgTmpData *cfg +) +#else +PUBLIC S16 kwDbmDelUlTransaction(gCb, cfg) +KwCb *gCb; +KwUlCfgTmpData *cfg; +#endif +{ + TRC3(kwDbmDelUlTransaction) + + + if(cmHashListDelete(&(gCb->u.ulCb->transIdLstCp),(PTR) (cfg)) != ROK) + { + RLOG0(L_ERROR,"HashList Deletion failed"); + RETVALUE(RFAILED); + } + + RETVALUE(ROK); +} + + +/** + * @brief Handler to delete all transaction + * + * @details + * This function deletes all transaction + * + * @param[in] gCb RLC Instance Control Block + * + * @return S16 + * -# ROK + * -# RFAILED + * +*/ +#ifdef ANSI +PUBLIC S16 kwDbmDelAllUlTransactions +( +KwCb *gCb +) +#else +PUBLIC S16 kwDbmDelAllUlTransactions(gCb) +KwCb *gCb; +#endif +{ + KwUlCfgTmpData *cfg = NULL; + + TRC3(kwDbmDelAllUlTransctions) + + /* Until no more ueCb is ueLstCp hash list get and delete ueCb */ + while (ROK == cmHashListGetNext(&(gCb->u.ulCb->transIdLstCp), + (PTR) cfg, + (PTR *)&cfg)) + { + if(kwDbmDelUlTransaction(gCb, cfg) != ROK) + { + RETVALUE(RFAILED); + } + + cfg = NULLP; + } + + RETVALUE(ROK); +} + + +/** + * @brief Handler to Fetch an UeCb + * + * @details + * This function is invoked by CFG to fetch UeCb from the Ue hashlist + * of KwCb. + * + * @param[in] gCb RLC Instance Control Block + * @param[in] ueId UE Identifier + * @param[in] cellId Cell Identifier + * @param[out] ueCb UE Control Block + * + * @return S16 + * -# ROK + * -# RFAILED +*/ +#ifdef ANSI +PUBLIC S16 kwDbmFetchUlUeCb +( +KwCb *gCb, +CmLteRnti ueId, +CmLteCellId cellId, +KwUlUeCb **ueCb +) +#else +PUBLIC S16 kwDbmFetchUlUeCb(gCb,ueId, cellId, ueCb) +KwCb *gCb; +CmLteRnti ueId; +CmLteCellId cellId; +KwUlUeCb **ueCb; +#endif +{ + TRC3(kwDbmFetchUlUeCb) + + + RETVALUE(cmHashListFind(&(gCb->u.ulCb->ueLstCp), + (U8 *)&(ueId), sizeof(CmLteRnti), + KW_DEF_SEQ_NUM, + (PTR *) ueCb)); +} + + +/** + * @brief Handler to delete an UeCb + * + * @details + * This function is invoked by CFG to delete UeCb from the Ue hashlist + * of KwCb. + * + * + * @param[in] gCb RLC Instance Control Block + * @param[in] ueCb UE Control Block + * @param[in] abrtFlag Abort Flag + * + * @return Void + * +*/ +#ifdef ANSI +PUBLIC Void kwDbmDelUlUeCb +( +KwCb *gCb, +KwUlUeCb *ueCb, +Bool abortFlag +) +#else +PUBLIC Void kwDbmDelUlUeCb(gCb,eCb, abortFlag) +KwCb *gCb; +KwUlUeCb *ueCb; +Bool abortFlag; +#endif +{ + TRC3(kwDbmDelUlUeCb) + + +#if (!defined(KW_PDCP) || !(defined(PJ_SEC_ASYNC) || defined(PJ_CMP_ASYNC))) + UNUSED(abortFlag); +#endif /* (!defined(KW_PDCP) || ! (defined(PJ_SEC_ASYNC) || defined(PJ_CMP_ASYNC)))*/ + + /* Delete all logical channels */ + KW_MEM_ZERO(ueCb->lCh,sizeof(KwUlLch) * KW_MAX_LCH_PER_UE); + + /* Delete all SRB RbCbs in UeCb */ + kwDbmDelAllUlRb(gCb,ueCb->srbCb, KW_MAX_SRB_PER_UE); + + /* Delete all DRB RbCbs in UeCb */ + kwDbmDelAllUlRb(gCb,ueCb->drbCb, KW_MAX_DRB_PER_UE); + + /* Delete ueCb entry from ueLstCp */ + if(ROK != cmHashListDelete(&(gCb->u.ulCb->ueLstCp), (PTR) ueCb)) + { + RLOG_ARG1(L_ERROR,DBG_UEID,ueCb->ueId, + "HashList Deletion Failed cellId(%d)", + ueCb->cellId); + } + /* kw005.201 ccpu00117318, updating the statistics */ + gCb->genSts.numUe--; + /* Deallocate ueCb */ + KW_FREE(gCb,ueCb, sizeof(KwUlUeCb)); + + RETVOID; +} + +/** + * @brief Handler to delete all UeCbs + * + * @details + * This function is invoked by CFG to delete all UeCbs from the Ue + * hashlist of KwCb. + * + * @param[in] gCb RLC Instance Control Block + * + * @return Void +*/ +#ifdef ANSI +PUBLIC Void kwDbmDelAllUlUe +( +KwCb *gCb +) +#else +PUBLIC Void kwDbmDelAllUlUe(gCb) +KwCb *gCb; +#endif +{ + KwUlUeCb *ueCb = NULLP; /* UE Control Block */ + + TRC3(kwDbmDelAllUlUe) + + + /* Until no more ueCb is ueLstCp hash list get and delete ueCb */ + while (ROK == cmHashListGetNext(&(gCb->u.ulCb->ueLstCp), + (PTR) ueCb, + (PTR *)&ueCb)) + { + kwDbmDelUlUeCb(gCb,ueCb, TRUE); + + ueCb = NULLP; + } + + RETVOID; +} + + +/** + * @brief Handler to create CellCb + * + * @details + * This function is invoked by CFG to create CellCb and insert into + * the Cell hashlist of KwCb. + * + * @param[in] gCb RLC Instance Control Block + * @param[in] cellId Cell Identifier + * @param[in] cellCb Cell Control Block + * + * @return S16 + * -# ROK + * -# RFAILED +*/ +#ifdef ANSI +PUBLIC S16 kwDbmAddUlCellCb +( +KwCb *gCb, +CmLteCellId cellId, +KwUlCellCb *cellCb +) +#else +PUBLIC S16 kwDbmAddUlCellCb(gCb, cellId, cellCb) +KwCb *gCb; +CmLteCellId cellId; +KwUlCellCb *cellCb; +#endif +{ + KwUlCellCb *tCellCb; + + TRC3(kwDbmAddUlCellCb) + + + + tCellCb = cellCb; + tCellCb->cellId = cellId; + + if(ROK != cmHashListInsert(&(gCb->u.ulCb->cellLstCp), + (PTR) tCellCb, + (U8 *)&(tCellCb->cellId), + (U16) sizeof(CmLteCellId))) + { + RLOG_ARG0(L_ERROR,DBG_CELLID,tCellCb->cellId, + "HashList Insertion Failed"); + RETVALUE(RFAILED); + } + + RETVALUE(ROK); +} + + +/** + * @brief Handler to Fetch an CellCb + * + * @details + * This function is invoked by CFG to fetch UeCb from the Ue hashlist + * of KwCb. + * + * @param[in] gCb RLC Instance Control Block + * @param[in] cellId Cell Identifier + * @param[out] cellCb UE Control Block + * + * @return S16 + * -# ROK + * -# RFAILED + * +*/ +#ifdef ANSI +PUBLIC Void kwDbmFetchUlCellCb +( +KwCb *gCb, +CmLteCellId cellId, +KwUlCellCb **cellCb +) +#else +PUBLIC Void kwDbmFetchUlCellCb(gCb, cellId, cellCb) +KwCb *gCb; +CmLteCellId cellId; +KwUlCellCb **cellCb; +#endif +{ + TRC3(kwDbmFetchUlCellCb) + + + *cellCb = NULLP; + if(ROK != cmHashListFind(&(gCb->u.ulCb->cellLstCp), + (U8 *)&(cellId),sizeof(CmLteCellId), + KW_DEF_SEQ_NUM, (PTR*) cellCb)) + { + RLOG_ARG0(L_ERROR,DBG_CELLID, cellId,"CellCb not found"); + } + + RETVOID; +} + + +/** + * @brief Handler to delete CellCb + * + * @details + * This function is invoked by CFG to delete CellCb from the Cell hashlist + * of KwCb. + * + * @param[in] gCb RLC Instance Control Block + * @param[in] cellCb Cell Control Block + * + * @return Void +*/ +#ifdef ANSI +PUBLIC Void kwDbmDelUlCellCb +( +KwCb *gCb, +KwUlCellCb *cellCb +) +#else +PUBLIC Void kwDbmDelUlCellCb(gCb, cellCb) +KwCb *gCb; +KwUlCellCb *cellCb; +#endif +{ + TRC3(kwDbmDelUlCellCb) + + + /* Delete all rbCbs in cellCb */ + kwDbmDelAllUlRb(gCb,cellCb->rbCb, KW_MAX_RB_PER_CELL); + + /* Delete cellCb entry in hash list cellLstCp */ + if(ROK != cmHashListDelete(&(gCb->u.ulCb->cellLstCp), (PTR) cellCb)) + { + RLOG_ARG0(L_ERROR,DBG_CELLID,cellCb->cellId, + "HashList Deletion Failed"); + } + /* Deallocate cellCb */ + KW_FREE(gCb, cellCb, sizeof(KwUlCellCb)); + + RETVOID; +} /* kwDbmDelCellCb */ + + +/** + * @brief Handler to delete all UeCbs + * + * @details + * This function is invoked by CFG to delete all UeCbs from the Ue + * hashlist of KwCb. + * @param[in] gCb RLC Instance Control Block + * + * @return Void +*/ +#ifdef ANSI +PUBLIC Void kwDbmDelAllUlCell +( +KwCb *gCb +) +#else +PUBLIC Void kwDbmDelAllUlCell(gCb) +KwCb *gCb; +#endif +{ + KwUlCellCb *cellCb = NULLP; /* Cell Control Block */ + + TRC3(kwDbmDelAllUlCell) + + + /* Until no more cellCb is ueLstCp hash list get and delete cellCb */ + while (ROK == cmHashListGetNext(&(gCb->u.ulCb->cellLstCp), + (PTR) cellCb, + (PTR *)&cellCb)) + { + kwDbmDelUlCellCb(gCb,cellCb); + + cellCb = NULLP; + } + + RETVOID; +} + + +/** + * @brief Handler to delete all UeCbs and CellCbs + * + * @details + * This function is invoked by LMM to delete all UeCbs from the Ue + * hashlist of KwCb and cellCbs from the Cell hashlist of kwCb. + * + * @param[in] gCb RLC Instance Control Block + * +*/ +#ifdef ANSI +PUBLIC Void kwDbmUlShutdown +( +KwCb *gCb +) +#else +PUBLIC Void kwDbmUlShutdown(gCb) +KwCb *gCb; +#endif +{ + TRC3(kwDbmUlShutdown) + + kwDbmDelAllUlCell(gCb); + + kwDbmDelAllUlUe(gCb); + + kwDbmUlDeInit(gCb); + + RETVOID; +} + + +/********************************************************************30** + + End of file +**********************************************************************/ diff --git a/src/5gnrrlc/kw_dl.h b/src/5gnrrlc/kw_dl.h new file mode 100755 index 000000000..cde56a0c7 --- /dev/null +++ b/src/5gnrrlc/kw_dl.h @@ -0,0 +1,176 @@ +/******************************************************************************* +################################################################################ +# Copyright (c) [2017-2019] [Radisys] # +# # +# 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. # +################################################################################ +*******************************************************************************/ + +/********************************************************************20** + + Name: LTE RLC file for downlink and non real time tasks + + Type: C include file + + Desc: This file contains helper macros for RLC downlink + and non real time task + + File: kw_dl.h + +*********************************************************************21*/ +/** @file kw_dl.h +@brief RLC Downlink helper macros +*/ + +#ifndef __KW_DLH__ +#define __KW_DLH__ +#define KW_DL_INST 1 +#define KW_MAX_RNG_DEQ_INDX 8 + +/* Below are the status used within RLC */ +#define KW_SDU_OPAT_NOUPDATE 0 +#define KW_SDU_OPAT_UPD_TX 1 +#define KW_SDU_OPAT_UPD_RETX 2 + +/* Below are the status which needs to be updated to MAC */ +#define KW_RGU_SDU_OPAT_NOUPDATE 0 +#define KW_RGU_SDU_OPAT_UPDATE 1 +#define KW_RGU_SDU_OPAT_BREACH 2 + +/* PDB Values for various QCI bearers : This value is considered + after taking into account a 20ms delay at the network */ +#define KW_PDB_VALUE_FOR_QCI1 80 +#define KW_PDB_VALUE_FOR_QCI2 130 +#define KW_PDB_VALUE_FOR_QCI3 30 +#define KW_PDB_VALUE_FOR_QCI4 280 +#define KW_PDB_VALUE_FOR_QCI5 80 +#define KW_PDB_VALUE_FOR_QCI6 280 +#define KW_PDB_VALUE_FOR_QCI7 80 +#define KW_PDB_VALUE_FOR_QCI8 280 +#define KW_PDB_VALUE_FOR_QCI9 280 + +#define KW_DATA_BITMASK 0x80 /* Data bitmask is used to fill D/C bit for data*/ +/** + * @def KW_MEAS_IS_DL_IP_MEAS_ON_FOR_RB + * + * This macro is used to check if DL IP throughput measurement is ON + * or off for the passed rb + * + * Returns TRUE (non-zero) if measurement is ON else FALSE (zero) + * + * @param[in] _gCb RLC DL Cb + * @param[in] _rbCb RLC downlink control block + * +*/ +#ifdef LTE_L2_MEAS +#define KW_MEAS_IS_DL_ANY_MEAS_ON_FOR_RB(_gCb, _rbCb) \ + ((_rbCb->rlcId.rbType == CM_LTE_DRB) && \ + (_gCb->u.dlCb->kwL2Cb.measOn[_rbCb->qci])) + +#define KW_MEAS_IS_DL_IP_MEAS_ON_FOR_RB(_gCb, _rbCb) \ + ((_rbCb->rlcId.rbType == CM_LTE_DRB) && \ + (_gCb->u.dlCb->kwL2Cb.measOn[_rbCb->qci] & LKW_L2MEAS_DL_IP) && \ + (_rbCb->rbL2Cb.measOn & LKW_L2MEAS_DL_IP)) + +#define KW_MEAS_IS_DL_DELAY_MEAS_ON_FOR_RB(_gCb, _rbCb) \ + ((_rbCb->rlcId.rbType == CM_LTE_DRB) && \ + (_gCb->u.dlCb->kwL2Cb.measOn[_rbCb->qci] & LKW_L2MEAS_DL_DELAY)) + +#define KW_MEAS_IS_DL_UU_LOSS_MEAS_ON_FOR_RB(_gCb, _rbCb) \ + ((_rbCb->rlcId.rbType == CM_LTE_DRB) && \ + (_gCb->u.dlCb->kwL2Cb.measOn[_rbCb->qci] & LKW_L2MEAS_UU_LOSS)) +#define KW_UPD_PDCP_L2_DLDELAY_STS(_kwCb, _kwRbCb, _delay) \ +{ \ + if(((_kwRbCb)->rlcId.rbType == CM_LTE_DRB) && \ + ((_kwCb)->u.dlCb->kwL2Cb.measOn[_kwRbCb->qci] & LKW_L2MEAS_DL_DELAY)) \ + { \ + (_kwRbCb)->rbL2Cb.l2Sts[KW_L2MEAS_DL_DELAY]->dlPjSduDelay.sduDelay += _delay; \ + (_kwRbCb)->rbL2Cb.l2Sts[KW_L2MEAS_DL_DELAY]->dlPjSduDelay.numSdus++; \ + } \ +} + +#define KW_UPD_L2_UU_LOSS_PKTS(_kwCb, _kwRbCb, _val) \ +{ \ + if(((_kwRbCb)->rlcId.rbType == CM_LTE_DRB) && \ + ((_kwCb)->u.dlCb->kwL2Cb.measOn[_kwRbCb->qci] & LKW_L2MEAS_UU_LOSS)) \ + { \ + (_kwRbCb)->rbL2Cb.l2Sts[KW_L2MEAS_UU_LOSS]->uuLoss.dLoss += _val; \ + } \ +} +#define KW_UPD_L2_UU_LOSS_POS_PKTS(_kwCb,_kwRbCb,_val) \ +{ \ + if(((_kwRbCb)->rlcId.rbType == CM_LTE_DRB) && \ + ((_kwCb)->u.dlCb->kwL2Cb.measOn[_kwRbCb->qci] & LKW_L2MEAS_UU_LOSS)) \ + { \ + (_kwRbCb)->rbL2Cb.l2Sts[KW_L2MEAS_UU_LOSS]->uuLoss.posPkts += _val; \ + } \ +} +/* Discard new changes starts */ +#define KW_UPD_L2_DL_DISC_SDU_STS(_kwCb,_kwRbCb) \ +{ \ + if(((_kwRbCb)->rlcId.rbType == CM_LTE_DRB) && \ + ((_kwCb)->u.dlCb->kwL2Cb.measOn[_kwRbCb->qci] & LKW_L2MEAS_DL_DISC)) \ + { \ + (_kwRbCb)->rbL2Cb.l2Sts[KW_L2MEAS_DL_DISC]->dlDisc.discSdus++; \ + } \ +} + +#define KW_UPD_L2_DL_TOT_SDU_STS(_kwCb,_kwRbCb) \ +{ \ + if(((_kwRbCb)->rlcId.rbType == CM_LTE_DRB) && \ + ((_kwCb)->u.dlCb->kwL2Cb.measOn[_kwRbCb->qci] & LKW_L2MEAS_DL_DISC)) \ + { \ + (_kwRbCb)->rbL2Cb.l2Sts[KW_L2MEAS_DL_DISC]->dlDisc.totSdus++; \ + } \ +} + +#define KW_UPD_L2_DECR_NONIP_PER_QCI_RB_COUNT(_kwCb, _kwRbCb) \ +{ \ + if(((_kwRbCb)->rlcId.rbType == CM_LTE_DRB) && \ + ((_kwCb)->u.dlCb->kwL2Cb.measOn[_kwRbCb->qci] & LKW_L2MEAS_DL_DISC)) \ + { \ + U32 idx1; \ + for (idx1 = 0; idx1 < LKW_MAX_L2MEAS; idx1++) \ + { \ + if(_kwCb->u.dlCb->kwL2Cb.kwL2EvtCb[idx1].measCb.measType & LKW_L2MEAS_DL_DISC) \ + { \ + if(_kwCb->u.dlCb->kwL2Cb.kwL2EvtCb[idx1].measCb.val.nonIpThMeas.measData[(_kwRbCb)->qci].totDrbsPerQci > 0) \ + { \ + _kwCb->u.dlCb->kwL2Cb.kwL2EvtCb[idx1].measCb.val.nonIpThMeas.measData[(_kwRbCb)->qci].totDrbsPerQci--; \ + if (_kwCb->u.dlCb->kwL2Cb.kwL2EvtCb[idx1].measCb.val.nonIpThMeas.measData[(_kwRbCb)->qci].totDrbsPerQci == 0) \ + { \ + _kwCb->u.dlCb->kwL2Cb.kwL2EvtCb[idx1].measCb.val.nonIpThMeas.qci[(_kwRbCb)->qci] = 0; \ + cmMemset((U8 *)&_kwCb->u.dlCb->kwL2Cb.kwL2EvtCb[idx1].measCb.val.nonIpThMeas.measData[(_kwRbCb)->qci], 0, \ + sizeof(_kwCb->u.dlCb->kwL2Cb.kwL2EvtCb[idx1].measCb.val.nonIpThMeas.measData[(_kwRbCb)->qci])); \ + } \ + } \ + } \ + } \ + } \ +} +#else +#define KW_UPD_PDCP_L2_DLDELAY_STS(_kwCb, _kwRbCb, _delay) +#define KW_MEAS_IS_DL_IP_MEAS_ON_FOR_RB(_gCb, _rbCb) +#define KW_MEAS_IS_DL_DELAY_MEAS_ON_FOR_RB(_gCb, _rbCb) +#define KW_UPD_L2_DL_DISC_SDU_STS(_kwCb,_kwRbCb) +#define KW_UPD_L2_DL_TOT_SDU_STS(_kwCb, _kwRbCb) +#define KW_UPD_L2_DECR_NONIP_PER_QCI_RB_COUNT(_kwCb, _kwRbCb) +#endif + + +#endif /* __KW_DLH__ */ + +/********************************************************************30** + + End of file +**********************************************************************/ diff --git a/src/5gnrrlc/kw_dl.x b/src/5gnrrlc/kw_dl.x new file mode 100755 index 000000000..3ecec5cfa --- /dev/null +++ b/src/5gnrrlc/kw_dl.x @@ -0,0 +1,856 @@ +/******************************************************************************* +################################################################################ +# Copyright (c) [2017-2019] [Radisys] # +# # +# 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. # +################################################################################ +*******************************************************************************/ + +/********************************************************************20** + + Name: LTE RLC file + + Type: C include file + + Desc: This file contains all the data structures and + prototypes for LTE RLC. + + File: kw_dl.x + +*********************************************************************21*/ +/** + * @file kw_dl.x + * @brief RLC downlink structures, prototypes +*/ + +#ifndef __KW_DLX__ +#define __KW_DLX__ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ +#ifdef TENB_STATS +#ifndef L2_l3_SPLIT +#include "pj_tenb_stats.x" +#else +#include "l2_tenb_stats.x" +#endif +#endif +typedef struct kwDlUeCb KwDlUeCb; + +/** + * @brief Structure to hold the SN of the PDU onto which a SDU is mapped + * + * @details + * - sn : Sequence number of the AM pdu +*/ +typedef struct kwPduMap +{ + KwSn sn; /*!< Mapped PDU's SN */ +}KwPduMap; + +/** + * @brief Structure to hold information regarding a SDU received from PDCP + * + * @details + * - lstEnt : Used for linking ( we have linked list of SDUs) which forms + * the SDU queue + * - mBuf : Pointer to the SDU data + * - sduSz : Size of the mBuf above + * - actSz : Length of the SDU when received from PDCP, this might be + * different from sduSz, in case when the SDU is split + * - mode : Depending on the type, holds AM, UM or TM mode information + * - tm + * - sfn : System Frame number for BCCH/PCCH + * - subframe : Subframe number + * - rnti : RNTI for CCCH + * - um + * - sduId : Unique identity for the SDU + * - isSegmented : Whether this SDU is segmented into multiple PDUs + * - am + * - sduId : Unique identity for the SDU + * - rcvdSz : Length of this SDU which is received by the peer + * - isSegmented : Whether this SDU is segmented into multiple PDUs +*/ +typedef struct kwSdu +{ + CmLList lstEnt; /*!< List entry for SDU */ + Buffer *mBuf; /*!< SDU buffer */ + MsgLen sduSz; /*!< Buffer Size */ + MsgLen actSz; /*!< Actual buffer Size */ +/* kw005.201 added support for L2 Measurement */ +#ifdef LTE_L2_MEAS + KwSduSnMap *snMap; /*!< Sdu and the list of SN it maps to */ +#endif /* LTE_L2_MEAS */ + + union + { + struct _t + { + U16 sfn; /*!< Sub frame number for BCCH/PCCH */ + U8 subframe; /*!< Subframe number */ + CmLteRnti rnti; /*!< RNTI for CCCH */ +#ifdef EMTC_ENABLE + U8 emtcDiReason; /*!< DI reason */ + U8 pnb; /*!*/ +#endif + + /* Discard new changes starts */ + S16 discTmrInt; /*!< The discard time in milli + seconds for an PDCP SDU for this RB */ + /* Discard new changes ends */ + CmLteRlcId rlcId; /*!< RLC Identifier */ + KwLchInfo lch; /*!< Logical Channel Info */ + CmLteRlcMode mode; /*!< Entity Mode */ + U8 dir; /*!< Direction for UL/DL */ + Inst inst; /*!< Tapa Instance where rb created */ + SpId kwuSapId; /*!< KWU sap Id, to get the KwuSapCb */ + SpId udxSapId; /*!< UDX sap Id, to get the UdxSapCb */ + U32 transId; /*!< Transaction Id for RLC */ + Bool reestInProgress; /*!< Is reestablishment in progress */ + SpId rguSapId; /*!< RGU Instance SAP corresponding to this RB */ + union + { + KwTm tm; /*!< TM mode specific elements */ + KwUmDl umDl; /*!< UM downlink elements */ + KwAmDl amDl; /*!< AM downlink elements */ + }m; /*!< RLC mode specific Info */ + CmLList rlsLnk; /*!< Link to add to release list */ + Bool cleanupStarted; /*!< Whether cleanup of RB is in progress or not */ + U32 lastRprtdBoToMac; /*!< Last Reported BO to MAC Layer */ + U32 boUnRprtdCnt; /*!< Count to keep track of periodic BO Update */ +}KwDlRbCb; + +/** + * @brief Structure to hold mapping between logical channel and Radio Bearer + * + * @details + * - dlRbCb : Pointer to the downlink Radio Bearer +*/ +typedef struct kwDlLch +{ + KwDlRbCb *dlRbCb; /*!< Pointer to Downlink RbCb */ +}KwDlLch; + +/** + * @brief Structure to hold information about the Cells + * + * @details + * - cellHlEnt : Information about cells are stored in a hash table. This is + * required for that. + * - cellId : Identity of the cell + * - rbCb : Radio Bearers in the cell + * - lCh : Logical Channels in the cell +*/ +typedef struct kwDlCellCb +{ + CmHashListEnt cellHlEnt; /*!< Hash list entry for CellCb */ + CmLteCellId cellId; /*!< Cell Id */ + KwDlRbCb *rbCb[KW_MAX_RB_PER_CELL]; /*!< RbCbs within a Cell */ + KwDlLch lCh[KW_MAX_LCH_PER_CELL]; /*!< Array of Logical channels */ +}KwDlCellCb; + +#ifdef LTE_L2_MEAS +/** @struct KwContSduLst + * Structure contains list of rbId and index to KwOutStngSduLst + */ +typedef struct kwContSduLst +{ + CmLteLcId lcId; /*!< Holds the lcId of rbCb */ + U8 numSdus; /*!< Number sdus in sduIdx array */ + U8 sduIdx[KW_L2MEAS_MAX_OUTSTNGSDU]; /*!< Hold the index to KwOutStngSduLst */ +}KwContSduLst; +typedef struct kwSduInfo +{ + Bool isRetxPdu; + Ticks arvlTime; /* stores the the arrival time of each PDCP PDU */ +}KwSduInfo; + +typedef struct kwlchInfo +{ + CmLteLcId lcId; /*!< Holds the lcId of rbCb */ + U8 numSdus; /*!< Number sdus belonged to the this LC */ + KwSduInfo sduInfo[KW_L2MEAS_SDUIDX]; +}KwlchInfo; + +/** @struct KwL2MeasTb + * Structure containes list of rbId and index to KwOutStngSduLst + */ +typedef struct kwL2MeasTb +{ + U8 numLcId; /* number of logical channels in this TbCb */ + KwContSduLst sduInfo[KW_MAX_ACTV_DRB]; /*!< Contained sduLst for + outstanding sdu */ + U8 numLchInfo; + KwlchInfo lchInfo[KW_MAX_ACTV_DRB]; /* Holds the LC info details + used for DL delay L2 Meas*/ + U32 txSegSduCnt; /*!< This holds the no.of partially + transmitted SDU per TB which can be used for UU loss Meas*/ +}KwL2MeasTb; +#endif + +/** + * @brief Structure to hold information about the UEs + * + * @details + * - ueHlEnt : Information about cells are stored in a hash table. This is + * required for that. + * - key : Key to store/find the UE in the hashtable + * - srbCb : Signaling Radio Bearers configured for the UE + * - drbCb : Data Radio Bearers configured for the UE + * - lCh : Logical Channels in the UE +*/ +struct kwDlUeCb +{ + CmHashListEnt ueHlEnt; /*!< Hash list entry for UeCb */ + CmLteRnti ueId; /*!< UE Id */ + CmLteCellId cellId; /*!< Cell Id */ + KwDlRbCb *srbCb[KW_MAX_SRB_PER_UE]; /*!< SRB RbCbs within a UE */ + KwDlRbCb *drbCb[KW_MAX_DRB_PER_UE]; /*!< DRB RbCbs within a UE */ + KwDlLch lCh[KW_MAX_LCH_PER_UE]; /*!< Array of Logical channels */ +/* kw005.201 added support for L2 Measurement */ +#ifdef LTE_L2_MEAS + U16 numActRb[LKW_MAX_QCI]; /*!< number of RBs Active */ + U8 tbIdx; /*!< TBIDx for measTbCb */ + KwL2MeasTb *l2MeasTbCb[KW_MAX_TB_PER_UE]; /*!< Array of Measurement tbCb */ +#endif /* LTE_L2_MEAS */ +#ifdef TENB_STATS + TSL2UeStatsCb *tenbStats; /*!< UE Stats Holder */ +#endif +}; + +/**************************************************************************** + * EXTERN Declarations + ***************************************************************************/ +/**************************************************************************** + * Configuration Functions + ***************************************************************************/ +EXTERN S16 kwCfgAddDlRb ARGS ((KwCb *gCb, + CmLteRnti ueId, + CmLteCellId cellId, + CkwEntCfgInfo *entCfg, + CkwEntCfgCfmInfo *entCfm)); + +EXTERN S16 kwCfgReCfgDlRb ARGS ((KwCb *gCb, + CmLteRnti ueId, + CmLteCellId cellId, + CkwEntCfgInfo *entCfg, + CkwEntCfgCfmInfo *entCfm)); + +EXTERN S16 kwCfgDelDlRb ARGS ((KwCb *gCb, + CmLteRnti ueId, + CmLteCellId cellId, + CkwEntCfgInfo *entCfg, + CkwEntCfgCfmInfo *entCfm)); + +EXTERN S16 kwCfgDelDlUe ARGS ((KwCb *gCb, + CmLteRnti ueId, + CmLteCellId cellId, + CkwEntCfgInfo *entCfg, + CkwEntCfgCfmInfo *entCfm)); + +EXTERN S16 kwCfgReEstDlRb ARGS ((KwCb *gCb, + CmLteRnti ueId, + CmLteCellId cellId, + Bool sndReEst, + CkwEntCfgInfo *entCfg, + CkwEntCfgCfmInfo *entCfm)); + +EXTERN S16 kwCfgDelDlCell ARGS ((KwCb *gCb, + CmLteCellId cellId, + CkwEntCfgInfo *entCfg, + CkwEntCfgCfmInfo *entCfm)); + +EXTERN S16 kwCfgDlUeIdChng ARGS ((KwCb *gCb, + CkwUeInfo *ueInfo, + CkwUeInfo *newUeInfo, + CmStatus *status)); + +/**************************************************************************** + * DBM module Functions + ***************************************************************************/ +EXTERN S16 kwDbmDlInit ARGS ((KwCb *gCb)); + +EXTERN Void kwDbmDlDeInit ARGS ((KwCb *gCb)); + +EXTERN S16 kwDbmCreateDlUeCb ARGS ((KwCb *gCb, + CmLteRnti ueId, + CmLteCellId cellId, + KwDlUeCb **ueCb)); + +EXTERN S16 kwDbmFetchDlUeCb ARGS ((KwCb *gCb, + CmLteRnti ueId, + CmLteCellId cellId, + KwDlUeCb **ueCb)); + +EXTERN Void kwDbmDelDlUeCb ARGS ((KwCb *gCb, + KwDlUeCb *ueCb, + Bool abortFlag)); + +EXTERN Void kwDbmDelAllDlUe ARGS ((KwCb *gCb)); + +EXTERN S16 kwDbmCreateDlCellCb ARGS ((KwCb *gCb, + CmLteCellId cellId, + KwDlCellCb **cellCb)); + +EXTERN S16 kwDbmFetchDlCellCb ARGS ((KwCb *gCb, + CmLteCellId cellId, + KwDlCellCb **cellCb)); + +EXTERN Void kwDbmDelDlCellCb ARGS ((KwCb *gCb, KwDlCellCb *cellCb)); + +EXTERN Void kwDbmDelAllDlCell ARGS ((KwCb *gCb)); + +EXTERN Void kwDbmFetchDlRbCbByRbId ARGS ((KwCb *gCb, + CmLteRlcId *rlcId, + KwDlRbCb **rbCb)); + +EXTERN Void kwDbmFetchDlRbCbFromLchId ARGS ((KwCb *gCb, + CmLteRnti ueId, + CmLteCellId cellId, + CmLteLcId lcId, + KwDlRbCb **rbCb)); + +EXTERN Void kwDbmDelAllDlRb ARGS ((KwCb *gCb, KwDlRbCb **rbCbLst, U8 numRbCb)); + +EXTERN S16 kwDbmDlShutdown ARGS ((KwCb *gCb)); + +EXTERN Void kwUtlGetCurrTime ARGS((U32 *time)); +EXTERN PUBLIC Void kwUtlTrigPdbFlowCntrl ARGS((KwCb *gCb, KwDlRbCb *rbCb, U32 pktAdmitCnt )); +#ifdef LTE_L2_MEAS +EXTERN Void kwDbmDelAllDlL2MeasTbFrmUe ARGS ((KwCb *gCb, KwDlUeCb *ueCb)); + +#endif + +/**************************************************************************** + * Transparent Mode Functions + ***************************************************************************/ +EXTERN Void kwTmmQSdu ARGS ((KwCb *gCb, + KwDlRbCb *rbCb, + KwuDatReqInfo *datReqInfo, + Buffer *mBuf)); +EXTERN Void kwTmmSndToLi ARGS ((KwCb *gCb, + SuId suId, + KwDlRbCb *rbCb, + RguCStaIndInfo *staInd)); + +EXTERN Void kwDlTmmReEstablish ARGS ((KwCb *gCb, KwDlRbCb *rbCb)); + +/**************************************************************************** + * Unacknowledged Mode Functions + ***************************************************************************/ +EXTERN Void kwUmmQSdu ARGS ((KwCb *gCb, + KwDlRbCb *rbCb, + KwuDatReqInfo *datReq, + Buffer *mBuf)); + +EXTERN Void kwUmmDiscSdu ARGS ((KwCb *gCb, KwDlRbCb *rbCb, U32 sduId)); + +EXTERN Void kwDlUmmReEstablish ARGS ((KwCb *gCb, + CmLteRlcId rlcId, + Bool sndReEst, + KwDlRbCb *rbCb)); + +EXTERN Void kwUmmProcessSdus ARGS ((KwCb *gCb,KwDlRbCb *rbCb,KwDatReq *datReq)); + +EXTERN Void kwUmmFreeDlRbCb ARGS ((KwCb *gCb, KwDlRbCb *rbCb)); + +/**************************************************************************** + * Acknowledged Mode Functions + ***************************************************************************/ + +EXTERN S32 kwAmmCalculateBo ARGS ((KwAmDl *amDl)); + +EXTERN Void kwAmmSendDStaRsp ARGS ((KwCb *gCb, KwDlRbCb *rbCb, KwAmDl *amDl)); + +EXTERN Void kwAmmQSdu ARGS((KwCb *gCb, + KwDlRbCb *rbCb, + Buffer *mBuf, + KwuDatReqInfo *datReq)); + +EXTERN Void kwAmmProcessSdus ARGS((KwCb *gCb, + KwDlRbCb *rbCb, + KwDatReq *kwDatReq, + Bool staPduPres)); + +EXTERN Void kwAmmDlReEstablish ARGS((KwCb *gCb, + CmLteRlcId rlcId, + KwDlRbCb *rbCb)); + +EXTERN Void kwAmmDlHndlStatusPdu ARGS ((KwCb *gCb, + KwDlRbCb *rbCb, + KwUdxStaPdu *pStaPdu)); + +EXTERN S16 kwAmmDiscSdu ARGS((KwCb *gCb, KwDlRbCb *rbCb, U32 sduId)); + +EXTERN Void kwAmmPollRetxTmrExp ARGS((KwCb *gCB, KwDlRbCb *rbCb)); + +EXTERN Void kwAmmFreeDlRbCb ARGS ((KwCb *gCb, KwDlRbCb *rbCb)); + +/**************************************************************************** + * Utility Functions + ***************************************************************************/ + +EXTERN Void kwUtlStoreTxBuf ARGS ((CmLListCp *txBufLst, + KwTx *txBuf, + KwSn sn + )); +EXTERN KwTx* kwUtlGetTxBuf ARGS ((CmLListCp *txBufLst, + KwSn sn + )); +EXTERN Void kwUtlDelTxBuf ARGS ((CmLListCp *txBufLst, + KwTx *txBuf, + KwCb *gCb + )); +EXTERN Void kwUtlRemovTxBuf ARGS ((CmLListCp *txBufLst, + KwTx *txBuf, + KwCb *gCb + )); + +EXTERN S16 kwUtlSndDStaRsp ARGS ((KwCb *gCb, + KwDlRbCb *rbCb, + S32 bo, + S32 estHdrSz, + Bool staPduPrsnt, + U32 staPduBo)); + +#ifdef LTE_L2_MEAS_RLC +EXTERN Void kwUtlEmptySduQ ARGS ((KwCb *gCb, KwDlRbCb *rbCb, CmLListCp *sduQ)); +#else /* LTE_L2_MEAS */ +EXTERN Void kwUtlEmptySduQ ARGS ((KwCb *gCb,CmLListCp *sduQ)); +#endif /* LTE_L2_MEAS */ + +EXTERN Void kwUtlCalcLiForSdu ARGS ((KwCb *gCb, + U16 numLi, + MsgLen msgLen, + S16 *pduSz)); + +EXTERN S16 kwUtlSndToLi ARGS ((KwCb *gCb, SuId suId, KwDStaIndInfo *staIndInfo)); + +EXTERN Void kwUtlIncrementKwuStsSduTx ARGS((KwKwuSapCb *kwuSap)); + +EXTERN Void kwUtlIncrementGenStsBytesAndPdusSent ARGS((KwGenSts *genSts, + Buffer *pdu)); + +EXTERN Void kwUtlFreeDlMemory ARGS ((KwCb *gCb)); + +EXTERN Void kwUtlInitToBeFreed ARGS ((KwCb *gCb, KwDlDataToBeFreed *toBeFreed)); + +EXTERN Void kwUtlInitializeSelfPst ARGS((KwCb *gCb)); + +EXTERN Void kwUtlRaiseDlCleanupEvent ARGS((KwCb *gCb)); + +EXTERN Void kwUtlAddSduToBeFreedQueue ARGS((KwCb *gCb, KwSdu *sdu)); + +EXTERN Void kwUtlAddReTxPduToBeFreedQueue ARGS((KwCb *gCb, KwRetx *retx)); + +EXTERN Void kwUtlAddTxPduToBeFreedQueue ARGS((KwCb *gCb, KwTx *pdu)); + +#ifdef LTE_L2_MEAS +EXTERN S16 kwUtlL2MeasDlInit ARGS((KwCb *gCb)); +#endif + +/**************************************************************************** + * Debug Functions + ***************************************************************************/ +EXTERN Void ResetRLCStats ARGS((Void)); + +EXTERN Void PrintRLCStats ARGS((Void)); + +EXTERN Void DumpRLCDlDebugInformation ARGS((Void)); + +/**************************************************************************** + * Activation Functions + ***************************************************************************/ +EXTERN S16 kwDlActvInit ARGS ((Ent ent,Inst inst,Region region,Reason reason)); + +EXTERN S16 kwDlActvTsk ARGS ((Pst *pst, Buffer *mBuf)); + +EXTERN Bool kwDlUtlIsReestInProgress ARGS ((KwDlRbCb *rbCb)); + +EXTERN Void kwDlUtlResetReestInProgress ARGS ((KwDlRbCb *rbCb)); + +EXTERN Void kwDlUtlResetReestInProgress ARGS (( KwDlRbCb *rbCb)); + +EXTERN Void kwDlUtlSetReestInProgressForAllRBs ARGS ((KwCb *gCb, KwDlUeCb + *ueCb)); +EXTERN Void kwDlUtlSetReestInProgressForRB ARGS (( KwCb *gCb, KwDlRbCb *rbCb)); + +#ifdef LTE_L2_MEAS +EXTERN Void kwUtlUpdateContainedSduLst ARGS (( +U8 sduIdx, +KwContSduLst *contSduLst +)); +EXTERN Void kwUtlUpdateOutStandingSduLst ARGS (( +KwL2MeasDlIpTh *dlIpThPut, +U8 sduIdx, +MsgLen sduLen, +U32 sduId, +Bool newIdx +)); +EXTERN Void kwUtlUpdateBurstSdus ARGS(( +KwCb *gCb, +KwDlRbCb *rbCb, +KwContSduLst *contSduLst, +S32 dataVol, +U32 schPduSz +)); + +EXTERN KwL2MeasTb * kwUtlGetCurMeasTb ARGS(( +KwCb *gCb, +KwDlRbCb *rbCb +)); + +EXTERN S16 kwUtlSndDlL2MeasNCfm ARGS((KwCb *gCb, + KwL2MeasReqEvt *measReqEvt, + KwL2MeasCfmEvt *measCfmEvt)); + +EXTERN S16 kwUtlSndDlL2MeasCfm ARGS ((KwCb *gCb, KwL2MeasEvtCb *measEvtCb)); + +EXTERN S16 kwUtlProcHarqInd ARGS (( KwCb *gCb, RguHarqStatusInd *staInd, KwDlUeCb *ueCb, + U8 tbIdx)); +EXTERN Void kwUtlResetDlL2MeasInKwRb ARGS ((KwCb *gCb, + KwL2MeasCb *measCb, + U8 measType)); + +EXTERN S16 KwMiLkwL2MeasStopCfm ARGS((Pst *pst, U8 measType,U8 status)); + +EXTERN S16 kwUtlValidateIpThL2Meas ARGS((KwL2MeasReqEvt *measReqEvt, + KwL2MeasCfmEvt *measCfmEvt)); + +EXTERN S16 kwFetchLchInfo ARGS ((KwL2MeasReqEvt *measReqEvt, + KwL2MeasCfmEvt *measCfmEvt, + U16 ueId, + CmLteLcId *lChId, + U8 *numLch)); + +EXTERN S16 kwUtlNotifyMacUlIp ARGS ((KwL2MeasCb *measCb,U16 ueIdx, Bool enable, + CmLteLcId *lChId, U8 *numLCh)); +#endif +EXTERN Void kwUtlFreeDlMem ARGS(( Void)); +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __KW_DLX__ */ + + +/********************************************************************30** + + End of file +**********************************************************************/ diff --git a/src/5gnrrlc/kw_dl_ex_ms.c b/src/5gnrrlc/kw_dl_ex_ms.c new file mode 100755 index 000000000..2cbfe0884 --- /dev/null +++ b/src/5gnrrlc/kw_dl_ex_ms.c @@ -0,0 +1,624 @@ +/******************************************************************************* +################################################################################ +# Copyright (c) [2017-2019] [Radisys] # +# # +# 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. # +################################################################################ +*******************************************************************************/ + +/********************************************************************20** + + Name: LTE-RLC Layer - System Services Interface Functions + + Type: C file + + Desc: C source code for the interface to System Services + of LTE-RLC + + File: kw_dl_ex_ms.c + +*********************************************************************21*/ +static const char* RLOG_MODULE_NAME="RLC_DL"; +static int RLOG_MODULE_ID=2048; +static int RLOG_FILE_ID=195; + +/** @filekw_dl_ex_ms.c +@brief RLC System Services Interface +*/ + + +/* header (.h) include files */ +#include "envopt.h" /* environment options */ +#include "envdep.h" /* environment dependent */ +#include "envind.h" /* environment independent */ + +#include "gen.h" /* general */ +#include "ssi.h" /* system services */ +#include "cm5.h" /* common timer defines */ +#include "cm_tkns.h" /* common tokens defines */ +#include "cm_mblk.h" /* common memory allocation library defines */ +#include "cm_llist.h" /* common link list defines */ +#include "cm_hash.h" /* common hash list defines */ +#include "cm_lte.h" /* common LTE defines */ +#include "lkw.h" /* LKW defines */ +#include "ckw.h" /* CKW defines */ +#include "kwu.h" /* KWU defines */ +#include "rgu.h" /* RGU defines */ +#include "kw_err.h" /* Err defines */ +#include "kw_env.h" /* RLC environment options */ +#include "kw.h" /* RLC defines */ +#include "kw_udx.h" +#include "kw_dl.h" + + +/* extern (.x) include files */ +#include "gen.x" /* general */ +#include "ssi.x" /* system services */ + +#include "cm5.x" /* common timer library */ +#include "cm_tkns.x" /* common tokens */ +#include "cm_mblk.x" /* common memory allocation */ +#include "cm_llist.x" /* common link list */ +#include "cm_hash.x" /* common hash list */ +#include "cm_lte.x" /* common LTE includes */ +#include "cm_lib.x" /* common memory allocation library */ +#include "lkw.x" /* LKW */ +#include "ckw.x" /* CKW */ +#include "kwu.x" /* KWU */ +#include "rgu.x" /* RGU */ +#include "kw.x" +#include "kw_udx.x" +#include "kw_dl.x" + +#include "ctf.h" +PUBLIC S16 kwUtlDlBatchProcPkts(Void); +PUBLIC S16 kwDlBatchProc(Void); +#if (defined(MAC_RLC_HARQ_STA_RBUF) && defined(LTE_L2_MEAS)) +U32 isDatReqProcessed; +PUBLIC void kwUtlDlBatchProcHqStaInd ARGS ((Void)); +#endif + +#if (defined(L2_L3_SPLIT) && defined(ICC_RECV_TSK_RBUF)) +EXTERN S16 kwDlBatchProcSplit ARGS((Void)); +#endif +//UDAY +#ifdef L2_OPTMZ +U32 kwAmmStaPduList[512] = {0}; +EXTERN S16 ssGetDBufOfSize ARGS((Region region, Size size, Buffer **dBuf)); +#endif +PUBLIC S16 kwDlInitExt ARGS (( Void )); + +/** + * + * @brief + * + * Initialize External + * + * @b Description: + * Initializes variables used to interface with Upper/Lower Layer + * + * @return S16 + * -# ROK + * +*/ + +#ifdef ANSI +PUBLIC S16 kwDlInitExt +( +) +#else +PUBLIC S16 kwDlInitExt() +#endif +{ + TRC2(kwDlInitExt); + + RETVALUE(ROK); +} /* kwInitExt */ + + + +/*********************************************************************** + System Service Interface Functions + ***********************************************************************/ +/** + * + * @brief + * + * Activates Initialization + * + * @b Description: + * This function is invoked by system services to initialize the LTE-RLC + * layer. This is an entry point used by LTE_RLC layer to initialize its + * global variables, before becoming operational. + * + * Allowable values for parameters are specified in ssi.h. + * + * @param[in] ent - Specify the entity id of the LTE-RLC task. + * @param[in] inst - Specify the entity id of the LTE-RLC task. + * @param[in] region - Specifies the memory region from which + * LTE-RLC should allocate structures and buffers. + * @param[in] reason - Specifies the reason for calling this + * initialization function. + * + * @return S16 + * -# ROK + * + */ +#ifdef ANSI +PUBLIC S16 kwDlActvInit +( +Ent ent, /* entity */ +Inst inst, /* instance */ +Region region, /* region */ +Reason reason /* reason */ +) +#else +PUBLIC S16 kwDlActvInit(ent, inst, region, reason) +Ent ent; /* entity */ +Inst inst; /* instance */ +Region region; /* region */ +Reason reason; /* reason */ +#endif +{ + KwCb *tKwCb; + TRC3(kwDlActvInit) + + if (inst >= KW_MAX_RLC_INSTANCES) + { + /* intance greater than MAX instances */ + RETVALUE(RFAILED); + } + + if (kwCb[inst] != NULLP) + { + RETVALUE (RFAILED); + } + + if (SGetSBuf(region, 0, (Data **)&tKwCb, + (Size)sizeof (KwCb)) != ROK) + { + RETVALUE(RFAILED); + } + /* Initialize kwCb */ + KW_MEM_SET(tKwCb, 0, sizeof(KwCb)); + + /* Initialize task configuration parameters */ + tKwCb->init.ent = ent; /* entity */ + tKwCb->init.inst = inst; /* instance */ + tKwCb->init.region = region; /* static region */ + tKwCb->init.pool = 0; /* static pool */ + tKwCb->init.reason = reason; /* reason */ + tKwCb->init.cfgDone = FALSE; /* configuration done */ + tKwCb->init.acnt = TRUE; /* enable accounting */ + tKwCb->init.usta = TRUE; /* enable unsolicited status */ + tKwCb->init.trc = FALSE; /* enable trace */ + tKwCb->init.procId = SFndProcId(); + + kwCb[inst] = tKwCb; + +//UDAY +#ifdef L2_OPTMZ + for(int i = 0; i < 512; i++) + { + Buffer *mBuf = NULL; + Buffer *bufPtr = NULL; + SGetMsg(1, 0 , &mBuf); + ssGetDBufOfSize(1 , 1800, &bufPtr); + SUpdMsg(mBuf, bufPtr, 0); + kwAmmStaPduList[i] = (U32)mBuf; + } +#endif + /* call external function for intialization */ + /* + kwInitExt(); + */ + + + + RETVALUE(ROK); +} /* kwActvInit */ + + +/** + * + * @brief + * + * Activation Task + * + * @b Description: + * Processes events received for MLTE-RLC layer via System Services from + * other layers. + * + * @param[in] pst - Pst Structure + * @param[in] mBuf - Message Buffer + * + * @return S16 + * -# ROK + * + */ +#if (defined (MAC_FREE_RING_BUF) || defined (RLC_FREE_RING_BUF)) +pthread_t gRlcTId = 0; +#endif +#ifdef ANSI +PUBLIC S16 kwDlActvTsk +( +Pst *pst, /* pst structure */ +Buffer *mBuf /* message buffer */ +) +#else +PUBLIC S16 kwDlActvTsk(pst, mBuf) +Pst *pst; /* pst structure */ +Buffer *mBuf; /* message buffer */ +#endif +{ + S16 ret = ROK; + + TRC3(kwDlActvTsk); +#ifdef RLC_FREE_RING_BUF + gRlcTId = pthread_self(); +#endif + + switch(pst->srcEnt) + { + case ENTSM: + { + switch(pst->event) + { +#ifdef LCLKW + case LKW_EVT_CFG_REQ: + { + ret = cmUnpkLkwCfgReq(KwMiLkwCfgReq, pst, mBuf); + break; + } + + case LKW_EVT_CNTRL_REQ: + { + ret = cmUnpkLkwCntrlReq(KwMiLkwCntrlReq, pst, mBuf); + break; + } + + case LKW_EVT_STS_REQ: + { + ret = cmUnpkLkwStsReq(KwMiLkwStsReq, pst, mBuf); + break; + } + + case LKW_EVT_STA_REQ: + { + ret = cmUnpkLkwStaReq(KwMiLkwStaReq, pst, mBuf); + break; + } + /* kw005.201 added support for L2 Measurement */ +#endif /* LCLKW */ + default: + SPutMsg(mBuf); + if (pst->dstInst < KW_MAX_RLC_INSTANCES) + { + RLOG1(L_ERROR,"Received Invalid Event[%d] from SM", + pst->event); + } + ret = RFAILED; + break; + + } + break; + } + + case ENTKW: + { + + switch(pst->event) + { +#ifdef LCUDX + case UDX_EVT_BND_REQ: /* Bind request */ + { + ret = cmUnpkUdxBndReq(KwDlUdxBndReq, pst, mBuf ); + break; + } + + case UDX_EVT_UBND_REQ: /* Bind request */ + { + ret = cmUnpkUdxUbndReq(KwDlUdxUbndReq, pst, mBuf ); + break; + } + case UDX_EVT_CFG_REQ: /* Unbind request */ + { + ret = cmUnpkUdxCfgReq(KwDlUdxCfgReq, pst, mBuf ); + break; + } + + case UDX_EVT_UEIDCHG_REQ: /* Configuration request */ + { + ret = cmUnpkUdxUeIdChgReq(KwDlUdxUeIdChgReq, pst, mBuf); + break; + } + + case UDX_EVT_STA_UPD_REQ: /* Configuration request */ + { + ret = cmUnpkUdxStaUpdReq(KwDlUdxStaUpdReq, pst, mBuf); + break; + } + + case UDX_EVT_STA_PDU_REQ: /* Configuration request */ + { + ret = cmUnpkUdxStaPduReq(KwDlUdxStaPduReq, pst, mBuf); + break; + } + +#ifdef LTE_L2_MEAS + case UDX_EVT_L2MEAS_REQ: + { + ret = cmUnpkUdxL2MeasReq(KwDlUdxL2MeasReq, pst, mBuf); + break; + } + case UDX_EVT_L2MEAS_SEND_REQ: + { + + ret = cmUnpkUdxL2MeasSendReq(KwDlUdxL2MeasSendReq, pst, mBuf); + + break; + } + case UDX_EVT_L2MEAS_STOP_REQ: + { + ret = cmUnpkUdxL2MeasStopReq(KwDlUdxL2MeasStopReq, pst, mBuf); + break; + } +#endif + +#endif /* LCCKW */ + case UDX_EVT_DL_CLEANUP_MEM: + { + kwUtlFreeDlMemory(KW_GET_KWCB(pst->dstInst)); + break; + } + + default: + SPutMsg(mBuf); + if (pst->dstInst < KW_MAX_RLC_INSTANCES) + { + RLOG1(L_ERROR,"Received Invalid Event[%d] from RLC UL", + pst->event); + } + ret = RFAILED; + break; + + } + break; + } + + case ENTNH: + { + switch(pst->event) + { +#ifdef LCKWU + case KWU_EVT_BND_REQ: /* Bind request */ + { + ret = cmUnpkKwuBndReq(KwUiKwuBndReq, pst, mBuf ); + break; + } + + case KWU_EVT_UBND_REQ: /* Unbind request */ + { + ret = cmUnpkKwuUbndReq(KwUiKwuUbndReq, pst, mBuf ); + break; + } +#ifdef L2_L3_SPLIT + case KWU_EVT_CPLANE_DAT_REQ: /* C-Plane Data request */ + { + ret = cmUnpkKwuDatReq(KwUiKwuDatReq, pst, mBuf); + break; + } +#else + case KWU_EVT_DAT_REQ: /* Data request */ + { + ret = cmUnpkKwuDatReq(KwUiKwuDatReq, pst, mBuf); + break; + } +#endif + case KWU_EVT_DISC_SDU_REQ: /* Discard SDU request */ + { + ret = cmUnpkKwuDiscSduReq(KwUiKwuDiscSduReq, pst, mBuf); + break; + } + +#endif /* LCKWU */ + default: + SPutMsg(mBuf); + if (pst->dstInst < KW_MAX_RLC_INSTANCES) + { + RLOG1(L_ERROR,"Received Invalid Event[%d] from RRC", + pst->event); + } + ret = RFAILED; + break; + + } + break; + } + + case ENTPJ: + { + switch(pst->event) + { +#ifdef LCKWU + case KWU_EVT_BND_REQ: /* Bind request */ + { + ret = cmUnpkKwuBndReq(KwUiKwuBndReq, pst, mBuf ); + break; + } + + case KWU_EVT_UBND_REQ: /* Unbind request */ + { + ret = cmUnpkKwuUbndReq(KwUiKwuUbndReq, pst, mBuf ); + break; + } +#ifdef L2_L3_SPLIT + case KWU_EVT_CPLANE_DAT_REQ: /* C-Plane Data request */ + case KWU_EVT_UPLANE_DAT_REQ: /* U-Plane Data request */ + { + ret = cmUnpkKwuDatReq(KwUiKwuDatReq, pst, mBuf); + break; + } +#else + case KWU_EVT_DAT_REQ: /* Data request */ + { + ret = cmUnpkKwuDatReq(KwUiKwuDatReq, pst, mBuf); + break; + } +#endif + case KWU_EVT_DISC_SDU_REQ: /* Discard SDU request */ + { + ret = cmUnpkKwuDiscSduReq(KwUiKwuDiscSduReq, pst, mBuf); + break; + } + + default: + SPutMsg(mBuf); + if (pst->dstInst < KW_MAX_RLC_INSTANCES) + { + RLOG1(L_ERROR,"Received Invalid Event[%d] from PDCP", + pst->event); + } + ret = RFAILED; + break; +#endif /* LCKWU */ + } + break; + } + + case ENTRG: + { + switch(pst->event) + { +#ifdef LCRGU + case EVTRGUBNDCFM: /* Bind request */ + { + ret = cmUnpkRguBndCfm(KwLiRguBndCfm, pst, mBuf ); + break; + } + + case EVTRGUCSTAIND: /* Coomon Channel Status Response */ + { + ret = cmUnpkRguCStaInd(KwLiRguCStaInd, pst, mBuf); + break; + } + + case EVTRGUDSTAIND: /* Dedicated Channel Status Response */ + { + ret = cmUnpkRguDStaInd(KwLiRguDStaInd, pst, mBuf); + break; + } + /* kw005.201 added support for L2 Measurement */ +#ifdef LTE_L2_MEAS + case EVTRGUHQSTAIND: /* Harq status indication */ + { + ret = cmUnpkRguHqStaInd(KwLiRguHqStaInd, pst, mBuf); + break; + } +#endif + case EVTRGUFLOWCNTRLIND: + { + ret = cmUnpkRguFlowCntrlInd(KwLiRguFlowCntrlInd,pst,mBuf); + break; + } +#endif /* LCRGU */ +#ifdef RLC_STA_PROC_IN_MAC/* RLC Status PDU Processing */ + case UDX_EVT_STA_UPD_REQ: /* Configuration request */ + { + ret = cmUnpkUdxStaUpdReq(KwDlUdxStaUpdReq, pst, mBuf); + break; + } +#endif + + default: + SPutMsg(mBuf); + if (pst->dstInst < KW_MAX_RLC_INSTANCES) + { + RLOG1(L_ERROR,"Received Invalid Event[%d] from MAC", + pst->event); + } + ret = RFAILED; + break; + } + break; + } +#ifdef SS_RBUF + case ENTTF: + { + switch(pst->event) + { + case EVTCTFBTCHPROCTICK: + { + kwUtlDlBatchProcPkts(); + break; + } + } + SPutMsg(mBuf); + break; + } +#endif + case ENTYS: + { + switch(pst->event) + { + case KWU_EVT_TTI_IND: + { +#if (defined(L2_L3_SPLIT) && defined(ICC_RECV_TSK_RBUF)) + kwDlBatchProcSplit(); +#else +#if defined(PDCP_RLC_DL_RBUF) + kwDlBatchProc(); +#endif +#endif + +#if (defined(SPLIT_RLC_DL_TASK) && defined(MAC_RLC_HARQ_STA_RBUF) && defined(LTE_L2_MEAS)) + //KwDlHarqStaBatchProc(); + kwUtlDlBatchProcHqStaInd(); +#endif +#ifndef KWSELFPSTDLCLEAN + /* Revanth_chg */ + /* Moving Cleanup from self post event to TTI event */ + kwUtlFreeDlMem(); +#endif + + SPutMsg(mBuf); + break; + } + } + break; + } + + + default: + { + if (pst->dstInst < KW_MAX_RLC_INSTANCES) + { + /*KwCb *tKwCb = KW_GET_KWCB(pst->dstInst);*/ + RLOG1(L_ERROR, "Received Invalid Source Entity[%d]", + pst->event); + } + SPutMsg(mBuf); + ret = RFAILED; + break; + } + } + SExitTsk(); + + RETVALUE(ret); +} /* kwActvTsk */ + + + +/********************************************************************30** + End of file +**********************************************************************/ diff --git a/src/5gnrrlc/kw_env.h b/src/5gnrrlc/kw_env.h new file mode 100755 index 000000000..43135ce1a --- /dev/null +++ b/src/5gnrrlc/kw_env.h @@ -0,0 +1,90 @@ +/******************************************************************************* +################################################################################ +# Copyright (c) [2017-2019] [Radisys] # +# # +# 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. # +################################################################################ +*******************************************************************************/ + +/********************************************************************20** + + Name: LTE RLC file + + Type: C include file + + Desc: This file contains the constants required for LTE-RLC. + The defines in this file need to be changed by the customer + to reflect the software architecture needed to run under the + target system hardware architecture. + + File: kw_env.h + +*********************************************************************21*/ +/** @file kw_env.h +@brief RLC Hash definitions +*/ + +#ifndef __KWENVH__ +#define __KWENVH__ + +#define KW_MAX_RLC_INSTANCES 2 +#define KW_MAX_LI KWU_MAX_STA_IND_SDU + +#define KW_MAX_DL_LI 28 +#define KW_MAX_NEW_DL_PDU 16 +/* kw003.201 Adding new environment variables */ +/* This parameter is utilized when KW_BG_DL_PROC enbled. This parameter */ +/* defines how many PDUs may be released in one go without affecting */ +/* TTI response time */ +/* kw004.201 modifed the value from 20 to 15 */ +#define KW_AM_MAX_PDUS_RLS 1 +/* This parameter governs maximum number of PDUs to processed at a */ +/* given point when KW_BG_UL_PROC is enabled. */ +/* kw004.201 modifed the value from 20 to 5 */ +#define KW_AM_MAX_UL_PDUS 1 + +#define KW_AM_UM_MAX_UL_SDUS 1 +#define KW_AM_UM_MAX_DL_SDUS 300 + +#ifdef SPLIT_RLC_DL_TASK +#define KW_MAX_TO_BE_FREED 60 +#else +#define KW_MAX_TO_BE_FREED 10 +#endif + +/* Number of packets queued in SDU Q after which overload + * START is signalled to PDCP for an UM bearer */ +#define KW_UM_RB_OVERLOAD_HIGH_THRES 512 +/* Number of packets queued in SDU Q after which overload + * STOP is signalled to PDCP for an UM bearer */ +#define KW_UM_RB_OVERLOAD_LOW_THRES 300 + +/* Value of this macro can be in the range of 1 to RGU_MAX_PDU */ +#define KW_MAX_PDU 16 + +#ifdef LTE_L2_MEAS +/* This value is decided on the assumption that there will be maximum 3 active DRB at a time */ +#define KW_MAX_ACTV_DRB 2 +/* Assumption is that all UEs wont have all RBs with max SDU: if greater, will be ignored */ +#define KW_L2MEAS_SDUIDX ((KW_MAX_DL_LI/4)*KW_MAX_ACTV_DRB) +/* Number of out standing SDUS in one RbCb : This would be sufficient but anything more will be discarded for counters */ +#define KW_L2MEAS_MAX_OUTSTNGSDU 31 +#endif + + +#endif /* __KWENVH__ */ + +/********************************************************************30** + + End of file +**********************************************************************/ diff --git a/src/5gnrrlc/kw_err.h b/src/5gnrrlc/kw_err.h new file mode 100755 index 000000000..50f1defb7 --- /dev/null +++ b/src/5gnrrlc/kw_err.h @@ -0,0 +1,365 @@ +/******************************************************************************* +################################################################################ +# Copyright (c) [2017-2019] [Radisys] # +# # +# 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. # +################################################################################ +*******************************************************************************/ + +/********************************************************************20** + + Name: LTE RLC file + + Type: C include file + + Desc: This file contain the hash definations for RLC + + File: kw_err.h + +*********************************************************************21*/ +/** @file kw_err.h +@brief RLC Hash definitions +*/ + +#ifndef __KW_ERR_H__ +#define __KW_ERR_H__ + +#if (ERRCLASS & ERRCLS_INT_PAR) +#define KWLOGERROR(cb,errCls, errCode, errVal, errDesc) \ + SLogError(cb->init.ent, cb->init.inst, cb->init.procId, \ + __FILE__, __LINE__, errCls, errCode, errVal, errDesc) + +#define KW_GET_AND_VALIDATE_KWUSAP(_spId, _kwuSap, _errCode, _fn) \ +{ \ + S16 _ret; \ + _ret = RFAILED; \ + _kwuSap = NULLP; \ + if((_spId < (S16) kwCb.genCfg.maxKwuSaps) && (_spId >= 0)) \ + { \ + _kwuSap = kwCb.kwuSap + _spId; \ + if((_kwuSap != NULLP) && (_kwuSap->state == KW_SAP_BND)) \ + { \ + _ret = ROK; \ + } \ + } \ + if(_ret != ROK) \ + { \ + KWLOGERROR(ERRCLS_INT_PAR, EKWxxx, (ErrVal) spId, \ + "KwUiKwuBndReq: KWU SAP State is Invalid during Bind Req"); \ + KW_SEND_SAPID_ALARM(spId, LKW_EVENT_KWU_BND_REQ, LCM_CAUSE_INV_SAP);\ + RETVALUE(RFAILED); \ + } \ +} +#else +#define KW_GET_AND_VALIDATE_KWUSAP(_spId, _kwuSap, _errCode, _fn) \ + _kwuSap = kwCb.kwuSap + _spId; +#define KWLOGERROR(cb, errCls, errCode, errVal, errDesc) + +#endif + +#if (ERRCLASS & ERRCLS_INT_PAR) +#define KW_GET_AND_VALIDATE_CKWSAP(_cb,_ckwSap, _errCode, _fn) \ +{ \ + S16 _ret; \ + _ret = RFAILED; \ + if((_ckwSap != NULLP) && (_ckwSap->state == KW_SAP_BND)) \ + { \ + _ret = ROK; \ + } \ + if(_ret != ROK) \ + { \ + KWLOGERROR(_cb,ERRCLS_INT_PAR, EKWxxx, (ErrVal) spId,\ + "KwUiCkwBndReq: CKW SAP State is Invalid during Bind Req");\ + KW_SEND_SAPID_ALARM(_cb,spId, LKW_EVENT_CKW_BND_REQ, LCM_CAUSE_INV_STATE);\ + RETVALUE(RFAILED); \ + } \ +} +#endif +#if (ERRCLASS & ERRCLS_INT_PAR) +#define KW_GET_AND_VALIDATE_UDXSAP(_cb,_udxSap, _errCode, _fn) \ +{ \ + S16 _ret; \ + _ret = RFAILED; \ + if((_udxSap != NULLP) && (_udxSap->state == KW_SAP_BND)) \ + { \ + _ret = ROK; \ + } \ + if(_ret != ROK) \ + { \ + KWLOGERROR(_cb,ERRCLS_INT_PAR, EKWxxx, (ErrVal) spId,\ + "KwUiCkwBndReq: UDX SAP State is Invalid during Bind Req");\ + KW_SEND_SAPID_ALARM(_cb,spId, LKW_EVENT_UDX_BND_REQ, LCM_CAUSE_INV_STATE);\ + RETVALUE(RFAILED); \ + } \ +} +#endif + +/* Error Codes */ +#define ERRKW 0 +#define EKWXXX 0 + +#define EKW001 (ERRKW + 1) /* gp_amm.c: 293 */ +#define EKW002 (ERRKW + 2) /* gp_amm.c: 405 */ +#define EKW003 (ERRKW + 3) /* gp_amm.c: 419 */ +#define EKW004 (ERRKW + 4) /* gp_amm.c: 880 */ +#define EKW005 (ERRKW + 5) /* gp_amm.c:1351 */ +#define EKW006 (ERRKW + 6) /* gp_amm.c:1367 */ +#define EKW007 (ERRKW + 7) /* gp_amm.c:1561 */ +#define EKW008 (ERRKW + 8) /* gp_amm.c:1649 */ +#define EKW009 (ERRKW + 9) /* gp_amm.c:2423 */ +#define EKW010 (ERRKW + 10) /* gp_amm.c:2445 */ +#define EKW011 (ERRKW + 11) /* gp_amm.c:2555 */ +#define EKW012 (ERRKW + 12) /* gp_amm.c:3047 */ +#define EKW013 (ERRKW + 13) /* gp_amm.c:3069 */ +#define EKW014 (ERRKW + 14) /* gp_amm.c:3077 */ +#define EKW015 (ERRKW + 15) /* gp_amm.c:3147 */ +#define EKW016 (ERRKW + 16) /* gp_amm.c:3179 */ +#define EKW017 (ERRKW + 17) /* gp_amm.c:3187 */ +#define EKW018 (ERRKW + 18) /* gp_amm.c:4489 */ + +#define EKW019 (ERRKW + 19) /* gp_cfg.c: 268 */ +#define EKW020 (ERRKW + 20) /* gp_cfg.c: 311 */ +#define EKW021 (ERRKW + 21) /* gp_cfg.c: 368 */ +#define EKW022 (ERRKW + 22) /* gp_cfg.c: 380 */ + +#define EKW023 (ERRKW + 23) /* gp_dbm.c: 633 */ +#define EKW024 (ERRKW + 24) /* gp_dbm.c: 958 */ +#define EKW025 (ERRKW + 25) /* gp_dbm.c:1182 */ +#define EKW026 (ERRKW + 26) /* gp_dbm.c:1190 */ +#define EKW027 (ERRKW + 27) /* gp_dbm.c:1198 */ +#define EKW028 (ERRKW + 28) /* gp_dbm.c:1263 */ + +#define EKW029 (ERRKW + 29) /* gp_ex_ms.c: 317 */ +#define EKW030 (ERRKW + 30) /* gp_ex_ms.c: 389 */ +#define EKW031 (ERRKW + 31) /* gp_ex_ms.c: 431 */ +#define EKW032 (ERRKW + 32) /* gp_ex_ms.c: 481 */ +#define EKW033 (ERRKW + 33) /* gp_ex_ms.c: 493 */ +#define EKW034 (ERRKW + 34) /* gp_ex_ms.c: 638 */ +#define EKW035 (ERRKW + 35) /* gp_ex_ms.c: 730 */ +#define EKW036 (ERRKW + 36) /* gp_ex_ms.c: 772 */ +#define EKW037 (ERRKW + 37) /* gp_ex_ms.c: 802 */ +#define EKW038 (ERRKW + 38) /* gp_ex_ms.c: 849 */ +#define EKW039 (ERRKW + 39) /* gp_ex_ms.c: 861 */ + +#define EKW040 (ERRKW + 40) /* gp_lim.c: 221 */ +#define EKW041 (ERRKW + 41) /* gp_lim.c: 231 */ + +#define EKW042 (ERRKW + 42) /* gp_lmm.c: 225 */ +#define EKW043 (ERRKW + 43) /* gp_lmm.c: 280 */ +#define EKW044 (ERRKW + 44) /* gp_lmm.c: 418 */ +#define EKW045 (ERRKW + 45) /* gp_lmm.c: 886 */ +#define EKW046 (ERRKW + 46) /* gp_lmm.c: 952 */ +#define EKW047 (ERRKW + 47) /* gp_lmm.c:1016 */ +#define EKW048 (ERRKW + 48) /* gp_lmm.c:1340 */ + +#define EKW049 (ERRKW + 49) /* gp_pj_cfg.c: 505 */ +#define EKW050 (ERRKW + 50) /* gp_pj_cfg.c:1276 */ + +#define EKW051 (ERRKW + 51) /* gp_pj_cfg.c.tmp: 505 */ +#define EKW052 (ERRKW + 52) /* gp_pj_cfg.c.tmp:1276 */ + +#define EKW053 (ERRKW + 53) /* gp_pj_dlm.c: 243 */ +#define EKW054 (ERRKW + 54) /* gp_pj_dlm.c: 381 */ +#define EKW055 (ERRKW + 55) /* gp_pj_dlm.c: 518 */ +#define EKW056 (ERRKW + 56) /* gp_pj_dlm.c: 564 */ +#define EKW057 (ERRKW + 57) /* gp_pj_dlm.c: 644 */ +#define EKW058 (ERRKW + 58) /* gp_pj_dlm.c: 724 */ +#define EKW059 (ERRKW + 59) /* gp_pj_dlm.c: 864 */ +#define EKW060 (ERRKW + 60) /* gp_pj_dlm.c: 883 */ +#define EKW061 (ERRKW + 61) /* gp_pj_dlm.c: 921 */ +#define EKW062 (ERRKW + 62) /* gp_pj_dlm.c:1036 */ +#define EKW063 (ERRKW + 63) /* gp_pj_dlm.c:1049 */ +#define EKW064 (ERRKW + 64) /* gp_pj_dlm.c:1176 */ +#define EKW065 (ERRKW + 65) /* gp_pj_dlm.c:1226 */ +#define EKW066 (ERRKW + 66) /* gp_pj_dlm.c:1299 */ +#define EKW067 (ERRKW + 67) /* gp_pj_dlm.c:1324 */ +#define EKW068 (ERRKW + 68) /* gp_pj_dlm.c:1466 */ +#define EKW069 (ERRKW + 69) /* gp_pj_dlm.c:1534 */ +#define EKW070 (ERRKW + 70) /* gp_pj_dlm.c:1621 */ +#define EKW071 (ERRKW + 71) /* gp_pj_dlm.c:1637 */ +#define EKW072 (ERRKW + 72) /* gp_pj_dlm.c:1657 */ +#define EKW073 (ERRKW + 73) /* gp_pj_dlm.c:1680 */ +#define EKW074 (ERRKW + 74) /* gp_pj_dlm.c:1750 */ +#define EKW075 (ERRKW + 75) /* gp_pj_dlm.c:1772 */ +#define EKW076 (ERRKW + 76) /* gp_pj_dlm.c:1847 */ +#define EKW077 (ERRKW + 77) /* gp_pj_dlm.c:1961 */ + +#define EKW078 (ERRKW + 78) /* gp_pj_lmm.c: 319 */ +#define EKW079 (ERRKW + 79) /* gp_pj_lmm.c: 806 */ +#define EKW080 (ERRKW + 80) /* gp_pj_lmm.c: 870 */ + +#define EKW081 (ERRKW + 81) /* gp_pj_uim.c: 268 */ +#define EKW082 (ERRKW + 82) /* gp_pj_uim.c: 347 */ +#define EKW083 (ERRKW + 83) /* gp_pj_uim.c: 444 */ +#define EKW084 (ERRKW + 84) /* gp_pj_uim.c: 758 */ +#define EKW085 (ERRKW + 85) /* gp_pj_uim.c: 844 */ +#define EKW086 (ERRKW + 86) /* gp_pj_uim.c: 937 */ +#define EKW087 (ERRKW + 87) /* gp_pj_uim.c:1008 */ +#define EKW088 (ERRKW + 88) /* gp_pj_uim.c:1158 */ +#define EKW089 (ERRKW + 89) /* gp_pj_uim.c:1221 */ +#define EKW090 (ERRKW + 90) /* gp_pj_uim.c:1305 */ +#define EKW091 (ERRKW + 91) /* gp_pj_uim.c:1412 */ +#define EKW092 (ERRKW + 92) /* gp_pj_uim.c:1454 */ +#define EKW093 (ERRKW + 93) /* gp_pj_uim.c:1566 */ + +#define EKW094 (ERRKW + 94) /* gp_pj_uim.c.tmp: 268 */ +#define EKW095 (ERRKW + 95) /* gp_pj_uim.c.tmp: 347 */ +#define EKW096 (ERRKW + 96) /* gp_pj_uim.c.tmp: 444 */ +#define EKW097 (ERRKW + 97) /* gp_pj_uim.c.tmp: 758 */ +#define EKW098 (ERRKW + 98) /* gp_pj_uim.c.tmp: 844 */ +#define EKW099 (ERRKW + 99) /* gp_pj_uim.c.tmp: 937 */ +#define EKW100 (ERRKW + 100) /* gp_pj_uim.c.tmp:1008 */ +#define EKW101 (ERRKW + 101) /* gp_pj_uim.c.tmp:1158 */ +#define EKW102 (ERRKW + 102) /* gp_pj_uim.c.tmp:1221 */ +#define EKW103 (ERRKW + 103) /* gp_pj_uim.c.tmp:1305 */ +#define EKW104 (ERRKW + 104) /* gp_pj_uim.c.tmp:1412 */ +#define EKW105 (ERRKW + 105) /* gp_pj_uim.c.tmp:1454 */ +#define EKW106 (ERRKW + 106) /* gp_pj_uim.c.tmp:1566 */ + +#define EKW107 (ERRKW + 107) /* gp_pj_ulm.c: 482 */ +#define EKW108 (ERRKW + 108) /* gp_pj_ulm.c: 812 */ +#define EKW109 (ERRKW + 109) /* gp_pj_ulm.c: 828 */ +#define EKW110 (ERRKW + 110) /* gp_pj_ulm.c: 943 */ +#define EKW111 (ERRKW + 111) /* gp_pj_ulm.c: 972 */ +#define EKW112 (ERRKW + 112) /* gp_pj_ulm.c:1047 */ +#define EKW113 (ERRKW + 113) /* gp_pj_ulm.c:1064 */ +#define EKW114 (ERRKW + 114) /* gp_pj_ulm.c:2070 */ +#define EKW115 (ERRKW + 115) /* gp_pj_ulm.c:2077 */ + +#define EKW116 (ERRKW + 116) /* gp_pj_utl.c: 213 */ +#define EKW117 (ERRKW + 117) /* gp_pj_utl.c: 221 */ +#define EKW118 (ERRKW + 118) /* gp_pj_utl.c: 291 */ +#define EKW119 (ERRKW + 119) /* gp_pj_utl.c: 356 */ +#define EKW120 (ERRKW + 120) /* gp_pj_utl.c: 421 */ +#define EKW121 (ERRKW + 121) /* gp_pj_utl.c: 510 */ +#define EKW122 (ERRKW + 122) /* gp_pj_utl.c: 525 */ +#define EKW123 (ERRKW + 123) /* gp_pj_utl.c: 532 */ +#define EKW124 (ERRKW + 124) /* gp_pj_utl.c: 554 */ +#define EKW125 (ERRKW + 125) /* gp_pj_utl.c: 640 */ +#define EKW126 (ERRKW + 126) /* gp_pj_utl.c: 652 */ +#define EKW127 (ERRKW + 127) /* gp_pj_utl.c: 676 */ +#define EKW128 (ERRKW + 128) /* gp_pj_utl.c: 782 */ +#define EKW129 (ERRKW + 129) /* gp_pj_utl.c: 794 */ +#define EKW130 (ERRKW + 130) /* gp_pj_utl.c: 805 */ +#define EKW131 (ERRKW + 131) /* gp_pj_utl.c: 826 */ +#define EKW132 (ERRKW + 132) /* gp_pj_utl.c: 905 */ +#define EKW133 (ERRKW + 133) /* gp_pj_utl.c: 919 */ +#define EKW134 (ERRKW + 134) /* gp_pj_utl.c: 926 */ +#define EKW135 (ERRKW + 135) /* gp_pj_utl.c:1027 */ +#define EKW136 (ERRKW + 136) /* gp_pj_utl.c:1042 */ +#define EKW137 (ERRKW + 137) /* gp_pj_utl.c:1070 */ +#define EKW138 (ERRKW + 138) /* gp_pj_utl.c:1205 */ +#define EKW139 (ERRKW + 139) /* gp_pj_utl.c:1222 */ +#define EKW140 (ERRKW + 140) /* gp_pj_utl.c:1232 */ +#define EKW141 (ERRKW + 141) /* gp_pj_utl.c:2460 */ +#define EKW142 (ERRKW + 142) /* gp_pj_utl.c:2470 */ +#define EKW143 (ERRKW + 143) /* gp_pj_utl.c:2642 */ +#define EKW144 (ERRKW + 144) /* gp_pj_utl.c:2874 */ +#define EKW145 (ERRKW + 145) /* gp_pj_utl.c:2963 */ +#define EKW146 (ERRKW + 146) /* gp_pj_utl.c:3153 */ +#define EKW147 (ERRKW + 147) /* gp_pj_utl.c:3171 */ +#define EKW148 (ERRKW + 148) /* gp_pj_utl.c:3219 */ +#define EKW149 (ERRKW + 149) /* gp_pj_utl.c:3322 */ +#define EKW150 (ERRKW + 150) /* gp_pj_utl.c:3353 */ +#define EKW151 (ERRKW + 151) /* gp_pj_utl.c:3412 */ +#define EKW152 (ERRKW + 152) /* gp_pj_utl.c:3449 */ +#define EKW153 (ERRKW + 153) /* gp_pj_utl.c:3540 */ + +#define EKW154 (ERRKW + 154) /* gp_pj_utl.c.tmp: 213 */ +#define EKW155 (ERRKW + 155) /* gp_pj_utl.c.tmp: 221 */ +#define EKW156 (ERRKW + 156) /* gp_pj_utl.c.tmp: 291 */ +#define EKW157 (ERRKW + 157) /* gp_pj_utl.c.tmp: 356 */ +#define EKW158 (ERRKW + 158) /* gp_pj_utl.c.tmp: 421 */ +#define EKW159 (ERRKW + 159) /* gp_pj_utl.c.tmp: 510 */ +#define EKW160 (ERRKW + 160) /* gp_pj_utl.c.tmp: 525 */ +#define EKW161 (ERRKW + 161) /* gp_pj_utl.c.tmp: 532 */ +#define EKW162 (ERRKW + 162) /* gp_pj_utl.c.tmp: 554 */ +#define EKW163 (ERRKW + 163) /* gp_pj_utl.c.tmp: 640 */ +#define EKW164 (ERRKW + 164) /* gp_pj_utl.c.tmp: 652 */ +#define EKW165 (ERRKW + 165) /* gp_pj_utl.c.tmp: 676 */ +#define EKW166 (ERRKW + 166) /* gp_pj_utl.c.tmp: 782 */ +#define EKW167 (ERRKW + 167) /* gp_pj_utl.c.tmp: 794 */ +#define EKW168 (ERRKW + 168) /* gp_pj_utl.c.tmp: 805 */ +#define EKW169 (ERRKW + 169) /* gp_pj_utl.c.tmp: 826 */ +#define EKW170 (ERRKW + 170) /* gp_pj_utl.c.tmp: 905 */ +#define EKW171 (ERRKW + 171) /* gp_pj_utl.c.tmp: 919 */ +#define EKW172 (ERRKW + 172) /* gp_pj_utl.c.tmp: 926 */ +#define EKW173 (ERRKW + 173) /* gp_pj_utl.c.tmp:1027 */ +#define EKW174 (ERRKW + 174) /* gp_pj_utl.c.tmp:1042 */ +#define EKW175 (ERRKW + 175) /* gp_pj_utl.c.tmp:1070 */ +#define EKW176 (ERRKW + 176) /* gp_pj_utl.c.tmp:1205 */ +#define EKW177 (ERRKW + 177) /* gp_pj_utl.c.tmp:1222 */ +#define EKW178 (ERRKW + 178) /* gp_pj_utl.c.tmp:1232 */ +#define EKW179 (ERRKW + 179) /* gp_pj_utl.c.tmp:2460 */ +#define EKW180 (ERRKW + 180) /* gp_pj_utl.c.tmp:2470 */ +#define EKW181 (ERRKW + 181) /* gp_pj_utl.c.tmp:2642 */ +#define EKW182 (ERRKW + 182) /* gp_pj_utl.c.tmp:2874 */ +#define EKW183 (ERRKW + 183) /* gp_pj_utl.c.tmp:2963 */ +#define EKW184 (ERRKW + 184) /* gp_pj_utl.c.tmp:3153 */ +#define EKW185 (ERRKW + 185) /* gp_pj_utl.c.tmp:3171 */ +#define EKW186 (ERRKW + 186) /* gp_pj_utl.c.tmp:3219 */ +#define EKW187 (ERRKW + 187) /* gp_pj_utl.c.tmp:3322 */ +#define EKW188 (ERRKW + 188) /* gp_pj_utl.c.tmp:3353 */ +#define EKW189 (ERRKW + 189) /* gp_pj_utl.c.tmp:3412 */ +#define EKW190 (ERRKW + 190) /* gp_pj_utl.c.tmp:3449 */ +#define EKW191 (ERRKW + 191) /* gp_pj_utl.c.tmp:3540 */ + +#define EKW192 (ERRKW + 192) /* gp_ptui.c: 666 */ +#define EKW193 (ERRKW + 193) /* gp_ptui.c: 709 */ +#define EKW194 (ERRKW + 194) /* gp_ptui.c: 752 */ +#define EKW195 (ERRKW + 195) /* gp_ptui.c: 795 */ +#define EKW196 (ERRKW + 196) /* gp_ptui.c: 842 */ +#define EKW197 (ERRKW + 197) /* gp_ptui.c:1081 */ +#define EKW198 (ERRKW + 198) /* gp_ptui.c:1123 */ +#define EKW199 (ERRKW + 199) /* gp_ptui.c:1158 */ + +#define EKW200 (ERRKW + 200) /* gp_tmm.c: 213 */ +#define EKW201 (ERRKW + 201) /* gp_tmm.c: 303 */ +#define EKW202 (ERRKW + 202) /* gp_tmm.c: 405 */ +#define EKW203 (ERRKW + 203) /* gp_tmm.c: 519 */ + +#define EKW204 (ERRKW + 204) /* gp_tmr.c: 253 */ +#define EKW205 (ERRKW + 205) /* gp_tmr.c: 358 */ +#define EKW206 (ERRKW + 206) /* gp_tmr.c: 554 */ + +#define EKW207 (ERRKW + 207) /* gp_uim.c: 276 */ +#define EKW208 (ERRKW + 208) /* gp_uim.c: 358 */ +#define EKW209 (ERRKW + 209) /* gp_uim.c: 437 */ +#define EKW210 (ERRKW + 210) /* gp_uim.c: 690 */ +#define EKW211 (ERRKW + 211) /* gp_uim.c: 769 */ +#define EKW212 (ERRKW + 212) /* gp_uim.c: 832 */ +#define EKW213 (ERRKW + 213) /* gp_uim.c: 912 */ + +#define EKW214 (ERRKW + 214) /* gp_umm.c: 213 */ +#define EKW215 (ERRKW + 215) /* gp_umm.c: 706 */ +#define EKW216 (ERRKW + 216) /* gp_umm.c:1248 */ + +#define EKW217 (ERRKW + 217) /* gp_utl.c: 227 */ +#define EKW218 (ERRKW + 218) /* gp_utl.c: 237 */ +#define EKW219 (ERRKW + 219) /* gp_utl.c: 263 */ +#define EKW220 (ERRKW + 220) /* gp_utl.c: 278 */ +#define EKW221 (ERRKW + 221) /* gp_utl.c: 383 */ +#define EKW222 (ERRKW + 222) /* gp_utl.c: 401 */ +#define EKW223 (ERRKW + 223) /* gp_utl.c: 413 */ +#define EKW224 (ERRKW + 224) /* gp_utl.c: 473 */ +#define EKW225 (ERRKW + 225) /* gp_utl.c: 598 */ +#define EKW226 (ERRKW + 226) /* gp_pj_tmr.c: 291 */ +#define EKW227 (ERRKW + 227) /* gp_pj_tmr.c: 576 */ + + +#endif /* __KW_ERR_H__ */ + +/********************************************************************30** + + End of file +**********************************************************************/ diff --git a/src/5gnrrlc/kw_id.c b/src/5gnrrlc/kw_id.c new file mode 100755 index 000000000..8722d5a1b --- /dev/null +++ b/src/5gnrrlc/kw_id.c @@ -0,0 +1,136 @@ +/******************************************************************************* +################################################################################ +# Copyright (c) [2017-2019] [Radisys] # +# # +# 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. # +################################################################################ +*******************************************************************************/ + +/********************************************************************20** + + Name: LTE-RLC Layer + + Type: C source file + + Desc: + + File: kw_id.c + +*********************************************************************21*/ + + + +/* header include files (.h) */ + +#include "envopt.h" /* environment options */ +#include "envdep.h" /* environment dependent */ +#include "envind.h" /* environment independent */ + +#include "gen.h" /* general */ +#include "ssi.h" /* system services interface */ + +/* header/extern include files (.x) */ + +#include "gen.x" /* general */ +#include "ssi.x" /* system services interface */ + + +/* local defines */ + +#define KWSWMV 2 /* rlc - main version */ +#define KWSWMR 1 /* rlc - main revision */ +#define KWSWBV 0 /* rlc - branch version */ +#define KWSWBR 5 /* rlc - kw005.201 patch level */ +#define KWSWPN "1000371" /* rlc - part number */ + +/* local typedefs */ + +/* local externs */ + +/* forward references */ + +/* public variable declarations */ + +#ifdef __cplusplus +EXTERN "C" { +#endif /* CPLUSPLUS */ + +EXTERN S16 kwGetSId ARGS((SystemId *s)); +#ifdef __cplusplus +} +#endif /* CPLUSPLUS */ + +/* copyright banner */ + +PUBLIC CONSTANT Txt kwBan1[] = + {"(c) COPYRIGHT 1989-2002, Trillium Digital Systems, Inc."}; + +PUBLIC CONSTANT Txt kwBan2[] = + {" All rights reserved."}; + +/* system id */ + +PRIVATE CONSTANT SystemId sId ={ + KWSWMV, /* rlc - main version */ + KWSWMR, /* rlc - main revision */ + KWSWBV, /* rlc - branch version */ + KWSWBR, /* rlc - branch revision */ + KWSWPN /* rlc - part number */ +}; + +/* +* support functions +*/ + +/* +* +* Fun: get system id +* +* Desc: Get system id consisting of part number, main version and +* revision and branch version and branch. +* +* Ret: TRUE - ok +* +* Notes: None +* +* File: kw_id.c +* +*/ + +#ifdef ANSI +PUBLIC S16 kwGetSId +( +SystemId *s /* system id */ +) +#else +PUBLIC S16 kwGetSId(s) +SystemId *s; /* system id */ +#endif +{ + TRC2(kwGetSId); + + s->mVer = sId.mVer; + s->mRev = sId.mRev; + s->bVer = sId.bVer; + s->bRev = sId.bRev; + s->ptNmb = sId.ptNmb; + + RETVALUE(TRUE); + +} /* end of kwGetSId */ + + +/********************************************************************30** + + End of file +**********************************************************************/ diff --git a/src/5gnrrlc/kw_lim.c b/src/5gnrrlc/kw_lim.c new file mode 100755 index 000000000..7ad2d1487 --- /dev/null +++ b/src/5gnrrlc/kw_lim.c @@ -0,0 +1,699 @@ +/******************************************************************************* +################################################################################ +# Copyright (c) [2017-2019] [Radisys] # +# # +# 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. # +################################################################################ +*******************************************************************************/ + +/********************************************************************20** + + Name: LTE-RLC Layer - Lower Interface Functions + + Type: C file + + Desc: Source code for RLC Lower Interface Module. + This file contains following functions + + --KwLiRguBndCfm + --KwLiRguCDatInd + --KwLiRguDDatInd + --KwLiRguCStaInd + --KwLiRguDStaInd + --KwLiRguHqStaInd + + File: kw_lim.c + +**********************************************************************/ +static const char* RLOG_MODULE_NAME="LIM"; +static int RLOG_MODULE_ID=2048; +static int RLOG_FILE_ID=196; + +/** + * @file kw_lim.c + * @brief RLC Lower Interface module +*/ + +#define KW_MODULE KW_DBGMASK_INF + + +/* header (.h) include files */ +#include "envopt.h" /* environment options */ +#include "envdep.h" /* environment dependent */ +#include "envind.h" /* environment independent */ + +#include "gen.h" /* general */ +#include "ssi.h" /* system services */ +#include "cm5.h" /* common timer defines */ +#include "cm_tkns.h" /* common tokens defines */ +#include "cm_mblk.h" /* common memory allocation library defines */ +#include "cm_llist.h" /* common link list defines */ +#include "cm_hash.h" /* common hash list defines */ +#include "cm_lte.h" /* common LTE defines */ +#include "lkw.h" /* LKW defines */ +#include "ckw.h" /* CKW defines */ +#include "kwu.h" /* KWU defines */ +#include "rgu.h" /* RGU defines */ +#include "kw_err.h" +#include "kw_env.h" /* RLC environment options */ + +#include "kw.h" /* RLC defines */ +#include "kw_udx.h" +#include "kw_dl.h" +#include "kw_ul.h" + +/* extern (.x) include files */ +#include "gen.x" /* general */ +#include "ssi.x" /* system services */ + +#include "cm5.x" /* common timer library */ +#include "cm_tkns.x" /* common tokens */ +#include "cm_mblk.x" /* common memory allocation */ +#include "cm_llist.x" /* common link list */ +#include "cm_hash.x" /* common hash list */ +#include "cm_lte.x" /* common LTE includes */ +#include "cm_lib.x" /* common memory allocation library */ +#include "lkw.x" /* LKW */ +#include "ckw.x" /* CKW */ +#include "kwu.x" /* KWU */ +#include "rgu.x" /* RGU */ + +#include "kw.x" +#include "kw_udx.x" +#include "kw_dl.x" +#include "kw_ul.x" + +#ifdef __cplusplus +EXTERN "C" { +#endif /* __cplusplus */ + + +/***************************************************************************** + * RGU INTERFACE + ****************************************************************************/ +/** + * @brief Handler for bind confirmation from MAC. + * + * @details + * This function handles the bind confirmation received from MAC. If the + * bind was successful changes the state of the SAP to KW_SAP_BND + * else KW_SAP_CFG. Sends an alarm to LM in any case + * + * @param[in] pst Post structure + * @param[in] suId Service User ID + * @param[in] status Status whether the bind was successful or not + * + * @return S16 + * -# ROK + * -# RFAILED + * +*/ +#ifdef ANSI +PUBLIC S16 KwLiRguBndCfm +( +Pst *pst, +SuId suId, +U8 status +) +#else +PUBLIC S16 KwLiRguBndCfm (pst, suId, status) +Pst *pst; +SuId suId; +U8 status; +#endif +{ + U16 event; /* Event */ + U16 cause; /* Cause */ + KwRguSapCb *rguSap; /* RGU SAP Control Block */ + KwCb *tKwCb; + + TRC3(KwLiRguBndCfm) + +#if (ERRCLASS & ERRCLS_INT_PAR) + if (pst->dstInst >= KW_MAX_RLC_INSTANCES) + { + RETVALUE (RFAILED); + } +#endif + tKwCb = KW_GET_KWCB(pst->dstInst); + + RLOG2(L_DEBUG,"KwLiRguBndCfm(suId(%d), status(%d)", suId, status); + +#if (ERRCLASS & ERRCLS_INT_PAR) + if (tKwCb->init.cfgDone != TRUE) + { + RLOG0(L_FATAL,"General configuration not done"); + + KW_SEND_SAPID_ALARM(tKwCb,suId,LKW_EVENT_LI_BND_CFM, LCM_CAUSE_INV_STATE); + + RETVALUE(RFAILED); + } + + if ((suId >= tKwCb->genCfg.maxRguSaps) || (suId < 0)) + { + RLOG0(L_ERROR, "Invalid suId"); + + KW_SEND_SAPID_ALARM(tKwCb,suId, LKW_EVENT_LI_BND_CFM, LCM_CAUSE_INV_SUID); + + RETVALUE(RFAILED); + } +#endif /* ERRCLASS & ERRCLS_INT_PAR */ + + rguSap = (tKwCb->genCfg.rlcMode == LKW_RLC_MODE_DL) ? + &(tKwCb->u.dlCb->rguDlSap[suId]) : &(tKwCb->u.ulCb->rguUlSap[suId]); + + RLOG1(L_DEBUG, "KwLiRguBndCfm: For RGU SAP state=%d", rguSap->state) + + switch (rguSap->state) + { + case KW_SAP_BINDING: + { + kwStopTmr (tKwCb,(PTR)rguSap, KW_EVT_WAIT_BNDCFM); + + rguSap->retryCnt = 0; + + if (status == CM_BND_OK) + { + rguSap->state = KW_SAP_BND; + event = LCM_EVENT_BND_OK; + cause = LKW_CAUSE_SAP_BNDENB; + } + else + { + rguSap->state = KW_SAP_CFG; + event = LCM_EVENT_BND_FAIL; + cause = LKW_CAUSE_UNKNOWN; + } + + break; + } + default: + event = LKW_EVENT_RGU_BND_CFM; + cause = LCM_CAUSE_INV_STATE; + break; + } + + /* Send an alarm with proper event and cause */ + KW_SEND_SAPID_ALARM(tKwCb, suId, event, cause); + + RETVALUE(ROK); +} /* KwLiRguBndCfm */ + +PUBLIC int rlcDDatIndRcvd; +PUBLIC int rlcCDatIndRcvd; +/** + * @brief Handler to process PDU received from MAC for common logical channels. + * + * @details + * This function receives the PDU from MAC for common logical channels + * does checks before handing over the PDU to the TM module + * + * @param[in] pst Post structure + * @param[in] suId Service User ID + * @param[in] datInd Data Indication Information + * + * @return S16 + * -# ROK + * -# RFAILED + * +*/ +#ifdef ANSI +PUBLIC S16 KwLiRguCDatInd +( +Pst *pst, +SuId suId, +RguCDatIndInfo *datInd +) +#else +PUBLIC S16 KwLiRguCDatInd(pst,suId,datInd) +Pst *pst; +SuId suId; +RguCDatIndInfo *datInd; +#endif +{ + KwUlRbCb *rbCb; + KwCb *tKwCb; + + rlcCDatIndRcvd++; + TRC3(KwLiRguCDatInd) + +#if (ERRCLASS & ERRCLS_INT_PAR) + if (pst->dstInst >= KW_MAX_RLC_INSTANCES) + { + KW_SHRABL_STATIC_BUF_FREE(pst->region, pst->pool, datInd, sizeof(RguCDatIndInfo)); + RETVALUE (RFAILED); + } +#endif + + tKwCb = KW_GET_KWCB(pst->dstInst); + + +#if (ERRCLASS & ERRCLS_DEBUG) + if (tKwCb->genCfg.rlcMode == LKW_RLC_MODE_DL) + { + KW_SHRABL_STATIC_BUF_FREE(pst->region, pst->pool, datInd, sizeof(RguCDatIndInfo)); + RETVALUE(RFAILED); + } +#endif + + /* kw006.201 ccpu00120058, Added array boundary condition check */ +#if (ERRCLASS & ERRCLS_DEBUG) + if(KW_MAX_LCH_PER_CELL <= datInd->lcId) + { + RLOG_ARG1(L_ERROR,DBG_LCID,datInd->lcId, "Invalid LcId, Max is [%d]", + KW_MAX_LCH_PER_CELL); + KW_SHRABL_STATIC_BUF_FREE(pst->region, pst->pool, datInd, sizeof(RguCDatIndInfo)); + RETVALUE(RFAILED); + } +#endif /* (ERRCLASS & ERRCLS_DEBUG) */ + + /* Fetch RbCb from lcId */ + kwDbmFetchUlRbCbFromLchId(tKwCb, 0, datInd->cellId, datInd->lcId, &rbCb); + if (!rbCb) + { + RLOG_ARG1(L_ERROR, DBG_CELLID,datInd->cellId, "LcId [%d] not found", + datInd->lcId); + KW_SHRABL_STATIC_BUF_FREE(pst->region, pst->pool, datInd, sizeof(RguCDatIndInfo)); + RETVALUE(RFAILED); + } + + /* Dispatch to TM Module */ +#ifdef CCPU_OPT + kwTmmRcvFrmLi(tKwCb, rbCb, datInd->rnti, datInd->pdu); +#else /* CCPU_OPT */ + kwTmmRcvFrmLi(tKwCb, rbCb, datInd->pdu); +#endif /* CCPU_OPT */ + + KW_SHRABL_STATIC_BUF_FREE(pst->region, pst->pool, datInd, sizeof(RguCDatIndInfo)); + + RETVALUE(ROK); +} /* KwLiRguCDatInd */ + +/** + * @brief Handler to process PDU received from MAC for + * dedicated logical channels. + * + * @details + * This function receives the PDU from MAC for one or more dedicated + * logical channels and passes it to the UTL module for further processing + * + * @param[in] pst Post structure + * @param[in] suId Service User ID + * @param[in] datInd Data Indication Information + * + * @return S16 + * -# ROK + * -# RFAILED + * +*/ + +#ifdef ANSI +PUBLIC S16 KwLiRguDDatInd +( +Pst *pst, +SuId suId, +RguDDatIndInfo *datInd +) +#else +PUBLIC S16 KwLiRguDDatInd(pst, suId, datInd) +Pst *pst; +SuId suId; +RguDDatIndInfo *datInd; +#endif +{ + TRC3(KwLiRguDDatInd) + + rlcDDatIndRcvd++; +#if (ERRCLASS & ERRCLS_INT_PAR) + if (pst->dstInst >= KW_MAX_RLC_INSTANCES) + { + KW_SHRABL_STATIC_BUF_FREE(pst->region, pst->pool, datInd, sizeof(RguDDatIndInfo)); + RETVALUE (RFAILED); + } +#endif + +#if (ERRCLASS & ERRCLS_DEBUG) + if (((KwCb*)KW_GET_KWCB(pst->dstInst))->genCfg.rlcMode == LKW_RLC_MODE_DL) + { + RLOG1(L_DEBUG,"KwLiRguDDatInd(pst, suId(%d))recieved in DL Inst",suId); + KW_SHRABL_STATIC_BUF_FREE(pst->region, pst->pool, datInd, sizeof(RguDDatIndInfo)); + RETVALUE(RFAILED); + } +#endif + kwUtlRcvFrmLi(KW_GET_KWCB(pst->dstInst),datInd); +#ifndef SS_RBUF +#ifdef SS_LOCKLESS_MEMORY + KW_SHRABL_STATIC_BUF_FREE(pst->region, pst->pool, datInd, sizeof(RguDDatIndInfo)); +#else + KW_PST_FREE(pst->region, pst->pool, datInd, sizeof(RguDDatIndInfo)); +#endif +#endif + + RETVALUE(ROK); +} /* KwLiRguDDatInd */ + +/** + * @brief Handler for trigerring the data transfer from RLC to MAC + * for common logical channels. + * + * @details + * This function receives the size of the PDU to be transmitted + * and acts as a trigger for forming PDU and sending it to MAC. + * + * @param[in] pst Post structure + * @param[in] suId Service User ID + * @param[in] staInd Status Indication Information for Common Logical + * Channels + * + * @return S16 + * -# ROK + * -# RFAILED + * +*/ +#ifdef ANSI +PUBLIC S16 KwLiRguCStaInd +( +Pst *pst, +SuId suId, +RguCStaIndInfo *staInd +) +#else +PUBLIC S16 KwLiRguCStaInd(pst,suId,staInd) +Pst *pst; +SuId suId; +RguCStaIndInfo *staInd; +#endif +{ + KwDlRbCb *rbCb; + KwCb *tKwCb; + + TRC3(KwLiRguCStaInd) + +#if (ERRCLASS & ERRCLS_INT_PAR) + if (pst->dstInst >= KW_MAX_RLC_INSTANCES) + { + KW_SHRABL_STATIC_BUF_FREE(pst->region, pst->pool, staInd, sizeof(RguCStaIndInfo)); + RETVALUE (RFAILED); + } +#endif + + tKwCb = KW_GET_KWCB(pst->dstInst); + + +#if (ERRCLASS & ERRCLS_INT_PAR) + if ((suId >= tKwCb->genCfg.maxRguSaps) || (suId < 0)) + { + KWLOGERROR(tKwCb, + ERRCLS_INT_PAR, + EKW040, + (ErrVal) suId, + "KwLiRguCStaInd: Invalid RGU suId\n"); + RETVALUE(RFAILED); + } + if (tKwCb->genCfg.rlcMode == LKW_RLC_MODE_UL) + { + RLOG_ARG1(L_ERROR,DBG_LCID,staInd->lcId, + "Received in RLC UL CELLID:%d", + staInd->cellId); + KW_SHRABL_STATIC_BUF_FREE(pst->region, pst->pool, staInd, sizeof(RguCStaIndInfo)); + RETVALUE(RFAILED); + } +#endif + + rbCb = NULLP; + + /* kw006.201 ccpu00120058, added boundary condition check */ +#if (ERRCLASS & ERRCLS_DEBUG) + if(KW_MAX_LCH_PER_CELL < staInd->lcId) + { + RLOG_ARG2(L_ERROR,DBG_LCID,staInd->lcId, + "Invalid LcId, Max is [%d] CELLID:%d", + KW_MAX_LCH_PER_CELL, + staInd->cellId); + KW_SHRABL_STATIC_BUF_FREE(pst->region, pst->pool, staInd, sizeof(RguCStaIndInfo)); + RETVALUE(RFAILED); + } +#endif /* (ERRCLASS & ERRCLS_DEBUG) */ + /* Fertch RbCb from lcId */ + kwDbmFetchDlRbCbFromLchId(tKwCb,0, staInd->cellId, staInd->lcId, &rbCb); + if(!rbCb) + { + RLOG_ARG1(L_ERROR, DBG_CELLID,staInd->cellId, + "LcId [%d] not found CELLID:%d", + staInd->lcId); + KW_SHRABL_STATIC_BUF_FREE(pst->region, pst->pool, staInd, sizeof(RguCStaIndInfo)); + RETVALUE(RFAILED); + } + + /* Dispatch to TM Module */ + rbCb->transId = staInd->transId; + /* ccpu00136940 */ + /* If trace flag is enabled send the trace indication */ + if(tKwCb->init.trc == TRUE) + { + /* Populate the trace params */ + kwLmmSendTrc(tKwCb,EVTRGUCSTAIND, NULLP); + } + kwTmmSndToLi(tKwCb, suId, rbCb, staInd); +#ifndef SS_RBUF +#ifdef SS_LOCKLESS_MEMORY + KW_SHRABL_STATIC_BUF_FREE(pst->region, pst->pool, staInd, sizeof(RguCStaIndInfo)); +#else + KW_PST_FREE(pst->region, pst->pool, staInd, sizeof(RguCStaIndInfo)); +#endif +#else + KW_SHRABL_STATIC_BUF_FREE(pst->region, pst->pool, staInd, sizeof(RguCStaIndInfo)); +#endif + RETVALUE(ROK); +} /* KwLiRguCStaInd */ + +/** + * @brief Handler for trigerring the data transfer from RLC to MAC + * for dedicated logical channels. + * + * @details + * This function receives the size of the PDUs to be transmitted to + * MAC via one or more dedicated logical channels and acts as a trigger + * for forming PDUs and sending them to MAC. + * + * @param[in] pst Post structure + * @param[in] suId Service User ID + * @param[in] staInd Status Indication Information for Dedicated Logical + * Channels + * + * @return S16 + * -# ROK + * -# RFAILED + * +*/ +#ifdef ANSI +PUBLIC S16 KwLiRguDStaInd +( +Pst *pst, +SuId suId, +RguDStaIndInfo *staInd +) +#else +PUBLIC S16 KwLiRguDStaInd(pst, suId, staInd) +Pst *pst; +SuId suId; +RguDStaIndInfo *staInd; +#endif +{ + KwCb *gCb; + TRC3(KwLiRguDStaInd) + +#if (ERRCLASS & ERRCLS_INT_PAR) + if (pst->dstInst >= KW_MAX_RLC_INSTANCES) + { + KW_SHRABL_STATIC_BUF_FREE(pst->region, pst->pool, staInd, sizeof(RguDStaIndInfo)); + RETVALUE (RFAILED); + } +#endif + + gCb = KW_GET_KWCB(pst->dstInst); + +#if (ERRCLASS & ERRCLS_INT_PAR) + if (((KwCb*)KW_GET_KWCB(pst->dstInst))->genCfg.rlcMode == LKW_RLC_MODE_UL) + { + RLOG_ARG0(L_ERROR,DBG_CELLID,staInd->cellId,"Received in RLC UL "); + KW_SHRABL_STATIC_BUF_FREE(pst->region, pst->pool, staInd, sizeof(RguDStaIndInfo)); + RETVALUE(RFAILED); + } + if ((suId >= gCb->genCfg.maxRguSaps) || (suId < 0)) + { + KWLOGERROR(gCb, + ERRCLS_INT_PAR, + EKW040, + (ErrVal) suId, + "KwLiRguDStaInd: Invalid RGU suId\n"); + RETVALUE(RFAILED); + } +#endif + kwUtlSndToLi(gCb, suId, staInd); + + /* kw002.201 :Freeing from proper region */ + KW_SHRABL_STATIC_BUF_FREE(pst->region, pst->pool, staInd, sizeof(RguDStaIndInfo)); + RETVALUE(ROK); +} /* KwLiRguDStaInd */ + +/** + * @brief Handler for handling the flow cntrl Ind from MAC + * to RLC + * + * @details + * This function receives the flow control indication from + * MAC and calls kwUtlTrigPdbFlowCntrl + * + * @param[in] pst Post structure + * @param[in] suId Service User ID + * @param[in] flowCntrlInd flow control Indication Information + * from MAC + * + * @return S16 + * -# ROK + * -# RFAILED + * +*/ +#ifdef ANSI +PUBLIC S16 KwLiRguFlowCntrlInd +( +Pst *pst, +SuId suId, +RguFlowCntrlInd *flowCntrlInd +) +#else +PUBLIC S16 KwLiRguFlowCntrlInd(pst, suId, flowCntrlInd) +Pst *pst; +SuId suId; +RguFlowCntrlInd *flowCntrlInd; +#endif +{ + KwCb *tKwCb; + KwDlRbCb *rbCb = NULLP; + U32 idx; + U32 lcIdx; + + tKwCb = KW_GET_KWCB(pst->dstInst); + for (idx = 0; idx < flowCntrlInd->numUes; idx++) + { + for (lcIdx = 0; lcIdx < flowCntrlInd->ueFlowCntrlInfo[idx].numLcs; lcIdx++) + { + RguLcFlowCntrlInfo *lcInfo = &(flowCntrlInd->ueFlowCntrlInfo[idx].lcInfo[lcIdx]); + kwDbmFetchDlRbCbFromLchId(tKwCb, flowCntrlInd->ueFlowCntrlInfo[idx].ueId, flowCntrlInd->cellId, lcInfo->lcId, &rbCb); + if (rbCb) + { + + if (lcInfo->pktAdmitCnt == 0) /* Special case */ + { + kwUtlTrigPdbFlowCntrl(tKwCb, rbCb, lcInfo->pktAdmitCnt); + continue; + } + if (rbCb->mode == CM_LTE_MODE_AM) + { + if ((rbCb->m.amDl.retxLst.count != 0) || + ((rbCb->m.amDl.bo == 0) || + (rbCb->m.amDl.bo < lcInfo->maxBo4FlowCtrl))) + { + continue; + } + } + else /* UM */ + { + if ((rbCb->m.umDl.bo == 0) || + (rbCb->m.umDl.bo < lcInfo->maxBo4FlowCtrl)) + { + continue; + } + } + kwUtlTrigPdbFlowCntrl(tKwCb, rbCb, lcInfo->pktAdmitCnt); + } + } + } + RETVALUE(ROK); +} +/* kw005.201 added support for L2 Measurement */ +#ifdef LTE_L2_MEAS + +/** + * + * @brief + * + * Handler for indicating the Harq Status of the data sent. + * + * @b Description: + * + * This function receives the harq status of the data sent to MAC. + * This information is used for two things. + * 1. Computing the UuLoss of UM + * 2. Computing the DL Delay for UM and AM. + * + * @param[in] pst - Post structure + * @param[in] suId - Service User ID + * @param[in] staInd - Harq Status Indication Information. + * + * @return S16 + * -# ROK + * -# RFAILED + * + */ +#ifdef ANSI +PUBLIC S16 KwLiRguHqStaInd +( +Pst *pst, +SuId suId, +RguHarqStatusInd *staInd +) +#else +PUBLIC S16 KwLiRguHqStaInd(pst,suId,staInd) +Pst *pst; +SuId suId; +RguHarqStatusInd *staInd; +#endif +{ + + KwUeKey ueKey; + S16 ret; + KwDlUeCb *ueCb; + U8 tbIdx; + KwCb *tKwCb; + + TRC3(KwLiRguHqStaInd) + + tKwCb = KW_GET_KWCB(pst->dstInst); + ueKey.cellId = staInd->cellId; + ueKey.ueId = staInd->ueId; + + ret = kwDbmFetchDlUeCb(tKwCb, ueKey.ueId, ueKey.cellId, &ueCb); + if (ret != ROK ) + { + RETVALUE(RFAILED); + } + + /*Call kwUtlProcHarqInd as many times as number of Tbs present*/ + for ( tbIdx = 0; tbIdx < staInd->numTbs; tbIdx++) + { + kwUtlProcHarqInd(tKwCb, staInd, ueCb, tbIdx); + } + + RETVALUE(ROK); +} /* KwLiRguHqStaInd */ +#endif /* LTE_L2_MEAS */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +/********************************************************************30** + End of file +**********************************************************************/ diff --git a/src/5gnrrlc/kw_lmm.c b/src/5gnrrlc/kw_lmm.c new file mode 100755 index 000000000..e0750210f --- /dev/null +++ b/src/5gnrrlc/kw_lmm.c @@ -0,0 +1,2634 @@ +/******************************************************************************* +################################################################################ +# Copyright (c) [2017-2019] [Radisys] # +# # +# 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. # +################################################################################ +*******************************************************************************/ + +/********************************************************************20** + + Name: LTE - RLC - Layer Manager file + + Type: C source file + + Desc: It contains the following common functions for processing + the all the external interfaces. + -- KwMiLkwCfgReq + -- KwMiLkwCfgCfm + -- KwMiLkwCntrlReq + -- KwMiLkwCntrlCfm + -- KwMiLkwStaReq + -- KwMiLkwStaCfm + -- KwMiLkwStaInd + -- KwMiLkwStsReq + -- KwMiLkwStsCfm + -- KwMiLkwTrcInd + + File: kw_lmm.c + +*********************************************************************21*/ +static const char* RLOG_MODULE_NAME="LMM"; +static int RLOG_MODULE_ID=2048; +static int RLOG_FILE_ID=197; +/** @file kw_lmm.c +@brief RLC Layer Manager Module +**/ + + +/* header (.h) include files */ +#include "envopt.h" /* environment options */ +#include "envdep.h" /* environment dependent */ +#include "envind.h" /* environment independent */ + +#include "gen.h" /* general */ +#include "ssi.h" /* system services */ +#include "cm5.h" /* common timer defines */ +#include "cm_tkns.h" /* common tokens defines */ +#include "cm_mblk.h" /* common memory allocation library defines */ +#include "cm_llist.h" /* common link list defines */ +#include "cm_hash.h" /* common hash list defines */ +#include "cm_lte.h" /* common LTE defines */ +#include "lkw.h" /* LKW defines */ +#include "ckw.h" /* CKW defines */ +#include "kwu.h" /* KWU defines */ +#include "rgu.h" /* RGU defines */ +#include "kw_err.h" /* Err defines */ +#include "kw_env.h" /* RLC environment options */ + +#include "kw.h" /* RLC defines */ +#include "kw_dl.h" +#include "kw_ul.h" +#include "kw_udx.h" + +/* extern (.x) include files */ +#include "gen.x" /* general */ +#include "ssi.x" /* system services */ + +#include "cm5.x" /* common timer library */ +#include "cm_tkns.x" /* common tokens */ +#include "cm_mblk.x" /* common memory allocation */ +#include "cm_llist.x" /* common link list */ +#include "cm_hash.x" /* common hash list */ +#include "cm_lte.x" /* common LTE includes */ +#include "cm_lib.x" /* common memory allocation library */ +#include "lkw.x" /* LKW */ +#include "ckw.x" /* CKW */ +#include "kwu.x" /* KWU */ +#include "rgu.x" /* RGU */ + +#include "kw.x" +#include "kw_udx.x" +#include "kw_dl.x" +#include "kw_ul.x" + +#define KW_MODULE KW_DBGMASK_LMM + +RLCStats gRlcStats; + +/********************************************************************* + * Forward Declaration of LKW Porting Functions + ********************************************************************/ +PUBLIC KwCb *kwCb[KW_MAX_RLC_INSTANCES]; +EXTERN S16 kwActvTmr ARGS ((Ent ent, Inst inst)); + +PRIVATE Void kwLmmSendCfm ARGS ((KwCb *gCb,Pst *pst,KwMngmt *cfm,U8 type, + Header *hdr)); +PRIVATE S16 kwLmmGenCfg ARGS ((KwCb *gCb, KwGenCfg *cfg)); +PRIVATE S16 kwLmmCfgKwuSap ARGS ((KwCb *gCb,KwSapCfg *cfg)); +PRIVATE S16 kwLmmCfgUdxSap ARGS ((KwCb *gCb,KwSapCfg *cfg)); +PRIVATE S16 kwLmmCfgCkwSap ARGS ((KwCb *gCb,KwSapCfg *cfg)); +PRIVATE S16 kwLmmCfgRguSap ARGS ((KwCb *gCb,KwSapCfg *cfg)); +PRIVATE S16 kwLmmGenCntrl ARGS ((KwCb *gCb,KwMngmt *cntrl)); +PRIVATE S16 kwLmmUdxSapCntrl ARGS ((KwCb *gCb,KwMngmt *cntrl)); +PRIVATE S16 kwLmmLSapCntrl ARGS ((KwCb *gCb,KwMngmt *cntrl)); +PRIVATE S16 kwLmmGetKwuSapSta ARGS ((KwCb *gCb,KwKwuSapSta *sta)); +PRIVATE S16 kwLmmGetRguSapSta ARGS ((KwCb *gCb,KwRguSapSta *sta)); +PRIVATE S16 kwLmmGetCkwCntSapSta ARGS ((KwCb *gCb,KwCkwCntSapSta *sta)); +PRIVATE S16 kwLmmGetGenSts ARGS ((KwCb *gCb,KwGenSts *sts,Action action)); +PRIVATE S16 kwLmmGetSapSts ARGS ((KwCb *gCb,KwMngmt *sts,Elmnt elmnt,Action + action)); + + +/********************************************************************* + * Primitives for RGU interface + ********************************************************************/ +/** + * @brief + * Stores the general RLC configuration. + * @details + * It calculates the memory requirement of the Saps + * It also initializes the control blocks, the hash lists and registers + * the timers. In case of error it rolls back and reports error in the + * confirm.If the general configuration is already done it is treated as + * reconfiguration, but right now reconfiguration is not supported. + * + * @param[in] gCb RLC Instance Control Block + * @param[in] cfm RLC LM general config structure + * + * @return S16 + * LCM_REASON_NOT_APPL (SUCCESS) + * LCM_REASON_MEM_NOAVAIL + * LCM_REASON_REGTMR_FAIL + * LCM_REASON_INVALID_PAR_VAL + * LCM_REASON_HASHING_FAILED + */ +#ifdef ANSI +PRIVATE S16 kwLmmGenCfg +( +KwCb *gCb, +KwGenCfg *cfg +) +#else +PRIVATE S16 kwLmmGenCfg(gCB,cfg) +KwCb *gCb; +KwGenCfg *cfg; +#endif +{ + Size kwSapSize; + Size kwUdxSapSize; + S16 ret; + CmTqCp *kwTqCp; + Size rguSapSize; + + TRC2(kwLmmGenCfg) + + if(cfg->maxUe > KW_MAX_UE) + { +#if (ERRCLASS & ERRCLS_INT_PAR) + RLOG2(L_ERROR, "Invalid maxUe : Max [%lu] Received [%lu]", + KW_MAX_UE, + cfg->maxUe); +#endif /* ERRCLASS & ERRCLS_INT_PAR */ + RETVALUE(LCM_REASON_INVALID_PAR_VAL); + } + + if(cfg->maxKwuSaps > KW_MAX_KWUSAPS) + { +#if (ERRCLASS & ERRCLS_INT_PAR) + RLOG2(L_ERROR, "Invalid maxKwuSaps : Max [%lu] Received [%lu]", + KW_MAX_KWUSAPS, + cfg->maxKwuSaps); +#endif /* ERRCLASS & ERRCLS_INT_PAR */ + RETVALUE(LCM_REASON_INVALID_PAR_VAL); + } + + if(cfg->maxUdxSaps > KW_MAX_UDXSAPS) + { +#if (ERRCLASS & ERRCLS_INT_PAR) + RLOG2(L_ERROR, "Invalid maxUduSaps : Max [%lu] Received [%lu]", + KW_MAX_UDXSAPS, + cfg->maxUdxSaps); +#endif /* ERRCLASS & ERRCLS_INT_PAR */ + RETVALUE(LCM_REASON_INVALID_PAR_VAL); + } + + if((cfg->maxRguSaps == 0) || (cfg->maxRguSaps > KW_MAX_RGUSAPS)) + { + + + RETVALUE(LCM_REASON_INVALID_PAR_VAL); + } + if(gCb->init.cfgDone == TRUE) + { + /* reconfiguration not supported */ + RETVALUE(LCM_REASON_RECONFIG_FAIL); + } + + gCb->genCfg = *cfg; + + /* Timer Queue Control point initialization */ + kwTqCp = &(gCb->kwTqCp); + kwTqCp->tmrLen = KW_TMR_LEN; + kwTqCp->nxtEnt = 0; + + if(gCb->genCfg.rlcMode == LKW_RLC_MODE_DL) + { + KW_ALLOC(gCb,gCb->u.dlCb, sizeof (KwDlCb)); + if (gCb->u.dlCb == NULLP) + { + RLOG0(L_FATAL,"Memory Allocation failed"); + RETVALUE(LCM_REASON_MEM_NOAVAIL); + + } + /* allocate memory to the KWU sap's */ + kwSapSize = (Size)((Size) gCb->genCfg.maxKwuSaps * + (Size)sizeof(KwKwuSapCb)); + + KW_ALLOC(gCb,gCb->u.dlCb->kwuDlSap, kwSapSize); + +#if (ERRCLASS & ERRCLS_INT_PAR) + if(gCb->u.dlCb->kwuDlSap == NULLP) + { + KW_FREE(gCb,gCb->u.dlCb, sizeof (KwDlCb)); + RLOG0(L_FATAL,"Memory Allocation failed"); + RETVALUE(LCM_REASON_MEM_NOAVAIL); + } +#endif /* ERRCLASS & ERRCLS_INT_PAR */ + + gCb->u.dlCb->numKwuSaps = gCb->genCfg.maxKwuSaps; + + kwUdxSapSize = (Size)((Size) gCb->genCfg.maxUdxSaps * + (Size)sizeof(KwUdxDlSapCb)); + + KW_ALLOC(gCb,gCb->u.dlCb->udxDlSap, kwUdxSapSize); +#if (ERRCLASS & ERRCLS_INT_PAR) + if(gCb->u.dlCb->udxDlSap == NULLP) + { + KW_FREE(gCb,gCb->u.dlCb->kwuDlSap, kwSapSize); + KW_FREE(gCb,gCb->u.dlCb, sizeof (KwDlCb)); + RLOG0(L_FATAL,"Memory Allocation failed"); + RETVALUE(LCM_REASON_MEM_NOAVAIL); + } +#endif /* ERRCLASS & ERRCLS_INT_PAR */ + + rguSapSize = (Size)((Size) gCb->genCfg.maxRguSaps * + (Size)sizeof(KwRguSapCb)); + KW_ALLOC(gCb,gCb->u.dlCb->rguDlSap, rguSapSize); +#if (ERRCLASS & ERRCLS_INT_PAR) + if(gCb->u.dlCb->rguDlSap == NULLP) + { + KW_FREE(gCb,gCb->u.dlCb->udxDlSap, kwSapSize); + KW_FREE(gCb,gCb->u.dlCb->kwuDlSap, kwSapSize); + KW_FREE(gCb,gCb->u.dlCb, sizeof (KwDlCb)); + + KWLOGERROR(gCb,ERRCLS_INT_PAR, EKW043, (ErrVal) cfg->maxUe, + "kwLmmGenCfg: SgetSBuf Failed for rguSap...!"); + RETVALUE(LCM_REASON_MEM_NOAVAIL); + } +#endif /* ERRCLASS & ERRCLS_INT_PAR */ + + + /* Initialize the Ue and Cell hash list */ + ret = kwDbmDlInit(gCb); + if (ret != ROK) + { + KW_FREE(gCb,gCb->u.dlCb->udxDlSap, kwSapSize); + KW_FREE(gCb,gCb->u.dlCb->kwuDlSap, kwSapSize); + KW_FREE(gCb,gCb->u.dlCb->rguDlSap, rguSapSize); + KW_FREE(gCb,gCb->u.dlCb, sizeof (KwDlCb)); + RLOG0(L_FATAL,"RLC DL Initialization failed"); + RETVALUE(LCM_REASON_MEM_NOAVAIL); + } + /* Register the timer */ +/*Pradeep: changing the SRegTmrMt() to SRegTmr()*/ + if(SRegTmrMt(gCb->init.ent, gCb->init.inst, (U16)cfg->timeRes, + kwActvTmr) != ROK) + { + KW_FREE(gCb,gCb->u.dlCb->udxDlSap, kwUdxSapSize); + KW_FREE(gCb,gCb->u.dlCb->kwuDlSap, kwSapSize); + KW_FREE(gCb,gCb->u.dlCb->rguDlSap, rguSapSize); + KW_FREE(gCb,gCb->u.dlCb, sizeof (KwDlCb)); + + RETVALUE(LCM_REASON_REGTMR_FAIL); + } + + /* initializations for background processing of freeing memory */ + kwUtlInitToBeFreed(gCb, &(gCb->u.dlCb->toBeFreed)); + kwUtlInitializeSelfPst(gCb); + + if(SGetMsg(gCb->init.region, + gCb->init.pool, + &(gCb->u.dlCb->selfPstMBuf)) != ROK) + { + KW_FREE(gCb,gCb->u.dlCb->udxDlSap, kwSapSize); + KW_FREE(gCb,gCb->u.dlCb->kwuDlSap, kwSapSize); + KW_FREE(gCb,gCb->u.dlCb->rguDlSap, rguSapSize); + KW_FREE(gCb,gCb->u.dlCb, sizeof (KwDlCb)); + + RETVALUE(LCM_REASON_MEM_NOAVAIL); + + } +#ifdef LTE_L2_MEAS + kwUtlL2MeasDlInit(gCb); +#endif + } + else if(gCb->genCfg.rlcMode == LKW_RLC_MODE_UL) + { + KW_ALLOC(gCb,gCb->u.ulCb, sizeof (KwUlCb)); + if (gCb->u.ulCb == NULLP) + { + RLOG0(L_FATAL,"Memory Allocation failed"); + RETVALUE(LCM_REASON_MEM_NOAVAIL); + + } + /* allocate memory to the KWU sap's */ + kwSapSize = (Size)((Size) gCb->genCfg.maxKwuSaps * + (Size)sizeof(KwKwuSapCb)); + + KW_ALLOC(gCb,gCb->u.ulCb->kwuUlSap, kwSapSize); + +#if (ERRCLASS & ERRCLS_INT_PAR) + if(gCb->u.ulCb->kwuUlSap == NULLP) + { + KW_FREE(gCb,gCb->u.ulCb, sizeof (KwUlCb)); + RLOG0(L_FATAL,"Memory Allocation failed"); + RETVALUE(LCM_REASON_MEM_NOAVAIL); + } +#endif /* ERRCLASS & ERRCLS_INT_PAR */ + + gCb->u.ulCb->numKwuSaps = gCb->genCfg.maxKwuSaps; + + /* allocate memory to the KWU sap's */ + kwUdxSapSize = (Size)((Size) gCb->genCfg.maxUdxSaps * + (Size)sizeof(KwUdxUlSapCb)); + + KW_ALLOC(gCb,gCb->u.ulCb->udxUlSap, kwUdxSapSize); + +#if (ERRCLASS & ERRCLS_INT_PAR) + if(gCb->u.ulCb->kwuUlSap == NULLP) + { + KW_FREE(gCb,gCb->u.ulCb->kwuUlSap, kwSapSize); + KW_FREE(gCb,gCb->u.ulCb, sizeof (KwUlCb)); + RLOG0(L_FATAL,"Memory Allocation failed"); + RETVALUE(LCM_REASON_MEM_NOAVAIL); + } +#endif /* ERRCLASS & ERRCLS_INT_PAR */ + + rguSapSize = (Size)((Size) gCb->genCfg.maxRguSaps * + (Size)sizeof(KwRguSapCb)); + KW_ALLOC(gCb,gCb->u.ulCb->rguUlSap, rguSapSize); +#if (ERRCLASS & ERRCLS_INT_PAR) + if(gCb->u.ulCb->rguUlSap == NULLP) + { + KW_FREE(gCb,gCb->u.ulCb->kwuUlSap, kwSapSize); + KW_FREE(gCb,gCb->u.ulCb->rguUlSap, kwSapSize); + KW_FREE(gCb,gCb->u.ulCb, sizeof (KwUlCb)); + + KWLOGERROR(gCb,ERRCLS_INT_PAR, EKW043, (ErrVal) cfg->maxUe, + "kwLmmGenCfg: SgetSBuf Failed for rguSap...!"); + RETVALUE(LCM_REASON_MEM_NOAVAIL); + } +#endif /* ERRCLASS & ERRCLS_INT_PAR */ + + /* Initialize the Ue and Cell hash list */ + ret = kwDbmUlInit(gCb); + if (ret != ROK) + { + KW_FREE(gCb,gCb->u.ulCb->udxUlSap, kwUdxSapSize); + KW_FREE(gCb,gCb->u.ulCb->kwuUlSap, kwSapSize); + KW_FREE(gCb,gCb->u.ulCb->rguUlSap, kwSapSize); + KW_FREE(gCb,gCb->u.ulCb, sizeof (KwUlCb)); + RLOG0(L_FATAL,"RLC DL Initialization failed"); + } + + /* Register the timer */ + + if(SRegTmrMt(gCb->init.ent, gCb->init.inst, (U16)cfg->timeRes, + kwActvTmr) != ROK) + { + KW_FREE(gCb,gCb->u.ulCb->udxUlSap, kwUdxSapSize); + KW_FREE(gCb,gCb->u.ulCb->kwuUlSap, kwSapSize); + KW_FREE(gCb,gCb->u.ulCb->rguUlSap, kwSapSize); + KW_FREE(gCb,gCb->u.ulCb, sizeof (KwUlCb)); + + RETVALUE(LCM_REASON_REGTMR_FAIL); + } +#ifdef LTE_L2_MEAS + kwUtlL2MeasUlInit(gCb); +#endif + } + else + { +#if (ERRCLASS & ERRCLS_INT_PAR) + RLOG0(L_ERROR, "Received Invalid RLC Mode"); +#endif /* ERRCLASS & ERRCLS_INT_PAR */ + + RETVALUE(LCM_REASON_INVALID_PAR_VAL); + } + /* Timer Initialization */ + gCb->kwTqCp.tmrLen = KW_TMR_LEN; + + cmMemset((U8*)gCb->kwTq, NULLP, sizeof(CmTqType) * KW_TMR_LEN); + + KW_MEM_CPY(&(gCb->init.lmPst), &cfg->lmPst, sizeof(Pst)); + + gCb->init.lmPst.srcProcId = gCb->init.procId; + gCb->init.lmPst.srcEnt = gCb->init.ent; + gCb->init.lmPst.srcInst = gCb->init.inst; + gCb->init.lmPst.event = EVTNONE; + + /* kw002.201 For multi core and multi region,no need to reinitiailize the + * region again . This would be done with kwActvInit from SSI */ +#if !defined(SS_MULTICORE_SUPPORT) && !defined(SS_M_PROTO_REGION) + gCb->init.region = cfg->lmPst.region; +#endif /* !defined(SS_MULTICORE_SUPPORT) && !defined(SS_M_PROTO_REGION) */ + gCb->init.pool = cfg->lmPst.pool; + + gCb->init.cfgDone = TRUE; + + RETVALUE(LCM_REASON_NOT_APPL); +} + +/** + * @brief + * Sends confirmation message to LM Called by KwMiLkwCfgReq function + * + * @param[in] gCb RLC Instance Control Block + * @param[in] pst Post structure + * @param[in] cfm RLC LM structure + * @param[in] type Type of LM message + * @param[in] hdr Message header + * + * @return S16 + * -# ROK + */ +#ifdef ANSI +PRIVATE Void kwLmmSendCfm +( +KwCb *gCb, +Pst *pst, +KwMngmt *cfm, +U8 type, +Header *hdr +) +#else +PRIVATE Void kwLmmSendCfm(gCb,pst, cfm, type, hdr) +KwCb gCb; +Pst *pst; +KwMngmt *cfm; +U8 type; +Header *hdr; +#endif +{ + Pst rPst; /* Reply post structure */ + + TRC2(kwLmmSendCfm); + + KW_MEM_SET(&rPst, 0, sizeof(Pst)); + + /* reply post structure for confirmation */ + if (gCb) + { + rPst.srcEnt = gCb->init.ent; + rPst.srcInst = gCb->init.inst; + cfm->hdr.entId.ent = gCb->init.ent; + cfm->hdr.entId.inst = gCb->init.inst; + } + else + { + rPst.srcEnt = pst->dstEnt; + rPst.srcInst = pst->dstInst; + cfm->hdr.entId.ent = pst->dstEnt; + cfm->hdr.entId.inst = pst->dstInst; + } + rPst.srcProcId = SFndProcId(); + rPst.dstEnt = pst->srcEnt; + rPst.dstInst = pst->srcInst; + rPst.dstProcId = pst->srcProcId; + rPst.selector = hdr->response.selector; + rPst.prior = hdr->response.prior; + rPst.route = hdr->response.route; + rPst.region = hdr->response.mem.region; + rPst.pool= hdr->response.mem.pool; + + /* Fill the reply header */ + cfm->hdr.elmId.elmnt = hdr->elmId.elmnt; + cfm->hdr.transId = hdr->transId; + + switch(type) + { + case TCFG: + KwMiLkwCfgCfm(&rPst,cfm); + break; + case TCNTRL: + SGetDateTime(&(cfm->t.cntrl.dt)); + KwMiLkwCntrlCfm(&rPst,cfm); + break; + case TSTS: + SGetDateTime(&(cfm->t.sts.dt)); + KwMiLkwStsCfm(&rPst,0,cfm); + break; + case TSSTA: + SGetDateTime(&(cfm->t.ssta.dt)); + KwMiLkwStaCfm(&rPst,cfm); + break; + default: +#if (ERRCLASS & ERRCLS_INT_PAR) + RLOG0(L_ERROR, "Received Invalid Message Type"); + if(!gCb) + { + fflush(stdout); + } +#endif /* ERRCLASS & ERRCLS_INT_PAR */ + break; + } + + RETVOID; +} + + +/** + * @brief + * This function processes configuration requests received from the layer + * manager. + * + * @details + * The configuration requests can be for general configuration, or + * configuration of RGU, KWU, and CKW SAPs. The type of the configuration + * request can be determined from the elmId field in the header of the layer + * manager message.This function is called by the layer manager to configure + * RLC. + * + * This function implements the following logic: + * + * - if genCfg is not done, send negative Cfm to the layer manager; + * + * - switch (cfg->hdr.elmId.elmnt) + * - case STGEN + * - update the genCfg field in RlCb; + * - allocate the maximum static memory required by the RLC product; + * - register the timer service by calling SReqTmr; + * - set CfgDone for not configuring again; + * - case STKWUSAP + * - if all the parameters are valid, then allocate the KwuSap control + * block; + * - update the SAP control block with the information provided in the + * - configuration request; + * - send configuration confirm with the status, success; + * - case STCKWSAP + * - if all the parametes are valid, then allocate the CkwSap control + * block; + * - update the SAP control block with the information provided in the + * configuration request; + * - send configuration confirm with the status, success; + * - case STRGUSAP + * - if all the parametes are valid, then allocate the rguSap control + * block; + * - update the SAP control block with the information provided in the + * configuration request; + * - send configuration confirm with the status, success; + * - case STUDXSAP + * - if all the parametes are valid, then allocate the udxSap control + * block; + * - update the SAP control block with the information provided in the + * configuration request; + * - send configuration confirm with the status, success; + * - end switch; + * + * @param[in] pst post structure + * @param[in] cfg LM management structure + * + * @return S16 + * -# Success : ROK + * -# Failure : RFAILED + */ + +#ifdef ANSI +PUBLIC S16 KwMiLkwCfgReq +( +Pst *pst, +KwMngmt *cfg +) +#else +PUBLIC S16 KwMiLkwCfgReq (pst, cfg) +Pst *pst; +KwMngmt *cfg; +#endif +{ + Reason reason; /* failure reason */ + KwCb *tKwCb=NULLP; + + TRC3(KwMiLkwCfgReq); + +#if (ERRCLASS & ERRCLS_INT_PAR) + /* Check if the instance is configured */ + if (pst->dstInst >= KW_MAX_RLC_INSTANCES) + { + cfg->cfm.status = LCM_PRIM_NOK; + cfg->cfm.reason = LCM_REASON_INVALID_INSTANCE; + kwLmmSendCfm(tKwCb,pst, cfg, TCFG, &cfg->hdr); + RETVALUE(RFAILED); + } +#endif + + tKwCb = KW_GET_KWCB(pst->dstInst); + + if (!tKwCb) + { + cfg->cfm.status = LCM_PRIM_NOK; + cfg->cfm.reason = LCM_REASON_GENCFG_NOT_DONE; + kwLmmSendCfm(tKwCb,pst, cfg, TCFG, &cfg->hdr); + RETVALUE(RFAILED); + } + /* check configuration is done or not */ + if ((tKwCb->init.cfgDone != TRUE) && + (cfg->hdr.elmId.elmnt != STGEN)) + { + /* + * if general config is not over then use pst structure + * in primitive to communicate to stack manager + */ + + cfg->cfm.status = LCM_PRIM_NOK; + cfg->cfm.reason = LCM_REASON_GENCFG_NOT_DONE; + kwLmmSendCfm(tKwCb,pst, cfg, TCFG, &cfg->hdr); + RETVALUE(RFAILED); + } + + RLOG1(L_DEBUG, "KwMiLkwCfgReq elmId(%d)", cfg->hdr.elmId.elmnt); + + switch(cfg->hdr.elmId.elmnt) + { + case STGEN: + { + reason = kwLmmGenCfg(tKwCb,&cfg->t.cfg.s.gen); + break; + } + case STKWUSAP: + { + reason = kwLmmCfgKwuSap(tKwCb,&cfg->t.cfg.s.sap); + break; + } + case STCKWSAP: + { + reason = kwLmmCfgCkwSap(tKwCb,&cfg->t.cfg.s.sap); + break; + } + case STRGUSAP: + { + reason = kwLmmCfgRguSap(tKwCb,&cfg->t.cfg.s.sap); + break; + } + case STUDXSAP: + { + reason = kwLmmCfgUdxSap(tKwCb,&cfg->t.cfg.s.sap); + break; + } + default: + { + reason = LCM_REASON_INVALID_ELMNT; + break; + } + } + + if (reason == LCM_REASON_NOT_APPL) + { + cfg->cfm.status = LCM_PRIM_OK; + cfg->cfm.reason = LCM_REASON_NOT_APPL; + kwLmmSendCfm(tKwCb,pst, cfg, TCFG, &cfg->hdr); + RETVALUE(ROK); + } + else + { + cfg->cfm.status = LCM_PRIM_NOK; + cfg->cfm.reason = reason; + kwLmmSendCfm(tKwCb,pst, cfg, TCFG, &cfg->hdr); + RETVALUE(RFAILED); + } +} + +/** + * @brief + * The layer manager initiates and uses the management-control procedure to + * control RLC elements.The RLC control request primitive (KwMiLkwCntrlReq) + * can be called more than once and at any time after the + * management-configuration procedure.The control request primitive + * is confirmed by a KwMiLkwCntrlCfm primitive. + * + * @details + * This function implements the following logic: + * + * - if(cfgDone = FALSE) + * - send negative confirmation to the layer manager; + * - return; + * - else + * - switch(cntrl->hdr.elmId.elmnt) + * - case STGEN + * - switch (action) + * - case AENA + * - switch(subAction) + * - case SAUSTA + * - enable the unsolicited status flag; + * - send the control Cfm with success; + * - case SADBG + * - set the debug mask; + * - send the control Cfm with success; + * - case SATRC + * - enable the trace flag; + * - send the control Cfm with success; + * - case ADISIMM + * - switch(subAction) + * - case SAUSTA + * - disable the unsolicited status flag; + * - send the control Cfm with success; + * - case SATRC + * - disable the trace flag; + * - send the control Cfm with success; + * - case ASHUTDOWN + * - case STRGUSAP + * - Call LSapCntrl + * - case STUDXSAP + * - Call UdxSapCntrl + * - default + * - end else + * + * @param[in] pst post structure + * @param[in] cntrl LM management structure + * + * @return S16 + * -# ROK + * -# RFAILED + */ +#ifdef ANSI +PUBLIC S16 KwMiLkwCntrlReq +( +Pst *pst, +KwMngmt *cntrl +) +#else +PUBLIC S16 KwMiLkwCntrlReq(pst, cntrl) +Pst *pst; +KwMngmt *cntrl; +#endif +{ + Reason reason; /* failure reason */ + KwCb *tKwCb=NULLP; + + TRC3(KwMiLkwCntrlReq) + +#if (ERRCLASS & ERRCLS_INT_PAR) + /* Check if the instance is configured */ + if (pst->dstInst >= KW_MAX_RLC_INSTANCES) + { + cntrl->cfm.status = LCM_PRIM_NOK; + cntrl->cfm.reason = LCM_REASON_INVALID_INSTANCE; + + kwLmmSendCfm(tKwCb,pst, cntrl, TCNTRL, &cntrl->hdr); + RETVALUE(RFAILED); + } +#endif + + tKwCb = KW_GET_KWCB(pst->dstInst); + + if(!tKwCb) + { + cntrl->cfm.status = LCM_PRIM_NOK; + cntrl->cfm.reason = LCM_REASON_GENCFG_NOT_DONE; + kwLmmSendCfm(tKwCb,pst, cntrl, TCNTRL, &cntrl->hdr); + RETVALUE(RFAILED); + } + + if (!(tKwCb->init.cfgDone)) + { + cntrl->cfm.status = LCM_PRIM_NOK; + cntrl->cfm.reason = LCM_REASON_GENCFG_NOT_DONE; + kwLmmSendCfm(tKwCb,pst, cntrl, TCNTRL, &cntrl->hdr); + RETVALUE(RFAILED); + } + RLOG1(L_DEBUG, "KwMiLkwCntrlReq(elmId(%d))", cntrl->hdr.elmId.elmnt); + + /* In normal cases, LCM_REASON_NOT_APPL is returned in cfm. + * In all error cases appropriate reason is returned + * by the functions below + */ + + switch (cntrl->hdr.elmId.elmnt) + { + case STGEN: + { + /* general control */ + reason = kwLmmGenCntrl(tKwCb,cntrl); + break; + } + case STRGUSAP: + { + /* Lower SAP control */ + reason = kwLmmLSapCntrl(tKwCb,cntrl); + break; + } + case STUDXSAP: + { + /* Udx Sap cntrl */ + reason = kwLmmUdxSapCntrl(tKwCb,cntrl); + break; + } + default: + { + reason = LCM_REASON_INVALID_ELMNT; + break; + } + } /* end switch */ + + if (reason == LCM_REASON_NOT_APPL) + { + cntrl->cfm.status = LCM_PRIM_OK; + cntrl->cfm.reason = LCM_REASON_NOT_APPL; + } + else + { + cntrl->cfm.status = LCM_PRIM_NOK; + cntrl->cfm.reason = reason; + } + + kwLmmSendCfm(tKwCb,pst, cntrl, TCNTRL, &cntrl->hdr); + + RETVALUE(ROK); +} + +/** + * @brief + * This function processes solicited status requests received from the layer + * manager. The layer manager can request status information regarding the + * system ID, RGUSAP,KWUSAP, or CKWSAP. + * + * @param[in] pst post structure + * @param[in] sta LM management structure + * @return S16 + * -# ROK (SUCCESS) + * -# RFAILED + */ +#ifdef ANSI +PUBLIC S16 KwMiLkwStaReq +( +Pst *pst, +KwMngmt *sta +) +#else +PUBLIC S16 KwMiLkwStaReq(pst, sta) +Pst *pst; +KwMngmt *sta; +#endif +{ + KwMngmt rSta; /* Status */ + Reason reason; /* Failure reason */ + KwCb *tKwCb=NULLP; + + TRC3(KwMiLkwStaReq); + +#if (ERRCLASS & ERRCLS_INT_PAR) + /* Check if the instance is configured */ + if (pst->dstInst >= KW_MAX_RLC_INSTANCES) + { + sta->cfm.status = LCM_PRIM_NOK; + sta->cfm.reason = LCM_REASON_INVALID_INSTANCE; + + kwLmmSendCfm(tKwCb,pst, sta, TSSTA, &sta->hdr); + RETVALUE(RFAILED); + } +#endif + + tKwCb = KW_GET_KWCB(pst->dstInst); + if (!tKwCb) + { + sta->cfm.status = LCM_PRIM_NOK; + sta->cfm.reason = LCM_REASON_GENCFG_NOT_DONE; + + kwLmmSendCfm(tKwCb,pst, sta, TSSTA, &sta->hdr); + RETVALUE(RFAILED); + } + + RLOG1(L_DEBUG, "Status request for elmId(%d))", sta->hdr.elmId.elmnt); + + reason = LCM_REASON_NOT_APPL; + + KW_MEM_SET(&rSta, 0, sizeof(KwMngmt)); + switch (sta->hdr.elmId.elmnt) + { + case STSID: + { + reason = LCM_REASON_NOT_APPL; + kwGetSId(&rSta.t.ssta.s.sysId); + break; + } + case STKWUSAP: + { + KW_MEM_CPY (&rSta.t.ssta.s.kwuSap, + &sta->t.ssta.s.kwuSap, + sizeof (KwKwuSapSta)); + + reason = kwLmmGetKwuSapSta (tKwCb,&rSta.t.ssta.s.kwuSap); + break; + } + case STRGUSAP: + { + KW_MEM_CPY (&rSta.t.ssta.s.rguSap, + &sta->t.ssta.s.rguSap, + sizeof (KwRguSapSta)); + + reason = kwLmmGetRguSapSta (tKwCb,&rSta.t.ssta.s.rguSap); + break; + } + case STCKWSAP: + { + KW_MEM_CPY (&rSta.t.ssta.s.ckwSap, + &sta->t.ssta.s.ckwSap, + sizeof (KwCkwCntSapSta)); + + reason = kwLmmGetCkwCntSapSta (tKwCb,&rSta.t.ssta.s.ckwSap); + break; + } + default: + { + reason = LCM_REASON_INVALID_ELMNT; + break; + } + } /* end of switch */ + + if (reason == LCM_REASON_NOT_APPL) + { + rSta.cfm.status = LCM_PRIM_OK; + rSta.cfm.reason = LCM_REASON_NOT_APPL; + } + else + { + rSta.cfm.status = LCM_PRIM_NOK; + rSta.cfm.reason = reason; + } + kwLmmSendCfm(tKwCb,pst, &rSta, TSSTA, &sta->hdr); + + RETVALUE(ROK); +} + +/** + * @brief + * This function processes statistics requests received from the layer + * manager. + * + * @details + * After collecting the statistics, ir calls the statistics confirm function + * to send the statistics to the layer manager. + * + * - switch(sts->hdr.elmId.elmnt) + * - case STGEN + * - get the general statistics from the KW control block; + * - if (action = RESET) + * - reset the general statistic field in the RlCb; + * - call KwMiLkwStsCfm to send statistics back to layer manager; + * - case STCKWSAP + * - case STKWUSAP + * - case STRGUSAP + * - get the SAP specific statistics from KW control block; + * - if (action = RESET) + * - reset the general statistic field in the RlCb; + * - call KwMiLkwStsCfm to send statistics to the layer manager; + * -end switch; + * + * @param[in] pst post structure + * @param[in] action action + * @param[in] sts LM management structure + * + * @return S16 + * -# ROK + * -# RFAILED + */ +#ifdef ANSI +PUBLIC S16 KwMiLkwStsReq +( +Pst *pst, +Action action, +KwMngmt *sts +) +#else +PUBLIC S16 KwMiLkwStsReq (pst, action, sts) +Pst *pst; +Action action; +KwMngmt *sts; +#endif +{ + KwMngmt rSts; /* Statistics */ + Reason reason; /* Reason for failure */ + KwCb *tKwCb=NULLP; + + TRC3(KwMiLkwStsReq); + +#if (ERRCLASS & ERRCLS_INT_PAR) + /* Check if the instance is configured */ + if (pst->dstInst >= KW_MAX_RLC_INSTANCES) + { + rSts.cfm.status = LCM_PRIM_NOK; + rSts.cfm.reason = LCM_REASON_INVALID_INSTANCE; + + kwLmmSendCfm(tKwCb,pst, &rSts, TCNTRL, &sts->hdr); + RETVALUE(RFAILED); + } +#endif + + tKwCb = KW_GET_KWCB(pst->dstInst); + if (!tKwCb) + { + rSts.cfm.status = LCM_PRIM_NOK; + rSts.cfm.reason = LCM_REASON_GENCFG_NOT_DONE; + + kwLmmSendCfm(tKwCb,pst, &rSts, TCNTRL, &sts->hdr); + RETVALUE(RFAILED); + } + + RLOG2(L_DEBUG, "KwMiLkwStsReq(elmId(%d),action(%d))", + action, + sts->hdr.elmId.elmnt); + + KW_MEM_SET(&rSts, 0, sizeof(KwMngmt)); + + switch (sts->hdr.elmId.elmnt) + { + case STGEN: + { + reason = kwLmmGetGenSts(tKwCb,&rSts.t.sts.s.gen, action); + break; + } + case STKWUSAP: + case STCKWSAP: + { + if( sts->hdr.elmId.elmnt == STKWUSAP) + { + /* kw005.201, modified the element of kwuSap from suId to spId */ + rSts.t.sts.s.kwuSap.spId = sts->t.sts.s.kwuSap.spId; + } + reason = kwLmmGetSapSts(tKwCb,&rSts, sts->hdr.elmId.elmnt, action); + break; + } + default: + { + reason = LCM_REASON_INVALID_ELMNT; + break; + } + } /* end switch */ + + if (reason == LCM_REASON_NOT_APPL) + { + rSts.cfm.status = LCM_PRIM_OK; + rSts.cfm.reason = LCM_REASON_NOT_APPL; + } + else + { + rSts.cfm.status = LCM_PRIM_NOK; + rSts.cfm.reason = reason; + } + kwLmmSendCfm(tKwCb,pst, &rSts, TSTS, &sts->hdr); + + RETVALUE(ROK); +} + +/* kw005.201 added support for L2 Measurement */ +#ifdef LTE_L2_MEAS +/** +@brief +This function processes L2 Measurement requests received from the layer manager. +The L2 Measurement is start for a time period and after the timer expiry, the +measurement confirm is sent. + +- Accept only one set of measurements. +- Allocate and initialise KwL2MeasEvtCb. +- Validate if the measurement is already in progress. + - Loop through the existing measEvtCb with matching measType + - Check if measurement is running for any qci present in the measReq + - If present, move the qCi to list of invalid qCIs. +- Set KwL2MeasEvtCb.measOn to TRUE for QCIs to be measured. +- For the number of measurements requested. + - For all Ues with RBs matching qCI. + - Add RbCb to the RB linked list. + - Set kwRbCb.measOn to measurement type. + - If Meas type is DL_DELAY + - Update COUNT to startCount. +- Start l2Timer + + * @param[in] pst post structure + * @param[in] action action + * @param[in] cfg LM management structure + * @return S16 + * -# Success : ROK + * -# Failure : RFAILED +*/ +#ifdef ANSI +PUBLIC S16 KwMiLkwL2MeasReq +( +Pst *pst, +KwL2MeasReqEvt *measReqEvt +) +#else +PUBLIC S16 KwMiLkwL2MeasReq (pst, measReqEvt) +Pst *pst; +KwL2MeasReqEvt *measReqEvt; +#endif +{ + S16 ret = ROK; + U16 cntr; + U8 measType; + KwL2MeasCfmEvt measCfmEvt; + + KwCb *tKwCb; + + TRC3(KwMiLkwL2MeasReq); + + tKwCb = KW_GET_KWCB(pst->dstInst); + + /* Initialize measCfmEvt */ + KW_MEM_ZERO(&measCfmEvt, sizeof(KwL2MeasCfmEvt)); + /* validate the received measReqEvt */ + /*LTE_L2_MEAS_PHASE2*/ + if(measReqEvt->measPeriod != 0) + { + /* L2 MEAS AGHOSH */ + if((measReqEvt->measReq.measType & LKW_L2MEAS_DL_IP)|| + (measReqEvt->measReq.measType & LKW_L2MEAS_UL_IP)) + { + ret = kwUtlValidateIpThL2Meas(measReqEvt, &measCfmEvt); + } + + if(ret != ROK) + { +#if (ERRCLASS & ERRCLS_ADD_RES) +#endif /* ERRCLASS & ERRCLS_ADD_RES */ + kwUtlSndUlL2MeasNCfm(tKwCb, measReqEvt, &measCfmEvt); + KW_FREE(tKwCb, measReqEvt, sizeof(KwL2MeasReqEvt)) + RETVALUE(RFAILED); + } + } + + measType = measReqEvt->measReq.measType; + + if((measType != LKW_L2MEAS_DL_IP) && + (measType != LKW_L2MEAS_ACT_UE) && + (measType != LKW_L2MEAS_DL_DISC) && + (measType != LKW_L2MEAS_DL_DELAY) && + (measType != LKW_L2MEAS_UU_LOSS) && + (measType != LKW_L2MEAS_UL_IP))/* || (qci > LKW_MAX_QCI)*/ + { + measCfmEvt.transId = measReqEvt->transId; + measCfmEvt.measType = measType; + measCfmEvt.status.status = LCM_PRIM_NOK; + measCfmEvt.status.reason = LKW_CAUSE_INVALID_MEASTYPE; + kwUtlSndDlL2MeasNCfm(tKwCb, measReqEvt, &measCfmEvt); + KW_FREE(tKwCb, measReqEvt, sizeof(KwL2MeasReqEvt)) + RETVALUE(ROK); + } + + /* for UL IP throughput meas enable for all QCIs */ + if(measType & LKW_L2MEAS_UL_IP) + { + for(cntr = 0; cntr < LKW_MAX_QCI; cntr++) + { + tKwCb->u.ulCb->kwL2Cb.measOn[cntr] |= LKW_L2MEAS_UL_IP; + } + } + + if(measType & + (LKW_L2MEAS_DL_IP | LKW_L2MEAS_DL_DISC | + LKW_L2MEAS_DL_DELAY | LKW_L2MEAS_UU_LOSS)) + { + KwL2MeasReqEvt *measEvt; + Pst *udxPst; + + udxPst = &(KW_GET_UDX_SAP(tKwCb)->pst); + + KW_ALLOC_SHRABL_BUF(udxPst->region, + udxPst->pool, + measEvt, + sizeof(KwL2MeasReqEvt)); + +#if (ERRCLASS & ERRCLS_ADD_RES) /* KW_FIX */ + if(measEvt == NULLP) + { + RLOG0(L_FATAL,"Memory Allocation failed"); + RETVALUE(RFAILED); + } +#endif + cmMemcpy((Void*)measEvt, (Void*)measReqEvt, sizeof(KwL2MeasReqEvt)); + /*Redirect the request to DL task */ + /* NOTE:As of today, there are no cases where the Req will fail at DL + as long as it reached the DL, so we don't wait for a confirmation from + DL to send the confirmation to LM*/ + /* The interface for sending a confirmation back does not exist today; + it needs to be created when the need arises */ + KwUlUdxL2MeasReq(&(KW_GET_UDX_SAP(tKwCb)->pst),measEvt); + } + + /* We need to copy the transId for sending back confirms later */ + for(cntr = 0; cntr < LKW_MAX_L2MEAS; cntr++) + { + KwL2MeasEvtCb* measEvtCb = &(tKwCb->u.ulCb->kwL2Cb.kwL2EvtCb[cntr]); + if(measEvtCb->measCb.measType & measType) + { + measEvtCb->transId= measReqEvt->transId; + } + } + /*KW_FREE(tKwCb, measReqEvt, sizeof(KwL2MeasReqEvt));*/ + + RETVALUE(ret); +} /* KwMiLkwL2MeasReq */ + +/** +@brief +This function processes L2 Measurement stop request received from the layer manager. +After receving this request, RLC stops L2 Measurement + * @param[in] pst post structure + * @param[in] measType meas Type + * @return S16 + * -# Success : ROK + * -# Failure : RFAILED +*/ + +#ifdef ANSI +PUBLIC S16 KwMiLkwL2MeasStopReq +( +Pst *pst, +U8 measType +) +#else +PUBLIC S16 KwMiLkwL2MeasStopReq (pst, measType) +Pst *pst; +U8 measType; +#endif +{ + S16 ret = ROK; + KwL2MeasEvtCb *measEvtCb = NULLP; + + U16 cntr; + U8 status = ROK; + KwCb *tKwCb; + + TRC3(KwMiLkwL2MeasStopReq); + + tKwCb = KW_GET_KWCB(pst->dstInst); + + /* reset the counter values for the measurement that is stopped */ + for(cntr = 0; cntr < LKW_MAX_L2MEAS; cntr++) + { + measEvtCb = &(tKwCb->u.ulCb->kwL2Cb.kwL2EvtCb[cntr]); + if(measEvtCb->measCb.measType & measType) + { + kwUtlResetUlL2MeasInKwRb(tKwCb, &measEvtCb->measCb, measType); + + } + } + + /* for UL IP throughput meas disable for all QCIs */ + if(measType & LKW_L2MEAS_UL_IP) + { + for(cntr = 0; cntr < LKW_MAX_QCI; cntr++) + { + tKwCb->u.ulCb->kwL2Cb.measOn[cntr] &= ~LKW_L2MEAS_UL_IP; + } + } + + if((measType & LKW_L2MEAS_DL_IP) || (measType & LKW_L2MEAS_DL_DISC) + || (measType & LKW_L2MEAS_DL_DELAY)) + { + /*Redirect the request to DL task */ + KwUlUdxL2MeasStopReq(&(KW_GET_UDX_SAP(tKwCb)->pst),measType); + /*RETVALUE(ROK);*/ + } + /*cmMemset((U8*)&measCfmEvt, 0, sizeof(KwL2MeasCfmEvt)); */ + + status = LCM_PRIM_OK; + KwMiLkwL2MeasStopCfm(&tKwCb->genCfg.lmPst, measType,status); + + RETVALUE(ret); +} +/** +@brief +This function processes L2 Measurement Send request received from the layer manager. +After receving this request, RLC sends L2 Measurement + * @param[in] pst post structure + * @param[in] measType meas Type + * @return S16 + * -# Success : ROK + * -# Failure : RFAILED +*/ + +#ifdef ANSI +PUBLIC S16 KwMiLkwL2MeasSendReq +( +Pst *pst, +U8 measType +) +#else +PUBLIC S16 KwMiLkwL2MeasSendReq (pst, measType) +Pst *pst; +U8 measType; +#endif +{ + /*S16 ret = ROK;*/ + KwL2MeasEvtCb *measEvtCb = NULLP; + U16 cntr; + KwCb *tKwCb; + TRC3(KwMiLkwL2MeasSendReq); + + tKwCb = KW_GET_KWCB(pst->dstInst); + + /* In case of addition of any new measType here ,appropriate handling + * has to be done in RLC DL (kwUtlSndDlL2MeasCfm)*/ + if(measType & + (LKW_L2MEAS_DL_DISC | LKW_L2MEAS_DL_DELAY + | LKW_L2MEAS_UU_LOSS| LKW_L2MEAS_DL_IP)) + { + /*Redirect the request to DL task */ + KwUlUdxL2MeasSendReq(&(KW_GET_UDX_SAP(tKwCb)->pst),measType); + /* L2 MEAS AGHOSH */ + /*RETVALUE(ROK);*/ + } + + for(cntr = 0; cntr < LKW_MAX_L2MEAS; cntr++) + { + measEvtCb = &(tKwCb->u.ulCb->kwL2Cb.kwL2EvtCb[cntr]); + /* L2 MEAS AGHOSH */ + if(measEvtCb->measCb.measType & measType) + { + kwUtlHdlL2TmrExp(tKwCb, measEvtCb); + } + } + + RETVALUE(ROK); +} +#endif /* LTE_L2_MEAS */ + +/** + * @brief + * This function configures the RLC data sap + * + * @param[in] gCb RLC Instance Control Block + * @param[in] cfg RLC LM Sap configuration structure + * + * @return S16 + * -# LCM_REASON_NOT_APPL (SUCCESS) + * -# LCM_REASON_INVALID_SAP + * -# LCM_REASON_MEM_NOAVAIL + * -# LCM_REASON_RECONFIG_FAIL + */ +#ifdef ANSI +PRIVATE S16 kwLmmCfgKwuSap +( +KwCb *gCb, +KwSapCfg *cfg +) +#else +PRIVATE S16 kwLmmCfgKwuSap(gCb,cfg) +KwCb *gCb; +KwSapCfg *cfg; +#endif +{ + KwKwuSapCb *kwuSapCb; + TRC2(kwLmmCfgKwuSap) + +#if (ERRCLASS & ERRCLS_INT_PAR) + /* Validate the protocol parameters */ + if((cfg->sapId >= (S16)gCb->genCfg.maxKwuSaps) || (cfg->sapId < 0)) + { + RETVALUE(LCM_REASON_INVALID_PAR_VAL); + } +#endif /* ERRCLASS & ERRCLS_INT_PAR */ + + kwuSapCb = (gCb->genCfg.rlcMode == LKW_RLC_MODE_DL) ? + (KwKwuSapCb*)(gCb->u.dlCb->kwuDlSap + cfg->sapId): + (KwKwuSapCb*)(gCb->u.ulCb->kwuUlSap + cfg->sapId); + +#if (ERRCLASS & ERRCLS_INT_PAR) + /* Check for reconfiguration */ + if (kwuSapCb->state != KW_SAP_NOT_CFG) + { + RLOG2(L_ERROR,"RLC Mode [%d] : Invalid kwuSap State [%d]", + gCb->genCfg.rlcMode, kwuSapCb->state); + /* reconfiguration not allowed */ + RETVALUE(LCM_REASON_RECONFIG_FAIL); + } +#endif /* ERRCLASS & ERRCLS_INT_PAR */ + + /* Fill the parameters */ + KW_FILL_SAP_HELPER(kwuSapCb, cfg, gCb); + + RETVALUE(LCM_REASON_NOT_APPL); +} + +/** + * @brief + * This function configures the RLC control sap + * + * @param[in] gCb RLC Instance Control Block + * @param[in] cfg RLC LM Sap configuration structure + * + * @return S16 + * -# LCM_REASON_NOT_APPL (SUCCESS) + * -# LCM_REASON_INVALID_SAP + * -# LCM_REASON_INVALID_SAP + * -# LCM_REASON_RECONFIG_FAIL + */ +#ifdef ANSI +PRIVATE S16 kwLmmCfgCkwSap +( +KwCb *gCb, +KwSapCfg *cfg +) +#else +PRIVATE S16 kwLmmCfgCkwSap(gCb,cfg) +KwCb *gCb; +KwSapCfg *cfg; +#endif +{ + KwCkwSapCb *ckwSap; + + TRC2(kwLmmCfgCkwSap) + +#if (ERRCLASS & ERRCLS_INT_PAR) + /* Validate config parameters */ + if ((cfg->sapId >= KW_MAX_CKWSAPS) || (cfg->sapId < 0) ) + { + RETVALUE(LCM_REASON_INVALID_PAR_VAL); + } + + if (gCb->genCfg.rlcMode == LKW_RLC_MODE_DL) + { + /* Get Sap control block */ + RETVALUE(LCM_REASON_INVALID_PAR_VAL); + } +#endif + + ckwSap = &(gCb->u.ulCb->ckwSap); + +#if (ERRCLASS & ERRCLS_INT_PAR) + /* Check for reconfiguration */ + if(ckwSap->state != KW_SAP_NOT_CFG) + { + RLOG1(L_ERROR,"Invalid kwuSap State [%d]",ckwSap->state); + RETVALUE(LCM_REASON_RECONFIG_FAIL); + } +#endif /* ERRCLASS & ERRCLS_INT_PAR */ + + /* Fill the parameters */ + KW_FILL_SAP_HELPER(ckwSap, cfg, gCb); + + RETVALUE(LCM_REASON_NOT_APPL); +} + +/** + * @brief + * This function configures the UDX sap + * + * @param[in] gCb RLC Instance Control Block + * @param[in] cfg RLC LM Sap configuration structure + * + * @return S16 + * -# LCM_REASON_NOT_APPL (SUCCESS) + * -# LCM_REASON_INVALID_SAP + * -# LCM_REASON_INVALID_SAP + * -# LCM_REASON_RECONFIG_FAIL + */ +#ifdef ANSI +PRIVATE S16 kwLmmCfgUdxSap +( +KwCb *gCb, +KwSapCfg *cfg +) +#else +PRIVATE S16 kwLmmCfgUdxSap(gCb,cfg) +KwCb *gCb; +KwSapCfg *cfg; +#endif +{ + KwUdxDlSapCb *udxDlSap; + KwUdxUlSapCb *udxUlSap; + + TRC2(kwLmmCfgUdxSap); + +#if (ERRCLASS & ERRCLS_INT_PAR) + /* Validate the protocol parameters */ + if((cfg->sapId >= KW_MAX_UDXSAPS) || (cfg->sapId < 0)) + { + RETVALUE(LCM_REASON_INVALID_PAR_VAL); + } +#endif + /* Get Sap control block */ + if (gCb->genCfg.rlcMode == LKW_RLC_MODE_DL) + { + udxDlSap = (gCb->u.dlCb->udxDlSap + cfg->sapId); +#if (ERRCLASS & ERRCLS_INT_PAR) + /* Check for reconfiguration */ + if(udxDlSap->state != KW_SAP_NOT_CFG) + { + RLOG1(L_ERROR,"Invalid udxDlSap State [%d]",udxDlSap->state); + RETVALUE(LCM_REASON_RECONFIG_FAIL); + } +#endif /* ERRCLASS & ERRCLS_INT_PAR */ + + /* Fill the parameters */ + KW_FILL_SAP_HELPER(udxDlSap, cfg, gCb); + } + else + { + udxUlSap = (gCb->u.ulCb->udxUlSap + cfg->sapId); + +#if (ERRCLASS & ERRCLS_INT_PAR) + /* Check for reconfiguration */ + if(udxUlSap->state != KW_SAP_NOT_CFG) + { + RLOG1(L_ERROR,"Invalid udxUlSap State [%d]", udxUlSap->state); + RETVALUE(LCM_REASON_RECONFIG_FAIL); + } +#endif /* ERRCLASS & ERRCLS_INT_PAR */ + + /* Fill the parameters */ + KW_FILL_SAP_HELPER(udxUlSap, cfg, gCb); + + udxUlSap->bndTmrInt = cfg->bndTmrIntvl; + udxUlSap->retryCnt = 0; + cmInitTimers(&(udxUlSap->bndTmr), 1); + } + + RETVALUE(LCM_REASON_NOT_APPL); +} + +/** + * @brief + * This function configures the RGU sap + * + * @param[in] gCb RLC Instance Control Block + * @param[in] cfg RLC LM Sap configuration structure + * @return S16 + * -# LCM_REASON_NOT_APPL (SUCCESS) + * -# LCM_REASON_INVALID_SAP + * -# LCM_REASON_INVALID_SAP + * -# LCM_REASON_RECONFIG_FAIL + */ +#ifdef ANSI +PRIVATE S16 kwLmmCfgRguSap +( +KwCb *gCb, +KwSapCfg *cfg +) +#else +PRIVATE S16 kwLmmCfgRguSap(gCb,cfg) +KwCb *gCb; +KwSapCfg *cfg; +#endif +{ + KwRguSapCb *rguSap; + + TRC2(kwLmmCfgRguSap); + +#if (ERRCLASS & ERRCLS_INT_PAR) + /* Validate the protocol parameters */ + if((cfg->sapId >= gCb->genCfg.maxRguSaps) || \ + (cfg->sapId < 0)) + { + KWLOGERROR(gCb,ERRCLS_INT_PAR, EKW047, (ErrVal)cfg->sapId, + "kwLmmCfgRguSap: Invalid RGU sapId\n"); + RETVALUE(LCM_REASON_INVALID_PAR_VAL); + } +#endif + + rguSap = (gCb->genCfg.rlcMode == LKW_RLC_MODE_DL) ? + &(gCb->u.dlCb->rguDlSap[cfg->sapId]): &(gCb->u.ulCb->rguUlSap[cfg->sapId]); + +#if (ERRCLASS & ERRCLS_INT_PAR) + /* Check for reconfiguration */ + if(rguSap->state != KW_SAP_NOT_CFG) + { + RLOG2(L_ERROR,"RLC Mode [%d]: Invalid rguSap State [%d]", + gCb->genCfg.rlcMode, rguSap->state); + RETVALUE(LCM_REASON_RECONFIG_FAIL); + } +#endif /* ERRCLASS & ERRCLS_INT_PAR */ + + /* Fill the parameters */ + KW_FILL_SAP_HELPER(rguSap, cfg, gCb); + rguSap->suId = cfg->sapId; + rguSap->bndTmrInt = cfg->bndTmrIntvl; + rguSap->retryCnt = 0; + rguSap->state = KW_SAP_CFG; + + cmInitTimers(&(rguSap->bndTmr), 1); + + RETVALUE(LCM_REASON_NOT_APPL); +} + +/** + * @brief + * Validates the RLC general control parameters + * + * @param[in] cntrl RLC LM structure + * + * @return S16 + * -# LCM_REASON_NOT_APPL (SUCCESS) + * -# LCM_REASON_INVALID_SUBACTION + * -# LCM_REASON_INVALID_ACTION + */ +#ifdef ANSI +PRIVATE S16 kwLmmValidateGenCntrl +( +KwMngmt *cntrl +) +#else +PRIVATE S16 kwLmmValidateGenCntrl(cntrl) +KwMngmt *cntrl; +#endif +{ + S16 reason; /* reason for failure */ + U8 sAction; /* subaction field */ + + TRC2(kwLmmValidateGenCntrl); + + reason = LCM_REASON_NOT_APPL; + sAction = cntrl->t.cntrl.subAction; + + switch (cntrl->t.cntrl.action) + { + case AENA: + case ADISIMM: + if ((sAction != SAUSTA) && + (sAction != SADBG) && + (sAction != SATRC)) + { + reason = LCM_REASON_INVALID_SUBACTION; + } + break; + case ASHUTDOWN: + break; + default: + reason = LCM_REASON_INVALID_ACTION; + break; + } + + RETVALUE(reason); +} + +/** + * @brief + * it deregisters the timers and deregisters the kwuSap Control blocks + * + * @param[in] gCb RLC Instance Control Block + * + * @return Void + */ +#ifdef ANSI +PRIVATE Void kwLmmCleanGblRsrcs +( +KwCb *gCb +) +#else +PRIVATE Void kwLmmCleanGblRsrcs(gCb) +KwCb *gCb; +#endif +{ + Size kwSapSize; + Size kwUdxSapSize; + + TRC2(kwLmmCleanGblRsrcs) + + if (gCb->init.cfgDone) + { + /* Deregister the timers */ +/*Pradeep: changing the SDeregTmrMt() to SDeregTmr*/ + (Void) SDeregTmrMt(gCb->init.ent, gCb->init.inst, + (S16)gCb->genCfg.timeRes, kwActvTmr); + /*(Void) SDeregTmr(gCb->init.ent, gCb->init.inst, + (S16)gCb->genCfg.timeRes, kwActvTmr);*/ + + kwSapSize = (Size)(gCb->genCfg.maxKwuSaps * sizeof(KwKwuSapCb)); + + if (gCb->genCfg.rlcMode == LKW_RLC_MODE_DL) + { + kwUdxSapSize = (Size)(gCb->genCfg.maxUdxSaps * sizeof(KwUdxDlSapCb)); + if (gCb->u.dlCb) + { + gCb->u.dlCb->shutdownReceived = TRUE; + kwUtlFreeDlMemory(gCb); + if (gCb->u.dlCb->kwuDlSap != NULLP) + { + KW_FREE(gCb,gCb->u.dlCb->kwuDlSap, kwSapSize); + } + + if(gCb->u.dlCb->udxDlSap != NULLP) + { + KW_FREE(gCb,gCb->u.dlCb->udxDlSap, kwUdxSapSize); + } + + if(gCb->u.dlCb->rguDlSap != NULLP) + { + KW_FREE(gCb,gCb->u.dlCb->rguDlSap, gCb->genCfg.maxRguSaps); + gCb->genCfg.maxRguSaps = 0; + } + if (gCb->u.dlCb->shutdownReceived) + { + if (gCb->u.dlCb->selfPstMBuf != NULL) + { + SPutMsg(gCb->u.dlCb->selfPstMBuf); + } + KW_FREE(gCb,gCb->u.dlCb, sizeof (KwDlCb)); + } + } + + } + else + { + kwUdxSapSize = (Size)(gCb->genCfg.maxUdxSaps * sizeof(KwUdxUlSapCb)); + if (gCb->u.ulCb) + { + if (gCb->u.ulCb->kwuUlSap != NULLP) + { + KW_FREE(gCb,gCb->u.ulCb->kwuUlSap, kwSapSize); + } + + if(gCb->u.ulCb->udxUlSap != NULLP) + { + KW_FREE(gCb,gCb->u.ulCb->udxUlSap, kwUdxSapSize); + } + + if(gCb->u.ulCb->rguUlSap != NULLP) + { + KW_FREE(gCb,gCb->u.ulCb->rguUlSap, gCb->genCfg.maxRguSaps); + gCb->genCfg.maxRguSaps = 0; + } + + KW_FREE(gCb,gCb->u.ulCb, sizeof (KwUlCb)); + } + } + + gCb->init.cfgDone = FALSE; + gCb->init.acnt = FALSE; + gCb->init.trc = FALSE; + + gCb->init.usta = FALSE; + } + + RETVOID; +} + +/** + * @brief + * Delete all SAPs and Control Blocks + * + * @details + * Shutdown of RLC happens at modules level, tm, um and am modules will be + * shutdown using utility functin and dbm shutdown will clean up the SAPs, + * control blocks and lists. + * + * @params[in] gCb RLC instance control block + * + * @return S16 + * -# LCM_REASON_NOT_APPL (SUCCESS) + * -# LCM_REASON_HASHING_FAILED + */ +#ifdef ANSI +PRIVATE S16 kwLmmShutdown +( +KwCb *gCb +) +#else +PRIVATE S16 kwLmmShutdown(gCb) +KwCb *gCb; +#endif +{ + KwRguSapCb *rguSap; + U32 idx; + + TRC2(kwLmmShutdown) + + if (gCb->genCfg.rlcMode == LKW_RLC_MODE_DL) + { + for (idx = 0; idx < gCb->genCfg.maxRguSaps; idx++) + { + rguSap = &(gCb->u.dlCb->rguDlSap[idx]); + if ((rguSap->state == KW_SAP_BND) || (rguSap->state == KW_SAP_BINDING)) + { + KwLiRguUbndReq(&(rguSap->pst), rguSap->spId, 0); + } + } + } + else + { + for (idx = 0; idx < gCb->genCfg.maxRguSaps; idx++) + { + rguSap = &(gCb->u.ulCb->rguUlSap[idx]); + if ((rguSap->state == KW_SAP_BND) || (rguSap->state == KW_SAP_BINDING)) + { + KwLiRguUbndReq(&(rguSap->pst), rguSap->spId, 0); + } + } + } + + if(gCb->genCfg.rlcMode == LKW_RLC_MODE_DL) + { + kwDbmDlShutdown(gCb); + } + else + { + kwDbmUlShutdown(gCb); + } + + kwLmmCleanGblRsrcs(gCb); + + KW_MEM_SET (&(gCb->genSts), 0, sizeof (KwGenSts)); + + RETVALUE(LCM_REASON_NOT_APPL); +} + +/** + * @brief + * Function processes the general control request + * + * @param[in] gCb RLC instance control block + * @param[in] cntrl RLC LM structure + * + * @return S16 + * -# LCM_REASON_NOT_APPL (SUCCESS) + * -# LCM_REASON_INVALID_SUBACTION + * -# LCM_REASON_INVALID_ACTION + */ +#ifdef ANSI +PRIVATE S16 kwLmmGenCntrl +( +KwCb *gCb, +KwMngmt *cntrl +) +#else +PRIVATE S16 kwLmmGenCntrl(gCb,cntrl) +KwCb *gCb; +KwMngmt *cntrl; +#endif +{ + KwTrcCntrl *trcCntrl; /* trace */ +#ifdef DEBUGP + KwDbgCntrl *dbgCntrl; /* debug */ +#endif /* DEBUGP */ + S16 reason; /* reason for failure */ + + TRC2(kwLmmGenCntrl); + + /* Validate control parameters */ + reason = kwLmmValidateGenCntrl (cntrl); + + if (reason != LCM_REASON_NOT_APPL) + { + RETVALUE(reason); + } + + switch(cntrl->t.cntrl.action) + { + case AENA: + { + switch(cntrl->t.cntrl.subAction) + { + case SAUSTA: + { + KW_SET_USTA_FLAG(gCb, TRUE); + break; + } + case SADBG: + { +#ifdef DEBUGP + dbgCntrl = &cntrl->t.cntrl.s.dbgCntrl; + KW_GET_DBG_MASK(gCb) |= dbgCntrl->dbgMask; +#endif /* DEBUGP */ + break; + } + case SATRC: + { + trcCntrl = &cntrl->t.cntrl.s.trcCntrl; + gCb->init.trc = TRUE; + gCb->trcLen = trcCntrl->trcLen; + (gCb->trcMask) |= trcCntrl->trcMask; + break; + } + } + break; + } + case ADISIMM: + { + switch(cntrl->t.cntrl.subAction) + { + case SAUSTA: + { + gCb->init.usta = FALSE; + } + break; + case SADBG: + { +#ifdef DEBUGP + dbgCntrl = &cntrl->t.cntrl.s.dbgCntrl; + KW_GET_DBG_MASK(gCb) &= ~(dbgCntrl->dbgMask); +#endif /* DEBUGP */ + } + break; + case SATRC: + { + trcCntrl = &cntrl->t.cntrl.s.trcCntrl; + gCb->init.trc = FALSE; + gCb->trcMask &= ~(trcCntrl->trcMask); + } + break; + } + break; + } + case ASHUTDOWN: + { + reason = kwLmmShutdown(gCb); + break; + } + } + RETVALUE(reason); +} + +/** + * @brief + * Bind/Unbind RLC UDX sap + * + * @param[in] gCb RLC Instance Control Block + * @param[in] cntrl RLC LM structure + * + * @return S16 + * -# LCM_REASON_NOT_/PPL (SUCCESS) + * -# LCM_REASON_INVALID_SAP + * -# LCM_REASON_INVALID_STATE + * -# LCM_REASON_INVALID_ACTION + */ +#ifdef ANSI +PRIVATE S16 kwLmmUdxSapCntrl +( +KwCb *gCb, +KwMngmt *cntrl +) +#else +PRIVATE S16 kwLmmUdxSapCntrl(gCb,cntrl) +KwCb *gCb; +KwMngmt *cntrl; +#endif +{ + TRC2(kwLmmUdxSapCntrl) + +#if (ERRCLASS & ERRCLS_INT_PAR) + if (gCb->genCfg.rlcMode == LKW_RLC_MODE_DL) + { + RETVALUE(LCM_REASON_INVALID_SAP); + } + /* validate SuId */ + if((cntrl->t.cntrl.s.sapCntrl.suId < 0) || + (cntrl->t.cntrl.s.sapCntrl.suId >= KW_MAX_UDXSAPS)) + { + RETVALUE(LCM_REASON_INVALID_SAP); + } +#endif /* ERRCLASS & ERRCLS_INT_PAR */ + +#define UDX_SAP gCb->u.ulCb->udxUlSap[cntrl->t.cntrl.s.sapCntrl.suId] +#if (ERRCLASS & ERRCLS_INT_PAR) + /* validate SAP */ + if(UDX_SAP.state == KW_SAP_NOT_CFG) + { + RLOG0(L_ERROR,"udxUlSap not configured yet"); + RETVALUE(LCM_REASON_INVALID_STATE); + } +#endif /* ERRCLASS & ERRCLS_INT_PAR */ + + switch(cntrl->t.cntrl.action) + { + case ABND: + { + if(UDX_SAP.state != KW_SAP_BND) + { + /* start timer to wait for bind confirm */ + kwStartTmr(gCb,(PTR)(&UDX_SAP), KW_EVT_WAIT_BNDCFM); + UDX_SAP.state = KW_SAP_BINDING; + KwUlUdxBndReq(&(UDX_SAP.pst), UDX_SAP.suId, UDX_SAP.spId); + } + else + { + /* control request received for an already bound SAP */ + RETVALUE(LCM_REASON_INVALID_STATE); + } + } + break; + case AUBND: + { + /* make the state of UDXSAP configured but not bound */ + UDX_SAP.state = KW_SAP_CFG; + KwUlUdxUbndReq(&(UDX_SAP.pst), UDX_SAP.spId, 0); + } + break; + default: + RETVALUE(LCM_REASON_INVALID_ACTION); + break; + } /* end of switch */ +#undef UDX_SAP + RETVALUE(LCM_REASON_NOT_APPL); +} + +/** + * @brief + * Bind/Unbind RLC lower sap + * + * @param[in] gCb RLC Instance Control Block + * @param[in] cntrl RLC LM structure + * @return S16 + * -# LCM_REASON_NOT_APPL (SUCCESS) + * -# LCM_REASON_INVALID_SAP + * -# LCM_REASON_INVALID_STATE + * -# LCM_REASON_INVALID_ACTION + */ +#ifdef ANSI +PRIVATE S16 kwLmmLSapCntrl +( +KwCb *gCb, +KwMngmt *cntrl +) +#else +PRIVATE S16 kwLmmLSapCntrl(gCb,cntrl) +KwCb *gCb; +KwMngmt *cntrl; +#endif +{ + KwRguSapCb *rguSap; /* rgu sap pointer */ + + TRC2(kwLmmLSapCntrl) + +#if (ERRCLASS & ERRCLS_INT_PAR) + /* validate SuId */ + if((cntrl->t.cntrl.s.sapCntrl.suId < 0) || + (cntrl->t.cntrl.s.sapCntrl.suId >= gCb->genCfg.maxRguSaps)) + { + KWLOGERROR(gCb,ERRCLS_INT_PAR, EKW047, (ErrVal)cntrl->t.cntrl.s.sapCntrl.suId, + "kwLmmLSapCntrl: Invalid RGU suId\n"); + RETVALUE(LCM_REASON_INVALID_SAP); + } +#endif /* ERRCLASS & ERRCLS_INT_PAR */ + rguSap = (gCb->genCfg.rlcMode == LKW_RLC_MODE_DL) ? + &(gCb->u.dlCb->rguDlSap[cntrl->t.cntrl.s.sapCntrl.suId]): \ + &(gCb->u.ulCb->rguUlSap[cntrl->t.cntrl.s.sapCntrl.suId]); + +#if (ERRCLASS & ERRCLS_INT_PAR) + /* validate SAP */ + if(rguSap->state == KW_SAP_NOT_CFG) + { + RLOG1(L_ERROR,"RLC Mode [%d]:rguSap not configured yet", gCb->genCfg.rlcMode); + RETVALUE(LCM_REASON_INVALID_STATE); + } +#endif /* ERRCLASS & ERRCLS_INT_PAR */ + + switch(cntrl->t.cntrl.action) + { + case ABND: + { + if(rguSap->state != KW_SAP_BND) + { + /* start timer to wait for bind confirm */ + kwStartTmr(gCb,(PTR)(rguSap), KW_EVT_WAIT_BNDCFM); + rguSap->state = KW_SAP_BINDING; + rguSap->spId = cntrl->t.cntrl.s.sapCntrl.spId; + rguSap->suId = cntrl->t.cntrl.s.sapCntrl.suId; + KwLiRguBndReq(&(rguSap->pst), rguSap->suId, rguSap->spId); + } + else + { + /* control request received for an already bound SAP */ + RETVALUE(LCM_REASON_INVALID_STATE); + } + } + break; + case AUBND: + { + /* make the state of RGUSAP is configure but not bound */ + rguSap->state = KW_SAP_CFG; + KwLiRguUbndReq(&(rguSap->pst), rguSap->spId, 0); + } + break; + default: + RETVALUE(LCM_REASON_INVALID_ACTION); + break; + } /* end of switch */ + + RETVALUE(LCM_REASON_NOT_APPL); +} + +/** + * @brief + * Function gather the general KWU SAP status + * + * @param[in] gCb RLC Instance Control Block + * @param[in] sta LM KWU Sap Status structure + * + * @return S16 + * -# LCM_REASON_NOT_APPL (SUCCESS) + * -# LCM_REASON_INVALID_PAR_VAL(FAILURE) + */ +#ifdef ANSI +PRIVATE S16 kwLmmGetKwuSapSta +( +KwCb *gCb, +KwKwuSapSta *sta +) +#else +PRIVATE S16 kwLmmGetKwuSapSta(gCb,sta) +KwCb *gCb; +KwKwuSapSta *sta; +#endif +{ + KwKwuSapCb *kwSapCb; + + TRC2(kwLmmGetKwuSapSta); + +#if (ERRCLASS & ERRCLS_INT_PAR) + /* Validate the protocol parameters */ + if ((sta->spId >= (S16)gCb->genCfg.maxKwuSaps)|| + (sta->spId < 0)) + { + RETVALUE(LCM_REASON_INVALID_PAR_VAL); + } +#endif + + /* Get Sap control block */ + kwSapCb = (gCb->genCfg.rlcMode == LKW_RLC_MODE_DL)? + (KwKwuSapCb*)(gCb->u.dlCb->kwuDlSap + sta->spId): + (KwKwuSapCb*)(gCb->u.ulCb->kwuUlSap + sta->spId); + + sta->state = kwSapCb->state; + + RETVALUE(LCM_REASON_NOT_APPL); +} + +/** + * @brief + * Function gather the general RGU SAP status + * + * @param[in] gCb RLC Instance Control Block + * @param[in] sta LM RGU Sap Status structure + * @return S16 + * -# LCM_REASON_NOT_APPL (SUCCESS) + * -# LCM_REASON_INVALID_PAR_VAL(FAILURE) + */ +#ifdef ANSI +PRIVATE S16 kwLmmGetRguSapSta +( +KwCb *gCb, +KwRguSapSta *sta +) +#else +PRIVATE S16 kwLmmGetRguSapSta(gCb,sta) +KwCb *gCb; +KwRguSapSta *sta; +#endif +{ + TRC2(kwLmmGetRguSapSta); + +#if (ERRCLASS & ERRCLS_INT_PAR) + /* Validate the protocol parameters */ + if((sta->suId >= KW_MAX_RGUSAPS) || (sta->suId < 0)) + { + RETVALUE(LCM_REASON_INVALID_PAR_VAL); + } +#endif + + sta->state = (gCb->genCfg.rlcMode == LKW_RLC_MODE_DL) ? + gCb->u.dlCb->rguDlSap[sta->suId].state : + gCb->u.ulCb->rguUlSap[sta->suId].state ; + + RETVALUE(LCM_REASON_NOT_APPL); +} + +/** + * @brief + * Function gather the general CKW SAP status + * + * @param[in] gCb RLC Instance Control Block + * @param[in] sta LM CKW Sap Status structure + * @return S16 + * -# LCM_REASON_NOT_APPL (SUCCESS) + * -# LCM_REASON_INVALID_PAR_VAL(FAILURE) + */ +#ifdef ANSI +PRIVATE S16 kwLmmGetCkwCntSapSta +( +KwCb *gCb, +KwCkwCntSapSta *sta +) +#else +PRIVATE S16 kwLmmGetCkwCntSapSta(gCb,sta) +kwCb *gCb, +KwCkwCntSapSta *sta; +#endif +{ + TRC2(kwLmmGetCkwCntSapSta); + +#if (ERRCLASS & ERRCLS_INT_PAR) + /* Validate config parameters */ + if ((sta->spId >= KW_MAX_CKWSAPS ) || + (sta->spId < 0 ) || + (gCb->genCfg.rlcMode == LKW_RLC_MODE_DL)) + { + RETVALUE(LCM_REASON_INVALID_PAR_VAL); + } +#endif + sta->state = gCb->u.ulCb->ckwSap.state; + + RETVALUE(LCM_REASON_NOT_APPL); + +} + +/** + * @brief + * Gather the general statistics + * + * @param[in] gCb RLC Instance Control Block + * @param[in] sts LM general statistics structure + * @param[in] action action + * @return S16 + * -# LCM_REASON_NOT_APPL (SUCCESS) + * -# LCM_REASON_INVALID_PAR_VAL(FAILURE) + */ +#ifdef ANSI +PRIVATE S16 kwLmmGetGenSts +( +KwCb *gCb, +KwGenSts *sts, +Action action +) +#else +PRIVATE S16 kwLmmGetGenSts(gCb,sts, action) +KwCb *gCb; +KwGenSts *sts; +Action action; +#endif +{ + TRC2(kwLmmGetGenSts); + +#if (ERRCLASS & ERRCLS_INT_PAR) + /* Validate protocol parameters */ + if ((action != LKW_ZEROSTS) && (action != LKW_NOZEROSTS)) + { + RETVALUE(LCM_REASON_INVALID_PAR_VAL); + } +#endif + + *sts = gCb->genSts; + + if(action == LKW_ZEROSTS) + { + KW_MEM_SET (&(gCb->genSts), 0, sizeof (KwGenSts)); + } + + RETVALUE(LCM_REASON_NOT_APPL); +} + +/** + * @brief + * Gather the SAP statistics + * + * @param[in] gCb RLC Instance Control Block + * @param[in] sts LM general statistics structure + * @param[in] elmnt element + * @param[in] action action + * + * @return S16 + * -# LCM_REASON_NOT_APPL (SUCCESS) + * -# LCM_REASON_INVALID_PAR_VAL (FAIL) + */ +#ifdef ANSI +PRIVATE S16 kwLmmGetSapSts +( +KwCb *gCb, +KwMngmt *sts, +Elmnt elmnt, +Action action +) +#else +PRIVATE S16 kwLmmGetSapSts(sts, elmnt, action) +KwCb *gCb; +KwMngmt *sts; +Elmnt elmnt; +Action action; +#endif +{ + TRC2(kwLmmGetSapSts); + + /* Validate protocol parameters */ + if (action != LKW_ZEROSTS && action != LKW_NOZEROSTS) + { + RETVALUE(LCM_REASON_INVALID_PAR_VAL); + } + switch(elmnt) + { + case STKWUSAP: + { + KwKwuSapSts *kwuSap; + KwKwuSapCb *kwuSapCb; + kwuSap = &sts->t.sts.s.kwuSap; + + /* Get Sap control block */ + /* kw005.201, modified the element of kwuSap from suId to spId */ + kwuSapCb = (gCb->genCfg.rlcMode == LKW_RLC_MODE_DL)? + (KwKwuSapCb*)(gCb->u.dlCb->kwuDlSap + kwuSap->spId): + (KwKwuSapCb*)(gCb->u.ulCb->kwuUlSap + kwuSap->spId); + + + *kwuSap = kwuSapCb->sts; + + if (action == LKW_ZEROSTS) + { + KW_MEM_SET (&kwuSapCb->sts, 0, sizeof (KwKwuSapSts)); + } + break; + } + /* kw005.201 removed RGUSAP statistics support */ + case STCKWSAP: + { + KwCkwCntSts *ckwSap; + ckwSap = &sts->t.sts.s.ckwSap; + if (gCb->genCfg.rlcMode == LKW_RLC_MODE_DL) + { + RETVALUE(LCM_REASON_INVALID_PAR_VAL); + } + + ckwSap->statMsgs = gCb->u.ulCb->ckwSap.sts.statMsgs; + + if (action == LKW_ZEROSTS) + { + KW_MEM_SET (&(gCb->u.ulCb->ckwSap.sts), 0, sizeof (KwCkwCntSts)); + } + break; + } + default: + RETVALUE(LCM_REASON_INVALID_ELMNT); + } + + SGetDateTime(&sts->t.sts.dt); + + RETVALUE(LCM_REASON_NOT_APPL); +} + +/** + * @brief + * This function sends Unsolicited Status Indication to the Layer Management + * Entity. + * + * @param[in] gCb RLC Instance Control Block + * @param[in] category Category + * @param[in] event event + * @param[in] cause cause + * @param[in] UeId ueId + * @param[in] Qci qci + * + * @return Void + */ +#ifdef LTE_L2_MEAS +#ifdef ANSI +PUBLIC Void kwLmmSendAlarm +( +KwCb *gCb, +U16 category, +U16 event, +U16 cause, +SuId suId, +U32 ueId, +U8 qci +) +#else +PUBLIC Void kwLmmSendAlarm(category, event, cause, suId, ueId, qci) +KwCb *gCb; +U16 category; +U16 event; +U16 cause; +SuId suId; +U32 ueId; +U8 qci; +#endif +#else /* LTE_L2_MEAS */ +#ifdef ANSI +PUBLIC Void kwLmmSendAlarm +( +KwCb *gCb, +U16 category, +U16 event, +U16 cause, +SuId suId, +U32 ueId +) +#else +PUBLIC Void kwLmmSendAlarm(category, event, cause, suId, ueId) +KwCb *gCb; +U16 category; +U16 event; +U16 cause; +SuId suId; +U32 ueId; +#endif +#endif /* LTE_L2_MEAS */ +{ + KwMngmt usta; /* Rlc Management Structure */ + + TRC2(kwLmmSendAlarm); + + if(gCb->init.usta == FALSE) + { + RETVOID; + } + + usta.hdr.elmId.elmnt = STGEN; + usta.hdr.entId.ent = gCb->init.ent; + usta.hdr.entId.inst = gCb->init.inst; + + /* fill in the event and category */ + usta.t.usta.alarm.category = category; + usta.t.usta.alarm.event = event; + usta.t.usta.alarm.cause = cause; + + /* set the suId and ueId */ + usta.t.usta.ueId = ueId; + usta.t.usta.suId = suId; +/* kw005.201 added support for L2 Measurement */ +#ifdef LTE_L2_MEAS + if(event == LKW_EVT_MEAS_HALT) + { + usta.t.usta.qci = qci; + } +#endif /* LTE_L2_MEAS */ + /* update the date and time */ + (Void) SGetDateTime(&usta.t.usta.alarm.dt); + + KwMiLkwStaInd(&(gCb->init.lmPst), &usta); + + RETVOID; + +} + +/** + * @brief + * This function sends trace indication to LM + * + * @param[in] gCb RLC Instance Control Block + * @param[in] event event + * @param[in] mBuf meessage buffer + * + * @return S16 + * -# ROK + * -# RFAILED + */ +#ifdef ANSI +PUBLIC S16 kwLmmSendTrc +( +KwCb *gCb, +Event event, +Buffer *mBuf +) +#else +PUBLIC S16 kwLmmSendTrc(gCb,event, mBuf) +KwCb *gCb; +Event event; +Buffer *mBuf; +#endif +{ + KwMngmt trc; /* RLC management control block */ + Buffer *dstMbuf; + MsgLen bufLen; + Data *tempBuf; + MsgLen tempCnt; + Pst pst; + + TRC2(kwLmmSendTrc) + + RLOG2(L_DEBUG, "kwLmmSendTrc(): Trace for event=%d, gCb->trcLen=%d", + event, + gCb->trcLen); + + cmMemset((U8 *)&trc, 0, sizeof(KwMngmt)); + + pst = gCb->init.lmPst; + + trc.t.trc.event = event; + SGetDateTime(&trc.t.trc.dt); + trc.cfm.status = LCM_PRIM_OK; + trc.cfm.reason = LCM_REASON_NOT_APPL; + + if(mBuf != NULLP) + { + /* Check if the whole buffer is to be sent in Trace indication */ + if(gCb->trcLen == LKW_FULL_TRACE) + { + if (SCpyMsgMsg(mBuf, pst.region, pst.pool, &dstMbuf) + != ROK) + { + /* rg005.201 removed SPutSBuf on error */ + RLOG0(L_ERROR,"SCpyMsgMsg Failed"); + RETVALUE(RFAILED); + } + /* Send Trace Indication to Layer manager */ + KwMiLkwTrcInd(&pst, &trc, dstMbuf); + } + /* check if only a specified number of bytes are to be sent */ + else if(gCb->trcLen > 0) + { + /* Get the length of the recvd message buffer */ + if (SFndLenMsg(mBuf, &bufLen) != ROK) + { + RLOG0(L_ERROR,"SFndLenMsg Failed"); + RETVALUE(RFAILED); + } + /* Check if the recvd buffer size is less than request trace len */ + if(bufLen < gCb->trcLen) + { + /* Copy the whole of the recvd buffer in trace indication */ + + if (SCpyMsgMsg(mBuf, pst.region, pst.pool, &dstMbuf) + != ROK) + { + RLOG0(L_ERROR,"SCpyMsgMsg Failed"); + RETVALUE(RFAILED); + } + + /* Send Trace Indication to Layer manager */ + KwMiLkwTrcInd(&pst, &trc, dstMbuf); + } + else + { + /* if the recvd buffer size is greater than request trace len */ + /* Get a temporary buffer to store the msg */ + KW_ALLOC(gCb,tempBuf, gCb->trcLen); + +#if (ERRCLASS & ERRCLS_INT_PAR) + if(tempBuf == NULLP) + { + (Void) SPutSMem(KW_GET_MEM_REGION(gCb), KW_GET_MEM_POOL(gCb)); + + RLOG0(L_FATAL,"Memory Allocation failed"); + RETVALUE(LCM_REASON_MEM_NOAVAIL); + } +#endif /* ERRCLASS & ERRCLS_INT_PAR */ + + /* Copy trcLen nos of bytes from the recvd message */ + if (SCpyMsgFix(mBuf,0,gCb->trcLen,tempBuf,&tempCnt) != ROK) + { + RLOG0(L_ERROR,"SCpyMsgFix Failed"); + RETVALUE(RFAILED); + } + + if (SGetMsg(pst.region, pst.pool, &dstMbuf) != ROK) + { + RLOG0(L_FATAL,"Memory Allocation failed"); + RETVALUE(RFAILED); + } + /* Copy the tempBuf data to dst mBuf */ + if (SCpyFixMsg(tempBuf,dstMbuf,0,gCb->trcLen,&tempCnt) != ROK) + { + RLOG0(L_ERROR,"SCpyMsgFix Failed"); + RETVALUE(RFAILED); + } + + /* Free the memory allocated for tempBuf */ + KW_FREE(gCb,tempBuf, gCb->trcLen); + /* Send Trace Indication to Layer manager */ + KwMiLkwTrcInd(&pst, &trc, dstMbuf); + } + } + } + else + { + KwMiLkwTrcInd(&pst, &trc, mBuf); + } + + RETVALUE(ROK); +} + + +/* + * @brief + * Activate Task - timer + * + * @details + * Invoked by system services to activate a task with a timer tick. + * + * @param[in] ent entity + * @param[in] inst instance + * + * @return S16 + * -# ROK + * -# RFAILED + * + */ + +#ifdef ANSI +PUBLIC S16 kwActvTmr +( +Ent ent, +Inst inst +) +#else +PUBLIC S16 kwActvTmr(ent,inst) +Ent ent; +Inst inst; +#endif +{ + KwCb *gCb; + TRC2(kwActvTmr) + + if (inst >= KW_MAX_RLC_INSTANCES) + { + RETVALUE (RFAILED); + } + gCb = KW_GET_KWCB(inst); + cmPrcTmr(&(gCb->kwTqCp), gCb->kwTq, (PFV) kwTmrExpiry); + + RETVALUE(ROK); + +} /* end of kwActvTmr */ + + +/********************************************************************30** + + End of file +**********************************************************************/ diff --git a/src/5gnrrlc/kw_ptli.c b/src/5gnrrlc/kw_ptli.c new file mode 100755 index 000000000..dd2672908 --- /dev/null +++ b/src/5gnrrlc/kw_ptli.c @@ -0,0 +1,1190 @@ +/******************************************************************************* +################################################################################ +# Copyright (c) [2017-2019] [Radisys] # +# # +# 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. # +################################################################################ +*******************************************************************************/ + +/********************************************************************20** + + Name: LTE-RLC Layer - Lower Interface + + Type: C file + + Desc: C source code for the lower interface of LTE-RLC + + File: kw_ptli.c + +*********************************************************************21*/ +static const char* RLOG_MODULE_NAME="LIM"; +static int RLOG_MODULE_ID=2048; +static int RLOG_FILE_ID=238; +/** @file kw_ptli.c +@brief RLC Lower Interface +*/ + + +/* header (.h) include files */ +#include "envopt.h" /* environment options */ +#include "envdep.h" /* environment dependent */ +#include "envind.h" /* environment independent */ + +#include "gen.h" /* general */ +#include "ssi.h" /* system services */ +#include "cm5.h" /* common timer defines */ +#include "cm_tkns.h" /* common tokens defines */ +#include "cm_mblk.h" /* common memory allocation library defines */ +#include "cm_llist.h" /* common link list defines */ +#include "cm_hash.h" /* common hash list defines */ +#include "cm_lte.h" /* common LTE defines */ +#include "lkw.h" /* LKW defines */ +#include "ckw.h" /* CKW defines */ +#include "kwu.h" /* KWU defines */ +#include "rgu.h" /* RGU defines */ +#ifdef KW_PDCP +#include "cpj.h" /* CPJ defines */ +#include "pju.h" /* PJU defines */ +#include "lpj.h" /* LPJ defines */ +#endif +#include "kw_err.h" +#include "kw_env.h" /* RLC environment options */ +#include "kw.h" /* RLC defines */ + +/* extern (.x) include files */ +#include "gen.x" /* general */ +#include "ssi.x" /* system services */ + +#include "cm5.x" /* common timer library */ +#include "cm_tkns.x" /* common tokens */ +#include "cm_mblk.x" /* common memory allocation */ +#include "cm_llist.x" /* common link list */ +#include "cm_hash.x" /* common hash list */ +#include "cm_lte.x" /* common LTE includes */ +#include "cm_lib.x" /* common memory allocation library */ +#include "lkw.x" /* LKW */ +#include "ckw.x" /* CKW */ +#include "kwu.x" /* KWU */ +#include "rgu.x" /* RGU */ +#ifdef KW_PDCP +#include "cpj.x" /* CPJ defines */ +#include "pju.x" /* PJU defines */ +#include "lpj.x" /* LPJ defines */ +#endif +#include "kw.x" +#include "ss_rbuf.h" +#include "ss_rbuf.x" + +#ifndef LCKWLIRGU +#define PTKWRGU +#endif + +#ifndef RG +#define PTKWRGU +#endif + +#ifdef __cplusplus +EXTERN "C" { +#endif /* __cplusplus */ + + + +#ifdef RLC_MAC_DAT_REQ_RBUF +PUBLIC S16 kwLiRguDatReqRbuf(Pst *Post,SpId spId,Void *datReq); +#endif + +#ifdef RLC_MAC_STA_RSP_RBUF +PUBLIC S16 kwLiRguStaRspRbuf(Pst *Post,SpId spId,Void *staRsp); +#endif +#if defined(MAC_RLC_HARQ_STA_RBUF) && defined(LTE_L2_MEAS) +EXTERN S16 KwDlHarqStaBatchProc (Void); +#endif + + +/********************************************************************* + * Forward Declaration of RGU Porting Functions + ********************************************************************/ +EXTERN S16 PtLiRguBndReq ARGS(( +Pst *post, +SuId suId, +SpId spId +)); + +EXTERN S16 PtLiRguUbndReq ARGS (( +Pst *post, +SpId spId, +Reason reason +)); + +EXTERN S16 PtLiRguCDatReq ARGS (( +Pst *post, +SpId spId, +RguCDatReqInfo *datReq +)); + +EXTERN S16 PtLiRguDDatReq ARGS (( +Pst *post, +SpId spId, +RguDDatReqInfo *datReq +)); + +EXTERN S16 PtLiRguCStaRsp ARGS (( +Pst *post, +SpId spId, +RguCStaRspInfo *staRsp +)); + +EXTERN S16 PtLiRguDStaRsp ARGS (( +Pst *post, +SpId spId, +RguDStaRspInfo *staRsp +)); +/* kw005.201 added support for L2 Measurement */ +#ifdef LTE_L2_MEAS +#ifdef LTE_RLC_R9 +EXTERN S16 PtLiRguL2mUlThrpMeasReq ARGS (( +Pst *post, +SpId spId, +RguL2MUlThrpMeasReqInfo *l2mUlThrpMeasReq +)); +#endif /* LTE_RLC_R9 */ +#endif /* LTE_L2_MEAS */ + + +/********************************************************************* + * Primitives for RGU interface + ********************************************************************/ + +/* RGU Bind Request primitive */ + +PUBLIC RguBndReq kwLiRguBndReqMt[] = +{ +#ifdef LCKWLIRGU + cmPkRguBndReq, /* 0 - loosely coupled */ +#else + PtLiRguBndReq, /* 0 - loosely coupled, portable */ +#endif /* LCRGUIRGU */ +#ifdef RG + RgUiRguBndReq, /* 1 - tightly coupled, MAC */ +#else + PtLiRguBndReq, /* 1 - tightly coupled, portable */ +#endif /* RG */ +#ifdef LCKWLIRGU + cmPkRguBndReq, /* 0 - loosely coupled */ +#else + PtLiRguBndReq, /* 0 - loosely coupled, portable */ +#endif /* LCRGUIRGU */ +}; + +/* RGU Unbind Request primitive */ + +PUBLIC RguBndReq kwLiRguUbndReqMt[] = +{ +#ifdef LCKWLIRGU + cmPkRguUbndReq, /* 0 - loosely coupled */ +#else + PtLiRguUbndReq, /* 0 - loosely coupled, portable */ +#endif /* LCRGUIRGU */ +#ifdef RG + RgUiRguUbndReq, /* 1 - tightly coupled, MAC */ +#else + PtLiRguUbndReq, /* 1 - tightly coupled, portable */ /* RG */ +#endif /* RG */ +#ifdef LCKWLIRGU + cmPkRguUbndReq, /* 0 - loosely coupled */ +#else + PtLiRguUbndReq, /* 0 - loosely coupled, portable */ +#endif /* LCRGUIRGU */ +}; + +/* RGU Common Channel Data Request primitive */ + +PUBLIC RguCDatReq kwLiRguCDatReqMt[] = +{ +#ifdef LCKWLIRGU + cmPkRguCDatReq, /* 0 - loosely coupled */ +#else + PtLiRguCDatReq, /* 0 - loosely coupled, portable */ +#endif /* LCRGUIRGU */ +#ifdef RG + RgUiRguCDatReq, /* 1 - tightly coupled, MAC */ +#else + PtLiRguCDatReq, /* 1 - tightly coupled, portable */ +#endif /* RG */ +#ifdef LCKWLIRGU + cmPkRguCDatReq, /* 0 - loosely coupled */ +#else + PtLiRguCDatReq, /* 0 - loosely coupled, portable */ +#endif /* LCRGUIRGU */ +}; + +/* RGU Dedicated Channel Data Request primitive */ + +PUBLIC RguDDatReq kwLiRguDDatReqMt[] = +{ +#ifdef LCKWLIRGU + cmPkRguDDatReq, /* 0 - loosely coupled */ +#else + PtLiRguDDatReq, /* 0 - loosely coupled, portable */ +#endif /* LCRGUIRGU */ +#ifdef RG + RgUiRguDDatReq, /* 1 - tightly coupled, MAC */ +#else + PtLiRguDDatReq, /* 1 - tightly coupled, portable */ +#endif /* RG */ +#ifdef LCKWLIRGU + cmPkRguDDatReq, /* 0 - loosely coupled */ +#else + PtLiRguDDatReq, /* 0 - loosely coupled, portable */ +#endif /* LCRGUIRGU */ +}; + +/* RGU Common Channel Status Response primitive */ + +PUBLIC RguCStaRsp kwLiRguCStaRspMt[] = +{ +#ifdef LCKWLIRGU + cmPkRguCStaRsp, /* 0 - loosely coupled */ +#else + PtLiRguCStaRsp, /* 0 - loosely coupled, portable */ +#endif /* LCRGUIRGU */ +#ifdef RG + RgUiRguCStaRsp, /* 1 - tightly coupled, MAC */ +#else + PtLiRguCStaRsp, /* 1 - tightly coupled, portable */ +#endif /* RG */ +#ifdef LCKWLIRGU + cmPkRguCStaRsp, /* 0 - loosely coupled */ +#else + PtLiRguCStaRsp, /* 0 - loosely coupled, portable */ +#endif /* LCRGUIRGU */ +}; + +/* RGU Dedicated Channel Status Response primitive */ + +PUBLIC RguDStaRsp kwLiRguDStaRspMt[] = +{ +#ifdef LCKWLIRGU + cmPkRguDStaRsp, /* 0 - loosely coupled */ +#else + PtLiRguDStaRsp, /* 0 - loosely coupled, portable */ +#endif /* LCRGUIRGU */ +#ifdef RG + RgUiRguDStaRsp, /* 1 - tightly coupled, MAC */ +#else + PtLiRguDStaRsp, /* 1 - tightly coupled, portable */ +#endif /* RG */ +#ifdef LCKWLIRGU + cmPkRguDStaRsp, /* 0 - LWLC loosely coupled */ +#else + PtLiRguDStaRsp, /* 0 - LWLC loosely coupled, portable */ +#endif /* LCRGUIRGU */ +}; + +/* kw005.201 added support for L2 Measurement */ +#ifdef LTE_L2_MEAS +#ifdef LTE_RLC_R9 +/* RGU L2 Measurement Ul Ip Throughput Measurement Request primitive */ + +PUBLIC RguL2MUlThrpMeasReq kwLiRguL2MUlThrpMeasReqMt[] = +{ +#ifdef LCKWLIRGU + cmPkRguL2MUlThrpMeasReq, /* 0 - loosely coupled */ +#else + PtLiRguL2mUlThrpMeasReq, /* 0 - loosely coupled, portable */ +#endif /* LCRGUIRGU */ +#ifdef RG + RgUiRguL2MUlThrpMeasReq, /* 1 - tightly coupled, MAC */ +#else + PtLiRguL2mUlThrpMeasReq, /* 1 - tightly coupled, portable */ +#endif /* RG */ +}; +#endif /* LTE_RLC_R9 */ +#endif /* LTE_L2_MEAS */ + +/**************************************************************************** + * RGU Interface Mt functions + ***************************************************************************/ +/** + * + * @brief + * + * Handler for RGU SAP bind Request. + * + * @b Description: + * + * This function is used by RLC to request for binding to + * MAC for accessing MAC services.This function binds MAC's + * SAP (identified by spId) with the service user's SAP + * (identified by suId). + * + * @param[in] pst Post structure + * @param[in] suId Service user SAP ID + * @param[in] spId Service provider ID + * + * @return S16 + * -# ROK + */ + +#ifdef ANSI +PUBLIC S16 KwLiRguBndReq +( +Pst *post, /* post structure */ +SuId suId, /* Service User Id */ +SpId spId /* Service Provider Id */ +) +#else +PUBLIC S16 KwLiRguBndReq(post, suId, spId) +Pst *post; /* post structure */ +SuId suId; /* Service User Id */ +SpId spId; /* Service Provider Id */ +#endif +{ + TRC3(KwLiRguBndReq) + + /* jump to specific primitive depending on configured selector */ + (*kwLiRguBndReqMt[post->selector])(post, suId, spId); + + RETVALUE(ROK); + +} /* end of KwLiRguBndReq */ + + +/** + * + * @brief + * + * Handler for bind confirmation from MAC. + * + * @b Description: + * + * This function handles the bind confirmation received + * from MAC. + * + * @param[in] post - Post structure + * @param[in] suId - Service provider SAP ID + * @param[in] reason - Reason of confirmation + * + * @return S16 + * -# ROK + */ + +#ifdef ANSI +PUBLIC S16 KwLiRguUbndReq +( +Pst *post, +SpId spId, +Reason reason +) +#else +PUBLIC S16 KwLiRguUbndReq(post, spId, reason) +Pst *post; +SpId spId; +Reason reason; +#endif +{ + TRC3(KwLiRguUbndReq) + + /* jump to specific primitive depending on configured selector */ + (*kwLiRguUbndReqMt[post->selector])(post, spId, reason); + + RETVALUE(ROK); + +} /* end of KwLiRguUbndReq */ + + +/** + * + * @brief + * + * Handler for sending the PDU from RLC to MAC for common logical channels. + * + * @b Description: + * + * This function sends a PDU of a common logical channel to MAC + * along with timing info for BCCH and PCCH and RNTI for CCCH. + * + * @param[in] post Post structure + * @param[in] spId Service Provider ID + * @param[in] datIndInfo Data Request Information + * + * @return S16 + * -# ROK + * -# RFAILED + * + */ +#ifdef ANSI +PUBLIC S16 KwLiRguCDatReq +( +Pst *post, +SpId spId, +RguCDatReqInfo *datReq +) +#else +PUBLIC S16 KwLiRguCDatReq(post, spId, datReq) +Pst *post; +SpId spId; +RguCDatReqInfo *datReq; +#endif +{ + TRC3(KwLiRguCDatReq) +// printf("CSHP: KwLiRguCDatReq "); +#ifdef RLC_MAC_DAT_REQ_RBUF + //printf("to RING \n"); + post->event=EVTRGUCDATREQ; + if((kwLiRguDatReqRbuf(post, spId, datReq)) != ROK) + { + + SPutStaticBuffer(post->region, post->pool, + (Data *) datReq, sizeof(RguCDatReqInfo), 0); + RETVALUE(RFAILED); + } +#else + + // printf("to Pack Sel is %d \n",post->selector); + /* jump to specific primitive depending on configured selector */ + (*kwLiRguCDatReqMt[post->selector])(post, spId, datReq); +#endif + RETVALUE(ROK); + +} /* end of KwLiRguCDatReq */ + + +/** + * + * @brief + * + * Handler for sending PDU(s) from RLC to MAC for dedicated logical channels. + * + * @b Description: + * + * This function sends PDU(s) to MAC via one or more dedicated + * logical channels along with the Buffer Occupancy of these + * channels. + * + * @param[in] post Post structure + * @param[in] spId Service Provider ID + * @param[in] datIndInfo Data Request Information + * + * @return S16 + * -# ROK + * -# RFAILED + * + */ +#ifdef ANSI +PUBLIC S16 KwLiRguDDatReq +( +Pst *post, +SpId spId, +RguDDatReqInfo *datReq +) +#else +PUBLIC S16 KwLiRguDDatReq(post, spId, datReq) +Pst *post; +SpId spId; +RguDDatReqInfo *datReq; +#endif +{ + TRC3(KwLiRguDDatReq) +#ifdef RLC_MAC_DAT_REQ_RBUF + post->event=EVTRGUDDATREQ; + if((kwLiRguDatReqRbuf(post, spId, datReq)) != ROK) + { + + SPutStaticBuffer(post->region, post->pool, + (Data *) datReq, sizeof(RguDDatReqInfo), 0); + RETVALUE(RFAILED); + } +#else + /* jump to specific primitive depending on configured selector */ + (*kwLiRguDDatReqMt[post->selector])(post, spId, datReq); +#endif + RETVALUE(ROK); + +} /* end of KwLiRguDDatReq */ + + +/** + * + * @brief + * + * Handler for reporting the Buffer Occupancy to MAC + * for common logical channels. + * + * @b Description: + * + * This function reports the Buffer Occupancy of a common logical + * channel to MAC along with timing information for BCCH and PCCH + * and RNTI for CCCH. + * + * @param[in] post Post structure + * @param[in] spId Service Provider ID + * @param[in] staRspInfo Status Response Information + * + * @return S16 + * -# ROK + * -# RFAILED + * + */ +#ifdef ANSI +PUBLIC S16 KwLiRguCStaRsp +( +Pst *post, +SpId spId, +RguCStaRspInfo *staRsp +) +#else +PUBLIC S16 KwLiRguCStaRsp(post, spId, staRsp) +Pst *post; +SpId spId; +RguCStaRspInfo *staRsp; +#endif +{ + TRC3(KwLiRguCStaRsp) + + /* jump to specific primitive depending on configured selector */ + (*kwLiRguCStaRspMt[post->selector])(post, spId, staRsp); + RETVALUE(ROK); + +} /* end of KwLiRguCStaRsp */ + + +/** + * + * @brief + * + * Handler for reporting the Buffer Occupancy to MAC + * for dedicated logical channels. + * + * @b Description: + * + * This function reports the Buffer Occupancy of one or more + * dedicated logical channels to MAC. + * + * @param[in] post Post structure + * @param[in] spId Service Provider ID + * @param[in] staRspInfo Status Response Information + * + * @return S16 + * -# ROK + * -# RFAILED + * + */ +#ifdef ANSI +PUBLIC S16 KwLiRguDStaRsp +( +Pst *post, +SpId spId, +RguDStaRspInfo *staRsp +) +#else +PUBLIC S16 KwLiRguDStaRsp(post, spId, staRsp) +Pst *post; +SpId spId; +RguDStaRspInfo *staRsp; +#endif +{ + TRC3(KwLiRguDStaRsp) +#if defined(SPLIT_RLC_DL_TASK) && defined(RLC_MAC_STA_RSP_RBUF) + post->event= EVTRGUDSTARSP; + if((kwLiRguStaRspRbuf(post, spId, staRsp)) != ROK) + { + RETVALUE(RFAILED); + } +#else + /* jump to specific primitive depending on configured selector */ + (*kwLiRguDStaRspMt[post->selector])(post, spId, staRsp); +#endif + RETVALUE(ROK); + +} /* end of KwLiRguDStaRsp */ + + +/* kw005.201 added support for L2 Measurement */ +#ifdef LTE_L2_MEAS +#ifdef LTE_RLC_R9 + +/** + * + * @brief + * + * Handler for sending ulThrpMeasReqInfo from RLC to MAC for UL ip throughput measurement. + * + * @b Description: + * + * This function sends ulThrpMeasReqInfo from RLC to MAC whenver UL ip throughput + * measurement is ON for a single or multiple qci in a UE. This is an indication for MAC + * to start the T2/T1 time stamps for the coresponding LCHs in the UE. + * + * @param[in] post Post structure + * @param[in] spId Service Provider ID + * @param[in] ulThrpMeasReqInfo Ul ip measurement request info + * + * @return S16 + * -# ROK + * -# RFAILED + * + */ +#ifdef ANSI +PUBLIC S16 KwLiRguL2MUlThrpMeasReq +( +Pst *post, +SpId spId, +RguL2MUlThrpMeasReqInfo *l2mUlThrpMeasReq +) +#else +PUBLIC S16 KwLiRguL2MUlThrpMeasReq(post, spId, l2mUlThrpMeasReq) +Pst *post; +SpId spId; +RguL2MUlThrpMeasReqInfo *l2mUlThrpMeasReq; +#endif +{ + TRC3(KwLiRguL2MUlThrpMeasReq) + + /* jump to specific primitive depending on configured selector */ + (*kwLiRguL2MUlThrpMeasReqMt[post->selector])(post, spId, l2mUlThrpMeasReq); + + RETVALUE(ROK); + +} /* end of KwLiRguL2MUlThrpMeasReq */ + +#endif /* LTE_RLC_R9 */ +#endif /* LTE_L2_MEAS */ + + + +/**************************************************************************** + * Porting Functions + ***************************************************************************/ + +/** + * + * @brief + * + * PtLiRguBndReq - portable bind request + * + * @param[in] post - Post structure + * @param[in] suId - Service user SAP ID + * @param[in] spId - Service provider ID + * + * @return S16 + * -# ROK + */ + +#ifdef ANSI +PUBLIC S16 PtLiRguBndReq +( +Pst *post, +SuId suId, +SpId spId +) +#else +PUBLIC S16 PtLiRguBndReq(post, suId, spId) +Pst *post; +SuId suId; +SpId spId; +#endif /* ANSI */ +{ +#if (ERRCLASS & ERRCLS_DEBUG) + KwCb *tKwCb; +#endif + + TRC3(PtLiRguBndReq) +#if (ERRCLASS & ERRCLS_DEBUG) + tKwCb = KW_GET_KWCB(post->srcInst); + RLOG0(L_ERROR,"Improper selector value"); +#endif /* (ERRCLASS & ERRCLS_DEBUG) */ + RLOG0(L_ERROR,"Improper selector value"); + UNUSED(post); + UNUSED(suId); + UNUSED(spId); + + RETVALUE(ROK); +} /* end of PtLiRguBndReq() */ + + +/** + * + * @brief + * + * PtLiRguUbndReq - portable bind request + * + * @param[in] post - Post structure + * @param[in] spId - Service user SAP ID + * @param[in] reason - Service provider ID + * + * @return S16 + * -# ROK + */ + +#ifdef ANSI +PUBLIC S16 PtLiRguUbndReq +( +Pst *post, +SpId spId, +Reason reason +) +#else +PUBLIC S16 PtLiRguUbndReq(post, spId, reason) +Pst *post; +SpId spId; +Reason reason; +#endif /* ANSI */ +{ +#if (ERRCLASS & ERRCLS_DEBUG) + KwCb *tKwCb; +#endif + + TRC3(PtLiRguUbndReq) +#if (ERRCLASS & ERRCLS_DEBUG) + tKwCb = KW_GET_KWCB(post->srcInst); + RLOG0(L_ERROR,"Improper selector value"); +#endif /* (ERRCLASS & ERRCLS_DEBUG) */ + UNUSED(post); + UNUSED(spId); + UNUSED(reason); + + RETVALUE(ROK); +} /* end of PtLiRguUbndReq() */ + + +/** + * + * @brief + * + * PtLiRguCDatReq - portable common channel data request + * + * @param[in] post - Post structure + * @param[in] spId - Service user SAP ID + * @param[in] datReq - Service provider ID + * + * @return S16 + * -# ROK + */ + +#ifdef ANSI +PUBLIC S16 PtLiRguCDatReq +( +Pst *post, +SpId spId, +RguCDatReqInfo *datReq +) +#else +PUBLIC S16 PtLiRguCDatReq(post, spId, datReq) +Pst *post; +SpId spId; +RguCDatReqInfo *datReq; +#endif /* ANSI */ +{ +#if (ERRCLASS & ERRCLS_DEBUG) + KwCb *tKwCb; +#endif + + TRC3(PtLiRguCDatReq) +#if (ERRCLASS & ERRCLS_DEBUG) + tKwCb = KW_GET_KWCB(post->srcInst); + RLOG0(L_ERROR,"Improper selector value"); +#endif /* (ERRCLASS & ERRCLS_DEBUG) */ + UNUSED(post); + UNUSED(spId); + UNUSED(datReq); + + RETVALUE(ROK); +} /* end of PtLiRguCDatReq() */ + + +/** + * + * @brief + * + * PtLiRguDDatReq - portable dedicated channel data request + * + * @param[in] post - Post structure + * @param[in] spId - Service user SAP ID + * @param[in] datReq - Service provider ID + * + * @return S16 + * -# ROK + */ + +#ifdef ANSI +PUBLIC S16 PtLiRguDDatReq +( +Pst *post, +SpId spId, +RguDDatReqInfo *datReq +) +#else +PUBLIC S16 PtLiRguDDatReq( post, spId, datReq) +Pst *post; +SpId spId; +RguDDatReqInfo *datReq; +#endif /* ANSI */ +{ +#if (ERRCLASS & ERRCLS_DEBUG) + KwCb *tKwCb; +#endif + + TRC3(PtLiRguDDatReq) +#if (ERRCLASS & ERRCLS_DEBUG) + tKwCb = KW_GET_KWCB(post->srcInst); + RLOG0(L_ERROR,"Improper selector value"); +#endif /* (ERRCLASS & ERRCLS_DEBUG) */ + UNUSED(post); + UNUSED(spId); + UNUSED(datReq); + + RETVALUE(ROK); +} /* end of PtLiRguDDatReq() */ + + +/** + * + * @brief + * + * PtLiRguCStaRsp - portable common channel Status Response + * + * @param[in] post - Post structure + * @param[in] spId - Service user SAP ID + * @param[in] staRsp - Service provider ID + * + * @return S16 + * -# ROK + */ + +#ifdef ANSI +PUBLIC S16 PtLiRguCStaRsp +( +Pst *post, +SpId spId, +RguCStaRspInfo *staRsp +) +#else +PUBLIC S16 PtLiRguCStaRsp(post, spId, staRsp) +Pst *post; +SpId spId; +RguCStaRspInfo *staRsp; +#endif /* ANSI */ +{ +#if (ERRCLASS & ERRCLS_DEBUG) + KwCb *tKwCb; +#endif + + TRC3(PtLiRguCStaRsp) +#if (ERRCLASS & ERRCLS_DEBUG) + tKwCb = KW_GET_KWCB(post->srcInst); + RLOG0(L_ERROR,"Improper selector value"); +#endif /* (ERRCLASS & ERRCLS_DEBUG) */ + UNUSED(post); + UNUSED(spId); + UNUSED(staRsp); + + RETVALUE(ROK); +} /* end of PtLiRguCStaRsp() */ + + +/** + * + * @brief + * + * PtLiRguDStaRsp - portable dedicated channel Status Response + * + * @param[in] post - Post structure + * @param[in] spId - Service user SAP ID + * @param[in] staRsp - Service provider ID + * + * @return S16 + * -# ROK + */ + +#ifdef ANSI +PUBLIC S16 PtLiRguDStaRsp +( +Pst *post, +SpId spId, +RguDStaRspInfo *staRsp +) +#else +PUBLIC S16 PtLiRguDStaRsp(post, spId, staRsp) +Pst *post; +SpId spId; +RguDStaRspInfo *staRsp; +#endif /* ANSI */ +{ +#if (ERRCLASS & ERRCLS_DEBUG) + KwCb *tKwCb; +#endif + + TRC3(PtLiRguDStaRsp) +#if (ERRCLASS & ERRCLS_DEBUG) + tKwCb = KW_GET_KWCB(post->srcInst); + RLOG0(L_ERROR,"Improper selector value"); +#endif /* (ERRCLASS & ERRCLS_DEBUG) */ + UNUSED(post); + UNUSED(spId); + UNUSED(staRsp); + + RETVALUE(ROK); +} /* end of PtLiRguDStaRsp() */ + +/* kw005.201 added support for L2 Measurement */ +#ifdef LTE_L2_MEAS +#ifdef LTE_RLC_R9 + +/** + * + * @brief + * + * PtLiRguL2mUlThrpMeasReq - portable L2 Measurement Ul Thoughput Measurement Request + * + * @param[in] post - Post structure + * @param[in] spId - Service user SAP ID + * @param[in] l2mUlThrpMeasReq - Ul Throughput Measurement Request + * + * @return S16 + * -# ROK + */ + +#ifdef ANSI +PUBLIC S16 PtLiRguL2mUlThrpMeasReq +( +Pst *post, +SpId spId, +RguL2MUlThrpMeasReqInfo *l2mUlThrpMeasReq +) +#else +PUBLIC S16 PtLiRguL2mUlThrpMeasReq(post, spId, l2mUlThrpMeasReq) +Pst *post, +Pst *post; +SpId spId; +RguL2MUlThrpMeasReqInfo *l2mUlThrpMeasReq; +#endif /* ANSI */ +{ +#if (ERRCLASS & ERRCLS_DEBUG) + KwCb *tKwCb; +#endif + + TRC3(PtLiRguL2mUlThrpMeasReq) +#if (ERRCLASS & ERRCLS_DEBUG) + tKwCb = KW_GET_KWCB(post->srcInst); + RLOG0(L_ERROR,"Improper selector value"); +#endif /* (ERRCLASS & ERRCLS_DEBUG) */ + UNUSED(post); + UNUSED(spId); + UNUSED(l2mUlThrpMeasReq); + + RETVALUE(ROK); +} /* end of PtLiRguL2mUlThrpMeasReq() */ + +#endif /* LTE_RLC_R9 */ +#endif /* LTE_L2_MEAS */ + +#ifdef MAC_RLC_UL_RBUF +PUBLIC S16 kwUlBatchProc ARGS ((Void)); +EXTERN Void kwUtlFreeUlRBuf ARGS((void)); + +#ifdef ANSI +PUBLIC S16 kwUlBatchProc +( +Void +) +#else +PUBLIC S16 kwUlBatchProc() +Void; +#endif +{ +/* Read from Ring Buffer and process PDCP packets */ + RguDDatIndInfo *datInd; + Void *elmIndx = NULLP; + PRIVATE Pst rlcUlRbfuPst={1,1,ENTKW,0,ENTRG,0,PRIOR0,RTESPEC,EVTRGUDDATIND,0,0,0,0}; +/* Read from Ring Buffer and process PDCP packets */ + +#ifndef SS_RBUF + RguDedDatInd1 *rguDatInd = NULLP; + U8 rngBufDeqIndx = 0; + + elmIndx = SRngGetRIndx(SS_RNG_BUF_ULMAC_TO_ULRLC); + while(NULLP != elmIndx) + { + rguDatInd = (RguDedDatInd1 *)elmIndx; + datInd = (RguDDatIndInfo*) rguDatInd->msg; + SsRngInfoTbl[SS_RNG_BUF_ULMAC_TO_ULRLC].nPktProc++;;//Number of pkt processed in tti + if(datInd != NULLP) + { + KwLiRguDDatInd(&rlcUlRbfuPst, 0, datInd); + } + else + { + RLOG0(L_ERROR,"Received NULL buffer"); + } + rguDatInd->msg=NULLP; + SRngIncrRIndx(SS_RNG_BUF_ULMAC_TO_ULRLC); + elmIndx = NULLP; + rguDatInd = NULLP; + + rngBufDeqIndx++; + + //if(rngBufDeqIndx >= SS_RNG_MAX_ULMAC_TO_ULRLC_DQ_CNT) + // break; + + if((elmIndx = SRngGetRIndx(SS_RNG_BUF_ULMAC_TO_ULRLC)) == NULLP) + break; + } +#else + elmIndx = SRngGetRIndx(SS_RNG_BUF_ULMAC_TO_ULRLC); + while(NULLP != elmIndx) + { + datInd = (RguDDatIndInfo *)elmIndx; + KwLiRguDDatInd(&rlcUlRbfuPst, 0, datInd); + + elmIndx = NULLP; + datInd = NULLP; + SRngIncrRIndx(SS_RNG_BUF_ULMAC_TO_ULRLC); + + if((elmIndx = SRngGetRIndx(SS_RNG_BUF_ULMAC_TO_ULRLC)) == NULLP) + break; + } +#endif + RETVALUE(ROK); + +} + +/** + * + * @brief + * Handler to clear Ring buffer from UL RLC + * + * @details + * This function clears all the ring buffer content from UL RLC + * + * @return S16 + * -# ROK + * -# RFAILED + * + */ +#ifdef ANSI +PUBLIC Void kwUtlFreeUlRBuf(void) +#else +PUBLIC Void kwUtlFreeUlRBuf() +#endif +{ + RguDDatIndInfo *datInd; + PTR elem; + U8 numLch; + U8 numPdu; + + TRC2(kwUtlFreeUlRBuf) + /* Free SS_RNG_BUF_ULMAC_TO_ULRLC */ + while((SDeqSRngBuf (SS_RNG_BUF_ULMAC_TO_ULRLC, &elem) == ROK)) + { + datInd = (RguDDatIndInfo *)elem; + for(numLch = 0; numLch< datInd->numLch; numLch++) + { + for(numPdu = 0; numPdu < datInd->lchData[numLch].pdu.numPdu; numPdu++) + { + if(datInd->lchData[numLch].pdu.mBuf[numPdu]) + { + KW_FREE_BUF_WC(datInd->lchData[numLch].pdu.mBuf[numPdu]); + } + } + } + KW_PST_FREE(0, 0, datInd, sizeof(RguDDatIndInfo)); + } +} +#endif +#ifdef RLC_MAC_STA_RSP_RBUF +#ifdef ANSI +PUBLIC S16 kwLiRguStaRspRbuf +( +Pst *post, +SpId spId, +Void *staRsp +) +#else +PUBLIC S16 kwLiRguStaRspRbuf(post, spId, staRsp) +Pst *post; +SpId spId; +Void *staRsp; +#endif /* ANSI */ +{ + S16 ret1 = ROK; + + Void *elem = NULLP; + + RguDStaRspInfo *staRspInfo = NULL; + elem = SRngGetWIndx(SS_RNG_BUF_DLRLC_TO_DLMAC); + if (NULLP != elem) + { + staRspInfo = (RguDStaRspInfo *)elem; + cmMemcpy((U8 *)staRspInfo, (U8 *)staRsp, sizeof(RguDStaRspInfo)); + staRspInfo->post = *post; + SRngIncrWIndx(SS_RNG_BUF_DLRLC_TO_DLMAC); + SsRngInfoTbl[SS_RNG_BUF_DLRLC_TO_DLMAC].pktRate++; + } + else + { + RLOG0(L_ERROR,"RLC DL STA RSP RBUF is FULL!!! "); + SsRngInfoTbl[SS_RNG_BUF_DLRLC_TO_DLMAC].pktDrop++; + ret1 = RFAILED; + } + RETVALUE(ret1); +} /* cmPkKwuDatReq */ + +#endif +#ifdef RLC_MAC_DAT_REQ_RBUF +#ifdef ANSI +PUBLIC S16 kwLiRguDatReqRbuf +( +Pst *post, +SpId spId, +Void *datReq +) +#else +PUBLIC S16 kwLiRguDatReqRbuf(post, spId, datReq) +Pst *post; +SpId spId; +Void *datReq; +#endif /* ANSI */ +{ + S16 ret1 = ROK; + + Void *elem = NULLP; + RguInfoRingElem *datReqRing=NULLP; + elem = SRngGetWIndx(SS_RNG_BUF_DLRLC_TO_DLMAC_DAT_REQ); + if (NULLP != elem) + { + datReqRing = (RguInfoRingElem *) elem; + datReqRing->spId = spId; + datReqRing->event = post->event; + datReqRing->msg =datReq; + SRngIncrWIndx(SS_RNG_BUF_DLRLC_TO_DLMAC_DAT_REQ); + SsRngInfoTbl[SS_RNG_BUF_DLRLC_TO_DLMAC_DAT_REQ].pktRate++; + } + else + { + printf("RLC DL DAT REQ RBUF is FULL!!! \n"); + SsRngInfoTbl[SS_RNG_BUF_DLRLC_TO_DLMAC_DAT_REQ].pktDrop++; + ret1 = RFAILED; + } + RETVALUE(ret1); +} /* cmPkKwuDatReq */ + +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +/********************************************************************30** + End of file +**********************************************************************/ diff --git a/src/5gnrrlc/kw_ptmi.c b/src/5gnrrlc/kw_ptmi.c new file mode 100755 index 000000000..b01d91837 --- /dev/null +++ b/src/5gnrrlc/kw_ptmi.c @@ -0,0 +1,802 @@ +/******************************************************************************* +################################################################################ +# Copyright (c) [2017-2019] [Radisys] # +# # +# 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. # +################################################################################ +*******************************************************************************/ + +/********************************************************************20** + + Name: RLC Layer Management interface + + Type: C source file + + Desc: This file contains source code for RLC layer management + interface primitives. It includes the definition of the + following functions and their portable function + definitions. + -- PjMiLpjCfgCfm + -- PjMiLpjCntrlCfm + -- PjMiLpjStaInd + + + File: kw_ptmi.c + +*********************************************************************21*/ + + +/* header (.h) include files */ +#include "envopt.h" /* environment options */ +#include "envdep.h" /* environment dependent */ +#include "envind.h" /* environment independent */ + +#include "gen.h" /* general */ +#include "ssi.h" /* system services */ +#include "cm5.h" /* common timer defines */ +#include "cm_tkns.h" /* common tokens defines */ +#include "cm_mblk.h" /* common memory allocation library defines */ +#include "cm_llist.h" /* common link list defines */ +#include "cm_hash.h" /* common hash list defines */ +#include "cm_lte.h" /* common LTE defines */ +#include "lkw.h" /* LKW defines */ +#include "ckw.h" /* CKW defines */ +#include "kwu.h" /* KWU defines */ +#include "rgu.h" /* RGU defines */ + +#include "kw_env.h" /* RLC environment options */ +#include "kw.h" /* RLC defines */ + +/* extern (.x) include files */ +#include "gen.x" /* general */ +#include "ssi.x" /* system services */ + +#include "cm5.x" /* common timer library */ +#include "cm_tkns.x" /* common tokens */ +#include "cm_mblk.x" /* common memory allocation */ +#include "cm_llist.x" /* common link list */ +#include "cm_hash.x" /* common hash list */ +#include "cm_lte.x" /* common LTE includes */ +#include "cm_lib.x" /* common memory allocation library */ +#include "lkw.x" /* LKW */ +#include "ckw.x" /* CKW */ +#include "kwu.x" /* KWU */ +#include "rgu.x" /* RGU */ + +#include "kw.x" + +/* local defines */ +#define MAXKWMI 2 /* max. layer management interfaces */ + +#ifndef LCKWMILKW +#define PTKWLKW +#endif + + +#ifndef SM +#define PTKWLKW +#endif + + + +#ifdef PTKWLKW +/* portable functions */ + +PRIVATE S16 PtMiLkwCfgCfm ARGS((Pst *pst, KwMngmt *cfm)); +PRIVATE S16 PtMiLkwCntrlCfm ARGS((Pst *pst, KwMngmt *cfm)); +PRIVATE S16 PtMiLkwStaInd ARGS((Pst *pst, KwMngmt *usta)); + +PRIVATE S16 PtMiLkwStaCfm ARGS((Pst *pst, KwMngmt *cfm)); +PRIVATE S16 PtMiLkwStsCfm ARGS((Pst *pst, Action action, + KwMngmt *cfm)); +PRIVATE S16 PtMiLkwTrcInd ARGS((Pst *pst, KwMngmt *trc, + Buffer *mBuf)); +/* kw005.201 added support for L2 Measurement */ +#ifdef LTE_L2_MEAS +PRIVATE S16 PtMiLkwL2MeasCfm ARGS((Pst *pst, KwL2MeasCfmEvt *measEvt)); +PRIVATE S16 PtMiLkwL2MeasStopCfm ARGS((Pst *pst, U8 measType,U8 status)); +#endif /* LTE_L2_MEAS */ +#endif /* PTKWLKW */ + + +/********************************************************************* + * Primitives for LKW interface + ********************************************************************/ +/* Configuration confirmation primitive */ + +PRIVATE LkwCfgCfm kwMiLkwCfgCfmMt[MAXKWMI] = +{ +#ifdef LCKWMILKW + cmPkLkwCfgCfm, /* 0 - loosely coupled - fc */ +#else + PtMiLkwCfgCfm, /* 0 - tightly coupled portable */ +#endif /* LCRLMILKW */ +#ifdef SM + SmMiLkwCfgCfm, /* 1 - tightly coupled layer management*/ +#else + PtMiLkwCfgCfm, /* 1 - tightly coupled portable */ +#endif /* SM */ +}; + +/* control confirmation primitives */ + +PRIVATE LkwCntrlCfm kwMiLkwCntrlCfmMt[MAXKWMI] = +{ +#ifdef LCKWMILKW + cmPkLkwCntrlCfm, /* 0 - loosely coupled - fc */ +#else + PtMiLkwCntrlCfm, /* 0 - tightly coupled portable */ +#endif /* LCRLMILKW */ +#ifdef SM + SmMiLkwCntrlCfm, /* 1 - tightly coupled layer management*/ +#else + PtMiLkwCntrlCfm, /* 1 - tightly coupled portable */ +#endif /* SM */ +}; + +/* Status Indication primitive */ + +PRIVATE LkwStaInd kwMiLkwStaIndMt[MAXKWMI] = +{ +#ifdef LCKWMILKW + cmPkLkwStaInd, /* 0 - loosely coupled */ +#else + PtMiLkwStaInd, /* 0 - tightly coupled, portable */ +#endif /* LCKWMILKW */ +#ifdef SM + SmMiLkwStaInd, /* 1 - tightly coupled, layer management */ +#else + PtMiLkwStaInd, /* 1 - tightly coupled, portable */ +#endif /* SM */ +}; + +/* Status confirm primitive */ + +PRIVATE LkwStaCfm kwMiLkwStaCfmMt[MAXKWMI] = +{ +#ifdef LCKWMILKW + cmPkLkwStaCfm, /* 0 - loosely coupled */ +#else + PtMiLkwStaCfm, /* 0 - tightly coupled, portable */ +#endif /* LCKWMILKW */ +#ifdef SM + SmMiLkwStaCfm, /* 1 - tightly coupled, layer management */ +#else + PtMiLkwStaCfm, /* 1 - tightly coupled, portable */ +#endif /* SM */ +}; + +/* Statistics confirm primitive */ + +PRIVATE LkwStsCfm kwMiLkwStsCfmMt[MAXKWMI] = +{ +#ifdef LCKWMILKW + cmPkLkwStsCfm, /* 0 - loosely coupled */ +#else + PtMiLkwStsCfm, /* 0 - tightly coupled, portable */ +#endif /* LCRLMILKW */ +#ifdef SM + SmMiLkwStsCfm, /* 1 - tightly coupled, layer management */ +#else + PtMiLkwStsCfm, /* 1 - tightly coupled, portable */ +#endif /* SM */ +}; + +/* Trace indication primitive */ + +PRIVATE LkwTrcInd kwMiLkwTrcIndMt[MAXKWMI] = +{ +#ifdef LCKWMILKW + cmPkLkwTrcInd, /* 0 - loosely coupled */ +#else + PtMiLkwTrcInd, /* 0 - tightly coupled, portable */ +#endif /* LCKWMILKW */ +#ifdef SM + SmMiLkwTrcInd, /* 1 - tightly coupled, layer management */ +#else + PtMiLkwTrcInd, /* 1 - tightly coupled, portable */ +#endif /* SM */ +}; + +/* kw005.201 added support for L2 Measurement */ +#ifdef LTE_L2_MEAS +PRIVATE CONSTANT LkwL2MeasCfm KwMiLkwL2MeasCfmMt[] = +{ +#ifdef LCKWMILKW + cmPkLkwL2MeasCfm, +#else + PtMiLkwL2MeasCfm, +#endif +#ifdef SM + SmMiLkwL2MeasCfm, +#else + PtMiLkwL2MeasCfm, +#endif +}; +PRIVATE CONSTANT LkwL2MeasStopCfm KwMiLkwL2MeasStopCfmMt[] = +{ +#ifdef LCKWMILKW + cmPkLkwL2MeasStopCfm, +#else + PtMiLkwL2MeasStopCfm, +#endif +#ifdef SM + SmMiLkwL2MeasStopCfm, +#else + PtMiLkwL2MeasStopCfm, +#endif +}; +#endif /* LTE_L2_MEAS */ + +/**************************************************************************** + * LKW Interface Mt functions + ***************************************************************************/ +/** + @brief + This function is called by the KwMiLkwCfgReq function for responding + to configuration requests.The cfm field in the KwMngmt structure contains + the response value. + + - This function calls the mapping matrix for sending the configuration + confirmation. + - The actual function called depends on the coupling at the LKW interface. + - For a loosely coupled interface, a common packing function is called. + - The packing function packs the parameter in a message buffer and posts + the message to the target task. + - For a tightly coupled interface, the actual function called depends on + the layer manager API provided. + +*/ +#ifdef ANSI +PUBLIC S16 KwMiLkwCfgCfm +( +Pst *pst, /* post structure */ +KwMngmt *cfm /* Layer Management structure */ +) +#else +PUBLIC S16 KwMiLkwCfgCfm(pst, cfm) +Pst *pst; /* post structure */ +KwMngmt *cfm; /* Layer Management structure */ +#endif +{ + TRC3(KwMiLkwCfgCfm); + + /* jump to specific primitive depending on configured selector */ + (*kwMiLkwCfgCfmMt[pst->selector])(pst, cfm); + + RETVALUE(ROK); +} + + +/** + @brief + This function is called by the KwMiLkwCntrlReq function to send a control confirm to the layer management module. + + - This function calls the mapping matrix for sending the control confirmation. + - Actual function called depends on the coupling of the LKW interface. + - For a loosely coupled interface, a common packing function is called. + - The packing function packs the parameter in a message buffer and posts the + message to the target task. + - For a tightly coupled interface, the actual function called depends on the + layer manager API provided. + +*/ +#ifdef ANSI +PUBLIC S16 KwMiLkwCntrlCfm +( +Pst *pst, /* post structure */ +KwMngmt *cfm /* configure */ +) +#else +PUBLIC S16 KwMiLkwCntrlCfm(pst, cfm) +Pst *pst; /* post structure */ +KwMngmt *cfm; /* confirm */ +#endif +{ + TRC3(KwMiLkwCntrlCfm) + + /* jump to specific primitive depending on configured selector */ + (*kwMiLkwCntrlCfmMt[pst->selector])(pst, cfm); + + RETVALUE(ROK); + +} /* end of KwMiLkwCntrlCfm */ + +/** + @brief + Description: + - This function can be used by RLC to send unsolicited status information + to the layer manager, when the unsolicited status flag is enabled by the + layer manager through a previous control request. + + - This function calls the mapping matrix for sending the unsolicited status + indication.The actual function called depends on the coupling of the + LKW interface. + + - For a loosely coupled interface, a common packing function is called. The + packing function packs the parameter in a message buffer and posts the + message to the target task. + + - For a tightly coupled interface, the actual function called depends on + the layer manager API provided. +*/ +#ifdef ANSI +PUBLIC S16 KwMiLkwStaInd +( +Pst *pst, /* post structure */ +KwMngmt *usta /* unsolicited status */ +) +#else +PUBLIC S16 KwMiLkwStaInd(pst, usta) +Pst *pst; /* post structure */ +KwMngmt *usta; /* unsolicited status */ +#endif +{ + TRC3(KwMiLkwStaInd); + + /* jump to specific primitive depending on configured selector */ + (*kwMiLkwStaIndMt[pst->selector])(pst, usta); + + RETVALUE(ROK); +} /* end of KwMiLkwStaInd */ + + +/** + @brief + - This function is called by the KwMiLkwStaReq function to send + the requested status information to the layer manager. + + - This function calls the mapping matrix for sending the status + confirmation. The actual function called depends on the coupling + of the LKW interface. + + - For a loosely coupled interface, a common packing function is called. + The packing function packs the parameter in a message buffer and + posts the message to the target task. + + - For a tightly coupled interface, the actual function called depends + on the layer manager API provided. + +*/ +#ifdef ANSI +PUBLIC S16 KwMiLkwStaCfm +( +Pst *pst, /* post structure */ +KwMngmt *cfm /* solicited status confirmation */ +) +#else +PUBLIC S16 KwMiLkwStaCfm(pst, cfm) +Pst *pst; /* post structure */ +KwMngmt *cfm; /* solicited status confirmation */ +#endif +{ + TRC3(KwMiLkwStaCfm); + + /* jump to specific primitive depending on configured selector */ + (*kwMiLkwStaCfmMt[pst->selector])(pst, cfm); + + RETVALUE(ROK); + +} /* end of KwMiLkwStaCfm */ + + +/** + @brief + - This function is called by the KwMiLkwStsReq function for responding + to statistics requests. + + - This function calls the mapping matrix for sending the statistics + confirmation. The actual function called depends on the coupling + of the LKW interface. + + - For a loosely coupled interface, a common packing function is called. + The packing function packs the parameter in a message buffer and + posts the message to the target task. + + - For a tightly coupled interface, the actual function called depends + on the layer manager API provided. + +*/ +#ifdef ANSI +PUBLIC S16 KwMiLkwStsCfm +( +Pst *pst, /* post structure */ +Action action, /* action */ +KwMngmt *cfm /* statistics confirmation */ +) +#else +PUBLIC S16 KwMiLkwStsCfm(pst, action, cfm) +Pst *pst; /* post structure */ +Action action; /* action */ +KwMngmt *cfm; /* statistics confirmation */ +#endif +{ + TRC3(KwMiLkwStsCfm); + + /* jump to specific primitive depending on configured selector */ + (*kwMiLkwStsCfmMt[pst->selector])(pst, action, cfm); + + RETVALUE(ROK); + +} /* end of KwMiLkwStsCfm */ + +/** + @brief + - This function can be used by RLC module to send unsolicited trace + indications to the layer manager, when tracing is enabled by the + layer manager through a previous control request. + + - This function calls the mapping matrix for sending the trace indication. + The actual function called depends on the coupling of the LKW interface. + + - For a loosely coupled interface, a common packing function is called. + The packing function packs the parameter in a message buffer and posts + the message to the target task. + + - For a tightly coupled interface, the actual function called depends on + the layer manager API provided. + +*/ +#ifdef ANSI +PUBLIC S16 KwMiLkwTrcInd +( +Pst *pst, /* post structure */ +KwMngmt *trc, /* trace indication */ +Buffer *mBuf /* message buffer */ +) +#else +PUBLIC S16 KwMiLkwTrcInd(pst, trc, mBuf) +Pst *pst; /* post structure */ +KwMngmt *trc; /* trace indication */ +Buffer *mBuf; /* message buffer */ +#endif +{ + TRC3(KwMiLkwTrcInd); + + /* jump to specific primitive depending on configured selector */ + (*kwMiLkwTrcIndMt[pst->selector])(pst, trc, mBuf); + + RETVALUE(ROK); + +} /* end of KwMiLkwTrcInd */ + + +/* kw005.201 added support for L2 Measurement */ +#ifdef LTE_L2_MEAS +#ifdef ANSI +PUBLIC S16 KwMiLkwL2MeasCfm +( +Pst * pst, +KwL2MeasCfmEvt *measEvt +) +#else +PUBLIC S16 KwMiLkwL2MeasCfm(pst, measEvt) +Pst * pst; +KwL2MeasCfmEvt *measEvt; +#endif +{ + + TRC3(KwMiLkwL2MeasCfm) + + (*KwMiLkwL2MeasCfmMt[pst->selector])(pst, measEvt); + + RETVALUE(ROK); + +} +#ifdef ANSI +PUBLIC S16 KwMiLkwL2MeasStopCfm +( +Pst *pst, +U8 measType, +U8 status +) +#else +PUBLIC S16 KwMiLkwL2MeasStopCfm(pst, measType,status) +Pst *pst; +U8 measType; +U8 status; +#endif +{ + + TRC3(KwMiLkwL2MeasStopCfm) + + (*KwMiLkwL2MeasStopCfmMt[pst->selector])(pst, measType,status); + + RETVALUE(ROK); + +} +#endif /* LTE_L2_MEAS */ +#ifdef PTKWLKW + + +/************************************************************************* + * Porting Functions + ************************************************************************/ +/* + * + * Fun: configuration Confirm + * + * Desc: This function is used to confirm the receipt of configuration + * request from layer management. + * + * Ret: ROK - ok + * + * Notes: None + * + * File: kw_ptmi.c + * + */ + +#ifdef ANSI +PUBLIC S16 PtMiLkwCfgCfm +( +Pst *pst, /* post structure */ +KwMngmt *cfm /* Layer Management structure */ +) +#else +PUBLIC S16 PtMiLkwCfgCfm(pst, cfm) +Pst *pst; /* post structure */ +KwMngmt *cfm; /* Layer Management structure */ +#endif +{ + TRC3(PtMiLkwCfgCfm) + + UNUSED(pst); + UNUSED(cfm); + + TRC2(PtMiLkwCfgCfm() : function is not implemented) + + RETVALUE(ROK); +} /* end of PtMiLkwCfgCfm */ + +/* + * + * Fun: Control Confirmation + * + * Desc: This function is the portable version of used to + * confirm the receipt of configuration request from + * layer management. + * + * Ret: ROK - ok + * + * Notes: None + * + * File: kw_ptmi.c + * + */ + +#ifdef ANSI +PRIVATE S16 PtMiLkwCntrlCfm +( +Pst *pst, /* Post structure */ +KwMngmt *cfm /* Layer Management structure */ +) +#else +PRIVATE S16 PtMiLkwCntrlCfm(pst, cfm) +Pst *pst; /* Post structure */ +KwMngmt *cfm; /* Layer Management structure */ +#endif +{ + TRC3(PtMiLkwCntrlCfm); + + UNUSED(pst); + UNUSED(cfm); + + TRC2(PtMiLkwCntrlCfm() : function is not implemented) + + RETVALUE(ROK); +} /* end of PtMiLkwCntrlCfm */ + + +/* + * + * Fun: unsolicited status indication + * + * Desc: This function is the portable version used to + * send the status indication to the layer manager + * + * Ret: ROK - ok + * + * Notes: None + * + * File: kw_ptmi.c + * + */ +#ifdef ANSI +PRIVATE S16 PtMiLkwStaInd +( +Pst *pst, /* post structure */ +KwMngmt *usta /* unsolicited status */ +) +#else +PRIVATE S16 PtMiLkwStaInd(pst, usta) +Pst *pst; /* post structure */ +KwMngmt *usta; /* unsolicited status */ +#endif +{ + TRC3(PtMiLkwStaInd) + + UNUSED(pst); + UNUSED(usta); + + TRC2(PtMiLkwStaInd() : function is not implemented) + + RETVALUE(ROK); +} /* end of PtMiLkwStaInd */ + + +/* + * + * Fun: portable function for solicited status confirmation + * + * Desc: This function is the portable version used to + * send the status confirmation to the layer manager + * + * Ret: ROK - ok + * + * Notes: None + * + * File: kw_ptmi.c + * + */ +#ifdef ANSI +PRIVATE S16 PtMiLkwStaCfm +( +Pst *pst, /* post structure */ +KwMngmt *cfm /* solicited status confirmation */ +) +#else +PRIVATE S16 PtMiLkwStaCfm(pst, cfm) +Pst *pst; /* post structure */ +KwMngmt *cfm; /* solicited status confirmation */ +#endif +{ + TRC3(PtMiLkwStaCfm) + + UNUSED(pst); + UNUSED(cfm); + + RETVALUE(ROK); +} /* end of PtMiLkwStaCfm */ + + +/* + * + * Fun: portable function for statistics confirmation + * + * Desc: This function is the portable version used to + * send the statistics confirmation to the layer manager + * + * Ret: ROK - ok + * + * Notes: None + * + * File: kw_ptmi.c + * + */ +#ifdef ANSI +PRIVATE S16 PtMiLkwStsCfm +( +Pst *pst, /* post structure */ +Action action, /* action */ +KwMngmt *cfm /* statistics confirmation */ +) +#else +PRIVATE S16 PtMiLkwStsCfm(pst, action, cfm) +Pst *pst; /* post structure */ +Action action; /* action */ +KwMngmt *cfm; /* statistics confirmation */ +#endif +{ + TRC3(PtMiLkwStsCfm) + + UNUSED(pst); + UNUSED(action); + UNUSED(cfm); + + RETVALUE(ROK); +} /* end of PtMiLkwStsCfm */ + + +/* + * + * Fun: portable function for trace indication + * + * Desc: This function is the portable version used to + * send trace indication to the layer manager + * + * Ret: ROK - ok + * + * Notes: None + * + * File: kw_ptmi.c + * + */ +#ifdef ANSI +PRIVATE S16 PtMiLkwTrcInd +( +Pst *pst, /* post structure */ +KwMngmt *trc, /* trace indication */ +Buffer *mBuf /* message buffer */ +) +#else +PRIVATE S16 PtMiLkwTrcInd(pst, trc, mBuf) +Pst *pst; /* post structure */ +KwMngmt *trc; /* trace indication */ +Buffer *mBuf; /* message buffer */ +#endif +{ + TRC3(PtMiLkwTrcInd) + + UNUSED(pst); + UNUSED(trc); + UNUSED(mBuf); + + RETVALUE(ROK); +} /* end of PtMiLkwTrcInd */ + +/* kw005.201 added support for L2 Measurement */ +#ifdef LTE_L2_MEAS +#ifdef ANSI +PRIVATE S16 PtMiLkwL2MeasCfm +( +Pst * pst, +KwL2MeasCfmEvt * measEvt +) +#else +PRIVATE S16 PtMiLkwL2MeasCfm(pst, measEvt) +Pst * pst; +KwL2MeasCfmEvt * measEvt; +#endif +{ + + TRC3(PtMiLkwL2MeasCfm) + + UNUSED(pst); + UNUSED(measEvt); + + RETVALUE(ROK); + +} +#ifdef ANSI +PRIVATE S16 PtMiLkwL2MeasStopCfm +( +Pst * pst, +U8 measType, +U8 status +) +#else +PRIVATE S16 PtMiLkwL2MeasStopCfm(pst, measType,status) +Pst * pst; +U8 measType; +U8 status; +#endif +{ + + TRC3(PtMiLkwL2MeasStopCfm) + + UNUSED(pst); + UNUSED(measType); + UNUSED(status); + + RETVALUE(ROK); + +} +#endif /* LTE_L2_MEAS */ +#endif /* PTKWLKW */ + + +/********************************************************************30** + + End of file +**********************************************************************/ diff --git a/src/5gnrrlc/kw_ptui.c b/src/5gnrrlc/kw_ptui.c new file mode 100755 index 000000000..99e00b043 --- /dev/null +++ b/src/5gnrrlc/kw_ptui.c @@ -0,0 +1,1729 @@ +/******************************************************************************* +################################################################################ +# Copyright (c) [2017-2019] [Radisys] # +# # +# 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. # +################################################################################ +*******************************************************************************/ + +/********************************************************************20** + + Name: LTE-RLC Layer - Upper Interface + + Type: C file + + Desc: C source code for the upper interface of LTE-RLC + + File: kw_ptui.c + +*********************************************************************21*/ +static const char* RLOG_MODULE_NAME="UIM"; +static int RLOG_MODULE_ID=2048; +static int RLOG_FILE_ID=199; + +/** @file kw_ptui.c +@brief RLC Upper Interface +*/ + + +/* header (.h) include files */ +#include "envopt.h" /* environment options */ +#include "envdep.h" /* environment dependent */ +#include "envind.h" /* environment independent */ + +#include "gen.h" /* general */ +#include "ssi.h" /* system services */ +#include "cm5.h" /* common timer defines */ +#include "cm_tkns.h" /* common tokens defines */ +#include "cm_mblk.h" /* common memory allocation library defines */ +#include "cm_llist.h" /* common link list defines */ +#include "cm_hash.h" /* common hash list defines */ +#include "cm_lte.h" /* common LTE defines */ +#include "lkw.h" /* LKW defines */ +#include "ckw.h" /* CKW defines */ +#include "kwu.h" /* KWU defines */ +#include "rgu.h" /* RGU defines */ + +#include "kw_err.h" +#include "kw_env.h" /* RLC environment options */ +#include "kw.h" /* RLC defines */ + +/* extern (.x) include files */ +#include "gen.x" /* general */ +#include "ssi.x" /* system services */ + +#include "cm5.x" /* common timer library */ +#include "cm_tkns.x" /* common tokens */ +#include "cm_mblk.x" /* common memory allocation */ +#include "cm_llist.x" /* common link list */ +#include "cm_hash.x" /* common hash list */ +#include "cm_lte.x" /* common LTE includes */ +#include "cm_lib.x" /* common memory allocation library */ +#include "lkw.x" /* LKW */ +#include "ckw.x" /* CKW */ +#include "kwu.x" /* KWU */ +#include "rgu.x" /* RGU */ +#if defined(MAC_RLC_UL_RBUF) || (defined(L2_L3_SPLIT) && defined(ICC_RECV_TSK_RBUF)) || defined(SS_RBUF) +#include "ss_rbuf.h" +#include "ss_rbuf.x" +#endif +#include "kw.x" +#if defined(L2_L3_SPLIT) && defined(ICC_RECV_TSK_RBUF) +#include "mt_plat_t33.h" +#include "mt_plat_t33.x" +#endif + +#ifndef LCKWUIKWU +#define PTKWKWU +#endif + +#ifndef LCKWUICKW +#define PTKWCKW +#endif + +#ifndef NH +#define PTKWKWU +#define PTKWCKW +#endif + +#ifndef PJ +#define PTKWKWU +#define PTKWCKW +#endif + + +#ifdef __cplusplus +EXTERN "C" { +#endif /* __cplusplus */ + + +/********************************************************************* + * Forward Declartion for KWU Porting Functions + ********************************************************************/ +#if defined(PDCP_RLC_DL_RBUF) || defined(SS_RBUF) +PUBLIC S16 kwDlBatchProc ARGS ((Void)); +PUBLIC S16 kwUtlDlFreeRlcRBuf ARGS((Void)); +EXTERN void kwUtlDlBatchProcHqStaInd ARGS ((Void)); +EXTERN Void kwUtlFreeDlMem ARGS((Void)); +EXTERN SsRngBufCnt rngCb; +EXTERN S16 kwUtlDlBatchProcPkts ARGS((Void)); +#endif + +#if (defined(L2_L3_SPLIT) && defined(ICC_RECV_TSK_RBUF)) +PUBLIC S16 kwDlBatchProcSplit ARGS((Void)); +#endif + +#ifdef PTKWKWU +PRIVATE S16 PtUiKwuBndCfm ARGS (( +Pst *pst, /* post structure */ +SuId suId, /* Service User Id */ +U8 status /* status */ +)); + +#endif /* PTKWKWU */ + +PUBLIC S16 PtUiKwuDatCfm ARGS (( +Pst *pst, +SuId suId, +KwuDatCfmInfo *datCfm +)); + +PUBLIC S16 PtUiKwuStaInd ARGS (( +Pst *pst, +SuId suId, +KwuStaIndInfo *staInd +)); + +PUBLIC S16 PtUiKwuReEstCmpInd ARGS (( +Pst *pst, +SuId suId, +CmLteRlcId rlcId +)); +/* kw005.201 added support for L2 Measurement */ +PUBLIC S16 PtUiKwuDiscSduCfm ARGS(( +Pst *pst, +SuId suId, +KwuDiscSduInfo *discCfm +)); +PUBLIC S16 PtUiKwuFlowCntrlInd ARGS(( +Pst *pst, +SuId suId, +KwuFlowCntrlIndInfo *flowCntrlIndInfo +)); +#ifdef LTE_L2_MEAS +PUBLIC S16 PtUiKwuDatAckInd ARGS(( +Pst *pst, +SuId suId, +KwuDatAckInfo *datAckInd +)); +#endif +#if (defined(PTKWKWU) || defined(KW_PDCP)) +PUBLIC S16 PtUiKwuDatInd ARGS (( +Pst *pst, +SuId suId, +KwuDatIndInfo *datInd, +Buffer *mBuf +)); +#endif /* PTKWKWU || KW_PDCP */ + + + +/********************************************************************* + * Forward Declartion for CKW Porting Functions + ********************************************************************/ +#ifdef PTKWCKW +PRIVATE S16 PtUiCkwBndCfm ARGS (( +Pst *pst, /* post structure */ +SuId suId, /* Service User Id */ +U8 status /* status */ +)); + +PUBLIC S16 PtUiCkwCfgCfm ARGS (( +Pst *pst, /* post structure */ +SuId suId, /* Service User Id */ +CkwCfgCfmInfo *cfmInfo /* Configuration Confirm */ +)); + +PUBLIC S16 PtUiCkwUeIdChgCfm ARGS(( +Pst *pst, /* post structure */ +SuId suId, /* Service User Id */ +U32 transId, +CkwUeInfo *ueInfo, +CmStatus status +)); + +#endif /* PTKWCKW */ + + + +/********************************************************************* + * Primitives for KWU interface + ********************************************************************/ + +/* KWU Bind Confirm primitive */ + +PUBLIC KwuBndCfm kwUiKwuBndCfmMt[] = +{ +#ifdef LCKWUIKWU + cmPkKwuBndCfm, /* 0 - loosely coupled */ +#else + PtUiKwuBndCfm, /* 0 - loosely coupled, portable */ +#endif /* LCKWUIKWU */ +#ifdef NH + NhLiKwuBndCfm, /* 1 - tightly coupled, RRC */ +#else + PtUiKwuBndCfm, /* 1 - tightly coupled, portable */ +#endif /* NH */ +#ifndef KW_PDCP +#ifdef PJ + PjLiKwuBndCfm, /* 2 - tightly coupled, PDCP */ +#else + PtUiKwuBndCfm, /* 2 - tightly coupled, portable */ +#endif /* NH */ +#endif /* KW_PDCP */ +#ifndef TENB_ACC +#ifdef LWLCKWUIKWU + cmPkKwuBndCfm, /* 3 - light weight loosely coupled */ +#else + PtUiKwuBndCfm, /* 3 - light weight loosely coupled, portable */ +#endif /* LCKWUIKWU */ +#endif /*TENB_ACC*/ +}; + +/* KWU Data Indication primitive */ + +PUBLIC KwuDatInd kwUiKwuDatIndMt[] = +{ +#ifdef LCKWUIKWU + cmPkKwuDatInd, /* 0 - loosely coupled */ +#else + PtUiKwuDatInd, /* 0 - loosely coupled, portable */ +#endif /* LCKWUIKWU */ +#ifdef NH + NhLiKwuDatInd, /* 1 - tightly coupled, RRC */ +#else + PtUiKwuDatInd, /* 1 - tightly coupled, portable */ +#endif /* NH */ +#ifdef KW_PDCP +#else +#ifdef PJ + PjLiKwuDatInd, /* 2 - tightly coupled, PDCP */ +#else + PtUiKwuDatInd, /* 2 - tightly coupled, portable */ +#endif /* NH */ +#ifndef TENB_ACC +#ifdef LWLCKWUIKWU + cmPkKwuDatInd, /* 3 - light weight loosely coupled */ +#else + PtUiKwuDatInd, /* 3 - light weight loosely coupled, portable */ +#endif /* LCKWUIKWU */ +#endif /*TENB_ACC*/ +#endif /* KW_PDCP */ +}; + +#ifndef KW_PDCP +PUBLIC KwuDatCfm kwUiKwuDatCfmMt[] = +{ +#ifdef LCKWUIKWU + cmPkKwuDatCfm, /* 0 - loosely coupled */ +#else + PtUiKwuDatCfm, /* 0 - loosely coupled, portable */ +#endif /* LCKWUIKWU */ + PtUiKwuDatCfm, /* 1 - tightly coupled, portable */ +#ifdef PJ + PjLiKwuDatCfm, /* 2 - tightly coupled, PDCP */ +#else + PtUiKwuDatCfm, /* 2 - tightly coupled, portable */ +#endif /* PJ */ +#ifndef TENB_ACC +#ifdef LWLCKWUIKWU + cmPkKwuDatCfm, /* 3 - light weight loosely coupled */ +#else + PtUiKwuDatCfm, /* 3 - light weight loosely coupled, portable */ +#endif /* LCKWUIKWU */ +#endif /*TENB_ACC*/ +}; + +/* KWU AM Status Indication primitive */ + +PUBLIC KwuStaInd kwUiKwuStaIndMt[] = +{ +#ifdef LCKWUIKWU + cmPkKwuStaInd, /* 0 - loosely coupled */ +#else + PtUiKwuStaInd, /* 0 - loosely coupled, portable */ +#endif /* LCKWUIKWU */ + PtUiKwuStaInd, /* 2 - tightly coupled, portable */ +#ifdef PJ + PjLiKwuStaInd, /* 2 - tightly coupled, PDCP */ +#else + PtUiKwuStaInd, /* 2 - tightly coupled, portable */ +#endif /* PJ */ +#ifndef TENB_ACC +#ifdef LWLCKWUIKWU + cmPkKwuStaInd, /* 3 - light weight loosely coupled */ +#else + PtUiKwuStaInd, /* 3 - light weight loosely coupled, portable */ +#endif /* LCKWUIKWU */ +#endif /*TENB_ACC*/ +}; + +PUBLIC KwuReEstCmpInd kwUiKwuReEstCmpIndMt[] = +{ +#ifdef LCKWUIKWU + cmPkKwuReEstCmpInd, /* 0 - loosely coupled */ +#else + PtUiKwuReEstCmpInd, /* 0 - loosely coupled, portable */ +#endif /* LCKWUIKWU */ + PtUiKwuReEstCmpInd, /* 1 - loosely coupled, portable */ +#ifdef PJ + PjLiKwuReEstCmpInd, /* 2 - tightly coupled, PDCP */ +#else + PtUiKwuReEstCmpInd, /* 2 - tightly coupled, portable */ +#endif /* PJ */ +#ifndef TENB_ACC +#ifdef LWLCKWUIKWU + cmPkKwuReEstCmpInd, /* 3 - light weight loosely coupled */ +#else + PtUiKwuReEstCmpInd, /* 3 - light weight loosely coupled, portable */ +#endif /* LCKWUIKWU */ +#endif /*TENB_ACC*/ +}; + +/* kw005.201 added support for L2 measurement */ +PUBLIC KwuDiscSduCfm kwUiKwuDiscSduCfmMt[] = +{ +#ifdef LCKWUIKWU + cmPkKwuDiscSduCfm, /* 0 - loosely coupled */ +#else + PtUiKwuDiscSduCfm, /* 0 - loosely coupled, portable */ +#endif /* LCKWUIKWU */ + PtUiKwuDiscSduCfm, /* 1 - loosely coupled portable */ +#ifdef PJ + PjLiKwuDiscSduCfm, /* 2 - tightly coupled, PDCP */ +#else + PtUiKwuDiscSduCfm, /* 2 - tightly coupled, PDCP */ +#endif +#ifndef TENB_ACC +#ifdef LWLCKWUIKWU + cmPkKwuDiscSduCfm, /* 3 - light weight loosely coupled */ +#else + PtUiKwuDiscSduCfm, /* 3 - light weight loosely coupled, portable */ +#endif /* PJ */ +#endif /*TENB_ACC*/ +}; +PUBLIC KwuFlowCntrlInd kwUiKwuFlowCntrlIndMt[] = +{ +#ifdef LCKWUIKWU + cmPkKwuFlowCntrlInd, /* 0 - loosely coupled */ +#else + PtUiKwuFlowCntrlInd, /* 0 - loosely coupled, portable */ +#endif /* LCKWUIKWU */ + PtUiKwuFlowCntrlInd, /* 1 - loosely coupled portable */ +#ifdef PJ + PjLiKwuFlowCntrlInd, /* 2 - tightly coupled, PDCP */ +#else + PtUiKwuFlowCntrlInd, /* 2 - tightly coupled, portable */ +#endif /* PJ */ +#ifdef LCKWUIKWU + cmPkKwuFlowCntrlInd, /* 3 - light weight loosely coupled */ +#else + PtUiKwuFlowCntrlInd, /* 3 - light weight loosely coupled, portable */ +#endif /* LCKWUIKWU */ +}; +#ifdef LTE_L2_MEAS +PUBLIC KwuDatAckInd kwUiKwuDatAckIndMt[] = +{ +#ifdef LCKWUIKWU + cmPkKwuDatAckInd, /* 0 - loosely coupled */ +#else + PtUiKwuDatAckInd, /* 0 - loosely coupled, portable */ +#endif /* LCKWUIKWU */ + PtUiKwuDatAckInd, /* 1 - loosely coupled, portable */ +#ifdef PJ + PjLiKwuDatAckInd, /* 2 - tightly coupled, PDCP */ +#else + PtUiKwuDatAckInd, /* 1 - tightly coupled, portable */ +#endif /* PJ */ +#ifndef TENB_ACC +#ifdef LWLCKWUIKWU + cmPkKwuDatAckInd, /* 3 - light weight loosely coupled, portable */ +#else + PtUiKwuDatAckInd, /* 3 - light weight loosely coupled */ +#endif /* PJ */ +#endif /*TENB_ACC*/ +}; +#endif /* LTE_L2_MEAS */ +/* KWU AM Data confirm primitive */ + +#endif /* KW_PDCP */ + + +/**************************************************************************** + * KWU Interface Mt functions + ***************************************************************************/ +/** + * + * @brief + * + * Handler for confirming the bind request received from KWU + * interface. + * + * @b Description: + * + * This function send the bind confirm primitive to the RLC user, + * when it receives a bind request from its service user. + * + * @param[in] pst Post structure + * @param[in] suId Service user SAP ID + * @param[in] status Status of Confirmation + * + * @return S16 + * -# ROK + * + */ +#ifdef ANSI +PUBLIC S16 KwUiKwuBndCfm +( +Pst *pst, /* post structure */ +SuId suId, /* Service User Id */ +U8 status /* Status */ +) +#else +PUBLIC S16 KwUiKwuBndCfm(pst, suId, status) +Pst *pst; /* post structure */ +SuId suId; /* Service User Id */ +U8 status; /* Status */ +#endif +{ + TRC3(KwUiKwuBndCfm) + + /* jump to specific primitive depending on configured selector */ + (*kwUiKwuBndCfmMt[pst->selector])(pst, suId, status); + + RETVALUE(ROK); + +} /* end of KwUiKwuBndCfm */ + + +/** + * + * @brief + * + * Handler for sending the data(SDU) from upper layer. + * + * @b Description: + * + * This function is used to transfer a SDU received from the peer + * RLC entity to the service user(RRC/PDCP). + * + * @param[in] pst Post structure + * @param[in] suId Service User SAP ID + * @param[in] datIndInfo Data Request Information + * @param[in] mBuf Data Buffer (SDU) + * + * @return S16 + * -# ROK + * -# RFAILED + */ +#ifdef ANSI +PUBLIC S16 KwUiKwuDatInd +( +Pst *pst, +SuId suId, +KwuDatIndInfo *datInd, +Buffer *mBuf +) +#else +PUBLIC S16 KwUiKwuDatInd(pst, suId, datInd, mBuf) +Pst *pst; +SuId suId; +KwuDatIndInfo *datInd; +Buffer *mBuf; +#endif +{ + TRC3(KwUiKwuDatInd) + + /* jump to specific primitive depending on configured selector */ + (*kwUiKwuDatIndMt[pst->selector])(pst, suId, datInd, mBuf); + + RETVALUE(ROK); + +} /* end of KwUiKwuDatInd */ + + PUBLIC int rlcDatCfmsSent = 0; + +#ifndef KW_PDCP +/** + * + * @brief + * + * Handler for sending the data confirmation to upper layer. + * + * @b Description: + * + * This function is used to send a confirmation to the service + * user about the data received by the peer RLC entity. + * + * @param[in] pst Post structure + * @param[in] suId Service User SAP ID + * @param[in] datCfmInfo Data Confirmation Information + * + * @return S16 + * -# ROK + * -# RFAILED + */ +#ifdef ANSI +PUBLIC S16 KwUiKwuDatCfm +( +Pst *pst, +SuId suId, +KwuDatCfmInfo *datCfm +) +#else +PUBLIC S16 KwUiKwuDatCfm(pst, suId, datCfm) +Pst *pst; +SuId suId; +KwuDatCfmInfo *datCfm; +#endif +{ + rlcDatCfmsSent++; + TRC3(KwUiKwuDatCfm) + + /* jump to specific primitive depending on configured selector */ + (*kwUiKwuDatCfmMt[pst->selector])(pst, suId, datCfm); + + RETVALUE(ROK); + +} /* end of KwUiKwuDatCfm */ + + +/** + * + * @brief + * + * Handler for sending the Status Indication to the upper layer. + * + * @b Description: + * + * This function is used only by RLC AM entity.It send status + * indication to the upper layer about the maximum number of + * re-transmissions reached for a RLC AM entity. + * + * @param[in] pst Post structure + * @param[in] suId Service User SAP ID + * @param[in] staInd RLC Entity Id + * + * @return S16 + * -# ROK + * -# RFAILED + */ +#ifdef ANSI +PUBLIC S16 KwUiKwuStaInd +( +Pst *pst, +SuId suId, +KwuStaIndInfo *staInd +) +#else +PUBLIC S16 KwUiKwuStaInd(pst, suId, staInd) +Pst *pst; +SuId suId; +KwuStaIndInfo *staInd; +#endif +{ + TRC3(KwUiKwuStaInd) + + /* jump to specific primitive depending on configured selector */ + (*kwUiKwuStaIndMt[pst->selector])(pst, suId, staInd); + + RETVALUE(ROK); + +} /* end of KwUiKwuStaInd */ + + +/** + * + * @brief + * + * Handler for sending the Status Indication to the upper layer. + * + * @b Description: + * + * This function is used only by RLC AM entity.It send status + * indication to the upper layer about the maximum number of + * re-transmissions reached for a RLC AM entity. + * + * @param[in] pst Post structure + * @param[in] suId Service User SAP ID + * @param[in] staInd RLC Entity Id + * + * @return S16 + * -# ROK + * -# RFAILED + */ +#ifdef ANSI +PUBLIC S16 KwUiKwuReEstCmpInd +( +Pst *pst, +SuId suId, +CmLteRlcId rlcId +) +#else +PUBLIC S16 KwUiKwuReEstCmpInd(pst, suId, rlcId) +Pst *pst; +SuId suId; +CmLteRlcId rlcId; +#endif +{ + TRC3(KwUiKwuReEstCmpInd) + RLOG0(L_DEBUG, "In KwUiKwuReEstCmpInd"); + + /* jump to specific primitive depending on configured selector */ + (*kwUiKwuReEstCmpIndMt[pst->selector])(pst, suId, rlcId); + + RETVALUE(ROK); + +} /* end of KwUiKwuReEstCmpInd */ +/* kw005.201 added support for L2 Measurement */ + +/** + * + * @brief + * + * Handler for sending the Sdu Disc Cfm to the upper layer. + * + * @b Description: + * + * This function confirms the discard of an SDU . + * + * @param[in] pst Post structure + * @param[in] suId Service User SAP ID + * @param[in] discCfm Disc information. + * + * @return S16 + * -# ROK + * -# RFAILED + */ +#ifdef ANSI +PUBLIC S16 KwUiKwuDiscSduCfm +( +Pst *pst, +SuId suId, +KwuDiscSduInfo *discCfm +) +#else +PUBLIC S16 KwUiKwuDiscSduCfm(pst, suId, discCfm) +Pst *pst; +SuId suId; +KwuDiscSduInfo *discCfm; +#endif +{ + TRC3(KwUiKwuDiscSduCfm) + + /* jump to specific primitive depending on configured selector */ + (*kwUiKwuDiscSduCfmMt[pst->selector])(pst, suId, discCfm); + + RETVALUE(ROK); + +} /* end of KwUiKwuDiscSduCfm */ + +/** + * + * @brief + * + * Handler for sending Flow indication to the upper layer. + * + * @b Description: + * + * This function indicates to PDCP if packets need to be stopped or + * started for a particular RB + * + * @param[in] pst Post structure + * @param[in] suId Service User SAP ID + * @param[in] flowCntrlIndInfo Flow control information. + * + * @return S16 + * -# ROK + * -# RFAILED + */ +#ifdef ANSI +PUBLIC S16 KwUiKwuFlowCntrlInd +( +Pst *pst, +SuId suId, +KwuFlowCntrlIndInfo *flowCntrlIndInfo +) +#else +PUBLIC S16 KwUiKwuFlowCntrlInd(pst, suId, flowCntrlIndInfo) +Pst *pst; +SuId suId; +KwuFlowCntrlIndInfo *flowCntrlIndInfo; +#endif +{ + TRC3(KwUiKwuFlowCntrlInd) + + /* jump to specific primitive depending on configured selector */ + (*kwUiKwuFlowCntrlIndMt[pst->selector])(pst, suId, flowCntrlIndInfo); + + RETVALUE(ROK); + +} /* end of KwUiKwuFlowCntrlInd */ +#ifdef LTE_L2_MEAS + +/** + * + * @brief + * + * Handler for sending the Data ack indication to the upper layer. + * + * @b Description: + * + * This function confirms the succesfull transmission of SDU + * + * @param[in] pst Post structure + * @param[in] suId Service User SAP ID + * @param[in] datAckInd DatAckInd + * + * @return S16 + * -# ROK + * -# RFAILED + */ +#ifdef ANSI +PUBLIC S16 KwUiKwuDatAckInd +( +Pst *pst, +SuId suId, +KwuDatAckInfo *datAckInd +) +#else +PUBLIC S16 KwUiKwuDatAckInd(pst, suId, datAckInd) +Pst *pst; +SuId suId; +KwuDatAckInfo *datAckInd; +#endif +{ + TRC3(KwUiKwuDatAckInd) + + /* jump to specific primitive depending on configured selector */ + (*kwUiKwuDatAckIndMt[pst->selector])(pst, suId, datAckInd); + + RETVALUE(ROK); + +} /* end of KwUiKwuDatAckInd */ +#endif /* LTE_L2_MEAS */ +#endif /* KW_PDCP */ + + +#ifdef PTKWKWU +/************************************************************************* + * KWU Porting Functions + ************************************************************************/ +/** + * + * @brief + * + * PtUiKwuBndCfm - Portable SAP bind confirm + * + * @param[in] pst - Post structure + * @param[in] suId - Service user SAP ID + * @param[in] status - Status + * + * @return S16 + * -# ROK + */ +#ifdef ANSI +PRIVATE S16 PtUiKwuBndCfm +( +Pst *pst, /* post structure */ +SuId suId, /* Service User Id */ +U8 status /* status */ +) +#else +PRIVATE S16 PtUiKwuBndCfm(pst, suId, status) +Pst *pst; /* post structure */ +SuId suId; /* Service User Id */ +U8 status; /* status */ +#endif +{ +#if (ERRCLASS & ERRCLS_DEBUG) + KwCb *tKwCb; +#endif + TRC3(PtUiKwuBndCfm); + + UNUSED(suId); + UNUSED(status); +#if (ERRCLASS & ERRCLS_DEBUG) + if (pst->srcInst >= KW_MAX_RLC_INSTANCES) + { + RETVALUE(RFAILED); + } + + tKwCb = KW_GET_KWCB(pst->srcInst); + RLOG0(L_ERROR, "Improper selector value"); +#endif /* (ERRCLASS & ERRCLS_DEBUG) */ + + RETVALUE(ROK); +} /* end of PtUiKwuBndCfm */ +#endif /* PTKWKWU */ + + +/** + * + * @brief + * + * PtUiKwuDatCfm - Portable common channel data request + * + * @param[in] pst - Post structure + * @param[in] suId - Service user SAP ID + * @param[in] datCfm - Data Request + * + * @return S16 + * -# ROK + */ +#ifdef ANSI +PUBLIC S16 PtUiKwuDatCfm +( +Pst *pst, +SuId suId, +KwuDatCfmInfo *datCfm +) +#else +PUBLIC S16 PtUiKwuDatCfm(pst, suId, datCfm) +Pst *pst; +SuId suId; +KwuDatCfmInfo *datCfm; +#endif +{ +#if (ERRCLASS & ERRCLS_DEBUG) + KwCb *tKwCb; +#endif + TRC3(PtUiKwuDatCfm) + + UNUSED(pst); + UNUSED(suId); + UNUSED(datCfm); +#if (ERRCLASS & ERRCLS_DEBUG) + if (pst->srcInst >= KW_MAX_RLC_INSTANCES) + { + RETVALUE(RFAILED); + } + tKwCb = KW_GET_KWCB(pst->srcInst); + + RLOG0(L_ERROR, "Improper selector value"); +#endif /* (ERRCLASS & ERRCLS_DEBUG) */ + + RETVALUE(ROK); + +} /* end of PtUiKwuDatCfm */ + + +/** + * + * @brief + * + * PtUiKwuStaInd - Portable common channel data request + * + * @param[in] pst - Post structure + * @param[in] suId - Service user SAP ID + * @param[in] staInd - Data Request + * + * @return S16 + * -# ROK + */ +#ifdef ANSI +PUBLIC S16 PtUiKwuStaInd +( +Pst *pst, +SuId suId, +KwuStaIndInfo *staInd +) +#else +PUBLIC S16 PtUiKwuStaInd(pst, suId, staInd) +Pst *pst; +SuId suId; +KwuStaIndInfo *staInd; +#endif +{ +#if (ERRCLASS & ERRCLS_DEBUG) + KwCb *tKwCb; +#endif + TRC3(PtUiKwuStaInd) + + UNUSED(pst); + UNUSED(suId); + UNUSED(staInd); + +#if (ERRCLASS & ERRCLS_DEBUG) + if (pst->srcInst >= KW_MAX_RLC_INSTANCES) + { + RETVALUE(RFAILED); + } + tKwCb = KW_GET_KWCB(pst->srcInst); + RLOG0(L_ERROR, "Improper selector value"); +#endif /* (ERRCLASS & ERRCLS_DEBUG) */ + + RETVALUE(ROK); + +} /* end of PtUiKwuStaInd */ + + +/** + * + * @brief + * + * PtUiKwuReEstCmpInd - Portable common channel data request + * + * @param[in] pst - Post structure + * @param[in] suId - Service user SAP ID + * @param[in] staInd - Data Request + * + * @return S16 + * -# ROK + */ +#ifdef ANSI +PUBLIC S16 PtUiKwuReEstCmpInd +( +Pst *pst, +SuId suId, +CmLteRlcId rlcId +) +#else +PUBLIC S16 PtUiKwuReEstCmpInd(pst, suId, rlcId) +Pst *pst; +SuId suId; +CmLteRlcId rlcId; +#endif +{ +#if (ERRCLASS & ERRCLS_DEBUG) + KwCb *tKwCb; +#endif + TRC3(PtUiKwuReEstCmpInd) + + UNUSED(pst); + UNUSED(suId); + UNUSED(rlcId); + +#if (ERRCLASS & ERRCLS_DEBUG) + if (pst->srcInst >= KW_MAX_RLC_INSTANCES) + { + RETVALUE(RFAILED); + } + tKwCb = KW_GET_KWCB(pst->srcInst); + RLOG0(L_ERROR, "Improper selector value"); +#endif /* (ERRCLASS & ERRCLS_DEBUG) */ + + RETVALUE(ROK); + +} /* end of PtUiKwuReEstCmpInd */ + +/* kw005.201 added support for L2 Measurement */ +/* + * @brief + * + * PtUiKwuDiscSduCfm - Portable common channel data request + * + * @param[in] pst - Post structure + * @param[in] suId - Service user SAP ID + * @param[in] staInd - Data Request + * + * @return S16 + * -# ROK + */ +#ifdef ANSI +PUBLIC S16 PtUiKwuDiscSduCfm +( +Pst *pst, +SuId suId, +KwuDiscSduInfo *discCfm +) +#else +PUBLIC S16 PtUiKwuDiscSduCfm(pst, suId, discCfm) +Pst *pst; +SuId suId; +KwuDiscSduInfo *discCfm; +#endif +{ +#if (ERRCLASS & ERRCLS_DEBUG) + KwCb *tKwCb; +#endif + TRC3(PtUiKwuDiscSduCfm) + + UNUSED(pst); + UNUSED(suId); + UNUSED(discCfm); + +#if (ERRCLASS & ERRCLS_DEBUG) + if (pst->srcInst >= KW_MAX_RLC_INSTANCES) + { + RETVALUE(RFAILED); + } + tKwCb = KW_GET_KWCB(pst->srcInst); + RLOG0(L_ERROR, "Improper selector value"); +#endif /* (ERRCLASS & ERRCLS_DEBUG) */ + + RETVALUE(ROK); + +} /* end of PtUiKwuDiscSduCfm */ + +/* + * @brief + * + * PtUiKwuFlowCntrlInd - Portable Flow control idication + * + * @param[in] pst - Post structure + * @param[in] suId - Service user SAP ID + * @param[in] flowCntrlInd - Flow control information + * + * @return S16 + * -# ROK + */ +#ifdef ANSI +PUBLIC S16 PtUiKwuFlowCntrlInd +( +Pst *pst, +SuId suId, +KwuFlowCntrlIndInfo *flowCntrlIndInfo +) +#else +PUBLIC S16 PtUiKwuFlowCntrlInd(pst, suId, flowCntrlIndInfo) +Pst *pst; +SuId suId; +KwuFlowCntrlIndInfo *flowCntrlIndInfo; +#endif +{ +#if (ERRCLASS & ERRCLS_DEBUG) + KwCb *tKwCb; +#endif + TRC3(PtUiKwuFlowCntrlInd) + + UNUSED(pst); + UNUSED(suId); + UNUSED(flowCntrlIndInfo); + +#if (ERRCLASS & ERRCLS_DEBUG) + if (pst->srcInst >= KW_MAX_RLC_INSTANCES) + { + RETVALUE(RFAILED); + } + tKwCb = KW_GET_KWCB(pst->srcInst); + RLOG0(L_ERROR, "Improper selector value"); +#endif /* (ERRCLASS & ERRCLS_DEBUG) */ + + RETVALUE(ROK); + +} /* end of PtUiKwuFlowCntrlInd */ +#ifdef LTE_L2_MEAS + +/** + * + * @brief + * + * Handler for sending the Data ack indication to the upper layer. + * + * @b Description: + * + * This function confirms the succesfull transmission of SDU + * + * @param[in] pst Post structure + * @param[in] suId Service User SAP ID + * @param[in] datAckInd DatAckInd + * + * @return S16 + * -# ROK + * -# RFAILED + */ +#ifdef ANSI +PUBLIC S16 PtUiKwuDatAckInd +( +Pst *pst, +SuId suId, +KwuDatAckInfo *datAckInd +) +#else +PUBLIC S16 PtUiKwuDatAckInd(pst, suId, datAckInd) +Pst *pst; +SuId suId; +KwuDatAckInfo *datAckInd; +#endif +{ +#if (ERRCLASS & ERRCLS_DEBUG) + KwCb *tKwCb; +#endif + TRC3(PtUiKwuDatAckInd) + + UNUSED(pst); + UNUSED(suId); + UNUSED(datAckInd); +#if (ERRCLASS & ERRCLS_DEBUG) + if (pst->srcInst >= KW_MAX_RLC_INSTANCES) + { + RETVALUE(RFAILED); + } + tKwCb = KW_GET_KWCB(pst->srcInst); + + RLOG0(L_ERROR, "Improper selector value"); +#endif /* (ERRCLASS & ERRCLS_DEBUG) */ + RETVALUE(ROK); +}/* end of PtUiKwuDatAckInd */ +#endif /* LTE_L2_MEAS */ +#if (defined(PTKWKWU) || defined(KW_PDCP)) + +/** + * + * @brief + * + * PtUiKwuDatInd - Portable common channel data request + * + * @param[in] pst - Post structure + * @param[in] suId - Service user SAP ID + * @param[in] datInd - Data Request + * + * @return S16 + * -# ROK + */ +#ifdef ANSI +PUBLIC S16 PtUiKwuDatInd +( +Pst *pst, +SuId suId, +KwuDatIndInfo *datInd, +Buffer *mBuf +) +#else +PUBLIC S16 PtUiKwuDatInd(pst, suId, datInd, mBuf) +Pst *pst; +SuId suId; +KwuDatIndInfo *datInd; +Buffer *mBuf; +#endif +{ +#if (ERRCLASS & ERRCLS_DEBUG) + KwCb *tKwCb; +#endif + TRC3(PtUiKwuDatInd) + + UNUSED(pst); + UNUSED(suId); + UNUSED(datInd); + UNUSED(mBuf); + +#if (ERRCLASS & ERRCLS_DEBUG) + if (pst->srcInst >= KW_MAX_RLC_INSTANCES) + { + RETVALUE(RFAILED); + } + tKwCb = KW_GET_KWCB(pst->srcInst); + RLOG0(L_ERROR, "Improper selector value"); +#endif /* (ERRCLASS & ERRCLS_DEBUG) */ + + RETVALUE(ROK); + +} /* end of PtUiKwuDatInd */ +#endif /* PTKWKWU || KW_PDCP */ + + + +/********************************************************************* + * Primitives for CKW interface + ********************************************************************/ + +/* CKW Bind Confirm primitive */ + +PUBLIC CkwBndCfm kwUiCkwBndCfmMt[] = +{ +#ifdef LCKWUICKW + cmPkCkwBndCfm, /* 0 - loosely coupled */ +#else + PtUiCkwBndCfm, /* 0 - loosely coupled, portable */ +#endif /* LCCKUICKW */ +#ifdef NH + NhLiCkwBndCfm, /* 1 - tightly coupled, RRC */ +#else + PtUiCkwBndCfm, /* 1 - tightly coupled, portable */ +#endif /* NH */ +}; + +/* CKW Configuration confirm primitive */ + +PUBLIC CkwCfgCfm kwUiCkwCfgCfmMt[] = +{ +#ifdef LCKWUICKW + cmPkCkwCfgCfm, /* 0 - loosely coupled */ +#else + PtUiCkwCfgCfm, /* 0 - loosely coupled, portable */ +#endif /* LCKWUICKW */ +#ifdef NH + NhLiCkwCfgCfm, /* 1 - tightly coupled, RRC */ +#else + PtUiCkwCfgCfm, /* 1 - tightly coupled, portable */ +#endif /* NH */ +}; + +PUBLIC CkwUeIdChgCfm kwUiCkwUeIdChgCfmMt[] = +{ +#ifdef LCKWUICKW + cmPkCkwUeIdChgCfm, /* 0 - loosely coupled */ +#else + PtUiCkwUeIdChgCfm, /* 0 - loosely coupled, portable */ +#endif /* LCKWUICKW */ +#ifdef NH + NhLiCkwUeIdChgCfm, /* 1 - tightly coupled, RRC */ +#else + PtUiCkwUeIdChgCfm, /* 1 - tightly coupled, portable */ +#endif /* NH */ +}; + + + +/**************************************************************************** + * CKW Interface Mt functions + ***************************************************************************/ +/** + * + * @brief + * + * Handler for confirming the bind request received from CKW + * interface. + * + * @b Description: + * + * This function send the bind confirm primitive to the RLC user, + * when it receives a bind request from its service user. + * + * @param[in] pst - Post structure + * @param[in] suId - Service user SAP ID + * @param[in] status - Status + * + * @return S16 + * -# ROK + */ +#ifdef ANSI +PUBLIC S16 KwUiCkwBndCfm +( +Pst *pst, /* post structure */ +SuId suId, /* Service User Id */ +U8 status /* Status */ +) +#else +PUBLIC S16 KwUiCkwBndCfm(pst, suId, status) +Pst *pst; /* post structure */ +SuId suId; /* Service User Id */ +U8 status; /* Status */ +#endif +{ + TRC3(KwUiCkwBndCfm) + + /* jump to specific primitive depending on configured selector */ + (*kwUiCkwBndCfmMt[pst->selector])(pst, suId, status); + + RETVALUE(ROK); + +} /* end of KwUiCkwBndCfm */ + + +/** + * + * @brief + * + * Handler for sending a configuration confirm to RRC. + * + * @b Description: + * + * This function is used by RLC user to send a configuration + * confirmation to RRC after configuring(add/delete/modify) + * the RLC entities. + * + * @param[in] pst Post structure + * @param[in] transId Transaction Id + * @param[in] cfmInfo Config Confirmation Info + * + * @return S16 + * -# ROK + * + */ +#ifdef ANSI +PUBLIC S16 KwUiCkwCfgCfm +( +Pst *pst, /* post structure */ +SuId suId, /* Service User Id */ +CkwCfgCfmInfo *cfmInfo /* Configuration Confirm */ +) +#else +PUBLIC S16 KwUiCkwCfgCfm(pst, suId, cfmInfo) +Pst *pst; /* post structure */ +SuId suId; /* Service User Id */ +CkwCfgCfmInfo *cfmInfo; /* Configuration Confirm */ +#endif +{ + TRC3(KwUiCkwCfgCfm) + + /* jump to specific primitive depending on configured selector */ + (*kwUiCkwCfgCfmMt[pst->selector])(pst, suId, cfmInfo); + + RETVALUE(ROK); + +} /* end of KwUiCkwCfgCfm */ + + +/** + * + * @brief + * + * Handler for sending a configuration for UE ID change. + * + * @b Description: + * + * This function is used by RLC to send a configuration + * confirm for UE ID change. + * + * @param[in] pst Post structure + * @param[in] suId Service User Id + * @param[in] transId Transaction Id + * @param[in] cfmInfo Config Confirmation Info + * + * @return S16 + * -# ROK + * + */ +#ifdef ANSI +PUBLIC S16 KwUiCkwUeIdChgCfm +( +Pst *pst, /* post structure */ +SuId suId, /* Service User Id */ +U32 transId, +CkwUeInfo *ueInfo, +CmStatus status +) +#else +PUBLIC S16 KwUiCkwUeIdChgCfm(pst, suId, transId,ueInfo,status) +Pst *pst; /* post structure */ +SuId suId; /* Service User Id */ +U32 transId; +CkwUeInfo *ueInfo; +CmStatus status; +#endif +{ + TRC3(KwUiCkwUeIdChgCfm) + + /* jump to specific primitive depending on configured selector */ + (*kwUiCkwUeIdChgCfmMt[pst->selector])(pst, suId, transId, ueInfo, status); + + RETVALUE(ROK); + +} /* end of KwUiCkwCfgCfm */ + + +#ifdef PTKWCKW +/************************************************************************* + * CKW Porting Functions + ************************************************************************/ +/** + * + * @brief + * + * KwUiCkwBndCfm - CKW SAP bind confirm + * + * @param[in] pst - Post structure + * @param[in] suId - Service user SAP ID + * @param[in] status - Status + * + * @return S16 + * -# ROK + */ +#ifdef ANSI +PRIVATE S16 PtUiCkwBndCfm +( +Pst *pst, /* post structure */ +SuId suId, /* Service User Id */ +U8 status /* status */ +) +#else +PRIVATE S16 PtUiCkwBndCfm(pst, suId, status) +Pst *pst; /* post structure */ +SuId suId; /* Service User Id */ +U8 status; /* status */ +#endif +{ +#if (ERRCLASS & ERRCLS_DEBUG) + KwCb *tKwCb; +#endif + TRC3(PtUiCkwBndCfm); + + UNUSED(pst); + UNUSED(suId); + UNUSED(status); + +#if (ERRCLASS & ERRCLS_DEBUG) + if (pst->srcInst >= KW_MAX_RLC_INSTANCES) + { + RETVALUE(RFAILED); + } + tKwCb = KW_GET_KWCB(pst->srcInst); + RLOG0(L_ERROR, "Improper selector value"); +#endif /* (ERRCLASS & ERRCLS_DEBUG) */ + + RETVALUE(ROK); +} /* end of PtUiCkwBndCfm */ + + +/** + * + * @brief + * + * PtUiCkwCfgCfm - KWU SAP bind confirm + * + * @param[in] pst - Post structure + * @param[in] suId - Service user SAP ID + * @param[in] cfmInfo - Configuration confirm + * + * @return S16 + * -# ROK + */ +#ifdef ANSI +PUBLIC S16 PtUiCkwCfgCfm +( +Pst *pst, /* post structure */ +SuId suId, /* Service User Id */ +CkwCfgCfmInfo *cfmInfo /* Configuration Confirm */ +) +#else +PUBLIC S16 PtUiCkwCfgCfm(pst, suId, cfmInfo) +Pst *pst; /* post structure */ +SuId suId; /* Service User Id */ +CkwCfgCfmInfo *cfmInfo; /* Configuration Confirm */ +#endif +{ +#if (ERRCLASS & ERRCLS_DEBUG) + KwCb *tKwCb; +#endif + TRC3(PtUiCkwCfgCfm); + + UNUSED(pst); + UNUSED(suId); + UNUSED(cfmInfo); + +#if (ERRCLASS & ERRCLS_DEBUG) + if (pst->srcInst >= KW_MAX_RLC_INSTANCES) + { + RETVALUE(RFAILED); + } + tKwCb = KW_GET_KWCB(pst->srcInst); + RLOG0(L_ERROR, "Improper selector value"); +#endif /* (ERRCLASS & ERRCLS_DEBUG) */ + + RETVALUE(ROK); + +} /* end of PtUiCkwCfgCfm */ + +#ifdef ANSI +PUBLIC S16 PtUiCkwUeIdChgCfm +( +Pst *pst, /* post structure */ +SuId suId, /* Service User Id */ +U32 transId, +CkwUeInfo *ueInfo, +CmStatus status +) +#else +PUBLIC S16 PtUiCkwUeIdChgCfm(pst, suId,transId,ueInfo,status) +Pst *pst; /* post structure */ +SuId suId; /* Service User Id */ +U32 transId; +CkwUeInfo *ueInfo; +CmStatus status; +#endif +{ +#if (ERRCLASS & ERRCLS_DEBUG) + KwCb *tKwCb; +#endif + TRC3(PtUiCkwUeIdChgCfm); + + UNUSED(pst); + UNUSED(suId); + UNUSED(transId); + UNUSED(ueInfo); + UNUSED(status); + +#if (ERRCLASS & ERRCLS_DEBUG) + if (pst->srcInst >= KW_MAX_RLC_INSTANCES) + { + RETVALUE(RFAILED); + } + tKwCb = KW_GET_KWCB(pst->srcInst); + RLOG0(L_ERROR, "Improper selector value"); +#endif /* (ERRCLASS & ERRCLS_DEBUG) */ + + RETVALUE(ROK); + +} /* end of PtUiCkwUeIdChgCfm */ +#endif /* PTKWCKW */ + +#if (defined(L2_L3_SPLIT) && defined(ICC_RECV_TSK_RBUF)) +/** + * + * @brief + * + * kwDlBatchProcSplit- process rbug messages + * + * @return S16 + * -# ROK + */ +#ifdef ANSI +PUBLIC S16 kwDlBatchProcSplit +( +Void +) +#else +PUBLIC S16 kwDlBatchProcSplit() +Void; +#endif +{ + +/* Read from Ring Buffer and process PDCP packets */ + Void *elmIndx = NULLP; + RxmBufReq *datReq = NULLP; +#ifdef LTE_ADV + U32 dlPktCount = 0; +#endif + U8 rngBufDeqIndx = 0; + U32 rngBufDeqMaxCnt; + U32 rngBufCurrCnt; + + rngBufDeqMaxCnt = SS_RNG_MAX_DLPDCP_TO_DLRLC_DQ_CNT; +#ifdef TENB_T2K3K_SPECIFIC_CHANGES + rngBufCurrCnt = SGetNumElemInRng(SS_RNG_BUF_RX_TO_DLRLC); + if ( rngBufCurrCnt > (3 * SS_RNG_MAX_DLPDCP_TO_DLRLC_DQ_CNT)) + { + if ( rngBufCurrCnt > (6 * SS_RNG_MAX_DLPDCP_TO_DLRLC_DQ_CNT)) + { + /* Restablishment scenario */ + rngBufDeqMaxCnt = (4 * SS_RNG_MAX_DLPDCP_TO_DLRLC_DQ_CNT); + } + else + { + rngBufDeqMaxCnt = (3 * SS_RNG_MAX_DLPDCP_TO_DLRLC_DQ_CNT)/2; + } + } +#endif + elmIndx = SRngGetRIndx(SS_RNG_BUF_RX_TO_DLRLC); + while(NULLP != elmIndx) + { + datReq = (RxmBufReq *)elmIndx; + if(datReq->mBuf != NULLP) + { + cmUnpkKwuDatReq(KwUiKwuDatReq, &datReq->pst, datReq->mBuf); + } + else + { + RLOG0(L_ERROR, "mBuf is NULL"); + if(datReq->mBuf) + cmUnpkKwuDatReq(KwUiKwuDatReq, &datReq->pst, datReq->mBuf); + + } + SsRngInfoTbl[SS_RNG_BUF_RX_TO_DLRLC].nPktProc++;//Number of pkt processed in tti + datReq->mBuf = NULLP; + SRngIncrRIndx(SS_RNG_BUF_RX_TO_DLRLC); + rngBufDeqIndx++; + if(rngBufDeqIndx >= rngBufDeqMaxCnt) + { + break; + } +#ifdef LTE_ADV + { + dlPktCount++; + if(dlPktCount > 75) + { + break; + } + } +#endif + if((elmIndx = SRngGetRIndx(SS_RNG_BUF_RX_TO_DLRLC)) == NULLP) + { + break; + } + } + + RETVALUE(ROK); +} +#endif + +#if defined(PDCP_RLC_DL_RBUF) || defined(SS_RBUF) +#ifdef ANSI +PUBLIC S16 kwDlBatchProc +( +Void +) +#else +PUBLIC S16 kwDlBatchProc() +Void; +#endif +{ +/* Read from Ring Buffer and process PDCP packets */ + + U8 rngBufDeqIndx = 0; + U32 rngBufDeqMaxCnt; +#ifdef TENB_T2K3K_SPECIFIC_CHANGES + U32 rngBufCurrCnt; +#endif + /* Memory regions different for BRCM and Intel */ + /*dstProcId,srcProcId,dstEnt,dstInst,srcEnt,srcInst,prior,route,event,region,pool,selector*/ +#ifdef SS_RBUF + PRIVATE Pst rlcDlRbfuPst ={1,1,ENTKW,1,ENTPJ,1,PRIOR0,RTESPEC,KWU_EVT_DAT_REQ,1,1,0,0}; +#else + PRIVATE Pst rlcDlRbfuPst ={1,1,ENTKW,1,ENTPJ,1,PRIOR0,RTESPEC,KWU_EVT_DAT_REQ,2,1,0,0}; +#endif + Void *elmIndx = NULLP; + KwuDatReqDetl *kwuDatReqDetl = NULLP; + KwuDatReqInfo datReq; + + rngBufDeqMaxCnt = SS_RNG_MAX_DLPDCP_TO_DLRLC_DQ_CNT; +#ifdef TENB_T2K3K_SPECIFIC_CHANGES + rngBufCurrCnt = SGetNumElemInRng(SS_RNG_BUF_DLPDCP_TO_DLRLC); + if ( rngBufCurrCnt > (3 * SS_RNG_MAX_DLPDCP_TO_DLRLC_DQ_CNT)) + { + if ( rngBufCurrCnt > (5 * SS_RNG_MAX_DLPDCP_TO_DLRLC_DQ_CNT)) + { + /* Restablishment scenario */ + rngBufDeqMaxCnt = (4 * SS_RNG_MAX_DLPDCP_TO_DLRLC_DQ_CNT); + } + else + { + rngBufDeqMaxCnt = (2 * SS_RNG_MAX_DLPDCP_TO_DLRLC_DQ_CNT); + } + } +#endif + elmIndx = SRngGetRIndx(SS_RNG_BUF_DLPDCP_TO_DLRLC); + while(NULLP != elmIndx) + { + kwuDatReqDetl = (KwuDatReqDetl *)elmIndx; + datReq.rlcId = kwuDatReqDetl->rlcId; + datReq.sduId = kwuDatReqDetl->sduId; + datReq.lcType = kwuDatReqDetl->lcType; + SsRngInfoTbl[SS_RNG_BUF_DLPDCP_TO_DLRLC].nPktProc++;;//Number of pkt processed in tti + if(kwuDatReqDetl->mBuf != NULLP) + { + KwUiKwuDatReq(&rlcDlRbfuPst, kwuDatReqDetl->spId, &datReq, kwuDatReqDetl->mBuf); + } + SRngIncrRIndx(SS_RNG_BUF_DLPDCP_TO_DLRLC); + rngBufDeqIndx++; + + if(rngBufDeqIndx >= rngBufDeqMaxCnt) + { + break; + } + elmIndx = (Void *)SRngGetRIndx(SS_RNG_BUF_DLPDCP_TO_DLRLC); + } + + RETVALUE(ROK); +} + + +#ifdef ANSI +PUBLIC S16 kwUtlDlBatchProcPkts +( +Void +) +#else +PUBLIC S16 kwUtlDlBatchProcPkts +Void; +#endif +{ + kwDlBatchProc(); +#ifdef SS_RBUF +#ifdef LTE_L2_MEAS + kwUtlDlBatchProcHqStaInd(); +#endif + kwUtlFreeDlMem(); +#endif + RETVALUE(ROK); +} + + +#ifdef ANSI +PUBLIC S16 kwUtlDlFreeRlcRBuf +( +Void +) +#else +PUBLIC S16 kwUtlDlFreeRlcRBuf +Void; +#endif +{ +/* Read from Ring Buffer and process PDCP packets */ + Void *elmIndx = NULLP; + KwuDatReqDetl *kwuDatReqDetl = NULLP; + /* Free SS_RNG_BUF_DLPDCP_TO_DLRLC */ + elmIndx = SRngGetRIndx(SS_RNG_BUF_DLPDCP_TO_DLRLC); + while(NULLP != elmIndx) + { + kwuDatReqDetl = (KwuDatReqDetl *)elmIndx; + SRngIncrRIndx(SS_RNG_BUF_DLPDCP_TO_DLRLC); + SsRngInfoTbl[SS_RNG_BUF_DLPDCP_TO_DLRLC].nPktProc++; + SPutMsg(kwuDatReqDetl->mBuf); + elmIndx = NULLP; + kwuDatReqDetl = NULLP; + if((elmIndx = SRngGetRIndx(SS_RNG_BUF_DLPDCP_TO_DLRLC)) == NULLP) + break; + } + RETVALUE(ROK); +} + + +#endif +#ifdef __cplusplus +} +#endif /* __cplusplus */ +/********************************************************************30** + End of file +**********************************************************************/ diff --git a/src/5gnrrlc/kw_tenb_stats.c b/src/5gnrrlc/kw_tenb_stats.c new file mode 100755 index 000000000..006326713 --- /dev/null +++ b/src/5gnrrlc/kw_tenb_stats.c @@ -0,0 +1,362 @@ +/******************************************************************************* +################################################################################ +# Copyright (c) [2017-2019] [Radisys] # +# # +# 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. # +################################################################################ +*******************************************************************************/ + +/********************************************************************** + + Name: + + Type: C include file + + Desc: + + File: l2_tenb_stats.c + +**********************************************************************/ + +/* header (.h) include files */ +#include "envopt.h" /* environment options */ +#include "envdep.h" /* environment dependent */ +#include "envind.h" /* environment independent */ + +#include "gen.h" /* general */ +#include "ssi.h" /* system services */ +#include "cm5.h" /* common timer defines */ +#include "cm_tkns.h" /* common tokens defines */ +#include "cm_mblk.h" /* common memory allocation library defines */ +#include "cm_llist.h" /* common link list defines */ +#include "cm_hash.h" /* common hash list defines */ +#include "cm_lte.h" /* common LTE defines */ +#include "lkw.h" /* LKW defines */ +#include "ckw.h" /* CKW defines */ +#include "kwu.h" /* KWU defines */ +#include "rgu.h" /* RGU defines */ +#include "kw_err.h" /* RLC error options */ +#include "kw_env.h" /* RLC environment options */ +#include "kw.h" /* RLC defines */ +#include "kw_ul.h" + +/* extern (.x) include files */ +#include "gen.x" /* general */ +#include "ssi.x" /* system services */ + +#include "cm5.x" /* common timer library */ +#include "cm_tkns.x" /* common tokens */ +#include "cm_mblk.x" /* common memory allocation */ +#include "cm_llist.x" /* common link list */ +#include "cm_hash.x" /* common hash list */ +#include "cm_lte.x" /* common LTE includes */ +#include "cm_lib.x" /* common memory allocation library */ +#include "lkw.x" /* LKW */ +#include "ckw.x" /* CKW */ +#include "kwu.x" /* KWU */ +#include "rgu.x" /* RGU */ + +#include "kw.x" +#include "kw_ul.x" +#ifdef TENB_STATS +#include "l2_tenb_stats.x" /* Total EnodeB Stats declarations */ +#endif + +#ifdef TENB_STATS +PUBLIC TSL2CellStatsCb* l2CellStats[L2_STATS_MAX_CELLS]; +PUBLIC TSL2UeStatsCb* l2UeStats[L2_STATS_MAX_UES]; +PUBLIC CmLListCp freeL2UeStatsLst; /*!< Free Pool of UE stats Blocks */ +PUBLIC CmLListCp inUseL2UeStatsLst;/*!< In Use Pool of UE stats Blocks */ + +/* +* +* Fun: TSL2AllocStatsMem +* +* Desc: Pre-Allocate Memory for L2 stats BLOCKs +* +* Ret: +* +* Notes: None +* +* +*/ +#ifdef ANSI +PUBLIC Void TSL2AllocStatsMem +( + Region region, + Pool pool +) +#else +PUBLIC Void TSL2AllocStatsMem(region, pool) + Region region; + Pool pool; +#endif +{ + U32 cnt=0; + + TRC2(TSL2AllocStatsMem) + + cmLListInit(&inUseL2UeStatsLst); + cmLListInit(&freeL2UeStatsLst); + for (cnt=0; cnt < L2_STATS_MAX_CELLS; cnt++) + { + if(NULL == l2CellStats[cnt]) + { + if (SGetSBuf(region, pool, (Data **)&l2CellStats[cnt], + (Size)sizeof (TSL2CellStatsCb)) != ROK) + { + printf("\n STATS Unexpected MEM Alloc Failure\n"); + } + } + cmMemset((U8 *)l2CellStats[cnt], 0x00, (Size)sizeof(TSL2CellStatsCb)); + } + + for (cnt=0; cnt < L2_STATS_MAX_UES; cnt++) + { + TSL2UeStatsCb *statsCb = l2UeStats[cnt]; + if(NULL == statsCb) + { + if (SGetSBuf(region, pool, (Data **)&statsCb, + (Size)sizeof (TSL2UeStatsCb)) != ROK) + { + printf("\n STATS Unexpected MEM Alloc Failure at %d\n", (int)cnt); + } + } + cmMemset((U8 *)statsCb, 0x00, (Size)sizeof(TSL2UeStatsCb)); + statsCb->lnk.node = (PTR)statsCb; + cmLListAdd2Tail(&freeL2UeStatsLst, &statsCb->lnk); + l2UeStats[cnt] = statsCb; + } + + RETVOID; +} + +/* +* +* Fun: TSL2AllocUeStatsBlk +* +* Desc: Assign Stats Block for this UE[RNTI] +* +* Ret: +* +* Notes: None +* +* +*/ +#ifdef ANSI +PUBLIC TSL2UeStatsCb* TSL2AllocUeStatsBlk +( + U16 rnti +) +#else +PUBLIC TSL2UeStatsCb* TSL2AllocUeStatsBlk(rnti) + U16 rnti; +#endif +{ + CmLList *tmp = NULLP; + TSL2UeStatsCb *statsCb = NULLP; + + TRC2(TSL2AllocUeStatsBlk) + + tmp = freeL2UeStatsLst.first; + if (tmp == NULLP) + { + printf("\n STATS Unexpected Mem BLK unavailable for UE %d\n", rnti); + } + cmLListDelFrm(&freeL2UeStatsLst, tmp); + statsCb = (TSL2UeStatsCb *)(tmp->node); + cmLListAdd2Tail(&inUseL2UeStatsLst, tmp); + + statsCb->stats.rnti = (U32)rnti; + statsCb->inUse = TRUE; + + RETVALUE(statsCb); +} + +/* +* +* Fun: TSL2DeallocUeStatsBlk +* +* Desc: Deassign Stats Block for this UE[RNTI] +* +* Ret: +* +* Notes: None +* +* +*/ +#ifdef ANSI +PUBLIC Void TSL2DeallocUeStatsBlk +( + U16 rnti, + TSL2UeStatsCb *statsCb +) +#else +PUBLIC Void TSL2DeallocUeStatsBlk(rnti, statsCb) + U16 rnti; + TSL2UeStatsCb *statsCb; +#endif +{ + TRC2(TSL2DeallocUeStatsBlk) + + statsCb->inUse = FALSE; + cmLListDelFrm(&inUseL2UeStatsLst, &statsCb->lnk); + freeL2UeStatsLst.crnt = freeL2UeStatsLst.first; + cmLListInsAfterCrnt(&freeL2UeStatsLst, &statsCb->lnk); + + RETVOID; +} + +/* +* +* Fun: TSL2AllocCellStatsBlk +* +* Desc: Assign Stats Block for this CELL[CELLID] +* +* Ret: +* +* Notes: None +* +* +*/ +#ifdef ANSI +PUBLIC TSL2CellStatsCb* TSL2AllocCellStatsBlk +( + U32 cellId +) +#else +PUBLIC TSL2CellStatsCb* TSL2AllocCellStatsBlk(cellId) + U32 cellId; +#endif +{ + TRC2(TSL2AllocCellStatsBlk) + + if (cellId != 1) + { + printf("\n STATS Unexpected CellID = %d\n", (int)cellId); + } + + RETVALUE(l2CellStats[cellId-1]); +} + +/* +* +* Fun: TSL2DeallocCellStatsBlk +* +* Desc: Deassign Stats Block for this CELL[CELLID] +* +* Ret: +* +* Notes: None +* +* +*/ +#ifdef ANSI +PUBLIC Void TSL2DeallocCellStatsBlk +( + U32 cellId +) +#else +PUBLIC Void TSL2DeallocCellStatsBlk(cellId) + U32 cellId; +#endif +{ + TRC2(TSL2DeallocCellStatsBlk) + + RETVOID; +} + +/* +* +* Fun: TSL2SendStatsToApp +* +* Desc: Collates and Sends STATS to Application +* Send UE STATS first. 10 UEs are grouped in one message. +* Followed by CELL Stats. All CELLS are grouped in one msg. +* At Reception of CELL stats APP assumes STATS reception cycle is complete. +* +* Ret: +* +* Notes: None +* +* +*/ +#ifdef ANSI +PUBLIC Void TSL2SendStatsToApp +( + Pst *pst, + SuId suId + ) +#else +PUBLIC Void TSL2SendStatsToApp(pst, suId) + Pst *pst; + SuId suId; +#endif +{ + U32 idx; + + TRC2(TSL2SendStatsToApp) + + for (idx = 0; idx < L2_STATS_MAX_UES; idx++) + { + TSL2UeStatsCb *statsCb = l2UeStats[idx]; + U32 rnti; + if (statsCb->inUse != TRUE) + { + continue; + } + if (pst->selector == 0) + { + /* Loose Coupling */ + TSInfPkSndL2UeStats(pst, suId, &statsCb->stats); + } + else + { +#ifdef PX + /* Tight Coupling */ + TSInfHdlL2UeStatsInd(pst, suId, &statsCb->stats); +#endif + } + rnti = statsCb->stats.rnti; + cmMemset((U8 *)&statsCb->stats.nonPersistent, 0x00, (Size)sizeof(statsCb->stats.nonPersistent)); + /* cmMemset((U8 *)&statsCb->stats, 0x00, (Size)sizeof(TSInfL2UeStats)); */ + statsCb->stats.rnti = rnti; + } + + /* Allocate mBuf for CELLSTATS */ + for (idx = 0; idx < L2_STATS_MAX_CELLS; idx++) + { + TSL2CellStatsCb *statsCellCb = l2CellStats[idx]; + U32 cellId; + if (pst->selector == 0) + { + /* Loose Coupling */ + TSInfPkSndL2CellStats(pst, suId, l2CellStats[idx]); + } + else + { +#ifdef PX + /* Tight Coupling */ + TSInfHdlL2CellStatsInd(pst, suId, l2CellStats[idx]); +#endif + } + cellId = statsCellCb->cellId; + cmMemset((U8 *)l2CellStats[idx], 0x00, (Size)sizeof(TSInfL2CellStats)); + statsCellCb->cellId = cellId; + } + RETVOID; +} +#endif /* TENB_STATS */ +/********************************************************************** + End of file +**********************************************************************/ diff --git a/src/5gnrrlc/kw_tmm_dl.c b/src/5gnrrlc/kw_tmm_dl.c new file mode 100755 index 000000000..730f3656b --- /dev/null +++ b/src/5gnrrlc/kw_tmm_dl.c @@ -0,0 +1,575 @@ +/******************************************************************************* +################################################################################ +# Copyright (c) [2017-2019] [Radisys] # +# # +# 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. # +################################################################################ +*******************************************************************************/ + +/********************************************************************** + + Name: LTE-RLC Layer + + Type: C file + + Desc: Source code for RLC Transparent mode assembly and + reassembly.This file contains following functions + + --kwTmmQSdu + --kwTmmSndToLi + --kwTmmRcvFrmLi + --kwTmmReEstablish + + File: kw_tmm_dl.c + +**********************************************************************/ +static const char* RLOG_MODULE_NAME="TMM"; +static int RLOG_MODULE_ID=2048; +static int RLOG_FILE_ID=200; +/** + * @file kw_tmm_dl.c + * @brief RLC Transparent Mode module +*/ + +/* header (.h) include files */ +#include "envopt.h" /* environment options */ +#include "envdep.h" /* environment dependent */ +#include "envind.h" /* environment independent */ + +#include "gen.h" /* general */ +#include "ssi.h" /* system services */ +#include "cm5.h" /* common timer defines */ +#include "cm_tkns.h" /* common tokens defines */ +#include "cm_mblk.h" /* common memory allocation library defines */ +#include "cm_llist.h" /* common link list defines */ +#include "cm_hash.h" /* common hash list defines */ +#include "cm_lte.h" /* common LTE defines */ +#include "lkw.h" /* LKW defines */ +#include "ckw.h" /* CKW defines */ +#include "kwu.h" /* KWU defines */ +#include "rgu.h" /* RGU defines */ +#include "kw_env.h" /* RLC environment options */ + +#include "kw.h" /* RLC defines */ +#include "kw_err.h" /* RLC defines */ +#include "kw_udx.h" +#include "kw_dl.h" + +/* extern (.x) include files */ +#include "gen.x" /* general */ +#include "ssi.x" /* system services */ + +#include "cm5.x" /* common timer library */ +#include "cm_tkns.x" /* common tokens */ +#include "cm_mblk.x" /* common memory allocation */ +#include "cm_llist.x" /* common link list */ +#include "cm_hash.x" /* common hash list */ +#include "cm_lte.x" /* common LTE includes */ +#include "cm_lib.x" /* common memory allocation library */ +#include "lkw.x" /* LKW */ +#include "ckw.x" /* CKW */ +#include "kwu.x" /* KWU */ +#include "rgu.x" /* RGU */ + +#include "kw.x" +#include "kw_udx.x" +#include "kw_dl.x" + +#define KW_MODULE (KW_DBGMASK_TM | KW_DBGMASK_DL) + +PRIVATE Void kwTmmSndStaRsp ARGS((KwCb *gCb, KwDlRbCb *rbCb, + MsgLen bo, KwuDatReqInfo *datReqInfo)); +extern U32 rgMacGT ; +/** @addtogroup tmmode */ +/*@{*/ + +/** + * @brief + * Handler to queue the SDU in the SDU queue and update BO and report it to + * the lower layer. + * + * @details + * This function is used to queue the received SDU in the SDU queue + * maintained in the radio bearer control block. After queuing the SDU, BO + * is updated and is reported to the lower layer. + * + * @param[in] rbCb RB control block. + * @param[in] datReqInfo Data Request Information. + * @param[in] mBuf SDU Buffer. + * + * @return S16 + * -# ROK + * -# RFAILED + */ +#ifdef ANSI +PUBLIC Void kwTmmQSdu +( +KwCb *gCb, +KwDlRbCb *rbCb, +KwuDatReqInfo *datReqInfo, +Buffer *mBuf +) +#else +PUBLIC Void kwTmmQSdu(gCb,rbCb,datReqInfo,mBuf) +KwCb *gCb; +KwDlRbCb *rbCb; +KwuDatReqInfo *datReqInfo; +Buffer *mBuf; +#endif +{ + KwSdu *sdu; + + TRC2(kwTmmQSdu) + + + KW_ALLOC(gCb,sdu,sizeof(KwSdu)); +#if (ERRCLASS & ERRCLS_ADD_RES) + if ( sdu == NULLP ) + { + RLOG_ARG2(L_FATAL,DBG_RBID,rbCb->rlcId.rbId, + "Memory Allocation failed UEID:%d CELLID:%d", + rbCb->rlcId.ueId, + rbCb->rlcId.cellId); + RETVOID; + } +#endif /* ERRCLASS & ERRCLS_ADD_RES */ +#ifdef CCPU_OPT + if ( rbCb->lch.lChType == CM_LTE_LCH_BCCH || + rbCb->lch.lChType == CM_LTE_LCH_PCCH ) + { + sdu->mode.tm.sfn = datReqInfo->tm.tmg.sfn; + sdu->mode.tm.subframe = datReqInfo->tm.tmg.subframe; +#ifdef EMTC_ENABLE + if(rbCb->lch.lChType == CM_LTE_LCH_PCCH) + { + sdu->mode.tm.pnb = datReqInfo->pnb; + } +#endif + } + else + { + sdu->mode.tm.rnti = datReqInfo->tm.rnti; + } +#endif + sdu->arrTime = rgMacGT; + SFndLenMsg(mBuf,&sdu->sduSz); + sdu->mBuf = mBuf; + + cmLListAdd2Tail(&(rbCb->m.tm.sduQ), &(sdu->lstEnt)); + sdu->lstEnt.node = (PTR)sdu; + + kwTmmSndStaRsp(gCb, rbCb, sdu->sduSz, datReqInfo); + RETVOID; +} + +/** +* @brief +* Handler to form a pdu and send it to the lower layer. +* +* @details +* This function forms one pdu from the first SDU in the SDU queue and sends +* it to the lower layer. +* +* @param[in] gCb RLC Instance Control Block +* @param[in] rbCb RB control block. +* @param[in] staInd Status Indication of common logical channel +* +* @return S16 +* -# ROK +* -# RFAILED +*/ +#ifdef ANSI +PUBLIC Void kwTmmSndToLi +( +KwCb *gCb, +SuId suId, +KwDlRbCb *rbCb, +RguCStaIndInfo *staInd +) +#else +PUBLIC Void kwTmmSndToLi(gCb, suId, rbCb, staInd) +KwCb *gCb; +SuId suId; +KwDlRbCb *rbCb; +RguCStaIndInfo *staInd; +#endif +{ + CmLList *node; /* Current Link List Node */ + KwSdu *sdu; /* SDU */ + RguCDatReqInfo *cDatReqInfo; /* Data Request Information */ + S16 timeDiff = 0; + Ticks curTime = 0; + + TRC2(kwTmmSndToLi) + + + CM_LLIST_FIRST_NODE(&(rbCb->m.tm.sduQ), + node); + + /* (Sfn,subframe) at which the message should be transmitted is + * validated with alloted (sfn,subframe)in the MAC layer */ + while (node != NULLP) + { + sdu = (KwSdu *)(node->node); + if ( rbCb->lch.lChType == CM_LTE_LCH_BCCH || + rbCb->lch.lChType == CM_LTE_LCH_PCCH ) + { + U16 sfn, subframe; + /* MS_FIX: syed sfn is of 10 bytes rather than 8 */ +#ifdef EMTC_ENABLE + /* As part of CATM feature cross subframe scheduling is implemented , so there is some delta(currently 2) + between MPDCCH and PDSCH,RLC expects cell crntTime of transmission of control dlsf, so one extra + information is provided in staInd, so that sfn,subframe should calculate from paging Timing information + in case of EMTC paging, instead of transId */ + if(staInd->isEmtcPaging) + { + sfn = staInd->pagingTimingInfo.sfn; + subframe = staInd->pagingTimingInfo.subframe; + } + else +#endif + { + sfn = (staInd->transId >> 8) & 0x3FF; + subframe = staInd->transId & 0xFF; + } + + /* Table + * tm.subframe - current subframe + * 0,sfn 7,sfn-1 + * 4,sfn 1,sfn + * 5,sfn 2,sfn + * 9,sfn 6,sfn + */ + /* MS_FIX: syed Incorrect sfn determination. + * Take care of SFN wraparound. TODO: It is better for RLC + * not to be aware of SCH DELTAs. So we should look for + * sending actual transmission time to RLC. */ + if ((subframe + TFU_DELTA) >= 10) + { + sfn = (sfn + 1)%1024; + } + + if ((sdu->mode.tm.sfn != sfn) || + (sdu->mode.tm.subframe != ((subframe+TFU_DELTA)%10))) + { + node = node->next; + RLOG_ARG4(L_DEBUG,DBG_RBID,rbCb->rlcId.rbId, + "Releasing SDU of RNTI = %d for RNTI = %d UEID:%d CELLID:%d", + sdu->mode.tm.rnti, + staInd->rnti, + rbCb->rlcId.ueId, + rbCb->rlcId.cellId); + RLOG_ARG4(L_DEBUG,DBG_RBID,rbCb->rlcId.rbId, + "sfn %d subframe %d UEID:%d CELLID:%d", + sfn, + subframe, + rbCb->rlcId.ueId, + rbCb->rlcId.cellId); + cmLListDelFrm(&(rbCb->m.tm.sduQ), &sdu->lstEnt); + KW_FREE_BUF(sdu->mBuf); + KW_FREE(gCb, sdu, sizeof(KwSdu)); + } + else + { + break; + } + } + else + { + curTime = rgMacGT; + if (curTime < sdu->arrTime) + { + timeDiff = (10240 - sdu->arrTime) + curTime; + } + else + { + timeDiff = curTime - sdu->arrTime; + } + RLOG_ARG4(L_DEBUG, DBG_RBID,rbCb->rlcId.rbId, + "TMM: TmSdu Sta Indication received for Rnti %d Sdu Rnti %d " + " UEID:%d CELLID:%d", + staInd->rnti, + sdu->mode.tm.rnti, + rbCb->rlcId.ueId, + rbCb->rlcId.cellId); + RLOG_ARG4(L_DEBUG, DBG_RBID,rbCb->rlcId.rbId, + "TMM: TmSdu Sta Indication received : timeDiff %d SduQCnt %lu" + " UEID:%d CELLID:%d", + timeDiff, + rbCb->m.tm.sduQ.count, + rbCb->rlcId.ueId, + rbCb->rlcId.cellId); + if (timeDiff > 40) + { + /* Memory leak needs to be fixed */ + node = node->next; + RLOG_ARG3(L_DEBUG, DBG_RBID,rbCb->rlcId.rbId, + " timeDiff greater than 40, so deleting the Sdu %u " + " UEID:%d CELLID:%d", + sdu->mode.tm.rnti, + rbCb->rlcId.ueId, + rbCb->rlcId.cellId); + cmLListDelFrm(&(rbCb->m.tm.sduQ), &sdu->lstEnt); + KW_FREE_BUF(sdu->mBuf); + KW_FREE(gCb, sdu, sizeof(KwSdu)); + continue; + } + + if (sdu->mode.tm.rnti != staInd->rnti) + { + /* Memory leak needs to be fixed */ + node = node->next; + RLOG_ARG4(L_DEBUG,DBG_RBID,rbCb->rlcId.rbId, + "TMM: Searching for Rnti %d Skipping Sdu for Rnti %d" + " UEID:%d CELLID:%d", + staInd->rnti, + sdu->mode.tm.rnti, + rbCb->rlcId.ueId, + rbCb->rlcId.cellId); + RLOG_ARG4(L_DEBUG,DBG_RBID,rbCb->rlcId.rbId, + " timeDiff %d sdu->arrTime %d" + " UEID:%d CELLID:%d", + timeDiff, + sdu->arrTime, + rbCb->rlcId.ueId, + rbCb->rlcId.cellId); + RLOG_ARG4(L_DEBUG,DBG_RBID,rbCb->rlcId.rbId, + "curTime %d SduQCnt %lu and continuing" + " UEID:%d CELLID:%d", + curTime, + rbCb->m.tm.sduQ.count, + rbCb->rlcId.ueId, + rbCb->rlcId.cellId); + continue; + } + else + { + RLOG_ARG3(L_DEBUG, DBG_RBID,rbCb->rlcId.rbId, + "TMM: TmSdu found %u UEID:%d CELLID:%d", + sdu->mode.tm.rnti, + rbCb->rlcId.ueId, + rbCb->rlcId.cellId); + break; + } + } + + } + if ( node == NULLP ) + { + RLOG_ARG2(L_ERROR,DBG_RBID,rbCb->rlcId.rbId, + "SDU not found TM Queue is empty UEID:%d CELLID:%d", + rbCb->rlcId.ueId, + rbCb->rlcId.cellId); + RETVOID; + } + sdu = (KwSdu *)node->node; + + KW_ALLOC_SHRABL_BUF(gCb->u.dlCb->rguDlSap[suId].pst.region, + gCb->u.dlCb->rguDlSap[suId].pst.pool, + cDatReqInfo,(Size)sizeof(RguCDatReqInfo)); +#if (ERRCLASS & ERRCLS_ADD_RES) + if ( cDatReqInfo == NULLP ) + { + RLOG_ARG2(L_FATAL,DBG_RBID,rbCb->rlcId.rbId, + "Memory Allocation failed UEID:%d CELLID:%d", + rbCb->rlcId.ueId, + rbCb->rlcId.cellId); + RETVOID; + } +#endif /* ERRCLASS & ERRCLS_ADD_RES */ +#ifdef CCPU_OPT + if ( rbCb->lch.lChType == CM_LTE_LCH_BCCH || + rbCb->lch.lChType == CM_LTE_LCH_PCCH ) + { + cDatReqInfo->u.timeToTx.sfn = sdu->mode.tm.sfn; + cDatReqInfo->u.timeToTx.subframe = sdu->mode.tm.subframe; +#ifdef EMTC_ENABLE + if(rbCb->lch.lChType == CM_LTE_LCH_PCCH) + { + cDatReqInfo->pnb = sdu->mode.tm.pnb; + } +#endif + } + else + { + cDatReqInfo->u.rnti = sdu->mode.tm.rnti; + } +#endif + cDatReqInfo->pdu = sdu->mBuf; + cDatReqInfo->transId = rbCb->transId; + cDatReqInfo->cellId = rbCb->rlcId.cellId; + cDatReqInfo->lcId = rbCb->lch.lChId; + cDatReqInfo->lcType = rbCb->lch.lChType; + + /* kw005.201 ccpu00117318, updating the statistics */ + gCb->genSts.bytesSent += sdu->sduSz; + gCb->genSts.pdusSent++; + + kwUtlIncrementKwuStsSduTx(gCb->u.dlCb->kwuDlSap + rbCb->kwuSapId); + + /* remove SDU from queue */ + sdu->mBuf = NULLP; + cmLListDelFrm(&(rbCb->m.tm.sduQ), + &sdu->lstEnt); + KW_FREE(gCb,sdu, sizeof(KwSdu)); + + /* If trace flag is enabled send the trace indication */ + if(gCb->init.trc == TRUE) + { + /* Populate the trace params */ + kwLmmSendTrc(gCb,EVTRGUCDATREQ, NULLP); + } + KwLiRguCDatReq (&(gCb->u.dlCb->rguDlSap[suId].pst), + gCb->u.dlCb->rguDlSap[suId].spId, + cDatReqInfo); + + RETVOID; +} + +/** + * + * @brief + * Handler to process the re-establishment request received from the upper + * layer. + * + * @details + * This function empties the SDU queue for the RB in the downlink. + * + * @param[in] gCb RLC Instance Control Block + * @param[in] rbCb RB control block. + * + * @return S16 + * -# ROK + */ +#ifdef ANSI +PUBLIC Void kwDlTmmReEstablish +( +KwCb *gCb, +KwDlRbCb *rbCb +) +#else +PUBLIC Void kwDlTmmReEstablish(gCb,rbCb) +KwCb *gCb; +KwDlRbCb *rbCb; +#endif +{ + TRC2(kwDlTmmReEstablish) + + +#ifdef LTE_L2_MEAS_RLC + kwUtlEmptySduQ(gCb, rbCb, &rbCb->m.tm.sduQ); +#else + kwUtlEmptySduQ(gCb,&rbCb->m.tm.sduQ); +#endif + + RETVOID; +} +/** + * + * @brief + * Handler to send Status Response to the lower layer. + * + * @details + * This function is used to the BO to the lower layer after receiving a data + * request from the upper layer. + * + * @param[in] gCb RLC Instance Control Block + * @param[in] rbCb RB control block. + * @param[in] bo Buffer Occupancy + * @param[in] datReqInfo Data Request Information. + * + * @return S16 + * -# ROK + * -# RFAILED + */ + +#ifdef ANSI +PRIVATE Void kwTmmSndStaRsp +( +KwCb *gCb, +KwDlRbCb *rbCb, +MsgLen bo, +KwuDatReqInfo *datReqInfo +) +#else +PRIVATE Void kwTmmSndStaRsp(rbCb,bo,datReqInfo) +KwCb *gCb; +KwDlRbCb *rbCb; +MsgLen bo; +KwuDatReqInfo *datReqInfo; +#endif +{ + RguCStaRspInfo *staRspInfo; /* Status Response Information */ + KwRguSapCb *rguSap; /* SAP Information */ + + TRC3(kwTmmSndStaRsp) + + + rguSap = &(gCb->u.dlCb->rguDlSap[rbCb->rguSapId]); + + KW_ALLOC_SHRABL_BUF(gCb->u.dlCb->rguDlSap[rbCb->rguSapId].pst.region, + gCb->u.dlCb->rguDlSap[rbCb->rguSapId].pst.pool, + staRspInfo,sizeof(RguCStaRspInfo)); +#if (ERRCLASS & ERRCLS_ADD_RES) + if ( staRspInfo == NULLP ) + { + RLOG_ARG2(L_FATAL,DBG_RBID,rbCb->rlcId.rbId, + "Memory Allocation failed UEID:%d CELLID:%d", + rbCb->rlcId.ueId, + rbCb->rlcId.cellId); + RETVOID; + } +#endif /* ERRCLASS & ERRCLS_ADD_RES */ + staRspInfo->bo = bo; + staRspInfo->cellId = rbCb->rlcId.cellId; + staRspInfo->lcId = rbCb->lch.lChId; + staRspInfo->lcType = rbCb->lch.lChType; +#ifdef CCPU_OPT + if ( rbCb->lch.lChType == CM_LTE_LCH_BCCH || + rbCb->lch.lChType == CM_LTE_LCH_PCCH ) + { + staRspInfo->u.timeToTx.sfn = datReqInfo->tm.tmg.sfn; + staRspInfo->u.timeToTx.subframe = datReqInfo->tm.tmg.subframe; +#ifdef EMTC_ENABLE + if(rbCb->lch.lChType == CM_LTE_LCH_PCCH) + { + staRspInfo->emtcDiReason = datReqInfo->emtcDiReason; + staRspInfo->pnb = datReqInfo->pnb; + } +#endif + } + else if ( rbCb->lch.lChType == CM_LTE_LCH_CCCH ) + { + staRspInfo->u.rnti = datReqInfo->tm.rnti; + } +#endif + + /* If trace flag is enabled send the trace indication */ + if(gCb->init.trc == TRUE) + { + /* Populate the trace params */ + kwLmmSendTrc(gCb,EVTRGUCSTARSP, NULLP); + } + + KwLiRguCStaRsp(&rguSap->pst,rguSap->spId,staRspInfo); + + RETVOID; +} + +#ifdef _cplusplus +} +#endif +/*@}*/ +/********************************************************************30** + End of file +**********************************************************************/ diff --git a/src/5gnrrlc/kw_tmm_ul.c b/src/5gnrrlc/kw_tmm_ul.c new file mode 100755 index 000000000..4011621f4 --- /dev/null +++ b/src/5gnrrlc/kw_tmm_ul.c @@ -0,0 +1,360 @@ +/******************************************************************************* +################################################################################ +# Copyright (c) [2017-2019] [Radisys] # +# # +# 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. # +################################################################################ +*******************************************************************************/ + +/********************************************************************** + + Name: LTE-RLC Layer + + Type: C file + + Desc: Source code for RLC Transparent mode assembly and + reassembly.This file contains following functions + + --kwTmmQSdu + --kwTmmSndToLi + --kwTmmRcvFrmLi + --kwTmmReEstablish + + File: kw_tmm_ul.c + +**********************************************************************/ +static const char* RLOG_MODULE_NAME="TMM"; +static int RLOG_MODULE_ID=2048; +static int RLOG_FILE_ID=201; + +/** @file kw_tmm_ul.c +@brief RLC Transparent Mode module +*/ + +/* header (.h) include files */ +#include "envopt.h" /* environment options */ +#include "envdep.h" /* environment dependent */ +#include "envind.h" /* environment independent */ + +#include "gen.h" /* general */ +#include "ssi.h" /* system services */ +#include "cm5.h" /* common timer defines */ +#include "cm_tkns.h" /* common tokens defines */ +#include "cm_mblk.h" /* common memory allocation library defines */ +#include "cm_llist.h" /* common link list defines */ +#include "cm_hash.h" /* common hash list defines */ +#include "cm_lte.h" /* common LTE defines */ +#include "lkw.h" /* LKW defines */ +#include "ckw.h" /* CKW defines */ +#include "kwu.h" /* KWU defines */ +#include "rgu.h" /* RGU defines */ +#include "kw_env.h" /* RLC environment options */ + +#include "kw.h" /* RLC defines */ +#include "kw_err.h" /* RLC defines */ +#include "kw_ul.h" + +/* extern (.x) include files */ +#include "gen.x" /* general */ +#include "ssi.x" /* system services */ + +#include "cm5.x" /* common timer library */ +#include "cm_tkns.x" /* common tokens */ +#include "cm_mblk.x" /* common memory allocation */ +#include "cm_llist.x" /* common link list */ +#include "cm_hash.x" /* common hash list */ +#include "cm_lte.x" /* common LTE includes */ +#include "cm_lib.x" /* common memory allocation library */ +#include "lkw.x" /* LKW */ +#include "ckw.x" /* CKW */ +#include "kwu.x" /* KWU */ +#include "rgu.x" /* RGU */ + +#include "kw.x" +#include "kw_ul.x" + +#if defined(PRE_DEF_UE_CTX) || defined(PRE_DEF_UE_CTX_HO) +#ifdef EG_GEN_LOAD_5GTF +extern U32 loadStart; +#endif + +EXTERN S16 PjUiPjuDatInd(Pst* pst,SuId suId,CmLtePdcpId * pdcpId,Buffer *mBuf); +#ifdef ANSI +PUBLIC Void AddUeContext +( +CmLteRnti crnti, +U8 rrcMsgType +) +#else +PUBLIC Void AddUeContext(crnti,rrcMsgType) +CmLteRnti crnti, +U8 rrcMsgType +#endif +{ + KwuDatIndInfo *datIndInfo; /* Data Indication Information */ + U8 rrcConReq[6] ={ 0x50, 0x30, 0x30, 0x30, 0x30, 0x34 }; + U8 rrcConSetupComplete[34] ={ 0x20, 0x00, 0x3e, 0x0e, 0x82, 0x02, 0x10, 0x12, 0x20, 0x02, 0x20, 0x64, 0xa8, 0x2c, 0x48, 0x05, 0x00, 0x80, 0x00, 0x08, 0x04, 0x03, 0xa0, 0x02, 0xa0, 0x10, 0x12, 0x20, 0x02, 0x20, 0x64, 0xa8, 0x2c, 0x48}; +#ifndef CA_PAL_5GTF + U8 rrcUeCapabilityInfo[12] ={0x38, 0x01, 0x00, 0x80, 0x1b, 0xff, 0x0c, 0x00, 0x20, 0x00, 0x80, 0x00}; +#else + /* U8 rrcUeCapabilityInfo[44] ={0x38,0x01,0x02,0x84,0x9b,0xff,0x0c,0x00,0x20,0x00,0x80,0x1f,0xfe,0xf4,0x4f,0xe0,0x40,0x03,0x80,0x11,0x04,0x0c,0x20,0x88,0x20,0x7f,0xff,0xff,0xff,0xf3,0xff,0x81,0xff,0xff,0xff,0xff,0x7f,0xf0,0x3f,0xff,0xff,0xff,0xe0,0x00}; +*/ +U8 rrcUeCapabilityInfo[] = +{ + 0x38,0x01,0x03,0x34,0x9b,0xff,0x0c,0x00,0x20,0x00,0x80,0x1f,0xfe,0xf4,0x4f,0xe0 + ,0x40,0x09,0x80,0x11,0x04,0x0c,0x20,0x88,0x20,0x63,0x04,0x41,0x03,0x20,0x22,0x08 + ,0x19,0x61,0x10,0x40,0xff,0xff,0xff,0xff,0xe7,0xff,0x03,0xff,0xff,0xff,0xfe,0xff + ,0xe0,0x7f,0xff,0xff,0xff,0xc0,0x00 +}; + +#endif + U8 rrcSecurityModeComplete[2] ={0x28, 0x80}; + U8 rrcReconfigComplete[2] ={0x10, 0x80}; + + Buffer *pdu; + + Pst ulPst1 ={100,100,217,0,215,0,PRIOR0,0,81,1,1,0,0}; + Pst ulPst2 ={100,100,217,0,216,0,PRIOR0,0,68,0,1,0,0}; + + TRC2(kwTmmRcvFrmLi) + + if(1 == rrcMsgType) + { + + KwuDatIndInfo datIndInfoTmp; + datIndInfo = &datIndInfoTmp; + datIndInfo->rlcId.rbId = 5; + datIndInfo->rlcId.rbType = 0; + datIndInfo->rlcId.ueId = 0; + datIndInfo->rlcId.cellId = 1; + datIndInfo->tCrnti = crnti; + datIndInfo->isOutOfSeq = 16; + + SGetMsg(DFLT_REGION, DFLT_POOL, (Buffer **) &pdu); + + SAddPstMsgMult(rrcConReq,6,pdu); + + RLOG1(L_INFO,"Profiling Framework Sending RRC Connection Req to RRC for UE :%d\n",crnti); + printf("Profiling Framework Sending RRC Connection Req to RRC for UE :%d\n",crnti); + KwUiKwuDatInd(&ulPst1, 1, datIndInfo, pdu); + } + else if(2 == rrcMsgType) + { + CmLtePdcpId pdcpId; + pdcpId.cellId = 1; + pdcpId.ueId = crnti; + pdcpId.rbId = 1; + pdcpId.rbType = 0; + + SGetMsg(DFLT_REGION, DFLT_POOL, (Buffer **) &pdu); + + SAddPstMsgMult(rrcConSetupComplete,34,pdu); + + RLOG1(L_INFO,"Profiling Framework: Sending RRC Connection Setup Complete to RRC for UE :%d\n",crnti); + printf("Profiling Framework: Sending RRC Connection Setup Complete to RRC for UE :%d\n",crnti); + PjUiPjuDatInd(&ulPst2, 1, &pdcpId, pdu); + } + + else if(3 == rrcMsgType) + { + CmLtePdcpId pdcpId; + pdcpId.cellId = 1; + pdcpId.ueId = crnti; + pdcpId.rbId = 1; + pdcpId.rbType = 0; + + SGetMsg(DFLT_REGION, DFLT_POOL, (Buffer **) &pdu); + +#ifndef CA_PAL_5GTF + SAddPstMsgMult(rrcUeCapabilityInfo,12,pdu); +#else + SAddPstMsgMult(rrcUeCapabilityInfo,sizeof(rrcUeCapabilityInfo),pdu); +#endif + RLOG1(L_INFO,"Profiling Framework: Sending RRC UE Capability Info to RRC for UE :%d\n",crnti); + printf("Profiling Framework: Sending RRC UE Capability Info to RRC for UE :%d\n",crnti); + PjUiPjuDatInd(&ulPst2, 1, &pdcpId, pdu); + } + else if(4 == rrcMsgType) + { + CmLtePdcpId pdcpId; + pdcpId.cellId = 1; + pdcpId.ueId = crnti; + pdcpId.rbId = 1; + pdcpId.rbType = 0; + + SGetMsg(DFLT_REGION, DFLT_POOL, (Buffer **) &pdu); + + SAddPstMsgMult(rrcSecurityModeComplete,2,pdu); + + RLOG1(L_INFO,"Profiling Framework: Sending RRC Security Mode Complete to RRC for UE :%d\n",crnti); + printf("Profiling Framework: Sending RRC Security Mode Complete to RRC for UE :%d\n",crnti); + PjUiPjuDatInd(&ulPst2, 1, &pdcpId, pdu); + } + else if(5 == rrcMsgType) + { + CmLtePdcpId pdcpId; + pdcpId.cellId = 1; + pdcpId.ueId = crnti; + pdcpId.rbId = 1; + pdcpId.rbType = 0; + + SGetMsg(DFLT_REGION, DFLT_POOL, (Buffer **) &pdu); + + SAddPstMsgMult(rrcReconfigComplete,2,pdu); + + RLOG1(L_INFO,"Profiling Framework: Sending RRC Reconfig Complete to RRC for UE :%d\n",crnti); + printf("Profiling Framework: Sending RRC Reconfig Complete to RRC for UE :%d\n",crnti); + PjUiPjuDatInd(&ulPst2, 1, &pdcpId, pdu); +#ifdef EG_GEN_LOAD_5GTF + loadStart=1; +#endif + } + RETVOID; +} +#endif +/** @addtogroup tmmode */ +/*@{*/ + +#define KW_MODULE (KW_DBGMASK_TM | KW_DBGMASK_UL) + +/** + * @brief + * Handler to process the Data Indication from the lower layer and send the + * SDU to upper layer. + * + * @details + * This function processes the PDU receivied from the lower layer and sends + * the same pdu as SDU to the upper layer.It sends CRNTI along with the SDU + * for CCCH. + * + * @param[in] gCb RLC Instance Control Block + * @param[in] rbCb RB control block. + * @param[in] tCrnti TCRNTI + * @param[in] pdu PDU + * + * @return S16 + * -# ROK + * -# RFAILED + */ +#ifdef CCPU_OPT +#ifdef ANSI +PUBLIC Void kwTmmRcvFrmLi +( +KwCb *gCb, +KwUlRbCb *rbCb, +CmLteRnti tCrnti, +Buffer *pdu +) +#else +PUBLIC Void kwTmmRcvFrmLi(gCb,rbCb, tCrnti, pdu) +KwCb *gCb; +KwUlRbCb *rbCb; +CmLteRnti tCrnti; +Buffer *pdu; +#endif +#else +#ifdef ANSI +PUBLIC Void kwTmmRcvFrmLi +( +KwCb *gCb, +KwUlRbCb *rbCb, +Buffer *pdu +) +#else +PUBLIC Void kwTmmRcvFrmLi(gCb,rbCb, pdu) +KwCb *gCb; +KwUlRbCb *rbCb; +Buffer *pdu; +#endif +#endif +{ + KwuDatIndInfo *datIndInfo; /* Data Indication Information */ + MsgLen msgLen; + + TRC2(kwTmmRcvFrmLi) + + /* Creating static memory for KwuDatIndInfo. #else will be + * removed once the sanity testing is performed for all platforms */ + KwuDatIndInfo datIndInfoTmp; + datIndInfo = &datIndInfoTmp; +#if (ERRCLASS & ERRCLS_ADD_RES) + if ( datIndInfo == NULLP ) + { + RLOG_ARG2(L_FATAL,DBG_RBID,rbCb->rlcId.rbId, + "Memory Allocation failed UEID:%d CELLID:%d", + rbCb->rlcId.ueId, + rbCb->rlcId.cellId); + RETVOID; + } +#endif /* ERRCLASS & ERRCLS_ADD_RES */ + KW_MEM_CPY(&(datIndInfo->rlcId),&(rbCb->rlcId),sizeof(CmLteRlcId)); +#ifdef CCPU_OPT + if ( rbCb->lch.lChType == CM_LTE_LCH_CCCH ) + { + datIndInfo->tCrnti = tCrnti; + } +#endif + gCb->genSts.pdusRecv++; + SFndLenMsg(pdu, &msgLen); + gCb->genSts.bytesRecv += msgLen; + /* If trace flag is enabled send the trace indication */ + if(gCb->init.trc == TRUE) + { + /* Populate the trace params */ + kwLmmSendTrc(gCb,KWU_EVT_DAT_IND, pdu); + } + KwUiKwuDatInd( &gCb->u.ulCb->kwuUlSap->pst, + gCb->u.ulCb->kwuUlSap->suId, + datIndInfo, pdu); + + RETVOID; +} + +/** + * @brief + * Handler to process the re-establishment request received from the upper + * layer. It is just a hook for future enhancement. + * + * + * @param[in] gCb RLC Instance Control Block + * @param[in] rbCb RB control block. + * + * @return S16 + * -# ROK + * + **/ +#ifdef ANSI +PUBLIC Void kwTmmUlReEstablish +( +KwCb *gCb, +KwUlRbCb *rbCb +) +#else +PUBLIC Void kwTmmUlReEstablish(rbCb) +KwCb *gCb; +KwRbCb *rbCb; +#endif +{ + TRC2(kwUlTmmReEstablish) + + RLOG_ARG0(L_DEBUG,DBG_RBID,rbCb->rlcId.rbId,"do nothing for TMM for ReEstablish"); + RETVOID; +} + +#ifdef _cplusplus +} +#endif +/*@}*/ +/********************************************************************30** + End of file +**********************************************************************/ diff --git a/src/5gnrrlc/kw_tmr.c b/src/5gnrrlc/kw_tmr.c new file mode 100755 index 000000000..f050a9589 --- /dev/null +++ b/src/5gnrrlc/kw_tmr.c @@ -0,0 +1,547 @@ +/******************************************************************************* +################################################################################ +# Copyright (c) [2017-2019] [Radisys] # +# # +# 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. # +################################################################################ +*******************************************************************************/ + +/********************************************************************20** + + Name: RLC - TMR module file + + Type: C source file + + Desc: Source code for timer functions such as, + + - kwStartTmr + - kwStopTmr + - kwTmrExpiry + - kwBndTmrExpiry + + File: kw_tmr.c + +*********************************************************************21*/ +static const char* RLOG_MODULE_NAME="TMR"; +static int RLOG_MODULE_ID=2048; +static int RLOG_FILE_ID=202; + + +/* header (.h) include files */ +#include "envopt.h" /* environment options */ +#include "envdep.h" /* environment dependent */ +#include "envind.h" /* environment independent */ + +#include "gen.h" /* general */ +#include "ssi.h" /* system services */ +#include "cm5.h" /* common timer defines */ +#include "cm_tkns.h" /* common tokens defines */ +#include "cm_mblk.h" /* common memory allocation library defines */ +#include "cm_llist.h" /* common link list defines */ +#include "cm_hash.h" /* common hash list defines */ +#include "cm_lte.h" /* common LTE defines */ +#include "lkw.h" /* LKW defines */ +#include "ckw.h" /* CKW defines */ +#include "kwu.h" /* KWU defines */ +#include "rgu.h" /* RGU defines */ +#include "kw_env.h" /* RLC environment options */ + +#include "kw.h" /* RLC defines */ +#include "kw_err.h" /* Error defines */ +#include "kw_ul.h" +#include "kw_udx.h" +#include "kw_dl.h" + +/* extern (.x) include files */ +#include "gen.x" /* general */ +#include "ssi.x" /* system services */ +#include "cm5.x" /* common timer library */ +#include "cm_tkns.x" /* common tokens */ +#include "cm_mblk.x" /* common memory allocation */ +#include "cm_llist.x" /* common link list */ +#include "cm_hash.x" /* common hash list */ +#include "cm_lte.x" /* common LTE includes */ +#include "cm_lib.x" /* common memory allocation library */ +#include "lkw.x" /* LKW */ +#include "ckw.x" /* CKW */ +#include "kwu.x" /* KWU */ +#include "rgu.x" /* RGU */ + +#include "kw.x" +#include "kw_udx.x" +#include "kw_dl.x" +#include "kw_ul.x" + +/** + * @file gp_tmr.c + * @brief RLC Timer Module +*/ + +/** + * @def KW_TMR_CALCUATE_WAIT + * + * This macro calculates and assigns wait time based on the value of the + * timer and the timer resolution. Timer value of 0 signifies that the + * timer is not configured + * + * @param[out] _wait Time for which to arm the timer changed to proper + * value according to the resolution + * @param[in] _tmrVal Value of the timer + * @param[in] _timerRes Resolution of the timer + * +*/ +#define KW_TMR_CALCUATE_WAIT(_wait, _tmrVal, _timerRes) \ +{ \ + (_wait) = ((_tmrVal) * SS_TICKS_SEC)/((_timerRes) * 1000); \ + if((0 != (_tmrVal)) && (0 == (_wait))) \ + { \ + (_wait) = 1; \ + } \ +} + +/* private function declarations */ +PRIVATE Void kwBndTmrExpiry(PTR cb); + +/** + * @brief Handler to start timer + * + * @param[in] gCb Pointer to the RLC instance control block + * @param[in] cb Control block depending on the type of the timer event. + * It can be uplink/downlink rbCb or rgu sap control block + * @param[in] tmrEvnt Timer event to be started + * + * @return Void +*/ +#ifdef ANSI +PUBLIC Void kwStartTmr +( +KwCb *gCb, +PTR cb, +S16 tmrEvnt +) +#else +PUBLIC Void kwStartTmr (gCb,cb, tmrEvnt) +KwCb *gCb; +PTR cb; +S16 tmrEvnt; +#endif +{ +/* kw005.201 added support for L2 Measurement */ +#ifdef LTE_L2_MEAS + KwL2MeasEvtCb *measEvtCb = NULLP; +#endif + + CmTmrArg arg; + arg.wait = 0; + + TRC2(kwStartTmr) + + /* kw002.201 Adjusting the wait time as per timeRes configured by layer manager */ + switch (tmrEvnt) + { + case KW_EVT_UMUL_REORD_TMR: + { + KwUmUl* umUl = &(((KwUlRbCb *)cb)->m.umUl); + /* kw005.201 Changed wait calculation ccpu00117634*/ + KW_TMR_CALCUATE_WAIT(arg.wait, umUl->reOrdTmrInt, gCb->genCfg.timeRes); + + arg.timers = &umUl->reOrdTmr; + arg.max = KW_MAX_UM_TMR; + break; + } + case KW_EVT_AMUL_REORD_TMR: + { + KwAmUl* amUl = &(((KwUlRbCb *)cb)->m.amUl); + /* kw005.201 Changed wait calculation ccpu00117634*/ + KW_TMR_CALCUATE_WAIT(arg.wait, amUl->reOrdTmrInt, gCb->genCfg.timeRes); + + arg.timers = &amUl->reOrdTmr; + arg.max = KW_MAX_AM_TMR; + break; + } + case KW_EVT_AMUL_STA_PROH_TMR: + { + KwAmUl* amUl = &(((KwUlRbCb *)cb)->m.amUl); + /* kw005.201 Changed wait calculation ccpu00117634*/ + KW_TMR_CALCUATE_WAIT(arg.wait, + amUl->staProhTmrInt, + gCb->genCfg.timeRes); + + arg.timers = &amUl->staProhTmr; + arg.max = KW_MAX_AM_TMR; + break; + } + case KW_EVT_AMDL_POLL_RETX_TMR: + { + KwAmDl* amDl = &(((KwDlRbCb *)cb)->m.amDl); + /* kw005.201 Changed wait calculation ccpu00117634*/ + KW_TMR_CALCUATE_WAIT(arg.wait, + amDl->pollRetxTmrInt, + gCb->genCfg.timeRes); + + arg.timers = &amDl->pollRetxTmr; + arg.max = KW_MAX_AM_TMR; + break; + } + case KW_EVT_WAIT_BNDCFM: + { + KwRguSapCb* rguSap = (KwRguSapCb *)cb; + /* kw005.201 Changed wait calculation ccpu00117634*/ + KW_TMR_CALCUATE_WAIT(arg.wait, rguSap->bndTmrInt, gCb->genCfg.timeRes); + + arg.timers = &rguSap->bndTmr; + arg.max = KW_MAX_RGUSAP_TMR; + break; + } +/* kw005.201 added support for L2 Measurement */ +#ifdef LTE_L2_MEAS + case KW_EVT_L2_TMR: + { + measEvtCb = (KwL2MeasEvtCb *)cb; + /* kw005.201 Changed wait calculation ccpu00117634*/ + KW_TMR_CALCUATE_WAIT(arg.wait, + measEvtCb->l2TmrCfg.val, + gCb->genCfg.timeRes); + + arg.timers = &measEvtCb->l2Tmr; + arg.max = KW_L2_MAX_TIMERS; + break; + } +#endif + default: + { + RLOG0(L_ERROR, "Invalid tmr Evnt"); + } + } + + if(arg.wait != 0) + { + arg.tqCp = &gCb->kwTqCp; + arg.tq = gCb->kwTq; + arg.cb = cb; + arg.evnt = tmrEvnt; + arg.tNum = 0; + + cmPlcCbTq(&arg); + } + + RETVOID; +} + +/** + * @brief Handler to stop a timer + * + * @param[in] gCb Pointer to the RLC instance control block + * @param[in] cb Control block depending on the type of the timer event. + * It can be uplink/downlink rbCb or rgu sap control block + * @param[in] tmrType Timer event to be started + * + * @return Void +*/ +#ifdef ANSI +PUBLIC Void kwStopTmr +( +KwCb *gCb, +PTR cb, +U8 tmrType +) +#else +PUBLIC Void kwStopTmr (gCb, cb, tmrType) +KwCb *gCb; +PTR cb; +U8 tmrType; +#endif +{ + CmTmrArg arg; +/* kw005.201 added support for L2 Measurement */ +#ifdef LTE_L2_MEAS + KwL2MeasEvtCb *measEvtCb = NULLP; +#endif + TRC2(kwStopTmr) + + arg.timers = NULLP; + + switch (tmrType) + { + case KW_EVT_UMUL_REORD_TMR: + { + arg.timers = &((KwUlRbCb *)cb)->m.umUl.reOrdTmr; + arg.max = KW_MAX_UM_TMR; + break; + } + case KW_EVT_AMUL_REORD_TMR: + { + arg.timers = &((KwUlRbCb *)cb)->m.amUl.reOrdTmr; + arg.max = KW_MAX_AM_TMR; + break; + } + case KW_EVT_AMUL_STA_PROH_TMR: + { + arg.timers = &((KwUlRbCb *)cb)->m.amUl.staProhTmr; + arg.max = KW_MAX_AM_TMR; + break; + } + case KW_EVT_AMDL_POLL_RETX_TMR: + { + arg.timers = &((KwDlRbCb *)cb)->m.amDl.pollRetxTmr; + arg.max = KW_MAX_AM_TMR; + break; + } + case KW_EVT_WAIT_BNDCFM: + { + arg.timers = &((KwRguSapCb *)cb)->bndTmr; + arg.max = KW_MAX_RGUSAP_TMR; + break; + } +/* kw005.201 added support for L2 Measurement */ +#ifdef LTE_L2_MEAS + case KW_EVT_L2_TMR: + { + measEvtCb = (KwL2MeasEvtCb *)cb; + arg.timers = &measEvtCb->l2Tmr; + arg.max = KW_L2_MAX_TIMERS; + break; + } +#endif + default: + { + RLOG0(L_ERROR, "Invalid tmr Evnt"); + } + } + if (tmrType != TMR0) + { + arg.tqCp = &gCb->kwTqCp; + arg.tq = gCb->kwTq; + arg.cb = cb; + arg.evnt = tmrType; + arg.wait = 0; + arg.tNum = 0; + cmRmvCbTq(&arg); + } + + RETVOID; +} + +/** + * @brief Handler to invoke events on expiry of timer. + * + * @details + * This function is used to handle expiry of timer,it invokes relevant + * functions. + * + * @param[in] cb Control block depending on the type of the timer event. + * It can be uplink/downlink rbCb or rgu sap control block + * @param[in] tmrEvnt Timer event to be started + * + * @return Void +*/ +#ifdef ANSI +PUBLIC Void kwTmrExpiry +( +PTR cb, +S16 tmrEvnt +) +#else +PUBLIC Void kwTmrExpiry (cb, tmrEvnt) +PTR cb; +S16 tmrEvnt; +#endif +{ +/* kw005.201 added support for L2 Measurement */ + TRC2(kwTmrExpiry) + + switch (tmrEvnt) + { + case KW_EVT_UMUL_REORD_TMR: + { + KwUlRbCb *ulRbCb = (KwUlRbCb *)cb; + kwUmmReOrdTmrExp(KW_GET_KWCB(ulRbCb->inst), ulRbCb); + + break; + } + case KW_EVT_AMUL_REORD_TMR: + { + KwUlRbCb *ulRbCb = (KwUlRbCb *)cb; + kwAmmReOrdTmrExp(KW_GET_KWCB(ulRbCb->inst), ulRbCb); + break; + } + case KW_EVT_AMUL_STA_PROH_TMR: + { + KwUlRbCb *ulRbCb = (KwUlRbCb *)cb; + kwAmmStaProTmrExp(KW_GET_KWCB(ulRbCb->inst), ulRbCb); + + break; + } + case KW_EVT_AMDL_POLL_RETX_TMR: + { + KwDlRbCb *dlRbCb = (KwDlRbCb *)cb; + KwCb *gCb = KW_GET_KWCB(dlRbCb->inst); + + kwAmmPollRetxTmrExp(gCb, dlRbCb); + + gCb->genSts.protTimeOut++; + break; + } + case KW_EVT_WAIT_BNDCFM: + { + kwBndTmrExpiry(cb); + break; + } + /* kw005.201 L2 Measurement support */ + default: + { + break; + } + } + + RETVOID; +} + +/** + * @brief Handler to check if the timer is running + * + * @param[in] gCb Pointer to the RLC instance control block + * @param[in] cb Control block depending on the type of the timer event. + * It can be uplink/downlink rbCb or rgu sap control block + * @param[in] tmrEvnt Timer event to be started + * + * @return Bool indicating whether the timer is running or not + * -# ROK + * -# RFAILED +*/ +#ifdef ANSI +PUBLIC Bool kwChkTmr +( +KwCb *gCb, +PTR cb, +S16 tmrEvnt +) +#else +PUBLIC Bool kwChkTmr(gCb,cb, tmrEvnt) +KwCb *gCb; +PTR cb; +S16 tmrEvnt; +#endif +{ + TRC2(kwChkTmr) + + switch (tmrEvnt) + { + case KW_EVT_UMUL_REORD_TMR: + { + return (((KwUlRbCb *)cb)->m.umUl.reOrdTmr.tmrEvnt == + KW_EVT_UMUL_REORD_TMR); + } + case KW_EVT_AMUL_REORD_TMR: + { + return (((KwUlRbCb *)cb)->m.amUl.reOrdTmr.tmrEvnt == + KW_EVT_AMUL_REORD_TMR); + } + case KW_EVT_AMUL_STA_PROH_TMR: + { + return (((KwUlRbCb *)cb)->m.amUl.staProhTmr.tmrEvnt == + KW_EVT_AMUL_STA_PROH_TMR); + } + case KW_EVT_AMDL_POLL_RETX_TMR: + { + return (((KwDlRbCb *)cb)->m.amDl.pollRetxTmr.tmrEvnt == + KW_EVT_AMDL_POLL_RETX_TMR); + } + case KW_EVT_WAIT_BNDCFM: + { + return (((KwRguSapCb *)cb)->bndTmr.tmrEvnt == KW_EVT_WAIT_BNDCFM); + } + default: + { + RLOG0(L_ERROR, "Invalid tmr Evnt"); + } + } + + RETVALUE(FALSE); +} + +/** + * @brief Handler to do processing on expiry of the bind timer + * + * @details + * This function processes the RLC bind timer expiry. If the number of + * retries is less than the maximum retry counter, bind request is sent + * again, else an alarm is raised to the layer manager. + * + * @param[in] cb Pointer to the Rgu sap + * + * @return Void +*/ +#ifdef ANSI +PRIVATE Void kwBndTmrExpiry +( +PTR cb +) +#else +PRIVATE Void kwBndTmrExpiry(cb) +PTR cb; +#endif +{ + KwRguSapCb *rguSapCb; + + TRC2(kwBndTmrExpiry) + + rguSapCb = (KwRguSapCb *) cb; + + if (rguSapCb->state == KW_SAP_BINDING) + { + if (rguSapCb->retryCnt < KW_MAX_SAP_BND_RETRY) + { + /* start timer to wait for bind confirm */ + kwStartTmr(KW_GET_KWCB(rguSapCb->pst.srcInst), + (PTR)rguSapCb, + KW_EVT_WAIT_BNDCFM); + + /* Send bind request */ + rguSapCb->retryCnt++; + KwLiRguBndReq (&rguSapCb->pst, rguSapCb->suId, rguSapCb->spId); + } + else + { + rguSapCb->retryCnt = 0; + rguSapCb->state = KW_SAP_CFG; + + /* Send alarm to the layer manager */ +#ifdef LTE_L2_MEAS + kwLmmSendAlarm(KW_GET_KWCB(rguSapCb->pst.srcInst), + LCM_CATEGORY_INTERFACE, + LCM_EVENT_BND_FAIL, + LCM_CAUSE_TMR_EXPIRED, + 0, + 0, + 0); +#else + kwLmmSendAlarm(KW_GET_KWCB(rguSapCb->pst.srcInst), + LCM_CATEGORY_INTERFACE, + LCM_EVENT_BND_FAIL, + LCM_CAUSE_TMR_EXPIRED, + 0, /* suId */ + 0 /* ueId */); +#endif + } + } + + RETVOID; +} + + + +/********************************************************************30** + + End of file +**********************************************************************/ diff --git a/src/5gnrrlc/kw_udx.c b/src/5gnrrlc/kw_udx.c new file mode 100755 index 000000000..75d610a49 --- /dev/null +++ b/src/5gnrrlc/kw_udx.c @@ -0,0 +1,1806 @@ +/******************************************************************************* +################################################################################ +# Copyright (c) [2017-2019] [Radisys] # +# # +# 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. # +################################################################################ +*******************************************************************************/ + +/********************************************************************20** + + Name: UDX RRC Control Interface + + Type: C file + + Desc: This file Contains the packing and unpacking functions for + UDX Interface + + File: kw_udx.c + +*********************************************************************21*/ + +#include "envopt.h" /* environment options */ +#include "envdep.h" /* environment dependent */ +#include "envind.h" /* environment independent */ + +#include "gen.h" /* general */ +#include "ssi.h" /* system services */ +#include "cm5.h" /* common timer defines */ +#include "cm_tkns.h" /* common tokens defines */ +#include "cm_mblk.h" /* common memory allocation library defines */ +#include "cm_llist.h" /* common link list defines */ +#include "cm_hash.h" /* common hash list defines */ +#include "cm_lte.h" /* common LTE defines */ +#include "lkw.h" +#include "kw_udx.h" /* UDX defines */ + +/* extern (.x) include files */ +#include "gen.x" /* general */ +#include "ssi.x" /* system services */ + +#include "cm5.x" /* common timer library */ +#include "cm_tkns.x" /* common tokens */ +#include "cm_mblk.x" /* common memory allocation */ +#include "cm_llist.x" /* common link list */ +#include "cm_hash.x" /* common hash list */ +#include "cm_lte.x" /* common LTE includes */ +#include "cm_lib.x" /* common memory allocation library */ +#include "kw.h" +#include "lkw.x" +#include "kw_udx.x" +#include + + +#ifdef LCUDX + +/* +* +* Fun: cmPkUdxBndReq +* +* Desc: pack the primitive UdxBndReq +* +* Ret: ROK -ok +* +* Notes: None +* +* File: ckw.c +* +*/ +#ifdef ANSI +PRIVATE S16 cmUnpkUdxStruct +( +Buffer *srcMBuf, +U32 offset, +U8 *dstBuf, +U32 size +) +#else +PRIVATE S16 cmUnpkUdxStruct(dstMBuf,srcBuf,size) +Buffer *srcMBuf; +U32 offset; +U8 *dstBuf; +MsgLen size; +#endif +{ + MsgLen tmpLen; + + TRC3(cmUnpkUdxStruct) + RETVALUE(SCpyMsgFix(srcMBuf,offset,size,dstBuf,&tmpLen)); + +} /*end of function cmPkUdxBndReq*/ + +/* +* +* Fun: cmPkUdxBndReq +* +* Desc: pack the primitive UdxBndReq +* +* Ret: ROK -ok +* +* Notes: None +* +* File: ckw.c +* +*/ +#ifdef ANSI +PRIVATE S16 cmPkUdxStruct +( +U8 *srcBuf, +MsgLen size, +Buffer *dstMBuf +) +#else +PRIVATE S16 cmPkUdxStruct(dstMBuf,srcBuf,size) +U8 *srcBuf; +MsgLen size; +Buffer *dstMBuf; +#endif +{ + + TRC3(cmPkUdxStruct) + RETVALUE(SAddPstMsgMult(srcBuf,size,dstMBuf)); + +} /*end of function cmPkUdxBndReq*/ +/* +* +* Fun: cmPkUdxBndReq +* +* Desc: pack the primitive UdxBndReq +* +* Ret: ROK -ok +* +* Notes: None +* +* File: ckw.c +* +*/ +#ifdef ANSI +PUBLIC S16 cmPkUdxBndReq +( +Pst *pst, +SuId suId, +SpId spId +) +#else +PUBLIC S16 cmPkUdxBndReq(pst, suId, spId) +Pst *pst; +SuId suId; +SpId spId; +#endif +{ + S16 ret1; + Buffer *mBuf; + mBuf = NULLP; + TRC3(cmPkUdxBndReq) + + if((ret1 = SGetMsg(pst->region, pst->pool, &mBuf)) != ROK) + { +#if (ERRCLASS & ERRCLS_ADD_RES) + if(ret1 != ROK) + { + SLogError(pst->srcEnt, pst->srcInst, pst->srcProcId, + __FILE__, __LINE__, (ErrCls)ERRCLS_ADD_RES, + (ErrVal)EUDXXXX, (ErrVal)0, "SGetMsg() failed"); + } +#endif /* ERRCLASS & ERRCLS_ADD_RES */ + RETVALUE(ret1); + } + CMCHKPKLOG(SPkS16, spId, mBuf, EUDXXXX, pst); + CMCHKPKLOG(SPkS16, suId, mBuf, EUDXXXX, pst); + pst->event = (Event) UDX_EVT_BND_REQ; + + RETVALUE(SPstTsk(pst,mBuf)); +} /*end of function cmPkUdxBndReq*/ + +/* +* +* Fun: cmPkUdxUbndReq +* +* Desc: pack the primitive UdxUbndReq +* +* Ret: ROK -ok +* +* Notes: None +* +* File: ckw.c +* +*/ +#ifdef ANSI +PUBLIC S16 cmPkUdxUbndReq +( +Pst *pst, +SpId spId, +Reason reason +) +#else +PUBLIC S16 cmPkUdxUbndReq(pst, spId, reason) +Pst *pst; +SpId spId; +Reason reason; +#endif +{ + S16 ret1; + Buffer *mBuf; + mBuf = NULLP; + TRC3(cmPkUdxUbndReq) + + if((ret1 = SGetMsg(pst->region, pst->pool, &mBuf)) != ROK) + { +#if (ERRCLASS & ERRCLS_ADD_RES) + if(ret1 != ROK) + { + SLogError(pst->srcEnt, pst->srcInst, pst->srcProcId, + __FILE__, __LINE__, (ErrCls)ERRCLS_ADD_RES, + (ErrVal)EUDXXXX, (ErrVal)0, "SGetMsg() failed"); + } +#endif /* ERRCLASS & ERRCLS_ADD_RES */ + RETVALUE(ret1); + } + CMCHKPKLOG(SPkS16, reason, mBuf, EUDXXXX, pst); + CMCHKPKLOG(SPkS16, spId, mBuf, EUDXXXX, pst); + pst->event = (Event) UDX_EVT_UBND_REQ; + + RETVALUE(SPstTsk(pst,mBuf)); +} /*end of function cmPkUdxUbndReq*/ + +/* +* +* Fun: cmPkUdxBndCfm +* +* Desc: pack the primitive UdxBndCfm +* +* Ret: ROK -ok +* +* Notes: None +* +* File: ckw.c +* +*/ +#ifdef ANSI +PUBLIC S16 cmPkUdxBndCfm +( +Pst *pst, +SuId suId, +U8 status +) +#else +PUBLIC S16 cmPkUdxBndCfm(pst, suId, status) +Pst *pst; +SuId suId; +U8 status; +#endif +{ + S16 ret1; + Buffer *mBuf; + mBuf = NULLP; + TRC3(cmPkUdxBndCfm) + + if((ret1 = SGetMsg(pst->region, pst->pool, &mBuf)) != ROK) + { +#if (ERRCLASS & ERRCLS_ADD_RES) + if(ret1 != ROK) + { + SLogError(pst->srcEnt, pst->srcInst, pst->srcProcId, + __FILE__, __LINE__, (ErrCls)ERRCLS_ADD_RES, + (ErrVal)EUDXXXX, (ErrVal)0, "SGetMsg() failed"); + } + +#endif /* ERRCLASS & ERRCLS_ADD_RES */ + RETVALUE(ret1); + } + CMCHKPKLOG(SPkU8, status, mBuf, EUDXXXX, pst); + CMCHKPKLOG(SPkS16, suId, mBuf, EUDXXXX, pst); + pst->event = (Event) UDX_EVT_BND_CFM; + + RETVALUE(SPstTsk(pst,mBuf)); +} /*end of function cmPkUdxBndCfm*/ + + +/* +* +* Fun: cmPkUdxCfgReq +* +* Desc: pack the primitive KwUiUdxCfgReq +* +* Ret: ROK -ok +* +* Notes: None +* +* File: ckw.c +* +*/ +#ifdef ANSI +PUBLIC S16 cmPkUdxCfgReq +( +Pst *pst, +SpId spId, +CkwCfgInfo *cfgInfo +) +#else +PUBLIC S16 cmPkUdxCfgReq(pst, spId, cfgInfo) +Pst *pst; +SpId spId; +CkwCfgInfo *cfgInfo; +#endif +{ + S16 ret1; + Buffer *mBuf; + mBuf = NULLP; + TRC3(cmPkUdxCfgReq) + + if((ret1 = SGetMsg(pst->region, pst->pool, &mBuf)) != ROK) + { +#if (ERRCLASS & ERRCLS_ADD_RES) + if(ret1 != ROK) + { + SLogError(pst->srcEnt, pst->srcInst, pst->srcProcId, + __FILE__, __LINE__, (ErrCls)ERRCLS_ADD_RES, + (ErrVal)EUDXXXX, (ErrVal)0, "SGetMsg() failed"); + } +#endif /* ERRCLASS & ERRCLS_ADD_RES */ + RETVALUE(ret1); + } + + switch(pst->selector) + { +#ifdef LCUDX + case UDX_SEL_LC: + { + cmPkUdxStruct((U8 *)cfgInfo, sizeof(CkwCfgInfo),mBuf); + /* Need Not free CfgInfo here as it is stored + in UL */ + break; + } + case UDX_SEL_LWLC: + { + CMCHKPKLOG(cmPkPtr,(PTR)cfgInfo,mBuf,EUDXXXX,pst); + break; + } +#endif /* LCUDX */ + } + + CMCHKPKLOG(SPkS16, spId, mBuf, EUDXXXX, pst); + pst->event = (Event) UDX_EVT_CFG_REQ; + + RETVALUE(SPstTsk(pst,mBuf)); +} /* cmPkUdxCfgReq */ + + +/* +* +* Fun: cmPkUdxCfgCfm +* +* Desc: pack the primitive KwUiUdxCfgCfm +* +* Ret: ROK -ok +* +* Notes: None +* +* File: ckw.c +* +*/ +#ifdef ANSI +PUBLIC S16 cmPkUdxCfgCfm +( +Pst *pst, +SuId suId, +CkwCfgCfmInfo *cfgCfmInfo +) +#else +PUBLIC S16 cmPkUdxCfgCfm(pst, suId, cfgCfmInfo) +Pst *pst; +SuId suId; +CkwCfgCfmInfo *cfgCfmInfo; +#endif +{ + S16 ret1; + Buffer *mBuf; + mBuf = NULLP; + TRC3(cmPkUdxCfgCfm) + + if((ret1 = SGetMsg(pst->region, pst->pool, &mBuf)) != ROK) + { +#if (ERRCLASS & ERRCLS_ADD_RES) + if(ret1 != ROK) + { + SLogError(pst->srcEnt, pst->srcInst, pst->srcProcId, + __FILE__, __LINE__, (ErrCls)ERRCLS_ADD_RES, + (ErrVal)EUDXXXX, (ErrVal)0, "SGetMsg() failed"); + } +#endif /* ERRCLASS & ERRCLS_ADD_RES */ + RETVALUE(ret1); + } + + switch(pst->selector) + { +#ifdef LCUDX + case UDX_SEL_LC: + { + cmPkUdxStruct((U8 *)cfgCfmInfo, sizeof(CkwCfgCfmInfo),mBuf); + /* Need to free the cfgCfmInfo here as it is allocated + buffer call SPutStaticBuffer */ + SPutStaticBuffer(pst->region,pst->pool,(Data *) cfgCfmInfo, + sizeof(CkwCfgCfmInfo),0); + break; + } + case UDX_SEL_LWLC: + { + CMCHKPKLOG(cmPkPtr,(PTR)cfgCfmInfo,mBuf,EUDXXXX,pst); + break; + } +#endif /* LCUDX */ + } + + CMCHKPKLOG(SPkS16, suId, mBuf, EUDXXXX, pst); + pst->event = (Event) UDX_EVT_CFG_CFM; + + RETVALUE(SPstTsk(pst,mBuf)); +} /* cmPkUdxCfgCfm */ + + +/* +* +* Fun: cmPkUdxUeIdChgReq +* +* Desc: pack the primitive KwUiUdxUeIdChgReq +* +* Ret: ROK -ok +* +* Notes: None +* +* File: ckw.c +* +*/ +#ifdef ANSI +PUBLIC S16 cmPkUdxUeIdChgReq +( +Pst *pst, +SpId spId, +U32 transId, +CkwUeInfo *ueInfo, +CkwUeInfo *newUeInfo +) +#else +PUBLIC S16 cmPkUdxUeIdChgReq(pst, spId, transId, ueInfo, newUeInfo) +Pst *pst; +SpId spId; +U32 transId; +CkwUeInfo *ueInfo; +CkwUeInfo *newUeInfo; +#endif +{ + S16 ret1; + Buffer *mBuf = NULLP; + + TRC3(cmPkUdxUeIdChgReq) + + if((ret1 = SGetMsg(pst->region, pst->pool, &mBuf)) != ROK) + { +#if (ERRCLASS & ERRCLS_ADD_RES) + if(ret1 != ROK) + { + SLogError(pst->srcEnt, pst->srcInst, pst->srcProcId, + __FILE__, __LINE__, (ErrCls)ERRCLS_ADD_RES, + (ErrVal)EUDXXXX, (ErrVal)0, "SGetMsg() failed"); + } +#endif /* ERRCLASS & ERRCLS_ADD_RES */ + + RETVALUE(ret1); + } + + switch(pst->selector) + { +#ifdef LCUDX + case UDX_SEL_LC: + { + cmPkUdxStruct((U8 *)newUeInfo, sizeof(CkwUeInfo),mBuf); + cmPkUdxStruct((U8 *)ueInfo, sizeof(CkwUeInfo),mBuf); + /* No need to free ueInfo here as it is stored */ + break; + } + case UDX_SEL_LWLC: + { + CMCHKPKLOG(cmPkPtr,(PTR)newUeInfo,mBuf,EUDXXXX,pst); + CMCHKPKLOG(cmPkPtr,(PTR)ueInfo,mBuf,EUDXXXX,pst); + break; + } + default: + { + printf("cmPkUdxUeIdChgReq()- selector =%d not supported \n", pst->selector); + exit(1); + } +#endif + } + CMCHKPKLOG(SPkU32, transId, mBuf, EUDXXXX, pst); + CMCHKPKLOG(SPkS16, spId, mBuf, EUDXXXX, pst); + pst->event = (Event) UDX_EVT_UEIDCHG_REQ; + + RETVALUE(SPstTsk(pst, mBuf)); + +} /* cmPkUdxUeIdChgReq */ + +/* +* +* Fun: cmPkUdxUeIdChgCfm +* +* Desc: pack the primitive KwUiUdxUeIdChgCfm +* +* Ret: ROK -ok +* +* Notes: None +* +* File: ckw.c +* +*/ +#ifdef ANSI +PUBLIC S16 cmPkUdxUeIdChgCfm +( +Pst *pst, +SuId suId, +U32 transId, +CmStatus status +) +#else +PUBLIC S16 cmPkUdxUeIdChgCfm(pst, suId, transId, status) +Pst *pst; +SuId suId; +U32 transId; +CmStatus status; +#endif +{ + S16 ret1; + Buffer *mBuf = NULLP; + TRC3(cmPkUdxUeIdChgCfm) + + if((ret1 = SGetMsg(pst->region, pst->pool, &mBuf)) != ROK) + { +#if (ERRCLASS & ERRCLS_ADD_RES) + if(ret1 != ROK) + { + SLogError(pst->srcEnt, pst->srcInst, pst->srcProcId, + __FILE__, __LINE__, (ErrCls)ERRCLS_ADD_RES, + (ErrVal)EUDXXXX, (ErrVal)0, "SGetMsg() failed"); + } +#endif /* ERRCLASS & ERRCLS_ADD_RES */ + + RETVALUE(ret1); + } + + CMCHKPK(cmPkCmStatus, &status, mBuf); + CMCHKPKLOG(SPkU32, transId, mBuf, EUDXXXX, pst); + CMCHKPKLOG(SPkS16, suId, mBuf, EUDXXXX, pst); + pst->event = (Event) UDX_EVT_UEIDCHG_CFM; + + RETVALUE(SPstTsk(pst, mBuf)); + +} /* cmPkUdxUeIdChgCfm */ + +/* +* +* Fun: cmPkUdxStaUpdCfm +* +* Desc: pack the primitive KwUiUdxUeIdChgCfm +* +* Ret: ROK -ok +* +* Notes: None +* +* File: ckw.c +* +*/ +#ifdef ANSI +PUBLIC S16 cmPkUdxStaUpdCfm +( +Pst *pst, +SuId suId, +CmLteRlcId *rlcId, +KwUdxBufLst *pStaPdu +) +#else +PUBLIC S16 cmPkUdxStaUpdCfm(pst, suId, rlcId,pStaPdu) +Pst *pst; +SuId suId; +CmLteRlcId *rlcId; +KwUdxBufLst *pStaPdu; +#endif +{ + S16 ret1; + Buffer *mBuf = NULLP; + + TRC3(cmPkUdxStaUpdCfm) + + if((ret1 = SGetMsg(pst->region, pst->pool, &mBuf)) != ROK) + { +#if (ERRCLASS & ERRCLS_ADD_RES) + if(ret1 != ROK) + { + SLogError(pst->srcEnt, pst->srcInst, pst->srcProcId, + __FILE__, __LINE__, (ErrCls)ERRCLS_ADD_RES, + (ErrVal)EUDXXXX, (ErrVal)0, "SGetMsg() failed"); + } +#endif /* ERRCLASS & ERRCLS_ADD_RES */ + + RETVALUE(ret1); + } + + switch (pst->selector) + { + case UDX_SEL_LC: + { + cmPkUdxStruct((U8 *)pStaPdu, sizeof(KwUdxBufLst),mBuf); + cmPkUdxStruct((U8 *)rlcId, sizeof(CmLteRlcId),mBuf); + break; + } + case UDX_SEL_LWLC: + { + CMCHKPK(cmPkPtr,(PTR) pStaPdu, mBuf); + CMCHKPK(cmPkPtr,(PTR) rlcId, mBuf); + break; + } + } + CMCHKPKLOG(SPkS16, suId, mBuf, EUDXXXX, pst); + pst->event = (Event) UDX_EVT_STA_UPD_CFM; + + RETVALUE(SPstTsk(pst, mBuf)); + +} /* cmPkUdxStaUpdCfm */ + +/* +* +* Fun: cmPkUdxStaProhTmrStart +* +* Desc: pack the primitive +* +* Ret: ROK -ok +* +* Notes: None +* +* File: Kw_udx.c +* +*/ +#ifdef ANSI +PUBLIC S16 cmPkUdxStaProhTmrStart +( +Pst *pst, +SpId spId, +CmLteRlcId *rlcId +) +#else +PUBLIC S16 cmPkUdxStaProhTmrStart(pst, suId, rlcId) +Pst *pst; +SpId spId; +CmLteRlcId *rlcId; +#endif +{ + S16 ret1; + Buffer *mBuf = NULLP; + + TRC3(cmPkUdxStaProhTmrStart) + + if((ret1 = SGetMsg(pst->region, pst->pool, &mBuf)) != ROK) + { +#if (ERRCLASS & ERRCLS_ADD_RES) + if(ret1 != ROK) + { + SLogError(pst->srcEnt, pst->srcInst, pst->srcProcId, + __FILE__, __LINE__, (ErrCls)ERRCLS_ADD_RES, + (ErrVal)EUDXXXX, (ErrVal)0, "SGetMsg() failed"); + } +#endif /* ERRCLASS & ERRCLS_ADD_RES */ + + RETVALUE(ret1); + } + + switch (pst->selector) + { + case UDX_SEL_LC: + { + cmPkUdxStruct((U8 *)rlcId, sizeof(CmLteRlcId),mBuf); + break; + } + case UDX_SEL_LWLC: + { + CMCHKPK(cmPkPtr,(PTR) rlcId, mBuf); + break; + } + } + CMCHKPKLOG(SPkS16, spId, mBuf, EUDXXXX, pst); + pst->event = (Event) UDX_EVT_STA_PHBT_TMR_START; + + RETVALUE(SPstTsk(pst, mBuf)); + +} /* cmPkUdxStaProhTmrStart */ + +/* +* +* Fun: cmPkUdxStaUpdReq +* +* Desc: pack the primitive KwUiUdxUeIdChgCfm +* +* Ret: ROK -ok +* +* Notes: None +* +* File: ckw.c +* +*/ +#ifdef ANSI +PUBLIC S16 cmPkUdxStaUpdReq +( +Pst *pst, +SpId spId, +CmLteRlcId *rlcId, +KwUdxStaPdu *pStaPdu +) +#else +PUBLIC S16 cmPkUdxStaUpdReq(pst, suId, rlcId,pStaPdu) +Pst *pst; +SpId spId; +CmLteRlcId *rlcId; +KwUdxStaPdu *pStaPdu; +#endif +{ + S16 ret1; + Buffer *mBuf = NULLP; + + TRC3(cmPkUdxStaUpdReq) + + if((ret1 = SGetMsg(pst->region, pst->pool, &mBuf)) != ROK) + { +#if (ERRCLASS & ERRCLS_ADD_RES) + if(ret1 != ROK) + { + SLogError(pst->srcEnt, pst->srcInst, pst->srcProcId, + __FILE__, __LINE__, (ErrCls)ERRCLS_ADD_RES, + (ErrVal)EUDXXXX, (ErrVal)0, "SGetMsg() failed"); + } +#endif /* ERRCLASS & ERRCLS_ADD_RES */ + + RETVALUE(ret1); + } + + switch (pst->selector) + { + case UDX_SEL_LC: + { + cmPkUdxStruct((U8 *)pStaPdu, sizeof(KwUdxStaPdu),mBuf); + cmPkUdxStruct((U8 *)rlcId, sizeof(CmLteRlcId),mBuf); + SPutStaticBuffer(pst->region,pst->pool,(Data *) pStaPdu, + sizeof(KwUdxStaPdu),0); + + break; + } + case UDX_SEL_LWLC: + { + CMCHKPK(cmPkPtr,(PTR) pStaPdu, mBuf); + CMCHKPK(cmPkPtr,(PTR) rlcId, mBuf); + break; + } + } + CMCHKPKLOG(SPkS16, spId, mBuf, EUDXXXX, pst); + pst->event = (Event) UDX_EVT_STA_UPD_REQ; + + RETVALUE(SPstTsk(pst, mBuf)); + +} /* cmPkUdxStaUpdReq */ + +/* +* +* Fun: cmPkUdxStaPduReq +* +* Desc: pack the primitive KwUiUdxUeIdChgCfm +* +* Ret: ROK -ok +* +* Notes: None +* +* File: ckw.c +* +*/ +#ifdef ANSI +PUBLIC S16 cmPkUdxStaPduReq +( +Pst *pst, +SpId spId, +CmLteRlcId *rlcId, +KwUdxDlStaPdu *pStaPdu +) +#else +PUBLIC S16 cmPkUdxStaPduReq(pst, suId, rlcId,pStaPdu) +Pst *pst; +SpId spId; +CmLteRlcId *rlcId; +KwUdxDlStaPdu *pStaPdu; +#endif +{ + S16 ret1; + Buffer *mBuf = NULLP; + + TRC3(cmPkUdxStaUpdReq) + + if((ret1 = SGetMsg(pst->region, pst->pool, &mBuf)) != ROK) + { +#if (ERRCLASS & ERRCLS_ADD_RES) + if(ret1 != ROK) + { + SLogError(pst->srcEnt, pst->srcInst, pst->srcProcId, + __FILE__, __LINE__, (ErrCls)ERRCLS_ADD_RES, + (ErrVal)EUDXXXX, (ErrVal)0, "SGetMsg() failed"); + } +#endif /* ERRCLASS & ERRCLS_ADD_RES */ + + RETVALUE(ret1); + } + + switch (pst->selector) + { + case UDX_SEL_LC: + { + cmPkUdxStruct((U8 *)pStaPdu, sizeof(KwUdxDlStaPdu),mBuf); + cmPkUdxStruct((U8 *)rlcId, sizeof(CmLteRlcId),mBuf); + /* Free status Pdu here for LC */ + SPutStaticBuffer(pst->region,pst->pool,(Data *) pStaPdu, + sizeof(KwUdxDlStaPdu),0); + break; + } + case UDX_SEL_LWLC: + { + CMCHKPK(cmPkPtr,(PTR) pStaPdu, mBuf); + CMCHKPK(cmPkPtr,(PTR) rlcId, mBuf); + break; + } + } + CMCHKPKLOG(SPkS16, spId, mBuf, EUDXXXX, pst); + pst->event = (Event) UDX_EVT_STA_PDU_REQ; + + RETVALUE(SPstTsk(pst, mBuf)); + +} /* cmPkUdxStaUpdReq */ + +#ifdef LTE_L2_MEAS +/* +* +* Fun: cmPkUdxL2MeasReq +* +* Ret: ROK -ok +* +* Notes: None +* +* +*/ +#ifdef ANSI +PUBLIC S16 cmPkUdxL2MeasReq +( +Pst *pst, +KwL2MeasReqEvt *measReqEvt +) +#else +PUBLIC S16 cmPkUdxL2MeasReq(pst, measReqEvt) +Pst *pst; +KwL2MeasReqEvt *measReqEvt; +#endif +{ + S16 ret1; + Buffer *mBuf = NULLP; + + TRC3(cmPkUdxL2MeasReq) + + if((ret1 = SGetMsg(pst->region, pst->pool, &mBuf)) != ROK) + { +#if (ERRCLASS & ERRCLS_ADD_RES) + if(ret1 != ROK) + { + SLogError(pst->srcEnt, pst->srcInst, pst->srcProcId, + __FILE__, __LINE__, (ErrCls)ERRCLS_ADD_RES, + (ErrVal)EUDXXXX, (ErrVal)0, "SGetMsg() failed"); + } +#endif /* ERRCLASS & ERRCLS_ADD_RES */ + + RETVALUE(ret1); + } + + switch (pst->selector) + { + case UDX_SEL_LC: + { + cmPkUdxStruct((U8 *)measReqEvt, sizeof(KwL2MeasReqEvt),mBuf); + break; + } + case UDX_SEL_LWLC: + { + CMCHKPK(cmPkPtr,(PTR) measReqEvt, mBuf); + break; + } + } + pst->event = (Event) UDX_EVT_L2MEAS_REQ; + + RETVALUE(SPstTsk(pst, mBuf)); + +} /* cmPkUdxStaUpdReq */ + +/* +* +* Fun: cmPkUdxL2MeasReq +* +* Ret: ROK -ok +* +* Notes: None +* +* +*/ +#ifdef ANSI +PUBLIC S16 cmPkUdxL2MeasSendReq +( +Pst *pst, +U8 measType +) +#else +PUBLIC S16 cmPkUdxL2MeasSendReq(pst, measReqEvt) +Pst *pst; +U8 measType +#endif +{ + S16 ret1; + Buffer *mBuf = NULLP; + + TRC3(cmPkUdxL2MeasSendReq) + + if((ret1 = SGetMsg(pst->region, pst->pool, &mBuf)) != ROK) + { +#if (ERRCLASS & ERRCLS_ADD_RES) + if(ret1 != ROK) + { + SLogError(pst->srcEnt, pst->srcInst, pst->srcProcId, + __FILE__, __LINE__, (ErrCls)ERRCLS_ADD_RES, + (ErrVal)EUDXXXX, (ErrVal)0, "SGetMsg() failed"); + } +#endif /* ERRCLASS & ERRCLS_ADD_RES */ + + RETVALUE(ret1); + } + + switch (pst->selector) + { + case UDX_SEL_LC: + case UDX_SEL_LWLC: + { + CMCHKPKLOG(SPkU8, measType, mBuf, EUDXXXX, pst); + break; + } + } + pst->event = (Event) UDX_EVT_L2MEAS_SEND_REQ; + + RETVALUE(SPstTsk(pst, mBuf)); + +} + +/* +* +* Fun: cmPkUdxL2MeasStopReq +* +* Ret: ROK -ok +* +* Notes: None +* +* +*/ +#ifdef ANSI +PUBLIC S16 cmPkUdxL2MeasStopReq +( +Pst *pst, +U8 measType +) +#else +PUBLIC S16 cmPkUdxL2MeasStopReq(pst, measType) +Pst *pst; +U8 measType +#endif +{ + S16 ret1; + Buffer *mBuf = NULLP; + + TRC3(cmPkUdxL2MeasStopReq) + + if((ret1 = SGetMsg(pst->region, pst->pool, &mBuf)) != ROK) + { +#if (ERRCLASS & ERRCLS_ADD_RES) + if(ret1 != ROK) + { + SLogError(pst->srcEnt, pst->srcInst, pst->srcProcId, + __FILE__, __LINE__, (ErrCls)ERRCLS_ADD_RES, + (ErrVal)EUDXXXX, (ErrVal)0, "SGetMsg() failed"); + } +#endif /* ERRCLASS & ERRCLS_ADD_RES */ + + RETVALUE(ret1); + } + + switch (pst->selector) + { + case UDX_SEL_LC: + case UDX_SEL_LWLC: + { + CMCHKPKLOG(SPkU8, measType, mBuf, EUDXXXX, pst); + break; + } + } + pst->event = (Event) UDX_EVT_L2MEAS_STOP_REQ; + + RETVALUE(SPstTsk(pst, mBuf)); + +} +#endif +/****************************************************************************** + * UNPACK FUNCTIONS + *****************************************************************************/ + +/* +* +* Fun: cmUnpkUdxBndReq +* +* Desc: unpack the primitive UdxBndReq +* +* Ret: ROK -ok +* +* Notes: None +* +* File: ckw.c +* +*/ +#ifdef ANSI +PUBLIC S16 cmUnpkUdxBndReq +( +UdxBndReq func, +Pst *pst, +Buffer *mBuf +) +#else +PUBLIC S16 cmUnpkUdxBndReq(func, pst, mBuf) +UdxBndReq func; +Pst *pst; +Buffer *mBuf; +#endif +{ + SuId suId = 0; + SpId spId = 0; + + TRC3(cmUnpkUdxBndReq) + + CMCHKUNPKLOG(SUnpkS16, &suId, mBuf, EUDXXXX, pst); + CMCHKUNPKLOG(SUnpkS16, &spId, mBuf, EUDXXXX, pst); + SPutMsg(mBuf); + + RETVALUE((*func)(pst, suId, spId)); +} /*end of function cmUnpkUdxBndReq*/ + +/* +* +* Fun: cmUnpkUdxUbndReq +* +* Desc: unpack the primitive UdxUbndReq +* +* Ret: ROK -ok +* +* Notes: None +* +* File: ckw.c +* +*/ +#ifdef ANSI +PUBLIC S16 cmUnpkUdxUbndReq +( +UdxUbndReq func, +Pst *pst, +Buffer *mBuf +) +#else +PUBLIC S16 cmUnpkUdxUbndReq(func, pst, mBuf) +UdxUbndReq func; +Pst *pst; +Buffer *mBuf; +#endif +{ + SpId spId = 0; + Reason reason = 0; + + TRC3(cmUnpkUdxUbndReq) + + CMCHKUNPKLOG(SUnpkS16, &spId, mBuf, EUDXXXX, pst); + CMCHKUNPKLOG(SUnpkS16, &reason, mBuf, EUDXXXX, pst); + SPutMsg(mBuf); + RETVALUE((*func)(pst, spId, reason)); +} /*end of function cmUnpkUdxUbndReq*/ + +/* +* +* Fun: cmUnpkUdxBndCfm +* +* Desc: unpack the primitive UdxBndCfm +* +* Ret: ROK -ok +* +* Notes: None +* +* File: ckw.c +* +*/ +#ifdef ANSI +PUBLIC S16 cmUnpkUdxBndCfm +( +UdxBndCfm func, +Pst *pst, +Buffer *mBuf +) +#else +PUBLIC S16 cmUnpkUdxBndCfm(func, pst, mBuf) +UdxBndCfm func; +Pst *pst; +Buffer *mBuf; +#endif +{ + SuId suId = 0; + U8 status = 0; + + TRC3(cmUnpkUdxBndCfm) + + CMCHKUNPKLOG(SUnpkS16, &suId, mBuf, EUDXXXX, pst); + CMCHKUNPKLOG(SUnpkU8, &status, mBuf, EUDXXXX, pst); + SPutMsg(mBuf); + + RETVALUE((*func)(pst, suId, status)); +} /*end of function cmUnpkUdxBndCfm*/ + + +/* +* +* Fun: cmUnpkUdxCfgReq +* +* Desc: unpack the primitive KwUiUdxCfgReq +* +* Ret: ROK -ok +* +* Notes: None +* +* File: ckw.c +* +*/ +#ifdef ANSI +PUBLIC S16 cmUnpkUdxCfgReq +( +UdxCfgReq func, +Pst *pst, +Buffer *mBuf +) +#else +PUBLIC S16 cmUnpkUdxCfgReq(func, pst, mBuf) +UdxCfgReq func; +Pst *pst; +Buffer *mBuf; +#endif +{ +#if(ERRCLASS & ERRCLS_DEBUG) + S16 ret1; +#endif /* ERRCLASS & ERRCLS_DEBUG */ + SpId spId = 0; + CkwCfgInfo tmpCfgInfo; + CkwCfgInfo *cfgInfo; /*stack Variable because it is not freed */ + + TRC3(cmUnpkUdxCfgReq) + + CMCHKUNPK(SUnpkS16, &(spId), mBuf); + switch(pst->selector) + { +#ifdef LCUDX + case UDX_SEL_LC: + { +#if(ERRCLASS & ERRCLS_DEBUG) + ret1 = cmUnpkUdxStruct(mBuf,0,(U8 *)&tmpCfgInfo,sizeof(CkwCfgInfo)); + if(ret1 != ROK) + { + SPutMsg(mBuf); + SLogError(pst->dstEnt, pst->dstInst, pst->dstProcId, + __FILE__, __LINE__, (ErrCls)ERRCLS_DEBUG, + (ErrVal)EUDXXXX, (ErrVal)ret1, "Unpacking failure"); + RETVALUE( ret1 ); + } +#else + cmUnpkUdxStruct(mBuf,0,(U8 *)&tmpCfgInfo,sizeof(CkwCfgInfo)); +#endif /* ERRCLASS & ERRCLS_DEBUG */ + cfgInfo = &tmpCfgInfo; + break; + } + case UDX_SEL_LWLC: + { + CMCHKUNPK(cmUnpkPtr,(PTR *) &cfgInfo, mBuf); + break; + } +#endif /* LCUDX */ + } + SPutMsg(mBuf); + + RETVALUE((*func)(pst, spId, cfgInfo)); +} /* cmUnpkUdxCfgReq */ + + +/* +* +* Fun: cmUnpkUdxCfgCfm +* +* Desc: unpack the primitive KwUiUdxCfgCfm +* +* Ret: ROK -ok +* +* Notes: None +* +* File: ckw.c +* +*/ +#ifdef ANSI +PUBLIC S16 cmUnpkUdxCfgCfm +( +UdxCfgCfm func, +Pst *pst, +Buffer *mBuf +) +#else +PUBLIC S16 cmUnpkUdxCfgCfm(func, pst, mBuf) +UdxCfgCfm func; +Pst *pst; +Buffer *mBuf; +#endif +{ + S16 ret1; + SuId suId = 0; + CkwCfgCfmInfo *cfgCfmInfo = NULLP; + + TRC3(cmUnpkUdxCfgCfm) + + CMCHKUNPK(SUnpkS16, &suId, mBuf); + + switch(pst->selector) + { +#ifdef LCUDX + case UDX_SEL_LC: + { + if((ret1 = SGetStaticBuffer(pst->region, pst->pool, (Data **)&cfgCfmInfo,\ + sizeof(CkwCfgCfmInfo),0)) != ROK) + { +#if (ERRCLASS & ERRCLS_ADD_RES) + if(ret1 != ROK) + { + SLogError(pst->srcEnt, pst->srcInst, pst->srcProcId, + __FILE__, __LINE__, (ErrCls)ERRCLS_ADD_RES, + (ErrVal)EUDXXXX, (ErrVal)0, "SGetMsg() failed"); + } +#endif /* ERRCLASS & ERRCLS_ADD_RES */ + RETVALUE(ret1); + } + + ret1 = cmUnpkUdxStruct(mBuf,0,(U8 *)cfgCfmInfo, sizeof(CkwCfgCfmInfo)); +#if(ERRCLASS & ERRCLS_DEBUG) + if(ret1 != ROK) + { + SPutMsg(mBuf); + SLogError(pst->dstEnt, pst->dstInst, pst->dstProcId, + __FILE__, __LINE__, (ErrCls)ERRCLS_DEBUG, + (ErrVal)EUDXXXX, (ErrVal)ret1, "Unpacking failure"); + RETVALUE( ret1 ); + } +#endif /* ERRCLASS & ERRCLS_DEBUG */ + break; + } + case UDX_SEL_LWLC: + { + CMCHKUNPK(cmUnpkPtr,(PTR *) &cfgCfmInfo, mBuf); + break; + } +#endif /* LCUDX */ + } + SPutMsg(mBuf); + + RETVALUE((*func)(pst, suId, cfgCfmInfo)); +} /* cmUnpkUdxCfgCfm */ + +/* +* +* Fun: cmUnpkUdxUeIdChgReq +* +* Desc: unpack the primitive KwUiUdxUeIdChgReq +* +* Ret: ROK -ok +* +* Notes: None +* +* File: ckw.c +* +*/ +#ifdef ANSI +PUBLIC S16 cmUnpkUdxUeIdChgReq +( +UdxUeIdChgReq func, +Pst *pst, +Buffer *mBuf +) +#else +PUBLIC S16 cmUnpkUdxUeIdChgReq(func, pst, mBuf) +UdxUeIdChgReq func; +Pst *pst; +Buffer *mBuf; +#endif +{ + SpId spId = 0; + U32 transId = 0; + CkwUeInfo tmpUeInfo; + CkwUeInfo tmpNewUeInfo; + CkwUeInfo *ueInfo; + CkwUeInfo *newUeInfo; + + TRC3(cmUnpkUdxUeIdChgReq) + + + CMCHKUNPK(SUnpkS16, &(spId), mBuf); + CMCHKUNPKLOG(SUnpkU32, &transId, mBuf, EUDXXXX, pst); + + switch(pst->selector) + { +#ifdef LCUDX + case UDX_SEL_LC: + { + cmUnpkUdxStruct(mBuf,0,(U8 *)&tmpNewUeInfo, sizeof(CkwUeInfo)); + cmUnpkUdxStruct(mBuf,sizeof(CkwUeInfo),(U8 *)&tmpUeInfo, sizeof(CkwUeInfo)); + + ueInfo = &tmpUeInfo; + newUeInfo = &tmpNewUeInfo; + break; + } + case UDX_SEL_LWLC: + { + CMCHKUNPK(cmUnpkPtr,(PTR *) &ueInfo, mBuf); + CMCHKUNPK(cmUnpkPtr,(PTR *) &newUeInfo, mBuf); + break; + } + default: + { + printf("cmUnpkUdxUeIdChgReq()- selector =%d not supported \n", pst->selector); + exit(1); + } + +#endif /* LCUDX */ + } + SPutMsg(mBuf); + + RETVALUE((*func)(pst, spId, transId, ueInfo, newUeInfo)); + +} /* cmUnpkUdxUeIdChgReq */ + +/* +* +* Fun: cmUnpkUdxUeIdChgCfm +* +* Desc: unpack the primitive KwUiUdxUeIdChgCfm +* +* Ret: ROK -ok +* +* Notes: None +* +* File: ckw.c +* +*/ +#ifdef ANSI +PUBLIC S16 cmUnpkUdxUeIdChgCfm +( +UdxUeIdChgCfm func, +Pst *pst, +Buffer *mBuf +) +#else +PUBLIC S16 cmUnpkUdxUeIdChgCfm(func, pst, mBuf) +UdxUeIdChgCfm func; +Pst *pst; +Buffer *mBuf; +#endif +{ + SuId suId = 0; + U32 transId = 0; + CmStatus status; + + TRC3(cmUnpkUdxUeIdChgCfm) + + cmMemset((U8 *)&status, (U8)0, (PTR)sizeof(CmStatus)); + + CMCHKUNPK(SUnpkS16, &suId, mBuf); + CMCHKUNPKLOG(SUnpkU32, &transId, mBuf, EUDXXXX, pst); + + CMCHKUNPK(cmUnpkCmStatus, &status, mBuf); + + SPutMsg(mBuf); + + RETVALUE((*func)(pst, suId, transId, status)); + +} /* cmUnpkUdxUeIdChgCfm */ + +/* +* +* Fun: cmUnpkUdxStaUpdCfm +* +* Desc: unpack the primitive KwUiUdxUeIdChgCfm +* +* Ret: ROK -ok +* +* Notes: None +* +* File: ckw.c +* +*/ +#ifdef ANSI +PUBLIC S16 cmUnpkUdxStaUpdCfm +( +UdxStaUpdCfm func, +Pst *pst, +Buffer *mBuf +) +#else +PUBLIC S16 cmUnpkUdxStaUpdCfm(func, pst, mBuf) +UdxStaUpdCfm func; +Pst *pst; +Buffer *mBuf; +#endif +{ + SuId suId = 0; + CmLteRlcId *rlcId = NULLP; /* KW_FIX */ + KwUdxBufLst *pBufLst = NULLP; /* KW_FIX*/ + + TRC3(cmUnpkUdxStaUpdCfm) + + CMCHKUNPK(SUnpkS16, &suId, mBuf); + switch (pst->selector) + { + case UDX_SEL_LC: + { + break; + } + case UDX_SEL_LWLC: + { + CMCHKUNPK(cmUnpkPtr, (PTR *)&rlcId,mBuf); + CMCHKUNPK(cmUnpkPtr, (PTR *)&pBufLst,mBuf); + break; + } + } + + SPutMsg(mBuf); + + RETVALUE((*func)(pst, suId, rlcId, pBufLst)); + +} /* cmUnpkUdxUeIdChgCfm */ + +/* +* +* Fun: cmUnpkUdxStaUpdReq +* +* Desc: unpack the primitive KwUiUdxUeIdChgCfm +* +* Ret: ROK -ok +* +* Notes: None +* +* File: ckw.c +* +*/ +#ifdef ANSI +PUBLIC S16 cmUnpkUdxStaUpdReq +( +UdxStaUpdReq func, +Pst *pst, +Buffer *mBuf +) +#else +PUBLIC S16 cmUnpkUdxStaUpdReq(func, pst, mBuf) +UdxStaUpdReq func; +Pst *pst; +Buffer *mBuf; +#endif +{ + SpId spId = 0; + CmLteRlcId *rlcId = NULLP; /* KW_FIX */ + KwUdxStaPdu *pStaPdu = NULLP; /* KW_FIX */ + S16 ret1; + CmLteRlcId tmpRlcId; + + TRC3(cmUnpkUdxStaUpdCfm) + + CMCHKUNPK(SUnpkS16, &spId, mBuf); + switch (pst->selector) + { + case UDX_SEL_LC: + { + if((ret1 = SGetStaticBuffer(pst->region, pst->pool, (Data **)&pStaPdu, + sizeof(KwUdxStaPdu),0)) != ROK) + { +#if (ERRCLASS & ERRCLS_ADD_RES) + if(ret1 != ROK) + { + SLogError(pst->srcEnt, pst->srcInst, pst->srcProcId, + __FILE__, __LINE__, (ErrCls)ERRCLS_ADD_RES, + (ErrVal)EUDXXXX, (ErrVal)0, "SGetMsg() failed"); + } +#endif /* ERRCLASS & ERRCLS_ADD_RES */ + RETVALUE(ret1); + } + ret1 = cmUnpkUdxStruct(mBuf,0,(U8 *)pStaPdu, sizeof(KwUdxStaPdu)); + ret1 = cmUnpkUdxStruct(mBuf,sizeof(KwUdxStaPdu),(U8 *)&tmpRlcId,sizeof(CmLteRlcId)); + rlcId = &tmpRlcId; + break; + } + case UDX_SEL_LWLC: + { + CMCHKUNPK(cmUnpkPtr, (PTR *)&rlcId,mBuf); + CMCHKUNPK(cmUnpkPtr, (PTR *)&pStaPdu,mBuf); + break; + } + } + + SPutMsg(mBuf); + + RETVALUE((*func)(pst, spId, rlcId, pStaPdu)); + +} /* cmUnpkUdxUeIdChgCfm */ + +/* +* +* Fun: cmUnpkUdxStaPduReq +* +* Desc: unpack the primitive KwUiUdxUeIdChgCfm +* +* Ret: ROK -ok +* +* Notes: None +* +* File: ckw.c +* +*/ +#ifdef ANSI +PUBLIC S16 cmUnpkUdxStaPduReq +( +UdxStaPduReq func, +Pst *pst, +Buffer *mBuf +) +#else +PUBLIC S16 cmUnpkUdxStaPduReq(func, pst, mBuf) +UdxStaPduReq func; +Pst *pst; +Buffer *mBuf; +#endif +{ + S16 ret1; + SpId spId = 0; + CmLteRlcId tmpRlcId; + CmLteRlcId *rlcId = NULLP; /* KW_FIX */ + KwUdxDlStaPdu *pStaPdu = NULLP; /* KW_FIX */ + + TRC3(cmUnpkUdxStaUpdCfm) + + CMCHKUNPK(SUnpkS16, &spId, mBuf); + switch (pst->selector) + { + case UDX_SEL_LC: + { + if((ret1 = SGetStaticBuffer(pst->region, pst->pool, (Data **)&pStaPdu, + sizeof(KwUdxDlStaPdu),0)) != ROK) + { +#if (ERRCLASS & ERRCLS_ADD_RES) + if(ret1 != ROK) + { + SLogError(pst->srcEnt, pst->srcInst, pst->srcProcId, + __FILE__, __LINE__, (ErrCls)ERRCLS_ADD_RES, + (ErrVal)EUDXXXX, (ErrVal)0, "SGetMsg() failed"); + } +#endif /* ERRCLASS & ERRCLS_ADD_RES */ + RETVALUE(ret1); + } + ret1 = cmUnpkUdxStruct(mBuf,0, (U8 *)pStaPdu, sizeof(KwUdxDlStaPdu)); + ret1 = cmUnpkUdxStruct(mBuf,sizeof(KwUdxDlStaPdu),(U8 *)&tmpRlcId,sizeof(CmLteRlcId)); + rlcId = &tmpRlcId; + break; + } + case UDX_SEL_LWLC: + { + CMCHKUNPK(cmUnpkPtr, (PTR *)&rlcId,mBuf); + CMCHKUNPK(cmUnpkPtr, (PTR *)&pStaPdu,mBuf); + break; + } + } + + SPutMsg(mBuf); + RETVALUE((*func)(pst, spId, rlcId, pStaPdu)); + +} /* cmUnpkUdxUeIdChgCfm */ + +/* +* +* Fun: cmUnpkUdxStaProhTmrStart +* +* Desc: unpack the Status prohibit timer start Msg +* +* Ret: ROK -ok +* +* Notes: None +* +* File: kw_udx.c +* +*/ +#ifdef ANSI +PUBLIC S16 cmUnpkUdxStaProhTmrStart +( +UdxStaProhTmrStart func, +Pst *pst, +Buffer *mBuf +) +#else +PUBLIC S16 cmUnpkUdxStaProhTmrStart(func, pst, mBuf) +UdxStaProhTmrStart func; +Pst *pst; +Buffer *mBuf; +#endif +{ + SpId spId = 0; + CmLteRlcId tmpRlcId; + CmLteRlcId *rlcId = NULLP; /* KW_FIX */ + + TRC3(cmUnpkUdxStaProhTmrStart) + + CMCHKUNPK(SUnpkS16, &spId, mBuf); + switch (pst->selector) + { + case UDX_SEL_LC: + { + cmUnpkUdxStruct(mBuf,0,(U8 *)&tmpRlcId,sizeof(CmLteRlcId)); + rlcId = &tmpRlcId; + break; + } + case UDX_SEL_LWLC: + { + CMCHKUNPK(cmUnpkPtr, (PTR *)&rlcId,mBuf); + break; + } + } + + SPutMsg(mBuf); + + RETVALUE((*func)(pst, spId, rlcId)); + +} /* cmUnpkUdxStaProhTmrStart */ + +#ifdef LTE_L2_MEAS +/* + + +* Fun: cmUnpkUdxL2MeasReq +* +* Ret: ROK -ok +* +* Notes: None +* +* +*/ +#ifdef ANSI +PUBLIC S16 cmUnpkUdxL2MeasReq +( +UdxL2MeasReq func, +Pst *pst, +Buffer *mBuf +) +#else +PUBLIC S16 cmUnpkUdxL2MeasReq(func, pst, mBuf) +UdxL2MeasReq func; +Pst *pst; +Buffer *mBuf; +#endif +{ + KwL2MeasReqEvt tmpMeasReqEvt; + KwL2MeasReqEvt *measReqEvt = NULLP; /* KW_FIX */ + + TRC3(cmUnpkUdxL2MeasReq) + + switch (pst->selector) + { + case UDX_SEL_LC: + { + cmUnpkUdxStruct(mBuf,0,(U8 *)&tmpMeasReqEvt,sizeof(KwL2MeasReqEvt)); + measReqEvt = &tmpMeasReqEvt; + break; + } + case UDX_SEL_LWLC: + { + CMCHKUNPK(cmUnpkPtr, (PTR *)&measReqEvt,mBuf); + break; + } + } + + SPutMsg(mBuf); + + RETVALUE((*func)(pst, measReqEvt)); +} /* cmUnpkUdxL2MeasReq */ + +/* +* +* Fun: cmUnpkUdxL2MeasSendReq +* +* Ret: ROK -ok +* +* Notes: None +* +* +*/ +#ifdef ANSI +PUBLIC S16 cmUnpkUdxL2MeasSendReq +( +UdxL2MeasSendReq func, +Pst *pst, +Buffer *mBuf +) +#else +PUBLIC S16 cmUnpkUdxL2MeasSendReq(func, pst, mBuf) +UdxL2MeasSendReq func; +Pst *pst; +Buffer *mBuf; +#endif +{ + U8 measType = 0; /* KW_FIX */ + + TRC3(cmUnpkUdxL2MeasSendReq) + + switch (pst->selector) + { + case UDX_SEL_LC: + case UDX_SEL_LWLC: + { + CMCHKUNPK(SUnpkU8, &measType, mBuf); + break; + } + } + + SPutMsg(mBuf); + + RETVALUE((*func)(pst, measType)); +} /* cmUnpkUdxL2MeasReq */ + +/* +* +* Fun: cmUnpkUdxL2MeasStopReq +* +* Ret: ROK -ok +* +* Notes: None +* +* +*/ +#ifdef ANSI +PUBLIC S16 cmUnpkUdxL2MeasStopReq +( +UdxL2MeasStopReq func, +Pst *pst, +Buffer *mBuf +) +#else +PUBLIC S16 cmUnpkUdxL2MeasStopReq(func, pst, mBuf) +UdxL2MeasSendReq func; +Pst *pst; +Buffer *mBuf; +#endif +{ + U8 measType = 0; /* KW_FIX */ + + TRC3(cmUnpkUdxL2MeasStopReq) + + switch (pst->selector) + { + case UDX_SEL_LC: + case UDX_SEL_LWLC: + { + CMCHKUNPK(SUnpkU8, &measType, mBuf); + break; + } + } + + SPutMsg(mBuf); + + RETVALUE((*func)(pst, measType)); +} /* cmUnpkUdxL2MeasStopReq */ +#endif +#endif /* LCUDX */ + + +/********************************************************************30** + End of file +**********************************************************************/ diff --git a/src/5gnrrlc/kw_udx.h b/src/5gnrrlc/kw_udx.h new file mode 100755 index 000000000..944689183 --- /dev/null +++ b/src/5gnrrlc/kw_udx.h @@ -0,0 +1,110 @@ +/******************************************************************************* +################################################################################ +# Copyright (c) [2017-2019] [Radisys] # +# # +# 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. # +################################################################################ +*******************************************************************************/ + +/********************************************************************20** + + Name: UDX Control Interface + + Type: C include file + + Desc: This file Contains the Data structures for and prototypes + UDX Interface + + File: kw_udx.h + +*********************************************************************21*/ + +#ifndef __KW_UDX_H__ +#define __KW_UDX_H__ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + +/** @file kw_udx.h + @brief UDX Interface File (ckw.h) +*/ + +/* UDX Interface Hash Defines */ + +/* Loose Coupling define */ +#define UDX_SEL_LC 0 /*!< Loose Coupling Option */ +#define UDX_SEL_LWLC 1 +#define KW_MAX_UDX 3 + + +/* CKW Interface defines */ +#define UDX_MAX_ENT_CFG 24 /*!< Maximum number of entities to configure */ + +#define ERRUDX 0 +#define EUDXXXX 0 +/* ckw_h_001.main_3 added support for L2 Measurement */ +#ifdef LTE_L2_MEAS +#define UDX_MAX_QCI 10 +#endif +/* CKW Interface configuration type */ +#define UDX_CFG_ADD 1 /*!< Add RLC Entity */ +#define UDX_CFG_MODIFY 2 /*!< Modify RLC Entity */ +#define UDX_CFG_DELETE 3 /*!< Delete RLC entity */ +#define UDX_CFG_REESTABLISH 4 /*!< Re-establish RLC entity */ +#define UDX_CFG_DELETE_UE 5 /*!< Release RLC entities per UE */ +#define UDX_CFG_DELETE_CELL 6 /*!< Release RLC entities per Cell */ + +/* CKW RLC entity direction configuration */ +#define UDX_CFG_DIR_UL 1 /*!< Unlink direction */ +#define UDX_CFG_DIR_DL 2 /*!< Downlink direction */ +#define UDX_CFG_DIR_BOTH 3 /*!< Both Downlink and Unlink */ + +/* CKW Configuration confirmations */ +#define UDX_CFG_CFM_OK 1 /*!< Configuration confirmation success */ +#define UDX_CFG_CFM_NOK 2 /*!< Configuration confirmation failed */ + +/*********************************************************************** + Defines for CKW Interface Events + ***********************************************************************/ +#define UDX_EVT_BND_REQ 0x01 /*!< Bind Request */ +#define UDX_EVT_BND_CFM 0x02 /*!< Bind Confirm */ +#define UDX_EVT_UBND_REQ 0x03 /*!< Unbind Request */ +#define UDX_EVT_CFG_REQ 0x04 /*!< Config Request */ +#define UDX_EVT_CFG_CFM 0x05 /*!< Config Confirm */ +#define UDX_EVT_UEIDCHG_REQ 0x06 /*!< UE Id Change Request */ +#define UDX_EVT_UEIDCHG_CFM 0x07 /*!< UE Id Change Confirm */ +#define UDX_EVT_STA_UPD_REQ 0x08 +#define UDX_EVT_STA_UPD_CFM 0x09 +#define UDX_EVT_STA_PDU_REQ 0x0A +#define UDX_EVT_STA_PHBT_TMR_START 0x0B +#define UDX_EVT_DL_CLEANUP_MEM 0x10 /*!< To cleanup memory in DL inst */ + +/*********************************************************************** + Defines for Measurements + ***********************************************************************/ +#define UDX_EVT_L2MEAS_REQ 0x11 +#define UDX_EVT_L2MEAS_SEND_REQ 0x12 +#define UDX_EVT_L2MEAS_STOP_REQ 0x13 + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif + + +/********************************************************************30** + End of file +**********************************************************************/ diff --git a/src/5gnrrlc/kw_udx.x b/src/5gnrrlc/kw_udx.x new file mode 100755 index 000000000..a97ca4905 --- /dev/null +++ b/src/5gnrrlc/kw_udx.x @@ -0,0 +1,308 @@ +/******************************************************************************* +################################################################################ +# Copyright (c) [2017-2019] [Radisys] # +# # +# 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. # +################################################################################ +*******************************************************************************/ + +/********************************************************************** + + Name: LTE RLC layer + + Type: C include file + + Desc: Defines required by LTE MAC + + File: kw_udx.x + + +**********************************************************************/ +/** @file kw_udx.x +@brief This file contains basic data structures for the Uplink Downlink +interface. +*/ + +#ifndef __UDX_X__ +#define __UDX_X__ + +#include "ckw.h" +#include "ckw.x" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +typedef struct kwNackInfo +{ + U8 nackRange; + U8 isSegment; + U32 sn; /*!< Nack Sn */ + U16 soStart; /*!< Segment offset start */ + U16 soEnd; /*!< Segment offset End */ +}KwNackInfo; + +typedef struct kwUdxStaPdu +{ + U32 ackSn; + /* TODO : KW_MAX_NACK_CNT should set to MAx SR delay + It is tradeoff to consider array based instead of dynamic + as there are chances where we might loose Status information + on spill over*/ + U8 nackCnt; /* Cnt of Nacks in the array*/ + KwNackInfo nackInfo[KW_MAX_NACK_CNT]; +}KwUdxStaPdu; + +typedef struct kwUdxBufLst +{ + CmLListCp rlsTxLst; /*!< Stores to be released Tx PDUs */ + CmLListCp rlsRetxLst; /*!< Stores to be released Retx PDUs */ + CmLListCp rlsSduLst; /*!< Stores to be released SDUs*/ +}KwUdxBufLst; + +typedef struct kwStatusPdu +{ + U32 ackSn; + KwNackInfo nackInfo[KW_MAX_NACK_CNT]; + U16 nackCount; + U16 controlBo; +}KwUdxDlStaPdu; +/* ### Umapathi*/ + +/** + * @brief + * UDX APIs + */ +typedef S16 (*UdxBndCfm) ARGS((Pst* pst, SuId suId,U8 status )); + +typedef S16 (*UdxBndReq) ARGS((Pst* pst, SuId suId,SpId spId )); + +typedef S16 (*UdxUbndReq) ARGS((Pst* pst, SuId suId,Reason reason)); + +typedef S16 (*UdxCfgReq) ARGS((Pst *pst, SpId spId, CkwCfgInfo *cfgInfo)); + +typedef S16 (*UdxCfgCfm) ARGS((Pst* pst,SuId suId,CkwCfgCfmInfo *cfmInfo)); + +typedef S16 (*UdxStaUpdReq) ARGS((Pst* pst, + SpId spId, + CmLteRlcId *rlcId, + KwUdxStaPdu *pStaPdu )); + +typedef S16 (*UdxUeIdChgReq) ARGS((Pst *pst, + SpId spId, + U32 transId, + CkwUeInfo *ueInfo, + CkwUeInfo *newUeInfo)); + +typedef S16 (*UdxUeIdChgCfm) ARGS((Pst *pst, + SuId suId, + U32 transId, + CmStatus status)); + +typedef S16 (*UdxStaUpdCfm) ARGS((Pst* pst, + SuId suId, + CmLteRlcId *rlcId, + KwUdxBufLst *pBufLst)); + +typedef S16 (*UdxStaPduReq) ARGS((Pst* pst, + SpId spId, + CmLteRlcId *rlcId, + KwUdxDlStaPdu *pStaPdu)); + +typedef S16 (*UdxStaProhTmrStart) ARGS((Pst* pst, + SuId suId, + CmLteRlcId *rlcId)); + +#ifdef LTE_L2_MEAS +typedef S16 (*UdxL2MeasReq) ARGS((Pst* pst, + KwL2MeasReqEvt *measReqEvt)); + +typedef S16 (*UdxL2MeasSendReq) ARGS((Pst* pst, + U8 measType)); + +typedef S16 (*UdxL2MeasStopReq) ARGS((Pst* pst, + U8 measType)); +#endif + +#ifdef LCUDX +EXTERN S16 cmPkUdxBndCfm ARGS((Pst* pst, SuId suId,U8 status )); +EXTERN S16 cmPkUdxBndReq ARGS((Pst* pst, SuId suId,SpId spId )); +EXTERN S16 cmPkUdxUbndReq ARGS((Pst* pst, SuId suId,Reason reason)); +EXTERN S16 cmPkUdxCfgReq ARGS((Pst *pst, SpId spId, CkwCfgInfo *cfgInfo)); +EXTERN S16 cmPkUdxCfgCfm ARGS(( Pst* pst,SuId suId,CkwCfgCfmInfo *cfmInfo)); +EXTERN S16 cmPkUdxStaUpdReq ARGS((Pst* pst,SpId spId,CmLteRlcId *rlcId, + KwUdxStaPdu *pStaPdu )); +EXTERN S16 cmPkUdxUeIdChgReq ARGS((Pst *pst, SpId spId, U32 transId, + CkwUeInfo *ueInfo, CkwUeInfo *newUeInfo)); +EXTERN S16 cmPkUdxUeIdChgCfm ARGS((Pst *pst, SuId suId, U32 transId, + CmStatus status)); + + +EXTERN S16 cmPkUdxStaUpdCfm ARGS((Pst* pst,SuId suId,CmLteRlcId *rlcId, + KwUdxBufLst *pBufLst)); + +EXTERN S16 cmPkUdxStaPduReq ARGS(( Pst* pst,SpId spId, CmLteRlcId *rlcId, + KwUdxDlStaPdu *pStaPdu )); +EXTERN S16 cmPkUdxStaProhTmrStart ARGS((Pst *pst, + SpId spId, + CmLteRlcId *rlcId)); + +#ifdef LTE_L2_MEAS +EXTERN S16 cmPkUdxL2MeasReq ARGS((Pst *pst, KwL2MeasReqEvt *measReqEvt)); +EXTERN S16 cmPkUdxL2MeasSendReq ARGS((Pst *pst, U8 measType)); +EXTERN S16 cmPkUdxL2MeasStopReq ARGS((Pst *pst, U8 measType)); +#endif + +EXTERN S16 cmUnpkUdxBndCfm ARGS((UdxBndCfm func,Pst* pst, Buffer *mBuf )); +EXTERN S16 cmUnpkUdxBndReq ARGS((UdxBndReq func,Pst* pst, Buffer *mBuf )); +EXTERN S16 cmUnpkUdxUbndReq ARGS((UdxUbndReq func,Pst* pst, Buffer *mBuf)); +EXTERN S16 cmUnpkUdxCfgReq ARGS((UdxCfgReq func,Pst *pst, Buffer *mBuf)); +EXTERN S16 cmUnpkUdxCfgCfm ARGS((UdxCfgCfm func , Pst* pst,Buffer *mBuf)); +EXTERN S16 cmUnpkUdxStaUpdReq ARGS((UdxStaUpdReq func,Pst* pst,Buffer *mBuf)); +EXTERN S16 cmUnpkUdxUeIdChgReq ARGS((UdxUeIdChgReq func,Pst *pst, Buffer *mBuf)); +EXTERN S16 cmUnpkUdxUeIdChgCfm ARGS((UdxUeIdChgCfm func,Pst *pst, Buffer *mBuf)); + +EXTERN S16 cmUnpkUdxStaUpdCfm ARGS((UdxStaUpdCfm func,Pst* pst,Buffer *mBuf)); + +EXTERN S16 cmUnpkUdxStaPduReq ARGS((UdxStaPduReq func, Pst* pst, Buffer *mBuf)); + +EXTERN S16 cmUnpkUdxStaProhTmrStart ARGS((UdxStaProhTmrStart func, + Pst* pst, + Buffer *mBuf)); + +#ifdef LTE_L2_MEAS +EXTERN S16 cmUnpkUdxL2MeasReq ARGS((UdxL2MeasReq func, Pst* pst, Buffer *mBuf)); +EXTERN S16 cmUnpkUdxL2MeasSendReq ARGS((UdxL2MeasSendReq func, Pst* pst, Buffer *mBuf)); +EXTERN S16 cmUnpkUdxL2MeasStopReq ARGS((UdxL2MeasStopReq func, Pst* pst, Buffer *mBuf)); +#endif +#endif + +#ifdef KW +EXTERN S16 KwUlUdxBndReq ARGS((Pst* pst, SuId suId, SpId spId)); + +EXTERN S16 KwDlUdxBndReq ARGS((Pst* pst, SuId suId, SpId spId)); + +EXTERN S16 KwDlUdxBndCfm ARGS((Pst* pst, SuId suId, U8 status)); + +EXTERN S16 KwUlUdxBndCfm ARGS((Pst* pst, SuId suId, U8 status)); + +EXTERN S16 KwDlUdxCfgCfm ARGS((Pst* pst, SuId suId, CkwCfgCfmInfo *cfmInfo)); + +EXTERN S16 KwUlUdxCfgCfm ARGS((Pst* pst, SuId suId, CkwCfgCfmInfo *cfmInfo)); + +EXTERN S16 KwDlUdxUeIdChgCfm ARGS((Pst *pst, + SuId suId, + U32 transId, + CmStatus status)); + +EXTERN S16 KwUlUdxUeIdChgCfm ARGS((Pst *pst, + SuId suId, + U32 transId, + CmStatus status)); + +EXTERN S16 KwUlUdxUbndReq ARGS((Pst* pst, SuId suId, Reason reason)); + +EXTERN S16 KwDlUdxUbndReq ARGS((Pst* pst, SuId suId, Reason reason)); + +EXTERN S16 KwUlUdxUeIdChgReq ARGS((Pst *pst, + SpId spId, + U32 transId, + CkwUeInfo *ueInfo, + CkwUeInfo *newUeInfo)); + +EXTERN S16 KwUlUdxCfgReq ARGS((Pst *pst, SpId spId, CkwCfgInfo *cfgInfo)); + +EXTERN S16 KwDlUdxCfgReq ARGS((Pst *pst, SpId spId, CkwCfgInfo *cfgInfo)); + +EXTERN S16 KwUlUdxStaUpdReq ARGS((Pst* pst, + SpId spId, + CmLteRlcId *rlcId, + KwUdxStaPdu *pStaPdu)); + +EXTERN S16 KwDlUdxStaUpdReq ARGS((Pst* pst, + SpId spId, + CmLteRlcId *rlcId, + KwUdxStaPdu *pStaPdu)); + +EXTERN S16 KwDlUdxStaUpdCfm ARGS((Pst* pst, + SuId suId, + CmLteRlcId *rlcId, + KwUdxBufLst *pBufLst)); + +EXTERN S16 KwUlUdxStaUpdCfm ARGS((Pst* pst, + SuId suId, + CmLteRlcId *rlcId, + KwUdxBufLst *pBufLst)); + +EXTERN S16 KwUlUdxStaPduReq ARGS((Pst *pst, + SpId spId, + CmLteRlcId *rlcId, + KwUdxDlStaPdu *pStaPdu )); + +EXTERN S16 KwDlUdxStaPduReq ARGS((Pst *pst, + SpId spId, + CmLteRlcId *rlcId, + KwUdxDlStaPdu *pStaPdu)); + +EXTERN S16 KwDlUdxUeIdChgReq ARGS((Pst *pst, + SpId spId, + U32 transId, + CkwUeInfo *ueInfo, + CkwUeInfo *newUeInfo)); + +EXTERN S16 KwDlUdxCfgReq ARGS((Pst *pst, SpId spId, CkwCfgInfo *cfgInfo)); + + +EXTERN S16 KwUlUdxStaUpdCfm ARGS((Pst* pst, + SuId suId, + CmLteRlcId *rlcId, + KwUdxBufLst *pBufLst)); + +EXTERN S16 KwDlUdxStaPduReq ARGS((Pst *pst, + SpId spId, + CmLteRlcId *rlcId, + KwUdxDlStaPdu *pStaPdu)); + +EXTERN S16 KwUlUdxStaProhTmrStart ARGS((Pst *pst, + SpId spId, + CmLteRlcId *rlcId )); + +EXTERN S16 KwDlUdxStaProhTmrStart ARGS((Pst *pst, + SpId spId, + CmLteRlcId *rlcId )); + +#ifdef LTE_L2_MEAS +EXTERN S16 KwDlUdxL2MeasReq ARGS((Pst *pst, KwL2MeasReqEvt *measReqEvt)); + +EXTERN S16 KwDlUdxL2MeasSendReq ARGS((Pst *pst, U8 status)); + +EXTERN S16 KwDlUdxL2MeasStopReq ARGS((Pst *pst, U8 status)); + +EXTERN S16 KwUlUdxL2MeasReq ARGS((Pst* pst, KwL2MeasReqEvt *measReqEvt)); + +EXTERN S16 KwUlUdxL2MeasSendReq ARGS((Pst *pst, U8 status)); + +EXTERN S16 KwUlUdxL2MeasStopReq ARGS((Pst* pst, U8 measType)); +#endif + +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* __UDX_X__ */ + + +/********************************************************************** + End of file +**********************************************************************/ diff --git a/src/5gnrrlc/kw_udx_dl.c b/src/5gnrrlc/kw_udx_dl.c new file mode 100755 index 000000000..2cc94e4de --- /dev/null +++ b/src/5gnrrlc/kw_udx_dl.c @@ -0,0 +1,826 @@ +/******************************************************************************* +################################################################################ +# Copyright (c) [2017-2019] [Radisys] # +# # +# 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. # +################################################################################ +*******************************************************************************/ + +/********************************************************************** + + Name: LTE RLC layer + + Type: C include file + + Desc: Defines required by LTE MAC + + File: kw_udx_dl.c + +**********************************************************************/ +static const char* RLOG_MODULE_NAME="UDX"; +static int RLOG_MODULE_ID=262144; +static int RLOG_FILE_ID=203; + +/* header include files (.h) */ +#include "envopt.h" /* environment options */ +#include "envdep.h" /* environment dependent */ +#include "envind.h" /* environment independent */ + +#include "gen.h" /* general */ +#include "ssi.h" /* system services */ +#include "cm5.h" /* common timer defines */ +#include "cm_tkns.h" /* common tokens defines */ +#include "cm_mblk.h" /* common memory allocation library defines */ +#include "cm_llist.h" /* common link list defines */ +#include "cm_hash.h" /* common hash list defines */ +#include "cm_lte.h" /* common LTE defines */ +#include "lkw.h" /* LKW defines */ +#include "ckw.h" /* CKW defines */ +#include "kwu.h" /* KWU defines */ +#include "rgu.h" /* RGU defines */ +#include "kw_err.h" /* Err defines */ +#include "kw_env.h" /* RLC environment options */ + +#include "kw.h" /* RLC defines */ +#include "kw_udx.h" +#include "kw_dl.h" + +/* extern (.x) include files */ +#include "gen.x" /* general */ +#include "ssi.x" /* system services */ + +#include "cm5.x" /* common timer library */ +#include "cm_tkns.x" /* common tokens */ +#include "cm_mblk.x" /* common memory allocation */ +#include "cm_llist.x" /* common link list */ +#include "cm_hash.x" /* common hash list */ +#include "cm_lte.x" /* common LTE includes */ +#include "cm_lib.x" /* common memory allocation library */ +#include "lkw.x" /* LKW */ +#include "ckw.x" /* CKW */ +#include "kwu.x" /* KWU */ +#include "rgu.x" /* RGU */ + +#include "kw.x" +#include "kw_udx.x" +#include "kw_dl.x" + + +#define KW_MODULE KW_DBGMASK_UDX +/* local defines */ + +EXTERN S16 kwDlmHndlStaRsp ARGS (( KwCb *gCb,KwDlRbCb *rbCb, + KwUdxStaPdu *pStaPdu, KwUdxBufLst *rlsPduLst)); + + + + +/** + * @brief + * UDX APIs + */ + +/** + * + * @brief + * Handler to bind the DL with UL. + * + * @param[in] pst Post structure + * @param[in] suId Service user SAP ID + * @param[in] spId Service provider ID + * + * @return S16 + * -# ROK + * -# RFAILED + */ +#ifdef ANSI +PUBLIC S16 KwDlUdxBndReq +( +Pst *pst, +SuId suId, +SpId spId +) +#else +PUBLIC S16 KwDlUdxBndReq (pst, suId, spId) +Pst *pst; +SuId suId; +SpId spId; +#endif +{ + KwUdxDlSapCb *udxSap; /* pointer to session SAP */ + KwCb *tKwCb; + + TRC3(KwDlUdxBndReq); + +#if (ERRCLASS & ERRCLS_INT_PAR) + if (pst->dstInst >= KW_MAX_RLC_INSTANCES) + { + RETVALUE(RFAILED); + } +#endif + tKwCb = KW_GET_KWCB(pst->dstInst); + + KWDBGP_BRIEF(tKwCb, "KwDlUdxBndReq(spId(%d), suId(%d))\n", + spId, suId); + + udxSap = (tKwCb->u.dlCb->udxDlSap + spId); + + /* Verify CKW SAP State */ + switch(udxSap->state) + { + /* SAP is configured but not bound */ + case KW_SAP_CFG: + case KW_SAP_UBND: + { + /* copy bind configuration parameters in SSAP sap */ + udxSap->suId = suId; + udxSap->pst.dstProcId = pst->srcProcId; + udxSap->pst.dstEnt = pst->srcEnt; + udxSap->pst.dstInst = pst->srcInst; + + /* Update the State */ + udxSap->state = KW_SAP_BND; + + RLOG1(L_INFO, "UDX SAP state [%d]", udxSap->state); + break; + } + /* SAP is already bound */ + case KW_SAP_BND: + { + /* + * Sap is already bound check source, destination Entity and + * Proc Id + */ + if (udxSap->pst.dstProcId != pst->srcProcId + || udxSap->pst.dstEnt != pst->srcEnt + || udxSap->pst.dstInst != pst->srcInst + || udxSap->suId != suId) + { + KW_SEND_SAPID_ALARM(tKwCb, spId, + LKW_EVENT_UDX_BND_REQ, LCM_CAUSE_INV_PAR_VAL); + + RLOG0(L_ERROR, "UDX SAP already Bound"); + KwDlUdxBndCfm(&(udxSap->pst), udxSap->suId, CM_BND_NOK); + } + break; + } + + default: + { +#if (ERRCLASS & ERRCLS_INT_PAR) + KW_SEND_SAPID_ALARM(tKwCb,spId, + LKW_EVENT_CKW_BND_REQ, LCM_CAUSE_INV_STATE); +#endif /* ERRCLASS & ERRCLS_INT_PAR */ + RLOG0(L_ERROR, "Invalid UDX SAP State in Bind Req"); + KwDlUdxBndCfm(&(udxSap->pst), udxSap->suId, CM_BND_NOK); + break; + } + } + KwDlUdxBndCfm(&(udxSap->pst), udxSap->suId, CM_BND_OK); + RETVALUE(ROK); +} + + +/** + * @brief + * Handler for unbinding the DL from UL. + * + * @param[in] pst Post structure + * @param[in] spId Service provider SAP ID + * @param[in] reason Reason for Unbinding + * + * @return S16 + * -# ROK + */ +#ifdef ANSI +PUBLIC S16 KwDlUdxUbndReq +( +Pst *pst, +SpId spId, +Reason reason +) +#else +PUBLIC S16 KwDlUdxUbndReq(pst, spId, reason) +Pst *pst; +SpId spId; +Reason reason; +#endif +{ + KwUdxDlSapCb *udxSap; + KwCb *tKwCb; + + TRC3(KwDlUdxUbndReq) + +#if (ERRCLASS & ERRCLS_INT_PAR) + if (pst->dstInst >= KW_MAX_RLC_INSTANCES) + { + RETVALUE(RFAILED); + } +#endif + + tKwCb = KW_GET_KWCB(pst->dstInst); + + RLOG2(L_DEBUG,"Unbind Req for spId[%d], reason[%d]", + spId, reason); + UNUSED(reason); + /* disable upper sap (CKW) */ + udxSap = (tKwCb->u.dlCb->udxDlSap + spId); + +#if (ERRCLASS & ERRCLS_INT_PAR) + KW_GET_AND_VALIDATE_UDXSAP(tKwCb,udxSap, EKW208, "KwUiDlUdxndReq"); +#endif /* ERRCLASS & ERRCLS_INT_PAR */ + udxSap->state = KW_SAP_CFG; + RETVALUE(ROK); +} + + +/** + * @brief + * Handler for configuring RLC entities. + * + * @details + * This function is used by RRC to configure(add/delete/modify) + * one or more RLC entities. + * - CKW_CFG_ADD => kwCfgAddRb + * - CKW_CFG_MODIFY => kwCfgReCfgRb + * - CKW_CFG_DELETE => kwCfgDelRb + * - CKW_CFG_REESTABLISH => kwCfgReEstRb + * - CKW_CFG_DELETE_UE => kwCfgDelUe + * + * @param[in] pst - Post structure + * @param[in] spId - Serive Provider ID + * @param[in] cfg - Configuration information for one or more RLC entities. + * + * @return S16 + * -# ROK + * -# RFAILED + */ +#ifdef ANSI +PUBLIC S16 KwDlUdxCfgReq +( +Pst *pst, +SpId spId, +CkwCfgInfo *cfg +) +#else +PUBLIC S16 KwDlUdxCfgReq(pst, spId, cfg) +Pst *pst; +SpId spId; +CkwCfgInfo *cfg; +#endif +{ + CkwCfgCfmInfo *cfgCfm; + U8 idx; + S16 ret = ROK; + KwCb *tKwCb; + Pst *pstUdxCfm; + + TRC3(KwDlUdxCfgReq) + +#if (ERRCLASS & ERRCLS_INT_PAR) + if (pst->dstInst >= KW_MAX_RLC_INSTANCES) + { + RETVALUE(RFAILED); + } +#endif + + tKwCb = KW_GET_KWCB(pst->dstInst); + + pstUdxCfm = &(tKwCb->u.dlCb->udxDlSap[spId].pst); + KWDBGP_BRIEF(tKwCb,"spId(%d)\n", spId); + + /* Validate SAP ID under ERRORCLS */ + KW_VALDATE_SAP(tKwCb,spId, + (&tKwCb->u.dlCb->udxDlSap[spId]), + ret); + if (ret != ROK) + { + /* kw002.201 Freeing from proper region */ + /* only RLC UL will free it KW_PST_FREE(pst->region, pst->pool, cfg, sizeof(CkwCfgInfo)); */ + RETVALUE(RFAILED); + } + + /* Allocate memory and memset to 0 for cfmInfo */ + KW_ALLOC_SHRABL_BUF_WC(pstUdxCfm->region, + pstUdxCfm->pool, + cfgCfm, + sizeof(CkwCfgCfmInfo)); + +#if (ERRCLASS & ERRCLS_ADD_RES) + if (cfgCfm == NULLP) + { + RLOG0(L_FATAL,"Memory Allocation Failed."); + /* kw002.201 Freeing from proper region */ + /* KW_PST_FREE(pst->region, pst->pool, cfg, sizeof(CkwCfgInfo)); */ + RETVALUE(RFAILED); + } +#endif /* ERRCLASS & ERRCLS_ADD_RES */ + + /* For every entity configuration process by cfgType */ + for (idx = 0; idx < cfg->numEnt; idx++) + { + CkwEntCfgCfmInfo *entCfgCfm; + CkwEntCfgInfo *entCfg; + + entCfg = (CkwEntCfgInfo *)&(cfg->entCfg[idx]); + entCfgCfm = (CkwEntCfgCfmInfo *)&(cfgCfm->entCfgCfm[idx]); + + switch (entCfg->cfgType) + { + case CKW_CFG_ADD: + { + if (entCfg->dir & KW_DIR_DL) + { + /* Add a new RB entity configuration */ + if (kwCfgAddDlRb(tKwCb,cfg->ueId, cfg->cellId,\ + entCfg, entCfgCfm) != ROK) + { + RLOG_ARG1(L_ERROR,DBG_RBID,cfg->entCfg[idx].rbId,"Addition Failed due to[%d]", + entCfgCfm->status.reason); + } + } + break; + } + case CKW_CFG_MODIFY: + { + if (entCfg->dir & KW_DIR_DL) + { + /* Re-configure the existing RB entity configuration */ + if (kwCfgReCfgDlRb(tKwCb,cfg->ueId, cfg->cellId,\ + entCfg, entCfgCfm) != ROK) + { + RLOG_ARG1(L_ERROR,DBG_RBID,cfg->entCfg[idx].rbId,"ReCfg Failed due to[%d]", + entCfgCfm->status.reason); + } + } + break; + } + + case CKW_CFG_DELETE: + { + if (entCfg->dir & KW_DIR_DL) + { + /* Delete the existing RB entity configuration */ + if (kwCfgDelDlRb(tKwCb,cfg->ueId, cfg->cellId,\ + entCfg, entCfgCfm) != ROK) + { + RLOG_ARG1(L_ERROR,DBG_RBID,cfg->entCfg[idx].rbId,"Deletion Failed due to[%d]", + entCfgCfm->status.reason); + } + } + break; + } + + case CKW_CFG_REESTABLISH: + { + if (entCfg->dir & KW_DIR_DL) + { + /*if direction is both then, re-establishment end indication + * should be sent only from the UL instance, only if DIR is + * DL only then DL instance will send indication.*/ + Bool sndReEst = TRUE; + if (entCfg->dir & KW_DIR_UL) + { + sndReEst = FALSE; + } + /* Re-establish the existing RB entity configuration */ + if (kwCfgReEstDlRb(tKwCb,cfg->ueId, cfg->cellId, + sndReEst,entCfg, entCfgCfm) != ROK) + { + RLOG_ARG1(L_ERROR,DBG_RBID,cfg->entCfg[idx].rbId,"Reest Failed due to[%d]", + entCfgCfm->status.reason); + } + } + break; + } + + case CKW_CFG_DELETE_UE: + { + /* Delete all RB entity configuration under UE */ + if (kwCfgDelDlUe(tKwCb,cfg->ueId, cfg->cellId, + entCfg, entCfgCfm) != ROK) + { + RLOG_ARG1(L_ERROR,DBG_UEID,cfg->ueId,"deletion Failed due to[%d]", + entCfgCfm->status.reason); + } + break; + } + case CKW_CFG_DELETE_CELL: + { + if (kwCfgDelDlCell(tKwCb,cfg->cellId,entCfg,entCfgCfm) + != ROK ) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cfg->cellId,"deletion Failed due to[%d]", + entCfgCfm->status.reason); + } + break; + } + + default: + { + KW_CFG_FILL_CFG_CFM(entCfgCfm, entCfg->rbId, entCfg->rbType,\ + CKW_CFG_CFM_NOK, CKW_CFG_REAS_INVALID_CFG); + RLOG0(L_ERROR, "Invalid CfgType"); + } + } + } + + /* Assign number of entity configuraitons and suId */ + cfgCfm->transId = cfg->transId; + cfgCfm->ueId = cfg->ueId; + cfgCfm->cellId = cfg->cellId; + cfgCfm->numEnt = cfg->numEnt; + + /* kw002.201 Freeing from proper region */ + /* KW_PST_FREE(pst->region, pst->pool, cfg, sizeof(CkwCfgInfo)); */ + /* Send Configuration confirm primitive */ + KwDlUdxCfgCfm(&(tKwCb->u.dlCb->udxDlSap[spId].pst), + tKwCb->u.dlCb->udxDlSap[spId].suId, + cfgCfm); + + RETVALUE(ROK); +} + +/** + *@brief + * This primitive is used by RRC to change the UeId for the existing UE + * context. + * + * @param pst - Pointer to the pst structure + * @param spId - The ID of the service provider SAP in the RLC layer + * @param transId - Transaction ID. This field uniquily identifies + * transaction between RRC and RLC + * @param ueInfo - Old UE Id Info for which the change request has come + * @param newUeInfo - New UE Id Info for existing UE context + * + * @return + * -# ROK + * -# RFAILED + */ +#ifdef ANSI +PUBLIC S16 KwDlUdxUeIdChgReq +( +Pst *pst, +SpId spId, +U32 transId, +CkwUeInfo *ueInfo, +CkwUeInfo *newUeInfo +) +#else +PUBLIC S16 KwDlUdxUeIdChgReq(pst,spId,transId,ueInfo,newUeInfo) +Pst *pst; +SpId spId; +U32 transId; +CkwUeInfo *ueInfo; +CkwUeInfo *newUeInfo; +#endif +{ + CmStatus status; + KwCb *tKwCb; + + TRC3(KwDlUdxUeIdChgReq) + +#if (ERRCLASS & ERRCLS_INT_PAR) + if (pst->dstInst >= KW_MAX_RLC_INSTANCES) + { + RETVALUE(RFAILED); + } +#endif + + tKwCb = KW_GET_KWCB(pst->dstInst); +#ifndef ALIGN_64BIT + KWDBGP_BRIEF(tKwCb, "(spId(%d), transId(%ld))\n", + spId, transId); +#else + KWDBGP_BRIEF(tKwCb, "(spId(%d), transId(%d))\n", + spId, transId); +#endif + + status.reason = CKW_CFG_REAS_NONE; + status.status = CKW_CFG_CFM_OK; + + if (kwCfgDlUeIdChng(tKwCb, ueInfo, newUeInfo, &status) != ROK) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,newUeInfo->cellId,"Failure due to[%d]", + status.reason); + } + KwDlUdxUeIdChgCfm(&(tKwCb->u.dlCb->udxDlSap[spId].pst), + tKwCb->u.dlCb->udxDlSap[spId].suId, + transId, + status); + + RETVALUE(ROK); +} + +/** +* @brief +* Request for status PDU from ULM to DLM. +* +* @param[in] pst - Post Structure +* @param[in] spId - Service Provider Id +* @param[in] rlcId - Rlc Information Id +* @param[in] pStaPdu - Status PDU +* +* @return S16 +* -# ROK +* -# RFAILED +**/ +#ifdef ANSI +PUBLIC S16 KwDlUdxStaPduReq +( +Pst *pst, +SpId spId, +CmLteRlcId *rlcId, +KwUdxDlStaPdu *pStaPdu +) +#else +PUBLIC S16 KwDlUdxStaPduReq(pst, spId, rlcId, pStaPdu) +Pst *pst; +SpId spId; +CmLteRlcId *rlcId; +KwUdxDlStaPdu *pStaPdu; +#endif +{ + KwDlRbCb *rbCb; + KwCb *tKwCb; + + tKwCb = KW_GET_KWCB (pst->dstInst); + + kwDbmFetchDlRbCbByRbId(tKwCb, rlcId, &rbCb); /* Fetch DBM RbCb */ + if (!rbCb) + { + RLOG_ARG2(L_ERROR, DBG_UEID,rlcId->ueId, "CellId [%u]:RbId[%d] not found", + rlcId->cellId,rlcId->rbId); + KW_FREE_SHRABL_BUF(pst->region, + pst->pool, + pStaPdu, + sizeof(KwUdxDlStaPdu)); + RETVALUE(RFAILED); + } + + AMDL.cntrlBo = pStaPdu->controlBo; + /* If there already exists a STAUS PDU, free it and take the new one + into account */ + if(AMDL.pStaPdu) + { + KW_FREE_SHRABL_BUF(pst->region, + pst->pool, + AMDL.pStaPdu, + sizeof(KwUdxDlStaPdu)); + } + + AMDL.pStaPdu = pStaPdu; + kwAmmSendDStaRsp(tKwCb, rbCb, &AMDL); + + RETVALUE (ROK); +} + +/** +* @brief +* It handles the status update recieved from ULM. +* +* @param[in] pst - Post Structure +* @param[in] spId - Service Provider Id +* @param[in] rlcId - Rlc Information Id +* @param[in] pStaPdu - Status PDU +* +* @return S16 +* -# ROK +* -# RFAILED +**/ +#ifdef ANSI +PUBLIC S16 KwDlUdxStaUpdReq +( +Pst* pst, +SpId spId, +CmLteRlcId *rlcId, +KwUdxStaPdu *pStaPdu +) +#else +PUBLIC S16 KwDlUdxStaUpdReq(pst, spId, rlcId,pStaPdu) +Pst* pst; +SpId spId; +CmLteRlcId *rlcId; +KwUdxStaPdu *pStaPdu; +#endif +{ + KwCb *tKwCb; + KwDlRbCb *rbCb; + + tKwCb = KW_GET_KWCB(pst->dstInst); + + kwDbmFetchDlRbCbByRbId(tKwCb, rlcId, &rbCb); + if (!rbCb) + { + RLOG_ARG2(L_ERROR, DBG_UEID,rlcId->ueId, "CellId [%u]:RbId[%d] not found", + rlcId->cellId,rlcId->rbId); + RETVALUE(RFAILED); + } + + kwAmmDlHndlStatusPdu(tKwCb, rbCb, pStaPdu); + + KW_FREE_SHRABL_BUF(pst->region, + pst->pool, + pStaPdu, + sizeof(KwUdxStaPdu)); + + RETVALUE(ROK); +} + +#ifdef LTE_L2_MEAS +/** +*/ +#ifdef ANSI +PUBLIC S16 KwDlUdxL2MeasReq +( +Pst *pst, +KwL2MeasReqEvt *measReqEvt +) +#else +PUBLIC S16 KwDlUdxL2MeasReq (pst, measReqEvt) +Pst *pst; +KwL2MeasReqEvt *measReqEvt; +#endif +{ + U32 cntr; + U8 measType; + VOLATILE U32 startTime = 0; + KwCb *tKwCb; + + TRC3(KwDlUdxL2MeasReq); + + /*starting Task*/ + SStartTask(&startTime, PID_RLC_MEAS_START); + + tKwCb = KW_GET_KWCB(pst->dstInst); + + /* Initialize measCfmEvt */ + + /* validate the received measReqEvt */ + /*LTE_L2_MEAS_PHASE2*/ + + measType = measReqEvt->measReq.measType; + + if(measType & LKW_L2MEAS_DL_IP) + { + /* if measurement is for DL IP enable for all QCI */ + for(cntr = 0; cntr < LKW_MAX_QCI; cntr++) + { + tKwCb->u.dlCb->kwL2Cb.measOn[cntr] |= LKW_L2MEAS_DL_IP; + } + } + else + { + /* for nonIpThroughput meas, enable only for the sent QCIs */ + U32 i; + for(i = 0; i < LKW_MAX_QCI; i++) + { + tKwCb->u.dlCb->kwL2Cb.measOn[i] |= measType; + } + } + + /* We need to copy the transId for sending back confirms later */ + for(cntr = 0; cntr < LKW_MAX_L2MEAS; cntr++) + { + KwL2MeasEvtCb* measEvtCb = &(tKwCb->u.dlCb->kwL2Cb.kwL2EvtCb[cntr]); + if(measEvtCb->measCb.measType & measType) + { + measEvtCb->transId= measReqEvt->transId; + } + } + + /*stopping Task*/ + SStopTask(startTime, PID_RLC_MEAS_START); + RETVALUE(ROK); +} /* KwDlUdxMeasReq */ + +/** +@brief +This function processes L2 Measurement stop request received from the layer manager. +After receving this request, RLC stops L2 Measurement + * @param[in] pst post structure + * @param[in] measType meas Type + * @return S16 + * -# Success : ROK + * -# Failure : RFAILED +*/ + +#ifdef ANSI +PUBLIC S16 KwDlUdxL2MeasStopReq +( +Pst *pst, +U8 measType +) +#else +PUBLIC S16 KwDlUdxL2MeasStopReq (pst, measType) +Pst *pst; +U8 measType; +#endif +{ + /* S16 ret = ROK;*/ + KwL2MeasEvtCb *measEvtCb = NULLP; + U16 cntr; + U8 status = ROK; +/* KwL2MeasCfmEvt measCfmEvt; */ + VOLATILE U32 startTime = 0; + KwCb *tKwCb=NULLP; + TRC3(KwDlUdxMeasStopReq); + + /*starting Task*/ + SStartTask(&startTime, PID_RLC_MEAS_STOP); + + tKwCb = KW_GET_KWCB(pst->dstInst); +/* cmMemset((U8*)&measCfmEvt, 0, sizeof(KwL2MeasCfmEvt)); */ + /* reset the counters for the measurement type passed */ + for(cntr = 0; cntr < LKW_MAX_L2MEAS; cntr++) + { + measEvtCb = &(tKwCb->u.dlCb->kwL2Cb.kwL2EvtCb[cntr]); + if(measEvtCb->measCb.measType & measType) + { + kwUtlResetDlL2MeasInKwRb(tKwCb, &measEvtCb->measCb, measType); + + } + } + + /* switch off the measurements for the type passed */ + for(cntr = 0; cntr < LKW_MAX_QCI; cntr++) + { + tKwCb->u.dlCb->kwL2Cb.measOn[cntr] &= ~measType; + } + + status = LCM_PRIM_OK; + /* Stop confirm is removed as UL thread is already sending it */ + + /*stopping Task*/ + SStopTask(startTime, PID_RLC_MEAS_STOP); + + RETVALUE(ROK); +} +/** +@brief +This function processes L2 Measurement Send request received from the layer manager. +After receving this request, RLC sends L2 Measurement + * @param[in] pst post structure + * @param[in] measType meas Type + * @return S16 + * -# Success : ROK + * -# Failure : RFAILED +*/ + +#ifdef ANSI +PUBLIC S16 KwDlUdxL2MeasSendReq +( +Pst *pst, +U8 measType +) +#else +PUBLIC S16 KwDlUdxL2MeasSendReq (pst, measType) +Pst *pst; +U8 measType; +#endif +{ + KwL2MeasEvtCb *measEvtCb; + U16 cntr; + + VOLATILE U32 startTime = 0; + KwCb *tKwCb; + TRC3(KwDlUdxMeasSendReq); + + tKwCb = KW_GET_KWCB(pst->dstInst); + for(cntr = 0; cntr < LKW_MAX_L2MEAS; cntr++) + { + measEvtCb = &(tKwCb->u.dlCb->kwL2Cb.kwL2EvtCb[cntr]); + if(measEvtCb->measCb.measType & measType) + { + /*starting Task*/ + SStartTask(&startTime, PID_RLC_MEAS_REPORT); + + kwUtlSndDlL2MeasCfm(tKwCb, measEvtCb); + + /*stopping Task*/ + SStopTask(startTime, PID_RLC_MEAS_REPORT); + } + } + + RETVALUE(ROK); +} +#endif /* LTE_L2_MEAS */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + + +/********************************************************************** + End of file +**********************************************************************/ diff --git a/src/5gnrrlc/kw_udx_ptdl.c b/src/5gnrrlc/kw_udx_ptdl.c new file mode 100755 index 000000000..bee2eacaa --- /dev/null +++ b/src/5gnrrlc/kw_udx_ptdl.c @@ -0,0 +1,479 @@ +/******************************************************************************* +################################################################################ +# Copyright (c) [2017-2019] [Radisys] # +# # +# 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. # +################################################################################ +*******************************************************************************/ + +/************************************************************************ + + Name: LTE-RLC ULDL Interface + + Type: C source file + + Desc: C source code for INF Interface Module + + File: kw_udx_ptdl.c + +**********************************************************************/ + +/** @file kw_udx_ptdl.c +*/ + +/* header include files (.h) */ +#include "envopt.h" /* environment options */ +#include "envdep.h" /* environment dependent */ +#include "envind.h" /* environment independent */ + +#include "gen.h" /* general */ +#include "ssi.h" /* system services */ +#include "cm5.h" /* common timer defines */ +#include "cm_tkns.h" /* common tokens defines */ +#include "cm_mblk.h" /* common memory allocation library defines */ +#include "cm_llist.h" /* common link list defines */ +#include "cm_hash.h" /* common hash list defines */ +#include "cm_lte.h" /* common LTE defines */ +#include "lkw.h" /* LKW defines */ +#include "ckw.h" /* CKW defines */ +#include "kwu.h" /* KWU defines */ +#include "rgu.h" /* RGU defines */ +#include "kw_err.h" /* Err defines */ +#include "kw_env.h" /* RLC environment options */ + +#include "kw.h" /* RLC defines */ +#include "kw_udx.h" +#include "kw_dl.h" + + +/* extern (.x) include files */ +#include "gen.x" /* general */ +#include "ssi.x" /* system services */ + +#include "cm5.x" /* common timer library */ +#include "cm_tkns.x" /* common tokens */ +#include "cm_mblk.x" /* common memory allocation */ +#include "cm_llist.x" /* common link list */ +#include "cm_hash.x" /* common hash list */ +#include "cm_lte.x" /* common LTE includes */ +#include "cm_lib.x" /* common memory allocation library */ +#include "lkw.x" /* LKW */ +#include "ckw.x" /* CKW */ +#include "kwu.x" /* KWU */ +#include "rgu.x" /* RGU */ + +#include "kw.x" +#include "kw_udx.x" +#include "kw_dl.x" + + +#define UDX_MAX_SEL 3 + +#ifndef LCKWULUDX +PRIVATE S16 PtDlUdxBndCfm ARGS(( Pst *pst,SuId suId,U8 status )); +PRIVATE S16 PtDlUdxCfgCfm ARGS((Pst *pst, SuId suId, CkwCfgCfmInfo *cfmInfo)); +PRIVATE S16 PtDlUdxUeIdChgCfm ARGS(( Pst *pst, SuId suId,U32 transId, + CmStatus status)); +PRIVATE S16 PtDlUdxStaUpdCfm ARGS(( Pst* pst,SuId suId,CmLteRlcId *rlcId, + KwUdxBufLst *pBufLst)); + +/* UDX Bind Confirm primitive */ +/** + * + * @brief + * + * Handler for confirming the bind request received from KWU + * interface. + * + * @b Description: + * + * This function send the bind confirm primitive to the RLC user, + * when it receives a bind request from its service user. + * + * @param[in] pst Post structure + * @param[in] suId Service user SAP ID + * @param[in] status Status of Confirmation + * + * @return S16 + * -# ROK + * + */ +#ifdef ANSI +PRIVATE S16 PtDlUdxBndCfm +( +Pst *pst, /* post structure */ +SuId suId, /* Service User Id */ +U8 status /* Status */ +) +#else +PRIVATE S16 PtDlUdxBndCfm(pst, suId, status) +Pst *pst; /* post structure */ +SuId suId; /* Service User Id */ +U8 status; /* Status */ +#endif +{ + TRC3(PtDlUdxBndCfm) + + RETVALUE(ROK); + +} /* end of KwDlUdxBndCfm */ + + + +/** + * + * @brief + * + * Handler for confirming the bind request received from KWU + * interface. + * + * @b Description: + * + * This function send the bind confirm primitive to the RLC user, + * when it receives a bind request from its service user. + * + * @param[in] pst Post structure + * @param[in] suId Service user SAP ID + * @param[in] status Status of Confirmation + * + * @return S16 + * -# ROK + * + */ +#ifdef ANSI +PRIVATE S16 PtDlUdxCfgCfm +( +Pst *pst, /* post structure */ +SuId suId, /* Service User Id */ +CkwCfgCfmInfo *cfmInfo /* Status */ +) +#else +PRIVATE S16 PtDlUdxCfgCfm(pst, suId, status) +Pst *pst; /* post structure */ +SuId suId; /* Service User Id */ +CkwCfgCfmInfo *cfmInfo; /* Status */ +#endif +{ + TRC3(PtDlUdxCfgCfm) + + RETVALUE(ROK); + +} /* end of KwDlUdxBndCfm */ + +/** + * + * @brief + * + * Handler for confirming the bind request received from KWU + * interface. + * + * @b Description: + * + * This function send the bind confirm primitive to the RLC user, + * when it receives a bind request from its service user. + * + * @param[in] pst Post structure + * @param[in] suId Service user SAP ID + * @param[in] status Status of Confirmation + * + * @return S16 + * -# ROK + * + */ +#ifdef ANSI +PRIVATE S16 PtDlUdxUeIdChgCfm +( +Pst *pst, /* post structure */ +SuId suId, /* Service User Id */ +U32 transId, +CmStatus status +) +#else +PRIVATE S16 PtDlUdxUeIdChgCfm(pst, suId, status) +Pst *pst; /* post structure */ +SuId suId; /* Service User Id */ +U32 transId; +CmStatus status; +#endif +{ + TRC3(PtDlUdxUeIdChgCfm) + + RETVALUE(ROK); + +} /* end of KwDlUdxBndCfm */ + + + +PRIVATE S16 PtDlUdxStaUpdCfm +( +Pst* pst, +SuId suId, +CmLteRlcId *rlcId, +KwUdxBufLst *pBufLst +) +{ + TRC3(PtDlUdxStaUpdCfm); + RETVALUE(ROK); +} + +PRIVATE S16 PtDlUdxStaProhTmrStart +( +Pst* pst, +SuId suId, +CmLteRlcId *rlcId +) +{ + TRC3(PtDlUdxStaProhTmrStart); + RETVALUE(ROK); +} +#endif + +PRIVATE UdxBndCfm kwDlUdxBndCfmMt[UDX_MAX_SEL] = +{ +#ifdef LCKWULUDX + cmPkUdxBndCfm, /* 0 - loosely coupled */ +#else + PtDlUdxBndCfm, /* 0 - loosely coupled, portable */ +#endif /* LCKWUIKWU */ +#ifdef LWLCKWULUDX + cmPkUdxBndCfm, /* 1 - loosely coupled */ +#else + PtDlUdxBndCfm, /* 1 - loosely coupled, portable */ +#endif /* LCKWUIKWU */ +#ifdef KW + KwUlUdxBndCfm, /* 2 - tightly coupled, RRC */ +#else + PtDlUdxBndCfm, /* 2 - tightly coupled, portable */ +#endif /* KW */ +}; + +PUBLIC UdxCfgCfm kwDlUdxCfgCfmMt[UDX_MAX_SEL] = +{ +#ifdef LCKWULUDX + cmPkUdxCfgCfm, /* 0 - loosely coupled */ +#else + PtDlUdxCfgCfm, /* 0 - loosely coupled, portable */ +#endif /* LCKWUIKWU */ +#ifdef LWLCKWULUDX + cmPkUdxCfgCfm, /* 1 - loosely coupled */ +#else + PtDlUdxCfgCfm, /* 1 - loosely coupled, portable */ +#endif /* LCKWUIKWU */ +#ifdef KW + KwUlUdxCfgCfm, /* 2 - tightly coupled, RRC */ +#else + PtDlUdxCfgCfm, /* 2 - tightly coupled, portable */ +#endif /* KW */ +}; + +PUBLIC UdxUeIdChgCfm kwDlUdxUeIdChgCfmMt[UDX_MAX_SEL] = +{ +#ifdef LCKWULUDX + cmPkUdxUeIdChgCfm, /* 0 - loosely coupled */ +#else + PtDlUdxUeIdChgCfm, /* 0 - loosely coupled, portable */ +#endif /* LCKWUIKWU */ +#ifdef LWLCKWULUDX + cmPkUdxUeIdChgCfm, /* 1 - loosely coupled */ +#else + PtDlUdxUeIdChgCfm, /* 1 - loosely coupled, portable */ +#endif /* LCKWUIKWU */ +#ifdef KW + KwUlUdxUeIdChgCfm, /* 2 - tightly coupled, RRC */ +#else + PtDlUdxUeIdChgCfm, /* 2 - tightly coupled, portable */ +#endif /* KW */ +}; + + +PRIVATE CONSTANT UdxStaProhTmrStart KwDlUdxStaProhTmrStartMt[UDX_MAX_SEL] = +{ +#ifdef LCKWULUDX + cmPkUdxStaProhTmrStart, +#else + PtDlUdxStaProhTmrStart, +#endif +#ifdef LWLCKWULUDX + cmPkUdxStaProhTmrStart, /* 1 - loosely coupled */ +#else + PtDlUdxStaProhTmrStart, /* 1 - loosely coupled, portable */ +#endif /* LCKWUIKWU */ +#ifdef KW + KwUlUdxStaProhTmrStart, /* 2 - tightly coupled, RRC */ +#else + PtDlUdxStaProhTmrStart, /* 2 - tightly coupled, portable */ +#endif /* KW */ +}; + +/** + * + * @brief + * + * Handler for confirming the bind request received from KWU + * interface. + * + * @b Description: + * + * This function send the bind confirm primitive to the RLC user, + * when it receives a bind request from its service user. + * + * @param[in] pst Post structure + * @param[in] suId Service user SAP ID + * @param[in] status Status of Confirmation + * + * @return S16 + * -# ROK + * + */ +#ifdef ANSI +PUBLIC S16 KwDlUdxBndCfm +( +Pst *pst, /* post structure */ +SuId suId, /* Service User Id */ +U8 status /* Status */ +) +#else +PUBLIC S16 KwDlUdxBndCfm(pst, suId, status) +Pst *pst; /* post structure */ +SuId suId; /* Service User Id */ +U8 status; /* Status */ +#endif +{ + TRC3(KwDlUdxBndCfm) + + /* jump to specific primitive depending on configured selector */ + (*kwDlUdxBndCfmMt[pst->selector])(pst, suId, status); + + RETVALUE(ROK); + +} /* end of KwDlUdxBndCfm */ + + + +/** + * + * @brief + * + * Handler for confirming the bind request received from KWU + * interface. + * + * @b Description: + * + * This function send the bind confirm primitive to the RLC user, + * when it receives a bind request from its service user. + * + * @param[in] pst Post structure + * @param[in] suId Service user SAP ID + * @param[in] status Status of Confirmation + * + * @return S16 + * -# ROK + * + */ +#ifdef ANSI +PUBLIC S16 KwDlUdxCfgCfm +( +Pst *pst, /* post structure */ +SuId suId, /* Service User Id */ +CkwCfgCfmInfo *cfmInfo /* Status */ +) +#else +PUBLIC S16 KwDlUdxCfgCfm(pst, suId, status) +Pst *pst; /* post structure */ +SuId suId; /* Service User Id */ +CkwCfgCfmInfo *cfmInfo; /* Status */ +#endif +{ + TRC3(KwDlUdxCfgCfm) + + /* jump to specific primitive depending on configured selector */ + (*kwDlUdxCfgCfmMt[pst->selector])(pst, suId, cfmInfo); + + RETVALUE(ROK); + +} /* end of KwDlUdxBndCfm */ + +/** + * + * @brief + * + * Handler for confirming the bind request received from KWU + * interface. + * + * @b Description: + * + * This function send the bind confirm primitive to the RLC user, + * when it receives a bind request from its service user. + * + * @param[in] pst Post structure + * @param[in] suId Service user SAP ID + * @param[in] status Status of Confirmation + * + * @return S16 + * -# ROK + * + */ +#ifdef ANSI +PUBLIC S16 KwDlUdxUeIdChgCfm +( +Pst *pst, /* post structure */ +SuId suId, /* Service User Id */ +U32 transId, +CmStatus status +) +#else +PUBLIC S16 KwDlUdxUeIdChgCfm(pst, suId, status) +Pst *pst; /* post structure */ +SuId suId; /* Service User Id */ +U32 transId; +CmStatus status; +#endif +{ + TRC3(KwDlUdxUeIdChgCfm) + + /* jump to specific primitive depending on configured selector */ + (*kwDlUdxUeIdChgCfmMt[pst->selector])(pst, suId,transId,status); + + RETVALUE(ROK); + +} /* end of KwDlUdxBndCfm */ + + + +#ifdef ANSI +PUBLIC S16 KwDlUdxStaProhTmrStart +( +Pst *pst, /* post structure */ +SuId suId, /* Service User Id */ +CmLteRlcId *rlcId +) +#else +PUBLIC S16 KwDlUdxStaProhTmrStart(pst, suId, rlcId) +Pst *pst; /* post structure */ +SuId suId; /* Service User Id */ +CmLteRlcId *rlcId; +#endif +{ + TRC3(KwDlUdxStaProhTmrStart) + + /* jump to specific primitive depending on configured selector */ + (*KwDlUdxStaProhTmrStartMt[pst->selector])(pst, suId, rlcId); + + RETVALUE(ROK); + +} /* end of KwDlUdxBndCfm */ + +/********************************************************************** + + End of file +**********************************************************************/ diff --git a/src/5gnrrlc/kw_udx_ptul.c b/src/5gnrrlc/kw_udx_ptul.c new file mode 100755 index 000000000..42f0453c3 --- /dev/null +++ b/src/5gnrrlc/kw_udx_ptul.c @@ -0,0 +1,787 @@ +/******************************************************************************* +################################################################################ +# Copyright (c) [2017-2019] [Radisys] # +# # +# 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. # +################################################################################ +*******************************************************************************/ + +/************************************************************************ + + Name: LTE-RLC ULDL Interface + + Type: C source file + + Desc: C source code for INF Interface Module + + File: kw_udx_ptul.c + +**********************************************************************/ + +/** @file kw_udx_ptul.c +*/ + +/* header include files (.h) */ +#include "envopt.h" /* environment options */ +#include "envdep.h" /* environment dependent */ +#include "envind.h" /* environment independent */ + +#include "gen.h" /* general */ +#include "ssi.h" /* system services */ +#include "cm5.h" /* common timer defines */ +#include "cm_tkns.h" /* common tokens defines */ +#include "cm_mblk.h" /* common memory allocation library defines */ +#include "cm_llist.h" /* common link list defines */ +#include "cm_hash.h" /* common hash list defines */ +#include "cm_lte.h" /* common LTE defines */ +#include "lkw.h" /* LKW defines */ +#include "ckw.h" /* CKW defines */ +#include "kwu.h" /* KWU defines */ +#include "rgu.h" /* RGU defines */ +#include "kw_err.h" /* Err defines */ +#include "kw_env.h" /* RLC environment options */ + +#include "kw.h" /* RLC defines */ +#include "kw_udx.h" +#include "kw_dl.h" + +/* extern (.x) include files */ +#include "gen.x" /* general */ +#include "ssi.x" /* system services */ + +#include "cm5.x" /* common timer library */ +#include "cm_tkns.x" /* common tokens */ +#include "cm_mblk.x" /* common memory allocation */ +#include "cm_llist.x" /* common link list */ +#include "cm_hash.x" /* common hash list */ +#include "cm_lte.x" /* common LTE includes */ +#include "cm_lib.x" /* common memory allocation library */ +#include "lkw.x" /* LKW */ +#include "ckw.x" /* CKW */ +#include "kwu.x" /* KWU */ +#include "rgu.x" /* RGU */ + +#include "kw.x" +#include "kw_udx.x" +#include "kw_dl.x" + + +#ifndef LCKWULUDX +PRIVATE S16 PtUlUdxBndReq ARGS((Pst* pst, SuId suId,SpId spId )); +PRIVATE S16 PtUlUdxUbndReq ARGS((Pst* pst, SuId suId,Reason reason)); +PRIVATE S16 PtUlUdxCfgReq ARGS((Pst *pst, SpId spId, CkwCfgInfo *cfgInfo)); +PRIVATE S16 PtUlUdxStaUpdReq ARGS((Pst* pst,SpId spId,CmLteRlcId *rlcId, + KwUdxStaPdu *pStaPdu )); +PRIVATE S16 PtUlUdxUeIdChgReq ARGS((Pst *pst, SpId spId, U32 transId, + CkwUeInfo *ueInfo, CkwUeInfo *newUeInfo)); +PRIVATE S16 PtUlUdxStaPduReq ARGS(( Pst* pst,SpId spId, CmLteRlcId *rlcId, + KwUdxDlStaPdu *pStaPdu )); +#ifdef ANSI +PRIVATE S16 PtUlUdxBndReq +( +Pst *pst, /* post structure */ +SuId suId, /* Service User Id */ +SpId spId /* Status */ +) +#else +PRIVATE S16 PtUlUdxBndReq(pst, suId,spId) +Pst *pst; /* post structure */ +SuId suId; /* Service User Id */ +SpId spId; /* Status */ +#endif +{ + TRC3(PtUlUdxBndReq) + + RETVALUE(ROK); + +} /* end of KwDlUdxBndReq */ + +/** + * + * @brief + * + * Handler for confirming the bind request received from KWU + * interface. + * + * @b Description: + * + * This function send the bind confirm primitive to the RLC user, + * when it receives a bind request from its service user. + * + * @param[in] pst Post structure + * @param[in] suId Service user SAP ID + * @param[in] status Status of Confirmation + * + * @return S16 + * -# ROK + * + */ +#ifdef ANSI +PRIVATE S16 PtUlUdxUbndReq +( +Pst *pst, /* post structure */ +SpId spId, /* Service User Id */ +Reason reason /* Status */ +) +#else +PRIVATE S16 PtUlUdxUbndReq(pst, suId, status) +Pst *pst; /* post structure */ +SpId spId; /* Service User Id */ +Reason Reason; /* Status */ +#endif +{ + TRC3(PtUlUdxUbndReq) + + RETVALUE(ROK); + +} /* end of PtDlUdxBndReq */ + +#ifdef ANSI +PRIVATE S16 PtUlUdxCfgReq +( +Pst *pst, /* post structure */ +SpId spId, /* Service User Id */ +CkwCfgInfo *cfmInfo /* Config Info */ +) +#else +PRIVATE S16 PtUlUdxCfgReq(pst, spId, status) +Pst *pst; /* post structure */ +SpId spId; /* Service User Id */ +CkwCfgInfo *cfmInfo; /* Config Info */ +#endif +{ + TRC3(PtUlUdxCfgReq) + + RETVALUE(ROK); + +} /* end of KwDlUdxCfgReq */ + +#ifdef ANSI +PRIVATE S16 PtUlUdxUeIdChgReq +( +Pst *pst, /* post structure */ +SpId spId, /* Service User Id */ +U32 transId, /* transaction Id */ +CkwUeInfo *ueInfo, /* Config Info */ +CkwUeInfo *newUeInfo /* Config Info */ +) +#else +PRIVATE S16 PtUlUdxUeIdChgReq(pst, spId,transId, ueInfo, newUeInfo) +Pst *pst; /* post structure */ +SpId spId; /* Service User Id */ +U32 transId; /* transaction Id */ +CkwUeInfo *ueInfo; /* Config Info */ +CkwUeInfo *newUeInfo; /* Config Info */ +#endif +{ + TRC3(PtUlUdxUeIdChgReq) + + + RETVALUE(ROK); + +} /* end of KwDlUdxCfgReq */ + + +PRIVATE S16 PtUlUdxStaPduReq +( +Pst* pst, +SpId spId, +CmLteRlcId *rlcId, +KwUdxDlStaPdu *pStaPdu +) +{ + TRC3(PtUlUdxStaPduReq); + + RETVALUE(ROK); +} + +/** +* @brief Request from ULM to DLM for UE Status +* +* @details +* +* Function : KwUdxUdxStatUpd +* +* @param[in] Pst* pst + +* @return S16 +* -# ROK +**/ +#ifdef ANSI +PRIVATE S16 PtUlUdxStaUpdReq +( +Pst* pst, +SpId spId, +CmLteRlcId *rlcId, +KwUdxStaPdu *pStaPdu +) +#else +PRIVATE S16 PtUlUdxStaUpdReq(pst, rlcId, pStaPdu) +Pst* pst; +SpId spId; +CmLteRlcId *rlcId; +KwUdxDlStaPdu *pStaPdu; +#endif +{ + + TRC3(PtUlUdxStaUpdReq); + + RETVALUE(ROK); +} /* end of KwUlmDlmStaUpd*/ + +#ifdef LTE_L2_MEAS +/** +* @brief Request from ULM to DLM for Measurement +* +* @details +* +* Function : KwUdxUdxL2MeasReq +* +* @param[in] Pst* pst + +* @return S16 +* -# ROK +**/ +#ifdef ANSI +PRIVATE S16 PtUlUdxL2MeasReq +( +Pst* pst, +KwL2MeasReqEvt *measReqEvt +) +#else +PRIVATE S16 PtUlUdxL2MeasReq(pst, measReqEvt ) +Pst* pst; +KwL2MeasReqEvt *measReqEvt; +#endif +{ + + TRC3(PtUlUdxL2MeasReq); + + RETVALUE(ROK); +} + +/** +* @brief Request from ULM to DLM for Measurement +* +* @details +* +* Function : KwUdxUdxL2MeasSendReq +* +* @param[in] Pst* pst + +* @return S16 +* -# ROK +**/ +#ifdef ANSI +PRIVATE S16 PtUlUdxL2MeasSendReq +( +Pst* pst, +U8 status +) +#else +PRIVATE S16 PtUlUdxL2MeasSendReq(pst, status ) +Pst* pst; +U8 status +#endif +{ + + TRC3(PtUlUdxL2MeasSendReq); + + RETVALUE(ROK); +} + +/** +* @brief Request from ULM to DLM for Measurement +* +* @details +* +* Function : KwUdxUdxL2MeasStopReq +* +* @param[in] Pst* pst + +* @return S16 +* -# ROK +**/ +#ifdef ANSI +PRIVATE S16 PtUlUdxL2MeasStopReq +( +Pst* pst, +U8 status +) +#else +PRIVATE S16 PtUlUdxL2MeasStopReq(pst, status ) +Pst* pst; +U8 status +#endif +{ + + TRC3(PtUlUdxL2MeasStopReq); + + RETVALUE(ROK); +} +#endif +#endif + +PRIVATE UdxBndReq kwUlUdxBndReqMt[] = +{ +#ifdef LCKWULUDX + cmPkUdxBndReq, /* 0 - loosely coupled */ +#else + PtUlUdxBndReq, /* 0 - loosely coupled, portable */ +#endif /* LCKWUIKWU */ +#ifdef LWLCKWULUDX + cmPkUdxBndReq, /* 1 - loosely coupled */ +#else + PtUlUdxBndReq, /* 1 - loosely coupled, portable */ +#endif /* LCKWUIKWU */ +#ifdef KW + KwDlUdxBndReq, /* 2 - tightly coupled, RRC */ +#else + PtUlUdxBndReq, /* 2 - tightly coupled, portable */ +#endif /* KW */ +}; + +PRIVATE UdxUbndReq kwUlUdxUbndReqMt[] = +{ +#ifdef LCKWULUDX + cmPkUdxUbndReq, /* 0 - loosely coupled */ +#else + PtUlUdxUbndReq, /* 0 - loosely coupled, portable */ +#endif /* LCKWUIKWU */ +#ifdef LWLCKWULUDX + cmPkUdxUbndReq, /* 1 - loosely coupled */ +#else + PtUlUdxUbndReq, /* 1 - loosely coupled, portable */ +#endif /* LCKWUIKWU */ +#ifdef KW + KwDlUdxUbndReq, /* 2 - tightly coupled, RRC */ +#else + PtUlUdxUbndReq, /* 2 - tightly coupled, portable */ +#endif /* KW */ +}; + + +PRIVATE UdxCfgReq kwUlUdxCfgReqMt[] = +{ +#ifdef LCKWULUDX + cmPkUdxCfgReq, /* 0 - loosely coupled */ +#else + PtUlUdxCfgReq, /* 0 - loosely coupled, portable */ +#endif /* LCKWUIKWU */ +#ifdef LWLCKWULUDX + cmPkUdxCfgReq, /* 1 - loosely coupled */ +#else + PtUlUdxCfgReq, /* 1 - loosely coupled, portable */ +#endif /* LCKWUIKWU */ +#ifdef KW + KwDlUdxCfgReq, /* 2 - tightly coupled, RRC */ +#else + PtUlUdxCfgReq, /* 2 - tightly coupled, portable */ +#endif /* KW */ +}; + +PRIVATE UdxUeIdChgReq kwUlUdxUeIdChgReqMt[] = +{ +#ifdef LCKWULUDX + cmPkUdxUeIdChgReq, /* 0 - loosely coupled */ +#else + PtUlUdxUeIdChgReq, /* 0 - loosely coupled, portable */ +#endif /* LCKWUIKWU */ +#ifdef LWLCKWULUDX + cmPkUdxUeIdChgReq, /* 1 - loosely coupled */ +#else + PtUlUdxUeIdChgReq, /* 1 - loosely coupled, portable */ +#endif /* LCKWUIKWU */ +#ifdef KW + KwDlUdxUeIdChgReq, /* 2 - tightly coupled, RRC */ +#else + PtUlUdxUeIdChgReq, /* 2 - tightly coupled, portable */ +#endif /* KW */ +}; + + +PRIVATE CONSTANT UdxStaUpdReq kwUlUdxStaUpdReqMt[KW_MAX_UDX] = +{ +#ifdef LCKWULUDX + cmPkUdxStaUpdReq, /* 0 - loosely coupled */ +#else + PtUlUdxStaUpdReq, /* 0 - loosely coupled, portable */ +#endif /* LCKWUIKWU */ +#ifdef LWLCKWULUDX + cmPkUdxStaUpdReq, /* 1 - loosely coupled */ +#else + PtUlUdxStaUpdReq, /* 1 - loosely coupled, portable */ +#endif /* LCKWUIKWU */ +#ifdef KW + KwDlUdxStaUpdReq, /* 2 - tightly coupled, RRC */ +#else + PtUlUdxStaUpdReq, /* 2 - tightly coupled, portable */ +#endif /* KW */ +}; + +PRIVATE CONSTANT UdxStaPduReq kwUlUdxStaPduReqMt[KW_MAX_UDX] = +{ +#ifdef LCKWULUDX + cmPkUdxStaPduReq, /* 0 - loosely coupled */ +#else + PtUlUdxStaPduReq, /* 0 - loosely coupled, portable */ +#endif /* LCKWUIKWU */ +#ifdef LWLCKWULUDX + cmPkUdxStaPduReq, /* 1 - loosely coupled */ +#else + PtUlUdxStaPduReq, /* 1 - loosely coupled, portable */ +#endif /* LCKWUIKWU */ +#ifdef KW + KwDlUdxStaPduReq, /* 2 - tightly coupled, RRC */ +#else + PtUlUdxStaPduReq, /* 2 - tightly coupled, portable */ +#endif /* KW */ +}; +#ifdef LTE_L2_MEAS +PRIVATE CONSTANT UdxL2MeasReq kwUlUdxL2MeasReqMt[KW_MAX_UDX] = +{ +#ifdef LCKWULUDX + cmPkUdxL2MeasReq, /* 0 - loosely coupled */ +#else + PtUlUdxL2MeasReq, /* 0 - loosely coupled, portable */ +#endif /* LCKWUIKWU */ +#ifdef LWLCKWULUDX + cmPkUdxL2MeasReq, /* 1 - loosely coupled */ +#else + PtUlUdxL2MeasReq, /* 1 - loosely coupled, portable */ +#endif /* LCKWUIKWU */ +#ifdef KW + KwDlUdxL2MeasReq, /* 2 - tightly coupled, RRC */ +#else + PtUlUdxL2MeasReq, /* 2 - tightly coupled, portable */ +#endif /* KW */ +}; + +PRIVATE CONSTANT UdxL2MeasSendReq kwUlUdxL2MeasSendReqMt[KW_MAX_UDX] = +{ +#ifdef LCKWULUDX + cmPkUdxL2MeasSendReq, /* 0 - loosely coupled */ +#else + PtUlUdxL2MeasSendReq, /* 0 - loosely coupled, portable */ +#endif /* LCKWUIKWU */ +#ifdef LWLCKWULUDX + cmPkUdxL2MeasSendReq, /* 1 - loosely coupled */ +#else + PtUlUdxL2MeasSendReq, /* 1 - loosely coupled, portable */ +#endif /* LCKWUIKWU */ +#ifdef KW + KwDlUdxL2MeasSendReq, /* 2 - tightly coupled, RRC */ +#else + PtUlUdxL2MeasSendReq, /* 2 - tightly coupled, portable */ +#endif /* KW */ +}; + +PRIVATE CONSTANT UdxL2MeasStopReq kwUlUdxL2MeasStopReqMt[KW_MAX_UDX] = +{ +#ifdef LCKWULUDX + cmPkUdxL2MeasStopReq, /* 0 - loosely coupled */ +#else + PtUlUdxL2MeasStopReq, /* 0 - loosely coupled, portable */ +#endif /* LCKWUIKWU */ +#ifdef LWLCKWULUDX + cmPkUdxL2MeasStopReq, /* 1 - loosely coupled */ +#else + PtUlUdxL2MeasStopReq, /* 1 - loosely coupled, portable */ +#endif /* LCKWUIKWU */ +#ifdef KW + KwDlUdxL2MeasStopReq, /* 2 - tightly coupled, RRC */ +#else + PtUlUdxL2MeasStopReq, /* 2 - tightly coupled, portable */ +#endif /* KW */ +}; +#endif +/** + * + * @brief + * + * Handler for confirming the bind request received from KWU + * interface. + * + * @b Description: + * + * This function send the bind confirm primitive to the RLC user, + * when it receives a bind request from its service user. + * + * @param[in] pst Post structure + * @param[in] suId Service user SAP ID + * @param[in] status Status of Confirmation + * + * @return S16 + * -# ROK + * + */ +#ifdef ANSI +PUBLIC S16 KwUlUdxBndReq +( +Pst *pst, /* post structure */ +SuId suId, /* Service User Id */ +SpId spId /* Status */ +) +#else +PUBLIC S16 KwUlUdxBndReq(pst, suId, status) +Pst *pst; /* post structure */ +SuId suId; /* Service User Id */ +SpId spId; /* Status */ +#endif +{ + TRC3(KwUlUdxBndReq) + + /* jump to specific primitive depending on configured selector */ + (*kwUlUdxBndReqMt[pst->selector])(pst, suId, spId); + + RETVALUE(ROK); + +} /* end of KwDlUdxBndReq */ + +/** + * + * @brief + * + * Handler for confirming the bind request received from KWU + * interface. + * + * @b Description: + * + * This function send the bind confirm primitive to the RLC user, + * when it receives a bind request from its service user. + * + * @param[in] pst Post structure + * @param[in] suId Service user SAP ID + * @param[in] status Status of Confirmation + * + * @return S16 + * -# ROK + * + */ +#ifdef ANSI +PUBLIC S16 KwUlUdxUbndReq +( +Pst *pst, /* post structure */ +SpId spId, /* Service User Id */ +Reason reason /* Status */ +) +#else +PUBLIC S16 KwUlUdxUbndReq(pst, suId, status) +Pst *pst; /* post structure */ +SpId spId; /* Service User Id */ +Reason Reason; /* Status */ +#endif +{ + TRC3(KwUlUdxUbndReq) + + /* jump to specific primitive depending on configured selector */ + (*kwUlUdxUbndReqMt[pst->selector])(pst, spId,reason ); + + RETVALUE(ROK); + +} /* end of KwDlUdxBndReq */ + +#ifdef ANSI +PUBLIC S16 KwUlUdxCfgReq +( +Pst *pst, /* post structure */ +SpId spId, /* Service User Id */ +CkwCfgInfo *cfmInfo /* Config Info */ +) +#else +PUBLIC S16 KwUlUdxCfgReq(pst, suId, status) +Pst *pst; /* post structure */ +SuId spId; /* Service User Id */ +CkwCfgInfo *cfmInfo; /* Config Info */ +#endif +{ + TRC3(KwUlUdxCfgReq) + + /* jump to specific primitive depending on configured selector */ + (*kwUlUdxCfgReqMt[pst->selector])(pst, spId, cfmInfo); + + RETVALUE(ROK); + +} /* end of KwDlUdxCfgReq */ + +#ifdef ANSI +PUBLIC S16 KwUlUdxUeIdChgReq +( +Pst *pst, /* post structure */ +SpId spId, /* Service User Id */ +U32 transId, /* transaction Id */ +CkwUeInfo *ueInfo, /* Config Info */ +CkwUeInfo *newUeInfo /* Config Info */ +) +#else +PUBLIC S16 KwUlUdxUeIdChgReq(pst, spId,transId, ueInfo, newUeInfo) +Pst *pst; /* post structure */ +SpId spId; /* Service User Id */ +U32 transId; /* transaction Id */ +CkwUeInfo *ueInfo; /* Config Info */ +CkwUeInfo *newUeInfo; /* Config Info */ +#endif +{ + TRC3(KwUlUdxUeIdChgReq) + + /* jump to specific primitive depending on configured selector */ + (*kwUlUdxUeIdChgReqMt[pst->selector])(pst, spId,transId,ueInfo,newUeInfo); + + RETVALUE(ROK); + +} /* end of KwDlUdxCfgReq */ + + + +PUBLIC S16 KwUlUdxStaPduReq +( +Pst* pst, +SpId spId, +CmLteRlcId *rlcId, +KwUdxDlStaPdu *pStaPdu +) +{ + TRC3(KwUlUdxStaPduReq); + + RETVALUE((*kwUlUdxStaPduReqMt[pst->selector])(pst,spId, rlcId, pStaPdu)); +} + +/** +* @brief Request from ULM to DLM for UE Status +* +* @details +* +* Function : KwUdxUdxStatUpd +* +* @param[in] Pst* pst + +* @return S16 +* -# ROK +**/ +#ifdef ANSI +PUBLIC S16 KwUlUdxStaUpdReq +( +Pst* pst, +SpId spId, +CmLteRlcId *rlcId, +KwUdxStaPdu *pStaPdu +) +#else +PUBLIC S16 KwUlUdxStaUpdReq(pst, rlcId, pStaPdu) +Pst* pst; +SpId spId; +CmLteRlcId *rlcId; +KwUdxStaPdu *pStaPdu; +#endif +{ + + TRC3(KwUlUdxStaUpdReq); + + RETVALUE((*kwUlUdxStaUpdReqMt[pst->selector])(pst,spId, rlcId, pStaPdu)); +} /* end of KwUlmDlmStaUpd*/ + +#ifdef LTE_L2_MEAS +/** +* @brief Request from ULM to DLM for MeasReq +* +* @details +* +* Function : KwUlUdxL2MeasReq +* +* @param[in] Pst* pst + +* @return S16 +* -# ROK +**/ +#ifdef ANSI +PUBLIC S16 KwUlUdxL2MeasReq +( +Pst* pst, +KwL2MeasReqEvt *measReqEvt +) +#else +PUBLIC S16 KwUlUdxL2MeasReq(pst,measReqEvt) +Pst* pst; +KwL2MeasReqEvt *measReqEvt; +#endif +{ + + TRC3(KwUlUdxStaUpdReq); + + RETVALUE((*kwUlUdxL2MeasReqMt[pst->selector])(pst,measReqEvt)); +} /* end of KwUlUdxL2MeasReq*/ + +/** +* @brief Request from ULM to DLM for MeasSendReq +* +* @details +* +* Function : KwUlUdxMeasSendReq +* +* @param[in] Pst* pst + +* @return S16 +* -# ROK +**/ +#ifdef ANSI +PUBLIC S16 KwUlUdxL2MeasSendReq +( +Pst* pst, +U8 measType +) +#else +PUBLIC S16 KwUlUdxL2MeasSendReq(pst,measReqEvt) +Pst* pst; +U8 measType; +#endif +{ + + TRC3(KwUlUdxStaUpdReq); + + RETVALUE((*kwUlUdxL2MeasSendReqMt[pst->selector])(pst,measType)); +} /* end of KwUlUdxMesReq*/ + +/** +* @brief Request from ULM to DLM for MeasStopReq +* +* @details +* +* Function : KwUlUdxL2MeasStopReq +* +* @param[in] Pst* pst + +* @return S16 +* -# ROK +**/ +#ifdef ANSI +PUBLIC S16 KwUlUdxL2MeasStopReq +( +Pst* pst, +U8 measType +) +#else +PUBLIC S16 KwUlUdxL2MeasStopReq(pst,measReqEvt) +Pst* pst; +U8 measType; +#endif +{ + + TRC3(KwUlUdxStaUpdReq); + + RETVALUE((*kwUlUdxL2MeasStopReqMt[pst->selector])(pst,measType)); +} /* end of KwUlUdxMesReq*/ +#endif +/********************************************************************** + + End of file +**********************************************************************/ diff --git a/src/5gnrrlc/kw_udx_ul.c b/src/5gnrrlc/kw_udx_ul.c new file mode 100755 index 000000000..c6e9cbc93 --- /dev/null +++ b/src/5gnrrlc/kw_udx_ul.c @@ -0,0 +1,621 @@ +/******************************************************************************* +################################################################################ +# Copyright (c) [2017-2019] [Radisys] # +# # +# 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. # +################################################################################ +*******************************************************************************/ + +/********************************************************************** + + Name: LTE RLC layer + + Type: C include file + + Desc: Defines required by LTE MAC + + File: kw_udx_ul.c + +**********************************************************************/ +static const char* RLOG_MODULE_NAME="UDX"; +static int RLOG_MODULE_ID=262144; +static int RLOG_FILE_ID=204; + +/** @file kw_udx_ul.c +@brief UDX Uplink Module +*/ + +/* header include files (.h) */ +#include "envopt.h" /* environment options */ +#include "envdep.h" /* environment dependent */ +#include "envind.h" /* environment independent */ + +#include "gen.h" /* general */ +#include "ssi.h" /* system services */ +#include "cm5.h" /* common timer defines */ +#include "cm_tkns.h" /* common tokens defines */ +#include "cm_mblk.h" /* common memory allocation library defines */ +#include "cm_llist.h" /* common link list defines */ +#include "cm_hash.h" /* common hash list defines */ +#include "cm_lte.h" /* common LTE defines */ +#include "lkw.h" /* LKW defines */ +#include "ckw.h" /* CKW defines */ +#include "kwu.h" /* KWU defines */ +#include "rgu.h" /* RGU defines */ +#include "kw_err.h" /* Err defines */ +#include "kw_env.h" /* RLC environment options */ + +#include "kw.h" /* RLC defines */ +#include "kw_udx.h" +#include "kw_ul.h" +#include "kw_dl.h" + +/* extern (.x) include files */ +#include "gen.x" /* general */ +#include "ssi.x" /* system services */ + +#include "cm5.x" /* common timer library */ +#include "cm_tkns.x" /* common tokens */ +#include "cm_mblk.x" /* common memory allocation */ +#include "cm_llist.x" /* common link list */ +#include "cm_hash.x" /* common hash list */ +#include "cm_lte.x" /* common LTE includes */ +#include "cm_lib.x" /* common memory allocation library */ +#include "lkw.x" /* LKW */ +#include "ckw.x" /* CKW */ +#include "kwu.x" /* KWU */ +#include "rgu.x" /* RGU */ + +#include "kw.x" +#include "kw_udx.x" +#include "kw_dl.x" +#include "kw_ul.x" + + +#define KW_MODULE KW_DBGMASK_UDX +/* local defines */ + +/* local externs */ + +/* forward references */ + +/* public variable declarations */ +EXTERN S16 kwHdlCkwUlCfgReq ARGS((KwCb *gCb,KwUlCfgTmpData *cfgTmpData, + CkwCfgCfmInfo *cfmInfo, CkwCfgCfmInfo *cfgCfm)); + +/** + * @brief + * UDX APIs + */ +/** + * @brief + * Handler for bind confirmation from DL. + * + * @details + * This function handles the bind confirmation received + * from DL. + * + * @param[in] pst Post structure + * @param[in] suId Service User ID + * @param[in] status Status of confirmation + * + * @return S16 + * -# ROK + * -# RFAILED + */ + +#ifdef ANSI +PUBLIC S16 KwUlUdxBndCfm +( +Pst *pst, +SuId suId, +U8 status +) +#else +PUBLIC S16 KwUlUdxBndCfm (pst, suId, status) +Pst *pst; +SuId suId; +U8 status; +#endif +{ + U16 event; + U16 cause; + KwUdxUlSapCb *udxSap; /* RGU SAP Control Block */ + KwCb *tKwCb; + + TRC3(KwUlUdxBndCfm) + +#if (ERRCLASS & ERRCLS_INT_PAR) + if (pst->dstInst >= KW_MAX_RLC_INSTANCES) + { + RETVALUE (RFAILED); + } +#endif + tKwCb = KW_GET_KWCB(pst->dstInst); + + KWDBGP_BRIEF(tKwCb, "KwUlUdxBndCfm(post, suId(%d), status(%d)\n", + suId, status); + +#if (ERRCLASS & ERRCLS_INT_PAR) + if (tKwCb->init.cfgDone != TRUE) + { + RLOG0(L_FATAL, "General configuration not done"); + KW_SEND_SAPID_ALARM(tKwCb,suId, + LKW_EVENT_LI_BND_CFM, LCM_CAUSE_INV_STATE); + + RETVALUE(RFAILED); + } + + if (suId < 0) + { + RLOG0(L_ERROR, "Invalid suId"); + KW_SEND_SAPID_ALARM(tKwCb,suId, + LKW_EVENT_LI_BND_CFM, LCM_CAUSE_INV_SUID); + + RETVALUE(RFAILED); + } +#endif /* ERRCLASS & ERRCLS_INT_PAR */ + + udxSap = tKwCb->u.ulCb->udxUlSap + suId; + + KWDBGP_DETAIL(tKwCb, "KwLiRguBndCfm: For RGU SAP state=%d\n", + udxSap->state); + + /* Check rguSap state */ + switch (udxSap->state) + { + case KW_SAP_BINDING: + { + if(TRUE == kwChkTmr(tKwCb,(PTR)udxSap,KW_EVT_WAIT_BNDCFM)) + { + kwStopTmr (tKwCb,(PTR)udxSap, KW_EVT_WAIT_BNDCFM); + } + udxSap->retryCnt = 0; + + if (status == CM_BND_OK) + { + udxSap->state = KW_SAP_BND; + event = LCM_EVENT_BND_OK; + cause = LKW_CAUSE_SAP_BNDENB; + } + else + { + udxSap->state = KW_SAP_CFG; + event = LCM_EVENT_BND_FAIL; + cause = LKW_CAUSE_UNKNOWN; + } + } + break; + + default: + event = LKW_EVENT_RGU_BND_CFM; + cause = LCM_CAUSE_INV_STATE; + break; + } + /* Send an alarm with proper event and cause */ + KW_SEND_SAPID_ALARM(tKwCb,suId, event, cause); + + RETVALUE(ROK); +} + +/** + * @brief + * Handles UDX Configuration Confirm + * + * @details + * This function handles the UDX configuration Confirm from DL Instance + * + * @param[in] pst Post structure + * @param[in] suId Service User ID + * @param[in] cfmInfo Confirm Information + * + * @return S16 + * -# ROK + * -# RFAILED + */ +#ifdef ANSI +PUBLIC S16 KwUlUdxCfgCfm +( +Pst *pst, +SuId suId, +CkwCfgCfmInfo *cfmInfo +) +#else +PUBLIC S16 KwUlUdxCfgCfm (pst, suId, cfmInfo) +Pst *pst; +SuId suId; +CkwCfgCfmInfo *cfmInfo; +#endif +{ + KwCb *tKwCb; + CkwCfgCfmInfo *cfgCfm; + KwUlCfgTmpData *cfgTmpData; + + TRC3(KwUlUdxCfgCfm) + +#if (ERRCLASS & ERRCLS_INT_PAR) + if (pst->dstInst >= KW_MAX_RLC_INSTANCES) + { + KW_FREE_SHRABL_BUF(pst->region, + pst->pool, + cfmInfo, + sizeof(CkwCfgCfmInfo)); + RETVALUE (RFAILED); + } +#endif + tKwCb = KW_GET_KWCB(pst->dstInst); + KWDBGP_BRIEF(tKwCb, " suId(%d)\n", suId); + +#if (ERRCLASS & ERRCLS_INT_PAR) + if (suId < 0) + { + RLOG0(L_ERROR, "Invalid suId"); + KW_SEND_SAPID_ALARM(tKwCb,suId, + LKW_EVENT_LI_BND_CFM, LCM_CAUSE_INV_SUID); + KW_FREE_SHRABL_BUF(pst->region, + pst->pool, + cfmInfo, + sizeof(CkwCfgCfmInfo)); + RETVALUE(RFAILED); + } +#endif /* ERRCLASS & ERRCLS_INT_PAR */ + + if(ROK != kwDbmFindUlTransaction(tKwCb,cfmInfo->transId, &cfgTmpData)) + { + RLOG0(L_ERROR, "Invalid transId"); + KW_FREE_SHRABL_BUF(pst->region, + pst->pool, + cfmInfo, + sizeof(CkwCfgCfmInfo)); + RETVALUE (RFAILED); + } + + if(ROK != kwDbmDelUlTransaction(tKwCb, cfgTmpData)) + { + KW_FREE_SHRABL_BUF(pst->region, + pst->pool, + cfmInfo, + sizeof(CkwCfgCfmInfo)); + RETVALUE(RFAILED); + } + /* Allocate memory and memset to 0 for cfmInfo */ + KW_ALLOC(tKwCb,cfgCfm, sizeof(CkwCfgCfmInfo)); +#if (ERRCLASS & ERRCLS_ADD_RES) + if (cfgCfm == NULLP) + { + RLOG0(L_FATAL, "Memory Allocation failed."); + KW_FREE_SHRABL_BUF(pst->region, + pst->pool, + cfmInfo, + sizeof(CkwCfgCfmInfo)); + RETVALUE(RFAILED); + } +#endif /* ERRCLASS & ERRCLS_ADD_RES */ + kwHdlCkwUlCfgReq(tKwCb,cfgTmpData, cfmInfo, cfgCfm); + KwUiCkwCfgCfm(&(tKwCb->u.ulCb->ckwSap.pst), + tKwCb->u.ulCb->ckwSap.suId , cfgCfm); + + /* free the memory from DL */ + KW_FREE_SHRABL_BUF(pst->region, + pst->pool, + cfmInfo, + sizeof(CkwCfgCfmInfo)); + + /* free the cfgInfo that came from LM */ + KW_PST_FREE(pst->region, pst->pool, cfgTmpData->cfgInfo, sizeof(CkwCfgInfo)); + KW_FREE(tKwCb,cfgTmpData,sizeof(KwUlCfgTmpData)); + + RETVALUE(ROK); +} + +/** + * @brief + * Handler for UeId change confirm + * + * @details + * This function handles the UeId Change Confirm from DL Instance + * + * @param[in] pst Post structure + * @param[in] suId Service User ID + * @param[in] transId Transaction Id + * @param[in] status Status of confirmation + * @return S16 + * -# ROK + * -# RFAILED + */ + +#ifdef ANSI +PUBLIC S16 KwUlUdxUeIdChgCfm +( +Pst *pst, +SuId suId, +U32 transId, +CmStatus status +) +#else +PUBLIC S16 KwUlUdxUeIdChgCfm (pst, suId, cfmInfo) +Pst *pst; +SuId suId; +U32 transId; +CmStatus status; +#endif +{ + KwCb *tKwCb; + KwUlCfgTmpData *cfgTmpData; + + TRC3(KwUlUdxUeIdChgCfm) + +#if (ERRCLASS & ERRCLS_INT_PAR) + if (pst->dstInst >= KW_MAX_RLC_INSTANCES) + { + RETVALUE (RFAILED); + } +#endif + tKwCb = KW_GET_KWCB(pst->dstInst); + + KWDBGP_BRIEF(tKwCb, " suId(%d) \n", suId); + +#if (ERRCLASS & ERRCLS_INT_PAR) + if (suId < 0) + { + RLOG0(L_ERROR, "Invalid suId"); + RETVALUE(RFAILED); + } +#endif /* ERRCLASS & ERRCLS_INT_PAR */ + + if(ROK != kwDbmFindUlTransaction(tKwCb, transId, &cfgTmpData)) + { + RLOG0(L_ERROR, "Invalid transId"); + RETVALUE (RFAILED); + } + + if(ROK != kwDbmDelUlTransaction(tKwCb, cfgTmpData)) + { + RETVALUE(RFAILED); + } + + if(status.status == CKW_CFG_CFM_OK) + { + if(cfgTmpData->ueCb != NULLP) + { + kwCfgApplyUlUeIdChng(tKwCb, cfgTmpData->ueInfo, cfgTmpData->newUeInfo, cfgTmpData); + } + } + KwUiCkwUeIdChgCfm(&(tKwCb->u.ulCb->ckwSap.pst), + tKwCb->u.ulCb->ckwSap.suId, + transId,cfgTmpData->ueInfo,status); + /* only newUeInfo needs to be freed here, ueInfo would be freed at the + interface or by he receipient in case of tight coupling */ + KW_PST_FREE(pst->region, pst->pool, cfgTmpData->newUeInfo, sizeof(CkwUeInfo)); + KW_FREE_WC(tKwCb, cfgTmpData, sizeof (KwUlCfgTmpData)); + RETVALUE(ROK); +} + +/** + * @brief + * Udx Status Prohibit Timer Start + * + * @param[in] pst Post structure + * @param[in] suId Service User ID + * @param[in] rlcId rlc Id + * @return S16 + * -# ROK + * -# RFAILED + */ +PUBLIC S16 KwUlUdxStaProhTmrStart +( +Pst* pst, +SuId suId, +CmLteRlcId *rlcId +) +{ + KwCb *tKwCb= NULLP; + KwUlRbCb *rbCb; + +#if (ERRCLASS & ERRCLS_INT_PAR) + if (pst->dstInst >= KW_MAX_RLC_INSTANCES) + { + RETVALUE (RFAILED); + } +#endif + tKwCb = KW_GET_KWCB(pst->dstInst); + + kwDbmFetchUlRbCbByRbId(tKwCb, rlcId, &rbCb); + if (rbCb == NULLP) + { + RLOG_ARG2(L_ERROR, DBG_UEID,rlcId->ueId, "CellId [%u]:RbId[%d] not found", + rlcId->cellId,rlcId->rbId); + RETVALUE(RFAILED); + } + + /* Start staProhTmr */ + kwStartTmr(tKwCb,(PTR)rbCb, KW_EVT_AMUL_STA_PROH_TMR); + + RETVALUE (ROK); +} + +/** + * @brief + * Handler for configuration confirm from DL. + * + * @param[in] gCb - RLC Instance Control Block + * @param[in] cfgTmpData - Configuration Temporary Data + * @param[in] cfmInfo - DL Configuration Confirm Info + * @param[out] cfgCfm - Configuration Confirm to be sent to RRC + * + * @return S16 + * -# ROK + * -# RFAILED + */ +#ifdef ANSI +PUBLIC S16 kwHdlCkwUlCfgReq +( +KwCb *gCb, +KwUlCfgTmpData *cfgTmpData, +CkwCfgCfmInfo *cfmInfo, +CkwCfgCfmInfo *cfgCfm +) +#else +PUBLIC S16 kwHdlCkwUlCfgReq(gCb,cfgTmpData,cfmInfo,cfmInfo) +KwCb *gCb; +KwUlCfgTmpData *cfgTmpData; +CkwCfgCfmInfo *cfmInfo; +CkwCfgCfmInfo *cfgCfm; +#endif +{ + CkwCfgInfo *cfg; + U32 idx; + U32 maxEnt; + + cfg = cfgTmpData->cfgInfo; + maxEnt = (cfg->numEnt < CKW_MAX_ENT_CFG)? cfg->numEnt:CKW_MAX_ENT_CFG; + + for (idx = 0; idx < maxEnt; idx++) + { + CkwEntCfgCfmInfo *entCfgCfm; + CkwEntCfgCfmInfo *entDlCfgCfm; + CkwEntCfgInfo *entCfg; + + entCfg = &(cfg->entCfg[idx]); + entCfgCfm = &(cfgCfm->entCfgCfm[idx]); + entDlCfgCfm = &(cfmInfo->entCfgCfm[idx]); + switch (entCfg->cfgType) + { + case CKW_CFG_ADD: + case CKW_CFG_MODIFY: + case CKW_CFG_DELETE: + { + if (entCfg->dir == KW_DIR_UL) + { + KW_MEM_CPY(entCfgCfm, + &cfgTmpData->cfgEntData[idx].entUlCfgCfm, + sizeof(CkwEntCfgCfmInfo)); + } + else if (entCfg->dir == KW_DIR_DL) + { + KW_MEM_CPY(entCfgCfm, entDlCfgCfm, sizeof(CkwEntCfgCfmInfo)); + } + else if(entCfg->dir == KW_DIR_BOTH) + { + if (entDlCfgCfm->status.status != CKW_CFG_CFM_OK) + { + kwCfgRollBackUlRb(gCb, + cfg->ueId, + &cfg->entCfg[idx], + &cfgTmpData->cfgEntData[idx]); + } + else + { + kwCfgApplyUlRb(gCb, + &cfg->entCfg[idx], + &cfgTmpData->cfgEntData[idx], + cfgTmpData); + } + KW_MEM_CPY(entCfgCfm, entDlCfgCfm, sizeof(CkwEntCfgCfmInfo)); + } + else + { + KW_CFG_FILL_CFG_CFM(entCfgCfm, entCfg->rbId, entCfg->rbType, + CKW_CFG_CFM_NOK, CKW_CFG_REAS_INVALID_DIR); + RLOG_ARG2(L_ERROR,DBG_UEID,cfg->ueId,"RBID[%d] direction[%d] is invalid", + entCfg->rbId,entCfg->dir); + } + break; + } + + case CKW_CFG_REESTABLISH: + { + if (entCfg->dir == KW_DIR_UL) + { + KW_MEM_CPY(entCfgCfm, + &cfgTmpData->cfgEntData[idx].entUlCfgCfm, + sizeof(CkwEntCfgCfmInfo)); + } + else if (entCfg->dir == KW_DIR_DL) + { + KW_MEM_CPY(entCfgCfm, entDlCfgCfm, sizeof(CkwEntCfgCfmInfo)); + } + else + { + if (entCfg->dir & KW_DIR_UL) + { + /* Reestablish indication is sent from UL Instance only*/ + if (entDlCfgCfm->status.status == CKW_CFG_CFM_OK) + { + kwCfgApplyReEstUlRb (gCb, cfg->ueId, + cfg->cellId, TRUE, + &cfgTmpData->cfgEntData[idx]); + } + KW_MEM_CPY(entCfgCfm, entDlCfgCfm, sizeof(CkwEntCfgCfmInfo)); + } + } + break; + } + case CKW_CFG_DELETE_UE: + { + if (cfgTmpData->cfgEntData[idx].entUlCfgCfm.status.status == CKW_CFG_CFM_OK) + { + kwCfgApplyDelUlUe(gCb, cfgTmpData); + KW_MEM_CPY(entCfgCfm, + &cfgTmpData->cfgEntData[idx].entUlCfgCfm, + sizeof(CkwEntCfgCfmInfo)); + } + else + { + KW_MEM_CPY(entCfgCfm, entDlCfgCfm, + sizeof(CkwEntCfgCfmInfo)); + } + break; + } + case CKW_CFG_DELETE_CELL: + { + if (cfgTmpData->cfgEntData[idx].entUlCfgCfm.status.status == CKW_CFG_CFM_OK) + { + kwCfgApplyDelUlCell(gCb, cfgTmpData); + KW_MEM_CPY(entCfgCfm, + &cfgTmpData->cfgEntData[idx].entUlCfgCfm, + sizeof(CkwEntCfgCfmInfo)); + } + else + { + KW_MEM_CPY(entCfgCfm, entDlCfgCfm, + sizeof(CkwEntCfgCfmInfo)); + } + break; + } + default: + { + KW_CFG_FILL_CFG_CFM(entCfgCfm, entCfg->rbId, entCfg->rbType, + CKW_CFG_CFM_NOK, CKW_CFG_REAS_INVALID_CFG); + + RLOG0(L_ERROR,"Invalid configuration type"); + } + } + } + + /* Assign number of entity configurations and suId */ + cfgCfm->transId = cfgTmpData->uprLyrTransId; + cfgCfm->ueId = cfg->ueId; + cfgCfm->cellId = cfg->cellId; + cfgCfm->numEnt = cfg->numEnt; + + RETVALUE(ROK); +} +#ifdef __cplusplus +} +#endif /* __cplusplus */ + + +/********************************************************************** + End of file +**********************************************************************/ diff --git a/src/5gnrrlc/kw_uim.c b/src/5gnrrlc/kw_uim.c new file mode 100755 index 000000000..3ec50f5b7 --- /dev/null +++ b/src/5gnrrlc/kw_uim.c @@ -0,0 +1,967 @@ +/******************************************************************************* +################################################################################ +# Copyright (c) [2017-2019] [Radisys] # +# # +# 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. # +################################################################################ +*******************************************************************************/ + +/********************************************************************20** + + Name: LTE-RLC Layer - Upper Interface Functions + + Type: C file + + Desc: Source code for RLC Upper Interface Module + This file contains following functions + + --KwUiCkwBndReq + --KwUiCkwUbndReq + --KwUiCkwCfgReq + + --KwUiKwuBndReq + --KwUiKwuUbndReq + --KwUiKwuDatReq + --KwUiKwuDiscSduReq + + File: kw_uim.c + +**********************************************************************/ +static const char* RLOG_MODULE_NAME="UIM"; +static int RLOG_MODULE_ID=2048; +static int RLOG_FILE_ID=205; + +/** + * @file kw_uim.c + * @brief RLC Upper Interface Module +*/ + +#define KW_MODULE KW_DBGMASK_INF + + +/* header (.h) include files */ +#include "envopt.h" /* environment options */ +#include "envdep.h" /* environment dependent */ +#include "envind.h" /* environment independent */ + +#include "gen.h" /* general */ +#include "ssi.h" /* system services */ +#include "cm5.h" /* common timer defines */ +#include "cm_tkns.h" /* common tokens defines */ +#include "cm_mblk.h" /* common memory allocation library defines */ +#include "cm_llist.h" /* common link list defines */ +#include "cm_hash.h" /* common hash list defines */ +#include "cm_lte.h" /* common LTE defines */ +#include "lkw.h" /* LKW defines */ +#include "ckw.h" /* CKW defines */ +#include "kwu.h" /* KWU defines */ +#include "rgu.h" /* RGU defines */ +#include "kw_env.h" /* RLC environment options */ +#include "kw.h" /* RLC defines */ +#include "kw_dl.h" +#include "kw_ul.h" +#include "kw_udx.h" + +/* extern (.x) include files */ +#include "gen.x" /* general */ +#include "ssi.x" /* system services */ + +#include "cm5.x" /* common timer library */ +#include "cm_tkns.x" /* common tokens */ +#include "cm_mblk.x" /* common memory allocation */ +#include "cm_llist.x" /* common link list */ +#include "cm_hash.x" /* common hash list */ +#include "cm_lte.x" /* common LTE includes */ +#include "cm_lib.x" /* common memory allocation library */ +#include "lkw.x" /* LKW */ +#include "ckw.x" /* CKW */ +#include "kwu.x" /* KWU */ +#include "rgu.x" /* RGU */ +#include "kw_err.h" +#include "kw.x" +#include "kw_udx.x" +#include "kw_dl.x" +#include "kw_ul.x" + + +/***************************************************************************** + * CKW INTERFACE + ****************************************************************************/ + +/** + * @brief + * Handler for binding the RLC upper layer service user with + * the RLC layer. + * + * @details + * This function is used by RLC user to request for binding to + * RLC. This function is called by the CKW interface to bind + * RLC's SAP (identified by spId) with the service user's + * SAP (identified by suId). + * + * @param[in] pst Post structure + * @param[in] suId Service User ID + * @param[in] spId Service provider ID + * + * @return S16 + * -# ROK + * -# RFAILED + * +*/ +#ifdef ANSI +PUBLIC S16 KwUiCkwBndReq +( +Pst *pst, +SuId suId, +SpId spId +) +#else +PUBLIC S16 KwUiCkwBndReq (pst, suId, spId) +Pst *pst; +SuId suId; +SpId spId; +#endif +{ + KwCkwSapCb *ckwSap; + KwCb *tKwCb; + + TRC3(KwUiCkwBndReq); + +#if (ERRCLASS & ERRCLS_INT_PAR) + if (pst->dstInst >= KW_MAX_RLC_INSTANCES) + { + RETVALUE(RFAILED); + } +#endif + + tKwCb = KW_GET_KWCB(pst->dstInst); + + RLOG2(L_DEBUG, "spId(%d), suId(%d)", spId, suId); + ckwSap = &(tKwCb->u.ulCb->ckwSap); + /* Take action based on the current state of the SAP */ + switch(ckwSap->state) + { + /* SAP is configured but not bound */ + case KW_SAP_CFG: + case KW_SAP_UBND: + { + /* copy bind configuration parameters in SSAP sap */ + ckwSap->suId = suId; + ckwSap->pst.dstProcId = pst->srcProcId; + ckwSap->pst.dstEnt = pst->srcEnt; + ckwSap->pst.dstInst = pst->srcInst; + + /* Update the State */ + ckwSap->state = KW_SAP_BND; + + RLOG1(L_DEBUG, "KwUiCkwBndReq: state (%d)", ckwSap->state); + break; + } + case KW_SAP_BND: + { + /* Sap is already bound check source, destination Entity and + * Proc Id */ + if (ckwSap->pst.dstProcId != pst->srcProcId || + ckwSap->pst.dstEnt != pst->srcEnt || + ckwSap->pst.dstInst != pst->srcInst || + ckwSap->suId != suId) + { + KW_SEND_SAPID_ALARM(tKwCb, + spId, + LKW_EVENT_CKW_BND_REQ, + LCM_CAUSE_INV_PAR_VAL); + + RLOG0(L_ERROR, "CKW SAP already Bound"); + KwUiCkwBndCfm(&(ckwSap->pst), ckwSap->suId, CM_BND_NOK); + RETVALUE(RFAILED); + } + break; + } + default: + { +#if (ERRCLASS & ERRCLS_INT_PAR) + RLOG0(L_ERROR, "Invalid CKW SAP State in Bind Req"); + KW_SEND_SAPID_ALARM(tKwCb, + spId, + LKW_EVENT_CKW_BND_REQ, + LCM_CAUSE_INV_STATE); +#endif /* ERRCLASS & ERRCLS_INT_PAR */ + KwUiCkwBndCfm(&(ckwSap->pst), ckwSap->suId, CM_BND_NOK); + RETVALUE(RFAILED); + break; + } + } + + KwUiCkwBndCfm(&(ckwSap->pst), ckwSap->suId, CM_BND_OK); + RETVALUE(ROK); +} + + +/** + * @brief + * Handler for unbinding the RLC upper layer service user CKW with + * the RLC layer. + * + * @details + * This function is used by RLC user to request for unbinding + * with RLC.This function is called by the CKW interface to + * unbind with RLC. + * + * @param[in] pst Post structure + * @param[in] spId Service provider SAP ID + * @param[in] reason Reason for Unbinding + * + * @return S16 + * -# ROK + * -# RFAILED +*/ +#ifdef ANSI +PUBLIC S16 KwUiCkwUbndReq +( +Pst *pst, +SpId spId, +Reason reason +) +#else +PUBLIC S16 KwUiCkwUbndReq(pst, spId, reason) +Pst *pst; +SpId spId; +Reason reason; +#endif +{ + KwCb *tKwCb; + + TRC3(KwUiCkwUbndReq) + +#if (ERRCLASS & ERRCLS_INT_PAR) + if (pst->dstInst >= KW_MAX_RLC_INSTANCES) + { + RETVALUE(RFAILED); + } +#endif /* ERRCLASS & ERRCLS_INT_PAR */ + tKwCb = KW_GET_KWCB(pst->dstInst); + + RLOG2(L_DEBUG,"spId(%d), reason(%d)", + spId, + reason); + + UNUSED(reason); + +#if (ERRCLASS & ERRCLS_INT_PAR) + KW_GET_AND_VALIDATE_CKWSAP(tKwCb, + (&(tKwCb->u.ulCb->ckwSap)), + EKW208, + "KwUiCkwUbndReq"); +#endif /* ERRCLASS & ERRCLS_INT_PAR */ + + /* disable upper sap (CKW) */ + tKwCb->u.ulCb->ckwSap.state = KW_SAP_CFG; + RETVALUE(ROK); +} + + +/** + * @brief + * Handler for configuring RLC entities. + * + * @details + * This function is used by RRC to configure(add/delete/modify) + * one or more RLC entities. + * + * @param[in] pst - Post structure + * @param[in] spId - Serive Provider ID + * @param[in] cfg - Configuration information for one or more RLC entities. + * + * @return S16 + * -# ROK + * -# RFAILED + */ +#ifdef ANSI +PUBLIC S16 KwUiCkwCfgReq +( +Pst *pst, +SpId spId, +CkwCfgInfo *cfg +) +#else +PUBLIC S16 KwUiCkwCfgReq(pst, spId, cfg) +Pst *pst; +SpId spId; +CkwCfgInfo *cfg; +#endif +{ + S16 ret = ROK; + KwCb *tKwCb; + KwUlCfgTmpData *cfgTmpData; + + static U32 transCount; + + + TRC3(KwUiCkwCfgReq) + +#if (ERRCLASS & ERRCLS_INT_PAR) + if (pst->dstInst >= KW_MAX_RLC_INSTANCES) + { + KW_PST_FREE(pst->region, pst->pool, cfg, sizeof(CkwCfgInfo)); + RETVALUE(RFAILED); + } +#endif + tKwCb = KW_GET_KWCB(pst->dstInst); + + RLOG1(L_DEBUG, "spId(%d)", spId); + + /* Validate SAP ID under ERRORCLS */ + KW_VALDATE_SAP(tKwCb, spId, (&(tKwCb->u.ulCb->ckwSap)), ret); + if (ret != ROK) + { + KW_PST_FREE(pst->region, pst->pool, cfg, sizeof(CkwCfgInfo)); + RETVALUE(RFAILED); + } + + KW_ALLOC(tKwCb, cfgTmpData, sizeof (KwUlCfgTmpData)); + + if (cfgTmpData == NULLP) + { + KW_PST_FREE(pst->region, pst->pool, cfg, sizeof(CkwCfgInfo)); + RETVALUE(RFAILED); + } + + + cfgTmpData->uprLyrTransId = cfg->transId; /*Save User TransId*/ + cfgTmpData->transId = ++transCount; /*Generate new TransId*/ + cfg->transId = cfgTmpData->transId; + cfgTmpData->cfgInfo = cfg; + + if (kwDbmAddUlTransaction(tKwCb, cfgTmpData) != ROK) + { + RLOG0(L_ERROR, "Addition to UL transId Lst Failed"); + KW_PST_FREE(pst->region, pst->pool, cfg, sizeof(CkwCfgInfo)); + + RETVALUE(RFAILED); + } + + kwHdlUiCkwUlCfgReq(tKwCb, cfgTmpData, cfg); + + KwUlUdxCfgReq(&(KW_GET_UDX_SAP(tKwCb)->pst),KW_GET_UDX_SAP(tKwCb)->spId,cfg); + + RETVALUE(ROK); +} + +/** + * @brief + * Handler to change the UeId + * + * @details + * This primitive is used by RRC to change the UeId for the existing UE + * context. + * + * @param[in] pst - Point to the pst structure + * @param[in] spId - The ID of the service provider SAP in the RLC layer + * @param[in] transId - Transaction ID. This field uniquily identifies + * transaction between RRC and RLC + * @param[in] ueInfo - Old UE Id Info for which the change request has come + * @param[in] newUeInfo - New UE Id Info for existing UE context + * + * @return S16 + * -# ROK + * -# RFAILED + */ +#ifdef ANSI +PUBLIC S16 KwUiCkwUeIdChgReq +( +Pst *pst, +SpId spId, +U32 transId, +CkwUeInfo *ueInfo, +CkwUeInfo *newUeInfo +) +#else +PUBLIC S16 KwUiCkwUeIdChgReq(pst, spId, transId, ueInfo, newUeInfo) +Pst *pst; +SpId spId; +U32 transId; +CkwUeInfo *ueInfo; +CkwUeInfo *newUeInfo; +#endif +{ + S16 ret = ROK; + KwCb *tKwCb; + KwUlCfgTmpData *cfgTmpData = NULLP; + + TRC3(KwUiCkwUeIdChgReq) + + do + { +#if (ERRCLASS & ERRCLS_INT_PAR) + if (pst->dstInst >= KW_MAX_RLC_INSTANCES) + { + ret = RFAILED; + break; + } +#endif + + tKwCb = KW_GET_KWCB(pst->dstInst); +#ifndef ALIGN_64BIT + RLOG_ARG2(L_DEBUG,DBG_CELLID,newUeInfo->cellId, + "KwUiCkwUeIdChgReq(pst, spId(%d), transId(%ld))", + spId, + transId); +#else + RLOG_ARG2(L_DEBUG,DBG_CELLID,newUeInfo->cellId, + "KwUiCkwUeIdChgReq(pst, spId(%d), transId(%d))\n", + spId, + transId); +#endif + + KW_ALLOC(tKwCb, cfgTmpData, sizeof (KwUlCfgTmpData)); + if (!cfgTmpData) + { + ret = RFAILED; + break; + } + + cfgTmpData->transId = transId; + cfgTmpData->ueInfo = ueInfo; + cfgTmpData->newUeInfo = newUeInfo; + + if (kwDbmAddUlTransaction(tKwCb, cfgTmpData)) + { + RLOG0(L_ERROR, "Addition to UL transId Lst Failed"); + ret = RFAILED; + break; + } + }while(0); + + if(ret) + { + /* there was an error in the processing, free up all the memory + * that was passed and could have been allocated in this function + */ + /* Freeing from proper region */ + KW_PST_FREE(pst->region, pst->pool, newUeInfo, sizeof(CkwUeInfo)); + KW_PST_FREE(pst->region, pst->pool, ueInfo, sizeof(CkwUeInfo)); + + if(cfgTmpData) + { + KW_FREE(tKwCb, cfgTmpData, sizeof (KwUlCfgTmpData)); + } + RETVALUE(RFAILED); + } + + if(ROK != kwCfgValidateUeIdChng(tKwCb,ueInfo,newUeInfo,cfgTmpData)) + { + RLOG_ARG0(L_ERROR,DBG_CELLID,cfgTmpData->ueInfo->cellId, + "Validation Failure for UeId change"); + } + + KwUlUdxUeIdChgReq(&(KW_GET_UDX_SAP(tKwCb)->pst), + KW_GET_UDX_SAP(tKwCb)->spId, + transId, + ueInfo, + newUeInfo); + + RETVALUE(ROK); +} + + +/** + * @brief + * Handler for Configuration Request + * + * @param[in] gCb RLC Instance Control Block + * @param[in] cfgTmpData Configuration stored in Transaction Block + * @param[in] cfg Configuration block + * + * @return S16 + * -# ROK + * -# RFAILED + */ +#ifdef ANSI +PUBLIC Void kwHdlUiCkwUlCfgReq +( +KwCb *gCb, +KwUlCfgTmpData *cfgTmpData, +CkwCfgInfo *cfg +) +#else +PUBLIC Void kwHdlUiCkwUlCfgReq(gCb, cfgTmpData, cfg) +KwCb *gCb; +KwUlCfgTmpData *cfgTmpData; +CkwCfgInfo *cfg; +#endif +{ + U8 idx; + + TRC3(kwHdlUiCkwUlCfgReq) + + cfgTmpData->ueId = cfg->ueId; + cfgTmpData->cellId = cfg->cellId; + for (idx = 0; idx < cfg->numEnt; idx++) + { + cfgTmpData->cfgEntData[idx].entUlCfgCfm.status.status = CKW_CFG_CFM_OK; + cfgTmpData->cfgEntData[idx].entUlCfgCfm.rbId = cfg->entCfg[idx].rbId; + cfgTmpData->cfgEntData[idx].entUlCfgCfm.rbType = cfg->entCfg[idx].rbType; + switch(cfg->entCfg[idx].cfgType) + { + case CKW_CFG_ADD: + case CKW_CFG_MODIFY: + case CKW_CFG_DELETE: + { + + if(cfg->entCfg[idx].dir & KW_DIR_UL) + { + /* Configuration is for UL , thus validating */ + if(ROK != kwCfgValidateUlRb(gCb, + &cfg->entCfg[idx], + &cfgTmpData->cfgEntData[idx], + cfgTmpData)) + { + RLOG_ARG2(L_ERROR,DBG_UEID, cfgTmpData->ueId, + "CELLID [%u]:Validation Failure for UL RB [%d]", + cfg->cellId,cfg->entCfg[idx].rbId); + cfgTmpData->cfgEntData[idx].entUlCfgCfm.status.status = CKW_CFG_CFM_NOK; + /*Validation is getting failed so no need to do configuration at DL. + *Set dir as UL, so that no configuration is done at DL */ + cfg->entCfg[idx].dir = KW_DIR_UL; + } + } + if(cfg->entCfg[idx].dir == KW_DIR_UL) + { + /*If the configuration is for UL only then apply it */ + if (cfgTmpData->cfgEntData[idx].entUlCfgCfm.status.status == CKW_CFG_CFM_OK) + { + kwCfgApplyUlRb(gCb, + &cfg->entCfg[idx], + &cfgTmpData->cfgEntData[idx], + cfgTmpData); + } + } + break; + } + case CKW_CFG_REESTABLISH: + { + if(cfg->entCfg[idx].dir & KW_DIR_UL) + { + if(ROK != kwCfgValidateReEstRb(gCb, + cfg->ueId, + cfg->cellId, + &cfg->entCfg[idx], + &cfgTmpData->cfgEntData[idx])) + { + RLOG_ARG2(L_ERROR,DBG_UEID,cfg->ueId, + "CellID [%u]:Validation Failure for Reest UL RB [%d]", + cfg->cellId,cfg->entCfg[idx].rbId); + cfgTmpData->cfgEntData[idx].entUlCfgCfm.status.status = CKW_CFG_CFM_NOK; + /* Setting dir as UL, so that no configuration is done at DL */ + cfg->entCfg[idx].dir = KW_DIR_UL; + break; + } + } + if(cfg->entCfg[idx].dir == KW_DIR_UL) + { + /*If the configuration is for UL only then apply it */ + if (cfgTmpData->cfgEntData[idx].entUlCfgCfm.status.status == CKW_CFG_CFM_OK) + { + kwCfgApplyReEstUlRb(gCb, + cfg->ueId, + cfg->cellId, + TRUE, + &cfgTmpData->cfgEntData[idx]); + } + } + break; + } + case CKW_CFG_DELETE_UE : + { + if(ROK != kwCfgValidateDelUlUe(gCb, + &cfg->entCfg[idx], + &cfgTmpData->cfgEntData[idx], + cfgTmpData)) + { + RLOG_ARG1(L_ERROR,DBG_CELLID,cfg->cellId, + "UL UEID [%d]:Validation Failure", + cfgTmpData->ueId); + cfgTmpData->cfgEntData[idx].entUlCfgCfm.status.status = CKW_CFG_CFM_NOK; + /* Setting dir as UL, so that no configuration is done at DL */ + cfg->entCfg[idx].dir = KW_DIR_UL; + } + break; + } + case CKW_CFG_DELETE_CELL : + { + if(ROK != kwCfgValidateDelUlCell(gCb, + cfg->cellId, + &cfg->entCfg[idx], + &cfgTmpData->cfgEntData[idx], + cfgTmpData)) + { + RLOG_ARG0(L_ERROR,DBG_CELLID,cfg->cellId, + "Del UL Cell Validation Failure"); + cfgTmpData->cfgEntData[idx].entUlCfgCfm.status.status = CKW_CFG_CFM_NOK; + /* Setting dir as UL, so that no configuration is done at DL */ + cfg->entCfg[idx].dir = KW_DIR_UL; + } + break; + } + }/* switch end */ + }/* for end */ + RETVOID; +} + + +/***************************************************************************** + * KWU INTERFACE + ****************************************************************************/ +/** + * @brief + * Handler for binding the RLC upper layer service user with + * the RLC layer. + * + * @details + * This function is used by RLC user to request for binding to + * RLC.This function is called by the KWU interface to bind + * RLC's SAP (identified by spId) with the service user's + * SAP (identified by suId). + * + * @param[in] pst Post structure + * @param[in] suId Service user SAP ID + * @param[in] spId Service provider ID + * + * @return S16 + * -# ROK + * -# RFAILED + * + */ +#ifdef ANSI +PUBLIC S16 KwUiKwuBndReq +( +Pst *pst, +SuId suId, +SpId spId +) +#else +PUBLIC S16 KwUiKwuBndReq (pst, suId, spId) +Pst *pst; +SuId suId; +SpId spId; +#endif +{ + KwKwuSapCb *kwuSap; /* SAP Config Block */ + KwCb *tKwCb; + + TRC3(KwUiKwuBndReq) + +#if (ERRCLASS & ERRCLS_INT_PAR) + if (pst->dstInst >= KW_MAX_RLC_INSTANCES) + { + RETVALUE(RFAILED); + } +#endif + tKwCb = KW_GET_KWCB(pst->dstInst); + RLOG2(L_DEBUG, "KwUiKwuBndReq(pst, spId(%d), suId(%d))", spId, suId); + + /* Validation of input parameters */ +#if (ERRCLASS & ERRCLS_INT_PAR) + if(!((spId < (S16) tKwCb->genCfg.maxKwuSaps) && (spId >=0))) + { + RLOG0(L_ERROR,"Invalid spId"); + KW_SEND_SAPID_ALARM(tKwCb,spId, LKW_EVENT_KWU_BND_REQ, LCM_CAUSE_INV_SAP); + RETVALUE(RFAILED); + } +#endif + + /* Get Sap control block */ + kwuSap = (tKwCb->genCfg.rlcMode == LKW_RLC_MODE_DL) ? + (tKwCb->u.dlCb->kwuDlSap + spId): + (tKwCb->u.ulCb->kwuUlSap + spId); + + /* Take action based on the current state of the SAP */ + switch(kwuSap->state) + { + /* SAP is configured but not bound */ + case KW_SAP_CFG: + case KW_SAP_UBND: + { + /* copy bind configuration parameters in sap */ + kwuSap->suId = suId; + kwuSap->pst.dstProcId = pst->srcProcId; + kwuSap->pst.dstEnt = pst->srcEnt; + kwuSap->pst.dstInst = pst->srcInst; + + /* Update the State */ + kwuSap->state = KW_SAP_BND; + + RLOG1(L_DEBUG, "KwUiKwuBndReq: state (%d)", kwuSap->state); + break; + } + case KW_SAP_BND: + { + /* Sap is already bound check source, destination Entity and Proc Id */ + if (kwuSap->pst.dstProcId != pst->srcProcId || + kwuSap->pst.dstEnt != pst->srcEnt || + kwuSap->pst.dstInst != pst->srcInst || + kwuSap->suId != suId) + { + KW_SEND_SAPID_ALARM(tKwCb, + spId, + LKW_EVENT_KWU_BND_REQ, + LCM_CAUSE_INV_PAR_VAL); + RLOG1(L_ERROR,"RLC Mode [%d] : KWU SAP already Bound", + tKwCb->genCfg.rlcMode); + KwUiKwuBndCfm(&(kwuSap->pst), kwuSap->suId, CM_BND_NOK); + RETVALUE(RFAILED); + } + break; + } + + default: + { +#if (ERRCLASS & ERRCLS_INT_PAR) + RLOG1(L_ERROR,"RLC Mode [%d]:Invalid KWU SAP State in Bind Req", + tKwCb->genCfg.rlcMode); + KW_SEND_SAPID_ALARM(tKwCb, + spId, + LKW_EVENT_KWU_BND_REQ, + LCM_CAUSE_INV_STATE); +#endif /* ERRCLASS & ERRCLS_INT_PAR */ + KwUiKwuBndCfm(&(kwuSap->pst), kwuSap->suId, CM_BND_NOK); + RETVALUE(RFAILED); + } + } + KwUiKwuBndCfm(&(kwuSap->pst), kwuSap->suId, CM_BND_OK); + RETVALUE(ROK); +} + + +/** + * @brief + * Handler for unbinding the RLC upper layer service user with + * the RLC layer. + * + * @details + * This function is used by RLC user to request for unbinding + * with RLC.This function is called by the KWU interface to + * unbind with RLC. + * + * @param[in] pst Post structure + * @param[in] spId Service provider SAP ID + * @param[in] reason Reason for Unbinding + * + * @return S16 + * -# ROK + * -# RFAILED + */ +#ifdef ANSI +PUBLIC S16 KwUiKwuUbndReq +( +Pst *pst, +SpId spId, +Reason reason +) +#else +PUBLIC S16 KwUiKwuUbndReq(pst, spId, reason) +Pst *pst; +SpId spId; +Reason reason; +#endif +{ + KwKwuSapCb *kwuSap; /* KWU SAP control block */ + KwCb *tKwCb; + + TRC3(KwUiKwuUbndReq) + +#if (ERRCLASS & ERRCLS_INT_PAR) + if ((pst->dstInst >= KW_MAX_RLC_INSTANCES) || + (spId >= (S16) kwCb[pst->dstInst]->genCfg.maxKwuSaps) || + (spId < 0)) + { + RETVALUE (RFAILED); + } +#endif + + tKwCb = KW_GET_KWCB(pst->dstInst); + + RLOG2(L_DEBUG, "spId(%d), reason(%d)", + spId, + reason); + + /* Get Sap control block */ + kwuSap = (tKwCb->genCfg.rlcMode == LKW_RLC_MODE_DL) ? + (tKwCb->u.dlCb->kwuDlSap + spId): + (tKwCb->u.ulCb->kwuUlSap + spId); + + kwuSap->state = KW_SAP_CFG; + + RETVALUE(ROK); +} + +/** + * @brief Handler for receiving the data(SDU) from upper layer. + * + * @details + * This function is used by RLC service user (PDCP) to + * transfer data (SDU) to RLC. + * + * @param[in] pst Post structure + * @param[in] spId Service Provider SAP ID + * @param[in] datreq Data Request Information + * @param[in] mBuf Data Buffer (SDU) + * + * @return S16 + * -# ROK + * -# RFAILED + */ +#ifdef ANSI +PUBLIC S16 KwUiKwuDatReq +( +Pst *pst, +SpId spId, +KwuDatReqInfo *datReq, +Buffer *mBuf +) +#else +PUBLIC S16 KwUiKwuDatReq(pst, spId, datReq, mBuf) +Pst *pst; +SpId spId; +KwuDatReqInfo *datReq; +Buffer *mBuf; +#endif +{ + S16 ret = ROK; /* Return Value */ + KwDlRbCb *rbCb; /* RB Control Block */ + KwKwuSapCb *kwuSap; /* SAP Config Block */ + KwCb *tKwCb; + + TRC3(KwUiKwuDatReq) + +#if (ERRCLASS & ERRCLS_INT_PAR) + if ((pst->dstInst >= KW_MAX_RLC_INSTANCES) || + (spId >= (S16) kwCb[pst->dstInst]->genCfg.maxKwuSaps) || + (spId < 0)) + { + SPutMsg(mBuf); + RETVALUE(RFAILED); + } +#endif + + tKwCb = KW_GET_KWCB(pst->dstInst); + + /* Get Sap control block */ + kwuSap = tKwCb->u.dlCb->kwuDlSap + spId; + + /* Validate SAP ID under ERRORCLS */ + KW_VALDATE_SAP(tKwCb,spId, kwuSap, ret); + if (ret != ROK) + { + KW_FREE_BUF(mBuf); + RETVALUE(RFAILED); + } + + /* Fetch the RbCb */ + kwDbmFetchDlRbCbByRbId(tKwCb, &datReq->rlcId, &rbCb); + if(!rbCb) + { + RLOG_ARG2(L_WARNING, DBG_UEID,datReq->rlcId.ueId, "CellId[%u]:DL RbId [%d] not found", + datReq->rlcId.cellId,datReq->rlcId.rbId); + KW_FREE_BUF(mBuf); + + RETVALUE(RFAILED); + } + + /* kw005.201 update the spId received in datReq to update statistics */ + rbCb->kwuSapId = spId; + /* Dispatch according to mode of the rbCb */ + switch (rbCb->mode) + { + case CM_LTE_MODE_TM: + { + /* Verify the user */ + if (pst->srcEnt != ENTNH) + { + /* kw002.201 Freeing from proper region */ + KW_SHRABL_STATIC_BUF_FREE(pst->region, pst->pool, datReq, + sizeof(KwuDatReqInfo)); + KW_FREE_BUF(mBuf); + + RETVALUE(RFAILED); + } + + kwTmmQSdu(tKwCb,rbCb, datReq, mBuf); + /* kw005.201 ccpu00117318, updated statistics */ + kwuSap->sts.sduRx++; + break; + } + case CM_LTE_MODE_UM: + { + kwUmmQSdu(tKwCb,rbCb, datReq, mBuf); + + /* kw005.201 ccpu00117318, updated statistics */ + kwuSap->sts.sduRx++; + break; + } + case CM_LTE_MODE_AM: + { + kwAmmQSdu(tKwCb,rbCb, mBuf, datReq); + /* kw005.201 ccpu00117318, updated statistics */ + kwuSap->sts.sduRx++; + break; + } + default: + { + RLOG0(L_ERROR, "Invalid RB Mode"); + break; + } + } + RETVALUE(ret); +} + + +/** + * @brief + * Handler for discarding a SDU. + * + * @details + * This function is used by RLC AM and RLC UM entities. + * This function is called by the service user to discard a particular + * RLC SDU if it is present in the SDU queue of the RB control block + * and if it is not mapped to any PDU. + * + * @param[in] pst Post structure + * @param[in] spId Service Provider SAP ID + * @param[in] discSdu SDU discard Information + * + * @return S16 + * -# ROK + * -# RFAILED + */ +#ifdef ANSI +PUBLIC S16 KwUiKwuDiscSduReq +( +Pst *pst, +SpId spId, +KwuDiscSduInfo *discSdu +) +#else +PUBLIC S16 KwUiKwuDiscSduReq(pst, spId, discSdu) +Pst *pst; +SpId spId; +KwuDiscSduInfo *discSdu; +#endif +{ + KW_SHRABL_STATIC_BUF_FREE(pst->region, pst->pool, discSdu, sizeof(KwuDiscSduInfo)); + RETVALUE(ROK); +} + +/********************************************************************30** + End of file +**********************************************************************/ diff --git a/src/5gnrrlc/kw_ul.h b/src/5gnrrlc/kw_ul.h new file mode 100755 index 000000000..689eae683 --- /dev/null +++ b/src/5gnrrlc/kw_ul.h @@ -0,0 +1,60 @@ +/******************************************************************************* +################################################################################ +# Copyright (c) [2017-2019] [Radisys] # +# # +# 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. # +################################################################################ +*******************************************************************************/ + +/********************************************************************20** + + Name: LTE RLC file for uplink and non real time tasks + + Type: C include file + + Desc: This file contains helper macros for RLC uplink + and non real time tasks + + File: kw_ul.h + +*********************************************************************21*/ +/** + * @file kw_ul.h + * @brief RLC uplink helper macros +*/ + +#ifndef __KW_ULH__ +#define __KW_ULH__ + +/** + * @def KW_MEAS_IS_UL_IP_MEAS_ON_FOR_RB + * + * This macro is used to check if UL IP throughput measurement is ON + * or off for the passed rb + * + * Returns TRUE(non-zero) if measurement is ON else FALSE (zero) + * + * @param[in] _gCb RLC UL Cb + * @param[in] _rbCb RLC uplink control block + * +*/ +#define KW_MEAS_IS_UL_IP_MEAS_ON_FOR_RB(_gCb, _rbCb) \ + ((_rbCb->rlcId.rbType == CM_LTE_DRB) && \ + (_gCb->u.ulCb->kwL2Cb.measOn[_rbCb->qci] & LKW_L2MEAS_UL_IP) && \ + (_rbCb->rbL2Cb.measOn & LKW_L2MEAS_UL_IP)) +#endif /* __KW_ULH__ */ + +/********************************************************************30** + + End of file +**********************************************************************/ diff --git a/src/5gnrrlc/kw_ul.x b/src/5gnrrlc/kw_ul.x new file mode 100755 index 000000000..e197f61d2 --- /dev/null +++ b/src/5gnrrlc/kw_ul.x @@ -0,0 +1,610 @@ +/******************************************************************************* +################################################################################ +# Copyright (c) [2017-2019] [Radisys] # +# # +# 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. # +################################################################################ +*******************************************************************************/ + +/********************************************************************20** + + Name: LTE RLC file for uplink and non real time tasks + + Type: C include file + + Desc: This file contains all the data structures and + prototypes for LTE RLC in the uplink. + + File: kw_ul.x + +*********************************************************************21*/ +/** + * @file kw_ul.x + * @brief RLC uplink structures, prototypes +*/ + +#ifndef __KW_ULX__ +#define __KW_ULX__ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +typedef struct kwUlUeCb KwUlUeCb; + +/** @defgroup um_uplink UM Uplink Module +*/ + +/** + * @brief Structure to hold a UM PDU + * + * @details + * - pdu : Buffer holding the UM PDU data + * - umHdr : UM PDU Header Information + * - pduSz : Length of the PDU excluding the header +*/ +typedef struct kwUmRecBuf +{ + Buffer *pdu; /**< Buffer holding the UM PDU */ + KwUmHdr umHdr; /**< UM PDU Header Information */ + MsgLen pduSz; /**< PDU Size */ +}KwUmRecBuf; + +/** + * @brief Structure to hold uplink information in UM mode for a particular RB + * + * @details + * - snLen : The sequence number length can be 5 bits or 10 bits. + * Here it is stored as 1 or 2 (as the number of bytes) + * - recBuf : Holds all the received PDUs. PDU's are removed from this + * after a SDU is formed or during restablishment + * - umWinSz : The window size is 512 for 10 bits sequence number and 16 + * for 5 bits sequence number + * - partialSdu : This is used to store the partially completed SDU. + * It remains till complete SDU is received +*/ +typedef struct kwUmUl +{ + U8 snLen; /**< Sequence number length */ + U8 reOrdTmrInt; /**< Timer Interval */ + KwUmRecBuf **recBuf; /**< Reception buffer */ + KwSn umWinSz; /**< UM window size */ + U16 modBitMask; /**< Bitmask for modulus to wrap around variables */ + KwSn sn; /**< Sequence number */ + KwSn vrUr; /**< VR(UR) - Receive state variable */ + KwSn vrUh; /**< VR(UH) - Highest received state variable */ + KwSn vrUx; /**< VR(UX) - Reordering state variable */ + CmTimer reOrdTmr; /**< Reordering Timer */ + Buffer *partialSdu; /**< Partial SDU - Remains till the complete SDU + is received */ +}KwUmUl; +/*@}*/ + +/** + * @brief Structure to hold a RLC AM PDU segment + * + * @details + * - lstEnt : This is required for the linked list in which the segments + * are stored + * - seg : Holds the segment data + * - segSz : The length of the segment in bytes + * - soEnd : SOEnd + * - amHdr : The AM Header for the PDU segment + * +*/ +typedef struct kwSeg +{ + CmLList lstEnt; /**< List entry for PDU segment */ + Buffer *seg; /**< PDU segment */ + MsgLen segSz; /**< Buffer Size */ + U16 soEnd; /**< Segment Offset End */ + KwAmHdr amHdr; /**< AM header */ +}KwSeg; + +/*@}*/ + +/** + * @brief Structure to hold a received AM PDU or segments of a PDU + * + * @details + * - pdu : Holds the PDU data + * - pduSz : Length of the PDU in bytes + * - amHdr : The AM Header for the PDU + * - segLst : The length of the segment in bytes + * - expByteSeg : The next expected segment for re-ordering + * - expSo : The next expected SO so to be in sequence + * - allRcvd : Whether all the segments for this PDU has been recevied + * +*/ +typedef struct kwAmRecBuf +{ + CmLList lnk; /**< Link to the receive buffer list */ + Buffer *pdu; /**< PDU buffer */ + MsgLen pduSz; /**< Buffer Size */ + KwAmHdr amHdr; /**< AM header Info */ + CmLListCp segLst; /**< PDU Segments list */ + KwSeg *expByteSeg; /**< Next expected byte segment */ + U16 expSo; /**< Next expected seg offset */ + Bool allRcvd; /**< All bytes received or not */ + Bool isDelvUpperLayer; /**< Is it sent to upper layer */ +}KwAmRecBuf; + +/** @addtogroup ammode */ +/*@{*/ + +/** + * @brief Structure to hold information about an uplink AM Radio Bearer + * + * @details + * - recBuf : Reception buffer + * - rxNext : RX_Next - Receive state variable + * - rxNextHighestRcvd : RX_Next_Highest_Rcvd - Highest received state variable + * - rxNextStatusTrig : RX_Next_Status_Trigger - reorderig state variable + * - vrMr : VR(MR) - Maximum acceptable receive state variable + * - rxHighestStatus : RX_Highest_Status - Maximum STATUS transmit state variable + * - staTrg : Flag to indicate if status trigger occured + * - partialSdu : Partial SDU - Remains till the complete SDU + * is received + * - expSn : The expected sequence number for reassembly + * - expSo : The expected SO for reassembly + * - staProhTmr : The Status Probihit Timer + * - staProhTmrInt : Status Prohibit Timer interval (in ??) + * - reOrdTmr : The Reordering Timer + * - reOrdTmrInt : Re-ordering timer interval + * - gatherStaPduInfo : Whether to gather information required to create + * the STATUS PDU + * +*/ +typedef struct kwAmUl +{ +#ifndef LTE_TDD + CmLListCp *recBufLst; +#else +// KwAmRecBuf *recBuf[1024]; /**< Reception buffer */ +#endif + KwSn rxNext; /**< RX_Next:Equvalent to VR(R) in 4G */ + KwSn rxNextHighestRcvd; /**< RX_Next_Highest_Rcvd: Equvalent to VR(H) in 4G */ + KwSn rxNextStatusTrig; /**< rxNextStatusTrig: Equvalent to VR(X) in 4G*/ + KwSn vrMr; /**< VR(MR) */ + KwSn rxHighestStatus; /**< rxHighestStatus: Eqvalent to VR(MS) in 4G*/ + Bool staTrg; /**< Whether status trigger occured */ + Buffer *partialSdu; /**< Partially received SDU */ + KwSn expSn; /**< Expected SN for reassembly */ + U16 expSo; /**< Expected SO for reassembly */ + CmTimer staProhTmr; /**< T_status_prohibit Timer */ + U16 staProhTmrInt; /**< Timer Interval */ + CmTimer reOrdTmr; /**< T_reordering Timer */ + U8 reOrdTmrInt; /**< Timer Interval */ + Bool gatherStaPduInfo; /**< Gather STATUS PDU creation info*/ + Bool isOutOfSeq; /**< To identify whether packets are Out-Of-Seq or not */ + U8 snLen; /*!< Sequence number length:12 bit or 18 bit : 5GNR RLC */ + U32 snModMask; /*!< (2 Pwr SnLen - 1): 5GNR RLC */ +}KwAmUl; + +/*@}*/ + +/** + * @brief Structure to hold uplink information about a Radio Bearer + * + * @details + * - rlcId : RLC identifier, uniquely identifies a Radio Bearer + * - lch : Information (type and id) of the logical channel associated + * with this Radio Bearer. + * - mode : The mode of the Radio Bearer; UM or AM + * - dir : The direction of the Radio Bearer, downlink or uplink or both + * - inst : Id of RLC instance where this Radio Bearer is present. Used + * to find the instance from the Radio Bearer for memory needs + * as different instances might have different memory. + * - kwuSapId : KWU SAP identifier + * - udxSapId : UDX SAP idenrifier + * - transId : Stores the transaction identifier used to communicate + * with MAC, the same value as sent by MAC is passed back + * for it to be able to corelate + * - m : Mode of the RB (TM/UM/AM) + * - umDl : Unacknowledged Mode downlink information + * - amDl : Acknowledged Mode downlink information +*/ +typedef struct _kwUlRbCb +{ +/* kw005.201 added support for L2 Measurement */ +#ifdef LTE_L2_MEAS + KwL2MeasRbCb rbL2Cb; /**< RB measurement L2 Cb */ + KwUlUeCb *ueCb; /*!< Pointer to UeCb */ + U8 qci; /**< qci of the RB */ + KwL2MeasIpThruput l2MeasIpThruput; /**< Holds related parameter for + DL/Ul ip throughput>*/ +#endif /* LTE_L2_MEAS */ + CmLteRlcId rlcId; /**< RLC Identifier */ + KwLchInfo lch; /**< Logical Channel Info */ + CmLteRlcMode mode; /**< Entity Mode */ + U8 dir; /**< Direction for UL/DL */ + Inst inst; /**< Tapa where Rb created Instance id */ + SpId kwuSapId; /**< KWU sap Id, to get the KwuSapCb */ + SpId udxSapId; /**< KWU sap Id, to get the KwuSapCb */ + U32 transId; /**< Transaction Id for RLC */ + union + { + KwUmUl umUl; /**< UM mode Ul elements */ + KwAmUl amUl; /**< AM mode uplink elements */ + }m; /**< RLC mode specific Info */ +}KwUlRbCb; + +/** + * @brief Structure to hold mapping between logical channel and Radio Bearer + * + * @details + * - ulRbCb : Pointer to the uplink Radio Bearer +*/ +typedef struct kwUlLch +{ + KwUlRbCb *ulRbCb; /**< Pointer to Uplink RbCb */ +}KwUlLch; + +/** + * @brief Structure to hold uplink information about the Cells + * + * @details + * - cellHlEnt : Information about cells are stored in a hash table. This is + * required for that. + * - cellId : Identity of the cell + * - rbCb : Radio Bearers in the cell + * - lCh : Logical Channels in the cell + * - selfPstUl : Pst structure for sending messages to self +*/ +typedef struct kwUlCellCb +{ + CmHashListEnt cellHlEnt; /**< Hash list entry for CellCb */ + CmLteCellId cellId; /**< Cell Id */ + KwUlRbCb *rbCb[KW_MAX_RB_PER_CELL]; /**< RbCbs within a Cell */ + KwUlLch lCh[KW_MAX_LCH_PER_CELL]; /**< Logical channels in a cell */ + Pst selfPstUl; +}KwUlCellCb; + +/** + * @brief Structure to hold uplink information about the UEs + * + * @details + * - ueHlEnt : Information about cells are stored in a hash table. This is + * required for that. + * - key : Key to store/find the UE in the hashtable + * - srbCb : Signaling Radio Bearers configured for the UE + * - drbCb : Data Radio Bearers configured for the UE + * - lCh : Logical Channels in the UE +*/ +struct kwUlUeCb +{ + CmHashListEnt ueHlEnt; /**< Hash list entry for UeCb */ + CmLteRnti ueId; /*!< UE Id */ + CmLteCellId cellId; /*!< Cell Id */ + KwUlRbCb *srbCb[KW_MAX_SRB_PER_UE]; /**< SRB RbCbs within an UE */ + KwUlRbCb *drbCb[KW_MAX_DRB_PER_UE]; /**< DRB RbCbs within an UE */ + KwUlLch lCh[KW_MAX_LCH_PER_UE]; /**< Logical channels of an UE*/ +/* kw005.201 added support for L2 Measurement */ +#ifdef LTE_L2_MEAS + U32 firstPacketTTI; /*!< is first packet of the burst */ + U16 numActRb[LKW_MAX_QCI]; /**< number of RBs Active */ + Bool isUlBurstActive; /*! Initialize External + * + * @b Description: + * Initializes variables used to interface with Upper/Lower Layer + * + * @return S16 + * -# ROK + * +*/ + +#ifdef ANSI +PUBLIC S16 kwUlInitExt +( +) +#else +PUBLIC S16 kwUlInitExt() +#endif +{ + TRC2(kwUlInitExt); + + RETVALUE(ROK); +} /* kwInitExt */ + + + +/*********************************************************************** + System Service Interface Functions + ***********************************************************************/ +/** + * + * @brief + * + * Activates Initialization + * + * @b Description: + * This function is invoked by system services to initialize the LTE-RLC + * layer. This is an entry point used by LTE_RLC layer to initialize its + * global variables, before becoming operational. + * + * Allowable values for parameters are specified in ssi.h. + * + * @param[in] ent - Specify the entity id of the LTE-RLC task. + * @param[in] inst - Specify the entity id of the LTE-RLC task. + * @param[in] region - Specifies the memory region from which + * LTE-RLC should allocate structures and buffers. + * @param[in] reason - Specifies the reason for calling this + * initialization function. + * + * @return S16 + * -# ROK + * + */ +#ifdef ANSI +PUBLIC S16 kwUlActvInit +( +Ent ent, /* entity */ +Inst inst, /* instance */ +Region region, /* region */ +Reason reason /* reason */ +) +#else +PUBLIC S16 kwUlActvInit(ent, inst, region, reason) +Ent ent; /* entity */ +Inst inst; /* instance */ +Region region; /* region */ +Reason reason; /* reason */ +#endif +{ + KwCb *tKwCb; + TRC3(kwDlActvInit) + + if (inst >= KW_MAX_RLC_INSTANCES) + { + /* intance greater than MAX instances */ + RETVALUE(RFAILED); + } + + if (kwCb[inst] != NULLP) + { + RETVALUE (RFAILED); + } + + if (SGetSBuf(region, 0, (Data **)&tKwCb, + (Size)sizeof (KwCb)) != ROK) + { + RETVALUE(RFAILED); + } + + /* Initialize kwCb */ + KW_MEM_SET(tKwCb, 0, sizeof(KwCb)); + + /* Initialize task configuration parameters */ + tKwCb->init.ent = ent; /* entity */ + tKwCb->init.inst = inst; /* instance */ + tKwCb->init.region = region; /* static region */ + tKwCb->init.pool = 0; /* static pool */ + tKwCb->init.reason = reason; /* reason */ + tKwCb->init.cfgDone = FALSE; /* configuration done */ + tKwCb->init.acnt = TRUE; /* enable accounting */ + tKwCb->init.usta = TRUE; /* enable unsolicited status */ + tKwCb->init.trc = FALSE; /* enable trace */ + tKwCb->init.procId = SFndProcId(); + + kwCb[inst] = tKwCb; + + /* call external function for intialization */ + /* + kwInitExt(); + */ +#ifdef TENB_STATS + TSL2AllocStatsMem(tKwCb->init.region, tKwCb->init.pool); +#endif + + RETVALUE(ROK); +} /* kwActvInit */ + + +/** + * + * @brief + * + * Activation Task + * + * @b Description: + * Processes events received for MLTE-RLC layer via System Services from + * other layers. + * + * @param[in] pst - Pst Structure + * @param[in] mBuf - Message Buffer + * + * @return S16 + * -# ROK + * + */ +#ifdef ANSI +PUBLIC S16 kwUlActvTsk +( +Pst *pst, /* pst structure */ +Buffer *mBuf /* message buffer */ +) +#else +PUBLIC S16 kwUlActvTsk(pst, mBuf) +Pst *pst; /* pst structure */ +Buffer *mBuf; /* message buffer */ +#endif +{ + S16 ret = ROK; + + TRC3(kwActvTsk); + + switch(pst->srcEnt) + { + case ENTSM: + { + switch(pst->event) + { +#ifdef LCLKW + case LKW_EVT_CFG_REQ: + { + ret = cmUnpkLkwCfgReq(KwMiLkwCfgReq, pst, mBuf); + break; + } + + case LKW_EVT_CNTRL_REQ: + { + ret = cmUnpkLkwCntrlReq(KwMiLkwCntrlReq, pst, mBuf); + break; + } + + case LKW_EVT_STS_REQ: + { + ret = cmUnpkLkwStsReq(KwMiLkwStsReq, pst, mBuf); + break; + } + + case LKW_EVT_STA_REQ: + { + ret = cmUnpkLkwStaReq(KwMiLkwStaReq, pst, mBuf); + break; + } + /* kw005.201 added support for L2 Measurement */ +#ifdef LTE_L2_MEAS + case LKW_EVT_L2MEAS_REQ: + { + ret = cmUnpkLkwL2MeasReq(KwMiLkwL2MeasReq, pst, mBuf); + break; + } + case LKW_EVT_L2MEAS_SEND_REQ: + { + + ret = cmUnpkLkwL2MeasSendReq(KwMiLkwL2MeasSendReq, pst, mBuf); + + break; + } + case LKW_EVT_L2MEAS_STOP_REQ: + { + ret = cmUnpkLkwL2MeasStopReq(KwMiLkwL2MeasStopReq, pst, mBuf); + break; + } +#endif +#endif /* LCLKW */ + default: + SPutMsg(mBuf); + if (pst->dstInst < KW_MAX_RLC_INSTANCES) + { + RLOG1(L_FATAL,"Received Invalid Event[%d] from SM", + pst->event); + } + ret = RFAILED; + break; + + } + break; + } + + case ENTKW: + { + switch(pst->event) + { +#ifdef LCUDX + case UDX_EVT_BND_CFM: /* Bind request */ + { + ret = cmUnpkUdxBndCfm(KwUlUdxBndCfm, pst, mBuf ); + break; + } + + case UDX_EVT_CFG_CFM: /* Unbind request */ + { + ret = cmUnpkUdxCfgCfm(KwUlUdxCfgCfm, pst, mBuf ); + break; + } + + case UDX_EVT_UEIDCHG_CFM: /* Configuration request */ + { + ret = cmUnpkUdxUeIdChgCfm(KwUlUdxUeIdChgCfm, pst, mBuf); + break; + } + + case UDX_EVT_STA_PHBT_TMR_START: /* Status Prohibit Timer Start */ + { + ret = cmUnpkUdxStaProhTmrStart(KwUlUdxStaProhTmrStart, pst, mBuf); + break; + } + +#endif /* LCCKW */ + + default: + SPutMsg(mBuf); + if (pst->dstInst < KW_MAX_RLC_INSTANCES) + { + RLOG1(L_ERROR,"Received Invalid Event[%d] from RLC UL", + pst->event); + } + ret = RFAILED; + break; + + } + break; + } + + case ENTNH: + { + switch(pst->event) + { +#ifdef LCCKW + case CKW_EVT_BND_REQ: /* Bind request */ + { + ret = cmUnpkCkwBndReq(KwUiCkwBndReq, pst, mBuf ); + break; + } + + case CKW_EVT_UBND_REQ: /* Unbind request */ + { + ret = cmUnpkCkwUbndReq(KwUiCkwUbndReq, pst, mBuf ); + break; + } + + case CKW_EVT_CFG_REQ: /* Configuration request */ + { + ret = cmUnpkCkwCfgReq(KwUiCkwCfgReq, pst, mBuf); + break; + } + + case CKW_EVT_UEIDCHG_REQ: /* Configuration request */ + { + ret = cmUnpkCkwUeIdChgReq(KwUiCkwUeIdChgReq, pst, mBuf); + break; + } + +#endif /* LCCKW */ + +#ifdef LCKWU + case KWU_EVT_BND_REQ: /* Bind request */ + { + ret = cmUnpkKwuBndReq(KwUiKwuBndReq, pst, mBuf ); + break; + } + + case KWU_EVT_UBND_REQ: /* Unbind request */ + { + ret = cmUnpkKwuUbndReq(KwUiKwuUbndReq, pst, mBuf ); + break; + } +#endif /* LCKWU */ + default: + SPutMsg(mBuf); + if (pst->dstInst < KW_MAX_RLC_INSTANCES) + { + RLOG1(L_ERROR,"Received Invalid Event[%d] from RRC", + pst->event); + } + ret = RFAILED; + break; + + } + break; + } + + case ENTPJ: + { + switch(pst->event) + { +#ifdef LCKWU + case KWU_EVT_BND_REQ: /* Bind request */ + { + ret = cmUnpkKwuBndReq(KwUiKwuBndReq, pst, mBuf ); + break; + } + + case KWU_EVT_UBND_REQ: /* Unbind request */ + { + ret = cmUnpkKwuUbndReq(KwUiKwuUbndReq, pst, mBuf ); + break; + } + + default: + SPutMsg(mBuf); + if (pst->dstInst < KW_MAX_RLC_INSTANCES) + { + RLOG1(L_ERROR,"Received Invalid Event[%d] from PDCP", + pst->event); + } + ret = RFAILED; + break; +#endif /* LCKWU */ + } + break; + } + + case ENTRG: + { + switch(pst->event) + { +#ifdef LCRGU + case EVTRGUBNDCFM: /* Bind request */ + { + ret = cmUnpkRguBndCfm(KwLiRguBndCfm, pst, mBuf ); + break; + } + + case EVTRGUCDATIND: /* Coomon Channel Data request */ + { + ret = cmUnpkRguCDatInd(KwLiRguCDatInd, pst, mBuf); + break; + } + + case EVTRGUDDATIND: /* Dedicated Channel Data request */ + { + ret = cmUnpkRguDDatInd(KwLiRguDDatInd, pst, mBuf); + break; + } + +#endif /* LCRGU */ + + default: + SPutMsg(mBuf); + if (pst->dstInst < KW_MAX_RLC_INSTANCES) + { + RLOG1(L_ERROR,"Received Invalid Event[%d] from MAC", + pst->event); + } + ret = RFAILED; + break; + } + break; + } +#if defined(L2_L3_SPLIT) && defined (TENB_T2K3K_SPECIFIC_CHANGES) && defined (MAC_RLC_UL_RBUF) + case ENTYS: + { + switch(pst->event) + { + case KWU_EVT_TTI_IND: + { + kwUlBatchProc(); + SPutMsg(mBuf); + break; + } + } + break; + } +#endif/* End for TENB_T2K3K_SPECIFIC_CHANGES and L2_L3_SPLIT */ +#ifndef UL_RLC_NET_CLUSTER +#ifdef TENB_STATS + case ENTTF: + { + switch(pst->event) + { + case TENBSTATSINIT: + { + + KwCb *tKwCb; + tKwCb = KW_GET_KWCB(pst->dstInst); + + TSL2SendStatsToApp(&(tKwCb->genCfg.lmPst), 0); + SPutMsg(mBuf); + break; + } + default: + { + printf("\n ERROR Invalid Event[%d] from CL to PDCPUL\n", + pst->event); + SPutMsg(mBuf); + break; + } + } + break; + } +#endif +#endif + default: + { + if (pst->dstInst < KW_MAX_RLC_INSTANCES) + { + RLOG1(L_ERROR, "Received Invalid Source Entity[%d]",pst->event); + } + SPutMsg(mBuf); + ret = RFAILED; + break; + } + } + SExitTsk(); + + RETVALUE(ret); +} /* kwActvTsk */ + + + +/********************************************************************30** + End of file +**********************************************************************/ diff --git a/src/5gnrrlc/kw_umm_dl.c b/src/5gnrrlc/kw_umm_dl.c new file mode 100755 index 000000000..987d3edaf --- /dev/null +++ b/src/5gnrrlc/kw_umm_dl.c @@ -0,0 +1,920 @@ +/******************************************************************************* +################################################################################ +# Copyright (c) [2017-2019] [Radisys] # +# # +# 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. # +################################################################################ +*******************************************************************************/ + +/********************************************************************** + + Name: LTE-RLC Layer + + Type: C file + + Desc: Source code for RLC Unacknowledged mode assembly and + reassembly.This file contains following functions + + --kwUmmQSdu + --kwUmmProcessSdus + --kwUmmProcessPdus + --kwUmmReAssembleSdus + --kwUmmReEstablish + + File: kw_umm_dl.c + +**********************************************************************/ +static const char* RLOG_MODULE_NAME="RLC"; +static int RLOG_MODULE_ID=2048; +static int RLOG_FILE_ID=239; +/** + * @file kw_umm_dl.c + * @brief RLC Unacknowledged Mode downlink module +*/ + +/* header (.h) include files */ +#include "envopt.h" /* environment options */ +#include "envdep.h" /* environment dependent */ +#include "envind.h" /* environment independent */ + +#include "gen.h" /* general */ +#include "ssi.h" /* system services interface */ +#include "cm5.h" /* Timer Functions */ +#include "cm_lte.h" /* common umts header file */ +#include "cm_hash.h" /* common hash module file */ +#include "cm_llist.h" /* common list header file */ +#include "ckw.h" /* RRC layer */ +#include "lkw.h" /* RRC layer */ +#include "kwu.h" /* RLC service user */ +#include "lkw.h" /* LM Interface */ +#include "rgu.h" /* MAC layer */ +#include "kw_env.h" /* RLC environment options */ + +#include "kw.h" /* RLC layer */ +#include "kw_err.h" +#include "kw_udx.h" +#include "kw_dl.h" + + +/* header/extern include files (.x) */ + +#include "gen.x" /* general */ +#include "ssi.x" /* system services interface */ +#include "cm_lib.x" /* common library */ +#include "cm5.x" /* Timer Functions */ +#include "cm_hash.x" /* common hash module */ +#include "cm_lte.x" /* common umts file */ +#include "cm_llist.x" /* common list header file */ +#include "ckw.x" /* RRC layer */ +#include "kwu.x" /* RLC service user */ +#include "lkw.x" /* LM Interface */ +#include "rgu.x" /* MAC later */ + +#include "kw.x" /* RLC layer */ +#include "kw_udx.x" +#include "kw_dl.x" + +#define KW_MODULE (KW_DBGMASK_UM | KW_DBGMASK_DL) + +/* variables for logging :declared in BRDCM cl */ +#ifndef TENB_ACC +extern U32 dldrops_kwu_um; +extern U32 dlpkt_um; +extern U32 buffer_occ; +extern U32 dlrate_kwu; +#endif + +PRIVATE Void kwUmmEstHdrSz ARGS ((KwUmDl *umUl)); + +PRIVATE Void kwUmmCreatePdu ARGS ((KwCb *gCb, + KwDlRbCb *rbCb, + Buffer *pdu, + U8 fi, + KwPduInfo *datReqPduInfo)); + +/** @addtogroup ummode */ +/*@{*/ + +/** + * @brief Handler to queue a SDU in the SDU queue, update BO and report + * it to the lower layer. + * + * @details + * This function is used to queue the received SDU in the + * SDU queue maintained in the radio bearer control block. + * After queuing the SDU, BO is updated and is reported + * to the lower layer. + * + * @param[in] gCb RLC Instance control block + * @param[in] rbCb RB control block + * @param[in] datReq Ptr to the datReq sent from PDCP + * @param[in] mBuf Sdu data + * + * @return Void +*/ +#ifdef ANSI +PUBLIC Void kwUmmQSdu +( +KwCb *gCb, +KwDlRbCb *rbCb, +KwuDatReqInfo *datReq, +Buffer *mBuf +) +#else +PUBLIC Void kwUmmQSdu(gCb,rbCb,datReq,mBuf) +KwCb *gCb; +KwDlRbCb *rbCb; +KwuDatReqInfo *datReq; +Buffer *mBuf; +#endif +{ + MsgLen len; /* SDU buffer length */ + KwSdu *sdu; /* SDU */ + + TRC2(kwUmmQSdu) + + KW_UPD_L2_DL_TOT_SDU_STS(gCb,rbCb); + + KW_ALLOC_WC(gCb, sdu, (Size)sizeof(KwSdu)); +#if (ERRCLASS & ERRCLS_ADD_RES) + if ( sdu == NULLP ) + { + RLOG_ARG2(L_FATAL,DBG_RBID,rbCb->rlcId.rbId, + "Memory allocation failed UEID:%d CELLID:%d", + rbCb->rlcId.ueId, + rbCb->rlcId.cellId); + SPutMsg(mBuf); + RETVOID; + } +#endif /* ERRCLASS & ERRCLS_ADD_RES */ + +/* Discard new changes starts */ + kwUtlGetCurrTime(&sdu->arrTime); +/* Discard new changes ends */ + SFndLenMsg(mBuf,&len); + + sdu->mBuf = mBuf; + sdu->sduSz = len; + sdu->actSz = len; + sdu->mode.um.sduId = datReq->sduId; + sdu->mode.um.isSegmented = FALSE; +#ifndef RGL_SPECIFIC_CHANGES +#ifndef TENB_ACC +#ifndef LTE_PAL_ENB + { + dlrate_kwu += len; + } +#endif +#endif +#endif + rbCb->m.umDl.bo += len; + + cmLListAdd2Tail(&(rbCb->m.umDl.sduQ), &sdu->lstEnt); + sdu->lstEnt.node = (PTR)sdu; + + kwUmmEstHdrSz(&rbCb->m.umDl); + + if(!kwDlUtlIsReestInProgress(rbCb)) + { + kwUtlSndDStaRsp(gCb,rbCb,rbCb->m.umDl.bo,rbCb->m.umDl.estHdrSz,FALSE,0); + } + + /* kw005.201 added support for L2 Measurement */ +#ifdef LTE_L2_MEAS_RLC + /* Update numActUe if it is not active */ + if((rbCb->rbL2Cb.measOn & LKW_L2MEAS_ACT_UE) && + (rbCb->ueCb->numActRb[rbCb->qci]++ == 0)) + { + kwCb.kwL2Cb.numActUe[rbCb->qci]++; + } +#endif + + RETVOID; +} + + +/** + * @brief Handler to form PDU(s) and update the BO. + * + * @details + * -# This function forms pdu(s) from the SDU(s) in the + * SDU queue and returns them. + * -# This function also updates the BO along with the + * along with the estimated Header size. + * + * @param[in] rbCb RB control block + * @param[out] pduInfo Pdu Info to be filled and the PDU size to be + * formed and the updated BO + * @param[in] pduSz The size for which PDUs have to constructed + * + * @return S16 + * -# ROK In case of success + * -# RFAILED If allocation of Sdu fails +*/ +#ifdef ANSI +PUBLIC Void kwUmmProcessSdus +( +KwCb *gCb, +KwDlRbCb *rbCb, +KwDatReq *datReq +) +#else +PUBLIC Void kwUmmProcessSdus(gCb, rbCb, datReq) +KwCb *gCb; +KwDlRbCb *rbCb; +KwDatReq *datReq; +#endif +{ + CmLList *firstNode; /* First Node in SDU queue */ + U8 fi=0; /* Framing Info */ + Buffer *pdu; /* Buffer for holding the formed PDU */ + KwPduInfo *pduInfo; /* PDU Info pointer */ + S16 pduSz; /* PDU Size to be constructed */ + + /* kw005.201 added support for L2 Measurement */ +#ifdef LTE_L2_MEAS + KwContSduLst contSduLst; /*Contained sduLst */ + S32 dataVol = rbCb->m.umDl.bo; + U32* totMacGrant= &(datReq->totMacGrant); + KwL2MeasDlIpTh *dlIpThPut = &rbCb->l2MeasIpThruput.dlIpTh; + U8 *sduIdx = &dlIpThPut->lastSduIdx; + Bool newIdx = FALSE; + S32 oldBo; + KwlchInfo lchInfo = {0}; + U32 segSduCnt = 0; +#endif + Ticks curTime = 0; + S16 timeDiff = 0; + KwSdu *sdu; + + + TRC2(kwUmmProcessSdus) + + + pdu = NULLP; + + pduInfo = &(datReq->pduInfo); + pduSz = datReq->pduSz; + +#ifdef LTE_L2_MEAS + contSduLst.numSdus = 0; + contSduLst.lcId = rbCb->lch.lChId; + oldBo = rbCb->m.umDl.bo; + lchInfo.lcId = rbCb->lch.lChId; + lchInfo.numSdus = 0; +#endif + + /* Discard new changes starts */ + kwUtlGetCurrTime(&curTime); + + /* ccpu00143043 */ + while ((pduSz > 0) && (rbCb->m.umDl.sduQ.count > 0) && + (rbCb->m.umDl.numLi < KW_MAX_DL_LI) && (pduInfo->numPdu < KW_MAX_PDU)) + { + CM_LLIST_FIRST_NODE(&rbCb->m.umDl.sduQ,firstNode); + sdu = (KwSdu *)(firstNode->node); + + if ((sdu->mode.um.isSegmented == FALSE) && (rbCb->discTmrInt > 0) && + (rbCb->rlcId.rbType == CM_LTE_DRB)) + { + timeDiff = KW_TIME_DIFF(curTime,sdu->arrTime); + + if (timeDiff >= rbCb->discTmrInt) + { +#ifdef LTE_L2_MEAS + KW_UPD_L2_DL_DISC_SDU_STS(gCb, rbCb); +#endif + rbCb->m.umDl.bo -= sdu->sduSz; + KW_RMV_SDU(gCb,&rbCb->m.umDl.sduQ,sdu); + continue; + } + } + /* When forming a new PDU, pdu == NULLP + -# Eliminate MAC header size for each pdu + -# Initialize the li array to 0 + -# Substract the fixed header length based on SN length + */ +#ifdef LTE_L2_MEAS + newIdx = FALSE; +#endif + if (!pdu) + { + KW_RMV_MAC_HDR_SZ(pduSz); + + /* account for the RLC header size */ + pduSz -= rbCb->m.umDl.snLen; + + /* kw005.201 fixing pduSz <= 0 problem, ccpu00119417 */ + if(pduSz <= 0) + { + break; + } + + rbCb->m.umDl.numLi = 0; + if (sdu->mode.um.isSegmented == TRUE) + { + fi = 2; + } + else + { + fi = 0; + } + } + + kwUtlCalcLiForSdu(gCb,rbCb->m.umDl.numLi,sdu->sduSz,&pduSz); + + /* Exact fit scenario : + If the SDU size matches with the PDU size + -# Allocate memory equal to PDU size; + -# update BO + -# Remove SDu from queue + -# Append to already existing PDU portion if present . + -# Add Header and create complete PDU and place it in + pduInfo and return + */ + if (sdu->sduSz == pduSz) + { + if (!pdu) + { + pdu = sdu->mBuf; + sdu->mBuf = NULLP; + } + else + { + SCatMsg(pdu, sdu->mBuf, M1M2); + } + + rbCb->m.umDl.bo -= pduSz; + pduSz = 0; + +#ifdef LTE_L2_MEAS + if(KW_MEAS_IS_DL_ANY_MEAS_ON_FOR_RB(gCb,rbCb)) + { + if(sdu->mode.um.isSegmented) + { + *sduIdx = dlIpThPut->lastSduIdx; + } + else + { + KW_GETSDUIDX(*sduIdx); + newIdx = TRUE; + } + kwUtlUpdateContainedSduLst(*sduIdx, &contSduLst); + kwUtlUpdateOutStandingSduLst(dlIpThPut, *sduIdx, sdu->actSz, + sdu->mode.um.sduId, newIdx); + /* ccpu00143043 */ + if ( lchInfo.numSdus < KW_L2MEAS_SDUIDX) + { + lchInfo.sduInfo[lchInfo.numSdus].arvlTime = sdu->arrTime; + lchInfo.sduInfo[lchInfo.numSdus].isRetxPdu = FALSE; + lchInfo.numSdus++; + } + } +#endif +/* kw005.201 added support for L2 Measurement */ +#ifdef LTE_L2_MEAS_RLC + kwUtlUpdSduSnMap(rbCb, sdu, datReq, TRUE); + if((rbCb->rbL2Cb.measOn & LKW_L2MEAS_DL_DELAY) || + (rbCb->rbL2Cb.measOn & LKW_L2MEAS_UU_LOSS)) + { + /* ccpu00143043 */ + if ( lchInfo.numSdus < KW_L2MEAS_SDUIDX) + { + lchInfo.arvlTime[lchInfo.numSdus] = sdu->arrTime; + lchInfo.numSdus++; + } + } +#endif /* LTE_L2_MEAS */ + KW_RMV_SDU(gCb,&(rbCb->m.umDl.sduQ),sdu); /* kw003.201 */ + kwUtlIncrementKwuStsSduTx(gCb->u.dlCb->kwuDlSap + rbCb->kwuSapId); + + kwUmmCreatePdu(gCb,rbCb,pdu,fi,pduInfo); + pdu = NULLP; + + } + /* Concatenation scenario : + If SDU size is less than the requested PDU size + -# Allocate memory and copy SDU into it. + -# Update BO + -# Remove SDU from the Queue. + -# Append to already existing PDU portion if present . + -# If the SDU size is greater than 2047 or the number of i + LIs reaches max, place it as a separate PDU in pduInfo and + set pdu to NULL + else + place the msglen in li array and continue with the next SDU. + -# If the number of PDUs is more than KW_MAX_PDU, return from + the function even if pduSize > 0. + */ + else if (sdu->sduSz < pduSz) + { + if (!pdu) + { + pdu = sdu->mBuf; + sdu->mBuf = NULLP; + } + else + { + SCatMsg(pdu, sdu->mBuf ,M1M2); + } + rbCb->m.umDl.bo -= sdu->sduSz; + + pduSz -= sdu->sduSz; +/* kw005.201 added support for L2 Measurement */ +#ifdef LTE_L2_MEAS_RLC + kwUtlUpdSduSnMap(rbCb, sdu, datReq, TRUE); +#endif /* LTE_L2_MEAS */ + if (sdu->sduSz < 2048 && rbCb->m.umDl.numLi < KW_MAX_DL_LI) + { + rbCb->m.umDl.li[(rbCb->m.umDl.numLi)++] = sdu->sduSz; + } + else + { + kwUmmCreatePdu(gCb, rbCb, pdu, fi, pduInfo); + pdu = NULLP; + + if ( pduInfo->numPdu == KW_MAX_PDU) + { + /* Could not transmit what MAC asked for because the number + * of PDUs to be transmitted has reached maximum. */ + RLOG_ARG2(L_DEBUG,DBG_RBID,rbCb->rlcId.rbId, + "Maximum Pdu limit has been reached UEID:%d CELLID:%d", + rbCb->rlcId.ueId, + rbCb->rlcId.cellId); + break; + } + } +#ifdef LTE_L2_MEAS + if(KW_MEAS_IS_DL_ANY_MEAS_ON_FOR_RB(gCb,rbCb) ) + { + if(sdu->mode.um.isSegmented) + { + *sduIdx = dlIpThPut->lastSduIdx; + } + else + { + KW_GETSDUIDX(*sduIdx); + newIdx = TRUE; + } + kwUtlUpdateContainedSduLst(*sduIdx, &contSduLst); + kwUtlUpdateOutStandingSduLst(dlIpThPut, *sduIdx, sdu->actSz, + sdu->mode.um.sduId, newIdx); + /* ccpu00143043 */ + if ( lchInfo.numSdus < KW_L2MEAS_SDUIDX) + { + lchInfo.sduInfo[lchInfo.numSdus].arvlTime = sdu->arrTime; + lchInfo.sduInfo[lchInfo.numSdus].isRetxPdu = FALSE; + lchInfo.numSdus++; + } + } +#endif + KW_RMV_SDU(gCb,&(rbCb->m.umDl.sduQ),sdu); + /* kw005.201 ccpu00117318, updating the statistics */ + kwUtlIncrementKwuStsSduTx(gCb->u.dlCb->kwuDlSap + rbCb->kwuSapId); + } + /* Segmentation scenario : + If size of SDU is greater than PDU size + -# Allocate memory and Segment the Sdu. + -# Update BO + -# Append to already existing PDU if any. + -# Set the second bit of the framing info. + -# Create the complete PDU and place in pduInfo. + */ + else + { + Buffer *remSdu; + + SSegMsg(sdu->mBuf,pduSz,&remSdu); + +#ifdef LTE_L2_MEAS + if(KW_MEAS_IS_DL_IP_MEAS_ON_FOR_RB(gCb, rbCb)) + { + if(sdu->mode.um.isSegmented) + { + *sduIdx = dlIpThPut->lastSduIdx; + } + else + { + KW_GETSDUIDX(*sduIdx); + newIdx = TRUE; + } + kwUtlUpdateContainedSduLst(*sduIdx, &contSduLst); + kwUtlUpdateOutStandingSduLst(dlIpThPut, *sduIdx, sdu->actSz, + sdu->mode.um.sduId, newIdx); + } + if(KW_MEAS_IS_DL_UU_LOSS_MEAS_ON_FOR_RB(gCb,rbCb)) + { + if(sdu->actSz == sdu->sduSz) + { + segSduCnt++; + } + } +#endif + if (!pdu) + { + pdu = sdu->mBuf; + } + else + { + SCatMsg(pdu, sdu->mBuf, M1M2); + KW_FREE_BUF_WC(sdu->mBuf); + } + + sdu->sduSz -= pduSz; + rbCb->m.umDl.bo -= pduSz; + sdu->mode.um.isSegmented = TRUE; + sdu->mBuf = remSdu; + pduSz = 0; + + fi |= 1; +/* kw005.201 added support for L2 Measurement */ +#ifdef LTE_L2_MEAS_RLC + kwUtlUpdSduSnMap(rbCb, sdu, datReq, FALSE); +#endif /* LTE_L2_MEAS */ + + kwUmmCreatePdu(gCb,rbCb,pdu,fi,pduInfo); + pdu = NULLP; + } +/* kw005.201 added support for L2 Measurement */ + } +#ifdef LTE_L2_MEAS_RLC + if((rbCb->rbL2Cb.measOn) && + (rbCb->m.umDl.sduQ.count == 0) && + (dataWasPrsnt)) + { + if(--(rbCb->ueCb->numActRb[rbCb->qci]) == 0) + { + kwCb.kwL2Cb.numActUe[rbCb->qci]--; + } + } +#endif /* LTE_L2_MEAS */ +#ifdef LTE_L2_MEAS + kwUtlUpdateBurstSdus(gCb, rbCb, &contSduLst, dataVol, *totMacGrant); + /* Need to check into optimizing this code : TODO */ + if(KW_MEAS_IS_DL_ANY_MEAS_ON_FOR_RB(gCb,rbCb) && (lchInfo.numSdus != 0)) + { + KwL2MeasTb *l2MeasTb = kwUtlGetCurMeasTb(gCb, rbCb); + /* ccpu00143043 */ + /* Fix Klock warning */ + if ((lchInfo.numSdus != 0) && (l2MeasTb != NULLP) && + (l2MeasTb->numLchInfo < KW_MAX_ACTV_DRB)) + { + cmMemcpy((U8 *) &l2MeasTb->lchInfo[l2MeasTb->numLchInfo], (U8 *) &lchInfo, sizeof(KwlchInfo)); + l2MeasTb->numLchInfo++; + } + l2MeasTb->txSegSduCnt += segSduCnt; + } + *totMacGrant -= (oldBo - rbCb->m.umDl.bo); +#endif + + /* If we have a situation wherein the size requested is greater than the total size of SDUs + and a pdu buffer which is not null, this if loop helps to send + a non null PDU to the lower layer. + */ + if (pduSz > 0 && pdu) + { + if (pduInfo->numPdu != KW_MAX_PDU) + { + rbCb->m.umDl.numLi--; + kwUmmCreatePdu(gCb,rbCb,pdu,fi,pduInfo); + pdu = NULLP; + } + else + { + KW_FREE_BUF_WC(pdu); + } + } + + kwUmmEstHdrSz(&rbCb->m.umDl); + datReq->boRep.bo = rbCb->m.umDl.bo; + datReq->boRep.estHdrSz = rbCb->m.umDl.estHdrSz; + datReq->boRep.staPduPrsnt = FALSE; + if (rbCb->m.umDl.sduQ.count > 0) + { + datReq->boRep.oldestSduArrTime = + ((KwSdu *)(rbCb->m.umDl.sduQ.first->node))->arrTime; + } + RETVOID; +} + +/** + * @brief Handler to process the re-establishment request received from i + * the upper layer. + * + * @details + * This function does the following functions : + * Remove all the SDUs in the SDU queue. + * + * @param[in] gCb RLC Instance control block + * @param[in] rlcID Identity of the RLC entity for which + * re-establishment is to be done + * @param[in] sendReEst Whether to send re-establishment complete + * indication to upper layer or not + * @param[in] rbCb RB control block for which re-establishment + * is to be done + * + * @return Void +*/ +#ifdef ANSI +PUBLIC Void kwDlUmmReEstablish +( +KwCb *gCb, +CmLteRlcId rlcId, +Bool sendReEst, +KwDlRbCb *rbCb +) +#else +PUBLIC Void kwDlUmmReEstablish(gCb, rlcId, rbCb) +KwCb *gCb; +CmLteRlcId rlcId; +Bool sendReEst; +KwDlRbCb *rbCb; +#endif +{ + /* The re-establishment indication is sent from the UL only */ + TRC2(kwDlUmmReEstablish) + + + kwUmmFreeDlRbCb(gCb, rbCb); + + rbCb->m.umDl.vtUs = 0; + + /* this would have been set when re-establishment was triggered + for SRB 1 */ + kwDlUtlResetReestInProgress(rbCb); + + RETVOID; +} +/** + * @brief Handler to create the header and complete a PDU. + * + * @details + * This function is used to create the header of a PDU and concatenate it + * with the data part of the PDU. + * Also updates the statistics + * Sets the passed pdu to NULLP + * + * @param[in] gCb RLC instance control block + * @param[in,out] rbCb RB control block + * @param[in] pdu PDU + * @param[in] fi Framing Info field + * @param[out] datReqPduInfo Holder in which to copy the created PDU pointer + * + * @return Void +*/ +#ifdef ANSI +PRIVATE Void kwUmmCreatePdu +( +KwCb *gCb, +KwDlRbCb *rbCb, +Buffer *pdu, +U8 fi, +KwPduInfo *datReqPduInfo +) +#else +PRIVATE Void kwUmmCreatePdu(gCb, rbCb, pdu, fi, datReqPduInfo) +KwCb *gCb; +KwDlRbCb *rbCb; +Buffer *pdu; +U8 fi; +KwPduInfo *datReqPduInfo +#endif +{ + KwSn sn; /* Sequence Number */ + U32 liCount; /* LI count */ + U8 e = 0; /* Extension Bit */ + U32 count; /* Loop Counter */ + U32 hdrSz; + + /* create a big array to store the header, assuming 3 bytes per 2 L1s + * (2 bytes if only a single LI) and 2 bytes for the + * FI and SN + * size of header = ( NumLi /2 ) * 3 + (NumLi % 2) * 2 + 2; + * where NumLi = Number of Length Indicators to be sent + */ + U8 hdr[((KW_MAX_DL_LI >> 1) * 3) + ((KW_MAX_DL_LI & 0x01) << 1) + 2]; + U32 idx = 0; /* To index to the hdr array */ + + /* Note: idx is not checked against crossing the hdr array bound as + * liCount will be < KW_MAX_DL_LI and as per the size calculated above; + * idx cannot cross the array + */ + + TRC2(kwUmmCreatePdu) + + + /* stats updated before for bytes sent before adding RLC headers */ + kwUtlIncrementGenStsBytesAndPdusSent(&gCb->genSts, pdu); + + sn = rbCb->m.umDl.vtUs; + liCount = rbCb->m.umDl.numLi; + + if(liCount > KW_MAX_DL_LI) + liCount = KW_MAX_DL_LI; + + /* if there are any LI's then set the first E bit */ + if(liCount) + { + e = 1; + } + + if (rbCb->m.umDl.snLen == 1) + { + hdr[idx++] = (fi << 6) | (e << 5) | sn; + } + else /* SN length is 2 */ + { + /* SN length is 10 bits */ + hdr[idx] = (fi << 3) | (e << 2) | (sn >> 8); + hdr[++idx] = sn & 0xff; + ++idx; + } + + hdrSz = sizeof(hdr); + for (count = 0;count < liCount;count++) + { + /* In each iteration we try and encode 2 LIs */ + /* if this is the last LI then e should be 0 */ + if(count == liCount - 1) + { + e = 0; + } + + /* ccpu00135170 Fixing KLOCK warning */ + if((idx + 1)>= hdrSz) + { + break; + } + /* odd LI, 1st , 3rd etc */ + hdr[idx] = (e << 7) | (rbCb->m.umDl.li[count] >> 4); + hdr[++idx] = (rbCb->m.umDl.li[count] & 0xf) << 4; + + count++; + if(count == liCount - 1) + { + e = 0; + } + else if(count >= liCount) + { + break; + } + /* ccpu00135170 Fixing KLOCK warning */ + if((idx + 1)>= hdrSz) + { + break; + } + /* even one, 2nd , 4th etc LI's, count starts at 0 */ + hdr[idx] |= ((e << 3) | (rbCb->m.umDl.li[count] >> 8)); + hdr[++idx] = rbCb->m.umDl.li[count] & 0xff; + ++idx; + } + + /* if odd number of L1s increment idx */ + if(liCount & 0x1) + { + ++idx; + } + + /* increment VT(US) */ + rbCb->m.umDl.vtUs = (rbCb->m.umDl.vtUs + 1) & rbCb->m.umDl.modBitMask; + + /* add the header to the beginning of the pdu */ + SAddPreMsgMultInOrder(hdr, idx, pdu); + + datReqPduInfo->mBuf[datReqPduInfo->numPdu++] = pdu; + RETVOID; +} + +/** + * @brief Handler to estimate the header size of the RLC SDUs + * present in the SDU queue. + * + * @details + * This function is used to update the estimated header size variable in RB. + * This function is called when a SDU is queued and when a PDU is formed and + * sent to the lower layer. + * + * @param[in] umDl UM mode downlink control block + * + * @return Void +*/ +#ifdef ANSI +PRIVATE Void kwUmmEstHdrSz +( +KwUmDl *umDl +) +#else +PRIVATE Void kwUmmEstHdrSz(umDl) +KwUmDl *umDl; +#endif +{ + /* The header size is estimated as : + If sdu count = 0 then 0 + else sdu count * 2 + 1; the 1 is added for the FI and SN byte; + 2 for one LI and E + */ + umDl->estHdrSz = (umDl->sduQ.count)?((umDl->sduQ.count << 1) + 1) : 0; + + RETVOID; +} + +/** + * @brief Handler to discard a SDU. + * + * @details + * This function is used to discard a SDU after receiving + * the Discard Request from the upper layer.The SDU is discarded if + * it is present and is not mapped to any PDU yet. + * The discards coming from the upper layer would be coming in + * sequence according to the sduId, so we should find the sduId at the + * head of the sduQ. Discards if there is a match else does nothing. + * + * @param[in] rbCb RB control block + * @param[in] sduId SDU ID of the SDU to be discarded + * + * @return Void +*/ +#ifdef ANSI +PUBLIC Void kwUmmDiscSdu +( +KwCb *gCb, +KwDlRbCb *rbCb, +U32 sduId +) +#else +PUBLIC Void kwUmmDiscSdu(gCb,rbCb,sduId) +KwCb *gCb; +KwDlRbCb *rbCb; +U32 sduId; +#endif +{ + CmLList *tmpNode; /* Temporary Node in SDU queue */ + + TRC2(kwUmmDiscSdu) + + + CM_LLIST_FIRST_NODE(&rbCb->m.umDl.sduQ,tmpNode); + + if (tmpNode) + { + KwSdu *sdu = (KwSdu *)tmpNode->node; + + if (sdu->mode.um.sduId == sduId && sdu->mode.um.isSegmented == FALSE) + { +/* kw005.201 added support for L2 Measurement */ + KW_RMV_SDU(gCb,&rbCb->m.umDl.sduQ,sdu); + gCb->genSts.numSduDisc++; + } + } + + RETVOID; +} + +/* + * + * @brief + * function to free/release the UnAcknowledged mode RBCB buffers + * + * @details + * This primitive Frees the Unacknowldged Mode RbCb sdu queue + * + * @param [in] gCb - RLC instance control block + * @param [in] rbCb - RB Control Block + * + * @return Void + */ +#ifdef ANSI +PUBLIC Void kwUmmFreeDlRbCb +( +KwCb *gCb, +KwDlRbCb *rbCb +) +#else +PUBLIC Void kwUmmFreeDlRbCb(gCb,rbCb) +KwCb *gCb; +KwDlRbCb *rbCb; +#endif +{ + TRC2(kwUmmFreeDlRbCb) + + + /* cat the SDU queue to the to be freed list */ + cmLListCatLList(&(gCb->u.dlCb->toBeFreed.sduLst),&(rbCb->m.umDl.sduQ)); + kwUtlRaiseDlCleanupEvent(gCb); + + RETVOID; +} /* kwUmmFreeDlRbCb */ + +/********************************************************************30** + End of file +**********************************************************************/ diff --git a/src/5gnrrlc/kw_umm_ul.c b/src/5gnrrlc/kw_umm_ul.c new file mode 100755 index 000000000..449e1861d --- /dev/null +++ b/src/5gnrrlc/kw_umm_ul.c @@ -0,0 +1,966 @@ +/******************************************************************************* +################################################################################ +# Copyright (c) [2017-2019] [Radisys] # +# # +# 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. # +################################################################################ +*******************************************************************************/ + +/********************************************************************** + + Name: LTE-RLC Layer + + Type: C file + + Desc: Source code for RLC Unacknowledged mode assembly and + reassembly.This file contains following functions + + --kwUmmQSdu + --kwUmmProcessSdus + --kwUmmProcessPdus + --kwUmmReAssembleSdus + --kwUmmReEstablish + + File: kw_umm_ul.c + +**********************************************************************/ +static const char* RLOG_MODULE_NAME="RLC"; +static int RLOG_MODULE_ID=2048; +static int RLOG_FILE_ID=240; + +/** + * @file kw_umm_ul.c + * @brief RLC Unacknowledged Mode uplink module +*/ + +/* header (.h) include files */ +#include "envopt.h" /* environment options */ +#include "envdep.h" /* environment dependent */ +#include "envind.h" /* environment independent */ + +#include "gen.h" /* general */ +#include "ssi.h" /* system services interface */ +#include "cm5.h" /* Timer Functions */ +#include "cm_lte.h" /* common umts header file */ +#include "cm_hash.h" /* common hash module file */ +#include "cm_llist.h" /* common list header file */ +#include "ckw.h" /* RRC layer */ +#include "lkw.h" /* RRC layer */ +#include "kwu.h" /* RLC service user */ +#include "lkw.h" /* LM Interface */ +#include "rgu.h" /* MAC layer */ +#include "kw_env.h" /* RLC environment options */ + +#include "kw.h" /* RLC layer */ +#include "kw_err.h" +#include "kw_ul.h" + + +/* header/extern include files (.x) */ + +#include "gen.x" /* general */ +#include "ssi.x" /* system services interface */ +#include "cm_lib.x" /* common library */ +#include "cm5.x" /* Timer Functions */ +#include "cm_hash.x" /* common hash module */ +#include "cm_lte.x" /* common umts file */ +#include "cm_llist.x" /* common list header file */ +#include "ckw.x" /* RRC layer */ +#include "kwu.x" /* RLC service user */ +#include "lkw.x" /* LM Interface */ +#include "rgu.x" /* MAC later */ + +#include "kw.x" /* RLC layer */ +#include "kw_ul.x" + +#define KW_MODULE (KW_DBGMASK_UM | KW_DBGMASK_UL) + +PRIVATE S16 kwUmmExtractHdr ARGS ((KwCb *gCb, + KwUlRbCb *rbCb, + Buffer *pdu, + KwUmHdr *umHdr)); + +PRIVATE Void kwUmmReAssembleSdus ARGS ((KwCb *gCb, + KwUlRbCb *rbCb, + KwUmRecBuf *umRecBuf)); + +#ifndef TENB_ACC +#ifndef LTE_PAL_ENB +extern U32 isMemThreshReached(Region region); +#endif +#endif +/** + * @brief Finds and sets the next VR(UR) depending on the + * passed sequence number + * + * @details + * Finds the next VR(UR) depending on the passed SN. Updates VR(UR) to + * the SN of the first UMD PDU with SN >= _nextSn that has not been received + * + * @param[in] umUl pointer to Um mode uplink control block + * @param[in] nextSn Sequence number after which the VR(UR) is to set to + * + * @return Void +*/ +PRIVATE Void kwUmmFindNextVRUR (KwUmUl* umUl, KwSn nextSn) +{ + KwSn ur = KW_UM_GET_VALUE(umUl->vrUr, *umUl); + + KwSn nextSnToCompare = KW_UM_GET_VALUE(nextSn,*umUl); + + while (ur < nextSnToCompare) + { + if (!(umUl->recBuf[nextSn])) /* if the buffer is empty, SN not received */ + { + umUl->vrUr = nextSn; + break; + } + nextSn = (nextSn + 1) & umUl->modBitMask; + nextSnToCompare = KW_UM_GET_VALUE(nextSn,*umUl); + } +} + +/** + * @brief Checks whether a sequence number is within the + * re-ordering window or not + * + * @param[in] sn Sequence Number to be checked + * @param[in] umUl pointer to Um mode uplink control block + * + * @return S16 + * -# TRUE + * -# FALSE + * + * @return Void +*/ +PRIVATE S16 kwUmmCheckSnInReordWindow (KwSn sn, + CONSTANT KwUmUl* CONSTANT umUl) +{ + return (KW_UM_GET_VALUE(sn, *umUl) < KW_UM_GET_VALUE(umUl->vrUh, *umUl)); +} + +/** + * @brief Handler to process the Data Indication from the lower layer + * and send the PDUs to re-assembly unit. + * + * @details + * This function processes the PDUs received from the lower layer + * re-orders them and sends them one after the other in sequence + * to the re-assembly unit. + * + * @param[in] gCb RLC Instance control block + * @param[in] rbCb RB control block + * @param[in] pduInfo Pdu information + * + * @return Void +*/ +/* kw005.201 added support for L2 Measurement */ +#ifdef LTE_L2_MEAS + +#ifdef ANSI +PUBLIC Void kwUmmProcessPdus +( +KwCb *gCb, +KwUlRbCb *rbCb, /* Rb Control Block */ +KwPduInfo *pduInfo, /* Pdu data and related information */ +U32 ttiCnt /* ttiCnt received from MAC */ +) +#else +PUBLIC Void kwUmmProcessPdus(rbCb,pduInfo,ttiCnt) +KwCb *gCb; +KwUlRbCb *rbCb; /* Rb Control Block */ +KwPduInfo *pduInfo; /* Pdu data and related information */ +U32 ttiCnt; /* ttiCnt received from MAC */ +#endif +#else +#ifdef ANSI +PUBLIC Void kwUmmProcessPdus +( +KwCb *gCb, +KwUlRbCb *rbCb, /* Rb Control Block */ +KwPduInfo *pduInfo /* Pdu data and related information */ +) +#else +PUBLIC Void kwUmmProcessPdus(rbCb,pduInfo) +KwCb *gCb; +KwUlRbCb *rbCb; /* Rb Control Block */ +KwPduInfo *pduInfo; /* Pdu data and related information */ +#endif +#endif +{ + KwSn *vrUh; /* vr(uh) */ + KwSn *vrUr; /* vr(ur) */ + KwSn *vrUx; /* vr(ux) */ + U16 curSn; /* Current Sequence Number */ + U32 pduCount; /* PDU count */ + U32 count; /* Loop counter */ + KwUmRecBuf **recBuf; /* UM Reception Buffer */ + + Bool tmrRunning; /* Boolean for checking Tmr */ +/* kw005.201 added support for L2 Measurement */ + + TRC2(kwUmmProcessPdus) + + + count = 0; + + /* pduCount should be the min of RGU_MAX_PDU and pduInfo->numPdu */ + pduCount = (pduInfo->numPdu < RGU_MAX_PDU)? pduInfo->numPdu : RGU_MAX_PDU; + + vrUh = &(rbCb->m.umUl.vrUh); + vrUr = &(rbCb->m.umUl.vrUr); + vrUx = &(rbCb->m.umUl.vrUx); + recBuf = (rbCb->m.umUl.recBuf); + + while (count < pduCount) + { + KwSn ur; + KwSn uh; + KwSn seqNum; + Buffer *pdu = pduInfo->mBuf[count]; + KwUmRecBuf *tmpRecBuf; + gCb->genSts.pdusRecv++; +#ifndef RGL_SPECIFIC_CHANGES +#ifndef TENB_ACC +#ifndef LTE_PAL_ENB + extern U32 ulrate_rgu; + MsgLen len; + SFndLenMsg(pdu, &len); + ulrate_rgu += len; +#endif +#endif +#endif + /* create a buffer to be later inserted into the reception buffer */ + KW_ALLOC_WC(gCb, tmpRecBuf, sizeof(KwUmRecBuf)); +#if (ERRCLASS & ERRCLS_ADD_RES) + if (tmpRecBuf == NULLP) + { + RLOG_ARG2(L_FATAL, DBG_RBID,rbCb->rlcId.rbId, + "Memory allocation failed UEID:%d CELLID:%d", + rbCb->rlcId.ueId, + rbCb->rlcId.cellId); + SPutMsg(pdu); + + RETVOID; + } +#endif /* ERRCLASS & ERRCLS_ADD_RES */ + /* ccpu00142274 - UL memory based flow control*/ +#ifndef RGL_SPECIFIC_CHANGES +#ifndef TENB_ACC +#ifndef LTE_PAL_ENB + /* Changed the condition to TRUE from ROK */ +#ifndef XEON_SPECIFIC_CHANGES + if(isMemThreshReached(kwCb[0]->init.region) == TRUE) + { + extern U32 rlculdrop; + rlculdrop++; + KW_FREE_BUF(pdu); + KW_FREE_WC(gCb, tmpRecBuf, sizeof(KwUmRecBuf)); + /*Fix for CR ccpu00144030: If threshhold is hit then also count + *should be incrmented */ + count++; + continue; + } +#endif +#endif +#endif +#endif + /* get the pdu header */ + if (kwUmmExtractHdr(gCb, rbCb, pdu, &(tmpRecBuf->umHdr))) + { + RLOG_ARG2(L_ERROR,DBG_RBID,rbCb->rlcId.rbId, + "Header Extraction Failed UEID:%d CELLID:%d", + rbCb->rlcId.ueId, + rbCb->rlcId.cellId); + + /* Header extraction is a problem. + * log an error and free the allocated memory */ + /* ccpu00136940 */ + KW_FREE_WC(gCb, tmpRecBuf, sizeof(KwUmRecBuf)); + SPutMsg(pdu); + count++; + /* kw005.201 ccpu00117318, updating the statistics */ + gCb->genSts.errorPdusRecv++; + continue; + } + curSn = tmpRecBuf->umHdr.sn; + + /* Check if the PDU should be discarded or not */ + ur = KW_UM_GET_VALUE(KW_UMUL.vrUr, KW_UMUL); + uh = KW_UM_GET_VALUE(KW_UMUL.vrUh, KW_UMUL); + seqNum = KW_UM_GET_VALUE(curSn, KW_UMUL); + + if (((ur < seqNum) && (seqNum < uh) && (KW_UMUL.recBuf[curSn])) || + (seqNum < ur)) + { + /* PDU needs to be discarded */ + RLOG_ARG3(L_DEBUG,DBG_RBID,rbCb->rlcId.rbId, + "Received a duplicate pdu with sn %d UEID:%d CELLID:%d", + curSn, + rbCb->rlcId.ueId, + rbCb->rlcId.cellId); + + KW_FREE_BUF(pdu); + KW_FREE_WC(gCb, tmpRecBuf, sizeof(KwUmRecBuf)); + count++; + /* kw005.201 ccpu00117318, updating the statistics */ + gCb->genSts.unexpPdusRecv++; + continue; + } + + /* kw005.201 added support for L2 Measurement */ +#ifdef LTE_L2_MEAS + + /* kw006.201 ccpu00120058, reduced code complexity by adding new function */ + kwUtlCalUlIpThrPut(gCb,rbCb, pdu, ttiCnt); + +#endif + + recBuf[curSn] = tmpRecBuf; + + recBuf[curSn]->pdu = pdu; + SFndLenMsg(pdu,&(recBuf[curSn]->pduSz)); + /* kw005.201 ccpu00117318, updating the statistics */ + gCb->genSts.bytesRecv += recBuf[curSn]->pduSz; + + if (!kwUmmCheckSnInReordWindow(curSn,&KW_UMUL)) + { /* currSn is outside re-ordering window */ + *vrUh = (curSn + 1) & KW_UMUL.modBitMask; + + /* re-assemble all pdus outside the modified re-ordering window */ + /* the first SN is VR(UR) */ + if (!kwUmmCheckSnInReordWindow(*vrUr,&KW_UMUL)) + { + /* TODO : should it be VR(UR) + 1 ?... check, earlier it was so */ + KwSn sn = *vrUr; /* SN's which need to be re-assembled */ + KwSn lowerEdge; /* to hold the lower-edge of the + re-ordering window */ + + /* The new value ov VR(UR) is the lower end of the window i + * and SN's still this value need to be re-assembled */ + + *vrUr = (*vrUh - KW_UMUL.umWinSz) & KW_UMUL.modBitMask; + lowerEdge = KW_UM_GET_VALUE(*vrUr ,KW_UMUL); + + while (KW_UM_GET_VALUE(sn, KW_UMUL) < lowerEdge) + { + if (recBuf[sn]) + { + kwUmmReAssembleSdus(gCb,rbCb,recBuf[sn]); + KW_FREE_WC(gCb,recBuf[sn],sizeof(KwUmRecBuf)); + recBuf[sn] = NULLP; + } + sn = (sn + 1) & KW_UMUL.modBitMask; + } + } + } + if (recBuf[*vrUr]) + { + KwSn sn = *vrUr; + KwSn tSn = KW_UM_GET_VALUE(sn,KW_UMUL); + KwSn tVrUr; + + /* set VR(UR) to next SN > current VR(UR) which is not received */ + KwSn nextVrUr = (*vrUr + 1) & KW_UMUL.modBitMask; + kwUmmFindNextVRUR(&KW_UMUL, nextVrUr); + + /* re-assemble SDUs with SN < Vr(UR) */ + tVrUr = KW_UM_GET_VALUE(*vrUr,KW_UMUL); + while (recBuf[sn] && tSn < tVrUr) + { + kwUmmReAssembleSdus(gCb,rbCb,recBuf[sn]); + KW_FREE_WC(gCb,recBuf[sn],sizeof(KwUmRecBuf)); + recBuf[sn] = NULLP; + sn = (sn + 1) & KW_UMUL.modBitMask; + tSn = KW_UM_GET_VALUE(sn, KW_UMUL); + } + } + + tmrRunning = kwChkTmr(gCb,(PTR)rbCb, KW_EVT_UMUL_REORD_TMR); + + if (tmrRunning) + { + KwSn tVrUx = KW_UM_GET_VALUE(*vrUx, KW_UMUL); + KwSn tVrUr = KW_UM_GET_VALUE(*vrUr ,KW_UMUL); + + KwSn tVrUh = KW_UM_GET_VALUE(*vrUh, KW_UMUL); + + S16 ret = kwUmmCheckSnInReordWindow(*vrUx, &KW_UMUL); + + if ( (tVrUx <= tVrUr) || ((!ret) && (tVrUx != tVrUh))) + { + kwStopTmr(gCb,(PTR)rbCb,KW_EVT_UMUL_REORD_TMR); + tmrRunning = FALSE; + } + } + + if (!tmrRunning) + { + if (KW_UM_GET_VALUE(*vrUh, KW_UMUL) > KW_UM_GET_VALUE(*vrUr, KW_UMUL)) + { + kwStartTmr(gCb,(PTR)rbCb,KW_EVT_UMUL_REORD_TMR); + *vrUx = *vrUh; + } + } + count++; + }/* end while count < pduCount */ +#ifdef LTE_L2_MEAS + kwUtlCalUlIpThrPutIncTTI(gCb, rbCb,ttiCnt); +#endif /* LTE_L2_MEAS */ + RETVOID; +} + +/** + * @brief Handler to reassemble the SDUs and send them to the upper layer. + * + * @details + * This function processes the received in-sequence PDU and + * re-assembles the SDUs and sends them to the upper layer. + * + * @param[in] gCb RLC Instance control block + * @param[in] rbCb RB control block + * @param[in] umRecBuf Reception Buffer to be Re-Assembled + * + * @return Void +*/ +#ifdef ANSI +PRIVATE Void kwUmmReAssembleSdus +( +KwCb *gCb, +KwUlRbCb *rbCb, +KwUmRecBuf *umRecBuf +) +#else +PRIVATE Void kwUmmReAssembleSdus(gCb,rbCb,umRecBuf) +KwCb *gCb; +KwUlRbCb *rbCb; +KwUmRecBuf *umRecBuf; +#endif +{ + U32 liCount; /* LI count */ + U32 count; /* Loop counter */ + U8 fi; /* Framing Info */ + U16 sn; /* Sequence Number of current PDU */ + MsgLen len; /* PDU Length */ + Buffer *sdu; /* SDU to be sent to upper layer */ + Buffer *remPdu; /* Remaining PDU */ + Buffer **partialSdu; /* Partial SDU */ + + TRC2(kwUmmReAssembleSdus) + + + liCount = umRecBuf->umHdr.numLi; + fi = umRecBuf->umHdr.fi; + sn = umRecBuf->umHdr.sn; + + for (count = 0; (count <= liCount);count++) + { + if (count < liCount ) + len = umRecBuf->umHdr.li[count]; + else + { + if (!(umRecBuf->pdu)) + { + RETVOID; + } + SFndLenMsg(umRecBuf->pdu,&len); + } + + /* get the sdu out of the pdu */ + SSegMsg(umRecBuf->pdu,len,&remPdu); + sdu = umRecBuf->pdu; + umRecBuf->pdu = remPdu; + + partialSdu = &(rbCb->m.umUl.partialSdu); + /* While re-assembling the SDUs, consider the first LI and perform + * the following steps. + -# If the first bit of FI(Framing Info of 2 bits) is set => + -# The current Data field in the PDU is a segment. + So form a SDU only if the + rbCb->m.um.umUl.partialSdu exists and the SNs are + in-sequence. + -# If there are no LIs and the second bit of LI is 1 + then a partial SDU is formed which would not be sent + to the upper layer. + -# else + -# If rbCb->partialSdu is not NULL then flush it off. + -# If LI count > 0 or LI count is 0 and second bit + of FI is not 1 + The SDU is complete.So send it to upper layer. + -# else + The SDU is partial and is placed + in rbCb->m.um.umUl.partialSdu; + */ + + if (0 == count ) + { + if (fi & 2) + { + if ((*partialSdu) && + (sn == ((rbCb->m.umUl.sn + 1) & rbCb->m.umUl.modBitMask))) + { + SCatMsg(*partialSdu,sdu,M1M2); + KW_FREE_BUF(sdu); + if (liCount > 0 || !(fi & 1)) + { + kwUtlSndDatInd(gCb,rbCb,*partialSdu); + *partialSdu = NULLP; + } + } + else + { + /* Partial Sdu stored is not valid now.So free it */ + if (*partialSdu) + { + KW_FREE_BUF(*partialSdu); + *partialSdu = NULLP; + } + + KW_FREE_BUF(sdu); + sdu = NULLP; + } + } + else + { + if (*partialSdu) + { + KW_FREE_BUF(*partialSdu); /* RLC mem leak fix */ + *partialSdu = NULLP; + } + + if (liCount > 0 || !( fi & 1)) + { + kwUtlSndDatInd(gCb,rbCb,sdu); + } + else + { + *partialSdu = sdu; + } + } + } + /* + If the SDU pointer has the last Data field of the PDU + -# If FI is 1,place the SDU in rbCb->m.um.umDl.partialSdu + -# else send the SDU to upper layer. + */ + else if (count == liCount) + { + if (fi & 1) + { + *partialSdu = sdu; + } + else + { + kwUtlSndDatInd(gCb, rbCb, sdu); + } + } + /* + If the LI is something other than the first one, + just send the SDU to the upper layer */ + else + { + kwUtlSndDatInd(gCb, rbCb, sdu); + } + } + rbCb->m.umUl.sn = sn; + + RETVOID; +} + +/** + * @brief Handler to process the re-establishment request received + * from the upper layer. + * + * @details + * This function does the following functions : + * - If direction of the RB is downlink : + * Remove all the SDUs in the SDU queue. + * - If direction of the RB is uplink : + * Call kwUmmReAssembleSdus() for each PDU with SN < VR(UH) + * + * @param[in] gCb RLC Instance control block + * @param[in] rlcID Identity of the RLC entity for which + * re-establishment is to be done + * @param[in] rbCb RB control block for which re-establishment + * is to be done + * + * @return Void +*/ +#ifdef ANSI +PUBLIC Void kwUmmUlReEstablish +( +KwCb *gCb, +CmLteRlcId *rlcId, +KwUlRbCb *rbCb +) +#else +PUBLIC Void kwUmmUlReEstablish(gCb, rlcId, rbCb) +KwCb *gCb; +CmLteRlcId *rlcId; +KwUlRbCb *rbCb; +#endif +{ + KwSn curSn; + KwSn vrUh; + KwUmRecBuf **recBuf; /* UM Reception Buffer */ + KwKwuSapCb *kwKwSap; /* KWU SAP Information */ + + TRC2(kwUmmUlReEstablish) + + + curSn = rbCb->m.umUl.vrUr; + vrUh = KW_UM_GET_VALUE(rbCb->m.umUl.vrUh,rbCb->m.umUl); + recBuf = rbCb->m.umUl.recBuf; + + if(TRUE == kwChkTmr(gCb,(PTR)rbCb,KW_EVT_UMUL_REORD_TMR)) + { + kwStopTmr(gCb,(PTR)rbCb,KW_EVT_UMUL_REORD_TMR); + } + + while (KW_UM_GET_VALUE(curSn,rbCb->m.umUl) < vrUh) + { + if ( recBuf[curSn] != NULLP ) + { + kwUmmReAssembleSdus(gCb,rbCb,recBuf[curSn]); + KW_FREE_WC(gCb,recBuf[curSn],sizeof(KwUmRecBuf)); + recBuf[curSn] = NULLP; + } + curSn = (curSn + 1) & rbCb->m.umUl.modBitMask; + } + rbCb->m.umUl.vrUr = 0; + rbCb->m.umUl.vrUh = 0; + rbCb->m.umUl.vrUx = 0; + + kwKwSap = gCb->u.ulCb->kwuUlSap + KW_UI_PDCP; + + /* In the UM Mode always send reestablish-indication to Upper Latyer*/ + KwUiKwuReEstCmpInd(&kwKwSap->pst, kwKwSap->suId, *rlcId); + + RETVOID; +} + +/** + * @brief Handler to extract the header from a PDU + * + * @details + * This function is used to extract the header of a PDU and store it + * along with the PDU buffer.The sequence number,framing info + * and LIs are extracted by this function. + * + * @param[in] gCb RLC Instance control block + * @param[in] rbCb Rb Control block for which the pdu is received + * @param[in] pdu PDU buffer + * @param[out] umHdr UM header to be filled after extraction + * + * @return S16 + * -# TRUE + * -# FALSE +*/ +#ifdef ANSI +PRIVATE S16 kwUmmExtractHdr +( +KwCb *gCb, +KwUlRbCb *rbCb, +Buffer *pdu, +KwUmHdr *umHdr +) +#else +PRIVATE S16 kwUmmExtractHdr(gCb, rbCb, pdu, umHdr) +KwCb *gCb; +KwUlRbCb *rbCb; +Buffer *pdu; +KwUmHdr *umHdr; +#endif +{ + U8 e; /* Extension Bit */ + Data dst[2]; /* Destination Buffer */ + S32 totalSz; /* Sum of LIs */ + MsgLen pduSz; /* PDU size */ +#if (ERRCLASS & ERRCLS_DEBUG) + S16 ret; /* Return Value */ +#endif + + TRC3(kwUmmExtractHdr) + + + SFndLenMsg(pdu,&pduSz); + + if ( rbCb->m.umUl.snLen == 1) + { +#if (ERRCLASS & ERRCLS_DEBUG) + ret = SRemPreMsg(dst,pdu); + if (ret != ROK) + { + RLOG_ARG2(L_ERROR,DBG_RBID,rbCb->rlcId.rbId, + "SRemPreMsg Failed for 5 bit SN UEID:%d CELLID:%d", + rbCb->rlcId.ueId, + rbCb->rlcId.cellId); + + RETVALUE(RFAILED); + } +#else + SRemPreMsg(dst,pdu); +#endif + pduSz--; + umHdr->sn = (dst[0]) & 0x1F; + umHdr->fi = (dst[0]) >> 6; + e = (dst[0]>>5) & 0x01; + } + else + { + /* snLen - sequnce length will be 10 bits requiring 2 bytes */ +#if (ERRCLASS & ERRCLS_DEBUG) + ret = SRemPreMsgMult(dst,2,pdu); + if (ret != ROK) + { + RLOG_ARG2(L_ERROR,DBG_RBID,rbCb->rlcId.rbId, + "SRemPreMsgMult Failed for 10 bits SN UEID:%d CELLID:%d", + rbCb->rlcId.ueId, + rbCb->rlcId.cellId); + RETVALUE(RFAILED); + } +#else + SRemPreMsgMult(dst,2,pdu); +#endif + pduSz -= 2; + + /* kw005.201 R9 Upgrade 3gpp spec 36.322 ver9.3.0 CR0082 * + * Removed the "if" condition for checking the reserved field * + * Added mask 0x03 for extracting the FI field. */ + + umHdr->fi = ( (dst[0] ) >> 3) & 0x03; + e = ( (dst[0] ) >> 2) & 0x01; + umHdr->sn = ( dst[0] & 0x03) << 8; + umHdr->sn |= dst[1]; + } + + umHdr->numLi = 0; + + totalSz = 0; + while(e && umHdr->numLi < KW_MAX_UL_LI ) + { +#if (ERRCLASS & ERRCLS_DEBUG) + ret = SRemPreMsgMult(dst,2,pdu); + if (ret != ROK) + { + RLOG_ARG2(L_ERROR,DBG_RBID,rbCb->rlcId.rbId, + "SRemPreMsgMult Failed UEID:%d CELLID:%d", + rbCb->rlcId.ueId, + rbCb->rlcId.cellId); + RETVALUE(RFAILED); + } +#else + SRemPreMsgMult(dst,2,pdu); +#endif + umHdr->li[umHdr->numLi] = ((dst[0]) & 0x7F) << 4; + umHdr->li[umHdr->numLi] |= dst[1] >> 4; + if ( 0 == umHdr->li[umHdr->numLi] ) + { + RLOG_ARG2(L_ERROR,DBG_RBID,rbCb->rlcId.rbId, + "Received LI as 0 UEID:%d CELLID:%d", + rbCb->rlcId.ueId, + rbCb->rlcId.cellId); + RETVALUE(RFAILED); + } + totalSz += umHdr->li[umHdr->numLi]; + if ( pduSz <= totalSz ) + { + RLOG_ARG3(L_ERROR,DBG_RBID,rbCb->rlcId.rbId, + "SN [%d]: UEID:%d CELLID:%d", + umHdr->sn, + rbCb->rlcId.ueId, + rbCb->rlcId.cellId); + RLOG_ARG4(L_ERROR,DBG_RBID,rbCb->rlcId.rbId, + "Corrupted PDU as TotSz[%lu] PduSz[%lu] UEID:%d CELLID:%d ", + totalSz, + pduSz, + rbCb->rlcId.ueId, + rbCb->rlcId.cellId); + RETVALUE(RFAILED); /* the situation where in the PDU size + is something that does not match with + the size in LIs*/ + } + umHdr->numLi++; + pduSz -= 2; + + e = ((dst[0]) & 0x80) >> 7; + + if ( e && umHdr->numLi < KW_MAX_UL_LI) + { + U8 tmp = ((dst[1]) & 0x08) >> 3; + umHdr->li[umHdr->numLi] = ( dst[1] & 0x07) << 8; + + +#if (ERRCLASS & ERRCLS_DEBUG) + ret = SRemPreMsg(dst,pdu); + if (ret != ROK) + { + RLOG_ARG2(L_ERROR,DBG_RBID,rbCb->rlcId.rbId, + "SRemPreMsg Failed UEID:%d CELLID:%d", + rbCb->rlcId.ueId, + rbCb->rlcId.cellId); + RETVALUE(RFAILED); + } +#else + SRemPreMsg(dst,pdu); +#endif + umHdr->li[umHdr->numLi] |= ( dst[0] ); /* The first byte lies in + the first 8 bits.We want + them in the last 8 bits */ + if ( 0 == umHdr->li[umHdr->numLi] ) + { + RLOG_ARG2(L_ERROR,DBG_RBID,rbCb->rlcId.rbId, + "Received LI as 0 UEID:%d CELLID:%d", + rbCb->rlcId.ueId, + rbCb->rlcId.cellId); + RETVALUE(RFAILED); + } + totalSz += umHdr->li[umHdr->numLi]; + pduSz--; + umHdr->numLi++; + + if (pduSz < totalSz) + { + RETVALUE(RFAILED); /* the situation where in the PDU size is + something that does not match with the + size in LIs*/ + } + + e = tmp; + } + } /* while(e && umHdr->numLi < KW_MAX_LI ) */ + if (e) + { + /* PDU was constructed with LIs that exceeded KW_MAX_LI */ + RETVALUE(RFAILED); + } + RETVALUE(ROK); +} + +/** + * @brief Handles expiry of re-ordering timer + * + * @param[in] gCb RLC Instance control block + * @param[in] rbCb Rb Control block for which re-order timer expired + * + * @return Void +*/ +#ifdef ANSI +PUBLIC Void kwUmmReOrdTmrExp +( +KwCb *gCb, +KwUlRbCb *rbCb +) +#else +PUBLIC Void kwUmmReOrdTmrExp(gCb, rbCb) +KwCb *gCb; +KwUlRbCb *rbCb; +#endif +{ + KwSn prevVrUr; /* prevVrUr */ + + TRC3(kwUmmReOrdTmrExp) + + + prevVrUr = KW_UMUL.vrUr; + + /* set VR(UR) to SN >= VR(UX) that has not been received */ + kwUmmFindNextVRUR(&KW_UMUL, KW_UMUL.vrUx); + + while (KW_UM_GET_VALUE(prevVrUr,KW_UMUL) < + KW_UM_GET_VALUE(KW_UMUL.vrUr,KW_UMUL)) + { + if (KW_UMUL.recBuf[prevVrUr]) + { + kwUmmReAssembleSdus(gCb, rbCb, KW_UMUL.recBuf[prevVrUr]); + if(KW_UMUL.recBuf[prevVrUr]->pdu != NULLP) /* RLC mem leak fix */ + { + KW_FREE_BUF(KW_UMUL.recBuf[prevVrUr]->pdu); + } + KW_FREE_WC(gCb, KW_UMUL.recBuf[prevVrUr], sizeof(KwUmRecBuf)); + KW_UMUL.recBuf[prevVrUr] = NULLP; + } + + prevVrUr = (prevVrUr + 1) & rbCb->m.umUl.modBitMask; + } + + if (KW_UM_GET_VALUE(KW_UMUL.vrUh, KW_UMUL) > + KW_UM_GET_VALUE(KW_UMUL.vrUr, KW_UMUL)) + { + kwStartTmr(gCb,(PTR)rbCb,KW_EVT_UMUL_REORD_TMR); + KW_UMUL.vrUx = KW_UMUL.vrUh; + } +} + +/** + * @brief + * Function to release/free the UnAcknowledged Mode Module RbCb buffers + * + * @details + * This primitive Frees the UM RbCb transmission Buffer, retransmission + * Buffer and reciption Buffers + * + * @param [in] gCb - RLC instance Control Block + * @param [in] rbCb - RB Control Block + * + * @return void + */ + +#ifdef ANSI +PUBLIC Void kwUmmFreeUlRbCb +( +KwCb *gCb, +KwUlRbCb *rbCb +) +#else +PUBLIC Void kwUmmFreeUlRbCb(gCb,rbCb) +KwCb *gCb; +KwUlRbCb *rbCb; +#endif +{ + KwSn curSn = 0; /* sequence number of PDU */ + KwSn windSz; /* PDU window size */ + KwUmRecBuf **umRecBuf; /* UM module receive buffer */ + + TRC2(kwUmmFreeUlRbCb) + + + windSz = rbCb->m.umUl.umWinSz << 1; + + umRecBuf = rbCb->m.umUl.recBuf; + + if(TRUE == kwChkTmr(gCb,(PTR)rbCb,KW_EVT_UMUL_REORD_TMR)) + { + kwStopTmr(gCb,(PTR)rbCb,KW_EVT_UMUL_REORD_TMR); + } + while (curSn < windSz) + { + if (umRecBuf[curSn] != NULLP) + { + KW_FREE_BUF_WC(umRecBuf[curSn]->pdu); + umRecBuf[curSn]->pdu = NULLP; + + KW_FREE_WC(gCb, umRecBuf[curSn], sizeof(KwUmRecBuf)); + umRecBuf[curSn] = NULLP; + } + curSn++; + } + KW_FREE_WC(gCb,rbCb->m.umUl.recBuf, (windSz ) * sizeof(KwUmRecBuf*)); + rbCb->m.umUl.recBuf = NULLP; + RETVOID; +} + + +/********************************************************************30** + End of file +**********************************************************************/ diff --git a/src/5gnrrlc/kw_utl_dl.c b/src/5gnrrlc/kw_utl_dl.c new file mode 100755 index 000000000..351225ab8 --- /dev/null +++ b/src/5gnrrlc/kw_utl_dl.c @@ -0,0 +1,2477 @@ +/******************************************************************************* +################################################################################ +# Copyright (c) [2017-2019] [Radisys] # +# # +# 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. # +################################################################################ +*******************************************************************************/ + +/********************************************************************** + + Name: LTE-RLC Layer + + Type: C file + + Desc: Source code for RLC Utility Module + This file contains following functions + + --kwUtlSndToLi + --kwUtlRcvFrmLi + --kwUtlEmptySduQ + --kwUtlSndDStaRsp + --kwUtlSndDatInd + --kwUtlShutDown + + File: kw_utl_dl.c + +**********************************************************************/ +static const char* RLOG_MODULE_NAME="UTL"; +static int RLOG_MODULE_ID=2048; +static int RLOG_FILE_ID=209; + +/** @file kw_utl_dl.c +@brief RLC Utility Module +*/ + +/* header (.h) include files */ +#include "envopt.h" /* environment options */ +#include "envdep.h" /* environment dependent */ +#include "envind.h" /* environment independent */ +/* kw005.201 added support for L2 Measurement */ +#ifdef LTE_L2_MEAS +#include +#endif +#include +#include "gen.h" /* general */ +#include "ssi.h" /* system services */ +#include "cm5.h" /* common timer defines */ +#include "cm_tkns.h" /* common tokens defines */ +#include "cm_mblk.h" /* common memory allocation library defines */ +#include "cm_llist.h" /* common link list defines */ +#include "cm_hash.h" /* common hash list defines */ +#include "cm_lte.h" /* common LTE defines */ +#include "ckw.h" /* CKW defines */ +#include "kwu.h" /* CKW defines */ +#include "lkw.h" /* LKW defines */ +#include "rgu.h" /* RGU defiens */ + +#include "kw_env.h" /* RLC environment options */ +#include "kw.h" /* RLC defines */ +#include "kw_err.h" /* Error defines */ +#include "kw_udx.h" +#include "kw_dl.h" + +/* extern (.x) include files */ +#include "gen.x" /* general */ +#include "ssi.x" /* system services */ + +#include "cm5.x" /* common timer library */ +#include "cm_tkns.x" /* common tokens */ +#include "cm_mblk.x" /* common memory allocation */ +#include "cm_llist.x" /* common link list */ +#include "cm_hash.x" /* common hash list */ +#include "cm_lte.x" /* common LTE includes */ +#include "cm_lib.x" /* common memory allocation library */ +#include "ckw.x" /* CKW includes */ +#include "kwu.x" /* KWU includes */ +#include "lkw.x" /* LKW inlcudes */ +#include "rgu.x" /* RGU includes */ + +#include "kw.x" /* RLC includes */ +#include "kw_udx.x" /* UDX interface includes */ +#include "kw_dl.x" /* RLC downlink includes */ + +#include "ss_rbuf.h" +#include "ss_rbuf.x" + +EXTERN SsRngBufCnt rngCb; + +#if (defined(MAC_RLC_HARQ_STA_RBUF) && defined(LTE_L2_MEAS)) +extern U32 isDatReqProcessed; +#endif +#define KW_MODULE (KW_DBGMASK_DUT | KW_DBGMASK_DL) /* for debugging purpose */ +#if (defined(MAC_RLC_HARQ_STA_RBUF) && defined(LTE_L2_MEAS)) || defined (SS_RBUF) +EXTERN void kwUtlDlBatchProcHqStaInd ARGS ((Void)); +#endif +Void ResetRLCStats(Void) +{ + KwCb* dlInst = kwCb[1]; + KwCb* ulInst = kwCb[0]; + cmMemset((U8*)&gRlcStats, 0, sizeof(RLCStats)); + cmMemset((U8*)&dlInst->genSts,0,sizeof(KwGenSts)); + cmMemset((U8*)&ulInst->genSts,0,sizeof(KwGenSts)); +} + +#ifndef ALIGN_64BIT +Void PrintRLCStats(Void) +{ + KwCb* dlInst = kwCb[1]; + KwCb* ulInst = kwCb[0]; + + RLOG4(L_ALWAYS,"RLC Stats: PDUs Sent = (%ld), PdusRext = (%ld), TimeOut = (%ld), SduDiscarded = (%ld)", + dlInst->genSts.pdusSent, + dlInst->genSts.pdusRetx, + dlInst->genSts.protTimeOut, + dlInst->genSts.numSduDisc); + RLOG3(L_ALWAYS,"RLC Stats: PDUs Rcvd = (%ld), unexpPdus = (%ld), errorPdus = (%ld)", + ulInst->genSts.pdusRecv, + ulInst->genSts.unexpPdusRecv, + ulInst->genSts.errorPdusRecv); + RLOG4(L_ALWAYS,"RLC Stats: AMDL: " + "StaPduSent:%lu NacksInStaPdu:%lu BytesUnused:%lu PollTimerExpires SRB:%lu ", + gRlcStats.amRlcStats.numDLStaPduSent, gRlcStats.amRlcStats.numDLNacksInStaPdu, + gRlcStats.amRlcStats.numDLBytesUnused, gRlcStats.amRlcStats.numDLPollTimerExpiresSrb); + RLOG3(L_ALWAYS,"RLC Stats: AMDL: " + "DRB:%lu MaxRetx:%lu RetransPdus:%lu", + gRlcStats.amRlcStats.numDLPollTimerExpiresDrb, gRlcStats.amRlcStats.numDLMaxRetx, + gRlcStats.amRlcStats.numDLRetransPdus); + RLOG4(L_ALWAYS,"RLC Stats: AMUL: " + " PdusDiscarded:%lu ReOrdTimerExpires:%lu StaPduRcvd:%lu NackInStaPduRcvd:%lu ", + gRlcStats.amRlcStats.numULPdusDiscarded, gRlcStats.amRlcStats.numULReOrdTimerExpires, + gRlcStats.amRlcStats.numULStaPduRcvd, gRlcStats.amRlcStats.numULNackInStaPduRcvd); + + RTLIN_DUMP_DEBUG("RLC Stats: PDUs Sent = (%ld), PdusRext = (%ld), TimeOut = (%ld), SduDiscarded = (%ld)\n", + dlInst->genSts.pdusSent, + dlInst->genSts.pdusRetx, + dlInst->genSts.protTimeOut, + dlInst->genSts.numSduDisc); + RTLIN_DUMP_DEBUG("RLC Stats: PDUs Rcvd = (%ld), unexpPdus = (%ld), errorPdus = (%ld)\n", + ulInst->genSts.pdusRecv, + ulInst->genSts.unexpPdusRecv, + ulInst->genSts.errorPdusRecv); + RTLIN_DUMP_DEBUG("RLC Stats:" + "AMDL: StaPduSent:%lu NacksInStaPdu:%lu BytesUnused:%lu PollTimerExpires SRB:%lu DRB:%lu MaxRetx:%lu RetransPdus:%lu \n" + "AMUL: PdusDiscarded:%lu ReOrdTimerExpires:%lu StaPduRcvd:%lu NackInStaPduRcvd:%lu \n", + gRlcStats.amRlcStats.numDLStaPduSent, gRlcStats.amRlcStats.numDLNacksInStaPdu, gRlcStats.amRlcStats.numDLBytesUnused, + gRlcStats.amRlcStats.numDLPollTimerExpiresSrb, gRlcStats.amRlcStats.numDLPollTimerExpiresDrb, gRlcStats.amRlcStats.numDLMaxRetx, + gRlcStats.amRlcStats.numDLRetransPdus, gRlcStats.amRlcStats.numULPdusDiscarded, gRlcStats.amRlcStats.numULReOrdTimerExpires, + gRlcStats.amRlcStats.numULStaPduRcvd, gRlcStats.amRlcStats.numULNackInStaPduRcvd); +} +#else +Void PrintRLCStats(Void) +{ + KwCb* dlInst = kwCb[1]; + KwCb* ulInst = kwCb[0]; + + printf ("\n================================ RLC STATS ===========================\n"); + RLOG4(L_ALWAYS,"RLC Stats: PDUs Sent = (%ld), PdusRext = (%ld), TimeOut = (%ld), SduDiscarded = (%ld)", + dlInst->genSts.pdusSent, + dlInst->genSts.pdusRetx, + dlInst->genSts.protTimeOut, + dlInst->genSts.numSduDisc); + RLOG3(L_ALWAYS,"RLC Stats: PDUs Rcvd = (%ld), unexpPdus = (%ld), errorPdus = (%ld)", + ulInst->genSts.pdusRecv, + ulInst->genSts.unexpPdusRecv, + ulInst->genSts.errorPdusRecv); + RLOG4(L_ALWAYS,"RLC Stats: AMDL: " + "StaPduSent:%lu NacksInStaPdu:%lu BytesUnused:%lu PollTimerExpires SRB:%lu ", + gRlcStats.amRlcStats.numDLStaPduSent, gRlcStats.amRlcStats.numDLNacksInStaPdu, + gRlcStats.amRlcStats.numDLBytesUnused, gRlcStats.amRlcStats.numDLPollTimerExpiresSrb); + RLOG3(L_ALWAYS,"RLC Stats: AMDL: " + "DRB:%lu MaxRetx:%lu RetransPdus:%lu", + gRlcStats.amRlcStats.numDLPollTimerExpiresDrb, gRlcStats.amRlcStats.numDLMaxRetx, + gRlcStats.amRlcStats.numDLRetransPdus); + RLOG4(L_ALWAYS,"RLC Stats: AMUL: " + " PdusDiscarded:%lu ReOrdTimerExpires:%lu StaPduRcvd:%lu NackInStaPduRcvd:%lu ", + gRlcStats.amRlcStats.numULPdusDiscarded, gRlcStats.amRlcStats.numULReOrdTimerExpires, + gRlcStats.amRlcStats.numULStaPduRcvd, gRlcStats.amRlcStats.numULNackInStaPduRcvd); + /* RTLIN_DUMP_DEBUG("AM RLC Stats:" + "AMDL: SDUs Tx :(%u) SDU Bytes Tx :(%u) SDUs Retx :(%u) MaxRetx:(%u) WindowStalls: (%u) \n" + "AMUL: DropOutWinRx :(%u) SDUs Rx :(%u) SDU Bytes Rx :(%u) SDUNack Rx :(%u) Duplicate Pdu Rx :(%u) \n", + gRlcStats.amRlcStats.numRlcAmCellSduTx, gRlcStats.amRlcStats.numRlcAmCellSduBytesTx, + gRlcStats.amRlcStats.numRlcAmCellRetxPdu, gRlcStats.amRlcStats.numRlcAmMaxRetx, gRlcStats.amRlcStats.numRlcAmCellWinStall, + gRlcStats.amRlcStats.numRlcAmCellDropOutWinRx, gRlcStats.amRlcStats.numRlcAmCellSduRx, + gRlcStats.amRlcStats.numRlcAmCellSduBytesRx, gRlcStats.amRlcStats.numRlcAmCellNackRx, gRlcStats.amRlcStats.numRlcAmCellDupPduRx); +*/ + RTLIN_DUMP_DEBUG("RLC Stats: PDUs Sent = (%d), PdusRext = (%d), TimeOut = (%d), SduDiscarded = (%d)\n", + dlInst->genSts.pdusSent, + dlInst->genSts.pdusRetx, + dlInst->genSts.protTimeOut, + dlInst->genSts.numSduDisc); + RTLIN_DUMP_DEBUG("RLC Stats: PDUs Rcvd = (%d), unexpPdus = (%d), errorPdus = (%d)\n", + ulInst->genSts.pdusRecv, + ulInst->genSts.unexpPdusRecv, + ulInst->genSts.errorPdusRecv); + RTLIN_DUMP_DEBUG("AMDL: StaPduSent:%u NacksInStaPdu:%u BytesUnused:%u PollTimerExpires SRB:%u DRB:%u MaxRetx:%u RetransPdus:%u \n" + " SDUs Tx :(%u) SDU Bytes Tx :(%u) SDUs Retx :(%u) WindowStalls: (%u) \n" + + "AMUL: PdusDiscarded:%u ReOrdTimerExpires:%u StaPduRcvd:%u NackInStaPduRcvd:%u \n" + " DropOutWinRx :(%u) SDUs Rx :(%u) SDU Bytes Rx :(%u) SDUNack Rx :(%u) Duplicate Pdu Rx:(%u) \n", + gRlcStats.amRlcStats.numDLStaPduSent, gRlcStats.amRlcStats.numDLNacksInStaPdu, gRlcStats.amRlcStats.numDLBytesUnused, + gRlcStats.amRlcStats.numDLPollTimerExpiresSrb, gRlcStats.amRlcStats.numDLPollTimerExpiresDrb, + gRlcStats.amRlcStats.numDLMaxRetx, gRlcStats.amRlcStats.numDLRetransPdus, + gRlcStats.amRlcStats.numRlcAmCellSduTx, gRlcStats.amRlcStats.numRlcAmCellSduBytesTx, + gRlcStats.amRlcStats.numRlcAmCellRetxPdu, gRlcStats.amRlcStats.numRlcAmCellWinStall, + gRlcStats.amRlcStats.numULPdusDiscarded, gRlcStats.amRlcStats.numULReOrdTimerExpires, + gRlcStats.amRlcStats.numULStaPduRcvd, gRlcStats.amRlcStats.numULNackInStaPduRcvd, + gRlcStats.amRlcStats.numRlcAmCellDropOutWinRx, gRlcStats.amRlcStats.numRlcAmCellSduRx, + gRlcStats.amRlcStats.numRlcAmCellSduBytesRx, gRlcStats.amRlcStats.numRlcAmCellNackRx, gRlcStats.amRlcStats.numRlcAmCellDupPduRx); +} +#endif + +/** + * + * @brief + * Handler for sending the data to multiple logical channels of a UE + * + * @details: + * This function sends the data for one or more logical channels + * after processing the SDUs and forming the PDUs.It calls + * UMM or AMM functions to form the PDUs for the requested sizes + * by MAC. + * + * @param[in] gCb RLC instance Control block + * @param[in] staIndInfo Status Indication Information containing the + * size of PDU(s) for one or more logical channels + * + * @return S16 + * -# ROK + * -# RFAILED + * + */ +#ifdef ANSI +PUBLIC S16 kwUtlSndToLi +( +KwCb *gCb, +SuId suId, +KwDStaIndInfo *staIndInfo +) +#else +PUBLIC S16 kwUtlSndToLi(gCb, suId, staIndInfo) +KwCb *gCb; +SuId suId; +KwDStaIndInfo *staIndInfo; +#endif +{ + KwDlUeCb *ueCb; /* UE control block */ + U32 count; /* Loop Counter */ + U32 numTb; /* Number of Tbs */ + KwDlRbCb *rbCb; /* RB Control Block */ + KwDatReq datReq; /* PDUs Information */ + RguDDatReqInfo *datReqInfo; /* Data Request Information */ + KwRguSapCb *rguSap; /* MAC SAP CB */ + U32 totNumPdu; /* Total number of PDUS */ + RguStaIndTb *staIndTb = NULLP; + RguDatReqTb *datReqTb = NULLP; + RguDStaIndPerUe *staInd = NULLP; +#ifdef LTE_L2_MEAS + U32 grantPerLch[RGU_MAX_LC] = {0}; +#endif +/* kw005.201 added support for L2 Measurement */ +#ifdef LTE_L2_MEAS_LOSS_DELAY + U8 snIdx1; + U8 snIdx2; +#endif /* LTE_L2_MEAS */ + U32 idx; + +//Debug + U32 staIndSz=0,datIndSz = 0; + TRC2(kwUtlSndToLi) + + + datReqInfo = NULLP; + KW_ALLOC_SHRABL_BUF(gCb->u.dlCb->rguDlSap->pst.region, + gCb->u.dlCb->rguDlSap->pst.pool, + datReqInfo,sizeof(RguDDatReqInfo)); +#if (ERRCLASS & ERRCLS_ADD_RES) + if ( datReqInfo == NULLP ) + { + RLOG_ARG0(L_FATAL,DBG_CELLID,staIndInfo->cellId, + "Memory allocation failed"); + RETVALUE(RFAILED); + } +#endif /* ERRCLASS & ERRCLS_ADD_RES */ + for(idx = 0; idx < staIndInfo->nmbOfUeGrantPerTti; idx++) + { + staInd = &staIndInfo->staInd[idx]; + /* Fetch Ue control block */ + if(ROK != kwDbmFetchDlUeCb(gCb,staInd->rnti,staIndInfo->cellId,&ueCb)) + { + /* Fetch UeCb failed */ + RLOG_ARG1(L_ERROR, DBG_CELLID,staIndInfo->cellId, + "UeId[%u]:ueCb not found", + staInd->rnti); + /* If ueCb is not found for current rnti then continue to look for next rnti*/ + continue; + } + /* kw002.201 Removed the allocation of KwDatReq */ + /* kw004.201 Used SSI function to initialize the variable */ + cmMemset( (U8 *)&datReq, 0, sizeof(KwDatReq) ); + totNumPdu = 0; + for (numTb = 0; numTb < staInd->nmbOfTbs; numTb++) + { + staIndTb = &(staInd->staIndTb[numTb]); + datReqTb = &(datReqInfo->datReq[idx].datReqTb[numTb]); +#ifdef LTE_L2_MEAS + ueCb->tbIdx = (ueCb->tbIdx+1) % KW_MAX_TB_PER_UE; +#endif + for (count = 0;count < staIndTb->nmbLch; count++) + { +#ifdef LTE_L2_MEAS + /*Calculate the total grant size from MAC */ + if((staIndTb->lchStaInd[count].lcId >= RGU_MAX_LC) + || (staIndTb->lchStaInd[count].lcId == 0)) + { + /* TODO : Need to figure out why this is happening */ + break; + } + else + { + grantPerLch[staIndTb->lchStaInd[count].lcId] += staIndTb->lchStaInd[count].totBufSize; + } +#endif + rbCb = ueCb->lCh[staIndTb->lchStaInd[count].lcId - 1].dlRbCb; + + if (rbCb && (!kwDlUtlIsReestInProgress(rbCb))) + { +//Debug + staIndSz += staIndTb->lchStaInd[count].totBufSize; + datReq.pduSz = staIndTb->lchStaInd[count].totBufSize; +#ifdef LTE_L2_MEAS + datReq.totMacGrant = grantPerLch[staIndTb->lchStaInd[count].lcId]; +#endif + kwUtlGetCurrTime(&datReq.boRep.oldestSduArrTime); + if ( CM_LTE_MODE_UM == rbCb->mode ) + { + kwUmmProcessSdus(gCb,rbCb,&datReq); + } + else if ( CM_LTE_MODE_AM == rbCb->mode ) + { + kwAmmProcessSdus(gCb,rbCb,&datReq,staInd->fillCtrlPdu); + } +#ifdef LTE_L2_MEAS + grantPerLch[staIndTb->lchStaInd[count].lcId] = datReq.totMacGrant; +#endif + if ( 0 == datReq.pduInfo.numPdu ) + { + continue; + } + totNumPdu += datReq.pduInfo.numPdu; + cmMemcpy((U8 *)(&(datReqTb->lchData[count].pdu)), + (U8 *)(&(datReq.pduInfo)),sizeof(KwPduInfo)); + +//Debug + U8 numPdu = 0; + for (;numPdu < datReqTb->lchData[count].pdu.numPdu ; numPdu ++) + { + MsgLen len = 0; + SFndLenMsg(datReqTb->lchData[count].pdu.mBuf[numPdu],&len); + datIndSz += len; + } + datReqTb->lchData[count].setMaxUlPrio = FALSE; + if (KW_AM_IS_POLL_BIT_SET(AMDL) && + (AMDL.sduQ.count > 1)) + { + /* Poll bit is set indicate to MAC*/ + datReqTb->lchData[count].setMaxUlPrio = TRUE; + } + datReqTb->lchData[count].boReport.bo = datReq.boRep.bo; + +#ifdef CCPU_OPT + datReqTb->lchData[count].boReport.estRlcHdrSz = + datReq.boRep.estHdrSz; + datReqTb->lchData[count].boReport.staPduPrsnt = + datReq.boRep.staPduPrsnt; +#endif /* CCPU_OPT */ + datReqTb->lchData[count].boReport.staPduBo = + datReq.boRep.staPduBo; + datReqTb->lchData[count].lcId = staIndTb->lchStaInd[count].lcId; + +#ifdef L2_OPTMZ + /* Set if Bearer is UM */ + if ( CM_LTE_MODE_UM == rbCb->mode ) + { + datReqTb->lchData[count].freeBuff = TRUE; + } + else + { + datReqTb->lchData[count].freeBuff = FALSE; + } +#endif + + /* kw005.201 added support for L2 Measurement */ +#ifdef LTE_L2_MEAS_LOSS_DELAY + datReqTb->rguSnInfo->lchMap[count].lChId = + staIndTb->lchStaInd[count].lcId; + /* In some cases L2 Measurement for few of the lcId may be off, + * in this case we are assigning snList to 0xffff + */ + for(snIdx1 = 0; snIdx1 < RGU_MAX_PDU; snIdx1++) + { + datReqTb->rguSnInfo->lchMap[count].snList[snIdx1] = 0xffff; + } + if(tbSnMap->numSn != 0) + { + snIdx2 = 0; + for(snIdx1=tbSnMap->prevNumSn;snIdx1 < tbSnMap->numSn;snIdx1++) + { + datReqTb->rguSnInfo->lchMap[count].snList[snIdx2++] = + tbSnMap->snSduMap[snIdx1].sn; + } + tbSnMap->prevNumSn = tbSnMap->numSn; + } +#endif + datReqTb->lchData[count].boReport.oldestSduArrTime = + datReq.boRep.oldestSduArrTime; + /* kw004.201 Used SSI function to initialize the variable */ + cmMemset( (U8 *)&datReq, 0, sizeof(KwDatReq) ); + } + } +#ifdef LTE_L2_MEAS + if(ueCb->l2MeasTbCb[ueCb->tbIdx]!= NULLP) + { + datReqTb->tbId = ueCb->tbIdx; + } + else + { + datReqTb->tbId = KW_INVALID_TBID; + } +#endif + datReqTb->nmbLch = staIndTb->nmbLch; + /*adding the check to make sure that lcId is not sent as 0 + * when no data is there in datReq */ + if ( 0 == totNumPdu ) + { + datReqTb->lchData[0].lcId = staIndTb->lchStaInd[0].lcId; + } + /* kw005.201 added support for L2 Measurement */ +#ifdef LTE_L2_MEAS_LOSS_DELAY + if(tbSnMap->numSn == 0) + { + KW_FREE(tbSnMap,sizeof(KwTbSnMap)); + KW_FREE(datReqTb->rguSnInfo,sizeof(RguSnMapInfo)); + datReqTb->rguSnInfo = NULLP; + kwCb.kwL2Cb.curTbSnMap = NULLP; + datReqTb->snMapPres = FALSE; + } + else + { + cmHashListInsert(&(kwCb.kwL2Cb.tbHlCp),(PTR)tbSnMap, + (U8 *) &(tbSnMap->tbId), (U16)sizeof(tbSnMap->tbId)); + kwCb.kwL2Cb.curTbSnMap = NULLP; + } +#endif /* LTE_L2_MEAS */ + } + datReqInfo->datReq[idx].nmbOfTbs = staInd->nmbOfTbs; + datReqInfo->datReq[idx].transId = staInd->transId; + datReqInfo->datReq[idx].rnti = staInd->rnti; + } + datReqInfo->cellId = staIndInfo->cellId; + datReqInfo->nmbOfUeGrantPerTti = staIndInfo->nmbOfUeGrantPerTti; + /* If trace flag is enabled send the trace indication */ + if(TRUE == gCb->init.trc ) + { + /* Populate the trace params */ + kwLmmSendTrc(gCb,EVTRGUDDATREQ, NULLP); + } + + rguSap = &(gCb->u.dlCb->rguDlSap[suId]); +//Debug + KwLiRguDDatReq(&rguSap->pst,rguSap->spId,datReqInfo); + RETVALUE(ROK); +} + +/** + * + * @brief + * Handler for sending Status Response to MAC. + * + * @detail: + * This function is used by RLC entity for sending + * status response to MAC after receiving a SDU from + * PDCP. + * + * @param[in] gCb RLC instance Control block + * @param[in] rbCb Radio Bearer Control Block + * @param[in] bo Buffer Occupancy + * @param[in] estHdrSz Estimated Header Size + * @param[in] staPduPrsnt Status PDU present or not + * + * @return S16 + * -# ROK + * -# RFAILED + */ +#ifdef ANSI +PUBLIC S16 kwUtlSndDStaRsp +( +KwCb *gCb, +KwDlRbCb *rbCb, +S32 bo, +S32 estHdrSz, +Bool staPduPrsnt, +U32 staPduBo +) +#else +PUBLIC S16 kwUtlSndDStaRsp(gCb,rbCb,bo,estHdrSz,staPduPrsnt,staPduBo) +KwCb *gCb; +KwDlRbCb *rbCb; +S32 bo; +S32 estHdrSz; +Bool staPduPrsnt; +U32 staPduBo; +#endif +{ + RguDStaRspInfo staRspInfo; /* Status Response Information */ + KwRguSapCb *rguSap; /* MAC SAP Information */ + TRC3(kwUtlSndDStaRsp) +#ifndef TENB_ACC + if ((rbCb->lastRprtdBoToMac > (U32)8000) && (rbCb->boUnRprtdCnt < (U32)5) + && (!staPduPrsnt) && ((CM_LTE_MODE_AM == rbCb->mode ) && (AMDL.nxtRetx == NULLP))) + { + rbCb->boUnRprtdCnt++; + RETVALUE(ROK); + } +#endif + + rguSap = &(gCb->u.dlCb->rguDlSap[rbCb->rguSapId]); + +#ifdef CCPU_OPT + staRspInfo.boReport.estRlcHdrSz = estHdrSz; + staRspInfo.boReport.staPduPrsnt = staPduPrsnt; +#endif +#ifdef LTE_ADV + staRspInfo.boReport.staPduBo = staPduBo; +#endif + rbCb->boUnRprtdCnt = (U32)0; + rbCb->lastRprtdBoToMac = (U32)bo; + staRspInfo.boReport.bo = bo; + staRspInfo.cellId = rbCb->rlcId.cellId; + staRspInfo.rnti = rbCb->rlcId.ueId; + staRspInfo.lcId = rbCb->lch.lChId; + if ( CM_LTE_MODE_UM == rbCb->mode && (rbCb->m.umDl.sduQ.count > 0)) + { + staRspInfo.boReport.oldestSduArrTime = + ((KwSdu *)(rbCb->m.umDl.sduQ.first->node))->arrTime; + } + else if ( CM_LTE_MODE_AM == rbCb->mode ) + { + if (rbCb->m.amDl.nxtRetx != NULLP) + { + staRspInfo.boReport.oldestSduArrTime = rbCb->m.amDl.nxtRetx->sduMap.sdu->arrTime; + } + else if (rbCb->m.amDl.nxtTx != NULLP) + { + staRspInfo.boReport.oldestSduArrTime = AMDL.nxtTx->arrTime; + } + else + { + kwUtlGetCurrTime(&staRspInfo.boReport.oldestSduArrTime); + } + } + /* If trace flag is enabled send the trace indication */ + if(gCb->init.trc == TRUE) + { + /* Populate the trace params */ + kwLmmSendTrc(gCb,EVTRGUDSTARSP, NULLP); + } + /* Send Status Response to MAC layer */ + KwLiRguDStaRsp(&rguSap->pst,rguSap->spId,&staRspInfo); + + + RETVALUE(ROK); +} + +/** + * + * @brief + * Handler for emptying the SDU queue. + * + * @detail: + * This function is used to empty the SDU queue when + * a re-establishment request is received from the + * upper layer. + * + * @param[in] gCb RLC instance control block + * @param[in] rbCb Radio bearer control block + * @param[in] sduQ SDU queue to be emptied + * + * @return Void + */ +/* kw005.201 added support for L2 Measurement */ +#ifdef LTE_L2_MEAS_RLC +#ifdef ANSI +PUBLIC Void kwUtlEmptySduQ +( +KwCb *gCb, +KwDlRbCb *rbCb, +CmLListCp *sduQ +) +#else +PUBLIC Void kwUtlEmptySduQ(gCb,rbCb, sduQ) +KwCb *gCb; +KwDlRbCb *rbCb; +CmLListCp *sduQ; +#endif +#else +#ifdef ANSI +PUBLIC Void kwUtlEmptySduQ +( +KwCb *gCb, +CmLListCp *sduQ +) +#else +PUBLIC Void kwUtlEmptySduQ(gCb,sduQ) +KwCb *gCb; +CmLListCp *sduQ; +#endif +#endif +{ +#ifdef LTE_L2_MEAS_RLC + CmLListCp *sduSnMapQ; /* SDU Sequence number map queue */ + CmLList *firstSduSnMap; /* First Node in SDU SnMap Queue */ + KwSduSnMap *sduSnMap; /* SDU Sn Map */ + + TRC2(kwUtlEmptySduQ) + sduSnMapQ = NULLP; + firstSduSnMap = NULLP; + sduSnMap = NULLP; + + + sduSnMapQ = &rbCb->sduSnMapQ; + CM_LLIST_FIRST_NODE(sduSnMapQ, firstSduSnMap); + + while(firstSduSnMap) + { + sduSnMap = (KwSduSnMap *)firstSduSnMap->node; + if(sduSnMap != NULLP) + { + cmLListDelFrm(&(rbCb->sduSnMapQ), &(sduSnMap->lstEnt)); + KW_FREE(sduSnMap, sizeof(KwSduSnMap)); + CM_LLIST_FIRST_NODE(sduSnMapQ, firstSduSnMap); + } + else + { + CM_LLIST_NEXT_NODE(sduSnMapQ, firstSduSnMap); + } + } +#endif + RETVOID; +} + +/** + * + * @brief + * Handler for calculating the Length Indicator (LI) length for a SDU + * + * @detail: + * This function is used to calculate the LI (Length Indicator) length + * which has to be substracted from the pduSize to correctly match the + * formed PDU(s) size with the size requested by MAC. + * + * @param[in] gCb RLC instance control block + * @param[in] numLi Number of LIs already present + * @param[in] msgLen Size of the SDU + * @param[in/out] pduSz Size of the pDU to be formed + * + * @return void + */ +#ifdef ANSI +PUBLIC Void kwUtlCalcLiForSdu +( +KwCb *gCb, +U16 numLi, +MsgLen msgLen, +S16 *pduSz +) +#else +PUBLIC Void kwUtlCalcLiForSdu(gCb,numLi,msgLen,pduSz) +KwCb *gCb; +U16 numLi; +MsgLen msgLen; +S16 *pduSz; +#endif +{ + TRC2(kwUtlCalcLiForSdu) + + if ( (*pduSz > msgLen) && (msgLen < KW_2K_BYTE)) + { + if(0 == (numLi & KW_BIT0)) /* check if number of LIs are odd or even */ + { + /* if number of LI's are even 2 bytes needed */ + *pduSz -= 2; + } + else + { + /* if number of LI's are odd one byte needed */ + *pduSz -= 1; + } + } + RETVOID; +} + +/** + * + * @brief + * Function to set that re-establishment has started for an RB + * + * @detail: + * This function is used to set the reestInProgress flag to TRUE. + * This also sets the estimated header size to 0 and sends bo as + * 0 to MAC so that RLC does not need to transmit any data. + * If the poll re-transmit timer is running for the RB; + * it is stopped + * + * @param[in] gCb RLC instance control block + * @param[in] rbCb RB for which re-establishment has started + * + * @return void + */ +#ifdef ANSI +PUBLIC Void kwDlUtlSetReestInProgressForRB +( +KwCb *gCb, +KwDlRbCb *rbCb +) +#else +PUBLIC Void kwDlUtlSetReestInProgressForRB(gCb,rbCb) +KwCb *gCb; +KwDlRbCb *rbCb; +#endif +{ + TRC2(kwDlUtlSetReestInProgressForRB) + + rbCb->reestInProgress = TRUE; + + if(rbCb->mode == CM_LTE_MODE_AM ) + { + rbCb->m.amDl.estHdrSz = 0; + + if(kwChkTmr(gCb, (PTR)rbCb, KW_EVT_AMDL_POLL_RETX_TMR)) + { + kwStopTmr(gCb, (PTR)rbCb, KW_EVT_AMDL_POLL_RETX_TMR); + } + } + else + { + rbCb->m.umDl.estHdrSz= 0; + } + + kwUtlSndDStaRsp(gCb, rbCb, 0, 0, FALSE,0); + + RETVOID; +} + +/** + * + * @brief + * Function to check if re-establishment is ongoing for an RB + * + * @param[in] rbCb RB for which re-establishment is to be checked + * + * @return Bool + * TRUE : Re-establishment is in progress + * FALSE : Re-establishment is not in progress + */ +#ifdef ANSI +PUBLIC Bool kwDlUtlIsReestInProgress +( +KwDlRbCb *rbCb +) +#else +PUBLIC Bool kwDlUtlIsReestInProgress(rbCb) +KwDlRbCb *rbCb; +#endif +{ + TRC2(kwDlUtlSetReestInProgressForRB) + + RETVALUE(rbCb->reestInProgress); +} + +/** + * + * @brief + * Function to set re-establishment to FALSE + * + * @param[in] rbCb RB for which re-establishment is to be reset + * + * @return Void + */ +#ifdef ANSI +PUBLIC Void kwDlUtlResetReestInProgress +( +KwDlRbCb *rbCb +) +#else +PUBLIC Void kwDlUtlResetReestInProgress(rbCb) +KwDlRbCb *rbCb; +#endif +{ + TRC2(kwDlUtlSetReestInProgressForRB) + + rbCb->reestInProgress = FALSE; +} + +/** + * + * @brief + * Function to set that re-establishment has started for all the RBs + * of an UE; except for SRB1 + * + * @detail: For SRB1 only the poll-retransmit timer is stopped + * + * @param[in] gCb RLC instance control block + * @param[in] ueCb UE for which re-establishment has started + * + * @return void + */ +#ifdef ANSI +PUBLIC Void kwDlUtlSetReestInProgressForAllRBs +( +KwCb *gCb, +KwDlUeCb *ueCb +) +#else +PUBLIC Void kwDlUtlSetReestInProgressForAllRBs(gCb,ueCb) +KwCb *gCb; +KwDlUeCb *ueCb; +#endif +{ + U32 rbIdx; + + TRC2(kwDlUtlSetReestInProgressForAllRBs) + + for(rbIdx = 0;rbIdx < KW_MAX_SRB_PER_UE;rbIdx++) + { + if(ueCb->srbCb[rbIdx] != NULLP) + { + if(ueCb->srbCb[rbIdx]->rlcId.rbId != 1) + { + kwDlUtlSetReestInProgressForRB(gCb,ueCb->srbCb[rbIdx]); + } + else + { + /* For SRB we just need to stop the poll re-transmit timer */ + if(kwChkTmr(gCb, (PTR)ueCb->srbCb[rbIdx], KW_EVT_AMDL_POLL_RETX_TMR)) + { + kwStopTmr(gCb, (PTR)ueCb->srbCb[rbIdx], KW_EVT_AMDL_POLL_RETX_TMR); + } + } + } + } + + for(rbIdx = 0;rbIdx < KW_MAX_DRB_PER_UE;rbIdx++) + { + if(ueCb->drbCb[rbIdx] != NULLP) + { + kwDlUtlSetReestInProgressForRB(gCb,ueCb->drbCb[rbIdx]); + } + } + + RETVOID; +} + +/** + * @brief Function to increment number of SDUs transmitted + * in KWU SAP statistics + * + * + * @param[in] kwuSap KWU SAP in which to increment the counter + * + * @return Void + */ +#ifdef ANSI +PUBLIC Void kwUtlIncrementKwuStsSduTx +( +KwKwuSapCb *kwuSap +) +#else +PUBLIC Void kwUtlIncrementKwuStsSduTx(kwuSap) +KwKwuSapCb *kwuSap; +#endif +{ + kwuSap->sts.sduTx++; + RETVOID; +} + +/** + * @brief Function to increment number of bytes and PDUs transmitted + * in General statistics + * + * + * @param[in] genSts KWU SAP in which to increment the counter + * @param[in] pdu The PDU which is sent + * + * @return Void + */ +#ifdef ANSI +PUBLIC Void kwUtlIncrementGenStsBytesAndPdusSent +( +KwGenSts *genSts, +Buffer *pdu +) +#else +PUBLIC Void kwUtlIncrementGenStsBytesAndPdusSent(genSts, pdu) +KwGenSts *genSts; +Buffer *pdu; +#endif +{ + MsgLen bytesSent; + SFndLenMsg(pdu, &bytesSent); + genSts->bytesSent += bytesSent; + genSts->pdusSent++; + RETVOID; +} + +/** + * @brief Function to initialize the data structures used to free memory + * + * + * @param[in] gCb RLC instance control block + * @param[out] toBeFreed Pointer to the freeing structure. This is + * initialized here + * + * @return Void + */ +#ifdef ANSI +PUBLIC Void kwUtlInitToBeFreed +( +KwCb *gCb, +KwDlDataToBeFreed *toBeFreed +) +#else +PUBLIC Void kwUtlInitToBeFreed(gCb, toBeFreed) +KwCb *gCb; +KwDlDataToBeFreed *toBeFreed; +#endif +{ + cmLListInit(&(toBeFreed->sduLst)); + cmLListInit(&(toBeFreed->rbLst)); + cmLListInit(&(toBeFreed->reTxLst)); + cmLListInit(&(toBeFreed->txLst)); + + RETVOID; +} + +/** + * @brief Function to initialize the DL self Pst structure + * + * + * @param[in] gCb RLC instance control block + * + * @return Void + */ +#ifdef ANSI +PUBLIC Void kwUtlInitializeSelfPst +( +KwCb *gCb +) +#else +PUBLIC Void kwUtlInitializeSelfPst(gCb) +KwCb *gCb; +#endif +{ + Pst *selfPst = &gCb->u.dlCb->selfPst; + + KW_MEM_SET(selfPst, 0, sizeof(Pst)); + selfPst->srcProcId = SFndProcId(); + selfPst->dstProcId = SFndProcId(); + selfPst->dstEnt = gCb->init.ent; + selfPst->dstInst = gCb->init.inst; /* this is for the DL instance */ + selfPst->srcEnt = gCb->init.ent; + selfPst->srcInst = gCb->init.inst; /* DL instance will send to itself */ + selfPst->prior = PRIOR3; + selfPst->event = UDX_EVT_DL_CLEANUP_MEM; +} + +/** + * @brief Function to send a DL cleanup event + * + * + * @param[in] gCb RLC instance control block + * + * @return Void + */ +#ifdef ANSI +PUBLIC Void kwUtlRaiseDlCleanupEvent +( +KwCb *gCb +) +#else +PUBLIC Void kwUtlRaiseDlCleanupEvent(gCb) +KwCb *gCb; +#endif +{ +#ifdef KWSELFPSTDLCLEAN + if(!gCb->u.dlCb->eventInQueue) + { + SPstTsk(&gCb->u.dlCb->selfPst, gCb->u.dlCb->selfPstMBuf); + gCb->u.dlCb->eventInQueue = TRUE; + } +#endif + RETVOID; +} + +/** + * @brief Function to add a SDU to the to be freed sdu list + * + * + * @param[in] gCb RLC instance control block + * @param[in] sdu SDU to be added to the list + * + * @return Void + */ +#ifdef ANSI +PUBLIC Void kwUtlAddSduToBeFreedQueue +( +KwCb *gCb, +KwSdu *sdu +) +#else +PUBLIC Void kwUtlAddSduToBeFreedQueue(gCb, sdu) +KwCb *gCb; +KwSdu *sdu; +#endif +{ + cmLListAdd2Tail(&(gCb->u.dlCb->toBeFreed.sduLst), &(sdu->lstEnt)); + RETVOID; +} + +/** + * @brief Function to add a re-transmitted pdu to the to be freed list + * + * + * @param[in] gCb RLC instance control block + * @param[in] retx Re-transmitted pdu to be added to the list + * + * @return Void + */ +#ifdef ANSI +PUBLIC Void kwUtlAddReTxPduToBeFreedQueue +( +KwCb *gCb, +KwRetx *retx +) +#else +PUBLIC Void kwUtlAddReTxPduToBeFreedQueue(gCb, retx) +KwCb *gCb; +KwRetx *retx; +#endif +{ + cmLListAdd2Tail(&(gCb->u.dlCb->toBeFreed.reTxLst), &(retx->lstEnt)); + RETVOID; +} + +/** + * @brief Function to add a transmitted pdu to the to be freed list + * + * + * @param[in] gCb RLC instance control block + * @param[in] pdu PDU to be added to the list + * + * @return Void + */ +#ifdef ANSI +PUBLIC Void kwUtlAddTxPduToBeFreedQueue +( +KwCb *gCb, +KwTx *pdu +) +#else +PUBLIC Void kwUtlAddTxPduToBeFreedQueue(gCb, pdu) +KwCb *gCb; +KwTx *pdu; +#endif +{ + pdu->rlsLnk.node = (PTR)pdu; + cmLListAdd2Tail(&(gCb->u.dlCb->toBeFreed.txLst), &(pdu->rlsLnk)); + RETVOID; +} + +/* + * @brief + * function to free/release the Acknowledged mode RBCB buffers + * + * @details + * This primitive Frees the Acknowledged Mode RbCb transmission Buffer, + * retransmission Buffer and reciption Buffers + * + * @param [in] gCb - RLC instance control block + * @param [in] rbCb - Downlink RB Control Block + * @param [in,out] toBeFreed - Number of buffers to be freed + * + * @return Bool + * - TRUE if more data to be freed + * - FALSE if all the data has been freed + */ +#ifdef ANSI +PRIVATE Bool kwUtlFreeDlAmRbMemory +( +KwCb *gCb, +KwDlRbCb *rbCb, +U32 *toBeFreed +) +#else +PRIVATE Bool kwUtlFreeDlAmRbMemory(gCb, rbCb, toBeFreed) +KwCb *gCb; +KwDlRbCb *rbCb; +U32 *toBeFreed +#endif +{ + KwRetx *retx; /* retransmission buffer */ + KwSn mTxNext; /* send state variable */ + KwTx *txBuf; + + TRC2(kwUtlFreeDlAmRbMemory) + + + MODAMT(AMDL.txNext, mTxNext, AMDL.txNextAck,AMDL.snModMask); + + /* TODO : to be checked changed from <= to < */ + while ((0 < mTxNext) && *toBeFreed) + { + txBuf = kwUtlGetTxBuf(AMDL.txBufLst, AMDL.txNextAck); + if (txBuf && txBuf->pduLst.first) + { + while(txBuf->pduLst.first) + { + KwDlPduInfo *pduInfo = (KwDlPduInfo *)(txBuf->pduLst.first->node); + KW_FREE_BUF(pduInfo->pdu); + /* Delete node from the txBuf Pdu lst */ + cmLListDelFrm(&txBuf->pduLst, txBuf->pduLst.first); + KW_FREE_WC(gCb, pduInfo, sizeof(KwDlPduInfo)); + } + kwUtlDelTxBuf(AMDL.txBufLst, txBuf, gCb); + if(gCb->u.dlCb->shutdownReceived == 0) + { + (*toBeFreed)--; + } + } + AMDL.txNextAck = (AMDL.txNextAck + 1) & AMDL.snModMask; + MODAMT(AMDL.txNext, mTxNext, AMDL.txNextAck,AMDL.snModMask); + } + if(*toBeFreed == 0) + { + RETVALUE(TRUE); + } + +#ifndef LTE_TDD + KW_FREE(gCb,AMDL.txBufLst, (KW_TX_BUF_BIN_SIZE * sizeof(CmLListCp))); +#endif + + KW_LLIST_FIRST_RETX(AMDL.retxLst, retx); + while (retx && (*toBeFreed)) /* Till to be freed becomes 0 */ + { + + KW_FREE_BUF(retx->seg); + + cmLListDelFrm(&AMDL.retxLst, &retx->lstEnt); + KW_FREE_WC(gCb, retx, sizeof(KwRetx)); + + KW_LLIST_FIRST_RETX(AMDL.retxLst, retx); + if(gCb->u.dlCb->shutdownReceived == 0) + { + (*toBeFreed)--; + } + + } + + AMDL.nxtRetx = NULLP; + + /* clean up if there is info about STATUS PDU to be sent */ + if(AMDL.pStaPdu) + { + Pst *udxPst; + udxPst = &gCb->u.dlCb->udxDlSap->pst; + KW_FREE_SHRABL_BUF_WC(udxPst->region, + udxPst->pool, + AMDL.pStaPdu, + sizeof(KwUdxDlStaPdu)); + AMDL.pStaPdu = NULLP; + } + + if(*toBeFreed == 0) + { + RETVALUE(TRUE); + } + if(gCb->u.dlCb->shutdownReceived) + { + (*toBeFreed)--; + } + + RETVALUE(FALSE);; +} + +/** + * @brief Function to free memory from the DL instance + * + * + * @param[in] gCb RLC instance control block + * + * @return Void + */ +#ifdef ANSI +PUBLIC Void kwUtlFreeDlMemory +( +KwCb *gCb +) +#else +PUBLIC Void kwUtlFreeDlMemory(gCb) +KwCb *gCb; +#endif +{ + U32 toBeFreed; + + /* safety check, in case some event was still lying in the queue after + the dlCb was deleted*/ + if(!gCb->u.dlCb) + { + RETVOID; + } + + KwDlDataToBeFreed* pToBeFreed = &gCb->u.dlCb->toBeFreed; + /* ccpu00136940 */ + if(gCb->u.dlCb->shutdownReceived) + { + toBeFreed = pToBeFreed->txLst.count + pToBeFreed->reTxLst.count + pToBeFreed->sduLst.count + pToBeFreed->rbLst.count; + } + else + { + if ((pToBeFreed->txLst.count + pToBeFreed->reTxLst.count + pToBeFreed->sduLst.count) > (3 * KW_MAX_TO_BE_FREED)) + { +#if !defined(KWSELFPSTDLCLEAN) && defined(MAC_RLC_HARQ_STA_RBUF) && defined(LTE_L2_MEAS) + if (isDatReqProcessed) + { + toBeFreed = (2 *KW_MAX_TO_BE_FREED); + } + else +#endif + { + toBeFreed = (3 *KW_MAX_TO_BE_FREED)/2; + } + } + else + { + toBeFreed = KW_MAX_TO_BE_FREED; + } + } + CmLListCp *lst; + + gCb->u.dlCb->eventInQueue = FALSE; /* reset as we have received the event + and are processing it */ + + /* Free from the ReTx list */ + lst = &pToBeFreed->reTxLst; +#ifndef L2_OPTMZ + while((lst->first) && toBeFreed && (pToBeFreed->reTxLst.count > 100)) +#else + while((lst->first) && toBeFreed) +#endif + { + KwRetx* seg = (KwRetx *)(lst->first->node); + cmLListDelFrm(lst, lst->first); + KW_FREE_BUF_WC(seg->seg); + KW_FREE_WC(gCb,seg, sizeof(KwRetx)); + toBeFreed--; + } + + /* Free from the Tx list */ + lst = &pToBeFreed->txLst; +#ifndef L2_OPTMZ + while((lst->first) && toBeFreed && (pToBeFreed->txLst.count > 100)) +#else + while((lst->first) && toBeFreed) +#endif + { + KwTx* pdu = (KwTx *)(lst->first->node); + cmLListDelFrm(lst, lst->first); + while(pdu->pduLst.first) + { + KwDlPduInfo *pduInfo = (KwDlPduInfo *)(pdu->pduLst.first->node); + + cmLListDelFrm(&pdu->pduLst, pdu->pduLst.first); + KW_FREE_BUF_WC(pduInfo->pdu); + KW_FREE_WC(gCb, pduInfo, sizeof(KwDlPduInfo)); + } + KW_FREE_WC(gCb,pdu, sizeof(KwTx)); + toBeFreed--; + } + + /* Free from the SDU queue */ + lst = &pToBeFreed->sduLst; +#ifndef L2_OPTMZ + while((lst->first) && toBeFreed && (pToBeFreed->sduLst.count > 100)) +#else + while((lst->first) && toBeFreed) +#endif + { + KwSdu* sdu = (KwSdu *)(lst->first->node); + KW_RMV_SDU(gCb, lst, sdu); + toBeFreed--; + } + + /* Free from the RBs */ + lst = &pToBeFreed->rbLst; +#ifndef L2_OPTMZ + while((lst->first) && toBeFreed && (pToBeFreed->rbLst.count > 100)) +#else + while((lst->first) && toBeFreed) +#endif + { + KwDlRbCb* rbCb = (KwDlRbCb *)(lst->first->node); + Bool moreToBeFreed = kwUtlFreeDlAmRbMemory(gCb, rbCb,&toBeFreed); + if(!moreToBeFreed) + { + cmLListDelFrm(lst, lst->first); + KW_FREE_WC(gCb, rbCb, sizeof(KwDlRbCb)); + } + } + + if ((toBeFreed == 0) && !(gCb->u.dlCb->shutdownReceived)) + { + kwUtlRaiseDlCleanupEvent(gCb); + } + + RETVOID; +} + + +#ifdef LTE_L2_MEAS +/** + * + * @brief Function to initialise measurement + * + * @b Description + * + * @param[in] gCb RLC Instance Control Block + * + * @return Void + * + */ +S16 kwUtlL2MeasDlInit(KwCb *gCb) +{ + U16 cntr; + + gCb->u.dlCb->kwL2Cb.kwNumMeas=0; + for(cntr = 0; cntr < LKW_MAX_L2MEAS; cntr++) + { + cmMemset((U8 *)&(gCb->u.dlCb->kwL2Cb.kwL2EvtCb[cntr]), 0, sizeof(KwL2MeasEvtCb)); + } + gCb->u.dlCb->kwL2Cb.kwL2EvtCb[KW_L2MEAS_DL_DISC].measCb.measType = LKW_L2MEAS_DL_DISC; + gCb->u.dlCb->kwL2Cb.kwL2EvtCb[KW_L2MEAS_DL_IP].measCb.measType = LKW_L2MEAS_DL_IP; + gCb->u.dlCb->kwL2Cb.kwL2EvtCb[KW_L2MEAS_DL_DELAY].measCb.measType= LKW_L2MEAS_DL_DELAY; + gCb->u.dlCb->kwL2Cb.kwL2EvtCb[KW_L2MEAS_UU_LOSS].measCb.measType= LKW_L2MEAS_UU_LOSS; + gCb->u.dlCb->kwL2Cb.kwL2EvtCb[KW_L2MEAS_ACT_UE].measCb.measType= LKW_L2MEAS_ACT_UE; + + RETVALUE(ROK); +} +/** + * + * @brief Function to detect the data Burst start Condition in a DTCH + * + * @b Description + * + * @param[in] rbCb RB control block + * @param[in] contSduLst Array of Contained SDUs in the DTCH + * @param[in] dataVol Available data in the DTCH + * @param[in] schPduSz Total grant Size given by MAC + * + * @return Void + * + */ +#ifdef ANSI +PUBLIC Void kwUtlUpdateBurstSdus +( +KwCb *gCb, +KwDlRbCb *rbCb, +KwContSduLst *contSduLst, +S32 dataVol, +U32 schPduSz +) +#else +PUBLIC Void kwUtlUpdateBurstSdus (gCb, rbCb, contSduLst, dataVol, schPduSz) +KwCb *gCb; +KwDlRbCb *rbCb; +KwContSduLst *contSduLst; +S32 dataVol; +U32 schPduSz; +#endif +{ + + KwL2MeasDlIpTh *l2MeasDlIpThruput = NULLP; + KwL2MeasTb *l2MeasTb = NULLP; + U8 idx; + U8 currTbIdx; + VOLATILE U32 startTime = 0; + KwContSduLst *dstContSduLst; + TRC2(kwUtlUpdateBurstSdus) + + + /*starting Task*/ + SStartTask(&startTime, PID_RLC_DLIP_TPT_BURSTCALC); + + l2MeasDlIpThruput = &rbCb->l2MeasIpThruput.dlIpTh; + + if(KW_MEAS_IS_DL_IP_MEAS_ON_FOR_RB(gCb, rbCb)) + { + if(dataVol > schPduSz) + { + if(l2MeasDlIpThruput->isBurstAct == FALSE) + { + l2MeasDlIpThruput->burstStartTime = glblTtiCnt; + l2MeasDlIpThruput->isBurstAct = TRUE; + l2MeasDlIpThruput->burstEndSduId = 0; + } + else + { /* This is the case when another burst started before RLC gets the + l2MeasDlIpThruput->burstEndSduId = 0; */ + } + } + else + { /* Store the burstEndSduId here */ + if((l2MeasDlIpThruput->isBurstAct == TRUE) && + (!l2MeasDlIpThruput->burstEndSduId)) + { + l2MeasDlIpThruput->burstEndSduId = + l2MeasDlIpThruput->outStngSduArr[l2MeasDlIpThruput->lastSduIdx].sduId; + } + } + if(l2MeasDlIpThruput->isBurstAct == TRUE) + { + l2MeasTb = kwUtlGetCurMeasTb(gCb,rbCb); + /* Get the lChId from index 0, because index 0 is always for DL */ + if(l2MeasTb->numLcId >= KW_MAX_ACTV_DRB) + { + /* ccpu00143043 */ + RETVOID; + } + l2MeasTb->sduInfo[l2MeasTb->numLcId].lcId = rbCb->lch.lChId; + /* Copy all the sduIdx from sduInfo to tb sduInfo */ + currTbIdx = l2MeasTb->sduInfo[l2MeasTb->numLcId].numSdus; + dstContSduLst = &l2MeasTb->sduInfo[l2MeasTb->numLcId]; + /* ccpu00143043 */ + for(idx = 0; ((idx < contSduLst->numSdus) + && (currTbIdx < KW_L2MEAS_MAX_OUTSTNGSDU)) ; idx++) + { + dstContSduLst->sduIdx[currTbIdx++] = contSduLst->sduIdx[idx]; + } + l2MeasTb->sduInfo[l2MeasTb->numLcId].numSdus += idx; + l2MeasTb->numLcId++; + }/* End of isBurstAct */ + }/* End of if measOn */ + + /*stopping Task*/ + SStopTask(startTime, PID_RLC_DLIP_TPT_BURSTCALC); + RETVOID; +} +/** + * @brief + * This function is used to store locally the sduIdx of the sdu in the + * outstanding SDU array + * + * @b Description: + * Stores the Sdu Idx in the contained SDU Array and increments + * the num contained Sdus + * + * @param[in] sduIdx the Index of the SDU in the outstanding SDU array + * @param[out] contSduLst This stores the indices of the SDUs + * + * @return Void + */ +#ifdef ANSI +PUBLIC Void kwUtlUpdateContainedSduLst +( +U8 sduIdx, +KwContSduLst *contSduLst +) +#else +PUBLIC Void kwUtlUpdateContainedSduLst(sduIdx, contSduLst) +U8 sduIdx; +KwContSduLst *contSduLst; +#endif +{ + if (contSduLst->numSdus < KW_L2MEAS_MAX_OUTSTNGSDU) + { + contSduLst->sduIdx[contSduLst->numSdus] = sduIdx; + contSduLst->numSdus++; + } + RETVOID; +} + +/** + * @brief + * This function is used to store the sduId of the sdu in the + * outstanding SDU array + * + * @b Description: + * Stores the Sdu Id in the outstanding SDU Array and increments + * the num contained Sdus + * + * @param[out] dlIpThPut The structure in which the outstanding sdus are + * updated + * @param[in] sduIdx The Idx at which the sdu ID is stored + * @param[in] sduLen The size if sdu in bytes + * @param[in] newIdx Indicates if the sdu is already present in the + * outstanding array + * + * @return Void + */ +#ifdef ANSI +PUBLIC Void kwUtlUpdateOutStandingSduLst +( +KwL2MeasDlIpTh *dlIpThPut, +U8 sduIdx, +MsgLen sduLen, +U32 sduId, +Bool newIdx +) +#else +PUBLIC Void kwUtlUpdateOutStandingSduLst(dlIpThPut, sduIdx, sduLen, sduId, newIdx) +KwL2MeasDlIpTh *dlIpThPut; +U8 sduIdx; +MsgLen sduLen; +U32 sduId; +Bool newIdx; +#endif +{ + if (sduIdx < KW_L2MEAS_MAX_OUTSTNGSDU) + { + if(newIdx == TRUE) + { + dlIpThPut->outStngSduArr[sduIdx].numTb = 0; + } + dlIpThPut->outStngSduArr[sduIdx].numTb++; + dlIpThPut->outStngSduArr[sduIdx].sduId = sduId; + dlIpThPut->outStngSduArr[sduIdx].sduLen = sduLen; + } + RETVOID; +} +#ifdef ANSI +PUBLIC KwL2MeasTb * kwUtlGetCurMeasTb +( +KwCb *gCb, +KwDlRbCb *rbCb +) +#else +PUBLIC KwL2MeasTb * kwUtlGetCurMeasTb(gCb, rbCb) +KwCb *gCb; +KwDlRbCb *rbCb; +#endif +{ + KwL2MeasTb *curL2MeasTb; + U16 idx; + + TRC3(kwUtlGetCurMeasTb) + + if((curL2MeasTb = rbCb->ueCb->l2MeasTbCb[rbCb->ueCb->tbIdx]) == NULLP) + { + /* Intentionally avoiding the KW_ALLOC macro to avoid memset */ + if (SGetSBuf(gCb->init.region, + gCb->init.pool, + (Data **)&curL2MeasTb, + (Size)sizeof(KwL2MeasTb)) != ROK) + { + RETVALUE(NULLP); + } + rbCb->ueCb->l2MeasTbCb[rbCb->ueCb->tbIdx] = curL2MeasTb; + /* Initialize the Meas Tb details */ + curL2MeasTb->numLcId = 0; + curL2MeasTb->numLchInfo = 0; + curL2MeasTb->txSegSduCnt = 0; + for (idx = 0; idx < KW_MAX_ACTV_DRB; idx++) + { + curL2MeasTb->sduInfo[idx].numSdus = 0; + } + for (idx = 0; idx < KW_MAX_ACTV_DRB; idx++) + { + curL2MeasTb->lchInfo[idx].numSdus = 0; + } + } + RETVALUE(curL2MeasTb); +} + + +/** + * + * @brief Handler for Processing harq status indication + * + * + * @b Description + * This function is called when the MAC sends a harq ind Mesage. + * This is used only for UuLoss and Dl Delay and DL Ipthoughput + * L2 Measurements. + * + * @param[in] staInd Harq status indication received from MAC. + * @param[in] ueCb UeCb corresponding to the Tb Id. + * @param[in] tbIdx TB index, 0 for SISO and 0,1 for MIMO. + * + * + * @return S16 + * -# ROK + */ + +#ifdef ANSI +PUBLIC S16 kwUtlProcHarqInd +( +KwCb *gCb, +RguHarqStatusInd *hqStaInd, +KwDlUeCb *ueCb, +U8 tbIdx +) +#else +PUBLIC S16 kwUtlProcHarqInd(gCb, hqStaInd, ueCb, tbIdx) +KwCb *gCb; +RguHarqStatusInd *hqStaInd; +KwDlUeCb *ueCb; +U8 tbIdx; +#endif +{ +#ifdef LTE_L2_MEAS + KwDlRbCb *kwRbCb; /* KW Control Block */ + KwL2MeasTb *l2MeasTb = NULLP; /* Measurement TbCb */ + U8 lcIdx; /* Logical channel id index */ + U8 sduIndx; /* sdu index to out standing sdu list in rbCb */ + U32 numSdus; /* number of sdus in the outstanding sdu list */ + KwOutStngSduInfo *outStngSduArr; /* Outstanding sdu list */ + Ticks ackTime; + Ticks delay; + U32 totlSduCnt = 0; +#endif + U8 timeAddedFlag; + S16 ret; + VOLATILE U32 startTime = 0; + /*kw005.201 Code added for DL IP thruput measurement*/ + + TRC3(kwUtlProcHarqInd) + + /*starting Task*/ + SStartTask(&startTime, PID_RLC_DLIP_TPT_PRCHARQIND); + + ret = ROK; + if(hqStaInd->tbId[tbIdx] >= KW_INVALID_TBID) + { + RETVALUE(ROK); + } + + /* Find the L2 measurement tbCb to process DL Ip thruput*/ + l2MeasTb = ueCb->l2MeasTbCb[hqStaInd->tbId[tbIdx]]; + if(l2MeasTb == NULLP) + { + RETVALUE(ROK); + } + /* For each logical channel in the tbCb, process + * and get the DL IP thruput */ + ackTime = SGetTtiCount(); + for(lcIdx = 0; ((lcIdx < l2MeasTb->numLcId) && (lcIdx < KW_MAX_ACTV_DRB)); lcIdx++) + { + timeAddedFlag = FALSE; + if((kwRbCb = ueCb->lCh[l2MeasTb->sduInfo[lcIdx].lcId - 1].dlRbCb) + == NULLP) + { + continue; + } + /* fix for DL IP stop*/ + if (!gCb->u.dlCb->kwL2Cb.measOn[kwRbCb->qci] + || (kwRbCb->rlcId.rbType == CM_LTE_SRB)) + { + continue; + } + + /* Get the outstanding SDUs using sdu index stored in Container sduList + * and check for HARQ ACK/NACK */ + numSdus = l2MeasTb->sduInfo[lcIdx].numSdus; + /* ccpu00143043 */ + if ((numSdus >= KW_L2MEAS_MAX_OUTSTNGSDU) || (numSdus == 0)) + { + break; + } + totlSduCnt += numSdus; + + if (KW_MEAS_IS_DL_IP_MEAS_ON_FOR_RB(gCb,kwRbCb)) + { + for(sduIndx = 0; sduIndx < numSdus; sduIndx++) + { + outStngSduArr =&(kwRbCb->l2MeasIpThruput.dlIpTh.outStngSduArr[\ + l2MeasTb->sduInfo[lcIdx].sduIdx[sduIndx]]); + if(hqStaInd->status[tbIdx] == TRUE) + { + /* If ACK is for burst End Sdu Id set burstActive + * to FALSE and accumulate time */ + if((kwRbCb->l2MeasIpThruput.dlIpTh.burstEndSduId == + outStngSduArr->sduId) && (outStngSduArr->numTb == 1)) + { + kwRbCb->l2MeasIpThruput.dlIpTh.isBurstAct = FALSE; + /*Update the l2Sts structure for calculating throughput*/ + kwRbCb->rbL2Cb.l2Sts[KW_L2MEAS_DL_IP]->dlIpThruput.volSummation + += outStngSduArr->sduLen; + + kwRbCb->rbL2Cb.l2Sts[KW_L2MEAS_DL_IP]->dlIpThruput.timeSummation + += glblTtiCnt - kwRbCb->l2MeasIpThruput.dlIpTh.burstStartTime; + outStngSduArr->sduId = 0; + outStngSduArr->sduLen = 0; + outStngSduArr->numTb = 0; + kwRbCb->l2MeasIpThruput.dlIpTh.burstEndSduId = 0; + } + + /* If burst is active and this sdu is only transmitted in single TB then + * accumulate volume and clear the outstanding sduList */ + if((kwRbCb->l2MeasIpThruput.dlIpTh.isBurstAct == TRUE) && + (--(outStngSduArr->numTb) == 0)) + { + kwRbCb->rbL2Cb.l2Sts[KW_L2MEAS_DL_IP]->dlIpThruput.volSummation + += outStngSduArr->sduLen; + + if(timeAddedFlag == FALSE) + { + kwRbCb->rbL2Cb.l2Sts[KW_L2MEAS_DL_IP]->dlIpThruput.timeSummation + += glblTtiCnt - kwRbCb->l2MeasIpThruput.dlIpTh.burstStartTime; + kwRbCb->l2MeasIpThruput.dlIpTh.burstStartTime = glblTtiCnt; + timeAddedFlag = TRUE; + } + outStngSduArr->sduId = 0; + outStngSduArr->sduLen = 0; + } + }/* End of status == TRUE */ + else + { + if(kwRbCb->l2MeasIpThruput.dlIpTh.isBurstAct == TRUE) + { + if((kwRbCb->l2MeasIpThruput.dlIpTh.burstEndSduId == + outStngSduArr->sduId)) + { + kwRbCb->l2MeasIpThruput.dlIpTh.isBurstAct = FALSE; + kwRbCb->l2MeasIpThruput.dlIpTh.burstEndSduId = 0; + } + /* Clear the outstanding sdu list */ + outStngSduArr->sduId = 0; + outStngSduArr->sduLen = 0; + outStngSduArr->numTb = 0; + } + } + } + } + } + + for(lcIdx = 0; ((lcIdx < l2MeasTb->numLchInfo) && (lcIdx < KW_MAX_ACTV_DRB)); lcIdx++) + { + if((kwRbCb = ueCb->lCh[l2MeasTb->lchInfo[lcIdx].lcId - 1].dlRbCb) + == NULLP) + { + continue; + } + numSdus = l2MeasTb->lchInfo[lcIdx].numSdus; + if ( numSdus == 0 ) + { + continue; + } + /* ccpu00143043 */ + if ((numSdus > KW_L2MEAS_MAX_OUTSTNGSDU) || (numSdus == 0)) + { + break; + } + /* Update stats */ + if(hqStaInd->status[tbIdx] == TRUE) + { + for(sduIndx = 0; sduIndx < numSdus; sduIndx++) + { + delay = KW_TIME_DIFF(ackTime,l2MeasTb->lchInfo[lcIdx].sduInfo[sduIndx].arvlTime); + KW_UPD_PDCP_L2_DLDELAY_STS(gCb,kwRbCb, delay); + } + /* Case of sduInfo not updated */ + if (totlSduCnt == 0) + { + totlSduCnt = numSdus; + } + KW_UPD_L2_UU_LOSS_POS_PKTS(gCb,kwRbCb, (totlSduCnt + l2MeasTb->txSegSduCnt)); + } + else + { + /* Case of sduInfo not updated */ + if (totlSduCnt == 0) + { + totlSduCnt = numSdus; + } + KW_UPD_L2_UU_LOSS_PKTS(gCb,kwRbCb, (totlSduCnt + l2MeasTb->txSegSduCnt)); + } + } + /* Free this tb, deallocate the memory */ + KW_FREE(gCb, l2MeasTb, sizeof(KwL2MeasTb)); + ueCb->l2MeasTbCb[hqStaInd->tbId[tbIdx]] = NULLP; + + /*stopping Task*/ + SStopTask(startTime, PID_RLC_DLIP_TPT_PRCHARQIND); + + RETVALUE(ret); +}/* end of kwUtlProcHarqInd */ + +/** + * + * @brief Handler for Sending L2 Measurement confirm. + * + * + * @b Description + * This function sends a consolidates the mesaurements taken during + * this time and sends the confirm . + * + * @param[in] measEvtCb Measurement Event Control Block. + * + * + * @return S16 + * -# ROK + */ + +#ifdef ANSI +PUBLIC S16 kwUtlSndDlL2MeasCfm +( +KwCb *gCb, +KwL2MeasEvtCb *measEvtCb +) +#else +PUBLIC S16 kwUtlSndDlL2MeasCfm(gCb, measEvtCb) +KwCb *gCb; +KwL2MeasEvtCb *measEvtCb; +#endif +{ + U32 qciIdx; + KwL2MeasCb *measCb = NULLP; + KwL2MeasCfmEvt measCfmEvt; + U32 posPkts; + U32 dLoss; + + U64 dlDataVol; + U64 dlTime; + U16 cntr; + /* Discard new changes starts */ + U8 qci = 0; + U32 cfmIdx =0; + /* Discard new changes ends */ + + TRC3(kwUtlSndL2MeasCfm) + + /* kw006.201 ccpu00120058 emoved 64 bit compilation warning */ +#ifndef ALIGN_64BIT + RLOG1(L_DEBUG,"kwUtlSndL2MeasCfm(transId(%ld))", measEvtCb->transId); +#else + RLOG1(L_DEBUG,"kwUtlSndL2MeasCfm(transId(%d))", measEvtCb->transId); +#endif + + /* Clean up the RB data structures */ + measCb = &measEvtCb->measCb; + + cmMemset((U8*)&measCfmEvt, 0, sizeof(KwL2MeasCfmEvt)); + measCfmEvt.transId = measEvtCb->transId; + + measCfmEvt.measType = measCb->measType; + measCfmEvt.status.status = LCM_PRIM_OK; + measCfmEvt.status.reason = LCM_REASON_NOT_APPL; + + if(measCb->measType & LKW_L2MEAS_DL_IP) + { + KwL2MeasCbUeMeasInfo *pUeInfoLstCb = measCb->val.ipThMeas.ueInfoLst; + KwL2MeasCfmUeInfoLst *pUeInfoLstCfm = measCfmEvt.val.ipThMeas.ueInfoLst; + + for(cntr = 0;(cntr < measCb->val.ipThMeas.numUes) && (cntr < gCb->genCfg.maxUe);cntr++) + { + pUeInfoLstCfm[cfmIdx].numCfm = 0; + if (pUeInfoLstCb[cntr].isValid == TRUE) + { + pUeInfoLstCfm[cfmIdx].ueId = pUeInfoLstCb[cntr].ueId; + pUeInfoLstCfm[cfmIdx].cellId = pUeInfoLstCb[cntr].cellId; + for(qciIdx = 0; qciIdx < pUeInfoLstCb[cntr].numQci; qciIdx++) + { + qci = pUeInfoLstCb[cntr].qci[qciIdx]; + pUeInfoLstCfm[cfmIdx].measCfm[pUeInfoLstCfm[cfmIdx].numCfm].qci = qci; + + dlDataVol = pUeInfoLstCb[cntr].measData[qci].dlIpThruput.volSummation; + dlTime = pUeInfoLstCb[cntr].measData[qci].dlIpThruput.timeSummation; + + if((0 == dlTime) || !(gCb->u.dlCb->kwL2Cb.measOn[qci] & LKW_L2MEAS_DL_IP) ) + { + pUeInfoLstCfm[cfmIdx].measCfm[pUeInfoLstCfm[cfmIdx].numCfm].val.ipThrput.dlIpThPut = 0; + } + else + { + pUeInfoLstCfm[cfmIdx].measCfm[pUeInfoLstCfm[cfmIdx].numCfm].val.ipThrput.dlIpThPut = + (dlDataVol / dlTime); + } + pUeInfoLstCfm[cfmIdx].measCfm[pUeInfoLstCfm[cfmIdx].numCfm].val.ipThrput.dlIpThPut *= 8; + + /* Reset the values after reporting to Application */ + pUeInfoLstCb[cntr].measData[qci].dlIpThruput.volSummation = 0; + pUeInfoLstCb[cntr].measData[qci].dlIpThruput.timeSummation = 0; + + measCfmEvt.val.ipThMeas.ueInfoLst[cfmIdx].numCfm++; + } + cfmIdx++; + } + } + measCfmEvt.val.ipThMeas.numUes = cfmIdx; + } + else + { + KwL2Cntr *pMeasData = measCb->val.nonIpThMeas.measData; + KwL2MeasCfmNonIpThMeas *pMeasCfmNonIp = &measCfmEvt.val.nonIpThMeas; + + pMeasCfmNonIp->numCfm = 0; + + for(qciIdx = 0; qciIdx < LKW_MAX_QCI; qciIdx++) + { + qci = measCb->val.nonIpThMeas.qci[qciIdx]; + if (qci > 0) + { + pMeasCfmNonIp->measCfm[pMeasCfmNonIp->numCfm].qci = qci; + + if(measCb->measType & LKW_L2MEAS_UU_LOSS) + { + dLoss = pMeasData[qci].uuLoss.dLoss; + posPkts = pMeasData[qci].uuLoss.posPkts; + if(((posPkts + dLoss) != 0)) + { + pMeasCfmNonIp->measCfm[pMeasCfmNonIp->numCfm].val.nonIpThrput.uuLoss = + ((dLoss * 1000000) / (posPkts + dLoss)); + } + pMeasData[qci].uuLoss.dLoss = 0; + pMeasData[qci].uuLoss.posPkts = 0; + } + if(measCb->measType & LKW_L2MEAS_DL_DISC) + { + + pMeasCfmNonIp->measCfm[pMeasCfmNonIp->numCfm].val.nonIpThrput.dlDiscRate = 0; + if(pMeasData[qci].dlDisc.totSdus != 0) + { + pMeasCfmNonIp->measCfm[pMeasCfmNonIp->numCfm].val.nonIpThrput.dlDiscRate = + (((pMeasData[qci].dlDisc.discSdus) * 1000000) / (pMeasData[qci].dlDisc.totSdus)); + } + + pMeasData[qci].dlDisc.totSdus = 0; + pMeasData[qci].dlDisc.discSdus = 0; + } + if(measCb->measType & LKW_L2MEAS_DL_DELAY) + { + if (pMeasData[qci].dlPjSduDelay.numSdus > 0) + { + pMeasCfmNonIp->measCfm[pMeasCfmNonIp->numCfm].val.nonIpThrput.dlSduDelay = + (pMeasData[qci].dlPjSduDelay.sduDelay / pMeasData[qci].dlPjSduDelay.numSdus); + pMeasData[qci].dlPjSduDelay.sduDelay = 0; + pMeasData[qci].dlPjSduDelay.numSdus = 0; + } + } + pMeasCfmNonIp->numCfm++; + } + } + } + /* Fix Klock warning */ + KwMiLkwL2MeasCfm(&gCb->genCfg.lmPst, &measCfmEvt); + RETVALUE(ROK); +} /* kwUtlSndL2MeasCfm */ +/** + * + * @brief Handler for Sending Negative confirm . + * + * + @b Description + * This function is called when the l2 measurement cannot be started + * This function sends negative confirm for all the requests + * + * @param[in] measReqEvt Measurement Req Structure + * + * + * @return S16 + * -# ROK + */ + +#ifdef ANSI +PUBLIC S16 kwUtlSndDlL2MeasNCfm +( +KwCb *gCb, +KwL2MeasReqEvt *measReqEvt, +KwL2MeasCfmEvt *measCfmEvt +) +#else +PUBLIC S16 kwUtlSndDlL2MeasNCfm(gCb,measReqEvt, measCfmEvt) +KwCb *gCb; +KwL2MeasReqEvt *measReqEvt; +KwL2MeasCfmEvt *measCfmEvt; +#endif +{ + TRC3(kwUtlSndDlL2MeasNCfm) + + KwMiLkwL2MeasCfm(&gCb->genCfg.lmPst, measCfmEvt); + RETVALUE(ROK); +} /* kwUtlSndL2MeasNCfm */ +/** + * + * @brief Handler for resetting the RB data structures + * + * + * @b Description + * This function resets the RB data structure after the expiry of + * measurement timer. + * + * @param[in] measCb Measurement Control Block. + * + * + * @return Void + */ +#ifdef ANSI + +PUBLIC Void kwUtlResetDlL2MeasInKwRb +( +KwCb *gCb, +KwL2MeasCb *measCb, +U8 measType +) +#else +PUBLIC Void kwUtlResetDlL2MeasInKwRb(gCb, measCb, measType) +KwCb *gCb; +KwL2MeasCb *measCb; +U8 measType; +#endif +{ + U32 ueIdx; + U32 qciIdx; + KwDlUeCb *ueCb = NULL; + + + + if (measCb->measType & LKW_L2MEAS_DL_IP) + { + for(ueIdx = 0; ueIdx < measCb->val.ipThMeas.numUes; ueIdx++) + { + if (measCb->val.ipThMeas.ueInfoLst[ueIdx].isValid == TRUE) + { + for (qciIdx =0; qciIdx < measCb->val.ipThMeas.ueInfoLst[ueIdx].numQci; qciIdx++) + { + if (measType & LKW_L2MEAS_DL_IP) + { + measCb->val.ipThMeas.ueInfoLst[ueIdx].measData[qciIdx].dlIpThruput.volSummation = 0; + measCb->val.ipThMeas.ueInfoLst[ueIdx].measData[qciIdx].dlIpThruput.timeSummation = 0; + gCb->u.dlCb->kwL2Cb.measOn[qciIdx] &= ~measType; + } + } + + if(ROK != kwDbmFetchDlUeCb(gCb,measCb->val.ipThMeas.ueInfoLst[ueIdx].ueId, + measCb->val.ipThMeas.ueInfoLst[ueIdx].cellId, &ueCb)) + { + continue; + } + + } + } + } + else + { + /* for now the only meas should be DL discard in this case */ + if (measCb->measType & LKW_L2MEAS_DL_DISC) + { + U32 i; + for(i = 0; i < measCb->val.nonIpThMeas.numQci; i++) + { + U8 qciVal = measCb->val.nonIpThMeas.qci[i]; + + measCb->val.nonIpThMeas.measData[qciVal].dlDisc.discSdus = 0; + measCb->val.nonIpThMeas.measData[qciVal].dlDisc.totSdus = 0; + } + + } + if (measCb->measType & LKW_L2MEAS_DL_DELAY) + { + U32 i; + for(i = 0; i < measCb->val.nonIpThMeas.numQci; i++) + { + U8 qciVal = measCb->val.nonIpThMeas.qci[i]; + + measCb->val.nonIpThMeas.measData[qciVal].dlPjSduDelay.sduDelay = 0; + } + } + measCb->val.nonIpThMeas.numQci = 0; + } +} /* kwUtlResetDlL2MeasInKwRb */ +#endif + +PRIVATE Void dumpRLCDlRbInformation(KwDlRbCb* dlRbCb) +{ + if(dlRbCb->mode == CM_LTE_MODE_UM) + { + RLOG_ARG3(L_DEBUG,DBG_RBID,dlRbCb->rlcId.rbId, + "UM Downlink UEID:%d CELLID:%d Q size = %d", + dlRbCb->rlcId.ueId, + dlRbCb->rlcId.cellId, + (int)dlRbCb->m.umDl.sduQ.count); + } + else if(dlRbCb->mode == CM_LTE_MODE_AM) + { + U32 j, numTxPdus=0; + for(j = 0; j <= (KW_AM_GET_WIN_SZ(dlRbCb->m.amDl.snLen)); j++) + { + KwTx *txBuf = kwUtlGetTxBuf(dlRbCb->m.amDl.txBufLst, j); + if(txBuf != NULLP) + { + numTxPdus++; + } + } + RLOG_ARG4(L_DEBUG,DBG_RBID,dlRbCb->rlcId.rbId, + "AM Downlink UEID:%d CELLID:%d Sizes SDU Q = %d TX Q = %d ", + dlRbCb->rlcId.ueId, + dlRbCb->rlcId.cellId, + (int)dlRbCb->m.amDl.sduQ.count, + (int)numTxPdus); + RLOG_ARG3(L_DEBUG,DBG_RBID,dlRbCb->rlcId.rbId, + "AM Downlink UEID:%d CELLID:%d RETX Q= %d", + dlRbCb->rlcId.ueId, + dlRbCb->rlcId.cellId, + (int)dlRbCb->m.amDl.retxLst.count); + } +} + +Void DumpRLCDlDebugInformation(Void) +{ + KwCb* dlInst = kwCb[1]; /* TODO : Check whether DL is 0 or 1 */ + + KwDlCb *dlCb = dlInst->u.dlCb; + + KwDlUeCb *ueCb = NULLP; + RTLIN_DUMP_DEBUG("RLC Information\n"); + RTLIN_DUMP_DEBUG("===============\n"); + /* Until no more ueCb is ueLstCp hash list get and delete ueCb */ + while (ROK == cmHashListGetNext(&dlCb->ueLstCp, + (PTR) ueCb, + (PTR *)&ueCb)) + { + U32 i; + for(i = 0; i< KW_MAX_SRB_PER_UE; i++) + { + KwDlRbCb* dlRbCb = ueCb->srbCb[i]; + if( dlRbCb != NULLP) + { + dumpRLCDlRbInformation(dlRbCb); + } + } + for(i = 0; i< KW_MAX_DRB_PER_UE; i++) + { + KwDlRbCb* dlRbCb = ueCb->drbCb[i]; + if( dlRbCb != NULLP) + { + dumpRLCDlRbInformation(dlRbCb); + } + } + } + + KwDlDataToBeFreed* pToBeFreed = &dlCb->toBeFreed; + + RTLIN_DUMP_DEBUG("toBeFreed RETX list size = %d\n",(int)pToBeFreed->reTxLst.count); + RTLIN_DUMP_DEBUG("toBeFreed TX list size = %d\n",(int)pToBeFreed->txLst.count); + RTLIN_DUMP_DEBUG("toBeFreed SDU list size = %d\n",(int)pToBeFreed->sduLst.count); + RTLIN_DUMP_DEBUG("toBeFreed RB list size = %d\n",(int)pToBeFreed->rbLst.count); +} + +/** + * + * @b Description + * This function frees downlink memory + * + * @param[in] Void + * + * + * @return Void + */ + +#ifdef ANSI +void kwUtlFreeDlMem +( + Void +) +#else +void kwUtlFreeDlMem() +Void; +#endif +{ + kwUtlFreeDlMemory(KW_GET_KWCB(KW_DL_INST)); +} + +/** + * + * @b Description + * This function returns current time + * + * @param[in] U32 + * + * + * @return Void + */ + +#ifdef ANSI +void kwUtlGetCurrTime +( + U32 *currTime +) +#else +void kwUtlGetCurrTime(U32 *currTime) +U32 *currTime; +#endif +{ + TRC2(kwUtlGetCurrTime) + + /* Need t define else part for PAL */ + *currTime = SGetTtiCount(); +} + +#if defined(MAC_RLC_HARQ_STA_RBUF) || defined (SS_RBUF) +#ifdef LTE_L2_MEAS +#ifdef ANSI +void kwUtlDlBatchProcHqStaInd +( + Void +) +#else +void kwUtlDlBatchProcHqStaInd() +Void; +#endif +{ + /* Read from Ring Buffer and process PDCP packets */ + //Pst pst = {0}; + + Void *elmIndx = NULLP; + RguHarqStaInd *staInd = NULLP; + +#if defined(MAC_RLC_HARQ_STA_RBUF) && defined(LTE_L2_MEAS) + isDatReqProcessed = TRUE; +#endif + elmIndx = (Void *)SRngGetRIndx(SS_RNG_BUF_MAC_HARQ); + while(NULLP != elmIndx) + { + staInd = (RguHarqStaInd *)elmIndx; + KwLiRguHqStaInd(&(staInd->pst), 0, &(staInd->hqStatusInd)); + + elmIndx = NULLP; + staInd = NULLP; + SRngIncrRIndx(SS_RNG_BUF_MAC_HARQ); + + if((elmIndx = (Void *)SRngGetRIndx(SS_RNG_BUF_MAC_HARQ)) == NULLP) + { +#if defined(MAC_RLC_HARQ_STA_RBUF) && defined(LTE_L2_MEAS) + isDatReqProcessed = FALSE; +#endif + break; + } + } +} +#endif +#endif + +/** + * @brief evaluate and trigger PDB based flow control to PDCP + * + * @details + * + * @param[in] rbCb RB control block + * + * + * @return Void + * + */ +#ifdef ANSI +PUBLIC Void kwUtlTrigPdbFlowCntrl +( +KwCb *gCb, +KwDlRbCb *rbCb, +U32 pktAdmitCnt +) +#else +PUBLIC Void kwUtlTrigPdbFlowCntrl(gCb,rbCb,pktAdmitCnt) +KwCb *gCb; +KwDlRbCb *rbCb; +U32 pktAdmitCnt; +#endif +{ + KwuFlowCntrlIndInfo *flowCntrlInfo; + KwKwuSapCb* kwuSap; + + kwuSap = gCb->u.dlCb->kwuDlSap + KW_UI_PDCP; + + KW_SHRABL_STATIC_BUF_ALLOC(kwuSap->pst.region, + kwuSap->pst.pool, + flowCntrlInfo, + sizeof(KwuFlowCntrlIndInfo)); + flowCntrlInfo->rlcId = rbCb->rlcId; + flowCntrlInfo->pktAdmitCnt = pktAdmitCnt; + KwUiKwuFlowCntrlInd(&kwuSap->pst, kwuSap->suId, flowCntrlInfo); +} + +/** + * + * @brief Store the DL buffer in hashList + * + * + * @b Description + * + * Use the SN % binSize as key and store the received UL buffer + * @param[in] txBufLst List CP array + * @param[in] txBuf transmitted buffer + * @param[in] sn sn of the received buffer + * + * + * @return Void + */ +#ifdef ANSI +PUBLIC Void kwUtlStoreTxBuf +( +CmLListCp *txBufLst, +KwTx *txBuf, +KwSn sn +) +#else +PUBLIC Void kwUtlStoreTxBuf(txBufLst, txBuf, sn) +CmLListCp *txBufLst; +KwTx *txBuf; +KwSn sn; +#endif +{ + U32 hashKey; + + TRC3(kwUtlStoretxBuf) + //printf("S-sn(%d)\n", sn); + hashKey = (sn % KW_TX_BUF_BIN_SIZE ); + txBuf->sn = sn; + txBuf->lnk.node = (PTR)txBuf; + cmLListAdd2Tail(&(txBufLst[hashKey]), &txBuf->lnk); + + RETVOID; +} /* kwUtlStoreRecBuf */ + +/** + * + * @brief Retrieve the DL buffer from the list + * + * + * @Description + * + * Use the SN % binSize as key and retrieve the DL buffer + * @param[in] txBufLst List CP array + * @param[in] sn sn of the transmitted buffer + * + * + * @return Void + */ +#ifdef ANSI +PUBLIC KwTx* kwUtlGetTxBuf +( +CmLListCp *txBufLst, +KwSn sn +) +#else +PUBLIC KwTx* kwUtlGetTxBuf(txBufLst, sn) +CmLListCp *txBufLst; +KwSn sn; +#endif +{ + U32 hashKey; + CmLListCp *txBufLstCp; + KwTx *txBuf; + CmLList *node = NULLP; + + TRC3(kwUtlGetTxBuf) + //printf("G-sn(%d)\n", sn); + + hashKey = (sn % KW_TX_BUF_BIN_SIZE ); + + txBufLstCp = &txBufLst[hashKey]; + CM_LLIST_FIRST_NODE(txBufLstCp, node); + while(node) + { + txBuf = (KwTx *) node->node; + if(txBuf->sn == sn) + { + RETVALUE(txBuf); + } + CM_LLIST_NEXT_NODE(txBufLstCp, node); + } + RETVALUE(NULLP); +} /* kwUtlStoreTxBuf */ +/** + * + * @brief Delete the DL buffer from the list + * + * + * @Description + * + * Use the SN % binSize as key and retrieve the DL buffer + * @param[in] txBufLst List CP array + * @param[in] sn sn of the transmitted bffer + * + * + * @return Void + */ +#ifdef ANSI +PUBLIC Void kwUtlDelTxBuf +( +CmLListCp *txBufLst, +KwTx *txBuf, +KwCb *gCb +) +#else +PUBLIC Void kwUtlDelTxBuf(txBufLst, txBuf, gCb) +CmLListCp *txBufLst; +KwTx *txBuf; +KwCb *gCb; +#endif +{ + U32 hashKey; + CmLListCp *txBufLstCp; + + TRC3(kwUtlDelTxBuf) + + hashKey = (txBuf->sn % KW_TX_BUF_BIN_SIZE ); + + txBufLstCp = &txBufLst[hashKey]; + //printf("D-sn(%d)\n", txBuf->hdr.sn); + cmLListDelFrm(txBufLstCp, &txBuf->lnk); + KW_FREE_WC(gCb, txBuf, sizeof(KwTx)); + RETVOID; +} /* kwUtlDelTxBuf */ + +/** + * + * @brief Remove the DL buffer from the list + * + * + * @Description + * + * Use the SN % binSize as key and retrieve the DL buffer + * @param[in] txBufLst List CP array + * @param[in] sn sn of the transmitted bffer + * + * + * @return Void + */ +#ifdef ANSI +PUBLIC Void kwUtlRemovTxBuf +( +CmLListCp *txBufLst, +KwTx *txBuf, +KwCb *gCb +) +#else +PUBLIC Void kwUtlRemovTxBuf(txBufLst, txBuf, gCb) +CmLListCp *txBufLst; +KwTx *txBuf; +KwCb *gCb; +#endif +{ + U32 hashKey; + CmLListCp *txBufLstCp; + + TRC3(kwUtlRemovTxBuf) + + hashKey = (txBuf->sn % KW_TX_BUF_BIN_SIZE ); + + txBufLstCp = &txBufLst[hashKey]; + //printf("D-sn(%d)\n", txBuf->hdr.sn); + cmLListDelFrm(txBufLstCp, &txBuf->lnk); + RETVOID; +} /* kwUtlRemovTxBuf */ + + + +/********************************************************************30** + End of file +**********************************************************************/ diff --git a/src/5gnrrlc/kw_utl_ul.c b/src/5gnrrlc/kw_utl_ul.c new file mode 100755 index 000000000..ff12ea81b --- /dev/null +++ b/src/5gnrrlc/kw_utl_ul.c @@ -0,0 +1,1222 @@ +/******************************************************************************* +################################################################################ +# Copyright (c) [2017-2019] [Radisys] # +# # +# 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. # +################################################################################ +*******************************************************************************/ + +/********************************************************************** + + Name: LTE-RLC Layer + + Type: C file + + Desc: Source code for RLC Utility Module + This file contains following functions + + --kwUtlSndToLi + --kwUtlRcvFrmLi + --kwUtlEmptySduQ + --kwUtlSndDatInd + --kwUtlShutDown + + File: kw_utl_ul.c + +**********************************************************************/ +static const char* RLOG_MODULE_NAME="UTL"; +static int RLOG_MODULE_ID=2048; +static int RLOG_FILE_ID=210; + +/** @file kw_utl_ul.c +@brief RLC Utility Module +*/ + +/* header (.h) include files */ +#include "envopt.h" /* environment options */ +#include "envdep.h" /* environment dependent */ +#include "envind.h" /* environment independent */ +/* kw005.201 added support for L2 Measurement */ +#ifdef LTE_L2_MEAS +#include +#endif + +#include "gen.h" /* general */ +#include "ssi.h" /* system services */ +#include "cm5.h" /* common timer defines */ +#include "cm_tkns.h" /* common tokens defines */ +#include "cm_mblk.h" /* common memory allocation library defines */ +#include "cm_llist.h" /* common link list defines */ +#include "cm_hash.h" /* common hash list defines */ +#include "cm_lte.h" /* common LTE defines */ +#include "ckw.h" /* CKW defines */ +#include "kwu.h" /* KWU defines */ +#include "lkw.h" /* LKW defines */ +#include "rgu.h" /* RGU defines */ + +#include "kw_env.h" /* RLC environment options */ +#include "kw.h" /* RLC defines */ +#include "kw_err.h" /* Error defines */ +#include "kw_ul.h" /* RLC Uplink defines */ + +/* extern (.x) include files */ +#include "gen.x" /* general */ +#include "ssi.x" /* system services */ + +#include "cm5.x" /* common timer library */ +#include "cm_tkns.x" /* common tokens */ +#include "cm_mblk.x" /* common memory allocation */ +#include "cm_llist.x" /* common link list */ +#include "cm_hash.x" /* common hash list */ +#include "cm_lte.x" /* common LTE includes */ +#include "cm_lib.x" /* common memory allocation library */ +#include "ckw.x" /* CKW includes */ +#include "kwu.x" /* KWU includes */ +#include "lkw.x" /* LKW includes */ +#include "rgu.x" /* RGU includes */ + +#include "kw.x" /* RLC inlcudes */ +#include "kw_ul.x" /* RLC uplink includes */ +#include "ss_rbuf.h" +#include "ss_rbuf.x" +#ifdef SS_RBUF +PUBLIC S16 SMrkUlPkt(Buffer *mbuf); +#endif +PUBLIC KwAmRecBuf* kwUtlGetRecBuf(CmLListCp *recBufLst, KwSn sn); +#define KW_MODULE (KW_DBGMASK_DUT | KW_DBGMASK_UL) /* for debugging purpose */ + + +/** + * + * @brief + * Handler for receiving data for multiple logical channels from MAC. + * + * @details + * This function receives the data sent by MAC for one or more + * logical channels.It calls the UMM or AMM functions to process + * the PDUs and send them to the uppper layer. + * + * @param[in] gCb - RLC instance control block + * @param[in] datIndInfo - Data Indication Information containing the PDU(s) + * for one or more logical channels + * + * @return S16 + * -# ROK + * -# RFAILED + * + */ +#ifdef ANSI +PUBLIC S16 kwUtlRcvFrmLi +( +KwCb *gCb, +KwDatIndInfo *datIndInfo +) +#else +PUBLIC S16 kwUtlRcvFrmLi(gCb,datIndInfo) +KwCb *gCb; +KwDatIndInfo *datIndInfo; +#endif +{ + U32 count; /* Loop Counter */ + KwPduInfo *pduInfo; /* PDU Information */ + KwUlRbCb *rbCb; /* RB Control Block */ + KwUlUeCb *ueCb; /* UE Control Block */ +/* kw005.201 added support for L2 Measurement */ + + TRC2(kwUtlRcvFrmLi) + + + ueCb = NULLP; + + /* fetch UeCb */ + if( ROK != kwDbmFetchUlUeCb(gCb,datIndInfo->rnti,datIndInfo->cellId,&(ueCb))) + { + /* Fetch UeCb failed */ + RLOG_ARG1(L_ERROR,DBG_CELLID,datIndInfo->cellId, + "UEID:%d UeCb not found", + datIndInfo->rnti); + /* free the buffers inside the datIndInfo */ + U32 i,j; + for(i = 0; i< datIndInfo->numLch; i++) + { + for(j = 0; j < datIndInfo->lchData[i].pdu.numPdu; j++) + { + if(datIndInfo->lchData[i].pdu.mBuf[j]) + { + KW_FREE_BUF_WC(datIndInfo->lchData[i].pdu.mBuf[j]); + } + } + } + + RETVALUE(RFAILED); + } + +#ifdef LTE_L2_MEAS + + if (RGU_L2M_UL_BURST_START == datIndInfo->burstInd) + { + ueCb->isUlBurstActive = TRUE; + } + else + { + ueCb->firstPacketTTI = 0; + ueCb->isUlBurstActive = FALSE; + } +#endif + for ( count = 0;count < datIndInfo->numLch; count++ ) + { + rbCb = ueCb->lCh[datIndInfo->lchData[count].lcId - 1].ulRbCb; + /* kw002.201 Removed allocation of pduInfo */ + pduInfo = &(datIndInfo->lchData[count].pdu); + /* Fix for CR ccpu00138374,sometimes rbCb is NULL in UL path, + * So inorder to avoid the crash, added this preventive check + */ + if(rbCb == NULLP) + { + U32 j; + for(j = 0; j < pduInfo->numPdu; j++) + { + if(pduInfo->mBuf[j]) + { + KW_FREE_BUF_WC(pduInfo->mBuf[j]); + } + } + continue; + } + +#ifdef SS_RBUF + SMrkUlPkt(pduInfo->mBuf[0]); +#endif + if ( rbCb->mode == CM_LTE_MODE_UM ) + { +/* kw005.201 added support for L2 Measurement */ +#ifdef LTE_L2_MEAS + kwUmmProcessPdus(gCb,rbCb, pduInfo, datIndInfo->ttiCnt); +#else + kwUmmProcessPdus(gCb,rbCb,pduInfo); +#endif + } + else if (rbCb->mode == CM_LTE_MODE_AM ) + { +/* kw005.201 added support for L2 Measurement */ +#ifdef LTE_L2_MEAS + kwAmmProcessPdus(gCb,rbCb, pduInfo, datIndInfo->ttiCnt); +#else + kwAmmProcessPdus(gCb,rbCb,pduInfo); +#endif + } + } + RETVALUE(ROK); +} + +/** + * + * @brief + * Handler for sending Data Indication to the upper layer. + * + * @Details + * This function is used to send re-assembled SDU to the upper layer. + * + * @param[in] gCb - RLC instance Control Block + * @param[in] rbCb - RB Control Block + * @param[in] sdu - SDU to be sent to upper layer + * + * @return S16 + * -# ROK + */ +#ifdef ANSI +PUBLIC S16 kwUtlSndDatInd +( +KwCb *gCb, +KwUlRbCb *rbCb, +Buffer *sdu +) +#else +PUBLIC S16 kwUtlSndDatInd(gCb,rbCb,sdu) +KwCb *gCb; +KwUlRbCb *rbCb; +Buffer *sdu; +#endif +{ +#ifndef KW_PDCP + KwKwuSapCb *kwKwSap; /* KWU SAP Information */ + KwuDatIndInfo *datIndInfo; /* Data Indication Information */ + KwuDatIndInfo datIndInfoTmp; +#endif + + TRC3(kwUtlSndDatInd) + + +#ifndef KW_PDCP + kwKwSap = gCb->u.ulCb->kwuUlSap + KW_UI_PDCP; + /* Creating static memory for KwuDatIndInfo. #else will be + * removed once the testing is done on all platforms */ + datIndInfo = &datIndInfoTmp; + +#if (ERRCLASS & ERRCLS_ADD_RES ) + if ( datIndInfo == NULLP ) + { + RLOG_ARG2(L_FATAL,DBG_RBID,rbCb->rlcId.rbId, + "Memory allocation failed UEID:%d CELLID:%d", + rbCb->rlcId.ueId, + rbCb->rlcId.cellId); + KW_FREE_BUF(sdu); + RETVALUE(RFAILED); + } +#endif /* ERRCLASS & ERRCLS_ADD_RES */ + + KW_MEM_CPY(&(datIndInfo->rlcId),&(rbCb->rlcId),sizeof(CmLteRlcId)); + /* Set the "isOutofSeq" flag for each packet + * If packets are in-sequence set flag as TRUE else FALSE */ + datIndInfo->isOutOfSeq = rbCb->m.amUl.isOutOfSeq; +#endif /* KW_PDCP */ + + /* If trace flag is enabled send the trace indication */ + if(gCb->init.trc == TRUE) + { + /* Populate the trace params */ + kwLmmSendTrc(gCb,KWU_EVT_DAT_IND, sdu); + } +#ifndef KW_PDCP + + KwUiKwuDatInd(&kwKwSap->pst, kwKwSap->suId, datIndInfo, sdu); +#endif + RETVALUE(ROK); +} /* kwUtlSndDatInd */ + + +PRIVATE Void dumpRLCUlRbInformation(KwUlRbCb* ulRbCb) +{ + if(ulRbCb->mode == CM_LTE_MODE_UM) + { + U32 i; + U32 pdusInReceptionBuffer = 0; + U32 windSz = ulRbCb->m.umUl.umWinSz << 1; + + for(i = 0; i< windSz; i++) + { + if(ulRbCb->m.umUl.recBuf[i] != NULLP) + { + pdusInReceptionBuffer++; + } + } + + RLOG_ARG3(L_DEBUG,DBG_RBID,ulRbCb->rlcId.rbId, + "UM UL UEID:%d CELLID:%d Reception Buffer size = %d", + (int)ulRbCb->rlcId.ueId, + (int)ulRbCb->rlcId.cellId, + (int)pdusInReceptionBuffer); + } + else if(ulRbCb->mode == CM_LTE_MODE_AM) + { + U32 i; + U32 pdusInReceptionBuffer = 0; + U32 totalSegs = 0; + U32 windSz = KW_AM_GET_WIN_SZ(ulRbCb->m.amUl.snLen) << 1; + + for(i = 0; i< windSz; i++) + { + KwAmRecBuf *recBuf = kwUtlGetRecBuf(ulRbCb->m.amUl.recBufLst, i); + if(recBuf != NULLP) + { + pdusInReceptionBuffer++; + totalSegs += (recBuf->segLst.count); + } + } + + RLOG_ARG4(L_DEBUG,DBG_RBID,ulRbCb->rlcId.rbId, + "AM UL UEID:%d CELLID:%d Reception Buf size = %d" + "total segs = %d", + (int)ulRbCb->rlcId.ueId, + (int)ulRbCb->rlcId.cellId, + (int)pdusInReceptionBuffer, + (int)totalSegs); + } +} + +Void DumpRLCUlDebugInformation(Void) +{ + KwCb* ulInst = kwCb[0]; /* TODO : Check whether UL is 0 or 1 */ + KwUlCb* ulCb = ulInst->u.ulCb; + KwUlUeCb *ueCb = NULLP; + + /* Until no more ueCb is ueLstCp hash list get and delete ueCb */ + while (ROK == cmHashListGetNext(&ulCb->ueLstCp, + (PTR) ueCb, + (PTR *)&ueCb)) + { + U32 i; + for(i = 0; i< KW_MAX_SRB_PER_UE; i++) + { + KwUlRbCb* ulRbCb = ueCb->srbCb[i]; + if(ulRbCb != NULLP) + { + dumpRLCUlRbInformation(ulRbCb); + } + } + for(i = 0; i< KW_MAX_DRB_PER_UE; i++) + { + KwUlRbCb* ulRbCb = ueCb->drbCb[i]; + if(ulRbCb != NULLP) + { + dumpRLCUlRbInformation(ulRbCb); + } + } + } +} + + +/* + * kwUtlFreeUlRbCb() function is split into two functions + * - kwAmmFreeUlRbCb() ---> gp_amm_ul.c + * - kwUmmFreeUlRbCb() ---> gp_umm_ul.c + * and placed in respective files mentioned above + */ + + + +/* kw005.201 added support for L2 Measurement */ +#ifdef LTE_L2_MEAS + +/** + * + * @brief + * Handler for initialisation of measurement + * + * @param[in] gCb - RLC instance Control Block + * + * @return S16 + * -# ROK + */ +S16 kwUtlL2MeasUlInit(KwCb *gCb) +{ + U16 cntr; + + gCb->u.ulCb->kwL2Cb.kwNumMeas=0; + for(cntr = 0; cntr < LKW_MAX_L2MEAS; cntr++) + { + cmMemset((U8 *)&(gCb->u.ulCb->kwL2Cb.kwL2EvtCb[cntr]), 0, sizeof(KwL2MeasEvtCb)); + } + gCb->u.ulCb->kwL2Cb.kwL2EvtCb[KW_L2MEAS_UL_IP].measCb.measType = LKW_L2MEAS_UL_IP; + RETVALUE(ROK); +} +/** + * + * @brief + * + * Handler to calculate the Ul Ip throughput for a LCH + * + * @b Description: + * + * + * @param[in] rbCb RB control block + * @param[in] pdu Pdu of LCH + * + * @return Void + * + */ +#ifdef ANSI +PUBLIC Void kwUtlCalUlIpThrPutIncTTI +( +KwCb *gCb, +KwUlRbCb *rbCb, +U32 ttiCnt +) +#else +PUBLIC Void kwUtlCalUlIpThrPutIncTTI(gCb, rbCb, ttiCnt) +KwCb *gCb; +KwUlRbCb *rbCb; +U32 ttiCnt; +#endif +{ + VOLATILE U32 startTime = 0; + TRC2(kwUtlCalUlIpThrPutIncTTI) + + /*starting Task*/ + SStartTask(&startTime, PID_RLC_IP_TPT_INCTTI); +#ifndef ALIGN_64BIT + RLOG_ARG4(L_UNUSED, DBG_RBID,rbCb->rlcId.rbId,"Log for ul ip throughput:" + "RB_MeasOn:%d ttiCnt :%ld UEID:%d CELLID:%d", + rbCb->rbL2Cb.measOn,ttiCnt, + rbCb->rlcId.ueId, + rbCb->rlcId.cellId); +#else + RLOG_ARG4(L_UNUSED,DBG_RBID,rbCb->rlcId.rbId, "Log for ul ip throughput:" + "RB_MeasOn:%d ttiCnt :%d UEID:%d CELLID:%d", + rbCb->rbL2Cb.measOn,ttiCnt, + rbCb->rlcId.ueId, + rbCb->rlcId.cellId); +#endif + + /*Check if UL IP throughput measurement is ON for this RB or not*/ + if(KW_MEAS_IS_UL_IP_MEAS_ON_FOR_RB(gCb,rbCb)) + { + if (TRUE == rbCb->ueCb->isUlBurstActive) + { + if (ttiCnt < rbCb->l2MeasIpThruput.prevTtiCnt) + { + /*Removed Error Print*/ + } + if (rbCb->l2MeasIpThruput.prevTtiCnt != 0) + { + rbCb->rbL2Cb.l2Sts[KW_L2MEAS_UL_IP]->ulIpThruput.timeSummation += + (ttiCnt - rbCb->l2MeasIpThruput.prevTtiCnt); + } + else + { + rbCb->ueCb->firstPacketTTI = ttiCnt; + } + rbCb->l2MeasIpThruput.prevTtiCnt = ttiCnt; + } + else + { + rbCb->l2MeasIpThruput.prevTtiCnt = 0; + } + } + + /*stopping Task*/ + SStopTask(startTime, PID_RLC_IP_TPT_INCTTI); +} /* kwUtlCalUlIpThrPutIncTTI */ + + +/** + * + * @brief + * + * Handler to calculate the Ul Ip throughput for a LCH + * + * @b Description: + * + * + * @param[in] rbCb RB control block + * @param[in] pdu Pdu of LCH + * + * @return Void + * + */ +#ifdef ANSI +PUBLIC Void kwUtlCalUlIpThrPut +( +KwCb *gCb, +KwUlRbCb *rbCb, +Buffer *pdu, +U32 ttiCnt +) +#else +PUBLIC Void kwUtlCalUlIpThrPut(gCb, rbCb, pdu, ttiCnt) + KwCb *gCb; + KwUlRbCb *rbCb; + Buffer *pdu; + U32 ttiCnt; +#endif +{ + MsgLen rlcSduSz = 0; /*Holds length of Rlc Sdu*/ + VOLATILE U32 startTime = 0; + TRC2(kwUtlCalUlIpThrPut) + + + /*starting Task*/ + SStartTask(&startTime, PID_RLC_IP_TPT_INCVOL); + + /*Check if UL IP throughput measurement is ON for this RB or not*/ + if(KW_MEAS_IS_UL_IP_MEAS_ON_FOR_RB(gCb, rbCb) && + (TRUE == rbCb->ueCb->isUlBurstActive) && + (rbCb->ueCb->firstPacketTTI) && + (ttiCnt != rbCb->ueCb->firstPacketTTI)) + { + SFndLenMsg(pdu, &rlcSduSz); + + rbCb->rbL2Cb.l2Sts[KW_L2MEAS_UL_IP]->ulIpThruput.volSummation += rlcSduSz; + + } + /*stopping Task*/ + SStopTask(startTime, PID_RLC_IP_TPT_INCVOL); +} /* kwUtlCalUlIpThrPut */ + + +/** + * + * @brief Handler for L2 Measurement timer expiry. + * + * + * @b Description + * This function is called when the l2 measurement timer expires. + * This function sends a consolidates the mesaurements taken during + * this time and sends the confirm . + * + * @param[in] measEvtCb Measurement Event Control Block. + * + * + * @return S16 + * -# ROK + */ + +#ifdef ANSI +PUBLIC S16 kwUtlHdlL2TmrExp +( +KwCb *gCb, +KwL2MeasEvtCb *measEvtCb +) +#else +PUBLIC S16 kwUtlHdlL2TmrExp(measEvtCb) +KwCb *gCb; +KwL2MeasEvtCb *measEvtCb; +#endif +{ + TRC3(kwUtlHdlL2TmrExp) + +#ifdef LTE_L2_MEAS_RLC + U16 qciIdx; + KwL2MeasCb *measCb; + + /* Clean up the RB data structures */ + if((measEvtCb->measCb.measType & LKW_L2MEAS_ACT_UE) && + (measEvtCb->measCb.val.nonIpThMeas.numSamples)) + { + measCb = &measEvtCb->measCb; + + for(qciIdx = 0; qciIdx < measCb->val.nonIpThMeas.numQci;qciIdx++) + { + measCb->val.nonIpThMeas.measData[measCb->val.nonIpThMeas.qci[qciIdx]].actUe.numActvUe += + kwCb.kwL2Cb.numActUe[measCb->val.nonIpThMeas.qci[qciIdx]]; + measCb->val.nonIpThMeas.measData[measCb->val.nonIpThMeas.qci[qciIdx]].actUe.sampOc++; + } + measEvtCb->val.nonIpThMeas.measCb.numSamples--; + kwStartTmr(gCb, (PTR)measEvtCb, KW_EVT_L2_TMR); + RETVALUE(ROK); + } +#endif + + kwUtlSndUlL2MeasCfm(gCb, measEvtCb); + + RETVALUE(ROK); +} /* kwUtlHdlL2TmrExp */ +/** + * + * @brief Handler for Sending L2 Measurement confirm. + * + * + * @b Description + * This function sends a consolidates the mesaurements taken during + * this time and sends the confirm . + * + * @param[in] measEvtCb Measurement Event Control Block. + * + * + * @return S16 + * -# ROK + */ + +#ifdef ANSI +PUBLIC S16 kwUtlSndUlL2MeasCfm +( +KwCb *gCb, +KwL2MeasEvtCb *measEvtCb +) +#else +PUBLIC S16 kwUtlSndUlL2MeasCfm(gCb, measEvtCb) +KwCb *gCb; +KwL2MeasEvtCb *measEvtCb; +#endif +{ + U32 qciIdx; + KwL2MeasCb *measCb; + KwL2MeasCfmEvt measCfmEvt; + + U64 ulDataVol; + U64 ulTime; + U16 cntr; + /* Discard new changes starts */ + U8 qci = 0; + U32 cfmIdx =0; + /* Discard new changes ends */ + + TRC3(kwUtlSndUlL2MeasCfm) + + /* kw006.201 ccpu00120058 emoved 64 bit compilation warning */ +#ifndef ALIGN_64BIT + RLOG1(L_DEBUG,"kwUtlSndUlL2MeasCfm(transId(%ld))", measEvtCb->transId); +#else + RLOG1(L_DEBUG,"kwUtlSndUlL2MeasCfm(transId(%d))", measEvtCb->transId); +#endif + + /* Clean up the RB data structures */ + measCb = &measEvtCb->measCb; + + cmMemset((U8*)&measCfmEvt, 0, sizeof(KwL2MeasCfmEvt)); + measCfmEvt.transId = measEvtCb->transId; + + measCfmEvt.measType = measCb->measType; + measCfmEvt.status.status = LCM_PRIM_OK; + measCfmEvt.status.reason = LCM_REASON_NOT_APPL; + + if( measCb->measType & LKW_L2MEAS_UL_IP) + { + KwL2MeasCbUeMeasInfo *pUeInfoLstCb = measCb->val.ipThMeas.ueInfoLst; + KwL2MeasCfmUeInfoLst *pUeInfoLstCfm = measCfmEvt.val.ipThMeas.ueInfoLst; + for(cntr = 0;(cntr < measCb->val.ipThMeas.numUes) && (cntr < gCb->genCfg.maxUe);cntr++) + { + pUeInfoLstCfm[cfmIdx].numCfm = 0; + if (pUeInfoLstCb[cntr].isValid == TRUE) + { + pUeInfoLstCfm[cfmIdx].ueId = pUeInfoLstCb[cntr].ueId; + pUeInfoLstCfm[cfmIdx].cellId = pUeInfoLstCb[cntr].cellId; + + for(qciIdx = 0; qciIdx < pUeInfoLstCb[cntr].numQci; qciIdx++) + { + qci = pUeInfoLstCb[cntr].qci[qciIdx]; + pUeInfoLstCfm[cfmIdx].measCfm[pUeInfoLstCfm[cfmIdx].numCfm].qci = qci; + + if(measCb->measType & LKW_L2MEAS_UL_IP) + { + ulDataVol = pUeInfoLstCb[cntr].measData[qci].ulIpThruput.volSummation; + ulTime = pUeInfoLstCb[cntr].measData[qci].ulIpThruput.timeSummation; + if(0 == ulTime) + { + pUeInfoLstCfm[cfmIdx].measCfm[pUeInfoLstCfm[cfmIdx].numCfm].val.ipThrput.ulIpThPut = 0; + } + else + { + pUeInfoLstCfm[cfmIdx].measCfm[pUeInfoLstCfm[cfmIdx].numCfm].val.ipThrput.ulIpThPut = (ulDataVol / ulTime); + + /* Converting it to kbps */ + pUeInfoLstCfm[cfmIdx].measCfm[pUeInfoLstCfm[cfmIdx].numCfm].val.ipThrput.ulIpThPut *= 8; + + } + /* Reset the values after reporting to Application */ + pUeInfoLstCb[cntr].measData[qci].ulIpThruput.volSummation = 0; + pUeInfoLstCb[cntr].measData[qci].ulIpThruput.timeSummation = 0; + } + pUeInfoLstCfm[cfmIdx].numCfm++; + } + cfmIdx++; + } + } + measCfmEvt.val.ipThMeas.numUes = cfmIdx; + } + KwMiLkwL2MeasCfm(&gCb->genCfg.lmPst, &measCfmEvt); + RETVALUE(ROK); +} /* kwUtlSndUlL2MeasCfm */ +/** + * + * @brief Handler for Sending Negative confirm . + * + * + @b Description + * This function is called when the l2 measurement cannot be started + * This function sends negative confirm for all the requests + * + * @param[in] gCb - RLC instance control block + * @param[in] measReqEvt Measurement Req Structure + * @param[in] measCfmEvt Confirmation to be sent to layer manager + * + * + * @return S16 + * -# ROK + */ + +#ifdef ANSI +PUBLIC S16 kwUtlSndUlL2MeasNCfm +( +KwCb *gCb, +KwL2MeasReqEvt *measReqEvt, +KwL2MeasCfmEvt *measCfmEvt +) +#else +PUBLIC S16 kwUtlSndUlL2MeasNCfm(gCb, measReqEvt, measCfmEvt) +KwCb *gCb; +KwL2MeasReqEvt *measReqEvt; +KwL2MeasCfmEvt *measCfmEvt; +#endif +{ + TRC3(kwUtlSndUlL2MeasNCfm) + + KwMiLkwL2MeasCfm(&gCb->genCfg.lmPst, measCfmEvt); + RETVALUE(ROK); +} /* kwUtlSndL2MeasNCfm */ + +#ifdef LTE_L2_MEAS_RLC +/** + * @brief Validates the measurement request parameters. + * + * @details + * + * Function :kwUtlValidateL2Meas + * + * @param[in] measReqEvt L2 measurement request received from layer manager. + * @param[out] measCfmEvt L2 measurement confirm to be prepared. + * @param[out] lChId List of LCh for the given Ue corresponding to QCIs + given in measurement request. + * @param[out] numLCh Number of LCh in array lChId. + **/ + +#ifdef ANSI +PUBLIC S16 kwUtlValidateL2Meas +( +KwL2MeasReqEvt *measReqEvt, +KwL2MeasCfmEvt *measCfmEvt, +CmLteLcId *lChId, +U8 *numLCh +) +#else +PUBLIC S16 kwUtlValidateL2Meas(measReqEvt, measCfmEvt, lChId, numLCh) +KwL2MeasReqEvt *measReqEvt; +KwL2MeasCfmEvt *measCfmEvt; +CmLteLcId *lChId; +U8 *numLCh; +#endif +{ + U8 measType; + S16 ret; + U8 qciIdx; + U8 qci; + U8 idx; + U8 *qciVal; + U8 numQci; + KwRbCb *rbCb; + + KwUeCb *ueCb; + RbCb **rbCbLst; + U8 rbIdx; + U8 lsbNibble = 0; + U8 msbNibble = 0; + U8 numFaild = 0; + + + TRC3(kwUtlValidateL2Meas) + + idx = 0; + rbCb = NULLP; + ret = ROK; + measType = measReqEvt->measReq.measType; + /* Check for the range of measType */ + /* LKW_L2MEAS_DL_IP+ LKW_L2MEAS_UL_IP = 0x0030*/ + if((measType == 0x00) || + measType > 0x30) + { + measCfmEvt->transId = measReqEvt->transId; + measCfmEvt->measType = measType; + measCfmEvt->status.status = LCM_PRIM_NOK; + measCfmEvt->status.reason = LKW_CAUSE_INVALID_MEASTYPE; + RETVALUE(RFAILED); + } + /*User can either request for Active UE,* + *Dl delay, Dl discard, Uu Loss OR Dl ip throughput, Ul ip throughput. */ + lsbNibble = measType & 0x0F; + msbNibble = measType & 0xF0; + + if( (lsbNibble != 0) && (msbNibble != 0) ) + { + measCfmEvt->transId = measReqEvt->transId; + measCfmEvt->measType = measType; + measCfmEvt->status.status = LCM_PRIM_NOK; + measCfmEvt->status.reason = LKW_CAUSE_INVALID_MEASTYPE; + RETVALUE(RFAILED); + } + + /* Check for total maximum number of Measurement Control Block */ + if(kwCb.kwL2Cb.kwNumMeas >= LKW_MAX_L2MEAS ) + { + measCfmEvt->transId = measReqEvt->transId; + measCfmEvt->measType = measType; + measCfmEvt->status.status = LCM_PRIM_NOK; + measCfmEvt->status.reason = LKW_CAUSE_EXCEED_NUMMEAS; + RETVALUE(RFAILED); + } + + /* Check that number of samples should be a non-zero value */ + if(((measType & LKW_L2MEAS_ACT_UE) && + (measReqEvt->measReq.val.nonIpThMeas.numSamples == 0))) + { + measCfmEvt->transId = measReqEvt->transId; + measCfmEvt->measType = measType; + measCfmEvt->status.status = LCM_PRIM_NOK; + measCfmEvt->status.reason = LKW_CAUSE_ZERO_NUMSAM; + RETVALUE(RFAILED); + } + /* Check that measurement period should be completely divisible * + * number of sample. */ + if(((measType & LKW_L2MEAS_ACT_UE) && + ((measReqEvt->measPeriod % + measReqEvt->measReq.val.nonIpThMeas.numSamples) != 0))) + { + measCfmEvt->transId = measReqEvt->transId; + measCfmEvt->measType = measType; + measCfmEvt->status.status = LCM_PRIM_NOK; + measCfmEvt->status.reason = LKW_CAUSE_INVALID_NUMSAM; + RETVALUE(RFAILED); + } + { + numQci = measReqEvt->measReq.val.nonIpThMeas.numQci; + qciVal = measReqEvt->measReq.val.nonIpThMeas.qci; + } + /* Check whether qci is configured or not */ + for(qciIdx = 0; qciIdx < numQci; qciIdx++) + { + qci = qciVal[qciIdx]; + ret = cmHashListFind(&(kwCb.kwL2Cb.qciHlCp), + (U8 *)&qci, (U16)sizeof(qci), 0, (PTR *)&rbCb); + if(ret != ROK) + { + measCfmEvt->val.nonIpThMeas.measCfm[measCfmEvt->val.nonIpThMeas.numCfm].qci = qci; + measCfmEvt->val.nonIpThMeas.numCfm++; + + } + } + if(measCfmEvt->val.nonIpThMeas.numCfm > 0) + { + measCfmEvt->status.status = LCM_PRIM_NOK; + measCfmEvt->status.reason = LKW_CAUSE_INVALID_QCI; + measCfmEvt->measType = measType; + measCfmEvt->transId = measReqEvt->transId; + RETVALUE(RFAILED); + } + { + for(qciIdx = 0; qciIdx < numQci; qciIdx++) + { + if(kwCb.kwL2Cb.measOn[qci] & measReqEvt->measReq.measType) + { + /* measurement is already ongoing */ + measCfmEvt->status.status = LCM_PRIM_NOK; + measCfmEvt->status.reason = LKW_CAUSE_MEAS_ALREADY_ENA; + measCfmEvt->val.nonIpThMeas.measCfm[measCfmEvt->val.nonIpThMeas.numCfm].qci = qci; + measCfmEvt->measType = measType; + measCfmEvt->val.nonIpThMeas.numCfm++; + } + } + } + if(measCfmEvt->val.nonIpThMeas.numCfm > 0) + { + measCfmEvt->transId = measReqEvt->transId; + RETVALUE(RFAILED); + } + + RETVALUE(ROK); +}/* kwUtlValidateL2Meas */ +#endif + +#ifdef ANSI +PUBLIC S16 kwUtlValidateIpThL2Meas +( +KwL2MeasReqEvt *measReqEvt, +KwL2MeasCfmEvt *measCfmEvt +) +#else +PUBLIC S16 kwUtlValidateIpThL2Meas(measReqEvt, measCfmEvt) +KwL2MeasReqEvt *measReqEvt; +KwL2MeasCfmEvt *measCfmEvt; +#endif +{ + U8 measType; + U8 lsbNibble = 0; + U8 msbNibble = 0; + + TRC3(kwUtlValidateIpThL2Meas) + + measType = measReqEvt->measReq.measType; + /* Check for the range of measType */ + /* LKW_L2MEAS_DL_IP+ LKW_L2MEAS_UL_IP = 0x0030*/ + if((measType == 0x00) || + measType > 0x30) + { + measCfmEvt->transId = measReqEvt->transId; + measCfmEvt->measType = measType; + measCfmEvt->status.status = LCM_PRIM_NOK; + measCfmEvt->status.reason = LKW_CAUSE_INVALID_MEASTYPE; + RETVALUE(RFAILED); + } + /*User can either request for Active UE,* + *Dl delay, Dl discard, Uu Loss OR Dl ip throughput, Ul ip throughput. */ + lsbNibble = measType & 0x0F; + msbNibble = measType & 0xF0; + + if( (lsbNibble != 0) && (msbNibble != 0) ) + { + measCfmEvt->transId = measReqEvt->transId; + measCfmEvt->measType = measType; + measCfmEvt->status.status = LCM_PRIM_NOK; + measCfmEvt->status.reason = LKW_CAUSE_INVALID_MEASTYPE; + RETVALUE(RFAILED); + } + RETVALUE(ROK); +}/* kwUtlValidateL2Meas */ + +/** + * + * @brief Handler for resetting the RB data structures + * + * + * @b Description + * This function resets the RB data structure after the expiry of + * measurement timer. + * + * @param[in] measCb Measurement Control Block. + * + * + * @return Void + */ +#ifdef ANSI + +PUBLIC Void kwUtlResetUlL2MeasInKwRb +( +KwCb *gCb, +KwL2MeasCb *measCb, +U8 measType +) +#else +PUBLIC Void kwUtlResetUlL2MeasInKwRb(measCb, measType) +KwCb *gCb; +KwL2MeasCb *measCb; +U8 measType; +#endif +{ + U32 rbIdx; + U32 ueIdx; + U32 qciIdx; + KwUlUeCb *ueCb = NULL; + + + + if (measCb->measType & LKW_L2MEAS_UL_IP) + { + for(ueIdx = 0; ueIdx < measCb->val.ipThMeas.numUes; ueIdx++) + { + if (measCb->val.ipThMeas.ueInfoLst[ueIdx].isValid == TRUE) + { + for (qciIdx =0; qciIdx < measCb->val.ipThMeas.ueInfoLst[ueIdx].numQci; qciIdx++) + { + if (measType & LKW_L2MEAS_UL_IP) + { + measCb->val.ipThMeas.ueInfoLst[ueIdx].measData[qciIdx].ulIpThruput.volSummation = 0; + measCb->val.ipThMeas.ueInfoLst[ueIdx].measData[qciIdx].ulIpThruput.timeSummation = 0; + } + } + + if(ROK != kwDbmFetchUlUeCb(gCb, measCb->val.ipThMeas.ueInfoLst[ueIdx].ueId, + measCb->val.ipThMeas.ueInfoLst[ueIdx].cellId, &ueCb)) + { + continue; + } + + for (rbIdx = 0; rbIdx < KW_MAX_DRB_PER_UE; rbIdx++) + { + if (ueCb->drbCb[rbIdx]) + { + ueCb->drbCb[rbIdx]->rbL2Cb.measOn &= ~measType; + } + } + } + } + } +} /* kwUtlResetUlL2MeasInKwRb */ + +/** + * + * @brief Handler for storing address of MeasData in rbCb at right index + * + * + * @b Description + * This function is called when LM sends measReq message to RLC. + * + * @param[in] + * @param[out] + * @param[in] + * + * + * @return S16 + * -# ROK + */ +#ifdef ANSI +PUBLIC Void kwUtlPlcMeasDatInL2Sts +( +KwL2Cntr *measData, +KwL2MeasRbCb *rbL2Cb, +U8 measType +) +#else +PUBLIC Void kwUtlPlcMeasDatInL2Sts(measData, rbL2Cb, measType) +KwL2Cntr *measData; +KwL2MeasRbCb *rbL2Cb; +U8 measType; +#endif +{ + TRC3(kwUtlPlcMeasDatInL2Sts) + + /* We should check the number of measType in the request. This can be done + * by looking at each bit in the measType. Also store the measData in the + * correct index of l2Sts in RbCb. + * */ + + if(measType & LKW_L2MEAS_ACT_UE) + { + rbL2Cb->l2Sts[KW_L2MEAS_ACT_UE] = measData; + } + if(measType & LKW_L2MEAS_UU_LOSS) + { + rbL2Cb->l2Sts[KW_L2MEAS_UU_LOSS] = measData; + } + if(measType & LKW_L2MEAS_DL_IP ) + { + rbL2Cb->l2Sts[KW_L2MEAS_DL_IP] = measData; + } + if(measType & LKW_L2MEAS_UL_IP) + { + rbL2Cb->l2Sts[KW_L2MEAS_UL_IP] = measData; + } + if(measType & LKW_L2MEAS_DL_DISC) + { + rbL2Cb->l2Sts[KW_L2MEAS_DL_DISC] = measData; + } + if(measType & LKW_L2MEAS_DL_DELAY) + { + rbL2Cb->l2Sts[KW_L2MEAS_DL_DELAY] = measData; + } +}/* End of kwUtlPlcMeasDatInL2Sts */ +#endif /* LTE_L2_MEAS */ + +/** + * + * @brief Store the UL buffer in hashList + * + * + * @b Description + * + * Use the SN % binSize as key and store the received UL buffer + * @param[in] recBufLst List CP array + * @param[in] recBuf received buffer + * @param[in] sn sn of the received buffer + * + * + * @return Void + */ +#ifdef ANSI +PUBLIC Void kwUtlStoreRecBuf +( +CmLListCp *recBufLst, +KwAmRecBuf *recBuf, +KwSn sn +) +#else +PUBLIC Void kwUtlStoreRecBuf(recBufLst, recBuf, sn) +CmLListCp *recBufLst; +KwAmRecBuf *recBuf; +KwSn sn; +#endif +{ + U32 hashKey; + + TRC3(kwUtlStoreRecBuf) + + hashKey = (sn % KW_RCV_BUF_BIN_SIZE ); + recBuf->lnk.node = (PTR)recBuf; + cmLListAdd2Tail(&(recBufLst[hashKey]), &recBuf->lnk); + + RETVOID; +} /* kwUtlStoreRecBuf */ + +/** + * + * @brief Retrieve the UL buffer from the list + * + * + * @Description + * + * Use the SN % binSize as key and retrieve the UL buffer + * @param[in] recBufLst List CP array + * @param[in] sn sn of the received buffer + * + * + * @return Void + */ +#ifdef ANSI +PUBLIC KwAmRecBuf* kwUtlGetRecBuf +( +CmLListCp *recBufLst, +KwSn sn +) +#else +PUBLIC KwAmRecBuf* kwUtlGetRecBuf(recBufLst, sn) +CmLListCp *recBufLst; +KwSn sn; +#endif +{ + U32 hashKey; + CmLListCp *recBufLstCp; + KwAmRecBuf *recBuf; + CmLList *node = NULLP; + + TRC3(kwUtlGetRecBuf) + + hashKey = (sn % KW_RCV_BUF_BIN_SIZE ); + + recBufLstCp = &recBufLst[hashKey]; + CM_LLIST_FIRST_NODE(recBufLstCp, node); + while(node) + { + recBuf = (KwAmRecBuf *) node->node; + if(recBuf->amHdr.sn == sn) + { + RETVALUE(recBuf); + } + CM_LLIST_NEXT_NODE(recBufLstCp, node); + } + RETVALUE(NULLP); +} /* kwUtlStoreRecBuf */ +/** + * + * @brief Delete the UL buffer from the list + * + * + * @Description + * + * Use the SN % binSize as key and retrieve the UL buffer + * @param[in] recBufLst List CP array + * @param[in] sn sn of the received buffer + * + * + * @return Void + */ +#ifdef ANSI +PUBLIC Void kwUtlDelRecBuf +( +CmLListCp *recBufLst, +KwAmRecBuf *recBuf, +KwCb *gCb +) +#else +PUBLIC Void kwUtlDelRecBuf(recBufLst, recBufi, gCb) +CmLListCp *recBufLst; +KwAmRecBuf *recBuf; +KwCb *gCb; +#endif +{ + U32 hashKey; + CmLListCp *recBufLstCp; + + TRC3(kwUtlDelRecBuf) + + hashKey = (recBuf->amHdr.sn % KW_RCV_BUF_BIN_SIZE ); + + recBufLstCp = &recBufLst[hashKey]; + cmLListDelFrm(recBufLstCp, &recBuf->lnk); + KW_FREE_WC(gCb, recBuf, sizeof(KwAmRecBuf)); + + RETVOID; +} /* kwUtlDelRecBuf */ + + + + +/********************************************************************30** + End of file +**********************************************************************/ diff --git a/src/cm/ckw.h b/src/cm/ckw.h new file mode 100755 index 000000000..5c10bc8eb --- /dev/null +++ b/src/cm/ckw.h @@ -0,0 +1,166 @@ +/******************************************************************************* +################################################################################ +# Copyright (c) [2017-2019] [Radisys] # +# # +# 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. # +################################################################################ +*******************************************************************************/ + +/********************************************************************20** + + Name: CKW RRC Control Interface + + Type: C include file + + Desc: This file Contains the Data structures for and prototypes + CKW Interface + + File: ckw.h + +*********************************************************************21*/ + +#ifndef __CKW_H__ +#define __CKW_H__ + +#ifdef __cplusplus +EXTERN "C" { +#endif /*for extern "C"*/ + +/** @file ckw.h + @brief CKW Interface File (ckw.h) +*/ + +/* CKW Interface Hash Defines */ + +/* Loose Coupling define */ +#define CKW_SEL_LC 0 /*!< Loose Coupling Option */ + +/* CKW Interface defines */ +#define CKW_MAX_ENT_CFG 24 /*!< Maximum number of entities to configure */ +/* ckw_h_001.main_3 added support for L2 Measurement */ +#ifdef LTE_L2_MEAS +#define CKW_MAX_QCI 10 +#endif +/* CKW Interface configuration type */ +#define CKW_CFG_ADD 1 /*!< Add RLC Entity */ +#define CKW_CFG_MODIFY 2 /*!< Modify RLC Entity */ +#define CKW_CFG_DELETE 3 /*!< Delete RLC entity */ +#define CKW_CFG_REESTABLISH 4 /*!< Re-establish RLC entity */ +#define CKW_CFG_DELETE_UE 5 /*!< Release RLC entities per UE */ +#define CKW_CFG_DELETE_CELL 6 /*!< Release RLC entities per Cell */ + +/* CKW RLC entity direction configuration */ +#define CKW_CFG_DIR_UL 1 /*!< Unlink direction */ +#define CKW_CFG_DIR_DL 2 /*!< Downlink direction */ +#define CKW_CFG_DIR_BOTH 3 /*!< Both Downlink and Unlink */ + +/* CKW Configuration confirmations */ +#define CKW_CFG_CFM_OK 1 /*!< Configuration confirmation success */ +#define CKW_CFG_CFM_NOK 2 /*!< Configuration confirmation failed */ + +/* CKW Configuration Failure Reasons */ +#define CKW_CFG_REAS_NONE 0 /*!< No Failure */ +#define CKW_CFG_REAS_RB_CREAT_FAIL 1 /*!< RB CB creation Failure */ +#define CKW_CFG_REAS_UE_CREAT_FAIL 2 /*!< UE CB creation Failure */ +#define CKW_CFG_REAS_CELL_CREAT_FAIL 3 /*!< CELL CB creation Failure */ +#define CKW_CFG_REAS_RB_PRSNT 4 /*!< RB CB already present */ +#define CKW_CFG_REAS_LCHTYPE_MIS 5 /*!< Logical channel type mismatch + with mode */ +#define CKW_CFG_REAS_RB_UNKWN 6 /*!< RB Cb unknown */ +#define CKW_CFG_REAS_UE_UNKWN 7 /*!< UE Cb unknown */ +#define CKW_CFG_REAS_CELL_UNKWN 8 /*!< Cell Cb unknown */ +#define CKW_CFG_REAS_RB_DEL_FAIL 9 /*!< RB Cb Deletion Failure */ +#define CKW_CFG_REAS_UE_DEL_FAIL 10 /*!< UE Cb Deletion Failure */ +#define CKW_CFG_REAS_RB_REEST_FAIL 11 /*!< RB Cb Re establish Failure */ +#define CKW_CFG_REAS_RB_MODE_MIS 12 /*!< RB Cb Mode mismatch */ +#define CKW_CFG_REAS_REEST_FAIL 13 /*!< RB Cb Re-establishment Failed */ +#define CKW_CFG_REAS_RECFG_FAIL 14 /*!< RB Cb Re-configuration Failed */ +#define CKW_CFG_REAS_INVALID_CFG 15 /*!< Invalid Configuration Type */ +#define CKW_CFG_REAS_SAME_UEID 16 /*!< UE Ids match in ChngUeId Request */ +#define CKW_CFG_REAS_CELL_DEL_FAIL 17 /*!< Cell Cb Deletion Failure */ +#define CKW_CFG_REAS_INVALID_LCHID 18 /*!< Invalid LChId */ +#define CKW_CFG_REAS_INVALID_DIR 19 /*!< Invalid Direction */ +#define CKW_CFG_REAS_UE_EXISTS 20 /*!< UE ID already exists */ +#define CKW_CFG_REAS_INVALID_SNLEN 21 /*!< Invalid SN Length */ +#define CKW_CFG_REAS_SNLEN_MIS 22 /*!< SN Length mismatch */ +#define CKW_CFG_REAS_INVALID_RGUSAP 23 /*!< Invalid RGU SAP ID */ + +/*********************************************************************** + Defines for CKW Interface Events + ***********************************************************************/ +#define CKW_EVT_BND_REQ 0x01 /*!< Bind Request */ +#define CKW_EVT_BND_CFM 0x02 /*!< Bind Confirm */ +#define CKW_EVT_UBND_REQ 0x03 /*!< Unbind Request */ +#define CKW_EVT_CFG_REQ 0x04 /*!< Config Request */ +#define CKW_EVT_CFG_CFM 0x05 /*!< Config Confirm */ +#define CKW_EVT_UEIDCHG_REQ 0x06 /*!< UE Id Change Request */ +#define CKW_EVT_UEIDCHG_CFM 0x07 /*!< UE Id Change Confirm */ + +/* Error Codes */ +#define ERRCKW 0 +#define ECKWXXX 0 +#define ECKW001 (ERRCKW + 1) /* ckw.c: 162 */ +#define ECKW002 (ERRCKW + 2) /* ckw.c: 167 */ +#define ECKW003 (ERRCKW + 3) /* ckw.c: 168 */ +#define ECKW004 (ERRCKW + 4) /* ckw.c: 213 */ +#define ECKW005 (ERRCKW + 5) /* ckw.c: 218 */ +#define ECKW006 (ERRCKW + 6) /* ckw.c: 219 */ +#define ECKW007 (ERRCKW + 7) /* ckw.c: 264 */ +#define ECKW008 (ERRCKW + 8) /* ckw.c: 270 */ +#define ECKW009 (ERRCKW + 9) /* ckw.c: 271 */ +#define ECKW010 (ERRCKW + 10) /* ckw.c: 543 */ +#define ECKW011 (ERRCKW + 11) /* ckw.c: 588 */ +#define ECKW012 (ERRCKW + 12) /* ckw.c: 606 */ +#define ECKW013 (ERRCKW + 13) /* ckw.c: 622 */ +#define ECKW014 (ERRCKW + 14) /* ckw.c: 702 */ +#define ECKW015 (ERRCKW + 15) /* ckw.c: 747 */ +#define ECKW016 (ERRCKW + 16) /* ckw.c: 765 */ +#define ECKW017 (ERRCKW + 17) /* ckw.c: 781 */ +#define ECKW018 (ERRCKW + 18) /* ckw.c: 863 */ +#define ECKW019 (ERRCKW + 19) /* ckw.c: 884 */ +#define ECKW020 (ERRCKW + 20) /* ckw.c: 885 */ +#define ECKW021 (ERRCKW + 21) /* ckw.c: 935 */ +#define ECKW022 (ERRCKW + 22) /* ckw.c: 950 */ +#define ECKW023 (ERRCKW + 23) /* ckw.c: 951 */ +#define ECKW024 (ERRCKW + 24) /* ckw.c: 995 */ +#define ECKW025 (ERRCKW + 25) /* ckw.c: 996 */ +#define ECKW026 (ERRCKW + 26) /* ckw.c:1034 */ +#define ECKW027 (ERRCKW + 27) /* ckw.c:1035 */ +#define ECKW028 (ERRCKW + 28) /* ckw.c:1072 */ +#define ECKW029 (ERRCKW + 29) /* ckw.c:1073 */ +#define ECKW030 (ERRCKW + 30) /* ckw.c:1299 */ +#define ECKW031 (ERRCKW + 31) /* ckw.c:1417 */ +#define ECKW032 (ERRCKW + 32) /* ckw.c:1424 */ +#define ECKW033 (ERRCKW + 33) /* ckw.c:1472 */ +#define ECKW034 (ERRCKW + 34) /* ckw.c:1493 */ +#define ECKW035 (ERRCKW + 35) /* ckw.c:1548 */ +#define ECKW036 (ERRCKW + 36) /* ckw.c:1570 */ +#define ECKW037 (ERRCKW + 37) /* ckw.c:1653 */ +#define ECKW038 (ERRCKW + 38) /* ckw.c:1663 */ +#define ECKW039 (ERRCKW + 39) /* ckw.c:1678 */ +#define ECKW040 (ERRCKW + 40) /* ckw.c:1691 */ +#define ECKW041 (ERRCKW + 41) /* ckw.c:1706 */ +#define ECKW042 (ERRCKW + 42) /* ckw.c:1755 */ +#define ECKW043 (ERRCKW + 43) /* ckw.c:1765 */ +#define ECKW044 (ERRCKW + 44) /* ckw.c:1780 */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* __CKW_H__ */ + + + +/********************************************************************30** + End of file +**********************************************************************/ diff --git a/src/cm/ckw.x b/src/cm/ckw.x new file mode 100755 index 000000000..08ca70d37 --- /dev/null +++ b/src/cm/ckw.x @@ -0,0 +1,611 @@ +/******************************************************************************* +################################################################################ +# Copyright (c) [2017-2019] [Radisys] # +# # +# 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. # +################################################################################ +*******************************************************************************/ + +/********************************************************************20** + + Name: CKW RRC Control Interface + + Type: C include file + + Desc: This file Contains the Data structures for and prototypes + CKW Interface + + File: ckw.x + +*********************************************************************21*/ + +#ifndef __CKW_X__ +#define __CKW_X__ + +#ifdef __cplusplus +EXTERN "C" { +#endif /*for extern "C"*/ + +/** @file ckw.x + @brief CKW Interface File (ckw.x) +*/ + +/*********************************************************************** + CKW typedefs and data structures + ***********************************************************************/ + +/** @brief + Logical Channel Information */ +typedef struct ckwLChInfo +{ + U8 lChId; /*!< Logical Channel ID. + The allowed values are [1..10] */ + U8 type; /*!< Logical Channel Type - + BCCH/PCCH/CCCH/DTCH/DCCH */ +}CkwLChInfo; + +/** @brief + Un-acknowledge Mode Information */ +typedef struct ckwUmInfo +{ + struct _umDl + { + U8 snLen; /*!< Sequence Number length in bits. Allowed values are 6 and 12*/ + }dl; /*!< Downlink */ + struct _umUl + { + U8 snLen; /*!< Sequence Number length in bits.*/ + /*!< Allowed values are 6 and 12*/ + U8 reOrdTmr; /*!< T_reordering Timer in msec */ + }ul; /*!< Uplink */ +}CkwUmInfo; + +/** @brief + Acknowledge Mode Information */ +typedef struct ckwAmInfo +{ + struct _amDl + { + U8 snLen; /*!< Sequence Number length in + bits. Allowed values are 12 and 18 */ + U16 pollRetxTmr; /*!< T_poll_retransmit Timer in msec */ + S16 pollPdu; /*!< Used to trigger a poll for every pollPdu.*/ + /*!< This field indicates the number of PDUs */ + /* Patch ckw_x_001.main_5 */ + /* !hashVal /* computed hash value */ +#define CM_HASH_SIZE(tbl) (tbl)->nmbBins /* hash table size */ + +#ifndef CM_MT_HASH_BIN +#define CM_HASH_NMBENT(tbl) (tbl)->nmbEnt /* number of entries in + * table + */ +#endif + +#define CM_HASH_DUPFLG(tbl) (tbl)->dupFlg /* allow duplicate keys */ + +#define CM_HASH_OFFSET(tbl) (tbl)->offset /* offset of CmHashListEnt + * structure in hash list + * entry + */ + +#define CM_HASH_KEYTYPE(tbl) (tbl)->keyType /* key type for selecting + * hash function + */ + +#define CM_HASH_BINSIZE sizeof(CmListEnt) /* size of a single bin + */ +/* bin bit mask */ + +#define CM_HASH_NOBITMASK 0x8000 /* illegal bin bit mask */ + +/* constant multiplier for multiplication method of computing hash index */ +#define CM_HASH_MULT24_CONST 10368890 /* when key is of max 24 bits */ + +/* bit position where the hash index is extracted in multiplication method */ +#define CM_HASH_MULT24_BITPOS 24 /* when key is of max 24 bits */ + +/* + * delete an entry from the hash table with open addressing + */ +#define cmHashListOADelete(hashListCp, entry) cmHashListDelete(hashListCp, (PTR)entry) + + +/* + * CM_HASH_MIX -- mix 3 32-bit values reversibly. + * For every delta with one or two bits set, and the deltas of all three + * high bits or all three low bits, whether the original value of a,b,c + * is almost all zero or is uniformly distributed, + * If CM_HASH_MIX() is run forward or backward, at least 32 bits in a,b,c + * have at least 1/4 probability of changing. + * If CM_HASH_MIX() is run forward, every bit of c will change between 1/3 and + * 2/3 of the time. (Well, 22/100 and 78/100 for some 2-bit deltas.) + * CM_HASH_MIX() was built out of 36 single-cycle latency instructions in a + * structure that could supported 2x parallelism, like so: + * a -= b; + * a -= c; x = (c>>13); + * b -= c; a ^= x; + * b -= a; x = (a<<8); + * c -= a; b ^= x; + * c -= b; x = (b>>13); + * ... + */ +#define CM_HASH_MIX(a,b,c) \ +{ \ + a -= b; a -= c; a ^= (c>>13); \ + b -= c; b -= a; b ^= (a<<8); \ + c -= a; c -= b; c ^= (b>>13); \ + a -= b; a -= c; a ^= (c>>12); \ + b -= c; b -= a; b ^= (a<<16); \ + c -= a; c -= b; c ^= (b>>5); \ + a -= b; a -= c; a ^= (c>>3); \ + b -= c; b -= a; b ^= (a<<10); \ + c -= a; c -= b; c ^= (b>>15); \ +} + +#endif /* __CMHASHH__ */ + + +/********************************************************************30** + + End of file +**********************************************************************/ diff --git a/src/cm/cm_hash.x b/src/cm/cm_hash.x new file mode 100755 index 000000000..a8607cb57 --- /dev/null +++ b/src/cm/cm_hash.x @@ -0,0 +1,176 @@ +/******************************************************************************* +################################################################################ +# Copyright (c) [2017-2019] [Radisys] # +# # +# 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. # +################################################################################ +*******************************************************************************/ + +/********************************************************************20** + + Name: common hash functions + + Type: C include file + + Desc: Structures, variables and typedefs required by common + functions. + (Newer version of functions in cm_bdy1) + + File: cm_hash.x + +*********************************************************************21*/ + +#ifndef __CMHASHX__ +#define __CMHASHX__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* typedefs */ + +/* forward definitions */ + +typedef struct cmHashListCp CmHashListCp; /* hash list control point */ + + +/* hash function */ + +typedef S16 (* CmHashFunc) ARGS((CmHashListCp *hashListCp, U8 *key, + U16 keyLen, U16 *idx)); + +/* list entry */ +typedef struct cmListEnt CmListEnt; /* list entry */ + +struct cmListEnt /* list entry */ +{ + CmListEnt *next; /* next entry in list */ + CmListEnt *prev; /* prev entry in list */ +}; + +#ifdef CM_MT_HASH_BIN +typedef struct cmListBinEnt CmListBinEnt;/* Bin entry */ + +struct cmListBinEnt /* Bin entry */ +{ + CmListEnt *next; /* next entry in list */ + CmListEnt *prev; /* prev entry in list */ + U16 nmbEnt; /* current number of entries */ +}; +#endif + + +/* hash list entry */ + +typedef struct cmHashListEnt /* hash list entry */ +{ + CmListEnt list; /* list pointers */ + U8 *key; /* pointer to key */ + U16 keyLen; /* length of key */ + U16 hashVal; /* computed hash value */ +} CmHashListEnt; + +/* hash list control point */ + +struct cmHashListCp /* hash list control point */ +{ +#ifndef CM_MT_HASH_BIN + CmListEnt *hl; /* pointer to hash list bins */ +#else + CmListBinEnt *hl; /* pointer to hash list bins */ +#endif + Region region; /* memory region to allocate bins */ + Pool pool; /* memory pool to allocate bins */ + U16 nmbBins; /* number of hash list bins */ + U16 binBitMask; /* number of bits if nmbBins is power of 2 */ + U8 nmbBinBits; /* number of bits to represent nmbBins */ +#ifndef CM_MT_HASH_BIN + U16 nmbEnt; /* current number of entries */ +#endif + U16 offset; /* offset of CmHashListEnt in entries */ + Bool dupFlg; /* allow duplicate keys */ + U16 keyType; /* key type for selecting hash functions */ + CmHashFunc hashFunc; /* hash function for this key type */ +}; + + +/* functions prototypes */ + +EXTERN S16 cmHashListInit ARGS(( + CmHashListCp *hashListCp, /* hash list to initialize */ + U16 nmbBins, /* number of hash list bins */ + U16 offset, /* offset of CmHashListEnt in entries */ + Bool dupFlg, /* allow duplicate keys */ + U16 keyType, /* key type for selecting hash fn */ + Region region, /* memory region to allocate bins */ + Pool pool)); /* memory pool to allocate bins */ + +EXTERN S16 cmHashListDeinit ARGS(( + CmHashListCp *hashListCp));/* hash list to initialize */ + +EXTERN S16 cmHashListInsert ARGS(( + CmHashListCp *hashListCp, /* hash list to add to */ + PTR entry, /* entry to add */ + U8 *key, /* pointer to key */ + U16 keyLen)); /* length of key */ + +EXTERN S16 cmHashListDelete ARGS(( + CmHashListCp *hashListCp, /* hash list to delete from */ + PTR entry)); /* entry to delete */ + +EXTERN S16 cmHashListFind ARGS(( + CmHashListCp *hashListCp, /* hash list to search */ + U8 *key, /* pointer to key */ + U16 keyLen, /* length of key */ + U16 seqNmb, /* used in case of duplicate keys */ + PTR *entry)); /* entry to be returned */ + +EXTERN S16 cmHashListGetNext ARGS(( + CmHashListCp *hashListCp, /* hash list to get from */ + PTR prevEnt, /* previous entry */ + PTR *entry)); /* entry to be returned */ + +#ifdef CM_MT_HASH_BIN +EXTERN S16 cmHashListBinGetNextEntry ARGS(( + CmHashListCp *hashListCp, /* hash list to get from */ + U16 binIdx, /* Index of the bin */ + PTR prevEnt, /* previous entry */ + PTR *entry)); /* entry to be returned */ +#endif + +/* This function is obsoleted! Use macros defined in cm_hash.h instead + */ +EXTERN S16 cmHashListQuery ARGS(( + CmHashListCp *hashListCp, /* hash list to query */ + U8 queryType, /* type of query */ + U16 *result)); /* result of query */ + +/* Hash list with open addressing + */ +EXTERN S16 cmHashListOAInsert ARGS(( + CmHashListCp *hashListCp, /* hash list to add to */ + PTR entry, /* entry to add */ + U8 *key, /* pointer to key */ + U16 keyLen)); /* length of key */ + +#ifdef __cplusplus +} +#endif + +#endif /* __CMHASHX__ */ + + +/********************************************************************30** + + End of file +**********************************************************************/ diff --git a/src/cm/cm_lib.x b/src/cm/cm_lib.x new file mode 100755 index 000000000..7e6fe0587 --- /dev/null +++ b/src/cm/cm_lib.x @@ -0,0 +1,61 @@ +/******************************************************************************* +################################################################################ +# Copyright (c) [2017-2019] [Radisys] # +# # +# 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. # +################################################################################ +*******************************************************************************/ + + +/********************************************************************20** + + Name: common library functions + + Type: C include file + + Desc: Prototypes for common functions that are implemented in + both a portable and a performance-efficient manner. These + functions are selected based on the operating system. + + File: cm_lib.x + +*********************************************************************21*/ + + + +#ifndef __CMLIBX__ +#define __CMLIBX__ + +#ifdef __cplusplus +extern "C" { +#endif + +PUBLIC U8 *cmMemcpy ARGS((U8 *tgt, CONSTANT U8 *src, PTR len)); +PUBLIC S16 cmMemcmp ARGS((CONSTANT U8 *s1, CONSTANT U8 *s2, PTR len)); +PUBLIC U8 *cmMemset ARGS((U8 *src, U8 val, PTR len)); + +PUBLIC S16 cmStrcmp ARGS((CONSTANT U8 *s1, CONSTANT U8 *s2)); +/* cm_lib_x_001.main_8:Changing from S16 to MsgLen.*/ +PUBLIC S16 cmStrncmp ARGS((CONSTANT U8 *s1, CONSTANT U8 *s2, MsgLen len)); +PUBLIC MsgLen cmStrlen ARGS((CONSTANT U8 *s)); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* __CMLIBX__ */ + + +/********************************************************************30** + + End of file +**********************************************************************/ diff --git a/src/cm/cm_llist.h b/src/cm/cm_llist.h new file mode 100755 index 000000000..740922fa8 --- /dev/null +++ b/src/cm/cm_llist.h @@ -0,0 +1,63 @@ +/******************************************************************************* +################################################################################ +# Copyright (c) [2017-2019] [Radisys] # +# # +# 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. # +################################################################################ +*******************************************************************************/ + +/********************************************************************20** + + Name: common - linked list functions + + Type: C include file + + Desc: macros for linked list functions + + File: cm_llist.h + +*********************************************************************21*/ + +#ifndef __CMLLISTH__ +#define __CMLLISTH__ + + +/* cm_llist_h_001.main_8 */ +#define cmLListFirst(l) ((l)->crnt = (l)->first) +#define cmLListLast(l) ((l)->crnt = (l)->last) +#define cmLListCrnt(l) ((l)->crnt) +#define cmLListNext(l) ((l)->crnt = ((l)->crnt ? (l)->crnt->next : \ + (l)->first)) +#define cmLListPrev(l) ((l)->crnt = ((l)->crnt ? (l)->crnt->prev : \ + (l)->first)) +#define cmLListLen(l) ((l)->count) +#define cmLListNode(n) ((n)->node) + +/* cm_llist_h_001.main_9 : added explicit check for warning fix */ +#ifndef __cplusplus +#define CM_LLIST_FIRST_NODE(l, n) ((((n) = cmLListFirst(l)) != NULLP) ? (n)->node : NULLP) +#define CM_LLIST_NEXT_NODE(l, n) ((((n) = cmLListNext(l))!= NULLP) ? (n)->node : NULLP) +#define CM_LLIST_PREV_NODE(l, n) ((((n) = cmLListPrev(l)) != NULLP) ? (n)->node : NULLP) +#else +#define CM_LLIST_FIRST_NODE(l, n) ((n) = cmLListFirst(l)) +#define CM_LLIST_NEXT_NODE(l, n) ((n) = cmLListNext(l)) +#define CM_LLIST_PREV_NODE(l, n) ((n) = cmLListPrev(l)) +#endif + +#endif /* __CMLLISTH__ */ + + +/********************************************************************30** + + End of file +**********************************************************************/ diff --git a/src/cm/cm_llist.x b/src/cm/cm_llist.x new file mode 100755 index 000000000..9c6573b25 --- /dev/null +++ b/src/cm/cm_llist.x @@ -0,0 +1,78 @@ +/******************************************************************************* +################################################################################ +# Copyright (c) [2017-2019] [Radisys] # +# # +# 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. # +################################################################################ +*******************************************************************************/ + +/********************************************************************20** + + Name: common - linked list functions + + Type: C include file + + Desc: Structures, variables and typedefs required by the + linked list management routines. + + File: cm_llist.x + +*********************************************************************21*/ + +#ifndef __CMLLISTX__ +#define __CMLLISTX__ + +#ifdef __cplusplus +extern "C" { +#endif + + +typedef struct cmLList CmLList; +typedef struct cmLListCp CmLListCp; + +/* doubly linked list */ +struct cmLList +{ + CmLList *next; /* next */ + CmLList *prev; /* previous */ + PTR node; /* node */ +}; + +struct cmLListCp +{ + CmLList *first; /* first entry in list */ + CmLList *last; /* last entry in list */ + CmLList *crnt; /* entry last accessed */ + U32 count; /* number of entries */ +}; + +EXTERN Void cmLListInit ARGS ((CmLListCp *lList)); +EXTERN Void cmLListAdd2Head ARGS ((CmLListCp *lList, CmLList *node)); +EXTERN Void cmLListAdd2Tail ARGS ((CmLListCp *lList, CmLList *node)); +EXTERN Void cmLListInsCrnt ARGS ((CmLListCp *lList, CmLList *node)); +/* cm_llist_x_001.main_6 - Add function */ +EXTERN Void cmLListInsAfterCrnt ARGS ((CmLListCp *lList, CmLList *node)); +EXTERN CmLList *cmLListDelFrm ARGS ((CmLListCp *lList, CmLList *node)); +EXTERN Void cmLListCatLList ARGS (( CmLListCp *list1, CmLListCp *list2)); + +#ifdef __cplusplus +} +#endif + +#endif /* __CMLLISTX__ */ + + +/********************************************************************30** + + End of file +**********************************************************************/ diff --git a/src/cm/cm_lte.h b/src/cm/cm_lte.h new file mode 100755 index 000000000..354f04d70 --- /dev/null +++ b/src/cm/cm_lte.h @@ -0,0 +1,102 @@ +/******************************************************************************* +################################################################################ +# Copyright (c) [2017-2019] [Radisys] # +# # +# 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. # +################################################################################ +*******************************************************************************/ + +/********************************************************************20** + + Name: Common LTE + + Type: C include file + + Desc: This file Contains the Data structures for Common LTE + + File: cm_lte.h + +*********************************************************************21*/ + +#ifndef __CM_LTE_H__ +#define __CM_LTE_H__ + +#ifdef __cplusplus +EXTERN "C" { +#endif /*__cplusplus*/ + +/** @file cm_lte.h + @brief CM_LTE Interface File (cm_lte.h) +*/ + +#define CM_LTE_MAX_LOGCH_PER_RB 2 /*!< Maximum Logical Channel per RB */ + +/* Mode of RLC entity */ +#define CM_LTE_MODE_TM 1 /*!< TM mode */ +#define CM_LTE_MODE_UM 2 /*!< UM mode */ +#define CM_LTE_MODE_AM 3 /*!< AM mode */ + +/* Logical Channel Type */ +#define CM_LTE_LCH_BCCH 1 /*!< BCCH Logical Channel */ +#define CM_LTE_LCH_PCCH 2 /*!< PCCH Logical Channel */ +#define CM_LTE_LCH_CCCH 3 /*!< CCCH Logical Channel */ +#define CM_LTE_LCH_DTCH 4 /*!< DTCH Logical Channel */ +#define CM_LTE_LCH_DCCH 5 /*!< DCCH Logical Channel */ + +/* Transport Channel Type */ +#define CM_LTE_TRCH_BCH 1 /*!< BCH Transport Channel */ +#define CM_LTE_TRCH_PCH 2 /*!< PCH Transport Channel */ +#define CM_LTE_TRCH_DL_SCH 3 /*!< DL-SCH Transport Channel */ +#define CM_LTE_TRCH_RACH 4 /*!< RACH Transport Channel */ +#define CM_LTE_TRCH_UL_SCH 5 /*!< UL-SCH Transport Channel */ + +#define CM_LTE_DIR_UL 1 /*!< Uplink Direction */ +#define CM_LTE_DIR_DL 2 /*!< Downlink Direction */ +#define CM_LTE_DIR_DL_UL 3 /*!< Bi-Directional */ + + +#define CM_LTE_SRB 0 /*!< Signalling Radio Bearer */ +#define CM_LTE_DRB 1 /*!< Data Radio Bearer */ +#define CM_MAX_UE_CAT_SUPP 8 /*!< CA dev changes*/ +#define CM_LTE_MAX_CELLS 8 /*!< Max Number of Cells. One primary + seven secondary cells */ + +#define CM_MAX_CPU_CORES 10 /*!< Maximum number of cores */ +#define CM_L2_CPU_UTIL 0 /*!< Get L2 CPU Utilization */ +#define CM_L3_CPU_UTIL 1 /*!< Get L3 CPU Utilization */ +#define CM_L2_MEM_UTIL_AREAIDX 0 /*!< Get L2 MEM utilization */ +#define CM_L3_MEM_UTIL_AREAIDX 1 /*!< Get L3 MEM utilization */ +#define CM_MEM_CPU_UITL_INFO_TMR_VAL 1000 /*!< timer value */ +#ifdef TENB_T2K3K_SPECIFIC_CHANGES +#define CM_NUM_L2_CORES 1 /*!< number of L2 cores */ +#define CM_NUM_L3_CORES 1 /*!< number of L3 cores */ +#else +#define CM_NUM_L2_CORES 4 /*!< number of L2 cores */ +#define CM_NUM_L3_CORES 1 /*!< number of L3 cores */ +#endif +#ifdef TENB_TTI_PERF +/*#define TTI_THRESHOLD_VALUE 800*/ + +#define displayTtiCounters(cellId) \ +RLOG_ARG4(L_ALWAYS,DBG_CELLID, (cellId),"avgTtiProcessingTime = [%d] maxTtiProcessingTime = [%d] ttiThresholdExceedCount = [%d] ttiStretchCount = [%d]",(ttiProc.totTtiProcessingTime/ttiProc.numOfTti),ttiProc.maxTtiProcessingTime,ttiProc.ttiThresholdExceedCount,ttiProc.ttiStretchCount) +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* __CM_LTE_H__ */ + +/********************************************************************30** + + End of file +**********************************************************************/ diff --git a/src/cm/cm_lte.x b/src/cm/cm_lte.x new file mode 100755 index 000000000..02ddd0826 --- /dev/null +++ b/src/cm/cm_lte.x @@ -0,0 +1,286 @@ +/******************************************************************************* +################################################################################ +# Copyright (c) [2017-2019] [Radisys] # +# # +# 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. # +################################################################################ +*******************************************************************************/ + +/********************************************************************20** + + Name: Common LTE + + Type: C include file + + Desc: This file Contains the Data structures for Common LTE + + File: cm_lte.x + + Sid: cm_lte.x@@/main/2 - Fri Nov 13 14:09:17 2009 + + Prg: chakrapani + +*********************************************************************21*/ + +#ifndef __CM_LTE_X__ +#define __CM_LTE_X__ + +#include +/* Packing Defines */ +#define cmPkLteRbId SPkU8 +#define cmPkLteRnti SPkU16 +#define cmPkLteCellId SPkU16 +#define cmPkLteRlcMode SPkU8 +#define cmPkLteLcId SPkU8 +#define cmPkLteLcType SPkU8 +#define cmPkLteAggrLvl SPkU32 + +/* Unpacking Defines */ +#define cmUnpkLteRbId SUnpkU8 +#define cmUnpkLteRnti SUnpkU16 +#define cmUnpkLteCellId SUnpkU16 +#define cmUnpkLteRlcMode SUnpkU8 +#define cmUnpkLteLcId SUnpkU8 +#define cmUnpkLteLcType SUnpkU8 +#define cmUnpkLteAggrLvl SUnpkU32 + +#define MAX_POOL_SIZE 6 /*!< Maximum pool size */ +#define MAX_REGION_SIZE 5 /*!< Maximum Region size */ +#ifdef PACK_STRUCT +#define CM_PACK_STRUCT __attribute__((packed)) +#else +#define CM_PACK_STRUCT +#endif + + + + +#ifdef __cplusplus +EXTERN "C" { +#endif /*__cplusplus*/ + +/** @file cm_lte.x + @brief CM_LTE Interface File (cm_lte.x) +*/ + +/* definitions for Common LTE */ + +/** @brief Radio Bearer ID */ +typedef U8 CmLteRbId; + +/** @brief Cell ID */ +typedef U16 CmLteCellId; + +/** @brief RNTI */ +typedef U16 CmLteRnti; + +/** @brief Mode Type TM/UM/AM */ +typedef U8 CmLteRlcMode; + +/** @brief Logical Channel ID */ +typedef U8 CmLteLcId; + +/** @brief Logical Channel Type */ +typedef U8 CmLteLcType; + +/** @brief Transport Channel Type */ +typedef U8 CmLteTrchType; + +/** @brief Contention Resolution ID */ +typedef U8 CmLteContResId[6]; + +/** @brief RLC ID */ +typedef struct cmLteRlcId +{ + CmLteRbId rbId; /*!< Radio Bearer ID */ + U8 rbType; /*!< RB Type */ + CmLteRnti ueId; /*!< UE ID */ + CmLteCellId cellId; /*!< Cell ID */ +}CmLteRlcId; + +/** @brief LTE Timing Info */ +typedef struct cmLteTimingInfo +{ + U16 hSfn; /*!< Hyper System Frame Number */ + U16 sfn; /*!< System Frame Number */ + U8 subframe; /*!< Subframe number */ +} CmLteTimingInfo; + +/** @brief PDCP ID */ +typedef struct cmLtePdcpId +{ + CmLteCellId cellId; /*!< Cell ID */ + CmLteRnti ueId; /*!< UE ID */ + CmLteRbId rbId; /*!< PDCP Instance ID */ + U8 rbType; /*!< RB type */ +} CmLtePdcpId; + +/* Defining structures for Memory Information for L2-MEAS */ +typedef struct cmLtePoolInfo +{ + U32 poolSize; + U32 totAvailable; + U32 crntUsed; + U32 maxUsed; +} CmLtePoolInfo; + +typedef struct cmLteRegionInfo +{ + U8 regionType; /* 0-SSI 1-Shared */ + U8 regionId; + U8 numPools; + U8 isGenMemInfoUpdated; + CmLtePoolInfo poolInfo[MAX_POOL_SIZE]; +}CmLteRegionInfo; + +typedef struct cmLteMemInfo +{ + U8 numRegions; + U8 idx; + CmLteRegionInfo regInfo[MAX_REGION_SIZE]; +}CmLteMemInfo; + +/** @brief CPU Utilization INFO */ +typedef struct cmLteCpuUtilInfo +{ + U32 avgCpuUtil; /*!< average cpu utilization */ + U32 maxCpuUtil; /*!< Max cpu utilization */ +}CmLteCpuUtilInfo; + +/** @brief CPU INFO */ +typedef struct cmLteCpuInfo +{ + U8 numCores; /*!< number of cores*/ + CmLteCpuUtilInfo cpuUtil[CM_MAX_CPU_CORES]; /*!< cpu measurement info*/ +}CmLteCpuInfo; +/** @brief CPU Utilization INFO */ +typedef struct cmCpuUtilStatsInfo +{ + U32 numSamples; + U32 maxCpuUtil; /*!< Max cpu utilization */ + U32 totCpuUtil; /*!< Total cpu utilization */ +}CmCpuUtilStatsInfo; + +/** @brief CPU INFO */ +typedef struct cmCpuStatsInfo +{ + U8 numCores; /*!< number of cores*/ + CmCpuUtilStatsInfo cpuUtil[CM_MAX_CPU_CORES]; /*!< cpu measurement info*/ +}CmCpuStatsInfo; + + + + +/** @brief Counter Statistics */ +typedef U32 CntrSts; + +/** @brief Aggregation Level */ +typedef enum cmLteAggrLvl +{ + CM_LTE_AGGR_LVL2 = 2, /*!< Aggregation level 2 */ + CM_LTE_AGGR_LVL4 = 4, /*!< Aggregation level 4 */ + CM_LTE_AGGR_LVL8 = 8, /*!< Aggregation level 8 */ + CM_LTE_AGGR_LVL16= 16 /*!< Aggregation level 16 */ +} CmLteAggrLvl; + +/** @brief UE Category */ +typedef enum cmLteUeCategory +{ + CM_LTE_UE_CAT_1 = 1, + CM_LTE_UE_CAT_2, + CM_LTE_UE_CAT_3, + CM_LTE_UE_CAT_4, + CM_LTE_UE_CAT_5, + CM_LTE_UE_CAT_6, + CM_LTE_UE_CAT_7, /* RRC-REL10-Upgrade */ + CM_LTE_UE_CAT_8 +} CmLteUeCategory; + +/**************************************************************************** + * PACK/UNPACK Functions + ***************************************************************************/ + +EXTERN PUBLIC S16 cmUpdateSsiMemInfo(CmLteMemInfo *mInfo); + +EXTERN PUBLIC S16 cmFillMemUtilizationMeas(CmLteMemInfo *memoryInfo,CmLteMemInfo *memInfo); + +EXTERN PUBLIC S16 cmClearMemUtilizationCounter(CmLteMemInfo *memInfo); +EXTERN PUBLIC S16 UpdateSocMemInfo(U8 area , CmLteMemInfo *mInfo); + +EXTERN S16 cmFillCpuUtilizationMeas(CmLteCpuInfo *cpuMeasInfo,CmCpuStatsInfo *cpuInfo); + +EXTERN S16 cmClearCpuUtilizationCounter(CmCpuStatsInfo *cpuInfo); +EXTERN PUBLIC Void UpdateSocCpuInfo(CmCpuStatsInfo *cpuInfo,U8 Idx); + +EXTERN PUBLIC S16 SGetRegPoolInfo(U8* numRegion, U8* numPool); + +/* Packing Functions */ +EXTERN S16 cmPkLteRlcId ARGS (( +CmLteRlcId *param, +Buffer *mBuf +)); + +EXTERN S16 cmPkLteTimingInfo ARGS (( +CmLteTimingInfo *param, +Buffer *mBuf +)); + +EXTERN S16 cmPkLtePdcpId ARGS (( +CmLtePdcpId *param, +Buffer *mBuf +)); + +/* Unpack Function */ +EXTERN S16 cmUnpkLteRlcId ARGS (( +CmLteRlcId *param, +Buffer *mBuf +)); + +EXTERN S16 cmUnpkLteTimingInfo ARGS (( +CmLteTimingInfo *param, +Buffer *mBuf +)); + +EXTERN S16 cmUnpkLtePdcpId ARGS (( +CmLtePdcpId *param, +Buffer *mBuf +)); + +#ifdef TENB_TTI_PERF + +typedef struct cmTtiProc +{ + U32 totTtiProcessingTime; + U32 numOfTti; + U32 maxTtiProcessingTime; + U32 ttiStretchCount; + U32 ttiThresholdExceedCount; + /* this count is added to compare phy reported tti stretch and calculated tti stretch */ + U32 phyReptTtiStretchCount; +}CmTtiProc; + +EXTERN CmTtiProc ttiProc; + +EXTERN Void cmUpdateTtiCounters(U32 ttiProcessingTime); +EXTERN Void cmResetTtiCounters(Void); +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* __CM_LTE_X__ */ + +/********************************************************************30** + + End of file +**********************************************************************/ diff --git a/src/cm/cm_math.h b/src/cm/cm_math.h new file mode 100755 index 000000000..83a5e6385 --- /dev/null +++ b/src/cm/cm_math.h @@ -0,0 +1,40 @@ +/******************************************************************************* +################################################################################ +# Copyright (c) [2017-2019] [Radisys] # +# # +# 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. # +################################################################################ +*******************************************************************************/ + +/********************************************************************20** + + Name: common memory allocation library + + Type: C include file + + Desc: Hash Defines + + File: cm_mblk.h + +*********************************************************************21*/ + +#ifndef __CMMATHH__ +#define __CMMATHH__ + +#endif /* __CMMATHH__ */ + + +/********************************************************************30** + + End of file +**********************************************************************/ diff --git a/src/cm/cm_math.x b/src/cm/cm_math.x new file mode 100755 index 000000000..26604866e --- /dev/null +++ b/src/cm/cm_math.x @@ -0,0 +1,62 @@ +/******************************************************************************* +################################################################################ +# Copyright (c) [2017-2019] [Radisys] # +# # +# 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. # +################################################################################ +*******************************************************************************/ + +/********************************************************************20** + + Name: common math library + + Type: C include file + + Desc: Extern defintions + + File: cm_math.x + +*********************************************************************21*/ + +#ifndef __CMMATHX__ +#define __CMMATHX__ + +#ifdef __cplusplus +EXTERN "C" { +#endif + +#ifdef SS_FLOAT + +/* environment dependent include files */ +#include + +/* Math library function prototypes */ +EXTERN U32 cmAbs ARGS((F64 val)); +EXTERN F64 cmPow ARGS((F64 x, F64 y)); +EXTERN F64 cmFloor ARGS((F64 x)); +EXTERN F64 cmLog ARGS((F64 x)); +EXTERN F64 cmLog10 ARGS((F64 x)); + +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __CMMATHX__ */ + + +/********************************************************************30** + + End of file +**********************************************************************/ diff --git a/src/cm/cm_mblk.h b/src/cm/cm_mblk.h new file mode 100755 index 000000000..b9e8a0a3c --- /dev/null +++ b/src/cm/cm_mblk.h @@ -0,0 +1,102 @@ +/******************************************************************************* +################################################################################ +# Copyright (c) [2017-2019] [Radisys] # +# # +# 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. # +################################################################################ +*******************************************************************************/ + +/********************************************************************20** + + Name: common memory allocation library + + Type: C include file + + Desc: Hash Defines + + File: cm_mblk.h + +*********************************************************************21*/ + +#ifndef __CMMBLKH__ +#define __CMMBLKH__ + +/* Hash defines for alignment bytes */ +#define CM_ALIGNBOUNDARY_FOUR 4 /* Align 32 bit */ +#define CM_ALIGNBOUNDARY_EIGHT 8 /* Align 64 bit */ + +/* Macro Definitions */ + +#define CM_INIT_MEMCP(_memCp,_maxSize,_sMem) \ +{ \ + _memCp->first = NULLP; \ + _memCp->last = NULLP; \ + _memCp->count = 0;\ + _memCp->memCb.maxSize = _maxSize;\ + _memCp->memCb.memAllocated = 0; \ + _memCp->memCb.initPtr = NULLP; \ + _memCp->memCb.runPtr = NULLP; \ + _memCp->memCb.sMem.region = _sMem->region; \ + _memCp->memCb.sMem.pool = _sMem->pool; \ +} + +#define CM_INIT_MEMCPVAR(_memCp) \ +{ \ + _memCp->first = NULLP; \ + _memCp->last = NULLP; \ + _memCp->count = 0;\ + _memCp->memCb.memAllocated = 0; \ + _memCp->memCb.initPtr = NULLP; \ + _memCp->memCb.runPtr = NULLP; \ +} + +#ifdef ALIGN_64BIT +#define CM_ALIGN_SIZE(_size) \ +{ \ + if( (_size % CM_ALIGNBOUNDARY_EIGHT) ) \ + _size = _size + ( CM_ALIGNBOUNDARY_EIGHT - \ + (_size % CM_ALIGNBOUNDARY_EIGHT)); \ +} +#else +#define CM_ALIGN_SIZE(_size) \ +{ \ + if( (_size % CM_ALIGNBOUNDARY_FOUR) ) \ + _size = _size + ( CM_ALIGNBOUNDARY_FOUR - \ + (_size % CM_ALIGNBOUNDARY_FOUR)); \ +} +#endif /* ALIGN_64BIT */ + +#define CMCHKUNPKPTR(func, val, ptr, mBuf) \ + { \ + S16 ret; \ + if ((ret = func(val, ptr, mBuf)) != ROK) \ + RETVALUE(ret); \ + } + +#define CMGETMBLK(ptr, size, pptr) \ + { \ + S16 ret; \ + ret = cmGetMem( ptr, size, pptr); \ + if (ret != ROK) \ + { \ + RETVALUE(RFAILED); \ + } \ + } + +#endif /* __CMMBLKH__ */ + + +/********************************************************************30** + + End of file +**********************************************************************/ diff --git a/src/cm/cm_mblk.x b/src/cm/cm_mblk.x new file mode 100755 index 000000000..ec460cf46 --- /dev/null +++ b/src/cm/cm_mblk.x @@ -0,0 +1,145 @@ +/******************************************************************************* +################################################################################ +# Copyright (c) [2017-2019] [Radisys] # +# # +# 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. # +################################################################################ +*******************************************************************************/ + +/********************************************************************20** + + Name: common memory allocation library + + Type: C include file + + Desc: Structures, variables and typedefs required by the + memory library routines + + File: cm_mblk.x + +*********************************************************************21*/ + +#ifndef __CMMBLKX__ +#define __CMMBLKX__ + +#ifdef __cplusplus +EXTERN "C" { +#endif + +/************************************************ + Memory Management Control Block +************************************************/ + +typedef struct cmMemCb +{ + Size maxSize; /* Size of memory chunk */ + Mem sMem; /* Static memory region and pool */ + U32 memAllocated; /* amount of memory already allocated */ + PTR initPtr; /* Initial pointer */ + PTR runPtr; /* Start of avaliable memory chunk */ +} CmMemCb; + +/************************************************ + Memory Link List Node Structure +************************************************/ +typedef struct cmMemList CmMemList; + +struct cmMemList +{ + CmMemList *next; /* next */ + CmMemList *prev; /* previous */ + /* cm_mblk_x_001.101: added new element "size" */ + Size size; /* block size */ +}; + +/************************************************ + Memory Link List Control Point +************************************************/ + +typedef struct cmMemListCp +{ + CmMemList *first; /* first entry in list */ + CmMemList *last; /* last entry in list */ + U32 count; /* number of entries */ + CmMemCb memCb; /* Memory Control Block */ +}CmMemListCp; + +/*********************************************** + Memory Status structure +***********************************************/ +typedef struct cmMemStatus +{ + Mem sMem; /* Static Memory region,pool */ + U32 memBlkCnt; /* Memory Blocks Count */ + Size maxBlkSize; /* Size of memory Block */ + Size memAllocated; /* Memory allocated off chunk */ +} CmMemStatus; + + +/*********************************************** + Extern Declarations +***********************************************/ + +#ifdef TFU_ALLOC_EVENT_NO_INIT +EXTERN S16 cmAllocEvntNoInit ARGS(( + Size evntSize, + Size maxBlkSize, + Mem *sMem, + Ptr *ptr)); +#endif +#ifdef TFU_ALLOC_EVENT_NO_INIT +EXTERN S16 cmGetMemNoInit ARGS(( + Ptr memPtr, + Size size, + Ptr *allocPtr)); +#endif +EXTERN S16 cmAllocEvnt ARGS(( + Size evntSize, + Size maxBlkSize, + Mem *sMem, + Ptr *ptr)); + +EXTERN Void cmInitMemCp ARGS(( + CmMemListCp *memCp, + Size maxBlkSize, + Mem *sMem )); + +#ifdef TFU_ALLOC_EVENT_NO_INIT +EXTERN S16 cmGetMemNoInit ARGS(( + Ptr memPtr, + Size size, + Ptr *allocPtr)); +#endif +EXTERN S16 cmGetMem ARGS(( + Ptr memPtr, + Size size, + Ptr *allocPtr)); + +EXTERN Void cmFreeMem ARGS(( + Ptr memPtr)); + +EXTERN Void cmGetMemStatus ARGS(( + Ptr memPtr, + CmMemStatus *status)); + +#ifdef __cplusplus +} +#endif + +#endif /* __CMMBLKX__ */ + + +/********************************************************************30** + + End of file +**********************************************************************/ diff --git a/src/cm/cm_tenb_stats.h b/src/cm/cm_tenb_stats.h new file mode 100755 index 000000000..f2d60d99e --- /dev/null +++ b/src/cm/cm_tenb_stats.h @@ -0,0 +1,82 @@ +/******************************************************************************* +################################################################################ +# Copyright (c) [2017-2019] [Radisys] # +# # +# 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. # +################################################################################ +*******************************************************************************/ + +/********************************************************************** + + Name: + + Type: + + Desc: + + File: cm_tenb_stats.h + +**********************************************************************/ + +/** @file cm_tenb_stats.h +*/ + +#ifdef TENB_STATS +#ifndef __TENBSTATSINFH__ +#define __TENBSTATSINFH__ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#define TENBSTATSINIT 0x7F + +#ifdef BRDCM +#define CL_DSTENT_SELECTOR 0 +#define STATS_SRCPROCID 1 +#define STATS_DSTPROCID 1 +#define STATS_DSTENT ENTPJ +#define STATS_DSTINST 0 /* PDCP UL */ +#else /* BRDCM */ +#ifdef MSPD +#define CL_DSTENT_SELECTOR 0 +#ifdef L2_L3_SPLIT +#define STATS_SRCPROCID 1 +#define STATS_DSTPROCID 1 +#define STATS_DSTENT ENTKW +#else +#define STATS_SRCPROCID 100 +#define STATS_DSTPROCID 100 +#define STATS_DSTENT ENTKW +#endif /* L2_L3_SPLIT */ + +#define STATS_DSTINST 0 /* PDCP UL */ +#else /* MSPD */ +#define CL_DSTENT_SELECTOR 0 +#define STATS_SRCPROCID 0 +#define STATS_DSTPROCID 0 +#define STATS_DSTENT ENTPJ +#define STATS_DSTINST 0 /* PDCP UL */ +#endif /* MSPD */ +#endif + +#define STATS_SRCENT ENTTF + +#define EVTTENBL2CELLSTATS 0xF1 +#define EVTTENBL2UESTATS 0xF2 + +#endif +#endif /* TENB_STATS */ +/********************************************************************** + End of file +**********************************************************************/ diff --git a/src/cm/cm_tenb_stats.x b/src/cm/cm_tenb_stats.x new file mode 100755 index 000000000..0ad436c97 --- /dev/null +++ b/src/cm/cm_tenb_stats.x @@ -0,0 +1,236 @@ +/******************************************************************************* +################################################################################ +# Copyright (c) [2017-2019] [Radisys] # +# # +# 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. # +################################################################################ +*******************************************************************************/ + +/********************************************************************** + + Name: + + Type: + + Desc: + + File: cm_tenb_stats.x + +**********************************************************************/ + +/** @file cm_tenb_stats.x +*/ + +#ifdef TENB_STATS + +#include "cm_tenb_stats.h" +#include "l2_tenb_stats.h" + +#ifndef __TENBSTATSINFX__ +#define __TENBSTATSINFX__ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +typedef struct tsInfL2CellStats +{ + U32 cellId; + struct schCellStats{ + U32 msg4Fail; + U32 msg3Fail; + U32 dlSumCw0Cqi; + U32 dlNumCw0Cqi; + U32 dlSumCw1Cqi; + U32 dlNumCw1Cqi; + U32 dlSumCw0iTbs; + U32 dlNumCw0iTbs; + U32 dlSumCw1iTbs; + U32 dlNumCw1iTbs; + U32 riCnt[4]; /* Rank = 1..4 */ + U32 dlNack[2][4]; + U32 dlAckNack[2][4]; /* [CW_CNT][RV_CNT] */ + U32 dlDtx[2][4]; + U32 ulNack[4]; + U32 ulAckNack[4]; /* [RV_CNT] */ + U32 ulDtx[4]; + U32 dlPrbUsage[10]; /* dlPrbUsage[0] to have overall PRB usage */ + U32 ulPrbUsage[10]; /* dlPrbUsage[0] to have overall PRB usage */ + U32 dlPdbRatio[10]; + U32 avgTtiProcTime; /* In us */ + U32 cntTtiProcTime1000; /* Count of instances where TTI proc time was + greater than 1000us */ + U32 cntTtiProcTime900; /* Count of instances where TTI proc time was + greater than 900us and less than 1000us */ + U32 cntTtiProcTime800; + U32 cntTtiProcTime700; + U32 cntTtiProcTime600; + U32 cntTtiProcTime500; +#ifdef RG_5GTF + U32 dl5gtfUePick; + U32 dl5gtfRbAllocPass; + U32 dl5gtfRbAllocFail; + U32 dl5gtfFnlzPass; + U32 dl5gtfFnlzFail; + U32 dl5gtfBoUpd; + U32 dl5gtfPdcchSend; + U32 dl5gtfPdschCons; + + U32 ul5gtfSrRecv; + U32 ul5gtfBsrRecv; + U32 ul5gtfUeSchPick; + U32 ul5gtfPdcchSchd; + U32 ul5gtfAllocAllocated; + U32 ul5gtfUeRbAllocDone; + U32 ul5gtfUeRmvFnlzZeroBo; + U32 ul5gtfUeFnlzReAdd; + U32 ul5gtfPdcchSend; + U32 ul5gtfRbAllocFail; +#endif + U32 ulSumCqi; + U32 ulNumCqi; + U32 ulSumiTbs; + U32 ulNumiTbs; + U32 dlTtlTpt; + U32 ulTtlTpt; + }sch; + struct rlcCellStats{ + U32 maxRlcSrbRetxFail; + U32 maxRlcDrbRetxFail; + U32 reOdrTmrExp; + }rlc; +}TSInfL2CellStats; + +typedef struct tsInfL2UeStats +{ + U32 rnti; + struct nonPersistentUeStats{ + struct schUeStats{ + U32 dlTxOccns; + U32 dlRetxOccns; + U32 dlPrbUsg; + U32 dlNackCnt[2]; /* [CW_CNT] */ + U32 dlAckNackCnt[2]; /* [CW_CNT] */ + U32 dlDtxCnt[2]; /* [CW_CNT] */ + U32 dlSumCw0Cqi; + U32 dlNumCw0Cqi; + U32 dlSumCw1Cqi; + U32 dlNumCw1Cqi; + U32 dlSumCw0iTbs; + U32 dlNumCw0iTbs; + U32 dlSumCw1iTbs; + U32 dlNumCw1iTbs; + U32 cqiDropCnt; + U32 dlPdbLvl[5]; /* PDB Levels */ + U32 riCnt[4]; /* Rank = 1..4 */ + U32 dlBo; + U32 dlTpt; + U32 ulTxOccns; + U32 ulRetxOccns; + U32 ulPrbUsg; + U32 ulAckNackCnt; + U32 ulNackCnt; + U32 ulDtxCnt; + U32 ulSumCqi; + U32 ulNumCqi; + U32 ulSumiTbs; + U32 ulNumiTbs; + U32 ulTpt; + }sch[L2_STATS_MAX_CELLS]; + struct pdcpUeStats{ + U32 dlPdcpDropCnt; + U32 dlPdcpAckWaitDropCnt; + U32 dlFlowCtrlDropCnt; + }pdcp; + struct rlcUeStats{ + U32 ulReOdrTmrExpCnt; + U32 dlMaxPktsInSduQ; + U32 dlMaxWindowSz; + }rlc; + }nonPersistent; + struct persistentUeStats{ + U32 activatedSCells; + U32 numActivation; + U32 numDeactivation; + }persistent; +}TSInfL2UeStats; + +typedef struct tsInfStatsCb +{ + Bool initDone; + Bool sockSend; + Bool fileSend; + Bool consPrint; + U32 statsPer; + U32 sockPort; + Bool startSockSend; + U8 cmdForFileStats; + char fileName[100]; + FILE *fptr; + U32 enbIp; +}TSInfStatsCb; + +typedef Void (*TSInfL2UeStatsInd) ARGS(( + Pst *, + SuId , + TSInfL2UeStats * +)); +EXTERN Void TSInfHdlL2UeStatsInd ARGS(( + Pst *pst, + SuId suId, + TSInfL2UeStats *stats +)); +EXTERN Void TSInfUnpkL2UeStats ARGS(( + TSInfL2UeStatsInd func, + Pst *pst, + Buffer *mBuf +)); +typedef Void (*TSInfL2CellStatsInd) ARGS(( + Pst *, + SuId , + TSInfL2CellStats * +)); +EXTERN Void TSInfHdlL2CellStatsInd ARGS(( + Pst *pst, + SuId suId, + TSInfL2CellStats *stats +)); +EXTERN Void TSInfUnpkL2CellStats ARGS(( + TSInfL2CellStatsInd func, + Pst *pst, + Buffer *mBuf +)); +EXTERN Void TSInfPkSndL2UeStats ARGS(( + Pst *pst, + SuId suId, + TSInfL2UeStats *stats +)); +EXTERN Void TSInfPkSndL2CellStats ARGS(( + Pst *pst, + SuId suId, + TSInfL2CellStats *stats +)); +EXTERN Void TSInfTrigStats ARGS(( + Region region, + Pool pool +)); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* __TENBSTATSINFX__ */ +#endif /* TENB_STATS */ + +/********************************************************************** + End of file +**********************************************************************/ diff --git a/src/cm/cm_tkns.h b/src/cm/cm_tkns.h new file mode 100755 index 000000000..4bc2a0389 --- /dev/null +++ b/src/cm/cm_tkns.h @@ -0,0 +1,102 @@ +/******************************************************************************* +################################################################################ +# Copyright (c) [2017-2019] [Radisys] # +# # +# 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. # +################################################################################ +*******************************************************************************/ + +/********************************************************************20** + + Name: general layer + + Type: C include file + + Desc: defines , required by cm_tkns.c and cm_tkns.h + + File: cm_tkns.h + +*********************************************************************21*/ + +#ifndef __CMTKNSH +#define __CMTKNSH + + +/* defines */ +#define cmPkTknPres(x, mBuf) cmPkTknU8(x, mBuf) + +#define cmUnpkTknPres(x, mBuf) cmUnpkTknU8(x, mBuf) + + +/* packing and unpacking for token bit strings */ + +#define CMPKTKNBSTR(tknStr, mBuf) \ +{ \ + Cntr i; \ + Cntr len; \ + \ + if(tknStr->pres) \ + { \ + if (tknStr->len % 8) \ + len = (tknStr->len/8 ) + 1; \ + else \ + len = (tknStr->len/8 ); \ + \ + /* Value */ \ + for (i = 0; i < (S16) len; i++) \ + { \ + CMCHKPK(SPkU8, tknStr->val[i], mBuf); \ + } \ + \ + /* Length */ \ + CMCHKPK(SPkU8, tknStr->len, mBuf); \ + } \ + \ + /* Token Header */ \ + CMCHKPK(SPkU8, tknStr->pres, mBuf); \ +} + +#define CMUNPKTKNBSTR(tknStr, mBuf) \ +{ \ + Cntr i; \ + Cntr len; \ + \ + /* Token Header */ \ + CMCHKUNPK(SUnpkU8, &tknStr->pres, mBuf); \ + \ + if(tknStr->pres) \ + { \ + /* Length */ \ + CMCHKUNPK(SUnpkU8, &tknStr->len, mBuf); \ + \ + if (tknStr->len % 8) \ + len = (tknStr->len/8 ) + 1; \ + else \ + len = (tknStr->len/8 ); \ + \ + /* Value */ \ + for (i = 1; i <= (S16) len; i++) \ + { \ + CMCHKUNPK(SUnpkU8, &tknStr->val[len - i], mBuf); \ + } \ + } \ + \ +} + +#endif /* __CMTKNSH */ + + +/********************************************************************30** + + End of file +**********************************************************************/ diff --git a/src/cm/cm_tkns.x b/src/cm/cm_tkns.x new file mode 100755 index 000000000..dd884364f --- /dev/null +++ b/src/cm/cm_tkns.x @@ -0,0 +1,197 @@ +/******************************************************************************* +################################################################################ +# Copyright (c) [2017-2019] [Radisys] # +# # +# 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. # +################################################################################ +*******************************************************************************/ + +/********************************************************************20** + + Name: general layer + + Type: C include file + + Desc: Token Structures, required by two or more layers + + File: cm_tkns.x + +*********************************************************************21*/ + +#ifndef __CMTKNSX +#define __CMTKNSX + +#ifdef __cplusplus +extern "C" { +#endif + + +/* typedefs */ + +/* Token Present */ +typedef TknU8 TknPres; +/* Do not remove TknBool definition. If cm_gprs.x is used then include this + * file before cm_gprs.x */ +typedef TknU8 TknBool; + +typedef struct tknS16 +{ + U8 pres; /* present flag */ + U8 spare1; /* for alignment */ + S16 val; /* value */ +#ifdef ALIGN_64BIT + U32 spare2; /* for 64 bit alignment */ +#endif +} TknS16; + +/* Token TknStr8 */ +typedef struct tknStr8 /* token string */ +{ + U8 pres; /* present flag */ + U8 len; /* length */ + U16 spare1; /* for alignment */ +#ifdef ALIGN_64BIT + U32 spare2; /* for 64 bit alignment */ +#endif + U8 val[8]; /* string value - 4 byte alligned */ +} TknStr8; + +/* Token TknStr16 */ +typedef struct tknStr16 /* token string */ +{ + U8 pres; /* present flag */ + U8 len; /* length */ + U16 spare1; /* for alignment */ +#ifdef ALIGN_64BIT + U32 spare2; /* for 64 bit alignment */ +#endif + U8 val[16]; /* string value - 4 byte alligned */ +} TknStr16; + +typedef struct tknStrOSXL +{ + U8 pres; /* present flag */ + U8 spare1; /* spare */ + U16 len; /* length */ +#ifdef ALIGN_64BIT + U32 spare2; /* for 64 bit alignment */ +#endif + U8 *val; /* string value - 4 byte alligned */ +} TknStrOSXL; + +/* Token TknBStr32 : length field indicates number of Bits present */ +typedef TknStr4 TknBStr32; + +/* Token TknStrBSXL : Len field indicates number of bits present */ +typedef TknStrOSXL TknStrBSXL; + + +/***************************************************** + Token structure for BMP Character Strings +******************************************************/ + +/* Token TknStrBMP4 */ +typedef struct tknStrBMP4 /* token string */ +{ + U8 pres; /* present flag */ + U8 len; /* length */ + U16 spare1; /* for alignment */ +#ifdef ALIGN_64BIT + U32 spare2; /* for 64 bit alignment */ +#endif + U16 val[4]; /* string value - 4 byte alligned */ +} TknStrBMP4; + +/* Token TknStrBMPXL */ +typedef struct tknStrBMPXL +{ + U8 pres; /* present flag */ + U8 spare1; /* spare */ + U16 len; /* length */ +#ifdef ALIGN_64BIT + U32 spare2; /* for 64 bit alignment */ +#endif + U16 *val; /* string value - 4 byte alligned */ +} TknStrBMPXL; + + +/***************************************************** + Token structure for UNIVERSAL Character Strings +******************************************************/ + +/* Token TknStrUNI4 */ +typedef struct tknStrUNI4 /* token string */ +{ + U8 pres; /* present flag */ + U8 len; /* length */ + U16 spare1; /* for alignment */ +#ifdef ALIGN_64BIT + U32 spare2; /* for 64 bit alignment */ +#endif + U32 val[4]; /* string value - 4 byte alligned */ +} TknStrUNI4; + +typedef struct tknStrUNIXL /* Universal String */ +{ + U8 pres; /* present flag */ + U8 spare1; /* spare */ + U16 len; /* length */ +#ifdef ALIGN_64BIT + U32 spare2; /* for 64 bit alignment */ +#endif + U32 *val; /* string value- 4 byte alligned */ +} TknStrUNIXL; + +/* common packing functions */ +EXTERN S16 cmPkTknPres ARGS((TknPres *tknPres, Buffer *mBuf)); +EXTERN S16 cmPkTknS16 ARGS((TknS16 *tknS16, Buffer *mBuf)); +EXTERN S16 cmPkTknBStr32 ARGS((TknBStr32 *tknbStr32, Buffer *mBuf)); +EXTERN S16 cmPkTknStr8 ARGS((TknStr8 *tknStr8, Buffer *mBuf)); +EXTERN S16 cmPkTknStr16 ARGS((TknStr16 *tknStr16, Buffer *mBuf)); +EXTERN S16 cmPkTknStrOSXL ARGS((TknStrOSXL *tknStrOSXL, Buffer *mBuf)); +EXTERN S16 cmPkTknStrBSXL ARGS((TknStrBSXL *tknStrBSXL, Buffer *mBuf)); +EXTERN S16 cmPkTknStrBMP4 ARGS((TknStrBMP4 *tknStrBMP4, Buffer *mBuf)); +EXTERN S16 cmPkTknStrBMPXL ARGS((TknStrBMPXL *tknStrBMPXL, Buffer *mBuf)); +EXTERN S16 cmPkTknStrUNI4 ARGS((TknStrUNI4 *tknStrUNI4, Buffer *mBuf)); +EXTERN S16 cmPkTknStrUNIXL ARGS((TknStrUNIXL *tknStrUNIXL, Buffer *mBuf)); + + + +/* common unpacking functions */ +EXTERN S16 cmUnpkTknPres ARGS((TknPres *tknPres, Buffer *mBuf)); +EXTERN S16 cmUnpkTknS16 ARGS((TknS16 *tknS16, Buffer *mBuf)); +EXTERN S16 cmUnpkTknBStr32 ARGS((TknBStr32 *tknBStr32, Buffer *mBuf)); +EXTERN S16 cmUnpkTknStr8 ARGS((TknStr8 *tknStr8, Buffer *mBuf)); +EXTERN S16 cmUnpkTknStr16 ARGS((TknStr16 *tknStr16, Buffer *mBuf)); +EXTERN S16 cmUnpkTknStrOSXL ARGS((TknStrOSXL *tknStrOSXL, Buffer *mBuf, + Ptr ptr)); +EXTERN S16 cmUnpkTknStrBSXL ARGS((TknStrBSXL *tknStrBSXL, Ptr ptr, + Buffer *mBuf)); +EXTERN S16 cmUnpkTknStrBMP4 ARGS((TknStrBMP4 *tknStrBMP4, Buffer *mBuf)); +EXTERN S16 cmUnpkTknStrBMPXL ARGS((TknStrBMPXL *tknStrBMPXL, Buffer *mBuf, + Ptr ptr)); +EXTERN S16 cmUnpkTknStrUNI4 ARGS((TknStrUNI4 *tknStrUNI4, Buffer *mBuf)); +EXTERN S16 cmUnpkTknStrUNIXL ARGS((TknStrUNIXL *tknStrUNIXL, Buffer *mBuf, + Ptr ptr)); + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* __CMTKNSX */ + + +/********************************************************************30** + + End of file +**********************************************************************/ diff --git a/src/cm/crg.h b/src/cm/crg.h new file mode 100755 index 000000000..62a35b555 --- /dev/null +++ b/src/cm/crg.h @@ -0,0 +1,128 @@ +/******************************************************************************* +################################################################################ +# Copyright (c) [2017-2019] [Radisys] # +# # +# 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. # +################################################################################ +*******************************************************************************/ + +/********************************************************************** + Name: LTE-MAC layer + + Type: C include file + + Desc: Defines required by the LTE MAC-RRC control (CRG) interface + + File: crg.h + +**********************************************************************/ + +#ifndef __CRG_H__ +#define __CRG_H__ + +/** + @file crg.h + @brief Defines for CRG interface. + */ + +/* Config/Reconfig/Delete MACROs */ +#define CRG_CONFIG 1 /*!< Macro for action type Configuration */ +#define CRG_RECONFIG 2 /*!< Macro for action type Re-Configuration */ +#define CRG_DELETE 3 /*!< Macro for action type Delete */ +#define CRG_RESET 4 /*!< Macro for action type Reset. Applicable + * only for UE. */ + +/* Cell/Ue/Logical channel MACROs */ +/* crg_h_001.main_6: Removed transport channel types from CRG. */ +#define CRG_CELL_CFG 1 /*!< Macro for Cell Configuration type*/ +#define CRG_UE_CFG 2 /*!< Macro for UE configuration type*/ +#define CRG_LCH_CFG 3 /*!< Macro for Logical channel Configuration type*/ +#define CRG_SCELL_CFG 4 /*!< Macro for SCell Configuration type*/ + +#ifdef LTE_ADV +#define CRG_MAX_SCELL_PER_UE 7 /*! + CM_LTE_TRCH_BCH
+ CM_LTE_TRCH_PCH
+ CM_LTE_TRCH_DL_SCH */ +} CrgDlLchCfg; + +/** + @brief Logical channel configuration information for uplink logical channels. */ +typedef struct crgUlLchCfg +{ + U8 ulTrchType; /*!< Indicates type of UL transport channel: + Validated only for BCCH at MAC. + UL Transport channel type can take following values:
+ CM_LTE_TRCH_RACH
+ CM_LTE_TRCH_UL_SCH */ + U8 lcgId; /*!< Logical channel group ID */ +} CrgUlLchCfg; + +/* crg_x_001.main_2: Documentation update */ +/** + @brief Logical channel configuration information for common and dedicated channels. */ +typedef struct crgLchCfg +{ + CmLteCellId cellId; /*!< Cell ID */ + CmLteRnti crnti; /*!< CRNTI for DTCH and DCCH */ + CmLteLcId lcId; /*!< Logical channel ID */ + CmLteLcType lcType; /*!< Identifies the Logical channel type. lcType can take the following values:
+ CM_LTE_LCH_BCCH
+ CM_LTE_LCH_PCCH
+ CM_LTE_LCH_CCCH
+ CM_LTE_LCH_DCCH
+ CM_LTE_LCH_DTCH */ + + U8 dir; /*!< Indicates Direction. Direction can take following + values:
+ CRG_DIR_TX
+ CRG_DIR_RX
+ CRG_DIR_TX_RX */ + + CrgDlLchCfg dlInfo; /*!< Downlink logical channel configuration info */ + CrgUlLchCfg ulInfo; /*!< Uplink logical channel configuration info */ + /* crg_x_001.main_5 - ADD - Members corresponding to LTE_L2_MEAS */ +#ifdef LTE_L2_MEAS + U8 qci; /*!< QCI for the logical channel. + Valid Range:[0-255] (Actual QCI - 1). */ + +#endif /* LTE_L2_MEAS */ +} CrgLchCfg; + +/** + @brief Basic configuration information for MAC. */ +typedef struct crgCfg +{ + U8 cfgType; /*!< Indicates configuration type */ + union crgCfgU + { + CrgCellCfg cellCfg; /*!< Cell configuration */ + CrgUeCfg ueCfg; /*!< UE configuration */ + CrgLchCfg lchCfg; /*!< Logical channel configuration */ + } u; /*!< Union of Cell/UE/Lch configuration */ +} CrgCfg; + + +/** + @brief Activation time information. */ +typedef struct crgActvTime +{ + Bool pres; /*!< Indicates the presence of activation time */ + CmLteTimingInfo actvTime; /*!< Activation time information */ +} CrgActvTime; + + +/** + @brief Cell reconfiguration information. */ +typedef struct crgCellRecfg +{ + CmLteCellId cellId; /*!< Cell ID */ + CrgRachCfg rachRecfg; /*!< RACH Configuration */ +} CrgCellRecfg; + +/** + @brief UE reconfiguration information. */ +typedef struct crgUeRecfg +{ + CmLteCellId cellId; /*!< Cell ID */ + CmLteRnti oldCrnti; /*!< Old UE ID */ + CmLteRnti newCrnti; /*!< New UE ID: This value must match + 'oldCrnti',if no CRNTI change during + reconfiguration */ + CrgUeUlHqCfg ueUlHqRecfg; /*!< UE UL HARQ information */ + CrgTxModeCfg txMode; /*!< UE Transmission mode ReCfg */ +#ifdef LTE_ADV + CrgUeSecCellInfo crgSCellCfg; /*!< Secondary cell dedicated informaton + per UE */ +#endif +} CrgUeRecfg; + +/** + @brief Logical channel reconfiguration information for dedicated channels only. */ +typedef struct crgLchRecfg +{ + CmLteCellId cellId; /*!< Cell ID */ + CmLteRnti crnti; /*!< CRNTI for DTCH and DCCH */ + CmLteLcId lcId; /*!< Logical channel ID */ + + struct ulRecfgS + { + U8 lcgId; /*!< Logical channel group ID */ + } ulRecfg; /*!< Uplink logical channel reconfiguration information */ + +} CrgLchRecfg; + +/** + @brief Basic reconfiguration information for MAC. */ +typedef struct crgRecfg +{ + U8 recfgType; /*!< Indicates reconfiguration type */ + union crgRecfgU + { + CrgCellRecfg cellRecfg; /*!< Cell Reconfig information */ + CrgUeRecfg ueRecfg; /*!< UE Reconfig information */ + CrgLchRecfg lchRecfg; /*!< Logical channel reconfiguration information */ + } u; /*!< Union of Cell/UE/Lch reconfiguration information + */ +} CrgRecfg; + +/** + @brief Basic Delete information for MAC. */ +typedef struct crgDel +{ + U8 delType; /*!< Indicates configuration item to be deleted */ + union crgDelU + { + struct cellDelS + { + CmLteCellId cellId; /*!< Cell ID */ + } cellDel; /*!< Cell Delete information */ + + struct ueDelS + { + CmLteCellId cellId; /*!< Cell ID */ + CmLteRnti crnti; /*!< UE ID: CRNTI */ + } ueDel; /*!< UE Delete information */ + + struct lchDelS + { + CmLteCellId cellId; /*!< Cell ID */ + CmLteRnti crnti; /*!< CRNTI for DTCH and DCCH */ + CmLteLcId lcId; /*!< Logical channel ID */ + U8 dir; /*!< Indicates Direction. Direction can take following + values:
+ CRG_DIR_TX
+ CRG_DIR_RX
+ CRG_DIR_TX_RX */ + } lchDel; /*!< Logical channel delete information */ + } u; /*!< Union of Cell/UE/Lch delete information */ +} CrgDel; + +/** + @brief UE RESET information for MAC. */ +typedef struct crgRst +{ + CmLteCellId cellId; /*!< Cell ID */ + CmLteRnti crnti; /*!< UE ID: CRNTI tobe RESET */ +} CrgRst; +/** + @brief Config/Reconfig/Delete information for MAC. */ +typedef struct crgCfgReqInfo +{ + U8 action; /*!< Determines cfg/recfg/del/reset */ + union cfgReqInfoU + { + CrgCfg cfgInfo; /*!< Configuration related infomation */ + CrgRecfg recfgInfo; /*!< Reconfiguration related information */ + CrgDel delInfo; /*!< Deletion related information */ + CrgRst rstInfo; /*!< Reset related information */ + } u; /*!< Union of config/re-config/delete information */ +} CrgCfgReqInfo; + +/* + Function Prototypes + */ +/** @brief Request from RRC to MAC to bind the interface SAPs. */ +typedef S16 (*CrgBndReq) ARGS(( + Pst* pst, + SuId suId, + SpId spId)); +/** @brief Confirmation from MAC to RRC for the bind/unbind + * request for the interface SAPs. */ +typedef S16 (*CrgBndCfm) ARGS(( + Pst* pst, + SuId suId, + U8 status)); +/** @brief Request from RRC to MAC to unbind the interface SAPs. */ +typedef S16 (*CrgUbndReq) ARGS(( + Pst* pst, + SpId spId, + Reason reason)); +/** @brief Configuration Request from RRC to MAC for + * configuring Cell/Ue/Lch. */ +typedef S16 (*CrgCfgReq) ARGS(( + Pst* pst, + SpId spId, + CrgCfgTransId transId, + CrgCfgReqInfo * cfgReqInfo)); +/** @brief Configuration Confirm from MAC to RRC. */ +typedef S16 (*CrgCfgCfm) ARGS(( + Pst* pst, + SuId suId, + CrgCfgTransId transId, + U8 status)); + +/** @brief Request from RRC to MAC to bind the interface SAPs. */ +EXTERN S16 RgUiCrgBndReq ARGS(( + Pst* pst, + SuId suId, + SpId spId +)); +/** @brief Confirmation from MAC to RRC for the bind/unbind + * request for the interface SAPs. */ +EXTERN S16 RgUiCrgBndCfm ARGS(( + Pst* pst, + SuId suId, + U8 status +)); +/** @brief Request from RRC to MAC to Unbind the interface SAPs. */ +EXTERN S16 RgUiCrgUbndReq ARGS(( + Pst* pst, + SpId spId, + Reason reason +)); +/** @brief Configuration Request from RRC to MAC for + * configuring Cell/Ue/Lch. */ +EXTERN S16 RgUiCrgCfgReq ARGS(( + Pst* pst, + SpId spId, + CrgCfgTransId transId, + CrgCfgReqInfo * cfgReqInfo +)); +/** @brief Configuration Confirm from MAC to RRC. */ +EXTERN S16 RgUiCrgCfgCfm ARGS(( + Pst* pst, + SuId suId, + CrgCfgTransId transId, + U8 status +)); + +#ifdef NH +/** @brief Request from RRC to MAC to bind the interface SAPs. */ +EXTERN S16 NhLiCrgBndReq ARGS(( + Pst* pst, + SuId suId, + SpId spId +)); +/** @brief Confirmation from MAC to RRC for the bind/unbind + * request for the interface SAPs. */ +EXTERN S16 NhLiCrgBndCfm ARGS(( + Pst* pst, + SuId suId, + U8 status +)); +/** @brief Request from RRC to MAC to Unbind the interface SAPs. */ +EXTERN S16 NhLiCrgUbndReq ARGS(( + Pst* pst, + SpId spId, + Reason reason +)); +/** @brief Configuration Request from RRC to MAC for + * configuring Cell/Ue/Lch. */ +EXTERN S16 NhLiCrgCfgReq ARGS(( + Pst* pst, + SpId spId, + CrgCfgTransId transId, + CrgCfgReqInfo * cfgReqInfo +)); +/** @brief Configuration Confirm from MAC to RRC. */ +EXTERN S16 NhLiCrgCfgCfm ARGS(( + Pst* pst, + SuId suId, + CrgCfgTransId transId, + U8 status +)); +#endif + +#ifdef LCCRG +/** @brief Request from RRC to MAC to bind the interface SAPs. */ +EXTERN S16 cmPkCrgBndReq ARGS(( + Pst* pst, + SuId suId, + SpId spId +)); +/** @brief Request from RRC to MAC to bind the interface SAPs. */ +EXTERN S16 cmUnpkCrgBndReq ARGS(( + CrgBndReq func, + Pst* pst, + Buffer *mBuf +)); +/** @brief Confirmation from MAC to RRC for the bind/unbind + * request for the interface SAPs. */ +EXTERN S16 cmPkCrgBndCfm ARGS(( + Pst* pst, + SuId suId, + U8 status +)); +/** @brief Confirmation from MAC to RRC for the bind/unbind + * request for the interface SAPs. */ +EXTERN S16 cmUnpkCrgBndCfm ARGS(( + CrgBndCfm func, + Pst* pst, + Buffer *mBuf +)); +/** @brief Request from RRC to MAC to unbind the interface SAPs. */ +EXTERN S16 cmPkCrgUbndReq ARGS(( + Pst* pst, + SpId spId, + Reason reason +)); +/** @brief Request from RRC to MAC to unbind the interface SAPs. */ +EXTERN S16 cmUnpkCrgUbndReq ARGS(( + CrgUbndReq func, + Pst* pst, + Buffer *mBuf +)); +/** @brief Configuration Request from RRC to MAC for + * configuring Cell/Ue/Lch. */ +EXTERN S16 cmPkCrgCfgReq ARGS(( + Pst* pst, + SpId spId, + CrgCfgTransId transId, + CrgCfgReqInfo * cfgReqInfo +)); +/** @brief Configuration Request from RRC to MAC for + * configuring Cell/Ue/Lch. */ +EXTERN S16 cmUnpkCrgCfgReq ARGS(( + CrgCfgReq func, + Pst* pst, + Buffer *mBuf +)); +/** @brief Configuration Confirm from MAC to RRC. */ +EXTERN S16 cmPkCrgCfgCfm ARGS(( + Pst* pst, + SuId suId, + CrgCfgTransId transId, + U8 status +)); +/** @brief Configuration Confirm from MAC to RRC. */ +EXTERN S16 cmUnpkCrgCfgCfm ARGS(( + CrgCfgCfm func, + Pst* pst, + Buffer *mBuf +)); +EXTERN S16 cmPkCrgCfgTransId ARGS(( + CrgCfgTransId *param, + Buffer *mBuf +)); +EXTERN S16 cmUnpkCrgCfgTransId ARGS(( + CrgCfgTransId *param, + Buffer *mBuf +)); +EXTERN S16 cmPkCrgBwCfg ARGS(( + CrgBwCfg *param, + Buffer *mBuf +)); +EXTERN S16 cmUnpkCrgBwCfg ARGS(( + CrgBwCfg *param, + Buffer *mBuf +)); +EXTERN S16 cmPkCrgRachCfg ARGS(( + CrgRachCfg *param, + Buffer *mBuf +)); +EXTERN S16 cmUnpkCrgRachCfg ARGS(( + CrgRachCfg *param, + Buffer *mBuf +)); +EXTERN S16 cmPkCrgCellCfg ARGS(( + CrgCellCfg *param, + Buffer *mBuf +)); +EXTERN S16 cmUnpkCrgCellCfg ARGS(( + CrgCellCfg *param, + Buffer *mBuf +)); +EXTERN S16 cmPkCrgUeUlHqCfg ARGS(( + CrgUeUlHqCfg *param, + Buffer *mBuf +)); +EXTERN S16 cmUnpkCrgUeUlHqCfg ARGS(( + CrgUeUlHqCfg *param, + Buffer *mBuf +)); +EXTERN S16 cmPkCrgUeCfg ARGS(( + CrgUeCfg *param, + Buffer *mBuf +)); +EXTERN S16 cmUnpkCrgUeCfg ARGS(( + CrgUeCfg *param, + Buffer *mBuf +)); + +#ifdef LTE_ADV +EXTERN S16 cmPkCrgUeSecCellInfo ARGS(( +CrgUeSecCellInfo *param, +Buffer *mBuf +)); + +EXTERN S16 cmUnpkCrgUeSecCellInfo ARGS(( +CrgUeSecCellInfo *param, +Buffer *mBuf +)); +#endif /* LTE_ADV */ + +EXTERN S16 cmPkCrgDlLchCfg ARGS(( + CrgDlLchCfg *param, + Buffer *mBuf +)); +EXTERN S16 cmUnpkCrgDlLchCfg ARGS(( + CrgDlLchCfg *param, + Buffer *mBuf +)); +EXTERN S16 cmPkCrgUlLchCfg ARGS(( + CrgUlLchCfg *param, + Buffer *mBuf +)); +EXTERN S16 cmUnpkCrgUlLchCfg ARGS(( + CrgUlLchCfg *param, + Buffer *mBuf +)); +EXTERN S16 cmPkCrgLchCfg ARGS(( + CrgLchCfg *param, + Buffer *mBuf +)); +EXTERN S16 cmUnpkCrgLchCfg ARGS(( + CrgLchCfg *param, + Buffer *mBuf +)); +EXTERN S16 cmPkCrgCfg ARGS(( + CrgCfg *param, + Buffer *mBuf +)); +EXTERN S16 cmUnpkCrgCfg ARGS(( + CrgCfg *param, + Buffer *mBuf +)); +EXTERN S16 cmPkCrgActvTime ARGS(( + CrgActvTime *param, + Buffer *mBuf +)); +EXTERN S16 cmUnpkCrgActvTime ARGS(( + CrgActvTime *param, + Buffer *mBuf +)); +EXTERN S16 cmPkCrgCellRecfg ARGS(( + CrgCellRecfg *param, + Buffer *mBuf +)); +EXTERN S16 cmUnpkCrgCellRecfg ARGS(( + CrgCellRecfg *param, + Buffer *mBuf +)); +EXTERN S16 cmPkCrgUeRecfg ARGS(( + CrgUeRecfg *param, + Buffer *mBuf +)); +EXTERN S16 cmUnpkCrgUeRecfg ARGS(( + CrgUeRecfg *param, + Buffer *mBuf +)); +EXTERN S16 cmPkCrgLchRecfg ARGS(( + CrgLchRecfg *param, + Buffer *mBuf +)); +EXTERN S16 cmUnpkCrgLchRecfg ARGS(( + CrgLchRecfg *param, + Buffer *mBuf +)); +EXTERN S16 cmPkCrgRecfg ARGS(( + CrgRecfg *param, + Buffer *mBuf +)); +EXTERN S16 cmUnpkCrgRecfg ARGS(( + CrgRecfg *param, + Buffer *mBuf +)); +EXTERN S16 cmPkCrgDel ARGS(( + CrgDel *param, + Buffer *mBuf +)); +EXTERN S16 cmUnpkCrgDel ARGS(( + CrgDel *param, + Buffer *mBuf +)); +EXTERN S16 cmPkCrgRst ARGS(( + CrgRst *param, + Buffer *mBuf +)); +EXTERN S16 cmUnpkCrgRst ARGS(( + CrgRst *param, + Buffer *mBuf +)); +EXTERN S16 cmPkCrgCfgReqInfo ARGS(( + CrgCfgReqInfo *param, + Buffer *mBuf +)); +EXTERN S16 cmUnpkCrgCfgReqInfo ARGS(( + CrgCfgReqInfo *param, + Buffer *mBuf +)); +#endif + +#ifdef DM +/** @brief Request from RRC to MAC to bind the interface SAPs. */ +EXTERN S16 DmUiCrgBndReq ARGS(( + Pst* pst, + SuId suId, + SpId spId +)); +/** @brief Confirmation from MAC to RRC for the bind/unbind + * request for the interface SAPs. */ +EXTERN S16 DmUiCrgBndCfm ARGS(( + Pst* pst, + SuId suId, + U8 status +)); +/** @brief Request from RRC to MAC to unbind the interface SAPs. */ +EXTERN S16 DmUiCrgUbndReq ARGS(( + Pst* pst, + SpId spId, + Reason reason +)); +/** @brief Configuration Request from RRC to MAC for + * configuring Cell/Ue/Lch. */ +EXTERN S16 DmUiCrgCfgReq ARGS(( + Pst* pst, + SpId spId, + CrgCfgTransId transId, + CrgCfgReqInfo * cfgReqInfo +)); +/** @brief Configuration Confirm from MAC to RRC. */ +EXTERN S16 DmUiCrgCfgCfm ARGS(( + Pst* pst, + SuId suId, + CrgCfgTransId transId, + U8 status +)); +#endif + +#ifdef __cplusplus +} +#endif +#endif /* __CRG_X__ */ + +/********************************************************************** + + End of file +**********************************************************************/ diff --git a/src/cm/ctf.h b/src/cm/ctf.h new file mode 100755 index 000000000..4a8e169d0 --- /dev/null +++ b/src/cm/ctf.h @@ -0,0 +1,283 @@ +/******************************************************************************* +################################################################################ +# Copyright (c) [2017-2019] [Radisys] # +# # +# 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. # +################################################################################ +*******************************************************************************/ + +/********************************************************************** + Name: LTE-PHY layer + + Type: C include file + + Desc: Defines required by the LTE PHY-RRC control (CTF) interface. + + File: ctf.h + +**********************************************************************/ +#ifndef __CTF_H__ +#define __CTF_H__ + +/** + * @file + * @brief Defines for CTF interface. +*/ +/* ctf_h_001.main_1 Wireshark Compilation issue */ +#ifdef WIRESHARK_LOG +#define EVTCTFWIRESHARK 8 +#endif +/* selva end*/ +/** Bind request event */ +#define EVTCTFBNDREQ 1 +/** Bind confirm event */ +#define EVTCTFBNDCFM 2 +/** Unbind request event */ +#define EVTCTFUBNDREQ 3 +/** Configuration request event */ +#define EVTCTFCFGREQ 4 +/** Configuration Confirm event */ +#define EVTCTFCFGCFM 5 +/** UE Id Change Request event */ +#define EVTCTFUEIDCHGREQ 6 +/** UE Id Change Request event */ +#define EVTCTFUEIDCHGCFM 7 +#ifdef TENB_AS_SECURITY +/**Data Request event*/ +/** key derivation primitive request event */ +#define EVTCTFKDFREQ 8 +/** Configuration Confirm event */ +#define EVTCTFKDFCFM 9 +#endif +/* ENB STOP indication from PHY to ENB-APP*/ +#define EVTCTFENBSTOPIND 10 + +/* Maximum NMM Message Length */ +#define MAX_NMM_MSG_LEN 1024 +/* Sniffer control response event */ +#define EVTCTFSNFCNTRSP 10 +/* sniffer RTWP response event */ +#define EVTCTFSNFRTWRSP 11 +/* Sniffer cell search respo event*/ +#define EVTCTFSNFCELSERSP 12 +/* Sniffer read sib1 respo event */ +#define EVTCTFSNFRDSIB1RSP 13 +/* Sniffer read sib response event */ +#define EVTCTFSNFRDSIBRSP 14 +/* Sniffer read sib indication event */ +#define EVTCTFSNFRDSIBIND 15 +/*Sniffer stop read sib response event */ +#define EVTCTFSNFSTRDSIBRSP 16 + +/* Sniffer msg */ +#define EVTCTFSNFREQMSGS 17 +#define EVTCTFSNFRSPMSGS 18 + +#define EVTCTFBTCHPROCTICK 19 +#define EVTCTFNRTRBUFCLEAN 20 + +/* CNM feature start */ +#define EVTCTFCNMINITSYNCREQ 21 +#define EVTCTFCNMINITSYNCRSP 22 + +#define EVTCTFCNMSYNCREQ 23 +#define EVTCTFCNMSYNCRSP 24 +#define EVTCTFCNMSYNCIND 25 +/* CNM feature end */ +#define EVTL2LOGBUF 28 +/* Periodic REM for TPM */ +#define EVTCTFPREMCELLSRCHRSP 26 +/* Periodic REM for TPM End */ + +#ifdef RSYS_WIRESHARK +#define EVTCTFWIRESHARKMSG 27 +#endif + +#define OAM_LTE_MAX_CARRIER_LIST 100 +#define MAX_NO_OF_NEIGHBOURS 16 +#define CPHY_MAX_BCCH_SIZE 2048 +#define SI_PERIODICITY_CNT 32 +#define OAM_LTE_MAX_PCI_LIST 51 + +/** Configuration Confirm - Positive confirmation: config successful. */ +#define CTF_CFG_CFM_OK 1 +/** Configuration Confirm - Negative confirmation: config failed. */ +#define CTF_CFG_CFM_NOK 2 + +/** Configuration type : CONFIG/SETUP (cfgType in CtfCfgReq). */ +#define CTF_CONFIG 1 +/** Configuration type : RECONFIG/MODIFY (cfgType in CtfCfgReq). */ +#define CTF_RECONFIG 2 +/** Configuration type : DELETE/RELEASE (cfgType in CtfCfgReq). */ +#define CTF_DELETE 3 + +#ifdef TENB_AS_SECURITY +#define CTF_KDF_TYPE1 0 +#define CTF_KDF_TYPE2 1 +#define CTF_KDF_TYPE3 2 +#ifdef SS_RBUF +#define CTF_KDF_TYPE4 3 +#define CTF_KDF_TYPE5 4 +#endif +#endif + +/* CNM Feature start */ +#define CTF_CNM_MAX_CELL_SEARCH 16 +#define CTF_CNM_MAX_VENDOR_PARAMS 8 +/* CNM Feature end*/ + +/* Periodic REM for TPM */ +#define CTF_REM_MAX_CELL_SEARCH 16 +/* Periodic REM for TPM End */ + +/** Configuration element type : Cell (cfgElem in CtfCfgInfo/CtfReCfgInfo). */ +#define CTF_CELL_CFG 1 +/** Configuration element type : UE (cfgElem in CtfCfgInfo/CtfReCfgInfo). */ +#define CTF_UE_CFG 2 + +/* Starts - Fix for CR ccpu00123185 */ +#define CTF_TX_PWR_CFG 3 +/* Ends - Fix for CR ccpu00123185 */ + +#define CTF_CELL_STOP 4 + +/** Configuration type for any sub-element : Setup */ +#define CTF_IE_CFG_SETUP 1 +/** Configuration type for any sub-element : Release */ +#define CTF_IE_CFG_RELEASE 2 + +/** CQI reporting mode configuration type : Periodic + * (reportingMode in CtfCqiReportCfgInfo). +*/ +#define CTF_CQI_RPTMODE_PRDIOC 1 +/** CQI reporting mode configuration type : Aperiodic + * (reportingMode in CtfCqiReportCfgInfo). +*/ +#define CTF_CQI_RPTMODE_APRDIOC 2 + +/** Periodic CQI format indicator configuration type : Wideband + * (formatIndicator in CtfCqiRptModePeriodic). +*/ +#define CTF_CQI_PRDIC_FMT_IND_WIDEBAND 1 +/** Periodic CQI format indicator configuration type : Subband + * (formatIndicator in CtfCqiRptModePeriodic). +*/ +#define CTF_CQI_PRDIC_FMT_IND_SUBBAND 2 + + +#define CTF_CFG_TRANSID_SIZE 9 /*!< Macro for Transaction ID size */ + +/* selector(coupling) values */ +#define CTF_SEL_LC 0 /*!< Macro for Light Coupling */ +#define CTF_SEL_TC 1 /*!< Macro for Tight Coupling */ +#define CTF_SEL_LWLC 2 /*!< Macro for Light Weight Loose Coupling */ + +/* Amit */ +#define CTF_MAX_SCELL_PER_UE 7 +#ifdef TENB_AS_SECURITY +#define CTF_MEM_SDU_SIZE 512 +/*Security related information*/ +#define CTF_SEC_KEY_LEN 32 +#define CTF_DER_KEY_LEN 32 +#define CTF_STRING_S_LEN 7 +#endif + +/*EMTC */ +#ifdef EMTC_ENABLE +#define CTF_MAX_CE_LEVEL 4 /*max number of CE LEVEL */ +#endif +/*EMTC*/ + +#define CTF_LTEU_MAX_EARFCN 10 +#ifdef ENABLE_CNM +#define EVTCTFCNMMSG 90/* Added for CNM Feature */ +#endif +#ifdef L2_L3_SPLIT +#define EVTCTFNMMMSG 91/* Added for CNM Feature */ +#endif + +/* pack unpack error code */ +#define ECTFXXX 0 /* reserved */ + +#define ERRCTF 0 + +#define ECTF001 (ERRCTF + 1) +#define ECTF002 (ERRCTF + 2) +#define ECTF003 (ERRCTF + 3) +#define ECTF004 (ERRCTF + 4) +#define ECTF005 (ERRCTF + 5) +#define ECTF006 (ERRCTF + 6) +#define ECTF007 (ERRCTF + 7) +#define ECTF008 (ERRCTF + 8) +#define ECTF009 (ERRCTF + 9) +#define ECTF010 (ERRCTF + 10) +#define ECTF011 (ERRCTF + 11) +#define ECTF012 (ERRCTF + 12) +#define ECTF013 (ERRCTF + 13) +#define ECTF014 (ERRCTF + 14) +#define ECTF015 (ERRCTF + 15) +#define ECTF016 (ERRCTF + 16) +#define ECTF017 (ERRCTF + 17) +#define ECTF018 (ERRCTF + 18) +#define ECTF019 (ERRCTF + 19) +#define ECTF020 (ERRCTF + 20) +#define ECTF021 (ERRCTF + 21) +#define ECTF022 (ERRCTF + 22) +#define ECTF023 (ERRCTF + 23) +#define ECTF024 (ERRCTF + 24) +#define ECTF025 (ERRCTF + 25) +#define ECTF026 (ERRCTF + 26) +#define ECTF027 (ERRCTF + 27) +#define ECTF028 (ERRCTF + 28) +#define ECTF029 (ERRCTF + 29) +#define ECTF030 (ERRCTF + 30) +#define ECTF031 (ERRCTF + 31) +#define ECTF032 (ERRCTF + 32) +#define ECTF033 (ERRCTF + 33) +#define ECTF034 (ERRCTF + 34) +#define ECTF035 (ERRCTF + 35) +#define ECTF036 (ERRCTF + 36) +#define ECTF037 (ERRCTF + 37) +#define ECTF038 (ERRCTF + 38) +#define ECTF039 (ERRCTF + 39) +#define ECTF040 (ERRCTF + 40) +#define ECTF041 (ERRCTF + 41) +#define ECTF042 (ERRCTF + 42) +#define ECTF043 (ERRCTF + 43) +#define ECTF044 (ERRCTF + 44) +#define ECTF045 (ERRCTF + 45) +#define ECTF046 (ERRCTF + 46) +#define ECTF047 (ERRCTF + 47) +#define ECTF048 (ERRCTF + 48) +#define ECTF049 (ERRCTF + 49) +#define ECTF050 (ERRCTF + 50) +#define ECTF051 (ERRCTF + 51) +#define ECTF052 (ERRCTF + 52) +#define ECTF053 (ERRCTF + 53) +#define ECTF054 (ERRCTF + 54) +#define ECTF055 (ERRCTF + 55) +#define ECTF056 (ERRCTF + 56) +#define ECTF057 (ERRCTF + 57) +#define ECTF058 (ERRCTF + 58) +#define ECTF059 (ERRCTF + 59) +/* ctf_h_001.main_2: Added new error code. */ +#define ECTF060 (ERRCTF + 60) +#define ECTF061 (ERRCTF + 61) + +#endif /* __CTF_H__ */ + + +/********************************************************************** + + End of file +**********************************************************************/ diff --git a/src/cm/envdep.h b/src/cm/envdep.h new file mode 100755 index 000000000..7f6bb9802 --- /dev/null +++ b/src/cm/envdep.h @@ -0,0 +1,2154 @@ +/******************************************************************************* +################################################################################ +# Copyright (c) [2017-2019] [Radisys] # +# # +# 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. # +################################################################################ +*******************************************************************************/ + +/********************************************************************20** + + Name: environment dependent + + Type: C include file + + Desc: Environment dependent defines required by the + by TRILLIUM software. The defines in this file need to + be changed by the customer to reflect the + processor family under which the TRILLIUM software + will run. + + File: envdep.h + +*********************************************************************21*/ + +#ifndef __ENVDEPH__ +#define __ENVDEPH__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* envdep_h_001.main_70: Additions */ +/* envdep_h_001.main_73: Not required for SUNOS */ +#ifdef SS_LINUX +#ifndef _GNU_SOURCE +#include +#define __USE_UNIX98 +#endif /* _GNU_SOURCE */ +#endif /* SS_LINUX */ +/*envdep_h_001.main_75 : RMIOS related changes*/ +#ifdef SS_RMIOS +#include "printk.h" +#endif + + +/* conversion of MSCDOS and MSCUNIX for backwards compatibility */ + +#ifdef MSCDOS /* microsoft, dos */ +#define ANSI /* ansi */ +#define DOS /* dos */ +#define MSC51 /* microsoft */ +#else /* not microsoft, dos */ +#ifdef MSCUNIX /* microsoft, unix */ +#define ANSI /* ansi */ +#define UNIX /* unix */ +#define MSC51 /* microsoft */ +#else /* not microsoft, dos or unix */ +#endif +#endif + +/* ensure microsoft 7.0 backwards compatible with microsoft 5.1 */ + +#ifdef MSC70 +#define MSC51 +#endif + +/* ensure microsoft 6.0 backwards compatible with microsoft 5.1 */ + +#ifdef MSC60 +#define MSC51 +#endif + +/* default to sunos 5.1 for sunos */ + +#ifdef SUNOS +#define SUNOS51 +#endif + +/* ensure sunos 4.1 backwards compatible with sunos */ + +#ifdef SUNOS41 +#ifndef SUNOS +#define SUNOS +#endif +#endif + +/* ensure sunos 5.1 backwards compatible with sunos */ + +#ifdef SUNOS51 +#ifndef SUNOS +#define SUNOS +#endif +#endif + +/* ensure elvis backwards compatible with sunos */ +#ifdef ELVIS_STACK +#ifndef SUNOS +#define SUNOS +#endif +#endif + +#ifdef ELVIS_APP +#ifndef SUNOS +#define SUNOS +#endif +#endif + +#ifdef POWER_STACK +#define UNIX +#define AIX +#define PROC_PPC +#endif /* POWER_STACK */ + +/* Fujitsu ALC evalutation board */ +#ifdef ALC_EVAL +#define PROC_68349 +#define PROC_68XXX +#define SOLMRI43 +#endif /* ALC_EVAL */ + +/* argument manipulation for ansi or non ansi function prototypes */ + +#ifdef ANSI /* ansi */ +#define ARGS(m) m +#else /* non ansi */ +#define ARGS(m) () +#endif + +/* type definition for ansi or non ansi pointers */ +#ifdef ANSI +typedef void *Ptr; /* ANSI vanilla pointer type definition */ +#else +typedef char *Ptr; /* K&R vanilla pointer type definition */ +#endif + + +/********************************************************************** + memory models +**********************************************************************/ + +/* + these defines are arranged first by environment (DOS, UNIX, SUNOS or + embedded) followed by compiler (microsoft c, borland, unix or + microtec c) as appropriate. +*/ +/*envdep_h_001.main_77 SSI-4GMX specfic changes*/ +#ifndef SS_4GMX_LCORE +/* envdep_h_001.main_76 Force definition of WIN32 when detecting WIN64 */ +#if defined(_WIN32) || defined(_WIN64) /* dos, nt win32 */ +#ifndef WIN32 + #define WIN32 +#endif +#endif +#endif + +#ifdef WIN32 /* dos, nt win32 */ +#define INTERRPT /* interrupt */ +#define ASM /* in-line assembly code */ +#define ISR_PUSH_ENV /* isr push environment */ +#define ISR_POP_ENV /* isr pop environment */ + +#define M_I86CM /* Intel 80x86 compact model */ + +#define BIOSKEY _bios_keybrd +#define BIOSTOD _bios_timeofday +#define DOSKEEP _dos_keep +#define DOSGETDATE _dos_getdate +#define DOSGETTIME _dos_gettime +#define DOSDATE dosdate_t +#define DOSTIME dostime_t +#define DOSSIZE size_t +#define DOSENABLE _enable +#define DOSDISABLE _disable +#define DOSGETVECT _dos_getvect +#define DOSSETVECT _dos_setvect +#define DOSINT86 int86 +#define DOSINT86X int86x +#define DOSMALLOC malloc +#define DOSEXIT _exit +#define NEAR _NEAR + +#define KEYBRD_READY _KEYBRD_READY +#define KEYBRD_READ _KEYBRD_READ +#define TIME_GETCLOCK _TIME_GETCLOCK +#endif /* WIN32 */ + +/*envdep_h_001.main_75 : RMIOS related changes*/ +#ifdef SS_RMIOS +#define INTERRPT /* interrupt */ +#define ASM /* in-line assembly code */ +#define ISR_PUSH_ENV /* isr push environment */ +#define ISR_POP_ENV /* isr pop environment */ +#endif + +#if (defined(VXWORKS_PENTIUM) || defined(VXWORKS_DIAB)) +#define INTERRPT /* interrupt */ +#define ASM /* in-line assembly code */ +#define ISR_PUSH_ENV /* isr push environment */ +#define ISR_POP_ENV /* isr pop environment */ + +#define M_I86CM /* Intel 80x86 compact model */ + +#define BIOSKEY _bios_keybrd +#define BIOSTOD _bios_timeofday +#define DOSKEEP _dos_keep +#define DOSGETDATE _dos_getdate +#define DOSGETTIME _dos_gettime +#define DOSDATE dosdate_t +#define DOSTIME dostime_t +#define DOSSIZE size_t +#define DOSENABLE _enable +#define DOSDISABLE _disable +#define DOSGETVECT _dos_getvect +#define DOSSETVECT _dos_setvect +#define DOSINT86 int86 +#define DOSINT86X int86x +#define DOSMALLOC malloc +#define DOSEXIT _exit +#define NEAR _NEAR + +#define KEYBRD_READY _KEYBRD_READY +#define KEYBRD_READ _KEYBRD_READ +#define TIME_GETCLOCK _TIME_GETCLOCK +#endif /* VXWORKS_PENTIUM */ + + +#ifdef DOS /* dos */ +#ifdef MSC51 /* dos, microsoft c */ +#ifdef M_I86HM /* Intel 80x86 huge model */ +#define INTERRPT _interrupt /* interrupt */ +#else +#define INTERRPT _interrupt far /* interrupt */ +#endif /* M_I86HM */ +#define ASM /* in-line assembly code */ +#define ISR_PUSH_ENV /* isr push environment */ +#define ISR_POP_ENV /* isr pop environment */ +#define BIOSKEY _bios_keybrd +#define BIOSTOD _bios_timeofday +#define DOSGETDATE _dos_getdate +#define DOSGETTIME _dos_gettime +#define DOSDATE dosdate_t +#define DOSTIME dostime_t +#define DOSENABLE _enable +#define DOSDISABLE _disable +#define DOSGETVECT _dos_getvect +#define DOSSETVECT _dos_setvect +#define DOSEXIT _exit +#define NEAR _NEAR +#define KEYBRD_READY _KEYBRD_READY +#define KEYBRD_READ _KEYBRD_READ +#define TIME_GETCLOCK _TIME_GETCLOCK + +#ifdef M_I86SM /* Intel 80x86 small model */ +#define I86SM +#endif /* M_I86SM */ + +#ifdef M_I86MM /* Intel 80x86 medium model */ +#define I86MM +#endif /* M_I86MM */ + +#ifdef M_I86CM /* Intel 80x86 compact model */ +#define I86CM +#endif /* M_I86CM */ + +#ifdef M_I86LM /* Intel 80x86 large model */ +#define I86LM +#endif /* M_I86LM */ + +#ifdef M_I86HM /* Intel 80x86 huge model */ +#define I86HM +#endif /* M_I86HM */ +#else /* not MSC51*/ +#ifdef BOR31 /* dos, borland c */ +#define INTERRPT _interrupt far /* interrupt */ +#define ASM /* in-line assembly code */ +#define ISR_PUSH_ENV /* isr push environment */ +#define ISR_POP_ENV /* isr pop environment */ + +#define I86LM /* Intel 80x86 large model */ + +#define BIOSKEY _bios_keybrd +#define BIOSTOD _bios_timeofday +#define DOSKEEP _dos_keep +#define DOSGETDATE _dos_getdate +#define DOSGETTIME _dos_gettime +#define DOSDATE dosdate_t +#define DOSTIME dostime_t +#define DOSSIZE size_t +#define DOSENABLE _enable +#define DOSDISABLE _disable +#define DOSGETVECT _dos_getvect +#define DOSSETVECT _dos_setvect +#define DOSINT86 int86 +#define DOSINT86X int86x +#define DOSMALLOC malloc +#define DOSEXIT _exit +#define NEAR _NEAR + +#define KEYBRD_READY _KEYBRD_READY +#define KEYBRD_READ _KEYBRD_READ +#define TIME_GETCLOCK _TIME_GETCLOCK +#else /* not BOR31 */ +#endif /* BOR31 */ +#endif /* MSC51 */ +#else /* not DOS */ +#ifdef UNIX /* unix */ +#define INTERRPT /* interrupt */ +#define ASM /* in-line assembly code */ +#define ISR_PUSH_ENV /* isr push environment */ +#define ISR_POP_ENV /* isr pop environment */ + + +#ifdef __alpha /* alpha */ +#define ALPHA +#undef OTHMOD +#endif /* __alpha */ +#else /* not UNIX */ +#ifdef SUNOS /* sun os */ +#define PROC_SPARC /* sparc model */ +#define UNIX /* unix */ + +#define INTERRPT /* interrupt */ +#define ASM /* in-line assembly code */ +#define ISR_PUSH_ENV /* isr push environment */ +#define ISR_POP_ENV /* isr pop environment */ +#else /* not SUNOS */ +#ifdef HPOS /* HP os */ +#define PROC_PARISC /* HP PA model */ +#define UNIX /* unix */ + +#define INTERRPT /* interrupt */ +#define ASM /* in-line assembly code */ +#define ISR_PUSH_ENV /* isr push environment */ +#define ISR_POP_ENV /* isr pop enviroment */ +#else /* not HPOS */ +#ifdef MOTADS /* embedded, motorola ads */ +#define PROC_68302 /* enable 68302 specific defines */ +#define M68 /* motorola 68000 */ + +#ifdef DOSMRI42D /* DOS microtec c cross-compiler */ +#define MRI68K /* microtec 68K c compiler */ +#define INTERRPT interrupt /* interrupt */ +#define ASM asm /* in-line assembly code */ +#define ISR_PUSH_ENV ASM(" movem.l d2-d7/a2-a6,-(a7)") /* isr push environment */ +#define ISR_POP_ENV ASM(" movem.l (a7)+,d2-d7/a2-a6") /* isr pop environment */ +#endif /* DOSMRI42D */ + +#ifdef SOLMRI43 /* solaris microtec c cross-compiler */ +#define MRI68K /* microtec 68K c compiler */ +#define INTERRPT interrupt /* interrupt */ +#define ASM asm /* in-line assembly code */ +#define ISR_PUSH_ENV ASM(" movem.l d2-d7/a2-a6,-(a7)") /* isr push environment */ +#define ISR_POP_ENV ASM(" movem.l (a7)+,d2-d7/a2-a6") /* isr pop environment */ +#endif /* SOLMRI43 */ + +#ifdef SOLOAS186 /* solaris oasys c cross-compiler */ +#define INTERRPT /* interrupt */ +#ifdef ANSI +#define ASM __asm /* in-line assembly code */ +#else /* not ANSI */ +#define ASM asm /* in-line assembly code */ +#endif /* ANSI */ +#define ISR_PUSH_ENV /* isr push environment */ +#define ISR_POP_ENV /* isr pop environment */ +#endif /* SOLOAS186 */ + +#else /* not MOTADS */ +#ifdef ELVIS /* elvis specific (not sun os) */ +#define M68 /* motorola 68000 */ + +#ifdef DOSMRI42D /* DOS microtec c cross-compiler */ +#define MRI68K /* microtec 68K c compiler */ +#define INTERRPT interrupt /* interrupt */ +#define ASM asm /* in-line assembly code */ +#define ISR_PUSH_ENV ASM(" movem.l d2-d7/a2-a6,-(a7)") /* isr push environment */ +#define ISR_POP_ENV ASM(" movem.l (a7)+,d2-d7/a2-a6") /* isr pop environment */ +#endif /* DOSMRI42D */ + +#ifdef SOLMRI43 /* solaris microtec c cross-compiler */ +#define MRI68K /* microtec 68K c compiler */ +#define INTERRPT interrupt /* interrupt */ +#define ASM asm /* in-line assembly code */ +#define ISR_PUSH_ENV ASM(" movem.l d2-d7/a2-a6,-(a7)") /* isr push environment */ +#define ISR_POP_ENV ASM(" movem.l (a7)+,d2-d7/a2-a6") /* isr pop environment */ +#endif /* SOLMRI43 */ + +#ifdef SOLOAS186 /* solaris oasys c cross-compiler */ +#define INTERRPT /* interrupt */ +#ifdef ANSI +#define ASM __asm /* in-line assembly code */ +#else /* not ANSI */ +#define ASM asm /* in-line assembly code */ +#endif /* ANSI */ +#define ISR_PUSH_ENV /* isr push environment */ +#define ISR_POP_ENV /* isr pop environment */ +#endif /* SOLOAS186 */ + +#else /* not ELVIS */ + +#ifdef MSC51 /* embedded, microsoft c */ +#ifdef M_I86HM /* Intel 80x86 huge model */ +#define INTERRPT _interrupt /* interrupt */ +#else /* not M_I86HM */ +#define INTERRPT _interrupt far /* interrupt */ +#endif /* M_I86HM */ +#define ASM /* in-line assembly code */ +#define ISR_PUSH_ENV /* isr push environment */ +#define ISR_POP_ENV /* isr pop environment */ +#define BIOSKEY _bios_keybrd +#define BIOSTOD _bios_timeofday +#define DOSGETDATE _dos_getdate +#define DOSGETTIME _dos_gettime +#define DOSDATE dosdate_t +#define DOSTIME dostime_t +#define DOSENABLE _enable +#define DOSDISABLE _disable +#define DOSGETVECT _dos_getvect +#define DOSSETVECT _dos_setvect +#define DOSEXIT _exit +#define NEAR _NEAR + +#define KEYBRD_READY _KEYBRD_READY +#define KEYBRD_READ _KEYBRD_READ +#define TIME_GETCLOCK _TIME_GETCLOCK + +#ifdef M_I86SM /* Intel 80x86 small model */ +#define I86SM +#endif /* M_I86SM */ + +#ifdef M_I86MM /* Intel 80x86 medium model */ +#define I86MM +#endif /* M_I86MM */ + +#ifdef M_I86CM /* Intel 80x86 compact model */ +#define I86CM +#endif /* M_I86CM */ + +#ifdef M_I86LM /* Intel 80x86 large model */ +#define I86LM +#endif /* M_I86CM */ + +#ifdef M_I86HM /* Intel 80x86 huge model */ +#define I86HM +#endif /* M_I86HM */ +#else /* not MSC51 */ +#ifdef BOR31 /* embedded, borland c */ +#define INTERRPT /* interrupt */ +#define ASM /* in-line assembly code */ +#define ISR_PUSH_ENV /* isr push environment */ +#define ISR_POP_ENV /* isr pop environment */ +#define I86LM /* Intel 80x86 large model */ + +#define BIOSKEY _bios_keybrd +#define BIOSTOD _bios_timeofday +#define DOSKEEP _dos_keep +#define DOSGETDATE _dos_getdate +#define DOSGETTIME _dos_gettime +#define DOSDATE dosdate_t +#define DOSTIME dostime_t +#define DOSSIZE size_t +#define DOSENABLE _enable +#define DOSDISABLE _disable +#define DOSGETVECT _dos_getvect +#define DOSSETVECT _dos_setvect +#define DOSINT86 int86 +#define DOSINT86X int86x +#define DOSMALLOC malloc +#define DOSEXIT _exit +#define NEAR _NEAR + +#define KEYBRD_READY _KEYBRD_READY +#define KEYBRD_READ _KEYBRD_READ +#define TIME_GETCLOCK _TIME_GETCLOCK +#else /* not BOR31 */ +#ifdef DOSMRI42D /* dos microtec c cross-compiler */ +#define MRI68K /* microtec 68K c compiler */ +#define INTERRPT interrupt /* interrupt */ +#define ASM asm /* in-line assembly code */ +#define ISR_PUSH_ENV ASM(" movem.l d2-d7/a2-a6,-(a7)") /* isr push environment */ +#define ISR_POP_ENV ASM(" movem.l (a7)+,d2-d7/a2-a6") /* isr pop environment */ +#ifdef _M68 +#define M68 /* motorola 68000 */ +#endif /* _M68 */ +#else /* DOSMRI42D */ +#ifdef SOLMRI43 /* solaris microtec c cross-compiler */ +#define MRI68K /* microtec 68K c compiler */ +#define INTERRPT interrupt /* interrupt */ +#define ASM asm /* in-line assembly code */ +#define ISR_PUSH_ENV ASM(" movem.l d2-d7/a2-a6,-(a7)") /* isr push environment */ +#define ISR_POP_ENV ASM(" movem.l (a7)+,d2-d7/a2-a6") /* isr pop environment */ +#ifdef _M68 +#define M68 /* motorola 68000 */ +#endif /* _M68 */ +#else /* not SOLMRI43 */ +#ifdef SOLOAS186 /* solaris oasys c cross-compiler */ +#define INTERRPT /* interrupt */ +#ifdef ANSI +#define ASM __asm /* in-line assembly code */ +#else /* not ANSI */ +#define ASM asm /* in-line assembly code */ +#endif /* ANSI */ +#define ISR_PUSH_ENV /* isr push environment */ +#define ISR_POP_ENV /* isr pop environment */ +#ifdef m68k /* motorola 68000 series */ +#define M68 /* motorola 68000 */ +#endif /* m68k */ +#else /* not SOLOAS186 */ +#ifdef MOTDCI_68360 +#define M68 +#define PROC_68XXX +#define PROC_68360 +#ifdef __GNUC__ +#define INTERRPT +#define ASM __asm__ /* in-line assembly code */ +#define ISR_PUSH_ENV /* isr push environment */ +#define ISR_POP_ENV /* isr pop environment */ +#else +#ifdef _MCC68K +#define INTERRPT interrupt +#define ASM asm /* in-line assembly code */ +#define ISR_PUSH_ENV ASM(" movem.l d2-d7/a2-a6,-(a7)") /* isr push env */ +#define ISR_POP_ENV ASM(" movem.l (a7)+,d2-d7/a2-a6") /* isr pop env */ +#endif /* _MCC68K */ +#endif /* __GNUCC__ */ +#else +#ifdef QUICCADS +#define M68 +#define PROC_68XXX +#define PROC_68360 +#ifdef __GNUC__ +#define INTERRPT +#define ASM __asm__ /* in-line assembly code */ +#define ISR_PUSH_ENV /* isr push environment */ +#define ISR_POP_ENV /* isr pop environment */ +#else /* not gnu cc */ +#ifdef _MCC68K +#define INTERRPT interrupt +#define ASM asm /* in-line assembly code */ +#define ISR_PUSH_ENV ASM(" movem.l d2-d7/a2-a6,-(a7)") /* isr push env */ +#define ISR_POP_ENV ASM(" movem.l (a7)+,d2-d7/a2-a6") /* isr pop env */ +#endif /* _MCC68K */ +#endif /* __GNUCC__ */ +#else +#ifdef ALC_EVAL +#ifdef SOLMRI43 +#define MRI68K /* microtec 68K c compiler */ +#define INTERRPT interrupt /* interrupt */ +#define ASM asm /* in-line assembly code */ +#define ISR_PUSH_ENV ASM(" movem.l d2-d7/a2-a6,-(a7)") /* isr push environment */ +#define ISR_POP_ENV ASM(" movem.l (a7)+,d2-d7/a2-a6") /* isr pop environment */ +#ifdef _M68 +#define M68 /* motorola 68000 */ +#endif /* _M68 */ +#endif /* SOLMRI43 */ +#else +#ifdef GSIP302 +#define M68 +#define PROC_68XXX +#define PROC_68302 +#ifdef __GNUC__ +#define INTERRPT +#define ASM __asm__ /* in-line assembly code */ +#define ISR_PUSH_ENV /* isr push environment */ +#define ISR_POP_ENV /* isr pop environment */ +#else /* not gnu cc */ +#ifdef _MCC68K +#define INTERRPT interrupt +#define ASM asm /* in-line assembly code */ +#define ISR_PUSH_ENV ASM(" movem.l d2-d7/a2-a6,-(a7)") /* isr push env */ +#define ISR_POP_ENV ASM(" movem.l (a7)+,d2-d7/a2-a6") /* isr pop env */ +#endif /* _MCC68K */ +#endif /* __GNUCC__ */ +#else /* not GSIP302 */ +#ifdef VB_360 +#define M68 +#define PROC_68XXX +#define PROC_68360 +#ifdef __GNUC__ +#define INTERRPT +#define ASM __asm__ /* in-line assembly code */ +#define ISR_PUSH_ENV /* isr push environment */ +#define ISR_POP_ENV /* isr pop environment */ +#else +#ifdef _MCC68K +#define INTERRPT interrupt +#define ASM asm /* in-line assembly code */ +#define ISR_PUSH_ENV ASM(" movem.l d2-d7/a2-a6,-(a7)") /* isr push env */ +#define ISR_POP_ENV ASM(" movem.l (a7)+,d2-d7/a2-a6") /* isr pop env */ +#endif /* _MCC68K */ +#endif /* __GNUCC__ */ +#else /* not VB_360 */ +#ifdef PQ_PPC860 /* Force PowerQUICC board */ +#define PROC_PPC /* any PowerPC processor */ +#define PROC_PPC860 /* MPC860 processor */ +#ifdef __GNUC__ /* gnu C compiler */ +#define INTERRPT +#define ASM __asm__ /* in-line assembly code */ +#define ISR_PUSH_ENV /* isr push environment */ +#define ISR_POP_ENV /* isr pop environment */ +#else +#ifdef _MCCPPC /* micortech C compiler */ +#define INTERRPT +#define ASM asm /* in-line assembly code */ +#define ISR_PUSH_ENV /* isr push env */ +#define ISR_POP_ENV /* isr pop env */ +#endif /* _MCC68K */ +#endif /* __GNUCC__ */ +#else /* NOT PQ_PPC860 */ +#ifdef PCORE +#define PROC_PPC +#define PROC_PPC604 +#ifdef __GNUC__ +#define INTERRPT +#define ASM __asm__ /* in-line assembly code */ +#define ISR_PUSH_ENV /* isr push environment */ +#define ISR_POP_ENV /* isr pop environment */ +#else +#ifdef _MCCPPC +#define INTERRPT +#define ASM asm /* in-line assembly code */ +#define ISR_PUSH_ENV /* isr push env */ +#define ISR_POP_ENV /* isr pop env */ +#endif /* _MCC68K */ +#endif /* __GNUCC__ */ +#else /* PCORE */ +#ifdef SS_PS /* pSOS RTOS */ +#define INTERRPT +#define ASM __asm /* in-line assembly code */ +#define ISR_PUSH_ENV /* isr push env */ +#define ISR_POP_ENV /* isr pop env */ +#else /* not SS_PS */ +#define OTHMOD /* other model */ +#endif /* SS_PS */ +#endif /* PCORE */ +#endif /* PQ_PPC860 */ +#endif /* VB_360 */ +#endif /* GSIP302 */ +#endif /* ALC_EVAL */ +#endif /* QUICCADS */ +#endif /* MOTDCI_68360 */ +#endif /* SOLOAS186 */ +#endif /* SOLMRI43 */ +#endif /* DOSMRI42D */ +#endif /* BOR31 */ +#endif /* MSC51 */ +#endif /* ELVIS */ +#endif /* MOTADS */ +#endif /* HPOS */ +#endif /* SUNOS */ +#endif /* UNIX */ +#endif /* DOS */ + + +/********************************************************************** + typedefs +**********************************************************************/ + +/* + these typedefs are arranged first by environment (DOS, UNIX or + embedded) followed by compiler (microsoft c, borland c, unix or + microtec c) as appropriate. +*/ + +#ifdef DOS /* dos */ +#ifdef MSC51 /* dos, microsoft c */ + +typedef unsigned char Bool; /* boolean */ +typedef char S8; /* signed - 8 bits */ +typedef unsigned char U8; /* unsigned - 8 bits */ + +typedef int S16; /* signed - 16 bits */ +typedef unsigned int U16; /* unsigned - 16 bits */ + +typedef long S32; /* signed - 32 bits */ +typedef unsigned long U32; /* unsigned - 32 bits */ +/* envdep_h_001.main_71 */ +typedef __int64 S64; /* signed - 64 bits */ +typedef unsigned __int64 U64; /* unsigned - 64 bits */ + +/* + void + + note: if typedef Void is set to S16 then RETVOID must be set + to: return(ROK). if typedef Void is set to void then RETVOID + must be set to: return +*/ + +/* envdep_h_001.main_78 Change typedef void to #define void*/ +#define Void void + +typedef S8 (*PFS8) ARGS((void )); /* pointer to function returning S8 */ +typedef S16 (*PFS16) ARGS((void )); /* pointer to function returning S16 */ +typedef S32 (*PFS32) ARGS((void )); /* pointer to function returning S32 */ +typedef Void (*PFVOID) ARGS((void )); /* pointer to function returning Void */ +typedef Void (INTERRPT *PIF) ARGS((void )); /* pointer to interrupt function */ + +#else /* not MSC51 */ +#ifdef BOR31 /* dos, borland c */ + +typedef unsigned char Bool; /* boolean */ +typedef char S8; /* signed - 8 bits */ +typedef unsigned char U8; /* unsigned - 8 bits */ + +typedef int S16; /* signed - 16 bits */ +typedef unsigned int U16; /* unsigned - 16 bits */ + +typedef long S32; /* signed - 32 bits */ +typedef unsigned long U32; /* unsigned - 32 bits */ + +/* + void + + note: if typedef Void is set to S16 then RETVOID must be set + to: return(ROK). if typedef Void is set to void then RETVOID + must be set to: return +*/ + +typedef void Void; /* void */ + +typedef S8 (*PFS8) ARGS((void )); /* pointer to function returning S8 */ +typedef S16 (*PFS16) ARGS((void )); /* pointer to function returning S16 */ +typedef S32 (*PFS32) ARGS((void )); /* pointer to function returning S32 */ +typedef Void (*PFVOID) ARGS((void )); /* pointer to function returning Void */ +typedef Void (INTERRPT far *PIF) ARGS((void )); /* pointer to interrupt function */ + +#else /* not BOR31 */ +#endif /* BOR31 */ +#endif /* MSC51 */ +#else /* not DOS */ +#ifdef UNIX /* unix */ + +typedef unsigned char Bool; /* boolean */ +/*envdep_h_001.main_77 SSI-4GMX specfic changes*/ +#if !(defined(SS_4GMX_LCORE) || defined(SS_4GMX_UCORE)) +typedef char S8; /* signed - 8 bits */ +#else +/*envdep_h_001.main_78 :removed signed to supress sprintf' differ in signedness warnings */ +typedef char S8; /* signed - 8 bits*/ +#endif +typedef unsigned char U8; /* unsigned - 8 bits */ + +typedef short S16; /* signed - 16 bits */ +typedef unsigned short U16; /* unsigned - 16 bits */ + +#if !(defined(ALPHA) || defined(BIT_64)) +typedef long S32; /* signed - 32 bits */ +typedef unsigned long U32; /* unsigned - 32 bits */ +/* envdep_h_001.main_71 */ +#ifdef SS_LINUX +/* envdep_h_001.main_79 RVDT compiler warning fix */ +#ifndef SS_4GMX_LCORE +/* envdep_h_001.main_72: Support for C89 standard */ +__extension__ typedef long long S64; /* signed - 64 bits */ +__extension__ typedef unsigned long long U64; /* unsigned - 64 bits */ +#else +typedef long long S64; /* signed - 64 bits */ +typedef unsigned long long U64; /* unsigned - 64 bits */ +#define Void void /* RVDT compiler warning fix */ +#endif /* SS_4GMX_LCORE */ +#else +typedef long long S64; /* signed - 64 bits */ +typedef unsigned long long U64; /* unsigned - 64 bits */ +#endif /* SS_LINUX */ +#else /* ALPHA & BIT_64 */ +typedef int S32; /* signed - 32 bits */ +typedef unsigned int U32; /* unsigned - 32 bits */ +/* envdep_h_001.main_71 */ +typedef long S64; /* signed - 64 bits */ +typedef unsigned long U64; /* unsigned - 64 bits */ +#endif /* ALPHA & BIT_64 */ +/* 1. Added F32 and F64 */ +#ifdef SS_FLOAT +typedef float F32; /* float - 32 bits */ +typedef double F64; /* double - 64 bits */ +#endif /* SS_FLOAT */ + +/* + void + + note: if typedef Void is set to S16 then RETVOID must be set + to: return(ROK). if typedef Void is set to void then RETVOID + must be set to: return +*/ + +#ifdef __cplusplus +#define Void void +#else +/* envdep_h_001.main_79 RVDT compiler warning fix */ +#ifndef SS_4GMX_LCORE +typedef void Void; /* void */ +#endif +#endif + +typedef S8 (*PFS8) ARGS((void )); /* pointer to function returning S8 */ +typedef S16 (*PFS16) ARGS((void )); /* pointer to function returning S16 */ +typedef S32 (*PFS32) ARGS((void )); /* pointer to function returning S32 */ +typedef Void (*PFVOID) ARGS((void )); /* pointer to function returning VOID */ +typedef Void (INTERRPT *PIF) ARGS((void )); /* pointer to interrupt function */ + +#else /* not UNIX */ +#ifdef PROC_68302 /* embedded, motorola ads */ +#ifdef DOSMRI42D /* dos microtec c cross-compiler */ + +typedef unsigned char Bool; /* boolean */ +typedef char S8; /* signed - 8 bits */ +typedef unsigned char U8; /* unsigned - 8 bits */ + +typedef short S16; /* signed - 16 bits */ +typedef unsigned short U16; /* unsigned - 16 bits */ + +typedef int S32; /* signed - 32 bits */ +typedef unsigned int U32; /* unsigned - 32 bits */ + +#ifndef ANSI +/* size_t is not defined, for some odd reason, in mcc68k's stddef.h */ +typedef unsigned size_t; /* size_t */ +#endif /* not ANSI */ + +/* + void + + note: if typedef Void is set to S16 then RETVOID must be set + to: return(ROK). if typedef Void is set to void then RETVOID + must be set to: return +*/ + +typedef void Void; /* void */ +typedef Void VOID; /* void */ + +typedef S8 (*PFS8) ARGS((void )); /* pointer to function returning S8 */ +typedef S16 (*PFS16) ARGS((void )); /* pointer to function returning S16 */ +typedef S32 (*PFS32) ARGS((void )); /* pointer to function returning S32 */ +typedef Void (*PFVOID) ARGS((void )); /* pointer to function returning Void */ +typedef Void (*PIF) ARGS((void )); /* pointer to interrupt function */ + +#else /* not DOSMRI42D */ +#ifdef SOLMRI43 /* solaris microtec c cross-compiler */ + +typedef unsigned char Bool; /* boolean */ +typedef char S8; /* signed - 8 bits */ +typedef unsigned char U8; /* unsigned - 8 bits */ + +typedef short S16; /* signed - 16 bits */ +typedef unsigned short U16; /* unsigned - 16 bits */ + +typedef int S32; /* signed - 32 bits */ +typedef unsigned int U32; /* unsigned - 32 bits */ + +/* + void + + note: if typedef Void is set to S16 then RETVOID must be set + to: return(ROK). if typedef Void is set to void then RETVOID + must be set to: return +*/ + +typedef void Void; /* void */ +typedef Void VOID; /* void */ + +typedef S8 (*PFS8) ARGS((void )); /* pointer to function returning S8 */ +typedef S16 (*PFS16) ARGS((void )); /* pointer to function returning S16 */ +typedef S32 (*PFS32) ARGS((void )); /* pointer to function returning S32 */ +typedef Void (*PFVOID) ARGS((void )); /* pointer to function returning Void */ +typedef Void (*PIF) ARGS((void )); /* pointer to interrupt function */ + +#else /* not SOLMRI43 */ +#ifdef SOLOAS186 /* solaris oasys c cross-compiler */ + +typedef unsigned char Bool; /* boolean */ +typedef char S8; /* signed - 8 bits */ +typedef unsigned char U8; /* unsigned - 8 bits */ + +typedef short S16; /* signed - 16 bits */ +typedef unsigned short U16; /* unsigned - 16 bits */ + +typedef int S32; /* signed - 32 bits */ +typedef unsigned int U32; /* unsigned - 32 bits */ + +/* + void + + note: if typedef Void is set to S16 then RETVOID must be set + to: return(ROK). if typedef Void is set to void then RETVOID + must be set to: return +*/ + +typedef void Void; /* void */ +typedef Void VOID; /* void */ + +typedef S8 (*PFS8) ARGS((void )); /* pointer to function returning S8 */ +typedef S16 (*PFS16) ARGS((void )); /* pointer to function returning S16 */ +typedef S32 (*PFS32) ARGS((void )); /* pointer to function returning S32 */ +typedef Void (*PFVOID) ARGS((void )); /* pointer to function returning Void */ +typedef Void (INTERRPT *PIF) ARGS((void )); /* pointer to interrupt function */ + +#else /* not SOLOAS186 */ +#ifdef __GNUC__ /* if GNUC cross compiler */ + +typedef unsigned char Bool; /* boolean */ +typedef char S8; /* signed - 8 bits */ +typedef unsigned char U8; /* unsigned - 8 bits */ + +typedef short S16; /* signed - 16 bits */ +typedef unsigned short U16; /* unsigned - 16 bits */ + +typedef int S32; /* signed - 32 bits */ +typedef unsigned int U32; /* unsigned - 32 bits */ +/* envdep_h_001.main_71 */ +typedef long long S64; /* signed - 64 bits */ +typedef unsigned long long U64; /* unsigned - 64 bits */ +/* 1. Added F32 and F64 types */ +#ifdef SS_FLOAT +typedef float F32; /* float - 32 bits */ +typedef double F64; /* double - 64 bits */ +#endif /* SS_FLOAT */ + +/* + void + + note: if typedef Void is set to S16 then RETVOID must be set + to: return(ROK). if typedef Void is set to void then RETVOID + must be set to: return +*/ + +typedef void Void; /* void */ +typedef Void VOID; /* void */ + +typedef S8 (*PFS8) ARGS((void )); /* pointer to function returning S8 */ +typedef S16 (*PFS16) ARGS((void )); /* pointer to function returning S16 */ +typedef S32 (*PFS32) ARGS((void )); /* pointer to function returning S32 */ +typedef Void (*PFVOID) ARGS((void )); /* pointer to function returning Void */ +typedef Void (INTERRPT *PIF) ARGS((void )); /* pointer to interrupt function */ + +#else /* not __GNUC__ */ +#endif /* __GNUC */ +#endif /* SOLOAS186 */ +#endif /* SOLMRI43 */ +#endif /* DOSMRI42D */ +#else /* not PROC_68302 */ +#ifdef PROC_68040 + +#ifdef SOLMRI43 /* solaris microtec c cross-compiler */ +typedef unsigned char Bool; /* boolean */ +typedef char S8; /* signed - 8 bits */ +typedef unsigned char U8; /* unsigned - 8 bits */ + +typedef short S16; /* signed - 16 bits */ +typedef unsigned short U16; /* unsigned - 16 bits */ + +typedef int S32; /* signed - 32 bits */ +typedef unsigned int U32; /* unsigned - 32 bits */ + +/* + void + + note: if typedef Void is set to S16 then RETVOID must be set + to: return(ROK). if typedef Void is set to void then RETVOID + must be set to: return +*/ + +typedef void Void; /* void */ +typedef Void VOID; /* void */ + +typedef S8 (*PFS8) ARGS((void )); /* pointer to function returning S8 */ +typedef S16 (*PFS16) ARGS((void )); /* pointer to function returning S16 */ +typedef S32 (*PFS32) ARGS((void )); /* pointer to function returning S32 */ +typedef Void (*PFVOID) ARGS((void )); /* pointer to function returning Void */ +typedef INTERRPT Void (*PIF) ARGS((void)); /* pointer to interrupt function */ +#endif /* SOLMRI43 */ +#else /* not PROC_68040 */ +#ifdef PROC_68360 + +typedef unsigned char Bool; /* boolean */ +typedef char S8; /* signed - 8 bits */ +typedef unsigned char U8; /* unsigned - 8 bits */ + +typedef short S16; /* signed - 16 bits */ +typedef unsigned short U16; /* unsigned - 16 bits */ + +typedef long S32; /* signed - 32 bits */ +typedef unsigned long U32; /* unsigned - 32 bits */ + +/* + void + + note: if typedef Void is set to S16 then RETVOID must be set + to: return(ROK). if typedef Void is set to void then RETVOID + must be set to: return +*/ + +typedef void Void; /* void */ + +typedef S8 (*PFS8) ARGS((void )); /* pointer to function returning S8 */ +typedef S16 (*PFS16) ARGS((void )); /* pointer to function returning S16 */ +typedef S32 (*PFS32) ARGS((void )); /* pointer to function returning S32 */ +typedef Void (*PFVOID) ARGS((void )); /* pointer to function returning Void */ +typedef INTERRPT Void (*PIF) ARGS((void )); /* pointer to interrupt function */ + +#else /* not PROC_68360 */ + +#ifdef WIN32 +typedef unsigned char Bool; /* boolean */ +typedef char S8; /* signed - 8 bits */ +typedef unsigned char U8; /* unsigned - 8 bits */ + +typedef short S16; /* signed - 16 bits */ +typedef unsigned short U16; /* unsigned - 16 bits */ + +typedef int S32; /* signed - 32 bits */ +typedef unsigned int U32; /* unsigned - 32 bits */ +/* envdep_h_001.main_76 Take care of the windows compiler non compliance + * to ANSI-C for data type ranges +*/ +typedef long long S64; /* signed - 64 bits */ +typedef unsigned long long U64; /* unsigned - 64 bits */ + +/* 1. Added F32 and F64 types */ +#ifdef SS_FLOAT +typedef float F32; /* float - 32 bits */ +typedef double F64; /* double - 64 bits */ +#endif /* SS_FLOAT */ +/* + void + + note: if typedef Void is set to S16 then RETVOID must be set + to: return(ROK). if typedef Void is set to void then RETVOID + must be set to: return +*/ + +typedef void Void; /* void */ + +typedef S8 (*PFS8) ARGS((void )); /* pointer to function returning S8 */ +typedef S16 (*PFS16) ARGS((void )); /* pointer to function returning S16 */ +typedef S32 (*PFS32) ARGS((void )); /* pointer to function returning S32 */ +typedef Void (*PFVOID) ARGS((void )); /* pointer to function returning Void */ +typedef Void (INTERRPT *PIF) ARGS((void )); /* pointer to interrupt function */ + +#else /* not WIN32 */ +#ifdef PROC_68349 +typedef unsigned char Bool; /* boolean */ +typedef char S8; /* signed - 8 bits */ +typedef unsigned char U8; /* unsigned - 8 bits */ + +typedef short S16; /* signed - 16 bits */ +typedef unsigned short U16; /* unsigned - 16 bits */ + +typedef long S32; /* signed - 32 bits */ +typedef unsigned long U32; /* unsigned - 32 bits */ + +/* + void + + note: if typedef Void is set to S16 then RETVOID must be set + to: return(ROK). if typedef Void is set to void then RETVOID + must be set to: return +*/ + +typedef void Void; /* void */ + +typedef S8 (*PFS8) ARGS((void )); /* pointer to function returning S8 */ +typedef S16 (*PFS16) ARGS((void )); /* pointer to function returning S16 */ +typedef S32 (*PFS32) ARGS((void )); /* pointer to function returning S32 */ +typedef Void (*PFVOID) ARGS((void )); /* pointer to function returning Void */ +typedef INTERRPT Void (*PIF) ARGS((void )); /* pointer to interrupt function */ + +#else /* not PROC_68349 */ + +#ifdef PROC_PPC +typedef unsigned char Bool; /* boolean */ +typedef char S8; /* signed - 8 bits */ +typedef unsigned char U8; /* unsigned - 8 bits */ + +typedef short S16; /* signed - 16 bits */ +typedef unsigned short U16; /* unsigned - 16 bits */ +#ifndef BIT_64 +typedef long S32; /* signed - 32 bits */ +typedef unsigned long U32; /* unsigned - 32 bits */ + +/* envdep_h_001.main_74 - additions */ +typedef long long S64; /* signed - 64 bits */ +typedef unsigned long long U64; /* unsigned - 64 bits */ +#else /* BIT_64 */ +typedef int S32; /* signed - 32 bits */ +typedef unsigned int U32; /* unsigned - 32 bits */ +typedef long S64; /* signed - 64 bits */ +typedef unsigned long U64; /* unsigned - 64 bits */ +#endif /* BIT_64 */ + +/* 1. Added F32 and F64 types */ +#ifdef SS_FLOAT +typedef float F32; /* float - 32 bits */ +typedef double F64; /* double - 64 bits */ +#endif /* SS_FLOAT */ +/* + void + + note: if typedef Void is set to S16 then RETVOID must be set + to: return(ROK). if typedef Void is set to void then RETVOID + must be set to: return +*/ + +typedef void Void; /* void */ + +typedef S8 (*PFS8) ARGS((void )); /* pointer to function returning S8 */ +typedef S16 (*PFS16) ARGS((void )); /* pointer to function returning S16 */ +typedef S32 (*PFS32) ARGS((void )); /* pointer to function returning S32 */ +typedef Void (*PFVOID) ARGS((void )); /* pointer to function returning Void */ +typedef INTERRPT Void (*PIF) ARGS((void )); /* pointer to interrupt function */ + +#else /* not PROC_PPC */ + +#ifdef SS_PS +typedef unsigned char Bool; /* boolean */ +typedef char S8; /* signed - 8 bits */ +typedef unsigned char U8; /* unsigned - 8 bits */ + +typedef short S16; /* signed - 16 bits */ +typedef unsigned short U16; /* unsigned - 16 bits */ + +#ifndef BIT_64 +typedef long S32; /* signed - 32 bits */ +typedef unsigned long U32; /* unsigned - 32 bits */ + +/* envdep_h_001.main_71 - additions */ +typedef int64_t S64; /* signed - 64 bits */ +typedef uint64_t U64; /* unsigned - 64 bits */ +#else /* BIT_64 */ +typedef int S32; /* signed - 32 bits */ +typedef unsigned int U32; /* unsigned - 32 bits */ +typedef long S64; /* signed - 64 bits */ +typedef unsigned long U64; /* unsigned - 64 bits */ +#endif /* BIT_64 */ + +/* + void + + note: if typedef Void is set to S16 then RETVOID must be set + to: return(ROK). if typedef Void is set to void then RETVOID + must be set to: return +*/ + +typedef void Void; /* void */ + +typedef S8 (*PFS8) ARGS((void )); /* pointer to function returning S8 */ +typedef S16 (*PFS16) ARGS((void )); /* pointer to function returning S16 */ +typedef S32 (*PFS32) ARGS((void )); /* pointer to function returning S32 */ +typedef Void (*PFVOID) ARGS((void )); /* pointer to function returning Void */ +typedef Void (INTERRPT *PIF) ARGS((void )); /* pointer to interrupt function */ + +#else /* not SS_PS */ + +typedef unsigned char Bool; /* boolean */ +typedef char S8; /* signed - 8 bits */ +typedef unsigned char U8; /* unsigned - 8 bits */ + +typedef int S16; /* signed - 16 bits */ +typedef unsigned int U16; /* unsigned - 16 bits */ + +typedef long S32; /* signed - 32 bits */ +typedef unsigned long U32; /* unsigned - 32 bits */ + +/* + void + + note: if typedef Void is set to S16 then RETVOID must be set + to: return(ROK). if typedef Void is set to void then RETVOID + must be set to: return +*/ + +typedef void Void; /* void */ + +typedef S8 (*PFS8) ARGS((void )); /* pointer to function returning S8 */ +typedef S16 (*PFS16) ARGS((void )); /* pointer to function returning S16 */ +typedef S32 (*PFS32) ARGS((void )); /* pointer to function returning S32 */ +typedef Void (*PFVOID) ARGS((void )); /* pointer to function returning Void */ +typedef Void (INTERRPT *PIF) ARGS((void )); /* pointer to interrupt function */ + +#endif /* SS_PS */ +#endif /* PROC_PPC */ +#endif /* PROC_68349 */ +#endif /* WIN32 */ +#endif /* PROC_68360 */ +#endif /* PROC_68040 */ +#endif /* PROC_68302 */ +#endif /* UNIX */ +#endif /* DOS */ + + +/* scope control keywords */ + +#ifdef PUBLIC +#undef PUBLIC +#define PUBLIC /* public is c default scope */ +#else /* not PUBLIC */ +#define PUBLIC +#endif /* PUBLIC */ + +#ifdef PRIVATE +#undef PRIVATE +#define PRIVATE static /* private is c static scope */ +#else /* not PRIVATE */ +#define PRIVATE static /* private is c static scope */ +#endif /* PRIVATE */ + +#ifdef EXTERN +#undef EXTERN +#define EXTERN extern +#else /* not EXTERN */ +#define EXTERN extern +#endif /* EXTERN */ + + +#ifdef ANSI +#define CONSTANT const /* constant */ +#else +#define CONSTANT +#endif /* ANSI */ + +#ifdef _MCC68K /* microtec 68K cross compiler */ + +#ifdef VOLATILE +#undef VOLATILE +#define VOLATILE volatile /* volatile */ +#else +#define VOLATILE volatile +#endif + +#if _STR_CMP(_VERSION,"4.4") >= 0 /* MCC68K only, check version */ +#ifdef INLINE +#undef INLINE +#define INLINE inline /* inline */ +#else /* not INLINE */ +#define INLINE inline /* inline */ +#endif /* INLINE */ +#else +#define INLINE /* no inline */ +#endif /* __STR_CMP */ +#else /* not _MCC68K */ +#ifdef __GNUC__ +#ifndef __STRICT_ANSI__ +#ifdef INLINE +#undef INLINE +#define INLINE __inline__ +#else /* not inline */ +#define INLINE __inline__ +#endif /* INLINE */ +#else /* not strict ansi */ +#ifdef INLINE +#undef INLINE +#define INLINE +#else /* not inline */ +#define INLINE +#endif /* INLINE */ +#endif /* __STRICT_ANSI */ +#ifdef VOLATILE +#undef VOLATILE +#define VOLATILE volatile /* volatile */ +#else /* volatile */ +#define VOLATILE volatile +#endif +#else /* not gnuc */ +#ifdef WIN32 +#ifdef VOLATILE +#undef VOLATILE +#define VOLATILE volatile +#else /* VOLATILE */ +#define VOLATILE volatile +#endif /* VOLATILE */ + +#ifdef INLINE +#undef INLINE +#define INLINE +#else +#define INLINE +#endif /* INLINE */ +#else /* not WIN32 */ + +#ifdef VOLATILE +#undef VOLATILE +#define VOLATILE /* volatile */ +#else +#define VOLATILE /* volatile */ +#endif /* VOLATILE */ + +#ifdef INLINE +#undef INLINE +#define INLINE +#else +#define INLINE +#endif /* INLINE */ + +#endif /* WIN32 */ +#endif /* __GNUC__ */ +#endif /* _MCC68K */ + +/*envdep_h_001.main_77 SSI-4GMX specfic changes*/ +/*envdep_h_001.main_78 : removed SSI-4GMX specfic changes*/ +#ifdef VOLATILE +#undef VOLATILE +#define VOLATILE volatile +#else +#define VOLATILE volatile +#endif + +#ifdef __cplusplus +#ifdef INLINE +#undef INLINE +#endif +#define INLINE +#endif + + +/********************************************************************** + prototypes for sprintf +**********************************************************************/ + +/*envdep_h_001.main_75 : RMIOS related changes*/ +#ifndef SS_RMIOS +#ifndef STDIO_INCLD + +#ifdef SUNOS41 +EXTERN S8 *sprintf ARGS((S8 *buffer, CONSTANT S8 *format, /* args */ ...)); +#else +#ifdef SUNOS51 +#else /* not SUNOS51 */ +#ifdef HPOS +EXTERN int sprintf ARGS((S8 *s, CONSTANT S8 *format, /* args */ ... )); +#else +#ifdef _MCC68K +EXTERN Void sprintf ARGS((S8 *outbuf, S8 *fmt, /* args */ ...)); /* td68k.x */ +#else +/* other os */ +#ifdef WIN32 +EXTERN int sprintf ARGS((S8 *buffer,CONSTANT S8 *format, /* args */ ...)); +#else +#ifdef VW +EXTERN int sprintf ARGS((S8 *buffer,CONSTANT S8 *format, /* args */ ...)); +#else +#ifdef SS_PS +EXTERN int sprintf ARGS((S8 *buffer,CONSTANT S8 *format, /* args */ ...)); +#endif /* SS_PS */ +#endif /* VW */ +#endif /* WIN32 */ +#endif /* _MCC68K */ +#endif /* HPOS */ +#endif /* SUNOS51 */ +#endif /* SUNOS41 */ +#endif /* STDIO_INCLD */ +#endif /*SS_RMIOS*/ + + +/********************************************************************** + defines for pointers, pointer sizes, stack alignment and registers +**********************************************************************/ + +/* + defines are provided for: intel 80x86 small, intel 80x86 medium, + intel 80x86 compact, intel 80x86 large, intel huge, motorola 68000, + sparc, vax and other processors. +*/ + +#ifdef I86SM /* Intel 80x86 small model */ + +#define NULLP 0 /* null pointer */ +#define NULLD 0L /* null data */ +#define PTR U16 /* pointer */ +#define PTRSIZE sizeof(U16) /* pointer size */ +#define STKALIGN 2 /* stack alignment */ + +#define REG1 register /* register 1 - highest priority */ +#define REG2 register /* register 2 */ +#define REG3 /* register 3 */ +#define REG4 /* register 4 */ +#define REG5 /* register 5 */ +#define REG6 /* register 6 */ +#define REG7 /* register 7 */ +#define REG8 /* register 8 - lowest priority */ + +#define FAR /* for small model */ +#define PTRSTRIDE 1 /* stride */ +#define MEM_SEG /* memory - segmented */ +#endif /* I86SM */ + +#ifdef I86MM /* Intel 80x86 medium model */ + +#define NULLP 0 /* null pointer */ +#define NULLD 0L /* null data */ +#define PTR U16 /* pointer */ +#define PTRSIZE sizeof(U16) /* pointer size */ +#define STKALIGN 2 /* stack alignment */ + +#define REG1 register /* register 1 - highest priority */ +#define REG2 register /* register 2 */ +#define REG3 /* register 3 */ +#define REG4 /* register 4 */ +#define REG5 /* register 5 */ +#define REG6 /* register 6 */ +#define REG7 /* register 7 */ +#define REG8 /* register 8 - lowest priority */ + +#define FAR /* for medium model */ +#define PTRSTRIDE 1 /* stride */ +#define MEM_SEG /* memory - segmented */ +#endif /* I86MM */ + +#ifdef I86CM /* Intel 80x86 compact model */ + +#define NULLP 0L /* null pointer */ +#define NULLD 0L /* null data */ +#ifndef BIT_64 +#define PTR U32 /* pointer */ +#define PTRSIZE sizeof(U32) /* pointer size */ +/* #define PTRFAR pointer far */ +#define STKALIGN 4 /* stack alignment */ +#else /* BIT_64 */ +#define PTR U64 /* pointer */ +/* envdep_h_001.main_78:Warning fix*/ +#define PTRSIZE sizeof(U64) /* pointer size */ +/* #define PTRFAR pointer far */ +#define STKALIGN 8 /* stack alignment */ +#endif /* BIT_64 */ + + +#define REG1 register /* register 1 - highest priority */ +#define REG2 register /* register 2 */ +#define REG3 /* register 3 */ +#define REG4 /* register 4 */ +#define REG5 /* register 5 */ +#define REG6 /* register 6 */ +#define REG7 /* register 7 */ +#define REG8 /* register 8 - lowest priority */ + +#define FAR far /* for compact model */ +#define PTRSTRIDE 1 /* stride */ +#define MEM_SEG /* memory - segmented */ +#endif /* I86CM */ + + +#ifdef I86LM /* Intel 80x86 large model */ + +#define NULLP 0L /* null pointer */ +#define NULLD 0L /* null data */ +#ifndef BIT_64 +#define PTR U32 /* pointer */ +#define PTRSIZE sizeof(U32) /* pointer size */ +#define PTRFAR /* pointer far */ +#define STKALIGN 4 /* stack alignment */ +#else /* BIT_64 */ +#define PTR U64 /* pointer */ +/* envdep_h_001.main_78:Warning fix*/ +#define PTRSIZE sizeof(U64) /* pointer size */ +/* #define PTRFAR pointer far */ +#define STKALIGN 8 /* stack alignment */ +#endif /* BIT_64 */ + +#define REG1 register /* register 1 - highest priority */ +#define REG2 register /* register 2 */ +#define REG3 /* register 3 */ +#define REG4 /* register 4 */ +#define REG5 /* register 5 */ +#define REG6 /* register 6 */ +#define REG7 /* register 7 */ +#define REG8 /* register 8 - lowest priority */ + +#define FAR far /* for large model */ +#define PTRSTRIDE 1 /* stride */ +#define MEM_SEG /* memory - segmented */ +#endif /* I86LM */ + +#ifdef I86HM /* Intel 80x86 huge model */ + +#define NULLP 0L /* null pointer */ +#define NULLD 0L /* null data */ +#ifndef BIT_64 +#define PTR U32 /* pointer */ +#define PTRSIZE sizeof(U32) /* pointer size */ +#define PTRFAR /* pointer far */ +#define STKALIGN 4 /* stack alignment */ +#else /* BIT_64 */ +#define PTR U64 /* pointer */ +#define PTRSIZE sizeof(U64) /* pointer size */ +#define PTRFAR /* pointer far */ +#define STKALIGN 8 /* stack alignment */ +#endif /* BIT_64 */ + +#define REG1 register /* register 1 - highest priority */ +#define REG2 register /* register 2 */ +#define REG3 /* register 3 */ +#define REG4 /* register 4 */ +#define REG5 /* register 5 */ +#define REG6 /* register 6 */ +#define REG7 /* register 7 */ +#define REG8 /* register 8 - lowest priority */ + +#define FAR far /* for huge model */ +#define PTRSTRIDE 1 /* stride */ +#define MEM_SEG /* memory - segmented */ +#endif /* I86HM */ + +#ifdef PROC_68XXX /* Motorola 68040 model */ + +#define NULLP 0L /* null pointer */ +#define NULLD 0L /* null data */ +#define PTR U32 /* pointer */ +#define PTRSIZE sizeof(U32) /* pointer size */ +/* #define PTRFAR pointer far */ +#define STKALIGN 4 /* stack alignment */ + +#define REG1 register /* register 1 - highest priority */ +#define REG2 register /* register 2 */ +#define REG3 register /* register 3 */ +#define REG4 register /* register 4 */ +#define REG5 register /* register 5 */ +#define REG6 register /* register 6 */ +#define REG7 register /* register 7 */ +#define REG8 register /* register 8 - lowest priority */ + +#define FAR /* for large model */ + +#ifdef PROC_68302 +#define PTRSTRIDE 2 /* stride (simulation case: e.g. for elvis) */ +#else +#ifdef PROC_68040 +#define PTRSTRIDE 4 /* stride (simulation case: e.g. for elvis) */ +#else /* other */ +#define PTRSTRIDE 4 /* stride (simulation case: e.g. for elvis) */ +#endif /* PROC_68040 */ +#endif /* PROC_68302 */ + +#define MEM_NONSEG /* memory - non-segmented */ +#endif /* PROC_68XXX */ + + +#ifdef PROC_SPARC /* SPARC */ + +#define NULLP 0L /* null pointer */ +#define NULLD 0L /* null data */ +#ifndef BIT_64 +#define PTR U32 /* pointer */ +#define PTRSIZE sizeof(U32) /* pointer size */ +/* #define PTRFAR pointer far */ +#define STKALIGN 4 /* stack alignment */ +#else /* BIT_64 */ +#define PTR U64 /* pointer */ +#define PTRSIZE sizeof(U64) /* pointer size */ +/* #define PTRFAR pointer far */ +#define STKALIGN 8 /* stack alignment */ +#endif /* BIT_64 */ + +#define REG1 register /* register 1 - highest priority */ +#define REG2 register /* register 2 */ +#define REG3 register /* register 3 */ +#define REG4 register /* register 4 */ +#define REG5 register /* register 5 */ +#define REG6 register /* register 6 */ +#define REG7 register /* register 7 */ +/*envdep_h_001.main_77 SSI-4GMX specfic changes*/ +#ifndef SS_4GMX_LCORE +#define REG8 register /* register 8 - lowest priority */ +#endif + +#define FAR /* for large model */ +#define PTRSTRIDE 4 /* stride */ +#define MEM_NONSEG /* memory - non-segmented */ +#endif /* PROC_SPARC */ +#ifdef PROC_PARISC /* HP PA RISC */ + +#define NULLP 0L /* null pointer */ +#define NULLD 0L /* null data */ +#ifndef BIT_64 +#define PTR U32 /* pointer */ +#define PTRSIZE sizeof(U32) /* pointer size */ +/* #define PTRFAR pointer far */ +#define STKALIGN 4 /* stack alignment */ +#else +#define PTR U64 /* pointer */ +#define PTRSIZE sizeof(U64) /* pointer size */ +/* #define PTRFAR pointer far */ +#define STKALIGN 8 /* stack alignment */ +#endif /* BIT_64 */ + +#define REG1 register /* register 1 - highest priority */ +#define REG2 register /* register 2 */ +#define REG3 register /* register 3 */ +#define REG4 register /* register 4 */ +#define REG5 register /* register 5 */ +#define REG6 register /* register 6 */ +#define REG7 register /* register 7 */ +#define REG8 register /* register 8 - lowest priority */ + +#define FAR /* for large model */ +#define PTRSTRIDE 4 /* stride */ +#define MEM_NONSEG /* memory - non-segmented */ +#endif /* PROC_PARISC */ + +/*envdep_h_001.main_75 : RMIOS related changes*/ +#ifdef SS_RMIOS +#define SPtr2l(ptr) ((unsigned long)(ptr)) +#define SPtr2ll(ptr) ((unsigned long long)(unsigned long)(ptr)) +#define SL2Ptr(l) ((PTR)(l)) +#define SLL2Ptr(ll) ((PTR)(ll & 0xFFFFFFFF)) + +#define NULLP 0L /* null pointer */ +#define NULLD 0L /* null data */ +#ifndef BIT_64 +#define PTR U32 /* pointer */ +#define PTRSIZE sizeof(U32) /* pointer size */ +#define STKALIGN 4 /* stack alignment */ +#else /* BIT_64 */ +#define PTR U64 /* pointer */ +#define PTRSIZE sizeof(U64) /* pointer size */ +#define STKALIGN 8 /* stack alignment */ +#endif /* BIT_64 */ + +#define REG1 register /* register 1 - highest priority */ +#define REG2 register /* register 2 */ +#define REG3 register /* register 3 */ +#define REG4 register /* register 4 */ +#define REG5 register /* register 5 */ +#define REG6 register /* register 6 */ +#define REG7 register /* register 7 */ +#define REG8 register /* register 8 - lowest priority */ +#endif + +#ifdef VAX /* VAX */ + +#define NULLP 0L /* null pointer */ +#define NULLD 0L /* null data */ +#define PTR U32 /* pointer */ +#define PTRSIZE sizeof(U32) /* pointer size */ +/* #define PTRFAR pointer far */ +#define STKALIGN 4 /* stack alignment */ + +#define REG1 register /* register 1 - highest priority */ +#define REG2 register /* register 2 */ +#define REG3 register /* register 3 */ +#define REG4 register /* register 4 */ +#define REG5 register /* register 5 */ +#define REG6 register /* register 6 */ +#define REG7 register /* register 7 */ +#define REG8 register /* register 8 - lowest priority */ + +#define FAR /* for large model */ +#define PTRSTRIDE 2 /* stride */ +#define MEM_NONSEG /* memory - non-segmented */ +#endif + + +#ifdef ALPHA /* ALPHA */ + +#define NULLP 0L /* null pointer */ +#define NULLD 0L /* null data */ +#define PTR U64 /* pointer */ +#define PTRSIZE sizeof(U64) /* pointer size */ +/* #define PTRFAR pointer far */ +#define STKALIGN 8 /* stack alignment */ + +#define REG1 register /* register 1 - highest priority */ +#define REG2 register /* register 2 */ +#define REG3 register /* register 3 */ +#define REG4 register /* register 4 */ +#define REG5 register /* register 5 */ +#define REG6 register /* register 6 */ +#define REG7 register /* register 7 */ +#define REG8 register /* register 8 - lowest priority */ + +#define FAR /* for large model */ +#define PTRSTRIDE 2 /* stride */ +#define MEM_NONSEG /* memory - non-segmented */ +#endif + +#ifdef PROC_68360 /* Motorola 68040 model */ + +#define NULLP 0L /* null pointer */ +#define NULLD 0L /* null data */ +#define PTR U32 /* pointer */ +#define PTRSIZE sizeof(U32) /* pointer size */ +/* #define PTRFAR pointer far */ +#define STKALIGN 4 /* stack alignment */ + +#define REG1 register /* register 1 - highest priority */ +#define REG2 register /* register 2 */ +#define REG3 register /* register 3 */ +#define REG4 register /* register 4 */ +#define REG5 register /* register 5 */ +#define REG6 register /* register 6 */ +#define REG7 register /* register 7 */ +#define REG8 register /* register 8 - lowest priority */ + +#define FAR /* for large model */ + +#define PTRSTRIDE 4 /* stride (simulation case: e.g. for elvis) */ +#define MEM_NONSEG /* memory - non-segmented */ +#endif /* PROC_68360 */ + + +#ifdef PROC_PPC /* SPARC */ + +#define NULLP 0L /* null pointer */ +#define NULLD 0L /* null data */ +#ifndef BIT_64 +#define PTR U32 /* pointer */ +#define PTRSIZE sizeof(U32) /* pointer size */ +/* #define PTRFAR pointer far */ +#define STKALIGN 4 /* stack alignment */ +#else /* BIT_64 */ +#define PTR U64 /* pointer */ +#define PTRSIZE sizeof(U64) /* pointer size */ +/* #define PTRFAR pointer far */ +#define STKALIGN 8 /* stack alignment */ +#endif /* BIT_64 */ + +#define REG1 register /* register 1 - highest priority */ +#define REG2 register /* register 2 */ +#define REG3 register /* register 3 */ +#define REG4 register /* register 4 */ +#define REG5 register /* register 5 */ +#define REG6 register /* register 6 */ +#define REG7 register /* register 7 */ +#define REG8 register /* register 8 - lowest priority */ + +#define FAR /* for large model */ +#define PTRSTRIDE 4 /* stride */ +#define MEM_NONSEG /* memory - non-segmented */ +#endif /* PROC_PPC */ + + +#ifdef SS_PS /* 32-bit pSOS */ +#define NULLP 0L /* null pointer */ +#define NULLD 0L /* null data */ +#ifndef BIT_64 +#define PTR U32 /* pointer */ +#define PTRSIZE sizeof(U32) /* pointer size */ +#define STKALIGN 4 /* stack alignment */ +#else /* BIT_64 */ +#define PTR U64 /* pointer */ +#define PTRSIZE sizeof(U64) /* pointer size */ +#define STKALIGN 8 /* stack alignment */ +#endif /* BIT_64 */ + + +#define REG1 register /* register 1 - highest priority */ +#define REG2 register /* register 2 */ +#define REG3 register /* register 3 */ +#define REG4 register /* register 4 */ +#define REG5 register /* register 5 */ +#define REG6 register /* register 6 */ +#define REG7 register /* register 7 */ +#define REG8 register /* register 8 - lowest priority */ + +#define FAR /* for large model */ +#define PTRSTRIDE 4 /* stride */ +#endif /* SS_PS */ + + +#ifdef OTHMOD /* All other models */ + +#define NULLP 0L /* null pointer */ +#define NULLD 0L /* null data */ +/* envdep_h_001.main_76 WIN32 and WIN64 falls here, so be sure PTR is correctly defined + * when compiling 64bits + */ +/*envdep_h_001.main_77 SSI-4GMX specfic changes*/ +#ifndef SS_4GMX_LCORE +#ifdef _WIN64 +#define PTR U64 /* pointer */ +#define PTRSIZE sizeof(U64) /* pointer size */ +#define STKALIGN 8 /* stack alignment */ +#else /* _WIN64 */ +#define PTR U32 /* pointer */ +#define PTRSIZE sizeof(U32) /* pointer size */ +#define STKALIGN 4 /* stack alignment */ +#endif +#else +#define PTR U32 /* pointer */ +#define PTRSIZE sizeof(U32) /* pointer size */ +#define STKALIGN 4 /* stack alignment */ +#endif + +#define REG1 register /* register 1 - highest priority */ +#define REG2 register /* register 2 */ +#define REG3 register /* register 3 */ +#define REG4 register /* register 4 */ +#define REG5 register /* register 5 */ +#define REG6 register /* register 6 */ +#define REG7 register /* register 7 */ +#define REG8 register /* register 8 - lowest priority */ + +#define FAR /* for large model */ +#define PTRSTRIDE 2 /* stride */ +#define MEM_NONSEG /* memory - non-segmented */ +#endif + + +/* pointer alignment macro */ + +#define PTRALIGN(s) ((PTR)(s) % PTRSTRIDE ? ((PTR)(s) + (PTRSTRIDE - ((PTR)(s) % PTRSTRIDE))) : (PTR)(s)) +/* + * This macro (DATAALIGN) should only be used in our + * static memory algorithms (SGetSBuf). + * + * Otherwise, use at your own risk! + */ +#define DATAALIGN(s) ((Size)(s) % PTRSTRIDE ? ((Size)(s) - (PTRSTRIDE - ((Size)(s) % PTRSTRIDE))) : (Size)(s)) + + +/* message function type macro */ + +typedef U32 MFTYPE; + + +/* typedef and defines for argument manipulation */ + +typedef S8 *ARGTYPE; + +#define ARG(argp,type) *((type*)argp) + +#define ARGINC(argp,type) argp=(ARGTYPE)(argp + (sizeof(type) < STKALIGN ? STKALIGN : sizeof(type))) + +/* Unused function parameter macro */ + +#ifdef UNUSED +#undef UNUSED +#define UNUSED(x) (x=x) +#else +#define UNUSED(x) (x=x) +#endif /* UNUSED */ + + +/********************************************************************** + defines for trace +**********************************************************************/ + +/* + trace macros are at the beginning of each function. they may + be used for debugging purposes. the trace macros are turned on + by the following command line option: + + TRACE0 - trace mos support functions + TRACE1 - trace mos interface functions + TRACE2 - trace layer support functions + TRACE3 - trace layer interface functions + TRACE4 - trace interrupt service functions + + there is one additional trace macro which turns on trace macros 0 - 4 + and pushes the text within trace macros 0 - 4 onto a stack. the text + is popped of of the stack upon RETVOID or RETVALUE. this macro is: + + TRACE5 - trace call stack + +*/ + +#ifdef TRACE5 /* trace 5 - call stack */ +#define TRACE0 /* trace 0 - mos support functions */ +#define TRACE1 /* trace 1 - mos interface functions */ +#define TRACE2 /* trace 2 - layer support functions */ +#define TRACE3 /* trace 3 - layer interface functions */ +#define TRACE4 /* trace 4 - interrupt service functions */ + +#define T5M 64 /* trace 5 - maximum call stack height */ +extern S8 *t5s[]; /* trace 5 - call stack */ +extern S16 t5t; /* trace 5 - top of call stack */ +#ifdef ERRCHK +extern Void FAR exit(int); +#endif +#endif + +#ifdef TRACE5 /* trace 5 - call stack */ +#ifdef ERRCHK +#define TRC0(a) if(t5t>=0&&t5t=0&&t5t=0&&t5t=0&&t5t=0&&t5t (y) ? (y) : (x)) /* get minimum value */ +#else +#define MIN(x, y) ((x) > (y) ? (y) : (x)) /* get minimum value */ +#endif /* MIN */ + +#ifdef MAX +#undef MAX +#define MAX(x, y) ((x) > (y) ? (x) : (y)) /* get maximum value */ +#else +#define MAX(x, y) ((x) > (y) ? (x) : (y)) /* get maximum value */ +#endif /* MAX */ +#endif /* HPOS */ + + + +/* + + The following defines are used as switches throughout the + TRILLIUM software + + PORTVER Portable version + MOSVER MOS version + + LCINT Loosely coupled - isdn network layer + TCINT Tightly coupled - isdn network layer + LCXNT Loosely coupled - x.25 network layer + TCXNT Tightly coupled - x.25 network layer + LCDAT Loosely coupled - data link layer + TCDAT Tightly coupled - data link layer + LCMAC Loosely coupled - mac layer + TCMAC Tightly coupled - mac layer + LCLM Loosely coupled - layer management + TCLM Tightly coupled - layer management + + ANSI ansi + + DOS dos environment + UNIX unix environment + + MSC51 microsoft c 5.1 compiler + MSC60 microsoft c 6.0 compiler + MSC70 microsoft c 7.0 compiler + DOSMRI42D dos microtec c 4.2D cross-compiler + SOLMRI43 solaris microtec c 4.3 cross-compiler + SOLOAS186 solaris oasys 1.8.6 cross-compiler + BOR31 borland c 3.1 compiler + + SUNOS sun os environment + SUNOS41 sun os 4.1 environment and compiler + SUNOS51 sun os 5.1 environment and compiler + + MSCDOS microsoft c, DOS environment - being phased out + MSCUNIX microsoft c, UNIX environment - being phased out + + UC2 Franklin UC2A interface + WT3 Retix WT-330 interface + FUT Dassault AT-FUT interface + MDP Dassault MOS/Driver interface + + ERRCHK Error check + + TRC0 Trace 0 - MOS support functions + TRC1 Trace 1 - MOS interface functions + TRC2 Trace 2 - layer support functions + TRC3 Trace 3 - layer interface functions + TRC4 Trace 4 - interrupt service functions + + X28X29 X.28 and X.29 support + +*/ + +#ifdef TENB_TTI_PERF +#define TTI_THRESHOLD_VALUE 800 +#endif + +#ifdef __cplusplus +} +#endif + + +#endif /* __ENVDEPH__ */ + + +/********************************************************************30** + + End of file +**********************************************************************/ diff --git a/src/cm/envind.h b/src/cm/envind.h new file mode 100755 index 000000000..97bf4d9a9 --- /dev/null +++ b/src/cm/envind.h @@ -0,0 +1,266 @@ +/******************************************************************************* +################################################################################ +# Copyright (c) [2017-2019] [Radisys] # +# # +# 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. # +################################################################################ +*******************************************************************************/ + +/********************************************************************20** + + Name: environment independent + + Type: C include file + + Desc: Environment independent defines required by the + by TRILLIUM software. The defines in this file should + not change regardless of the processor family + under which the TRILLIUM software will run. + + File: envind.h + +*********************************************************************21*/ + +#ifndef __ENVINDH__ +#define __ENVINDH__ + + +/* defines */ +/*envind_h_001.main_20*/ +#ifndef SS_RMIOS +#ifdef FALSE +#undef FALSE +#define FALSE 0 /* for booleans */ +#else +#define FALSE 0 /* for booleans */ +#endif + +#ifdef TRUE +#undef TRUE +#define TRUE 1 /* for booleans */ +#else +#define TRUE 1 /* for booleans */ +#endif /* TRUE */ +#endif + +#define NO 0 /* for booleans */ +#define YES 1 /* for booleans */ + +#define OFF 0 /* for booleans */ +#define ON 1 /* for booleans */ + +#define OK 0 /* for function returns */ +#define FAIL (-1) /* for function returns */ + +#define BASE10 10 /* Base 10 */ +#define BASE16 16 /* Base 16 */ + + +/* ASCII character set */ + +#define A_NULL 0x00 /* null */ +#define A_SOH 0x01 /* start of header */ +#define A_STX 0x02 /* start of text */ +#define A_ETX 0x03 /* end of text */ +#define A_EOT 0x04 /* end of transmission */ +#define A_ENQ 0x05 /* enquiry */ +#define A_ACK 0x06 /* acknowledge */ +#define A_BELL 0x07 /* bell */ +#define A_BS 0x08 /* backspace */ +#define A_HT 0x09 /* horizontal tab */ +#define A_LF 0x0a /* line feed */ +#define A_VT 0x0b /* vertical tab */ +#define A_FF 0x0c /* form feed */ +#define A_CR 0x0d /* carriage return */ +#define A_SO 0x0e /* SO */ +#define A_SI 0x0f /* SI */ +#define A_DLE 0x10 /* data link escape */ +#define A_DC1 0x11 /* data control 1 */ +#define A_DC2 0x12 /* data control 2 */ +#define A_DC3 0x13 /* data control 3 */ +#define A_DC4 0x14 /* data control 4 */ +#define A_NAK 0x15 /* negative acknowledge */ +#define A_SYN 0x16 /* synchronize */ +#define A_ETB 0x17 /* end of text block */ +#define A_CAN 0x18 /* cancel */ +#define A_EM 0x19 /* EM */ +#define A_SUB 0x1A /* SUB */ +#define A_ESC 0x1B /* escape */ +#define A_FS 0x1C /* FS */ +#define A_GS 0x1D /* GS */ +#define A_RS 0x1E /* RS */ +#define A_US 0x1F /* US */ +#define A_SP 0x20 /* space */ +#define A_EXCLAIM 0x21 /* ! */ +#define A_DBLQUO 0x22 /* " */ +#define A_POUND 0x23 /* # */ +#define A_DOLLAR 0x24 /* $ */ +#define A_PERCENT 0x25 /* % */ +#define A_AND 0x26 /* & */ +#define A_SNGQUO 0x27 /* ' */ +#define A_LTPARENT 0x28 /* ( */ +#define A_RTPARENT 0x29 /* ) */ +#define A_ASTERISK 0x2A /* * */ +#define A_PLUS 0x2B /* + */ +#define A_COMMA 0x2C /* , */ +#define A_HYPHEN 0x2D /* - */ +#define A_PERIOD 0x2E /* . */ +#define A_FWDSL 0x2F /* forward slash */ +#define A_0 0x30 /* 0 */ +#define A_1 0x31 /* 1 */ +#define A_2 0x32 /* 2 */ +#define A_3 0x33 /* 3 */ +#define A_4 0x34 /* 4 */ +#define A_5 0x35 /* 5 */ +#define A_6 0x36 /* 6 */ +#define A_7 0x37 /* 7 */ +#define A_8 0x38 /* 8 */ +#define A_9 0x39 /* 9 */ +#define A_COLON 0x3A /* : */ +#define A_SCOLON 0x3B /*;*/ +#define A_LT 0x3C /* < */ +#define A_EQUAL 0x3D /* = */ +#define A_GT 0x3E /* > */ +#define A_QMARK 0x3F /* ? */ +#define A_AMPER 0x40 /* @ */ +#define A_UP_A 0x41 /* A - upper case */ +#define A_UP_B 0x42 /* B - upper case */ +#define A_UP_C 0x43 /* C - upper case */ +#define A_UP_D 0x44 /* D - upper case */ +#define A_UP_E 0x45 /* E - upper case */ +#define A_UP_F 0x46 /* F - upper case */ +#define A_UP_G 0x47 /* G - upper case */ +#define A_UP_H 0x48 /* H - upper case */ +#define A_UP_I 0x49 /* I - upper case */ +#define A_UP_J 0x4A /* J - upper case */ +#define A_UP_K 0x4B /* K - upper case */ +#define A_UP_L 0x4C /* L - upper case */ +#define A_UP_M 0x4D /* M - upper case */ +#define A_UP_N 0x4E /* N - upper case */ +#define A_UP_O 0x4F /* O - upper case */ +#define A_UP_P 0x50 /* P - upper case */ +#define A_UP_Q 0x51 /* Q - upper case */ +#define A_UP_R 0x52 /* R - upper case */ +#define A_UP_S 0x53 /* S - upper case */ +#define A_UP_T 0x54 /* T - upper case */ +#define A_UP_U 0x55 /* U - upper case */ +#define A_UP_V 0x56 /* V - upper case */ +#define A_UP_W 0x57 /* W - upper case */ +#define A_UP_X 0x58 /* X - upper case */ +#define A_UP_Y 0x59 /* Y - upper case */ +#define A_UP_Z 0x5A /* Z - upper case */ +#define A_BKSL 0x5C /* backslash */ +#define A_LW_A 0x61 /* a - lower case */ +#define A_LW_B 0x62 /* b - lower case */ +#define A_LW_C 0x63 /* c - lower case */ +#define A_LW_D 0x64 /* d - lower case */ +#define A_LW_E 0x65 /* e - lower case */ +#define A_LW_F 0x66 /* f - lower case */ +#define A_LW_G 0x67 /* g - lower case */ +#define A_LW_H 0x68 /* h - lower case */ +#define A_LW_I 0x69 /* i - lower case */ +#define A_LW_J 0x6A /* j - lower case */ +#define A_LW_K 0x6B /* k - lower case */ +#define A_LW_L 0x6C /* l - lower case */ +#define A_LW_M 0x6D /* m - lower case */ +#define A_LW_N 0x6E /* n - lower case */ +#define A_LW_O 0x6F /* o - lower case */ +#define A_LW_P 0x70 /* p - lower case */ +#define A_LW_Q 0x71 /* q - lower case */ +#define A_LW_R 0x72 /* r - lower case */ +#define A_LW_S 0x73 /* s - lower case */ +#define A_LW_T 0x74 /* t - lower case */ +#define A_LW_U 0x75 /* u - lower case */ +#define A_LW_V 0x76 /* v - lower case */ +#define A_LW_W 0x77 /* w - lower case */ +#define A_LW_X 0x78 /* x - lower case */ +#define A_LW_Y 0x79 /* y - lower case */ +#define A_LW_Z 0x7A /* z - lower case */ +#define A_DEL 0x7F /* delete */ +#define A_INVCHR 0xFF /* invalid */ + +#define IA5MAX 128 /* maximum number of ASCII characters */ + + +/* general macros */ + +/* Moved macros MIN and MAX to envdep.h */ + +#ifdef ABS +#undef ABS +#define ABS(x) ((x) < 0 ? -(x) : x) /* absolute value */ +#else +#define ABS(x) ((x) < 0 ? -(x) : x) /* absolute value */ +#endif /* ABS */ + +/* RG: changed the order of parentheses to make the casts more accurate */ + +#define GetHiByte(w) (((U16)(w) >> 8) & 0xff) /* get hi byte from word */ +#define GetLoByte(w) ((U16)(w) & 0xff) /* get lo byte from word */ +#define GetHiWord(l) (((U32)(l) >> 16) & 0xffffL) /* get hi word of long */ +#define GetLoWord(l) ((U32)(l) & 0xffffL) /* get lo word of long */ + +/* envind_h_001_102: add 64 bit support */ +#if (defined(ALPHA) || defined(BIT_64)) +#define GetLo32Bit(l) ((U64)(l) & 0xffffffffL) /*get lo 32 bits */ +#define GetHi32Bit(l) (((U64)(l) >> 32) & 0xffffffffL) /*get hi 32 bits */ +#endif + +/* RG: changed put macros so the target does not have to be cleared before use */ + +#define PutHiByte(w,b) (U16) (((U16)(b) << 8) | ((U16)(w) & 0x00ff)) /* put hi byte to word */ +#define PutLoByte(w,b) (U16) (((U16)(b) & 0xff) | ((U16)(w) & 0xff00)) /* put lo byte to word */ +#define PutHiWord(l,w) (U32) (((U32)(w) << 16) | ((U32)(l) & (U32)0x0000ffff)) /* put hi word to long */ +#define PutLoWord(l,w) (U32) (((U32)(w) & 0xffff) | ((U32)(l) & (U32)0xffff0000)) /* put lo word to long */ + +/* envind_h_001_102: add 64 bit support */ +#if (defined(ALPHA) || defined(BIT_64)) +#define PutLo32Bit(l,w) (U64) (((U64)(w) & 0xffffffff) | ((U64)(l) & (U64)0xffffffff00000000)) /* put lo 32 bits */ +#define PutHi32Bit(l,w) (U64) (((U64)(w) << 32) | ((U64)(l) & (U64)0x00000000ffffffff)) /* put hi 32 bits */ +#endif + +#define Char(c) ((c) & 0x7f) /* truncate to 7 bits */ +#define Byte(c) ((c) & 0xff) /* truncate to 8 bits */ +#define Word(c) ((c) & 0xffffL) /* truncate to 16 bits */ + +#define IsOdd(c) (((c % 2) == 1) ? TRUE:FALSE) +#define IsEven(c) (((c % 2) == 0) ? TRUE:FALSE) + +#define StripPar(c) ((c) & 0x7f) + + +/* ASCII character set macros */ + +#define AIsUpper(c) ((c>=A_UP_A) && (c<=A_UP_Z)) +#define AIsLower(c) ((c>=A_LW_A) && (c<=A_LW_Z)) +#define AIsAlpha(c) (AIsUpper(c) || AIsLower(c)) +#define AIsDigit(c) ((c>=A_0) && (c<=A_9)) +#define AIsSpace(c) ((c==A_SP) || (c==A_HT) || (c==A_LF)) +#define AIsWhite(c) ((c==A_SP) || (c==A_HT) || (c==A_LF)) +#define AToUpper(c) (AIsLower(c) ? (c+A_UP_A-A_LW_A):(c)) +#define AToLower(c) (AIsUpper(c) ? (c+A_LW_A-A_UP_A):(c)) + +#define AIsAscii(c) ((c>=A_SP) && (c=A_UP_A) && (c<=A_UP_F)) +#define AIsXlower(c) ((c>=A_LW_A) && (c<=A_LW_F)) +#define AIsXdigit(c) (AIsDigit(c) || AIsXupper(c) || AIsXlower(c)) +#define AIsCntrl(c) (((c>=A_NULL) && (cS1AP) flags */ +#define SZTV1 +#define SZTV2 +#define SZTV3 + +/* CZT interface (App<->X2AP) flags */ +#define CZTV1 + +/* LSZ interface (SM<->S1AP) flags */ +#define LSZV1 + +/* LEG interface (SM<->EGTP) flags */ +#define LEGV2 + +/* CTF interface (App<->CL) flags */ +#define CTF_VER3 +#undef CTF_V3 + +/* CPJ interface (RRC<->PDCP) flags */ +#define CPJ_V2 + +/* TFU interface flags */ +#ifdef LTE_TDD +#define TFU_TDD +#else +#undef TFU_TDD +#endif + +#define TFU_UPGRADE 1 +#define TFU_VER_2 + +/* RGR interface (APP<->SCH) flags */ +#define RGR_V1 +#define RGR_V2 +#define RGR_CQI_REPT +#define RGR_SI_SCH +#define RGR_RRM_TICK + +/* RRM related interface flags */ +#define RM_INTF + +/* LSB interface flags */ +#define LSB4 +#define LSB8 +#define SB_CHECKSUM /* Define to include trillium supplied function */ +#define SB_CHECKSUM_CRC + +/************************************************************************** + Layer manager interface version definition +**************************************************************************/ +#define LMINT3 /* interface 3 */ + +#ifdef SS /* Common System Services */ +/************************************************************************** + Common System Services parameters +**************************************************************************/ +/* product specific options */ +#define SS_RTR_SUPPORT /* for supporting router tasks */ + +#ifdef SS_DRVR_SUPPORT +/* for backward compatibility */ +#define ENB_RELAY +/* for forward compatibility */ +#define RYINT1 +#endif /* SS_DRVR_SUPPORT */ + +/* post format, choose none or one */ +#define FCSPOSTINT /* forward compatibility, post format */ + +#endif /* SS */ + +/************************************************************************** + MTSS-Solaris parameters +**************************************************************************/ +#ifdef SS_MT /* MTSS-Solaris */ +#ifndef CONAVL +#define CONAVL /* console availability option */ +#endif +#define STDIO_INCLD +#endif +/******************************************************************/ +/* SCTP Layer */ +/******************************************************************/ +#ifdef SB + +/* List of other layers interacting with SCTP and in the same binary */ +#ifndef SM +#define SM +#endif + +#ifndef SZ +#define SZ +#endif + +#ifndef CZ +#define CZ +#endif + +#ifndef HI +#define HI +#endif + +/* Coupling with other layers */ +#define LCSBUISCT +#define LCSBLIHIT +#define LCSBMILSB + +/* new TUCL layer */ +#ifndef HI_REL_1_4 +#define HI_REL_1_4 +#endif + +#ifdef IPV6_SUPPORTED +#define SB_IPV6_SUPPORTED +#endif + +/* Checksum */ +/* needed dependencies */ +#ifdef LCSBUISCT +#ifndef LCSCT +#define LCSCT 1 +#endif +#endif + +#ifdef LCSBMILSB +#ifndef LCLSB +#define LCLSB 1 +#endif +#endif + +#ifdef LCSBLIHIT +#ifndef LCHIT +#define LCHIT 1 +#endif +#endif + +/*----- SCTP have dependencies in LSB and SCT ------*/ +#ifdef LCLSB +#ifndef LCSCT +#define LCSCT +#endif +#endif + +/*----- SCTP have dependencies in LSB and SCT ------*/ +#ifdef LCSCT +#ifndef LCLSB +#define LCLSB +#endif +#endif + +#endif /* SB */ + +/************************************************************************** + S1AP Section +**************************************************************************/ +#ifdef SZ +#undef SZ +#define SZ 1 + +/* Define the layers that coexist with S1AP. */ +#ifndef SB +#define SB +#endif + +#ifndef UZ +#define UZ +#endif + +#ifndef SM +#define SM +#endif + +/* product options */ +#define SZ_ENB +#define CM_PASN_CRIT_HANDL +#undef M_PASN_DBG +#undef S1AP_REL851 +#define SZ_DYNAMIC_PEER +#define SZ_USTA + +/* interface options */ +#define LCSZUISZT /* loosely coupled, SZ upper layer SZT interface */ +#define LCSZMILSZ /* loosely coupled, SZ manegement LSZ interface */ +#define LCSZLISCT /* loosely coupled, SZ lower layer SCT interface */ + +/* Based on the selection of coupling above the section below */ +/* defines enabling/disabling of loose coupling on the */ +/* respective interfaces */ +/* ****** THIS SECTION REQUIRES NO FURTHER CHANGES. ********** */ +/* Interface between S1AP and Application */ +#ifdef LCSZUISZT +#ifndef LCSZT +#define LCSZT 1 +#endif +#endif + +/* Interface between S1AP and management (SM) */ +#ifdef LCSZMILSZ +#ifndef LCLSZ +#define LCLSZ 1 +#endif +#endif + +/* Interface between S1AP and Application */ +#ifdef LWLCSZUISZT +#ifndef LWLCSZT +#define LWLCSZT +#endif +#endif + +/* Interface between SCTP and S1AP */ +#ifdef LCSZLISCT +#ifndef LCSCT +#define LCSCT +#endif +#endif + +#endif /* SZ */ + +/******************************************************************/ +/* EGTP Layer */ +/******************************************************************/ +#ifdef EG + +/* Product flags */ +#define EGTP_U 1 /* LTE Evolved GTP User Plane Protocol */ + + +/* All the layers that this layer interacts with and are part of */ +/* the binary are to be included here. */ +#ifndef EU +#define EU +#endif + +#ifndef HI +#define HI +#endif + +#ifndef SM +#define SM +#endif + +#ifdef IPV6_SUPPORTED +#define EG_IPV6_SUPPORTED +#endif + +/* EGTP does not use loose coupling towards higher layers and does */ +/* not talk to TUCL on HIT in the latest TeNB. However if it were */ +/* to use TUCL, it would be loosely coupled as TUCL is multi- */ +/* threaded. */ +/* TODO - LCEGUIEGT should not be needed. */ +#define LCSMEGMILEG +#define LCEGLIHIT +#define LCEGUIEGT +#define LCEGMILEG + +/* Managing the loose coupling definitions on the interface based */ +/* how the interface is coupled from E-GTP layer. */ +/* ****** THIS SECTION REQUIRES NO FURTHER CHANGES. ********** */ +#if defined(LCEGMILEG) +#ifndef LCLEG +#define LCLEG 1 +#endif +#endif + +#if defined(LCEGLIHIT) +#ifndef LCHIT +#define LCHIT 1 +#endif +#endif + +#ifdef LCEGUIEGT +#ifndef LCEGT +#define LCEGT +#endif +#endif +#endif /* EG */ + +/*************************************************************************/ +/* LTE-RRC Section */ +/*************************************************************************/ +#ifdef NH +#undef NH +#define NH 1 + +/* Define other layers that are part of the same binary */ +/* Along with RRC, we have application(NX,WR) and stack */ +/* manager (SM). */ +#ifndef SM +#define SM +#endif + +/* TODO - We need either WR or NX and not necessarily */ +/* both of them. See if we can remove one of it. */ +#ifndef NX +#define NX +#endif + +#ifndef WR +#define WR +#endif + + +/* RRC layer functionality flags */ +#define DISABLE_RRCSEC + +/* Interface coupling related flags */ +/* TODO - LCNHUINHU should not be needed. */ +/* TODO - LCWRLINHU should not be needed. */ +#define LWLCNHUINHU +#define LCNHUINHU +#define LCNHLICPJ +#define LCNHLIPJU +#define LCNHLICKW +#define LCNHLIKWU +#define LCNHLICTF +#define LCNHMILNH +#define LCWRLINHU + +/* CRG interface between MAC and RRC should be loosely coupled */ +#define LCNHLICRG + +/* Loose coupled NHU */ +#ifdef LCNHUINHU +#ifndef LCNHU +#define LCNHU 1 +#endif +#endif + +/* Light weight loose coupled NHU */ +#ifdef LWLCNHUINHU +#ifndef LWLCNHU +#define LWLCNHU 1 +#endif +#endif + +/* Loosely coupled CPJ */ +#ifdef LCNHLICPJ +#ifndef LCCPJ +#define LCCPJ 1 +#endif +#endif + +/* Loosely coupled PJU */ +#ifdef LCNHLIPJU +#ifndef LCPJU +#define LCPJU 1 +#endif +#endif + +/* Loosely coupled CRG */ +#ifdef LCNHLICRG +#ifndef LCCRG +#define LCCRG 1 /* loosely coupled CRG interface */ +#endif +#endif + +/* Loosely coupled CTF */ +#ifdef LCNHLICTF +#ifndef LCCTF +#define LCCTF 1 /* loosely coupled CTF interface */ +#endif /* LCCTF */ +#endif /* LCNHLICTF */ + +#ifdef LCNHLICKW +#ifndef LCCKW +#define LCCKW 1 /* loosely coupled CKW interface */ +#endif +#endif +#define LCNHLIKWU +#ifdef LCNHLIKWU +#ifndef LCKWU +#define LCKWU 1 /* loosely coupled KWU interface */ +#endif +#endif + +/* TODO These flags should move to SM definitions */ +#define LCSMNHMILNH + +/* Define flags related to loosely coupled LNH interface */ +#ifdef LCNHMILNH +#ifndef LCLNH +#define LCLNH 1 +#endif +#endif + +/* Release 9 related flags */ +#ifdef LTERRC_REL9 +#define S1AP_REL9A6 +#ifndef LNH_VER1 +#define LNH_VER1 +#endif +#ifndef NHU_VER1 +#define NHU_VER1 +#endif +#endif /* LTERRC_REL9 */ + +#ifdef RRC_PHY_CFG_SUPP +#define CTF_VER1 +#endif + +#define RNC_INTEG_CCPU + +#endif /* NH */ + +/**************************************************************************** + CL section +****************************************************************************/ +#if (defined(TF) || defined(YS)) + +/* Self entity definitions */ +#ifndef TF +#define TF +#endif + +#ifndef YS +#define YS +#endif + + +/* Other entity definitions */ +#ifndef RG +#define RG +#endif + +/* Selection of interface coupling flags */ +#define LCTFUITFU +#define LCTFUICTF +#define LCYSUICTF +#define LCYSUITFU +#define LCYSMILYS + +#if defined(MODE) && (MODE == TDD) +#define TFU_TDD +#else +#undef TFU_TDD +#endif + +/* The handling of enabling LC based on coupling enabled */ +/* between CL and other layers. */ +/* ****** THIS SECTION REQUIRES NO FURTHER CHANGES. ********** */ +#ifdef LCTFUITFU +#ifndef LCTFU +#define LCTFU +#endif +#endif + +#ifdef LCTFUICTF +#ifndef LCCTF +#define LCCTF +#endif +#endif + +#ifdef LCYSUICTF +#ifndef LCCTF +#define LCCTF +#endif +#endif + +#ifdef LCYSMILYS +#ifndef LCLYS +#define LCLYS +#endif +#endif + +#define TFU_WRR_2 +#endif /* YS/TF */ + +/**************************************************************************** + LTE-MAC Section +****************************************************************************/ +#ifdef RG +#undef RG +#define RG 1 + +/* Product options */ +#define RG_PHASE2_SCHED 1 +#undef RG_DEBUG +#undef TTI_PROC +#undef PROC_DL +#undef SCH_TTI_PROC +#undef TOM +#undef PAL_MAC_PROC +#undef UL_PROC_MAC +#define LTEMAC_RGU_PAD 1 +#define LTEMAC_MIMO 1 +#define LTEMAC_DRX 0 +#define UL_LA 1 +#undef DL_LA +#define LTEMAC_SPS 0 +#define LTEMAC_DLUE_TMGOPTMZ +#define RG_DL_DELTA_CHANGE +#define RG_CMNCH_SCHDELTA_CHANGE +#undef RG_ULSCHED_AT_CRC +#define TFU_RECPREQ_DELTA_CHANGE +#define TFU_DL_DELTA_CHANGE +#define TFU_UL_DELTA_CHANGE +#define TFU_DLHQFBK_DELTA_CHANGE +#define SCH_STATS + +/* Define all the layers that are colocated with the MAC layer */ +/* RRC is located on a different binary on a different CPU. RRC */ +/* should not be included here. SM should also not be defined */ +/* as it is also located on a different CPU. */ +#ifndef UR +#define UR +#endif + +#ifndef KW +#define KW +#endif + + +/* This section selects the coupling for each interface related to */ +/* MAC. The section below enabling the coupling code appropriately. */ +/* CCPU_OPT flag enables additional information between MAC and RLC */ +/* that aids in better selection of transport block size. */ +/* TODO - We should delete LWLC for RGM interface. */ +#define LCRGUICRG +#define LCRGUIRGU +#define LWLCRGUIRGU +#define LCRGMILRG +#define LCRGUIRGR +#define LCRGLITFU +#define LCRGUIRGM +#define LWLCRGUIRGM + +/* Managing the loose coupling definitions on the interface based */ +/* how the interface is coupled from MAC layer. */ +/* ****** THIS SECTION REQUIRES NO FURTHER CHANGES. ********** */ +#ifdef LCRGUICRG +#ifndef LCCRG +#define LCCRG +#endif +#endif + +#ifdef LCRGUIRGU +#ifndef LCRGU +#define LCRGU +#endif +#endif + +#ifdef LCRGMILRG +#ifndef LCLRG +#define LCLRG +#endif +#endif + +#ifdef LCRGUIRGR +#ifndef LCRGR +#define LCRGR +#endif +#endif + +#ifdef LCRGLITFU +#ifndef LCTFU +#define LCTFU +#endif +#endif + +#ifdef LCRGUIRGM +#ifndef RGM_LC +#define RGM_LC +#endif +#endif + +#ifdef LWLCRGUIRGM +#ifndef RGM_LWLC +#define RGM_LWLC +#endif +#endif +/******************* section to be changed by CUSTOMERS ******************/ + +#define RG_SC1 1 +/* + * Introduced timing deltas in FDD for DL control, DL data, + * Reception Request, CRC Indication, HARQ feedback Indication. + */ +#ifdef LTEMAC_DLUE_TMGOPTMZ +/* Delta used between MAC and RLC to recieve data from RLC*/ +#define RGU_DELTA 0 +#else +#define RGU_DELTA 1 +#endif + +#if defined(DLHQ_RTT_OPT) && defined(LOWLATENCY) +#define TFU_DELTA 2 +#else +#define TFU_DELTA 2 +#endif +#define TFU_RECPREQ_DLDELTA 2 + +#ifdef LTE_TDD +#define RG_ENV_DL_DELTA (TFU_DELTA + RGU_DELTA) + +#define TFU_DLDATA_DLDELTA (TFU_DELTA) +#define TFU_CRCIND_ULDELTA 2 +#define TFU_ULCNTRL_DELTA (4 - TFU_CRCIND_ULDELTA) + +#ifdef MSPD +/* Number of subframes in advance UL control (DCI-0/PHICH) should be sent from SCH */ +#define TFU_ULCNTRL_DLDELTA 2 +#else +#define TFU_ULCNTRL_DLDELTA 1 +#endif + +#ifdef DLHQ_RTT_OPT +/* Number of subframes later DL HARQ feedback reaches MAC from PHY */ +#define TFU_ENV_HQFBKIND_ULDELTA 2 +#else +#define TFU_ENV_HQFBKIND_ULDELTA 3 +#endif + +/* Number of subframes in Advance the Downlink control is + given from MAC to PHY */ +#define TFU_DLCNTRL_DLDELTA TFU_DELTA + +#else /* LTE_TDD */ +/* Number of subframes in advance UL control (DCI/PHICH) should be sent from SCH */ +#define TFU_ULCNTRL_DLDELTA (RG_SCH_CMN_HARQ_INTERVAL - TFU_CRCIND_ULDELTA) + +#ifdef LTEPHY_MSPD + +/* Number of subframes for UL CRC to reach SCH after reception of data at PHY */ +#define TFU_CRCIND_ULDELTA 2 + +#else /* LTEPHY_MSPD */ + +/* Number of subframes in advance DL control should be sent from SCH */ +#define TFU_DLCNTRL_DLDELTA 2 +/* Number of subframes in advance DL data should be sent from MAC */ +#define TFU_DLDATA_DLDELTA 2 + +/* Number of subframes for UL CRC to reach SCH after reception of data at PHY */ +#define TFU_CRCIND_ULDELTA 2 +/* Number of subframes later DL HARQ feedback reaches SCH from PHY */ +#define TFU_ENV_HQFBKIND_ULDELTA 2 + +#endif /* LTEPHY_MSPD */ +/* The number of frames ahead that RLC may require a STA IND */ +/* Seperated DL control and DL data timing deltas in FDD */ +#if (TFU_DLDATA_DLDELTA > TFU_DLCNTRL_DLDELTA) +#define RG_ENV_DL_DELTA (TFU_DLDATA_DLDELTA + RGU_DELTA) +#else +#define RG_ENV_DL_DELTA (TFU_DLCNTRL_DLDELTA + RGU_DELTA) +#endif + +#endif /* LTE_TDD */ + +/* Delta between Random Access Response and Msg-3*/ +#define RGSCH_RARSP_MSG3_DELTA 6 + +/* PUSCH data reception delta after the PDCCH for uplink(DCI-0) is sent*/ +#define RGSCH_PDCCH_PUSCH_DELTA 4 + +#ifdef LTEMAC_HDFDD +#define RG_SCH_HDFDD_DELTA 10 +#endif +#define RG_ENV_SCH_CMN_DL_DELTA RG_ENV_DL_DELTA /* This parameter should not be less than RG_ENV_DL_DELTA */ + +#define RG_SCH_NO_DELTA 0 /*Consider no delta */ +/* ccpu00117459 - ADD - Added check if incompatible falgs are enabled*/ +/* HDFDD and TDD cannot be enabled at the same time. */ +#if defined(LTEMAC_HDFDD) && (defined(LTE_TDD) || defined(TFU_TDD)) +#error "Enabling LTEMAC_HDFDD along with LTE_TDD or TFU_TDD is not a valid combination." +#endif + +/* LTE_TDD and TFU_TDD must be enabled for TDD mode */ +#if (defined(LTE_TDD) && (!defined(TFU_TDD))) || (defined(TFU_TDD) && (!defined(LTE_TDD))) +#error "Both LTE_TDD and TFU_TDD must be enabled for TDD mode of operation." +#endif +#endif /* RG */ + +/**************************************************************************** + LTE-RLC Section +****************************************************************************/ +#ifdef KW + +/* Only PDCP and MAC are in the same binary. RRC runs on a different */ +/* CPU and should not be defined here. */ +#ifndef RG +#define RG +#endif + +#ifndef PJ +#define PJ +#endif + +/* -------- LKW Interface ------*/ +/* This is the interface between RLC and the stack manager */ +/* This should support loosely coupling as they dont run */ +/* in the same thread */ +#define LCKWMILKW + +/* -------- CKW Interface ------*/ +/* CKW interface is loosely coupled as RRC and RLC reside */ +/* on two different CPUs running in different threads */ +#define LCKWUICKW + +/* -------- KWU Interface ------*/ +/* KWU interface exists between RRC/PDCP and RLC. Since RRC is */ +/* is loosely coupled with RLC, loosely coupled interface is */ +/* enabled. */ +/* CCPU_OPT carries additional information on the interface to */ +/* assit better scheduling at MAC */ +#define LCKWUIKWU + +/* RGU interface between RLC and MAC should be light weight */ +/* loosely coupled for performance. */ +/* TODO - Do we also need loose coupled interface */ +#define LWLCKWLIRGU +#define LCKWLIRGU +#define CCPU_OPT + +/* The management of enabling of loose coupling code based */ +/* on the selection of coupling choice between RLC and other */ +/* modules is below. */ + +/* Other RLC product flags */ +#undef RLC_STATUS_GEN +#undef UL_PROC_MAC + +/* ****** THIS SECTION REQUIRES NO FURTHER CHANGES. ********** */ +#ifdef LCKWUICKW +#ifndef LCCKW +#define LCCKW +#endif +#endif + +#ifdef LCKWMILKW +#ifndef LCLKW +#define LCLKW +#endif +#endif + +#ifdef LCKWUIKWU +#ifndef LCKWU +#define LCKWU +#endif +#endif + +#endif /* KW */ + +/**************************************************************************** + LTE-PDCP Section +****************************************************************************/ +#ifdef PJ + +#ifndef PX +#define PX +#endif + +#define LCPJMILPJ +#define LCPJUICPJ +#define LCPJUIPJU + +/* Other PDCP product flags */ +#define LTE_HENB +#undef CIPH_BATCH_PROC + +/* The handling of enabling LC based on whether PDCP enabled */ +/* loose coupling when PDCP is acting as the source. */ +/* ****** THIS SECTION REQUIRES NO FURTHER CHANGES. ********** */ +#ifdef LCPJMILPJ +#ifndef LCLPJ +#define LCLPJ +#endif +#endif + +#ifdef LCPJUICPJ +#ifndef LCCPJ +#define LCCPJ +#endif +#endif + +#ifdef LCKWUIKWU +#ifndef LCKWU +#define LCKWU +#endif +#endif + +#ifdef LCPJUIPJU +#ifndef LCPJU +#define LCPJU +#endif +#endif + +#undef SPACC_NONBLOCKING +#undef INTEL_NATIVE_SPACC +#undef INTEL_SPACC_IV_OPTIMIZATION +#undef SPACC_THREADED +#endif /* PJ */ + +/**************************************************************************** + TOTALeNodeB Application section +****************************************************************************/ +#ifdef WR + +/* Since application is many different layers to the lower layers */ +/* it must define multiple entities as self entities. */ +#ifndef EU +#define EU +#endif + +#ifndef EG +#define EG +#endif + +/* RRC user */ +#ifndef NX +#define NX +#endif + +/* S1AP user */ +#ifndef UZ +#define UZ +#endif + +/* X2AP user */ +#ifndef RS +#define RS +#endif + +/* Include all the layers that are part of the same binary. */ +/* We have stack manager (SM), S1AP (SZ), X2AP (CZ), RRM (RM), */ +/* RRC(NH) within the same binary. */ +#ifndef SM +#define SM +#endif + +#ifndef SZ +#define SZ +#endif + +#ifndef CZ +#define CZ +#endif + +#ifndef NH +#define NH +#endif + +#ifndef RM +#define RM +#endif + +#ifndef PX +#define PX +#endif + +/* Coupling choices between application and other layers */ +/* TODO - LWLCWRLIRGR should not be needed. */ +/* TODO - LCEULIEGT should not be needed. */ +/* TODO - LCNXLINHU should not be needed. */ +#define LCWRMILWR +#define LWLCWRMILWR +#define LCWRLIEGT +#define LCPXLIPJU +#define LCWRLICTF +#define LWLCNXLINHU +#define LCUZLISZT +#define LWLCUZLISZT +#define LCWRLIRGR +#define LWLCWRLIRGR +#define LCEULIEGT +#define LCNXLINHU +#define LCRSLICZT +#define LWLCRSLICZT +#define LCSZUISZT + +/* Coupling choices between stack manager and the layers */ +/* TODO LCSMSBMILSB should be replaced with LCSMMILSB. */ +/* TODO LCSMHIMILHI should be replaced with LCSMMILHI. */ +#define LCSMMILEG +#define LCSMMILCZ +#define LCSMMILSZ +#define LCSMSBMILSB +#define LCSMMILHI +#define LCSMHIMILHI + +/* TODO LCKWMILKW should be changed to LCSMMILKW in SMM */ +/* LCKWMILKW should be used only in RLC product */ +#define LCSMMILRG +#define LCSMMILNH +#define LCSMNHMILNH +#define LCKWMILKW +#define LCSMMILPJ +#define LCSMMILRM +#define LCSMMILYS +#define LWLCSMMILWR +#define LCSMMILWR +#define LWLCSMMILWR +#define LCSMYSMILYS +#define LCYSMILYS + +/* Application functionality related flags */ +#define SI_NEW +#define LTE_HO_SUPPORT +#define WR_SIBS_ENBLD +#undef WR_DETECT_RLF +#define WR_DL_CQI +#define WR_RSYS_KPI +#define WR_WATCHDOG +#define WR_IPV6_OAM_WORKAROUND + +#undef WR_GRPPWR_CNTRL +/* #undef ENB_OVRLOAD */ +/* The handling of enabling LC based on whether TeNB enabled */ +/* loose coupling when PDCP is acting as the source. */ +/* ****** THIS SECTION REQUIRES NO FURTHER CHANGES. ********** */ +#ifdef LCWRMILWR +#ifndef LCLWR +#define LCLWR +#endif +#endif + +#ifdef LCWRLINHU +#ifndef LCNHU +#define LCNHU +#endif +#endif + +#ifdef LCSZUISZT +#ifndef LCSZT +#define LCSZT +#endif +#endif +#ifdef LCNXLINHU +#ifndef LCNHU +#define LCNHU +#endif +#endif + +#ifdef LWLCNXLINHU +#ifndef LWLCNHU +#define LWLCNHU +#endif +#endif + +#ifdef LCWRLIEGT +#ifndef LCEGT +#define LCEGT +#endif +#endif + +#ifdef LCPXLIPJU +#ifndef LCPJU +#define LCPJU +#endif +#endif + + +#ifdef LCWRLICTF +#ifndef LCCTF +#define LCCTF +#endif +#endif + +#ifdef LCWRLIRGR +#ifndef LCRGR +#define LCRGR +#endif +#endif + +#ifdef LCRSLICZT +#ifndef LCCZT +#define LCCZT +#endif +#endif + +#ifdef LWLCRSLICZT +#ifndef LWLCCZT +#define LWLCCZT +#endif +#endif + +/* ************* SM and layer interaction flags **************** */ +#ifdef LCSMMILWR +#ifndef LCLWR +#define LCLWR +#endif +#endif + +#ifdef LWLCSMMILWR +#ifndef LWLCLWR +#define LWLCLWR +#endif +#endif + +#ifdef LCSMMILRG +#ifndef LCLRG +#define LCLRG +#endif +#endif + +#ifdef LCSMMILEG +#ifndef LCLEG +#define LCLEG +#endif +#endif + +#ifdef LCSMMILNH +#ifndef LCLNH +#define LCLNH +#endif +#endif + +#ifdef LWLCSMMILWR +#ifndef LWLCLWR +#define LWLCLWR +#endif +#endif + +#ifdef LCSMMILPJ +#ifndef LCLPJ +#define LCLPJ +#endif +#endif + +#ifdef LCKWMILKW +#ifndef LCLKW +#define LCLKW +#endif +#endif + +#ifdef LCSMYSMILYS +#ifndef LCLYS +#define LCLYS +#endif +#endif + +#ifdef LCYSMILYS +#ifndef LCLYS +#define LCLYS +#endif +#endif + +/* TODO - This definition does not follow naming conventions and */ +/* also is a duplicate of the above macro. This should be removed */ +/* from the code and then from this make file. */ +#ifdef LCSMNHMILNH +#ifndef LCLNH +#define LCLNH +#endif +#endif + +#endif /* WR */ +/* ************** End of TeNB Application section *************** */ + +/**************************************************************************** + X2AP section +****************************************************************************/ +#ifdef CZ +#undef CZ +#define CZ 1 + +/* Define the layers that coexist with X2AP. They are SCTP (SB), */ +/* X2AP user (RS/WR), stack manager (SM). */ +#ifndef SB +#define SB +#endif + +#ifndef RS +#define RS +#endif + +#ifndef SM +#define SM +#endif + +/* product options */ +#define CZ_ENB +#define CZ_DYNAMIC_PEER +#define CZ_USTA + +/* interface options */ +#define LCCZUICZT /* loosely coupled, CZ upper layer CZT interface */ +#define LCCZLISCT /* loosely coupled, CZ lower layer SCT interface */ +#define LCCZMILCZ /* loosely coupled, CZ manegement LCZ interface */ + +/* Based on the selection of coupling above the section below */ +/* defines enabling/disabling of loose coupling on the */ +/* respective interfaces */ +/* ****** THIS SECTION REQUIRES NO FURTHER CHANGES. ********** */ +/* Interface between S1AP and Application */ +#ifdef LCCZUICZT +#ifndef LCCZT +#define LCCZT 1 +#endif +#endif + +/* Interface between X2AP and management (SM) */ +#ifdef LCCZMILCZ +#ifndef LCLCZ +#define LCLCZ 1 +#endif +#endif + +/* Interface between X2AP and Application */ +#ifdef LWLCCZUICZT +#ifndef LWLCCZT +#define LWLCCZT +#endif +#endif + +/* Interface between SCTP and X2AP */ +#ifdef LCCZLISCT +#ifndef LCSCT +#define LCSCT +#endif +#endif + +#endif /* CZ */ + +/* ******************************************************************* */ +/* TUCL section */ +/* ******************************************************************* */ +#ifdef HI + +/* Define the products that TUCL directly talks to and are part of the */ +/* same binary. */ +#ifndef SB +#define SB +#endif + +#ifndef EG +#define EG +#endif + +#ifndef SM +#define SM +#endif + +/* We need to define LCHIUIHIT if there is at least one layer talking */ +/* to TUCL in a loosely coupled fashion. */ +#define LCHIUIHIT +#define LCHIMILHI + +/* The section below should not be edited normally. */ +#ifdef LCHIUIHIT +#ifndef LCHIT +#define LCHIT +#endif +#endif + +#ifdef LCHIMILHI +#ifndef LCLHI +#define LCLHI +#endif +#endif +#endif /* HI */ + +/**************************************************************************** + SON section +****************************************************************************/ +#ifdef NL +#define LWLCSMSONILNL +#define TCSMSONILNL +#define LCSMSONILNL + + +#ifdef LWLCSMSONILNL +#define NLU_LWLC +#endif + +#ifdef LCSMSONILNL +#define NLU_LC +#endif + +#ifdef TCSMSONILNL +#define NLU_TC +#endif + +#endif +/**************************************************************************** + RRM section +****************************************************************************/ +#ifdef RM + +#define LCRMLIRGM +#define LWLCRMLIRGM +#define LWLCRMUIRMU +#define LWLCSMRMMILRM +#define LCSMRMMILRM +#define PTSMMILRM +#define LCRMMILRM + +#ifdef LCRMLIRGM +#ifndef RGM_LC +#define RGM_LC +#endif +#endif + +#ifdef LWLCRMLIRGM +#ifndef RGM_LWLC +#define RGM_LWLC +#endif +#endif + + + +/* TODO: By conventions we should have this name LCRMU instead of RMU_LC */ +#ifdef LCRMUIRMU +#ifndef RMU_LC +#define RMU_LC +#endif +#endif + +#ifdef LWLCRMUIRMU +#ifndef RMU_LWLC +#define RMU_LWLC +#endif +#endif + +#ifdef LCRMMILRM +#ifndef LCLRM +#define LCLRM +#endif +#endif +#endif + +#endif /* __ENVOPTH__ */ + + +/********************************************************************30** + + End of file +**********************************************************************/ diff --git a/src/cm/gen.h b/src/cm/gen.h new file mode 100755 index 000000000..15d341128 --- /dev/null +++ b/src/cm/gen.h @@ -0,0 +1,2671 @@ +/******************************************************************************* +################################################################################ +# Copyright (c) [2017-2019] [Radisys] # +# # +# 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. # +################################################################################ +*******************************************************************************/ + +/********************************************************************20** + + Name: general layer + + Type: C include file + + Desc: Defines required by two or more layer service user + interfaces. + + File: gen.h + +*********************************************************************21*/ + +#ifndef __GENH__ +#define __GENH__ + +/* defines */ + +#define RTLIN_DUMP_DEBUG printf +/* bndCfg.bufOwnshp for xxBndReq */ + +#define SUOWN 0 /* service user (upper layer) owns buffers */ +#define SPOWN 1 /* service provider (lower layer) owns buffers */ + +/* bndCfg.flcTyp for xxBndReq */ + +#define FLCNOTALLOW 0 /* flow control not allowed */ +#define FLCALLOW 1 /* flow control allowed */ + +/* bndCfg.wdw for xxBndReq */ + +#define WDWNOTALLOW 0 /* window not allowed */ + +/* state values (e.g., for an interface) */ + +#define STATE_DISCONNECTED 0x00 /* disconnected state */ +#define STATE_CONNECTING 0x01 /* connecting state */ +#define STATE_CONNECTED 0x02 /* connected state */ +#define STATE_DISCONNECTING 0x03 /* disconnecting state */ + +/* Protocol Address Structure related defines ..*/ +#define MAX_PROTADDR_LEN 16 /* Right now defined for IP, IPX + * and IPV6 + */ +#define MAX_PROT_ADDRS 4 /* Number of Protocols supported */ + +/* addrs structure for xxConReq, xxDiscReq, xxCfgReq */ + +#define ADRLEN 20 /* Address Length */ +#define SHRTADRLEN 32 /* Short Addres Length */ +#define LNGADRLEN 64 /* Long Address Length */ + +/* token or element header values */ + +#define NOTPRSNT 0 /* not present */ +#define PRSNT_NODEF 1 /* present - no default */ +#define PRSNT_DEF 2 /* present - default */ + +#define MF_SIZE_TKNSTRS 22 /* token string size - small */ +#define MF_SIZE_TKNSTRM 32 /* token string size - medium */ +#define MF_SIZE_TKNSTR 132 /* token string size - regular */ +#define MF_SIZE_TKNSTRE 255 /* token string size - extra large */ +#define MF_SIZE_TKNBITS 7 /* token bits size */ +#define TP_SIZE_TKNSTR 8 /* token string size */ + +/* gen_h_001.main_133 --- size for extension container, MA_LIMIT_EXTCONT */ +#define MA_MF_EXTCONT_SIZE 20 +/* defines for type of service class */ + +#define FRMRLY 1 /* frame relay */ +#define MACINT 2 /* mac interface */ + +/* defines for ISUP and B-ISUP */ + + +/* subsystem field */ + +#define SSF_INTER 0 /* international subsystem field */ +#define SSF_NAT 2 /* national subsystem field */ + +#define PRI_ZERO 0 /* priority 0 - lowest */ +#define PRI_ONE 1 /* priority 1 */ +#define PRI_TWO 2 /* priority 2 */ + +/* direction of suspend */ + +#define FROM_LWR 1 /* direction from lower */ +#define FROM_UPR 2 /* direction from upper */ + +#define MOD15 0x0f /* modulo 15 mask */ +#define NOTUSED 0 /* not used */ + +#define DIR_OUT 1 +#define DIR_INC 2 + +#define PRESALLOW 0 +#define PRESREST 1 +#define MFROK 0 +#define MFRFAILED 1 +#define MFREOM 2 + +/* defines for ATM */ + +#ifndef CMFILE_REORG_1 + +/* special vcc's */ + +#define ATMVPI_SIG 0 /* Q.93B signalling */ +#define ATMVCI_SIG 5 /* Q.93B signalling */ + +#define ATMVPI_ILMI 0 /* ILMI address registration */ +#define ATMVCI_ILMI 16 /* ILMI address registration */ + +/* loss priority */ + +#define ATMLP_HIGH 0 /* high priority */ +#define ATMLP_LOW 1 /* low priority */ + +/* congestion indication */ + +#define ATMCI_NOCONG 0 /* not congested */ +#define ATMCI_CONG 1 /* congested */ + +/* reception status */ + +#define ATMRS_NOERROR 0 /* no error */ +#define ATMRS_ERROR 1 /* error */ + +/* establishement */ + +#define AM_E_DEMAND 0x00 /* demand */ + +/* quality of service classes */ + +#define ATMQOS_CLASS0 0 /* QoS class 0 -unspecified QoS class*/ +#define ATMQOS_CLASS1 1 /* QoS class 1 */ +#define ATMQOS_CLASS2 2 /* QoS class 2 */ +#define ATMQOS_CLASS3 3 /* QoS class 3 */ +#define ATMQOS_CLASS4 4 /* QoS class 4 */ + +/* ATM traffic descriptor octet group identifiers */ + +#define AM_ATD_FPCR_ID0 0x82 /* forward peak cell rate id, CLP = 0 */ +#define AM_ATD_BPCR_ID0 0x83 /* backward peak cell rate id, CLP = 0 */ +#define AM_ATD_FPCR_ID1 0x84 /* forward peak cell rate id, CLP = 0+1 */ +#define AM_ATD_BPCR_ID1 0x85 /* backward peak cell rate id, CLP = 0+1 */ +#define AM_ATD_FSCR_ID0 0x88 /* forward sust. cell rate id, CLP = 0 */ +#define AM_ATD_BSCR_ID0 0x89 /* backward sust. cell rate id, CLP = 0 */ +#define AM_ATD_FSCR_ID1 0x90 /* forward sust. cell rate id, CLP = 0+1 */ +#define AM_ATD_BSCR_ID1 0x91 /* backward sust. cell rate id, CLP = 0+1 */ +#define AM_ATD_FMBS_ID0 0xa0 /* forward mean burst size id, CLP = 0 */ +#define AM_ATD_BMBS_ID0 0xa1 /* backward mean burst size id, CLP = 0 */ +#define AM_ATD_FMBS_ID1 0xb0 /* forward mean burst size id, CLP = 0+1 */ +#define AM_ATD_BMBS_ID1 0xb1 /* backward mean burst size id, CLP = 0+1 */ +#define AM_ATD_BSTEFFRTIND 0xbe /* best effort indicator */ +#define AM_ATD_TFCMGMTOPTID 0xbf /* traffic management options id */ + +/* number of stop bits */ + +#define AM_NSB_UNUSED 0x00 /* none specified */ +#define AM_NSB_1 0x01 /* 1 stop bit */ +#define AM_NSB_15 0x02 /* 1.5 stop bits */ +#define AM_NSB_2 0x03 /* 2 stop bits */ + +/* crankback blocked transit type */ + +#define AM_CBTT_BLKSUCCEND 0x02 /* call or party has been blocked at the + * succeeding end of this interface */ +#define AM_CBTT_BLKNODE 0x03 /* blocked node */ +#define AM_CBTT_BLKLINK 0x04 /* blocked link */ +#define AM_CBTT_BLKBYDSUCC 0xff /* call or party has been blocked at or + * beyond the succeeding node, AINI */ + +/* Specific Crankback level for AINI */ +#define AM_AINI_CBLVL 0xff /* Crankback level for AINI */ + +/* crankback cause indicator */ + +#define AM_CBCAUSE_IND 0x85 /* crankback cause indicator */ + +/* Cranckback and general cause values */ + +#define AM_CV_INVCAUSEVAL 0 /* invalid cause value - proprietary */ +#define AM_CV_UNALLOCNMB 1 /* unallocated (unassigned) number */ +#define AM_CV_NOROUTTRANSNET 2 /* no route to transit network */ +#define AM_CV_NOROUTDST 3 /* no route to destination */ +#define AM_CV_VCCUNACPT 10 /* UNI 3.0: VPCI/VCI unacceptable */ +#define AM_CV_NORMCALLCLR 16 /* UNI 3.1: normal call clearing */ +#define AM_CV_USRBUSY 17 /* user busy */ +#define AM_CV_NOUSRRSP 18 /* no user response */ +#define AM_CV_NOANSUSR 19 /* no answer from user */ +#define AM_CV_CALLREJ 21 /* call rejected */ +#define AM_CV_NMBCHNG 22 /* number changed */ +#define AM_CV_CALLREJCLIR 23 /* user rejects all calls with CLIR */ +#define AM_CV_DSTOUTORD 27 /* destination out of order */ +#define AM_CV_INVNMBFORM 28 /* invalid number format */ +#define AM_CV_RSPSTATENQ 30 /* response to STATUS ENQUIRY */ +#define AM_CV_NORMUNSPEC 31 /* normal unspecified */ +#define AM_CV_PNDADDPTYREQ 32 /* PNNI: too many pending add party requests */ +#define AM_CV_CHNGINPGL 34 /* PNNI: Call cleared due to change in PGL */ +#define AM_CV_REQVCCUNAVAIL 35 /* requested VPCI/VCI unavailable */ +#define AM_CV_VCCFAIL 36 /* UNI 3.1: VPCI/VCI assignment failure */ +#define AM_CV_RATEUNAVAIL1 37 /* UNI 3.1: user cell rate unavailable */ +#define AM_CV_NETOUTORD 38 /* network out of order */ +#define AM_CV_TMPFAIL 41 /* Temporary failure */ +#define AM_CV_ACCINFODISC 43 /* access info discarded */ +#define AM_CV_NOVCCAVAIL 45 /* no VPCI/VCI unavailable */ +#define AM_CV_RESAIL 47 /* resources unavailable, unspecified */ +#define AM_CV_QOSUNAVAIL 49 /* Quality of Service unavailable */ +#define AM_CV_RATEUNAVAIL 51 /* UNI 3.0: user cell rate unavailable */ +#define AM_CV_REQPVPCVCCUNAV 53 /* PNNI: Requested Called party soft PVPC/PVCC not available */ +#define AM_CV_BCAPNOTAUTH 57 /* bearer capability not authorized */ +#define AM_CV_BCAPUNAVAIL 58 /* bearer capability not available */ +#define AM_CV_SRVUNAVAIL 63 /* Service or option unavailable */ +#define AM_CV_BCAPNOTIMPL 65 /* bearer capability not implemented */ +#define AM_CV_COMBUNSUPP 73 /* unsupported comb. of traffic parameters */ +#define AM_CV_AALPARMUNSUPP1 78 /* UNI 3.1: AAL paramteres cannot be supported */ +#define AM_CV_INVCALLREF 81 /* invalid call reference */ +#define AM_CV_CHANNOTEXST 82 /* identified channel does not exist */ +#define AM_CV_DSTNOTCOMP 88 /* incompatible destination */ +#define AM_CV_INVENDPTREF 89 /* invalid endpoint reference */ +#define AM_CV_INVTRANSNET 91 /* invalid transit network selection */ +#define AM_CV_MANYADDPTYREQ 92 /* too many add party requests */ +#define AM_CV_AALPARMUNSUPP 93 /* UNI 3.0:AAL paramteres cannot be supported */ +#define AM_CV_INFOELMSSG 96 /* mandatory info element is missing */ +#define AM_CV_MSGTYPNOTIMPL 97 /* message type not implemented */ +#define AM_CV_INFOELNOTIMPL 99 /* info element not implemented */ +#define AM_CV_INVINFOEL 100 /* invalid info element */ +#define AM_CV_MSGNOTCOMP 101 /* msg type not compatible with call st */ +#define AM_CV_TMRRCVRY 102 /* recovery on timer expiry */ +#define AM_CV_INVMSGLEN 104 /* incorrect message length */ +#define AM_CV_PROTERR 111 /* protocol error, unspecified */ +#define AM_CV_OPTELMERR 127 /* opt info el content error (non-std) */ +#define AM_CV_NOROUTNEXTNODE 128 /* next node unreachable */ +#define AM_CV_DTLNOTMYNODE 160 /* DTL Transit not my node ID */ + +/* AAL type */ + +#define AM_AALTYP_0 0x00 /* AAL for voice */ +#define AM_AALTYP_1 0x01 /* AAL type 1 */ +#define AM_AALTYP_2 0x02 /* AAL type 2 */ +#define AM_AALTYP_34 0x03 /* AAL type 3/4 */ +#define AM_AALTYP_5 0x05 /* AAL type 5 */ +#define AM_AALTYP_USR 0x10 /* user defined AAL */ + +/* AAL type 1 - identifiers */ +#define AM_AAL1_ID_STYPE 0x85 /* AAL Subtype ID */ +#define AM_AAL1_ID_CBR 0x86 /* CBR Rate ID */ +#define AM_AAL1_ID_MULT 0x87 /* Multiplier Identifier */ +#define AM_AAL1_ID_SCFRM 0x88 /* Source Clock Freq. Recovery Method Id */ +#define AM_AAL1_ID_ECM 0x89 /* Error correction Method Id */ +#define AM_AAL1_ID_SDTB 0x8A /* Structured Data Transfer Blocksize Id */ +#define AM_AAL1_ID_PFC 0x8B /* Partially filled cells Id */ + +/* AAL type 1 subtypes */ +#define AM_AAL1_STYPE_NULL 0x00 /* Null/Empty */ +#define AM_AAL1_STYPE_VOICE 0x01 /* Voice-band based on 64 kbit/s */ +#define AM_AAL1_STYPE_SCKT 0x02 /* Synchronous circuit Emulation */ +#define AM_AAL1_STYPE_ACKT 0x03 /* Asynchronous circuit Emulation */ +#define AM_AAL1_STYPE_HQAUD 0x04 /* High Quality Audio */ +#define AM_AAL1_STYPE_VIDEO 0x05 /* Video */ + +/* AAL type 1 CBR rates */ +#define AM_AAL1_CBR_64 0x01 /* 64 kbit/s */ +#define AM_AAL1_CBR_1544 0x04 /* 1544 kbit/s (DS1) */ +#define AM_AAL1_CBR_6312 0x05 /* 6312 kbit/s (DS2) */ +#define AM_AAL1_CBR_32064 0x06 /* 32064 kbit/s */ +#define AM_AAL1_CBR_44736 0x07 /* 44736 kbit/s (DS3) */ +#define AM_AAL1_CBR_97728 0x08 /* 97728 kbit/s */ +#define AM_AAL1_CBR_2048 0x10 /* 2048 kbit/s (E1) */ +#define AM_AAL1_CBR_8448 0x11 /* 8448 kbit/s (E2) */ +#define AM_AAL1_CBR_34368 0x12 /* 34368 kbit/s (E3) */ +#define AM_AAL1_CBR_139264 0x13 /* 139264 kbit/s */ +#define AM_AAL1_CBR_nx64 0x40 /* n x 64 kbit/s */ +#define AM_AAL1_CBR_nx8 0x41 /* n x 8 kbit/s */ + +/* AAL type 1 Clock recovery types */ +#define AM_AAL1_SCFRM_NULL 0x00 /* Null */ +#define AM_AAL1_SCFRM_SRTS 0x01 /* Synchronous Residual Time Stamp */ +#define AM_AAL1_SCFRM_ACR 0x02 /* Adaptive clock Recovery */ + +/* AAL type 1 Error Correction types */ +#define AM_AAL1_ECM_NULL 0x00 /* NULL */ +#define AM_AAL1_ECM_FEC 0x01 /* Interleaved FEC */ +#define AM_AAL1_ECM_DSST 0x02 /* For delay sensitive signal transport */ + +/* AAL type 1 Structured Data Transfer */ +#define AM_AAL1_SDTB_NULL 0x00 /* NULL */ +#define AM_AAL1_SDTB_SDT 0x01 /* Structured Data Transfer */ + +/* AAL type 5 & 3/4 - identifiers */ +#define AM_AAL5_ID_FMSDU 0x8c /* forward maximum CPCS SDU size id */ +#define AM_AAL5_ID_BMSDU 0x81 /* backward maximum CPCS SDU size id */ +#define AM_AAL5_ID_MIDRNG 0x82 /* Mid Range Id */ +#define AM_AAL5_ID_MODE 0x83 /* mode identifier */ +#define AM_AAL5_ID_SSCS 0x84 /* SSCS type identifier */ + +/* AAL type 5 & 3/4 - mode of operation */ + +#define AM_AAL5_MODE_MSG 0x01 /* message mode */ +#define AM_AAL5_MODE_STREAM 0x02 /* streaming mode */ + +/* AAL type 5 - SSCS type */ + +#define AM_AAL5_SSCS_NULL 0x00 /* null SSCS */ +#define AM_AAL5_SSCS_SSCOP_A 0x01 /* SSCOP assured mode SSCS */ +#define AM_AAL5_SSCS_SSCOP_N 0x02 /* SSCOP non-assured mode SSCS */ +#define AM_AAL5_SSCS_FR 0x04 /* frame relay SSCS */ + +/* bearer class */ + +#define AM_BCOB_A 0x01 /* bearer class A */ +#define AM_BCOB_C 0x03 /* bearer class C */ +#define AM_BCOB_X 0x10 /* bearer class X */ + +/* timing requirement */ + +#define AM_TMGREQ_NOIND 0 /* no indication */ +#define AM_TMGREQ_ETOEREQ 1 /* end-to-end timing required */ +#define AM_TMGREQ_ETOENOTREQ 2 /* end-to-end timing not required */ + +/* traffic type */ + +#define AM_TFCTYP_NOIND 0 /* no indication */ +#define AM_TFCTYP_CBR 1 /* constant bit rate */ +#define AM_TFCTYP_VBR 2 /* variable bit rate */ + +/* user plane connection configuration */ + +#define AM_CONCFG_PTPT 0 /* point to point */ +#define AM_CONCFG_PTMPT 1 /* point to multipoint */ + +/* susceptability to clipping */ + +#define AM_SUSCLP_NO 0 /* not susceptible to clipping */ +#define AM_SUSCLP_YES 1 /* susceptible to clipping */ + +/* layer 1 identity */ + +#define AM_L1_IDENT 0x01 /* layer 1 identity */ + +/* layer 2 identity */ + +#define AM_L2_IDENT 0x02 /* layer 2 identity */ + +/* layer 3 identity */ + +#define AM_L3_IDENT 0x03 /* layer 3 identity */ + +/* user information layer 1 */ + +#define AM_UIL1_CCITTV110 0x01 /* CCITT Standardized Rate Adaptation V.110/X.30. */ +#define AM_UIL1_G711ULAW 0x02 /* Reccomendation G.711 u-Law */ +#define AM_UIL1_G711ALAW 0x03 /* Recommendation G.711 A-Law */ +#define AM_UIL1_G721ADCPM 0x04 /* Recommendation G.721 32 kbit/s ADCPM and */ + /* Recommendation I.460 */ +#define AM_UIL1_G722G725 0x05 /* Recommendation G.722 and G.725 - 7kHz Audio */ +#define AM_UIL1_H261 0x06 /* Recommendation H.261 - 384 kbit/s Video */ +#define AM_UIL1_NONCCITT 0x07 /* Non-CCITT standardized Rate adaptation */ +#define AM_UIL1_CCITTV120 0x08 /* CCITT Standardized Rate Adaptation V.120 */ +#define AM_UIL1_CCITTX31 0x09 /* CCITT Standardized Rate Adaptation X.31 HDLC */ + +/* user information layer 2 protocol */ + +#define AM_UIL2_BASIC 0x01 /* basic mode - ISO 1745 */ +#define AM_UIL2_Q921 0x02 /* CCITT Recommendation Q.921 */ +#define AM_UIL2_X25SLP 0x06 /* CCITT Recommendation X.25, single link */ +#define AM_UIL2_X25MLP 0x07 /* CCITT Recommendation X.25, multi link */ +#define AM_UIL2_T71 0x08 /* extended LAPB for half duplex, */ + /* CCITT Recommendation T.71 */ +#define AM_UIL2_HDLCARM 0x09 /* HDLC ARM - ISO 4335 */ +#define AM_UIL2_HDLCNRM 0x0a /* HDLC NRM - ISO 4335 */ +#define AM_UIL2_HDLCABM 0x0b /* HDLC ABM - ISO 4335 */ +#define AM_UIL2_LANLLC 0x0c /* LAN LLC - ISO 8802/2 */ +#define AM_UIL2_X75SLP 0x0d /* CCITT Recommendation X.75, single link */ +#define AM_UIL2_Q922 0x0e /* CCITT Recommendation Q.922 */ +#define AM_UIL2_USRSPEC 0x10 /* CCITT User specified */ +#define AM_UIL2_T90 0x11 /* CCITT T.90 */ + +/* Layer 2/3 Operation Mode */ +#define AM_LOLYR_OPR_NORM 0x01 /* Normal mode of operation */ +#define AM_LOLYR_OPR_EXT 0x02 /* Extended mode of operation */ + +/* user information layer 3 protocol */ + +#define AM_UIL3_Q931 0x02 /* CCITT Recommendation Q.931 */ +#define AM_UIL3_T90 0x05 /* CCITT T.90 */ +#define AM_UIL3_X25PLP 0x06 /* CCITT Recommendation X.25, packet layer */ +#define AM_UIL3_ISO8208 0x07 /* ISO 8208 */ +#define AM_UIL3_ISO8348 0x08 /* ISO 8348 */ +#define AM_UIL3_ISO8473 0x09 /* ISO 8473 */ +#define AM_UIL3_T70 0x0a /* CCITT Recommendation T.70 */ +#define AM_UIL3_ISO9577 0x0b /* ISO/IEC TR 9577 */ +#define AM_UIL3_USRSPEC 0x10 /* CCITT User specified */ + +/* presentation method of protocol profile */ + +#define AM_PM_VAL1 0x01 /* value 1 */ + +/* information transfer mode */ + +#define AM_TM_CIRCUIT 0x00 /* circuit mode */ +#define AM_TM_PACKET 0x02 /* packet mode */ + +/* information transfer capability */ + +#define AM_ITC_SPEECH 0x00 /* speech */ +#define AM_ITC_UNRDIG 0x08 /* unrestricted digital information */ +#define AM_ITC_RESDIG 0x09 /* restricted digital information */ +#define AM_ITC_A31KHZ 0x10 /* 3.1kHz audio */ +#define AM_ITC_A7KHZ 0x11 /* 7 kHz audio */ +#define AM_ITC_A15KHZ 0x12 /* 15 kHz audio */ +#define AM_ITC_VIDEO 0x18 /* video */ + +/* information transfer rate */ + +#define AM_ITR_PKT 0x00 /* packet mode */ +#define AM_ITR_64KBIT 0x10 /* circuit mode - 64 kbits */ +#define AM_ITR_2X64KBIT 0x11 /* circuit mode - 2 X 64 kbits */ +#define AM_ITR_384KBIT 0x13 /* circuit mode - 384 kbits */ +#define AM_ITR_1472KBIT 0x14 /* circuit mode - 1472 kbits */ +#define AM_ITR_1536KBIT 0x15 /* circuit mode - 1536 kbits */ +#define AM_ITR_1920KBIT 0x17 /* circuit mode - 1920 kbits */ +#define AM_ITR_MULIRATE 0x18 /* circuit mode - multi rate */ + +/* symmetry */ + +#define AM_S_BISYM 0x00 /* bidirectional symmetry */ + +/* structure */ + +#define AM_S_DEF 0x00 /* default */ +#define AM_S_8KHZINTEG 0x01 /* 8 khz integrity */ +#define AM_S_SDUINTEG 0x04 /* service data unit integrity */ +#define AM_S_UNSTRUCT 0x07 /* unstructured */ + +/* intermediate rate */ + +#define AM_IR_NONE 0x00 /* none specified */ +#define AM_IR_8KBIT 0x01 /* 8 kbits */ +#define AM_IR_16KBIT 0x02 /* 16 kbits */ +#define AM_IR_32KBIT 0x03 /* 32 kbits */ + +/* negotiation */ + +#define AM_N_IBNOTPOSS 0x00 /* inband not possible */ +#define AM_N_IBPOSS 0x01 /* inband possible */ + + /* negotiation indicator */ + +#define AM_N_OBNOTPOSS 0x00 /* outband not possible */ +#define AM_N_OBPOSS 0x01 /* outband possible */ + +/* synchronous/asynchronous */ + +#define AM_SA_SYNC 0x00 /* synchronous */ +#define AM_SA_ASYNC 0x01 /* asynchronous */ + +/* assignor/assignee */ + +#define AM_AA_ORGASGNEE 0x00 /* originator is assignee */ +#define AM_AA_ORGASGNOR 0x01 /* originator is assignor */ + +/* duplex mode */ + +#define AM_DUPMODE_HALF 0x00 /* half duplex */ +#define AM_DUPMODE_FULL 0x01 /* full duplex */ + +/* mode of operation */ + +#define AM_MOO_BITTRANS 0x00 /* bit transparent */ +#define AM_MOO_PROTSEN 0x01 /* protocol sensitive */ + +/* multiple frame establishment */ + +#define AM_MFE_NOTSUP 0x00 /* not supported */ +#define AM_MFE_SUP 0x01 /* supported */ + +/* logical link identifier */ + +#define AM_LLI_DEF 0x00 /* default */ +#define AM_LLI_FULLNEG 0x01 /* full protocol negotiation */ + +/* inband/outband negotiation */ + +#define AM_ION_USRINFO 0x00 /* negotiation with user info messages */ +#define AM_ION_LL0 0x01 /* negotiation in band using logical link 0 */ + +/* narrow band coding standards */ + +#define AM_CSTD_CCITT 0x00 /* CCITT standards */ +#define AM_CSTD_INT 0x01 /* Other International Standards */ +#define AM_CSTD_NAT 0x02 /* National Standard */ +#define AM_CSTD_NET 0x03 /* Network Standard */ + +/* coding standard */ + +#define AM_CODESTD_CCITT 0 /* ITU-TS (CCITT) standardized */ +#define AM_CODESTD_NET 3 /* ATM Forum specific */ + +/* location */ + +#define AM_LOCN_USER 0x00 /* user */ +#define AM_LOCN_PRVNETLOC 0x01 /* private network serving local user */ +#define AM_LOCN_PUBNETLOC 0x02 /* public network serving local user */ +#define AM_LOCN_TRNSNET 0x03 /* transit network */ +#define AM_LOCN_PUBNETRMT 0x04 /* public network serving remote user */ +#define AM_LOCN_PRVNETRMT 0x05 /* private network serving remote user */ +#define AM_LOCN_INTNET 0x07 /* international network */ +#define AM_LOCN_NETINTWRK 0x0a /* network beyond interworking point */ + +/* extended high layer characteristics */ + +#define AM_XHLCI_TEL 0x01 /* Telephony - Recommendation G.711 */ +#define AM_XHLCI_FAXG4 0x04 /* Facsimile Group 4 - Recommendation T.62 */ +#define AM_XHLCI_DAPFAXG4 0x21 /* Doc App Profile for Facsimile Group 4 */ + /* Recommendation T.503 */ +#define AM_XHLCI_DAPMIXED 0x24 /* Doc App Profile for Facsimile Group 4 */ + /* Recommendation T.501 */ +#define AM_XHLCI_DAPPROC 0x28 /* Doc App Profile for Facsimile Group 4 */ + /* Recommendation T.502 */ +#define AM_XHLCI_TELETEX 0x31 /* Teletex - Recommendation T.62/T.70 */ +#define AM_XHLCI_DAPVIDEO 0x32 /* Doc App Profile for Facsimile Group 4 */ + /* Recommendation T.503 */ +#define AM_XHLCI_TELEX 0x35 /* Telex */ +#define AM_XHLCI_MHS 0x38 /* Message Handling System */ + /* Recommendation X.400 */ +#define AM_XHLCI_OSIAPP 0x41 /* OSI Application - Recommendation X.200 */ +#define AM_XHLCI_MAINT 0x5e /* Maintenance */ +#define AM_XHLCI_MNGMT 0x5f /* Management */ +#define AM_XHLCI_VIDTEL 0x60 /* Videotelephony (F.xyz and AV.242) */ +#define AM_XHLCI_RESERVE 0xff /* Reserved */ + + +/* ATM Traffic Descriptor tagging */ + +#define AM_ATD_TAGNOTREQ 0 /* tagging not requested */ +#define AM_ATD_TAGREQ 1 /* tagging requested */ + +/* ATM Traffic Descriptor Frame discard */ + +#define AM_ATD_NOFRMDISC 0 /* frame discard not allowed */ +#define AM_ATD_FRMDISC 1 /* frame discard allowed */ + +/* ATM Traffic Descriptor ABR specific token identifier */ + +#define AM_ATD_ABR_FMCR_ID 0x92 /* Forward ABR minimum cell rate identifier */ +#define AM_ATD_ABR_BMCR_ID 0x93 /* Forward ABR minimum cell rate identifier */ + +/* crankback level indicator */ + +#define AM_CBLEVEL_IND 0x81 /* crankback level indicator */ + +/* succeeding end block indicator */ + +#define AM_ENDBLK_IND 0x82 /* succeeding end block indicator */ + +/* blocked node indicator */ + +#define AM_BLKNODE_IND 0x83 /* blocked node indicator */ + +/* blocked link indicator */ + +#define AM_BLKLINK_IND 0x84 /* blocked link indicator */ + +/* connection level id */ + +#define AM_CONLEVEL_ID 0x81 /* connection level id */ + +/* connection level */ + +#define AM_CONLEVEL_VCC 0x01 /* virtual channel connection */ +#define AM_CONLEVEL_VPC 0x02 /* virtual path connection */ + +/* VPI/VCI selection type */ + +#define AM_VPCSEL_ANY 0x00 /* any VPI/VCI */ +#define AM_VPCSEL_REQ 0x02 /* required VPI/VCI */ +#define AM_VPCSEL_ASSGN 0x04 /* assigned VPI/VCI */ + +/* VPI id */ + +#define AM_VPI_ID 0x81 /* VPI id */ + +/* VCI id */ + +#define AM_VCI_ID 0x82 /* VCI id */ + +/* shaping indicator */ + +#define AM_SHAPIND_NOREQ 0x00 /* no user requirement */ +#define AM_SHAPIND_NOAGG 0x01 /* no aggregation of user and OAM cells */ + +/* payload types */ + +#define ATMPT_USR 0 /* user cells */ +#define ATMPT_RM 1 /* RM cells */ +#define ATMPT_OAM 2 /* OAM cells */ + +/* values for lnkNmb parameter */ + +#define AMT_CON_LNK_UNUSED 0xffff /* link number field not significant */ + + +/* defines for LAN emulation */ + +/* MAC address length */ + +#define MACADDRLEN 6 /* 48 bit MAC address length */ + +/* LANE and MAC header length */ + +#define LANE_HDR_LEN 2 /* 2 octet LANE header length */ +#define LANE_MACHDR_LEN 14 /* 802.3 (DA/SA/Len), 802.5 (AC/FC/DA/SA) */ + +/* Additional broadband repeat indicators */ + +#define AM_REPIND_Q2763_1 0x00 /* reserved for use by Rec. Q.2763 */ +#define AM_REPIND_Q2763_2i 0x01 /* reserved for use by Rec. Q.2763 */ + +/* values for AC/FC fields - to be ignored */ + +#define LANE_HDR_8025_AC 0x00 /* no significance */ +#define LANE_HDR_8025_FC 0x40 /* LLC frame, priority 0 */ + +/* value for pad octets */ + +#define LANE_PAD 0x00 /* pad octets */ + +/* source routed frame types */ + +#define LANE_FRAMETYPE_NSR 0x00 /* not source routed */ +#define LANE_FRAMETYPE_SRF 0x01 /* specifically routed frame */ +#define LANE_FRAMETYPE_ARE 0x02 /* all routes explorer frame */ +#define LANE_FRAMETYPE_STE 0x03 /* spanning tree explorer frame */ +#define LANE_FRAMETYPE_ERR 0x04 /* illegal frame type */ + +/* next hop types for SRF frames */ + +#define LANE_NEXTHOP_NONE 0x00 /* no hop */ +#define LANE_NEXTHOP_LAST 0x01 /* last hop */ +#define LANE_NEXTHOP_MORE 0x02 /* more hops */ + +/* maximum sizes for typedef arrays */ + +#define MAX_LANNAME 32 /* size of LAN name string */ +#define MAX_MACADDRTBL 16 /* size of MAC address table */ +#define MAX_RDTBL 16 /* size of route descriptor table */ +#define MAX_TLV_LEN 4 /* max length of value in TLV entry */ +#define MAX_TLV_TBL 16 /* size of TLV table */ + +/* marker (special LEC id) */ + +#define LANE_MARKER_CTRL 0xff00 /* control frame marker */ + +/* LAN emulation protocol */ + +#define LANE_PROTOCOL 0x01 /* LAN Emulation protocol */ + +/* LAN emulation protocol version */ + +#define LANE_VERSION 0x01 /* LAN Emulation protocol version */ + +/* op code type */ + +#define LANE_OPCODE_TYPE_REQ 0x00 /* request frame */ +#define LANE_OPCODE_TYPE_RSP 0x01 /* response frame */ + +/* op code name */ + +#define LANE_OPCODE_CFGREQ 0x0001 /* configuration request frame */ +#define LANE_OPCODE_CFGRSP 0x0101 /* configuration response frame */ +#define LANE_OPCODE_JOINREQ 0x0002 /* join request frame */ +#define LANE_OPCODE_JOINRSP 0x0102 /* join response frame */ +#define LANE_OPCODE_READYQUERY 0x0003 /* ready query frame */ +#define LANE_OPCODE_READYIND 0x0103 /* ready indication frame */ +#define LANE_OPCODE_REGREQ 0x0004 /* register request frame */ +#define LANE_OPCODE_REGRSP 0x0104 /* register response frame */ +#define LANE_OPCODE_UNREGREQ 0x0005 /* unregister request frame */ +#define LANE_OPCODE_UNREGRSP 0x0105 /* unregister response frame */ +#define LANE_OPCODE_ARPREQ 0x0006 /* configuration request frame */ +#define LANE_OPCODE_ARPRSP 0x0106 /* configuration response frame */ +#define LANE_OPCODE_FLUSHREQ 0x0007 /* flush request frame */ +#define LANE_OPCODE_FLUSHRSP 0x0107 /* flush response frame */ +#define LANE_OPCODE_NARPREQ 0x0008 /* negative ARP request frame */ +#define LANE_OPCODE_TOPCHREQ 0x0009 /* topology change request frame */ + +/* status */ + +#define LANE_STA_SUCCESS 0 /* success */ +#define LANE_STA_UNSUPPVER 1 /* version not supported */ +#define LANE_STA_INVPARAM 2 /* invalid request parameters */ +#define LANE_STA_DUPLANDST 4 /* duplicate LAN destination */ +#define LANE_STA_DUPATMADDR 5 /* duplicate ATM address */ +#define LANE_STA_RESAIL 6 /* insufficient resources to grant request */ +#define LANE_STA_NOACCESS 7 /* access denied */ +#define LANE_STA_INVLECID 8 /* invalid requestor-LECID */ +#define LANE_STA_INVLANDST 9 /* invalid LAN destination */ +#define LANE_STA_INVATMADDR 10 /* invalid ATM address */ +#define LANE_STA_NOCFG 20 /* no configuration */ +#define LANE_STA_LECSERR 21 /* LECS error */ +#define LANE_STA_INFOUNAVAIL 22 /* insufficient information */ + +/* non-standard status values, for internal use */ + +#define LANE_STA_INVCTRL 0x0f00 /* invalid control frame - unspecified */ + +/* flag values */ + +#define LANE_FLAG_RMTADDR 0x0001 /* remote address (unreg LAN dst) */ +#define LANE_FLAG_PROXY 0x0080 /* LEC acts as proxy */ +#define LANE_FLAG_TOPCH 0x0100 /* topology change */ + +/* tag values for LAN destination type */ + +#define LANE_TAG_NOTPRSNT 0x0000 /* not present */ +#define LANE_TAG_MACADDR 0x0001 /* MAC address */ +#define LANE_TAG_RD 0x0002 /* route designator */ + +/* LAN type */ + +#define LANE_LANTYPE_UNSPECIFIED 0x00 /* unspecified */ +#define LANE_LANTYPE_8023 0x01 /* IEEE 802.3/Ethernet */ +#define LANE_LANTYPE_8025 0x02 /* IEEE 802.5/Token Ring */ + +/* min frame size - values */ + +#define LANE_MIN_DATA_8023 62 /* minimum AAL SDU size for IEEE 802.3 data */ +#define LANE_MIN_DATA_8025 16 /* minimum AAL SDU size for IEEE 802.5 data */ +#define LANE_MIN_CTRL 108 /* minimum AAL SDU size for control frame */ + +/* max frame size - index */ + +#define LANE_MTU_IDX_UNSPECIFIED 0x00 /* unspecified */ +#define LANE_MTU_IDX_ENET 0x01 /* 1516 octets IEEE 802.3 */ +#define LANE_MTU_IDX_TR_4 0x02 /* 4544 octets IEEE 802.5 4Mbps */ +#define LANE_MTU_IDX_RFC1626 0x03 /* 9234 octets RFC 1626 */ +#define LANE_MTU_IDX_TR_16 0x04 /* 18190 octets IEEE 802.5 16Mbps */ + +/* max frame size - values */ + +#define LANE_MTU_VAL_UNSPECIFIED 0 /* unspecified */ +#define LANE_MTU_VAL_ENET 1516 /* 1516 octets IEEE 802.3 */ +#define LANE_MTU_VAL_TR_4 4544 /* 4544 octets IEEE 802.5 4Mbps */ +#define LANE_MTU_VAL_RFC1626 9234 /* 9234 octets RFC 1626 */ +#define LANE_MTU_VAL_TR_16 18190 /* 18190 octets IEEE 802.5 16Mbps */ + +/* VCC nature */ + +#define VCC_NATURE_PVC 0 /* permanent virtual circuit */ +#define VCC_NATURE_SVC 1 /* switched virtual circuit */ +#define VCC_NATURE_PVC_SVC 2 /* mixed PVC/SVC */ + +/* VCC type (values from LEC MIB) */ + +#define LANE_VCC_TYPE_CTRL_DIR 0 /* control direct VCC */ +#define LANE_VCC_TYPE_CTRL_DIST 1 /* control distribute VCC */ +#define LANE_VCC_TYPE_MCAST_SND_8023 2 /* multicast send VCC for 802.3 */ +#define LANE_VCC_TYPE_MCAST_FWD_8023 3 /* multicast forward VCC for 802.3 */ +#define LANE_VCC_TYPE_MCAST_SND_8025 4 /* multicast send VCC for 802.5 */ +#define LANE_VCC_TYPE_MCAST_FWD_8025 5 /* multicast forward VCC for 802.5 */ +#define LANE_VCC_TYPE_DATA_DIR_8023 6 /* data direct VCC for 802.3 */ +#define LANE_VCC_TYPE_DATA_DIR_8025 7 /* data direct VCC for 802.5 */ +#define LANE_VCC_TYPE_UNKNOWN 8 /* unclassified VCC */ +#define LANE_VCC_TYPE_CFG_DIR 9 /* cfg direct VCC */ + +/* LAN destination proxy class */ + +#define LANE_CLASS_LOCAL 0 /* local LAN destination */ +#define LANE_CLASS_PROXY 1 /* proxy LAN destination */ + +/* LAN destination mode (type) */ + +#define LANE_LDMODE_UCAST_MACADDR 0 /* unicast MAC address */ +#define LANE_LDMODE_MCAST_MACADDR 1 /* multicast MAC address */ +#define LANE_LDMODE_MCAST_ALLGRP 2 /* all group addresses */ +#define LANE_LDMODE_MACADDR 3 /* MAC address */ +#define LANE_LDMODE_RD 4 /* route descriptor */ +#define LANE_LDMODE_UCAST_ALLUNI 5 /* all unicast addresses */ + +/* configuration mode */ + +#define LANE_CFGMODE_AUTO 0 /* auto cfg (use LECS ATM addr) */ +#define LANE_CFGMODE_MANUAL 1 /* manual cfg (use LES ATM addr) */ + +/* ATM Forum OUI - 3 octets */ + +#define OUI_ATMF 0x00a03e /* ATM Forum OUI */ + +/* LAN Emulation Protocol Ids - 2 octets */ + +#define LANE_PID_CTRL 0x0001 /* control VCCs */ +#define LANE_PID_DATA_DIR_8023 0x0002 /* data direct VCCs for IEEE 802.3 */ +#define LANE_PID_DATA_DIR_8025 0x0003 /* data direct VCCs for IEEE 802.5 */ +#define LANE_PID_MCAST_8023 0x0004 /* multicast VCCs for IEEE 802.3 */ +#define LANE_PID_MCAST_8025 0x0005 /* multicast VCCs for IEEE 802.5 */ + +/* LAN Emulation standard TLV types - 4 octets */ + +#define LANE_TLV_C7 0x00a03e01 /* control timer */ +#define LANE_TLV_C10 0x00a03e02 /* max unknown frame count */ +#define LANE_TLV_C11 0x00a03e03 /* max unknown frame timer */ +#define LANE_TLV_C12 0x00a03e04 /* VCC aging timer */ +#define LANE_TLV_C13 0x00a03e05 /* max retry count */ +#define LANE_TLV_C17 0x00a03e06 /* ARP long (cache) timer */ +#define LANE_TLV_C18 0x00a03e07 /* ARP short (fwd delay) timer */ +#define LANE_TLV_C20 0x00a03e08 /* ARP Request timer */ +#define LANE_TLV_C21 0x00a03e09 /* Flush Request timer */ +#define LANE_TLV_C22 0x00a03e0a /* path switching delay */ +#define LANE_TLV_C23 0x00a03e0b /* local segment id */ +#define LANE_TLV_C24 0x00a03e0c /* mcast snd VCC type */ +#define LANE_TLV_C25 0x00a03e0d /* mcast snd VCC SCR */ +#define LANE_TLV_C26 0x00a03e0e /* mcast snd VCC PCR */ +#define LANE_TLV_C28 0x00a03e0f /* Ready Ind timer */ + +#endif /* CMFILE_REORG_1 */ + + + + +/* structure */ + +#define S_DEF 0x00 /* default */ +#define S_8KHZINTEG 0x01 /* 8 khz integrity */ +#define S_SDUINTEG 0x04 /* service data unit integrity */ +#define S_UNSTRUCT 0x07 /* unstructured */ + +/* define for TCAP string size */ +/* gen_h_001.main_128 - redefined value of MAX_ST_STRING to 256 */ +#define MAX_ST_STRING 256 /* longest string */ + + +/* defines for SPstTsk */ + +#define SEL_LC_NEW 0 /* loosely coupled interface - new */ +#define SEL_LC_OLD 1 /* loosely coupled interface - old */ + +/* defines for system service entity processor, region and pool id's */ + +#define OWNPROCID 0 /* own processor id */ +#define SP_POOL 0x00 /* service provider pool id */ +#define SU_POOL 0x00 /* service user pool id */ + +/* defines for stack manager region and pool id's */ + +#define SMREGION 1 /* stack manager region id */ +#define SMPOOL 0 /* stack manager pool id */ + +/* defines */ + +/* Mngmt.hdr.msgType */ + +#define TCFG 1 /* configuration */ +#define TCNTRL 2 /* control */ +#define TSTS 3 /* statistics */ +#define TSSTA 4 /* solicited status */ +#define TUSTA 5 /* unsolicited status */ +#define TTRC 6 /* trace */ +#define TACNT 7 /* billing */ +#define TUDAT 8 /* unit data */ +#define TWRMSTRT 9 /* warm start */ +#define TSWP 10 /* swapping */ +#define TSNAP 11 /* register snapshot */ +#define TUCFG 12 /* unconfig */ +#define TSNMP 13 /* snmp req */ +#define TOBJ 14 /* obj req */ +#define TMIB 15 /* mib req */ +/* gen_h_001.main_124 RRC 2.0 Release*/ +#define TAUDT 16 /* Audit req */ + +/* Mngmt.hdr.elmId.elmnt */ + +#define STGEN 1 /* general */ +#define STTSAP 2 /* transport SAP */ +#define STNSAP 3 /* network SAP */ +#define STLLSAP 4 /* logical link SAP */ +#define STDLSAP 5 /* data link SAP */ +#define STMSAP 6 /* MAC SAP */ +#define STPSAP 7 /* physical SAP */ +#define STSID 8 /* system id */ +#define STHG 9 /* hunt Group */ +#define STROUT 10 /* route */ +#define STDLC 11 /* data link connection */ +#define STINTCUG 12 /* international cugs */ +#define STBCHNPROF 13 /* B channel profile */ +#define STPVC 14 /* PVC configuration */ +#define STMCGRP 15 /* multicast group */ +#define STFRROUT 16 /* frame relay route */ +#define STDCHAN 17 /* X.31 D channel */ +#define STADRMAP 18 /* address mapping */ +#define STDELADRMAP 19 /* delete X.31 address mapping */ + +#define STLOOP 20 /* loop */ +#define STREG 21 /* region */ +#define STDPOOL 22 /* dynamic pool */ +#define STSPOOL 23 /* static pool */ +#define STDQ 24 /* demand queue */ +#define STENT 25 /* entity */ +#define STTSK 26 /* task */ + +#define STDELROUT 30 /* delete route */ +#define STDELPVC 31 /* delete PVC */ +#define STIFDSTADR 32 /* interface destination address */ + +#define STLNKSET 33 /* link set */ +#define STISAP 34 /* isup SAP */ +#define STICIR 35 /* isup circuit */ +#define STSPSAP 36 /* tcap lower sccp sap */ +#define STTCUSAP 37 /* tcap upper user sap */ +#define STTPSAP 38 /* tup SAP */ +#define STTPCIR 39 /* tup circuit */ +#define STVCC 40 /* virtual channel connection */ +#define STCGPTYNMB 41 /* calling party number */ +#define STWPSAP 42 /* wrapper SAP */ +#define STAALSAP 43 /* AAL SAP */ +#define STLANDST 44 /* LAN destination */ +#define STLES 45 /* LAN Emulation Server */ +#define STBUS 46 /* LAN Emulation Broadcast Server */ + +/* used by mtp level 3 */ + +#define STDLSAPACT 47 /* data link SAP - initial state = ACTIVE */ +#define STDLSAPDIS STDLSAP /* data link SAP - initial state = DISABLED */ +#define STTFCMTRC 49 /* traffic metrics */ +#define STPNNBR 50 /* PNNI Neighbor */ +#define STPNPTSE 51 /* PNNI PTSE */ +#define STLECS 52 /* LECS */ +#define STLECSLES 53 /* LECS LES */ +#define STLECSROUT 54 /* LECS ROUT */ +#define STERR 55 /* Software Error */ + +#define STMAP 56 /* map */ +#define STMAPNODE 57 /* node map */ +#define STRCC 58 /* Routing Control Channel */ +#define STRTEADDR 59 /* route to address */ +#define STRTENODE 60 /* route to node */ +#define STRTETNS 61 /* route to transit network */ +#define STRTETBL 62 /* routing table */ +#define STPNPG 63 /* PNNI PEER GROUP */ +#define STLINK 64 /* ATM Physical Link */ +#define STINFOGRP 65 /* information group */ + +#define STNISAP 66 /* FR-ATM network interworking sap */ +#define STSISAP 67 /* FR-ATM service interworking sap */ +#define STPROF 68 /* FR-ATM aal connection's profile */ +#define STNETPFX 69 /* network prefix */ +#define STUSRPART 70 /* user part */ +#define STADDR 71 /* address */ +#define STSRVC 72 /* service registry */ +#define STCIPSAP 73 /* PLOA's CIPSAP */ + +/* define for Envelope Function EFadr mapping */ +#define STEVEFADR 74 /* EV EFadr to SAP mapping */ + +/* Used by PNNI for horizontal link hello protocol and summary addresses */ +#define STHLHP 75 /* Horizontal link hello protocol */ +#define STSUMMADDR 76 /* Summary addresses */ + +/* used by LEC for static ARP entry */ +#define STSTAARP 77 /* static ARP entry */ + +/* used by PQ for TDM Configuration */ +#define STTDM 78 /* TDM Configuration */ + + +/* Used by LES */ +#define STLECSMPOATLV 79 /* LECS MPOA TLV entry */ + +#define STMPCCP 80 /* PLOA's MPC Control Point */ +#define STMPSAP 81 /* PLOA's MPC/MPS SAP */ +#define STMPSCP 82 /* PLOA's MPS Control Point */ + +/* used for group saps */ +#define STGRTSAP 85 /* transport sap group */ +#define STGRNSAP 86 /* netwrok sap group */ +#define STGRDLSAP 87 /* data link sap group */ +#define STALLSAP 88 /* all upper/lower SAPs */ +#define STPEERSAP 89 /* configure peer sap */ + +/* Used by V5 */ +#define STVINTERFACE 83 /* V5 Interface */ +#define STVPORT 84 /* V5 port */ +#define STVLINK 85 /* V5 Link */ + +/* Used by PLOA-CIP */ +#define STCIPPVC 86 /* PLOA Cfg. request to configure some + more PVC on the fly */ +#define STCIPARP 87 /* PLOA Cfg. request to configure some + extra IP-ATM binding on the fly */ + + +/* used by Q.93B for AalConParam of signaling channels */ +#define STSIGCONPARAM 90 /* config Signaling connection parameters */ +#define STDELSIGPARAM 91 /* Delete Signaling connection parameters */ + +/* used by System Manager */ +#define STVPROC 92 /* Configure virtual node */ +#define STPPROC 93 /* Configure physical node */ +#define STASSOC 94 /* Configire association between vnodes */ + /* and layers */ + +/* used by TCAP over TCP/IP */ +#define STSERVER 95 /* configure TCP/UDP server */ + +/* Used by Lan Emulation Services */ +#define STLECSTLV 96 /* PLOA LECS TLVs */ +#define STLESLEC 97 /* PLOA LEC in LES database */ +#define STLESSMS 98 /* PLOA Multicast Server Known to LES */ +#define STLESLECSMS 99 /* PLOA LEC assoc. with SMS */ +#define STBUSLEC 100 /* PLOA LEC in BUS Database */ +#define STSMS 101 /* PLOA LANE Selective M-cast Server */ +#define STSMSGRP 102 /* PLOA SMS Multicast Group */ +#define STSMSLEC 103 /* PLOA LEC Associated with SMS */ + +/* used by PLOA - PPPoA */ +#define STMASAP 104 /* POOA MASAP - PPPoA upper SAP */ + +/* Used By PNNI */ +#define STTFCMTRCNODE 105 /* configure metrics of the lowest level + / * node */ +#define STNHSSAP 106 /* PLOA NHS SAP */ +#define STMPSDISCTBL 107 /* PLOA MPS */ +#define STMPSINGRTBL 108 /* PLOA MPS */ +#define STMPSEGRTBL 109 /* PLOA MPS */ +#define STARISAP 110 /* PLOA ARI Sap */ + +#define STNHSCP 111 /* PLOA NHS */ +#define STNHSNXTHOP 112 /* PLOA NHS */ +#define STNHSTRCACHE 113 /* PLOA NHS */ +#define STNHSEXTNS 114 /* PLOA NHS */ +#define STNHSEGRCACHE 115 /* PLOA NHS */ +#define STNHSVENDATA 116 /* PLOA NHS */ + +/* used by H.323 Control */ +#define STSSAP 117 /* H.323 Session SAP element */ +#define ST323ENT 118 /* H323 entity element */ +#define STCALL 119 /* H.323 call element */ +#define STGRSSAP 120 /* H.323 group SSAP */ + +/* used by Q.93B for SVPC status */ +#define STVPC 121 /* Switched virtual path */ + +#define STCIPSRVR 122 /* PLOA CIP Server */ + +/* used by RTP/RTCP */ +#define STSESSION 123 /* RTP session */ + +/* Used by Q.930 */ +#define STCTLDPCB 124 /* Configure controlled interface */ + +#define STGCPENT 125 /* MGCP peer entity */ + +/* Used by SCCP */ +#define STNW 126 /* Network */ +#define STASSO 127 /* SCCP GTT Association */ +#define STDELASSO 128 /* SCCP Delete GTT Association */ + +/* Used by IME auto configuration of PVCs */ +#define STSRVCTYPE 129 /* service type */ +#define STSRVCCONNINFO 130 /* service connection info */ +#define STAALPROFILE 131 /* AAL[x] profiles; x = 1, 2, 34, 5 */ + +/* used by MPLS-LDP (+CR) */ +#define STPEER 132 /* LDP Peer */ +#define STFEC 133 /* MPLS FEC */ +#define STEXPRTE 134 /* CR-LDP Explicit Route */ +#define STRMSAP 135 /* LDP RM SAP */ +#define STINT 136 /* LDP Interface */ +#define STROUTSAP 137 /* LDP ARI SAP */ +#define STFWDSAP 138 /* LDP Forwarder SAP */ +#define STSESS 139 /* LDP Session */ +#define STADDRESS 140 /* LDP Address */ + +/* used by AAL2 Signaling */ +#define STALTSAP 141 /* AAL2 Service user */ +#define STSNTSAP 142 /* MTP3B SAP */ +#define STGRALTSAP 143 /* ALT Group */ +#define STGRSNTSAP 144 /* SNT Group */ +#define STPATH 145 /* AAL2 path */ +#define STDPC 146 /* DPC - MTP3B */ + +/* used by Annex G */ +#define STBE 147 +#define STGRBESAP 148 +#define STTPTSRV 149 +#define STDESC 150 +/* used by PLOA-PXY */ +#define STPXYSAP 151 /* PLOA PXY SAP configuration */ +#define STCIPARPENT 152 /* PLOA StaReq & CntrlReq for single arpEnt */ +#define STMACONLST 153 /* PLOA StaReq for list of conns */ +#define STMACON 154 /* PLOA StaReq for single conn */ + + +/* Used by SIP */ +#define STSIPENT 155 /* SIP Entity */ + +/* Used by GCP 1.2 and above */ +#define STGCPMGC 156 /* MGC Entity */ +#define STGCPMG 157 /* MG Entity */ + +/* Used bu HU - H.323 Service User */ +#define STLWRSAP 158 + +/* new elements added in sccp3.2 */ +#define STNIDPC 159 /* NID to DPC mapping */ +#define STNWSS7 160 /* NW specific NID to SS7-NID mapping */ +#define STTRFLIM 161 /* Traffic limitation data config */ +#define STMSGIMP 162 /* Message importance data config */ + +/* new elements for SCCP */ +#define STDELNW 163 /* delete network */ +#define STDELTSAP 164 /* delete transport sap */ +#define STDELNSAP 165 /* delete network sap */ + +/* new elements for 3GPP-RLC */ +#define STCRSAP 166 /* RLC Control SAP */ +#define STRLSAP 167 /* RLC Data SAP */ +#define STMKSAP 168 /* RLC MAC SAP */ + +/* new elements for 3GPP-NBAP */ +#define STNBUSAP 169 /* Upper SAP to NBAP */ +#define STIBPROT 170 /* NBAP Protocol */ + +/* new elements for MPLS-RSVP (+TE) */ +#define STLASAP 171 /* MPLS-Appl. Sap */ +#define STNBR 172 /* RSVP Neighbor */ +#define STRVINT 173 /* RSVP Interface */ +#define STLTSAP 174 /* MPLS Resource Manager SAP */ + +/* new elements for FP */ +#define STCSAP 175 /* FP Control User */ +#define STUSAP 176 /* FP Data User */ +#define STTPTENDP 177 /* SCTP endpoint */ + +/* new elements for LAPDm */ +#define STLSAP 178 +#define STRRSAP 179 +/*gen_h_001.main_127 - incremented values*/ +/* gen_h_001.main_123 - Add new elements for 3GPP-PDCP */ +#define STCTSAP 180 /* PDCP Control SAP */ +#ifndef QC /* gen_h_001.main_136: Fixing compilation warnings */ +#ifndef IE +#define STTCSAP 181 /* PDCP Data SAP */ +#endif +#endif +#define STPDCPENT 182 /* PDCP Entity */ +/*-- gen_h_001.main_130 --*/ +#define STINST 183 /* IuUP Instance */ + +/* gen_h_001.main_134 - lte rlc 2.1 */ +/* elements for LTE-RLC SAPs */ +#define STCKWSAP 184 /*!< RLC Control SAP element. */ +#define STKWUSAP 185 /*!< RLC Data SAP element. */ +#define STRGUSAP 186 /*!< RLC MAC SAP element. */ +/* elements for LTE-PDCP SAPs */ +#define STCPJSAP 187 /*!< PDCP control SAP element. */ +#define STPJUSAP 188 /*!< PDCP control SAP element. */ +#ifdef RM_INTF +#define STRMUSAP 189 /*!< LTE RRM control SAP element. */ +#define STRGMSAP 190 +#endif + +#define STNLUSAP 191 /*!< eNB APP and SON module SAP */ + +/* Mngmt.t.cntrl.action, Mngmt.hdr.elmId.elmntInst1 */ + +#define AENA 1 /* enable */ +#define ADISIMM 2 /* disable - immediately */ +#define ADISGRC 3 /* disable - gracefully */ +#define ARST 4 /* reset */ +#define ADGN 5 /* diagnose */ +#define AADD 6 /* add */ +#define ADEL 7 /* delete */ +#define AINH 8 /* inhibit */ +#define AUNINH 9 /* uninhibit */ +#define ASPRST 10 /* signalling point restart */ +#define AACTLNKSET 11 /* activate link set */ +#define ADEACTLNKSET 12 /* deactivate link set */ +#define AVAL 13 /* validate circuit */ +#define AFLCON 14 /* flow control on */ +#define AFLCOFF 15 /* flow control off */ +#define ACLEAR 16 /* clear */ +#define ASTRTLL 17 /* start local loop */ +#define AENDLL 18 /* end local loop */ +#define ACTION_DROP 19 /* action - drop */ +#define ACTION_NO_DROP 20 /* action - no drop */ +#define ABND_ENA 21 /* bind and enable */ +#define ARSTVCC 22 /* restart a virtual channel connection */ +#define ARSTVPC 23 /* restart a virtual path connection */ + +/* actions for LsaCntrlReq (q.2140) */ + +#define AFORCE_PRV 24 /* Force Proving */ +#define AFORCE_EM 25 /* Force Emergency */ +#define ACLR_FORCE_MD 26 /* Clear Force Mode */ +#define ACTION_LPO 27 /* Local Processor Outage */ +#define ACTION_LPR 28 /* Local Processor Recovered */ +#define APRV_UNS 29 /* Proving Unsuccessful Response */ + +#define ABND 30 /* bind */ +#define AUBND 31 /* disable + unbind */ +#define AUBND_DIS AUBND /* unbound disable */ + + +/* actions for mtp3 */ + +#define ADELROUT 32 /* delete rout control block */ +#define ADELLNKSET 33 /* delete all linkset control blocks, link control blocks + for a given linkset id */ +#define ADELCMBLNKSET 34 /* delete linkset control block for a given combined linkset id */ +#define ADELLNK 35 /* delete link control block */ +#define ASHUTDOWN 36 /* shutdown the layer */ +#define ATRAP 37 /* trap */ +#define AGEN_STA 38 /* generate status indications -MSOC */ + +/* actions for fault tolerance */ +#define AGO_ACT 38 /* go active */ +#define AGO_SBY 39 /* go standby */ +#define AWARMSTART 40 /* start warm start */ +#define AABORT 41 /* abort warm start or controlled sw */ +#define ASYNCHRONIZE 42 /* start controlled switchover */ +#define ANOACT 43 /* null action (nop) */ +#define AHOLDQUEUE 44 /* hold queue, for the message router */ +#define ARLSQUEUE 45 /* hold queue, for the message router */ +#define APEER_PING 46 /* peer ping, for peer system agent */ +#define ADIS_PEER_SAP 47 /* enable/disable peer sap */ +#define AGEN_FAULT 48 /* fault injection action */ +#define AAUDIT 49 /* Perform Audits on the layer */ +#define ADISIMM_L2 50 /* Disable Layer 2 only */ +#define ADEACTLNKSET_L2 51 /* deactivate link set: all links should be deactivated + only at L2 level */ +#define AGEN_MSG 52 /* message generation control action */ + +/* For PLOA */ +#define ASNDTRIGG 53 /* Generate Flow detection trigger */ + +#define AXIDINI 54 /* GPRS: start XID initialization */ +#define APMLEN 55 /* GPRS: change the N202 value of + an LLC link */ +/* For Q.930/Q.931 */ +#define AADD_BCHAN 56 /* Provision B Channel */ +#define ADEL_BCHAN 57 /* De-Provision B Channel */ +#define AMOOS 58 /* Put the D-Channel MOOS State */ +#define ASRVMSG_ON 59 /* Turn on service message capability */ +#define ASRVMSG_OFF 60 /* Turn off service message capability */ +#define ARESTART 61 /* Restart Interface/Channel */ + +/* For TCR 0004.01 */ +#define AMODIFY 62 /* Modify trace length */ + +/* For AAL2 Signaling */ +#define ASTOPRST 63 /* Stop Reset procedure */ +#define ABLK 64 /* Block Procedure - AAL2 */ +#define AUBLK 65 /* unblock procedure */ + +/* For GCP 1.2 */ +#define AHANDOFF 66 /* Handoff procedure */ +#define AMATEDCFG_ADD 67 /* Configure MG as mated pair */ +#define AMATEDCFG_RMV 68 /* Disassociate two MGs which were in a mated + pair cfg */ +#define AFAILOVER 69 /* Failover Procedure */ +/* For SIP */ +#define AADD_ASSOC_TPTSRV 70 /* Add transport server association */ +#define ADEL_ASSOC_TPTSRV 71 /* Delete transport server association */ + +/* for SCCP congestion control (sccp3.2) */ +#define ACONG 72 /* congestion cntrl - start sending SSC */ +/* For OAM */ +#define ASTRTOAMLL 72 /* OAM Start Loopback */ +#define AENDOAMLL 73 /* OAM End Loopback */ +#define ASTRTPMG 74 /* OAM Start Performance Monitoring and Generation */ +#define AENDPMG 75 /* OAM End Performance Monitoring and Generation */ +#define ASTRTPM 76 /* OAM Start Performance Monitoring */ +#define ASTRTPG 77 /* OAM Start Performance Generation */ +#define ASTRTPMLL 78 /* OAM Start PM Loopback of FMC's */ +#define AENDPMLL 79 /* OAM End Performance Generation */ +#define ARSTPM 80 /* OAM Reset counters of PM block */ + +#define AMODABORT 81 /* Abort Modification Request */ +#define AADD_ASSOC_ENDP 82 +#define ADEL_ASSOC_ENDP 83 +/* for support of adding/deleting PC (sccp3.2) */ +/* gen_h_001.main_121 - Support for adding/deleting PC */ +#define AADD_OPC 84 +#define ADEL_OPC 85 +/* gen_h_001.main_126 - Addition - New hash defines start/stop of MTP3 Audit */ +/* gen_h_001.main_127 - changed macro values */ +#define ASTRT_AUDIT 90 +#define ASTOP_AUDIT 91 +#define ASTRT_LNK_AUDIT 92 +#define ASTRT_LNKSET_AUDIT 93 +#define ASTRT_RTE_AUDIT 94 +#define ASTOP_LNK_AUDIT 95 +#define ASTOP_LNKSET_AUDIT 96 +#define ASTOP_RTE_AUDIT 97 + +/* gen_h_001.main_125 - Addition - SUA support*/ +#ifdef LSPV2_8 +#define AADD_ASP 86 +#define ADEL_ASP 87 +#define ADEL_ASPSSN 88 +#define ADEL_ASPCPC 89 +#endif + +/* Added for NBAP to support SCT(SCTP) as lower interface */ +#define AEOPENR 100 +#define AECLOSER 101 +#define AESTABLISH 102 +#define ATERMINATE 103 +#define AHBEAT_ENB_ASSOC 104 +#define AHBEAT_DIS_ASSOC 105 +#define AHBEAT_ENB_DSTADDR 106 +#define AHBEAT_DIS_DSTADDR 107 + +/* Mngmt.t.cntrl.subAction */ + +#define SAELMNT 1 /* specified element */ +#define SAACNT 2 /* accounting generation */ +#define SAUSTA 3 /* unsolicited status generation */ +#define SATRC 4 /* trace generation */ +#define SADBG 5 /* debugging */ +#ifdef SS_DIAG +/* gen_h_001.main_142:Added subaction SALOG */ +#define SALOG 6 /* logging */ +#endif + +/* grouping criteria's will be filled in subaction fields */ + +#define SAGR_DSTPROCID 6 /* group on dstProcId */ +#define SAGR_ROUTE 7 /* group on routes */ +#define SAGR_PRIORITY 8 /* group on priority */ +#define SAENA_PEER_SAP 9 /* enable peer sap */ +#define SADIS_PEER_SAP 10 /* disable peer sap */ +#define SAAUD 11 /* Audit */ +/* For GCP 1.2 */ +#define SADNS 12 /* Enable /Disable DNS Access*/ + +/* for SCCP traffic limitation mechanism and error report (sccp3.2) */ +#define SATRFLIM 13 /* traffic limitation mechanism */ +#define SAREPORT 14 /* sccp error perfroamce report */ + +#define SAGR_GENERIC_MAX 20 /* max on subactions to be defined in gen.h */ + +/* Subactions required for H.323 user layer (HU) */ +#define HU_RUNREQ 12 /* run a test case */ +#define HU_PROCEEDREQ 13 /* resume operation with a test case */ + +/* Mngmt.t.mib.opCode */ +#define MIBOPCODEBASE 1000 /* Base for non standard opCode values */ +#define MIB_REQUEST_GET 0 /* GET request for reading mib variable*/ +#define MIB_REQUEST_GET_NEXT 1 /* GET-NEXT request to read + lexicographically next mib variable*/ +#define MIB_REQUEST_SET 3 /* Assign mib variable a value */ + +/* Mngmt.t.mib.status */ +#define MIBSTATUSBASE 1000 /* Base for non standard status values */ +#define MIB_SUCCESS 0 /* Mib request successfully completed */ +#define MIB_NOSUCHNAME 2 /* no such name */ +#define MIB_INVALID_IDX (MIBSTATUSBASE + 1) /* Index to the row-column + * of mib table invalid */ +#define MIB_INVALID_OPCODE (MIBSTATUSBASE + 3) /* OpCode is not one of the + * above defined*/ +#define MIB_END_ALL_TABLES (MIBSTATUSBASE + 4) /* End of the table reached + * in get next */ +#define MIB_SUCCESS_NEXT_AVL_OBJ (MIBSTATUSBASE + 6) /* returning object from + * a different table than + * before */ + +/* Mngmt.t.trc.evnt */ + +#define TL1FRMRX 0 /* layer 1 - frame received */ +#define TL1FRMTX 1 /* layer 1 - frame transmitted */ +#define TL2FRMRX 2 /* layer 2 - frame received */ +#define TL2FRMTX 3 /* layer 2 - frame transmitted */ +#define TL2TMR 4 /* layer 2 - timer expired */ +#define TL3PKTRX 5 /* layer 3 - frame received */ +#define TL3PKTTX 6 /* layer 3 - frame transmitted */ +#define TL3TMR 7 /* layer 3 - timer expired */ +#define TL7FRMRX 8 /* layer 7 - frame received */ +#define TL7FRMTX 9 /* layer 7 - frame transmitted */ +#define TL7TMR 10 /* layer 7 - timer expired */ +#define TL5MSGTX 11 /* layer 5 - message transmitted */ +#define TL5MSGRX 12 /* layer 5 - message received */ + +/* defines for MxxStsReq */ + +#define ZEROSTS 0 /* zero statistics counters */ +#define NOZEROSTS 1 /* dont zero statistics counters */ + +/* defines for MxxCfgReq */ + +#define THRSHA 0 /* 00% resources available */ + /* scc drops frames */ +#define THRSHB 1 /* 10% resources available */ + /* lapb and lapd send rnr frames */ +#define THRSHC 2 /* 20% resources available */ + /* lapb and lapd send rr frames */ +#define THRSHD 3 /* 30% resources available */ + /* x.25 es and x.25 is send reset packets */ +#define THRSHE 4 /* 40% resources available */ + /* x.25 es and x.25 is send clear packets */ + /* to call packets */ +#define LSAP 1 /* Link Level SAP Type */ +#define XTSAP 2 /* Transport SAP Type */ + +#ifdef IGNORE +#undef IGNORE +#define IGNORE 0 /* Ignore SAP Type */ +#else +#define IGNORE 0 /* Ignore SAP Type */ +#endif /* IGNORE */ + +#define X25LINK 0 /* X25 Link */ +#define X75LINK 1 /* X75 Link */ + +#define USER 0 /* acts as user */ +#define NETWORK 1 /* acts as network */ +#define SYM_USER 2 /* acts as symmetrical user */ + +/* defines for MxxStaInd */ + +#define ENTR_CONG 1 /* event - entering congst */ +#define EXIT_CONG 2 /* event - exiting congest */ +#define PROT_ST_UP 3 /* event - link up */ +#define PROT_ST_DN 4 /* event - link down */ +#define PROT_ERR 5 /* event - protocol error */ +#define INV_REM 6 /* event - invalid remove */ +#define LINK_ALIGNED 7 /* event - mtp 2 - link alignment */ +#define ALIGN_LOST 8 /* event - mtp 2 - alignment lost */ +#define ELEC_DOWN 9 /* event - scc - electrical interface down */ +#define ELEC_UP 10 /* event - scc - electrical interface up */ +#define REG_DOWN 11 /* event - mos - memory region down */ +#define REG_UP 12 /* event - mos - memory region up */ +#define INH_DEN 13 /* event - link inhibit denied */ +#define INH_ACK 14 /* event - link inhibited */ +#define UNINHED 15 /* event - link uninhibited */ +#define UNINH_DEN 16 /* event - link uninhibit denied */ +#define CONG_LVL_1 17 /* event - congestion level 1 */ +#define CONG_LVL_2 18 /* event - congestion level 2 */ +#define CIR_OUT_ORD 19 /* event - cirquit out of order */ +#define CIRMGT_NORESP 20 /* event - no response to cirquit management message */ +#define CIR_INVAL 21 /* event - invalid circuit */ +#define CIR_VAL_FAIL 22 /* event - circuit validation failure */ +#define CIR_VAL_SUCC 23 /* event - circuit validation success */ +#define CIC_INVAL 24 /* event - invalid cic code */ +#define CONT_FAIL 25 /* event - continuity failed */ +#define CIR_UNEQUIP 49 /* event - circuit unequipped */ +#define RMT_BLKD 50 /* event - link remotely blocked */ +#define RMT_UNBLKD 51 /* event - link remotely unblocked */ +#define CIR_IN_SERV 52 /* event - circuit back in service */ +#define TERM_INIT_FAIL 53 /* event - terminal initialization failed */ +#define ERROR_LOG 54 /* event - software error logged */ + +#define INV_EVENT (ERROR_LOG + 1) /* event - invalid */ + +/* ss7 switch defines */ + +/* #define SW_TST 0 switch - test */ +#define SW_CCITT 1 /* switch - ccitt */ +#define SW_ITU 1 /* switch - itu-t */ +#define SW_CCITT88 1 /* switch - ccitt 88 */ +#define SW_ANSI 2 /* switch - ansi */ +#define SW_ANSI88 2 /* switch - ansi 88 */ +#define SW_ANSI92 3 /* switch - ansi 92*/ +#define SW_CCITT92 4 /* switch - ccitt 92 */ +#define SW_SINGTEL 4 /* switch - singapore telecom */ +#define SW_Q767 5 /* switch - int'l isup q.767 */ +#define SW_CHINA 6 /* switch - china */ + +/* for sccp3.2 */ +#define SW_JAPAN 7 /* switch - japan */ + + +#ifndef CMFILE_REORG_1 + +/* defines for Q.93B */ + +/* parameter values that are at management and at upper interface */ + +/* switch defines */ + +#define SW_ATMF_UNI30 0 /* switch - ATM Forum UNI v3.0 */ +#define SW_ATMF_UNI31 1 /* switch - ATM Forum UNI v3.1 */ +#define SW_IISP_UNI30 2 /* switch - Interim Inter-Switch Signalling Protocol */ +#define SW_IISP_UNI31 3 /* switch - Interim Inter-Switch Signalling Protocol */ +#define SW_Q2931 4 /* switch - ITU - 2931 */ +#define SW_ATMF_SIG_PNNI 5 /* switch - ATM Forum PNNI Signalling */ +#define SW_ATMF_UNI40 6 /* switch - ATM Forum UNI v4.0 */ +#define SW_ATMF_SIG_AINI 7 /* switch - ATM Forum AINI Signalling */ +#define SW_INVALID 0xff /* switch - invalid value */ + +/* information element id's */ + +#define AM_ME_ETOETRANSDLY 0x42 /* End-to-End Transit Delay */ +#define AM_ME_CONNNMB 0x4c /* Connected number */ +#define AM_ME_CONNSAD 0x4d /* Connected Subaddress */ +#define AM_ME_TFCDESC 0x59 /* ATM Traffic Descriptor */ +#define AM_ME_BHILYRINFO 0x5d /* Broadband High Layer Info */ +#define AM_ME_BLOLYRINFO 0x5f /* Broadband Low Layer Info */ +#define AM_ME_CDPTYNMB 0x70 /* Called Party Number */ +#define AM_ME_CDPTYSAD 0x71 /* Called Party Sub Address */ +#define AM_ME_CDPTYSOFTPVC 0xe0 /* Called party soft PVPC/PVCC */ +#define AM_ME_CRANKBACK 0xe1 /* Crankback */ +#define AM_ME_DSGTRANLST 0xe2 /* Designated Transit list */ +#define AM_ME_CGPTYSOFTPVC 0xe3 /* Calling party soft PVPC/PVCC */ +#define AM_ME_MINACCTFCDESC 0x81 /* Minimum Acceptable Tfc. Desc. */ +#define AM_ME_ALTTFCDESC 0x82 /* Alternative ATM Tfc. Desc. */ +#define AM_ME_ABRSETUPPARAM 0x84 /* ABR Setup Parameters */ +#define AM_ME_ABRADDPARAM 0xe4 /* ABR Additional Parameters */ +#define AM_ME_EXTQOSPARAM 0xec /* Extended Qos Parameter */ + +/* information element idx's */ + +#define AM_MEI_TFCDESC 0x06 /* ATM Traffic Descriptor */ +#define AM_MEI_BHILYRINFO 0x09 /* Broadband High Layer Info */ +#define AM_MEI_BLOLYRINFO 0x0b /* Broadband Low Layer Info */ +#define AM_MEI_CDPTYNMB 0x12 /* Called Party Number */ +#define AM_MEI_CDPTYSAD 0x13 /* Called Party Sub Address */ +#define AM_MEI_CRANKBACK 0x1f /* Crankback */ +#define AM_MEI_CDPTYSOFTPVC 0x20 /* Called Party Soft PVPC/PVCC */ +#define AM_MEI_CONNNMB 0x21 /* Connected number */ +#define AM_MEI_CONNSAD 0x22 /* Connected sub address */ +#define AM_MEI_DSGTRANLST 0x23 /* Designated Transit List */ +#define AM_MEI_CGPTYSOFTPVC 0x34 /* Calling Party Soft PVPC/PVCC */ +#define AM_UNKNOWN 0xfe /* message type unknown */ + +/* addressing related defines */ + +/* numbering plan identification */ + +#define AM_NMBPLN_UNK 0x00 /* unknown */ +#define AM_NMBPLN_ISDN 0x01 /* ISDN/telephony numbering plan (E.164) */ +#define AM_NMBPLN_NSAP 0x02 /* ISO NSAP */ +#define AM_NMBPLN_PVT 0x09 /* private */ + + +/* ATM address types */ + +#define ATMADDR_TYPE_E164 AM_NMBPLN_ISDN /* E.164 format */ +#define ATMADDR_TYPE_AESA AM_NMBPLN_NSAP /* ATM forum AESA format */ + +/* maximum size of VCC table */ +#define MAX_ATMVCCTBL_SZ 16 + +/* maximum number of ATM addresses in the ATM address table */ +#define MAX_ATMADDRTBL_SZ 4 + +/* type of number */ + +#define AM_TYPNMB_UNK 0x00 /* unknown */ +#define AM_TYPNMB_INT 0x01 /* international */ +#define AM_TYPNMB_NAT 0x02 /* national */ +#define AM_TYPNMB_NSP 0x03 /* network specific */ +#define AM_TYPNMB_SUB 0x04 /* subscriber number */ +#define AM_TYPNMB_ABR 0x06 /* abbreviated */ + +/* screening indicator */ + +#define AM_SCRIND_USRNOTSCR 0x00 /* user provided, not screened */ +#define AM_SCRIND_USRVERPASS 0x01 /* user provided, verified and passed */ +#define AM_SCRIND_USRVERFAIL 0x02 /* user provided, verified and failed */ +#define AM_SCRIND_NET 0x03 /* network provided */ + +/* presentation indicator */ + +#define AM_PRSIND_ALLOW 0x00 /* presentation allowed */ +#define AM_PRSIND_RESTRICT 0x01 /* presentation restricted */ +#define AM_PRSIND_NOTAVAIL 0x02 /* number not available */ + +/* odd/even indicator */ + +#define AM_OEIND_EVEN 0x00 /* even */ +#define AM_OEIND_ODD 0x01 /* odd */ + +/* type of subaddress */ + +#define AM_TYPSAD_NSAP 0x00 /* NSAP */ +#define AM_TYPSAD_USER 0x01 /* user specified - ATM Endsystem addr */ +#define AM_TYPSAD_USERSPEC 0x02 /* user specified */ + +/* authority and format identifiers for OSI NSAP addresses */ + +/* AFI for individual address */ +#define AFI_DCC 0x39 /* BCD format for ISO DCC */ +#define AFI_ICD 0x47 /* BCD format for ISO ICD */ +#define AFI_E164 0x45 /* BCD format for E.164 */ + +/* AFI for group addresses */ +#define AFI_GRP_DCC 0xBD /* BCD format for ISO DCC */ +#define AFI_GRP_ICD 0xC5 /* BCD format for ISO ICD */ +#define AFI_GRP_E164 0xC3 /* BCD format for E.164 */ + +/* low layer information - layer 2 id */ + +#define AM_LLI_L2ID 2 /* layer 2 id */ + +/* low layer information - layer 2 protocol */ + +#define AM_LLI_L2PROT_ISO1745 0x01 /* basic mode ISO 1745 */ +#define AM_LLI_L2PROT_Q921 0x02 /* CCITT Rec. Q.921 */ +#define AM_LLI_L2PROT_X25LNK 0x06 /* CCITT Rec. X.25, link layer */ +#define AM_LLI_L2PROT_X25MLNK 0x07 /* CCITT Rec. X.25, multilink */ +#define AM_LLI_L2PROT_LAPB 0x08 /* extended LAPB (half duplex) */ +#define AM_LLI_L2PROT_HDLC_ARM 0x09 /* HDLC ARM (ISO 4335) */ +#define AM_LLI_L2PROT_HDLC_NRM 0x0a /* HDLC NRM (ISO 4335) */ +#define AM_LLI_L2PROT_HDLC_ABM 0x0b /* HDLC ABM (ISO 4335) */ +#define AM_LLI_L2PROT_LLC 0x0c /* LAN LLC (ISO 8802/2) */ +#define AM_LLI_L2PROT_X75SLP 0x0d /* CCITT Rec. X.75 SLP */ +#define AM_LLI_L2PROT_Q922 0x0e /* CCITT Rec. Q.922 */ +#define AM_LLI_L2PROT_USER 0x10 /* user specified */ +#define AM_LLI_L2PROT_ISO7776 0x11 /* ISO 7776 DTE-DTE operation */ + +/* low layer information - layer 2 mode of operation */ + +#define AM_LLI_L2MODE_NORMAL 1 /* normal mode of operation */ +#define AM_LLI_L2MODE_EXT 2 /* extended mode of operation */ + +/* low layer information - layer 2 Q.933 use */ + +#define AM_LLI_L2Q933_USE 0 /* when Rec. Q.933 coding not used */ + +/* low layer information - layer 3 id */ + +#define AM_LLI_L3ID 3 /* layer 3 id */ + +/* low layer information - layer 3 protocol */ + +#define AM_LLI_L3PROT_X25PKT 0x06 /* CCITT Rec. X.25, packet layer */ +#define AM_LLI_L3PROT_ISO8208 0x07 /* ISO/IEC 8208 */ +#define AM_LLI_L3PROT_ISO8878 0x08 /* X.223/ISO 8878 */ +#define AM_LLI_L3PROT_ISO8473 0x09 /* ISO/IEC 8473 */ +#define AM_LLI_L3PROT_T70 0x0a /* CCITT Rec. T.70 */ +#define AM_LLI_L3PROT_ISO9577 0x0b /* ISO/IEC TR 9577 */ +#define AM_LLI_L3PROT_USER 0x80 /* user specified */ + +/* low layer information - layer 3 mode of operation */ + +#define AM_LLI_L3MODE_NORMAL 1 /* normal packet sequence numbering */ +#define AM_LLI_L3MODE_EXT 2 /* extended packet sequence numbering */ + +/* low layer information - layer 3 default packet size */ + +#define AM_LLI_L3PKTSIZE_16 0x04 /* default packet size 16 octets */ +#define AM_LLI_L3PKTSIZE_32 0x05 /* default packet size 32 octets */ +#define AM_LLI_L3PKTSIZE_64 0x06 /* default packet size 64 octets */ +#define AM_LLI_L3PKTSIZE_128 0x07 /* default packet size 128 octets */ +#define AM_LLI_L3PKTSIZE_256 0x08 /* default packet size 256 octets */ +#define AM_LLI_L3PKTSIZE_512 0x09 /* default packet size 512 octets */ +#define AM_LLI_L3PKTSIZE_1024 0x0a /* default packet size 1024 octets */ +#define AM_LLI_L3PKTSIZE_2048 0x0b /* default packet size 2048 octets */ +#define AM_LLI_L3PKTSIZE_4096 0x0c /* default packet size 4096 octets */ + +/* low layer information - layer 3 ISO/IEC TR 9577 Initial Protocol Id */ + +/* ec005.12: corrected value */ +#define AM_LLI_ISO9577_IPI_SNAP 0x80 /* IPI - SNAP */ +#define AM_LLI_ISO9577_IPI_IP 0xCC /* IPI - Internet Protocol */ + +/* low layer information - layer 3 SNAP Id */ + +#define AM_LLI_SNAP_ID 0x00 /* SNAP id */ + +/* high layer information type */ + +#define AM_HLITYP_ISO 0x00 /* ISO */ +#define AM_HLITYP_USR 0x01 /* user specific */ +#define AM_HLITYP_HLPROF 0x02 /* high layer profile */ +#define AM_HLITYP_APPID 0x03 /* vendor-specific application id */ +#define AM_HLITYP_BISDN 0x04 /* reference to ITU-T SG1 B-ISDN teleservice recommendation */ + +/* ABR Additional parameter identifiers */ + +#define AM_AAP_FAPR_ID 0xC2 /* forward additional parameter record identifier */ +#define AM_AAP_BAPR_ID 0xC3 /* forward additional parameter record identifier */ + +/* Extended QOS parameter identifiers */ + +#define AM_EQP_AFPCDV_ID 0x94 /* acceptable forward peak-to-peak cell delay variation identifier */ +#define AM_EQP_ABPCDV_ID 0x95 /* acceptable backward peak-to-peak cell delay variation identifier */ +#define AM_EQP_CFPCDV_ID 0x96 /* cumulative forward peak-to-peak cell delay variation identifier */ +#define AM_EQP_CBPCDV_ID 0x97 /* cumulative backward peak-to-peak cell delay variation identifier */ +#define AM_EQP_AFCLR_ID 0xA2 /* acceptable forward cell loss ratio identifier */ +#define AM_EQP_ABCLR_ID 0xA3 /* acceptable backward cell loss ratio identifier */ + +/* Extended QOS parameter origin token values */ + +#define AM_EQP_ORG_USR 0x00 /* originating user */ +#define AM_EQP_ORG_INTNET 0x01 /* intermediate network */ + +/* ABR Setup parameter identifiers */ + +#define AM_ASP_FAICR_ID 0xC2 /* forward ABR initial cell rate identifier */ +#define AM_ASP_BAICR_ID 0xC3 /* backward ABR initial cell rate identifier */ +#define AM_ASP_FATBE_ID 0xC4 /* forward ABR transient buffer exposure identifier */ +#define AM_ASP_BATBE_ID 0xC5 /* backward ABR transient buffer exposure identifier */ +#define AM_ASP_CRMFRTT_ID 0xC6 /* cumulative RM fixed round trip time identifier */ +#define AM_ASP_FRIF_ID 0xC8 /* forward rate increment factor identifier */ +#define AM_ASP_BRIF_ID 0xC9 /* backward rate increment factor identifier */ +#define AM_ASP_FRDF_ID 0xCA /* forward rate decrement factor identifier */ +#define AM_ASP_BRDF_ID 0xCB /* backward rate decrement factor identifier */ + +/* ATM Transfer capability */ + +#define AM_ATC_NRTVBR1 0x00 /* Non-real time VBR */ +#define AM_ATC_RTVBR1 0x01 /* Real time VBR */ +#define AM_ATC_NRTVBR2 0x02 /* Non-real time VBR */ +#define AM_ATC_CBR1 0x04 /* CBR */ +#define AM_ATC_CBR2 0x05 /* CBR */ +#define AM_ATC_CBR3 0x06 /* CBR */ +#define AM_ATC_CBRCLR 0x07 /* CBR with CLR commitment on CLP=0+1 */ +#define AM_ATC_NRTVBR3 0x08 /* Non-real time VBR */ +#define AM_ATC_RTVBR2 0x09 /* Real time VBR */ +#define AM_ATC_NRTVBR4 0x0A /* Non-real time VBR */ +#define AM_ATC_NRTVBRCLR 0x0B /* Non-real time VBR with CLR commitment on CLP=0+1 */ +#define AM_ATC_ABR 0x0C /* ABR */ +#define AM_ATC_RTVBRCLR 0x13 /* Real time VBR with CLR commitment on CLP=0+1 */ + + +/* defines for UME */ + +#define UM_MAXLEN_OBJ_ID 34 /* max length of an object-id */ + +/* PNNI qos class definitions + */ +#define PN_QOS_CLASS_UBR 0 /* unspecified */ +#define PN_QOS_CLASS_CBR 1 /* constant bit rate */ +#define PN_QOS_CLASS_VBR_RT 2 /* variable bit rate - real time */ +#define PN_QOS_CLASS_VBR_NRT 3 /* variable bit rate - non real time */ +#define PN_QOS_CLASS_ABR 4 /* available bit rate */ + +/* maximum number of ports per neighbor -- change if you expect more + */ +#define PN_MAX_PORTS_NBR 5 + +/* Peer group and node identifier length */ +#define PN_PGID_LEN 14 +#define PN_NODEID_LEN 22 + +/* maximum number of qos classes */ +#define PN_NUM_QOS_CLASSES 5 + +/* defines for PNNI */ + +#define SW_ATMF_RTE_PNNI1 0 /* PNNI Phase 1 */ + +/* OAM Traffic Descriptor */ + +#define AM_OTD_NUSRORGFMI 0x00 /* No user originated fault mgmt ind. */ +#define AM_OTD_USRORGFMI 0x01 /* user originated fault mgmt ind. */ + +#define AM_OTD_OAMF5OPT 0x00 /* The use of end-to-end OAM F5 Flow is optional +*/ +#define AM_OTD_OAMF5MAND 0x01 /* The use of end-to-end OAM F5 Flow is mandatory + */ + +#define AM_OTD_NUSRSHAPEREQ 0X00 /* No user req. on shaping by network */ + +#define AM_OTD_NAGGUSRSHAPE 0X01 /* Aggregate shaping not allowed */ + +#define AM_OTD_ETOEF5_0 0X00 /* 0% of FPCR/BPCR (CLP=0+1) */ +#define AM_OTD_ETOEF5_01 0x01 /* 0.1% of FPCR/BPCR (CLP=0+1) */ +#define AM_OTD_ETOEF5_1 0x04 /* 1% of FPCR/BPCR (CLP=0+1) */ + +#endif /* CMFILE_REORG_1 */ + +/* degines for management confirms */ + +/* status */ +#define LCM_PRIM_OK 0 /* OK , activity completed */ +#define LCM_PRIM_NOK 1 /* NOK, activity completed */ +#define LCM_PRIM_OK_NDONE 2 /* OK, activity not completed */ + +/* reason */ +#define LCM_REASON_NOT_APPL 0 /* not applicable */ +#define LCM_REASON_INVALID_ENTITY 1 /* invalid entity */ +#define LCM_REASON_INVALID_INSTANCE 2 /* invalid instance */ +#define LCM_REASON_INVALID_MSGTYPE 3 /* invalid message type */ +#define LCM_REASON_MEM_NOAVAIL 4 /* memory not avail */ +#define LCM_REASON_INVALID_ELMNT 5 /* invalid hdr.elmnt */ +#define LCM_REASON_RECONFIG_FAIL 6 /* reconfiguration */ +#define LCM_REASON_REGTMR_FAIL 7 /* timer registration failed */ +#define LCM_REASON_GENCFG_NOT_DONE 8 /* gene config not done */ +#define LCM_REASON_INVALID_ACTION 9 /* invalid control action */ +#define LCM_REASON_INVALID_SUBACTION 10 /* invalid control subaction */ +#define LCM_REASON_INVALID_STATE 11 /* invalid state */ +#define LCM_REASON_INVALID_SAP 12 /* invalid sap identifier */ +#define LCM_REASON_INVALID_PAR_VAL 13 /* invalid parameter value */ +#define LCM_REASON_QINIT_FAIL 15 /* queue initialization failed */ +#define LCM_REASON_NEG_CFM 16 /* negative confirmation */ +#define LCM_REASON_UPDTMR_EXPIRED 17 /* update timer expired */ +#define LCM_REASON_MISC_FAILURE 18 /* miscellaneous failures */ +#define LCM_REASON_EXCEED_CONF_VAL 19 /* Exceeds configured value */ +#define LCM_REASON_HASHING_FAILED 20 /* Hashing failed */ +#define LCM_REASON_PEERCFG_NOT_DONE 21 /* swft -peer sap not configured */ +#define LCM_REASON_PRTLYRCFG_NOT_DONE 22 /* swft -portable lyr not configured */ +/* common Distributed FT/HA related failure reasons */ +#define LCM_REASON_INV_RSET 23 /* Inv. rset */ +#define LCM_REASON_INV_RSET_RANGE 24 /* Inv. rset range */ +#define LCM_REASON_INV_RSET_TYPE 25 /* Inv. type of rset type */ +#define LCM_REASON_INV_RSET_QUAL 26 /* Inv. qual. of rset type*/ +#define LCM_REASON_INV_INTERFACE 27 /* Inv. Dist. Fn interface */ +#define LCM_REASON_INV_DIST_TYPE 28 /* Inv. type of dist type*/ +#define LCM_REASON_INV_DIST_QUAL 29 /* Inv. qual. of dist type*/ +#define LCM_REASON_NAK_RCVD 30 /* Got a nak failure */ +#define LCM_REASON_TIMEOUT 31 /* Got a timeout failure */ +#define LCM_REASON_PURE_FTHA 32 /* A req for Dist FTHA is recv + * by a Pure FTHA mod */ +#define LCM_REASON_DIST_FTHA 33 /* A req for Pure FTHA is recv + * by a Dist FTHA mod */ +#define LCM_REASON_INV_KEY 34 /* Invalid key */ +#define LCM_REASON_SW_INCOMP 35 /* enable node fail reason because + * of software interface version + * incompatability */ +#define LCM_REASON_VERSION_MISMATCH 36 /* interface version mismatch */ +#define LCM_REASON_SWVER_NAVAIL 37 /* interface version not found */ +#define LCM_REASON_INVALID_RTENT 38 /* invalid routing entery */ +/* gen_h_001.main_121 - Added LCM_REASONS for reconfiguration of PC at SCCP */ +#define LCM_REASON_MAXSPC_EXCEEDING 39 /* maximum configured SPC's exceeding */ +#define LCM_REASON_WRONG_DEFAULT_SPC 40 /* wrong default spc rcvd in cntrl req */ +#define LCM_REASON_SPC_EXISTS 41 /* spc already exists in the network */ +#define LCM_REASON_MINSPC_REACHED 42 /* network is already reached MINSPC */ +#define LCM_REASON_MORE_SPC_THAN_CONFIGURED 43 /* control request has got more spcs that configured in the network */ +#define LCM_REASON_DFL_SPC_DEL_NOT_ALLOWED 44 /* control request has got default spcs that configured in the network */ +#define LCM_REASON_NOTHING_TO_DELETE 45 /* control request has got zero spcs to delete */ +#define LCM_REASON_SPC_ALREADY_DELETED 46 /* spc's are already deleted */ + +#define LCM_REASON_LYR_SPECIFIC 256 /* protocol specific reasons */ + +/* gen_h_001.main_125- Addition - SUA support*/ +#define LCM_REASON_ASP_CONFIG 47 /* ASP Configuration Error */ +/* gen_h_001.main_142:Added new error type*/ +#define LCM_REASON_ULLOCK_INIT_FAILED 48 /* UL Lock creation Error */ + +/* category */ +#define LCM_CATEGORY_PROTOCOL 1 /* protocol related */ +#define LCM_CATEGORY_INTERFACE 2 /* interface related */ +#define LCM_CATEGORY_INTERNAL 3 /* internal errors */ +#define LCM_CATEGORY_RESOURCE 4 /* system resources */ +#define LCM_CATEGORY_PSF_FTHA 5 /* PSF-Fault tolernace High Av.*/ +#define LCM_CATEGORY_PERF_MONIT 6 /* SCCP Error performance */ +/*gen_h_001.main_137:moved category of states of DNS records to lso.h*/ + +#define LCM_CATEGORY_LYR_SPECIFIC 256 /* protocol specific category */ + +/* events */ +#define LCM_EVENT_UI_INV_EVT 1 /* upper interface invalid event */ +#define LCM_EVENT_LI_INV_EVT 2 /* lower interface invalid event */ +#define LCM_EVENT_PI_INV_EVT 3 /* peer interface invalid event */ +#define LCM_EVENT_INV_EVT 4 /* general invalid event */ +#define LCM_EVENT_INV_STATE 5 /* invalid internal state */ +#define LCM_EVENT_INV_TMR_EVT 6 /* invalid timer event */ +#define LCM_EVENT_MI_INV_EVT 7 /* mngmnt interface invalid event */ +#define LCM_EVENT_BND_FAIL 8 /* Bind failure */ +#define LCM_EVENT_NAK 9 /* destination naked a request */ +#define LCM_EVENT_TIMEOUT 10 /* timeout when waiting for reply */ +#define LCM_EVENT_BND_OK 11 /* bind ok */ +#define LCM_EVENT_SMEM_ALLOC_FAIL 12 /* static memory alloc fail */ +#define LCM_EVENT_DMEM_ALLOC_FAIL 13 /* Dynamic mmemory alloc fail */ +/*Alarms for distributed FTHA environment*/ +#define LCM_EVENT_SEQERR 14 /* seq error (standby) */ +#define LCM_EVENT_OOM 15 /* board mem threshold exceeded */ +#define LCM_EVENT_UPDMSG_ERR 16 /* update message decode error */ +#define LCM_EVENT_HTBT_EXP 17 /* Heartbeat timer expiry */ +#define LCM_EVENT_TRANSLATION_FAILURE 18 /* primitive translation failure */ +/*gen_h_001.main_137:Moved Events for alarm indication at various Dns Events to lso.h*/ + +#define LCM_EVENT_LYR_SPECIFIC 256 /* protocol specific events */ + +/* causes */ +#define LCM_CAUSE_UNKNOWN 0 /* unknown cause - not filled */ +#define LCM_CAUSE_OUT_OF_RANGE 1 /* out of range */ +#define LCM_CAUSE_INV_SAP 2 /* NULL/unknown sap */ +#define LCM_CAUSE_INV_SPID 3 /* invalid service provider */ +#define LCM_CAUSE_INV_SUID 4 /* invalid service user */ +#define LCM_CAUSE_INV_NETWORK_MSG 5 /* invalid network message */ +#define LCM_CAUSE_DECODE_ERR 6 /* message decoding problem */ +#define LCM_CAUSE_USER_INITIATED 7 /* user initiated */ +#define LCM_CAUSE_MGMT_INITIATED 8 /* mgmt initiated */ +#define LCM_CAUSE_INV_STATE 9 /* Invalid state */ +#define LCM_CAUSE_TMR_EXPIRED 10 /* Invalid state */ +#define LCM_CAUSE_INV_MSG_LENGTH 11 /* Invalid state */ +#define LCM_CAUSE_PROT_NOT_ACTIVE 12 /* protocol layer not active */ +#define LCM_CAUSE_INV_PAR_VAL 13 /* invalid parameter value */ +#define LCM_CAUSE_NEG_CFM 14 /* negative confirmation */ +#define LCM_CAUSE_MEM_ALLOC_FAIL 15 /* memory allocation failure */ +#define LCM_CAUSE_HASH_FAIL 16 /* hashing failure */ +#define LCM_CAUSE_VERSION_MISMATCH 17 /* interface version mismatch */ +#define LCM_CAUSE_SWVER_NAVAIL 18 /* intf ver not found */ +#define LCM_CAUSE_DLGFAIL_DUETO_RECOVERY 19 /* dialogue has failed dur to recovery */ +#define LCM_CAUSE_INV_ACTION 20 /* Invalid Control Action */ +/* gen_h_001.main_129 - defined new cause */ +#define LCM_CAUSE_NETWK_INITIATED 21 /* user initiated */ +#define LCM_CAUSE_LYR_SPECIFIC 256 /* protocol specific causes */ + +/* Interface identifier names for rolling upgrade. Each of the product * + * interface is given a unique number */ +/* Layer management interface identifiers */ +#define LMSIF 1 /* MOS stack manager interface ID */ +#define LNSIF 2 /* NTSS stack manager interface ID */ +#define LRYIF 3 /* relay stack manager interface ID */ +#define LAMIF 4 /* Q.93B stack manager interface ID */ +#define LASIF 5 /* Q.SAAL stack manager interface ID */ +#define LPNIF 6 /* PNNI stack manager interface ID */ +#define LACIF 7 /* AC stack manager interface ID */ +#define LECIF 8 /* LEC stack manager interface ID */ +#define LESIF 9 /* LE Services stack manager interface ID */ +#define LUMIF 10 /* UME stack manager interface ID */ +#define LIMIF 11 /* IME stack manager interface ID */ +#define LSAIF 12 /* Q.2140 stack manager interface ID */ +#define LSEIF 13 /* SE stack manager interface ID */ +#define LISIF 14 /* IS stack manager interface ID */ +#define LQIIF 15 /* QI stack manager interface ID */ +#define LPQIF 16 /* PQ stack manager interface ID */ +#define LSDIF 17 /* MTP-2 stack manager interface ID */ +#define LSNIF 18 /* MTP-3 stack manager interface ID */ +#define LSPIF 19 /* SCCP stack manager interface ID */ +#define LSTIF 20 /* TCAP stack manager interface ID */ +#define LIEIF 21 /* INAP stack manager interface ID */ +#define LQCIF 22 /* CAP stack manager interface ID */ +#define LTTIF 23 /* TCAP over TCP/IP stack manager interface ID */ +#define LMAIF 24 /* MAP stack manager interface ID */ +#define LSIIF 25 /* ISUP stack manager interface ID */ +#define LTPIF 26 /* TUP stack manager interface ID */ +#define LSRIF 27 /* MTP-3 Simple Router stack manager interface ID */ +#define LINIF 28 /* Q.930/Q.931 stack manager interface ID */ +#define LXNIF 29 /* network layer - XG, EI, XI, XE stack manager interface ID */ +#define LBDIF 30 /* data link layer- ER, BR, BD, LD, LB stack manager interface ID */ +#define LAPIF 31 /* APAD stack manager interface ID */ +#define LFRIF 32 /* Frame Relay stack manager interface ID */ +#define LMEIF 33 /* data link layer - message exchange stack manager interface ID */ +#define LWDIF 34 /* MTP-2 Wrapper stack manager interface ID */ +#define LWNIF 35 /* MTP-3 Wrapper stack manager interface ID */ +#define LWIIF 36 /* ISUP Wrapper stack manager interface ID */ +#define LWUIF 37 /* TUP Wrapper stack manager interface ID */ +#define LWSIF 38 /* SCCP Wrapper stack manager interface ID */ +#define LWCIF 39 /* TCAP Wrapper stack manager interface ID */ +#define LBIIF 40 /* B-ISUP stack manager interface ID */ +#define LFMIF 41 /* fault manager stack manager interface ID */ +#define LFNIF 42 /* Q933 stack manager interface ID */ +#define LEVIF 43 /* V5 Envelope Function stack manager interface ID */ +#define LLVIF 44 /* LAPV stack manager interface ID */ +#define LNVIF 45 /* V5.1 PSTN stack manager interface ID */ +#define LVFIF 46 /* VF Layer stack manager interface ID */ +#define LIXIF 47 /* X.31 stack manager interface ID */ +#define LFAIF 48 /* Fujitsu ALC/NTC/ATC driver stack manager interface ID */ +#define LPLIF 49 /* PMC Sierra LASAR driver stack manager interface ID */ +#define LAFIF 50 /* FR-ATM interworking stack manager interface ID */ +#define LCVIF 51 /* V5.X Control Protocol stack manager interface ID */ +#define LMVIF 52 /* V5.X System Manager stack manager interface ID */ +#define LBVIF 53 /* V5.X BCC Protocol stack manager interface ID */ +#define LLKIF 54 /* V5.2 Link stack manager interface ID */ +#define LPVIF 55 /* V5.X Protection Protocol stack manager interface ID */ +#define LCCIF 56 /* CC stack manager interface ID */ +#define LZCIF 57 /* ZC stack manager interface ID */ +#define LRMIF 58 /* RM stack manager interface ID */ +#define LZRIF 59 /* ZR stack manager interface ID */ +#define LRTIF 60 /* RT stack manager interface ID */ +#define LZSIF 61 /* ZS stack manager interface ID */ +#define LSFIF 62 /* SF stack manager interface ID */ +#define LXMIF 63 /* XM stack manager interface ID */ +#define LBWIF 64 /* PSIF - B-ISUP stack manager interface ID */ +#define LIWIF 65 /* PSIF - ISUP stack manager interface ID */ +#define LQWIF 66 /* PSIF - ISDN stack manager interface ID */ +#define LAWIF 67 /* PSIF - Q.93B stack manager interface ID */ +#define LZTIF 68 /* PSF - TCAP stack manager interface ID */ +#define LDTIF 69 /* PSF - TCAP stack manager interface ID */ +#define LZPIF 70 /* PSF - SCCP stack manager interface ID */ +#define LZNIF 71 /* PSF-MTP3 (FT/HA) stack manager interface ID */ +#define LZIIF 72 /* PSF-ISUP (FT/HA) stack manager interface ID */ +#define LZQIF 73 /* PSF-ISDN (FT/HA) stack manager interface ID */ +#define LZMIF 74 /* PSF-Q.93B (FT/HA) stack manager interface ID */ +#define LSGIF 75 /* System Manager stack manager interface ID */ +#define LSHIF 76 /* System Agent stack manager interface ID */ +#define LMRIF 77 /* Message Router stack manager interface ID */ +#define LPRIF 78 /* MPC860SAR driver stack manager interface ID */ +#define LGNIF 79 /* network service stack manager interface ID */ +#define LGTIF 80 /* GTP stack manager interface ID */ +#define LGLIF 81 /* GPRS LLC stack manager interface ID */ +#define LGGIF 82 /* GPRS-BSSGP stack manager interface ID */ +#define LGSIF 83 /* SNDCP stack manager interface ID */ +#define LHCIF 84 /* H.323 Control stack manager interface ID */ +#define LHIIF 85 /* TUCL stack manager interface ID */ +#define LHRIF 86 /* RTP/RTCP stack manager interface ID */ +#define LIQIF 87 /* ISDN-Q.SAAL Convergence Layer stack manager interface ID */ +#define LMGIF 88 /* MGCP stack manager interface ID */ +#define LDNIF 89 /* MTP-3 LDF stack manager interface ID */ +#define LDPIF 90 /* LDF-SCCP stack manager interface ID */ +#define LLNIF 91 /* MPLS-LDP(+CR) stack manager interface ID */ +#define LPAIF 92 /* PLOA stack manager interface ID */ +#define LALIF 93 /* AAL2 Signaling stack manager interface ID */ +#define LSBIF 94 /* SCTP stack manager interface ID */ +#define LSOIF 95 /* SIP stack manager interface ID */ +#define LITIF 96 /* M3UA stack manager interface ID */ +#define LNFIF 97 /* M3UA-NIF stack manager interface ID */ +#define LIDIF 98 /* IUA stack manager interface ID */ +#define LNDIF 99 /* IUA-NIF stack manager interface ID */ +#define LSUIF 100 /* SUA stack manager interface ID */ +#define LNPIF 101 /* SUA-NIF stack manager interface ID */ +#define LRAIF 102 /* RANAP stack manager interface ID */ +#define LZGIF 103 /* PSF-GCP (FT/HA) stack manager interface ID */ +#define LDGIF 104 /* LDF-GCP stack manager interface ID */ +#define LRNIF 105 /* RNSAP stack manager interface ID */ +#define LZJIF 106 /* PSF - MAP-GSM stack manager interface ID */ +#define LZFIF 107 /* PSF - CAP stack manager interface ID */ +#define LGMIF 108 /* GMM/SM stack manager interface ID */ +#define LZKIF 109 /* PSF - GMM/SM stack manager interface ID */ +/* gen_h_001.main_122 Additions */ +#define LAEIF 110 /* PSF - SUA stack manager interface ID */ +/* gen_h_001.main_138: Added the interface version for PSF S1AP */ +#define LYTIF 111 /* PSF - S1AP stack manager interface ID */ +/* gen_h_001.main_141: Added the interface version for PSF DIAMETER */ +#define LJCIF 112 /* PSF - DIAMETER stack manager interface ID */ + +/* Upper and Lower interface identifiers */ +#define AALIF 150 /* AAL interface ID */ +#define ALTIF 151 /* ALT interface ID */ +#define AMTIF 152 /* AMT interface ID */ +#define APLIF 153 /* APL interface ID */ +#define ARIIF 154 /* ARI interface ID */ +#define ASDIF 155 /* ASD interface ID */ +#define ASIIF 156 /* ASI interface ID */ +#define BITIF 157 /* BIT interface ID */ +#define CCTIF 158 /* CCT interface ID */ +#define CIPIF 159 /* CIP interface ID */ +#define DATIF 160 /* DAT interface ID */ +#define ECMIF 161 /* ECM interface ID */ +#define EVTIF 162 /* EVT interface ID */ +#define FNTIF 163 /* FNT interface ID */ +#define FRDIF 164 /* FRD interface ID */ +#define GBRIF 165 /* GBR interface ID */ +#define GGUIF 166 /* GGU interface ID */ +#define GLSIF 167 /* GLS interface ID */ +#define GNSIF 168 /* GNS interface ID */ +#define GSPIF 169 /* GSP interface ID */ +#define HCTIF 170 /* HCT interface ID */ +#define HGTIF 171 /* HGT interface ID */ +#define HITIF 172 /* HIT interface ID */ +#define HRTIF 173 /* HRT interface ID */ +#define IATIF 174 /* IAT interface ID */ +#define IETIF 175 /* IET interface ID */ +#define IFPIF 176 /* IFP interface ID */ +#define INTIF 177 /* INT interface ID */ +#define MACIF 178 /* MAC interface ID */ +#define MATIF 179 /* MAT interface ID */ +#define MDPIF 180 /* MDP interface ID */ +#define MGTIF 181 /* MGT interface ID */ +#define MPAIF 182 /* MPA interface ID */ +#define MVTIF 183 /* MVT interface ID */ +#define NUIIF 184 /* NUI interface ID */ +#define NVTIF 185 /* NVT interface ID */ +#define PCIIF 186 /* PCI interface ID */ +#define PXYIF 187 /* PXY interface ID */ +#define RLSIF 188 /* RLS interface ID */ +#define RMTIF 189 /* RMT interface ID */ +#define RTTIF 190 /* RTT interface ID */ +#define RYTIF 191 /* RYT interface ID */ +#define SCTIF 192 /* SCT interface ID */ +#define SDTIF 193 /* SDT interface ID */ +#define SFTIF 194 /* SFT interface ID */ +#define SITIF 195 /* SIT interface ID */ +#define SNTIF 196 /* SNT interface ID */ +#define SPTIF 197 /* SPT interface ID */ +#define STUIF 198 /* STU interface ID */ +#define TCTIF 199 /* TCT interface ID */ +#define TPTIF 200 /* TPT interface ID */ +#define TUTIF 201 /* TUT interface ID */ +#define UMEIF 202 /* UME interface ID */ +#define VFTIF 203 /* VFT interface ID */ +#define WITIF 204 /* WIT interface ID */ +#define WNTIF 205 /* WNT interface ID */ +#define WUTIF 206 /* WUT interface ID */ +#define XMTIF 207 /* XMT interface ID */ +#define XNTIF 208 /* XNT interface ID */ +#define RPTIF 209 /* RPT interface ID */ +#define RNTIF 210 /* RNT interface ID */ +#define CAPIF 211 /* CAP interface ID */ +#define LFPIF 212 /* LFP interface ID */ +#define FPUIF 213 /* FPU interface ID */ +#define CMKIF 214 /* CMK interface ID */ +#define MKUIF 215 /* MKU interface ID */ +#define PHUIF 216 /* PHU interface ID */ +#define GMUIF 212 /* GMU interface ID */ +/* gen_h_001.main_138: Added the interface version for SZT */ +#define SZTIF 213 /* SZT interface ID */ +/* gen_h_001.main_140: Added the interface version for AQU */ +#define AQUIF 214 /* AQU interface ID */ + +/* peer interface identifiers */ +#define SGPIF 250 /* System manager peer interface ID */ +#define SHPIF 251 /* System agent peer interface ID */ +#define MRPIF 252 /* Message router peer interface ID */ +#define ZNPIF 253 /* MTP-3 peer interface ID */ +#define ZPPIF 254 /* SCCP peer interface ID */ +#define ZTPIF 255 /* TCAP peer interface ID */ +#define ZIPIF 256 /* ISUP peer interface ID */ +#define ZQPIF 257 /* Q.931 peer interface ID */ +#define ZMPIF 258 /* Q.93B peer interface ID */ +#define ZCPIF 259 /* ICC peer interface ID */ +#define ZRPIF 260 /* ICC peer interface ID */ +#define ZSPIF 261 /* RT peer interface ID */ +#define ZAPIF 262 /* RANAP peer interface ID */ +#define ZGPIF 263 /* MGCP peer interface ID */ +#define ZBPIF 264 /* GTP peer interface ID */ +#define ZVPIF 265 /* PSF-M3UA peer interface ID */ +#define ZJPIF 266 /* MAP-GSM peer interface ID */ +#define ZFPIF 267 /* CAP peer interface ID */ +#define ZLPIF 268 /* ALCAP peer interface ID */ +#define ZKPIF 269 /* PSF GMMSM peer interface ID */ +/* gen_h_001.main_122 Additions */ +#define AEPIF 270 /* PSF SUA peer interface ID */ +/* gen_h_001.main_138: Added the interface version for PSF S1AP */ +#define YTPIF 271 /* PSF S1AP peer interface ID */ +/* gen_h_001.main_139: Added the interface version for eGTP-C PSF */ +#define HWPIF 272 /* eGTP-C PSF peer interface ID */ +/* gen_h_001.main_141: Added the interface version for PSF DIAMETER */ +#define JCPIF 273 /* PSF DIAMETER peer interface ID */ + +/* Maximum no.of interfaces a product a support on the upper/lower interface */ +#define MAX_INTF 2 /* Max intf to a usr/prov */ + +/* defines for SCCP ISNI and INS routing */ +#define MAX_ISNI_NID 0x07 /* Maximum no. of NIDs is ISNI */ +#define MAX_INS_NID 0x02 /* Maximum no. of NIDs in INS */ + + +/* defines for mode */ + +#define LOOPBACK_MODE 0 /* loopback mode */ +#define TESTING_MODE 1 /* testing mode */ +#define HARDWARE_MODE 2 /* hardware mode */ + +/* bind status */ +#define CM_BND_OK 1 /* bind request OK */ +#define CM_BND_NOK 2 /* bind request not OK */ + +/* New definition */ +#define CM_IPV4ADDR_TYPE 4 +#define CM_IPV6ADDR_TYPE 6 + + +/* debug masks and macros */ + +#ifdef DEBUGP + +#define DBGMASK_SI 0x00000001 /* system service interface */ +#define DBGMASK_MI 0x00000002 /* layer management interface */ +#define DBGMASK_UI 0x00000004 /* upper interface */ +#define DBGMASK_LI 0x00000008 /* lower interface */ +#define DBGMASK_PI 0x00000010 /* peer interface */ +#define DBGMASK_PLI 0x00000020 /* PSF's protocol layer interface */ + +#define DBGMASK_LYR 0x00000100 /* layer specific */ + +/* gen_h_001.main_132 : Guarding the Timestamp related changes in the compile time flag*/ +#ifdef DBG_TIMESTAMP +/* gen_h_001.main_131 : Added lock related macros */ +#define _DBG_INIT_WRITELCK(x) SInitLock(x, SS_LOCK_MUTEX) +#define _DBG_GET_WRITELCK(x) SLock(x) +#define _DBG_REL_WRITELCK(x) SUnlock(x) +#define _DBG_DEL_WRITELCK(x) SDestroyLock(x) + +#define DBGPRNTBUFSIZE 80 + +/* gen_h_001.main_131 : Modified the DBGP for the timestamp*/ +/* gen_h_001.main_133-modified macro */ +/* gen_h_001.main_140 : modified macro for printing the ProcId as well + * and changed sprintf to snprintf */ +#define DBGP(_tskInit, _layerName, _msgClass, _arg) \ + { \ + S8 _buf[DBGPRNTBUFSIZE]; \ + if ((_tskInit)->dbgMask & (_msgClass)) \ + { \ + if((_tskInit)->lyrMtFlag) \ + { \ + _DBG_GET_WRITELCK(&((_tskInit)->dbgLock)); \ + } \ + (Void) SGetTimeStamp(_buf); \ + snprintf((_tskInit)->prntBuf, PRNTSZE, \ + "[%s] [%s %d:0x%x:%x] %s:%d ", _buf, _layerName, \ + (_tskInit)->procId, (_tskInit)->ent, (_tskInit)->inst, \ + __FILE__, __LINE__); \ + SPrint((_tskInit)->prntBuf); \ + sprintf _arg; \ + SPrint((_tskInit)->prntBuf); \ + if((_tskInit)->lyrMtFlag) \ + { \ + _DBG_REL_WRITELCK(&((_tskInit)->dbgLock)); \ + } \ + } \ + } +#define DBGPN(_tskInit, _layerName, _msgClass, _arg) \ + { \ + S8 _buf[DBGPRNTBUFSIZE]; \ + if ((_tskInit)->dbgMask & (_msgClass)) \ + { \ + if((_tskInit)->lyrMtFlag) \ + { \ + _DBG_GET_WRITELCK(&((_tskInit)->dbgLock)); \ + } \ + (Void) SGetTimeStamp(_buf); \ + snprintf((_tskInit)->prntBuf, PRNTSZE, \ + "[%s] [%s %d:0x%x:%x] %s:%d ", _buf, _layerName, \ + (_tskInit)->procId, (_tskInit)->ent, (_tskInit)->inst, \ + __FILE__, __LINE__); \ + SPrint((_tskInit)->prntBuf); \ + snprintf _arg; \ + SPrint((_tskInit)->prntBuf); \ + if((_tskInit)->lyrMtFlag) \ + { \ + _DBG_REL_WRITELCK(&((_tskInit)->dbgLock)); \ + } \ + } \ + } + +#else +#define DBGP(_tskInit, _layerName, _msgClass, _arg) \ + { \ + if ((_tskInit)->dbgMask & (_msgClass)) \ + { \ + snprintf((_tskInit)->prntBuf, PRNTSZE, "[%s %d:0x%x:%x] %s:%d ", \ + _layerName, (_tskInit)->procId, (_tskInit)->ent, \ + (_tskInit)->inst, __FILE__, __LINE__); \ + SPrint((_tskInit)->prntBuf); \ + sprintf _arg; \ + SPrint((_tskInit)->prntBuf); \ + } \ + } +#define DBGPN(_tskInit, _layerName, _msgClass, _arg) \ + { \ + if ((_tskInit)->dbgMask & (_msgClass)) \ + { \ + snprintf((_tskInit)->prntBuf, PRNTSZE, "[%s %d:0x%x:%x] %s:%d ", \ + _layerName, (_tskInit)->procId, (_tskInit)->ent, \ + (_tskInit)->inst, __FILE__, __LINE__); \ + SPrint((_tskInit)->prntBuf); \ + snprintf _arg; \ + SPrint((_tskInit)->prntBuf); \ + } \ + } + +#endif +#else + +#define DBGP(_tskInit, _layerName, _msgClass, _arg) +#define DBGPN(_tskInit, _layerName, _msgClass, _arg) + +#endif /* DEBUGP */ + + +/* gen_h_001.main_126 : Added Circular Buffer */ + +/************************* CIRCULAR BUFFER ************************/ +/* + * Circular Buffer implementation provides two macro's + * + * 1. CBUF_INIT --> To initialize the Circular Bufffer + * 2. CBUF_WRITE --> To log data into the circular Buffer + * + * Usage: + * 1. CBUF_INIT must be called from the product's initialization + * function, prior to using the maro CBUF_WRITE. + * + * 2. CBUF_WRITE takes variable number of arguments + * + * 3. Enable the flag "CBUF_ENABLE" + * + * Note: + * 1. structure "cBuffer" is defined in gen.x + * 2. The structure cBuffer is added in "TskInit" under the flag + * "CBUF_ENABLE" + + * + * Limitation: + * 1. CBUF_WRITE can take a maximum of 255 characters, which is the + * value of the define PRNTSZE (defined in ssi.h) + * + * CBUF_INIT: + * This macro, allocates the memory to the circular Buffer and + * initializes the memory region with zeroes. + * + * E.g. CBUF_INIT(xxInit,100); + * where xxCb is the task initialisation structure, + * 100 - is the size of the circular buffer (bytes) + * + * CBUF_WRITE: + * This Macro, writes the data into circular buffer. Once the + * end of the buffer is reached, it starts again from the beggining + * of the circular Buffer. + * + * E.g. CBUF_WRITE(xxInit.cBuf,(xxInit.cBuf.tmpBuf,"%d |",10)); + * where xxInit is the task initialisation structure + * cBuf is the circular buffer's control structure + * tmpBuf is the temporary buffer declared inside "cBuffer" + * + * It is suggested to use a delimiter with every CBUF_WRITE. In this + * example "|" is the delimiter, which will be helpful in analyzing + * the circular buffer contents. + * + * CBUF_PRINT: + * This macro is used internally by the macro CBUF_WRITE. If the flag + * CBUF_DISPLAY is defined, then this macro is defined to SPrint. Else + * it does nothing. + * + */ + +#ifdef CBUF_ENABLE + +#define CBUFPRNTSZE 255 +#ifdef CBUF_DISPLAY +#define CBUF_PRINT(cBufPtr) SPrint(cBufPtr) +#else +#define CBUF_PRINT(cBufPtr) +#endif + +#define CBUF_INIT(_class,size) \ +{ \ + SGetSBuf((_class).region,(_class).pool, \ + &(_class).cBuf.cBufPtr,size); \ + (_class).cBuf.cBufSize = size; \ + (_class).cBuf.cBufIdx = 0; \ + cmMemset((U8 *)(_class).cBuf.cBufPtr,'|',size); \ +} + +#define CBUF_WRITE(_class,_argList) \ +{ \ + S32 tmpLen = 0; \ + U32 idx; \ + tmpLen = sprintf _argList; \ + if(CBUFPRNTSZE >= tmpLen) \ + { \ + for(idx = 0; idx < tmpLen; idx++) \ + { \ + (_class).cBufIdx = (_class).cBufIdx % (_class).cBufSize; \ + (_class).cBufPtr[(_class).cBufIdx++] = (_class).tmpBuf[idx]; \ + } \ + } \ + CBUF_PRINT((_class).tmpBuf); \ +} + +#define CBUF_DATA_PRINT(_class) \ +{ \ + S8 *tmpBuf = NULLP ;\ + U32 cBufIdx; \ + U32 tmpIdx=0; \ + SGetSBuf((_class).region,(_class).pool, \ + (U8 **)&tmpBuf,(_class).cBuf.cBufSize); \ + cmMemset((U8 *)tmpBuf,0,(_class).cBuf.cBufSize); \ + for(cBufIdx = (_class).cBuf.cBufIdx; cBufIdx < (_class).cBuf.cBufSize; cBufIdx++) \ + { \ + tmpBuf[tmpIdx++] = (_class).cBuf.cBufPtr[cBufIdx]; \ + tmpIdx = tmpIdx % ((_class).cBuf.cBufSize); \ + } \ + for(cBufIdx=0;cBufIdx < (_class).cBuf.cBufIdx;cBufIdx++) \ + { \ + tmpBuf[tmpIdx++] = (_class).cBuf.cBufPtr[cBufIdx]; \ + tmpIdx = tmpIdx % ((_class).cBuf.cBufSize); \ + } \ + SPrint(tmpBuf); \ + SPutSBuf((_class).region,(_class).pool, \ + (U8 *)tmpBuf,(_class).cBuf.cBufSize); \ +} +#else + +#define CBUF_INIT(_class,size) +#define CBUF_WRITE(_class,_argList) +#define CBUF_DATA_PRINT(_class) +#endif /* CBUF_ENABLE */ + + + +#ifdef CMFILE_REORG_1 + +/* defines */ + +/* packing macros */ + +/* system services typedefs */ + +#define cmPkBool(x, mBuf) SPkU8(x, mBuf) /* pack Bool */ +#define cmPkStatus(x, mBuf) SPkS16(x, mBuf) /* pack Status */ +#define cmPkTicks(x, mBuf) SPkU32(x, mBuf) /* pack Ticks */ +#define cmPkQLen(x, mBuf) SPkS16(x, mBuf) /* pack QLen */ +#define cmPkOrder(x, mBuf) SPkS16(x, mBuf) /* pack Order */ +#define cmPkData(x, mBuf) SPkU8(x, mBuf) /* pack Data */ +#define cmPkRandom(x, mBuf) SPkU16(x, mBuf) /* pack Random */ +#define cmPkSeq(x, mBuf) SPkS16(x, mBuf) /* pack Seq */ +#define cmPkReason(x, mBuf) SPkS16(x, mBuf) /* pack Reason */ +#define cmPkProcId(x, mBuf) SPkU16(x, mBuf) /* pack ProcId */ +#define cmPkVectNmb(x, mBuf) SPkS16(x, mBuf) /* pack VectNmb */ +#define cmPkPrior(x, mBuf) SPkU8(x, mBuf) /* pack Prior*/ +#define cmPkPriority(x, mBuf) cmPkPrior(x, mBuf) /* pack Priority */ +#define cmPkRoute(x, mBuf) SPkU8(x, mBuf) /* pack Route */ +#define cmPkTtype(x, mBuf) SPkS16(x, mBuf) /* pack Ttype */ +#define cmPkSema(x, mBuf) SPkS8(x, mBuf) /* pack Sema */ +#define cmPkTxt(x, mBuf) SPkS8(x, mBuf) /* pack Txt */ +#define cmPkEnt(x, mBuf) SPkU8(x, mBuf) /* pack Ent */ +#define cmPkInst(x, mBuf) SPkU8(x, mBuf) /* pack Inst */ +#define cmPkElmnt(x, mBuf) SPkS16(x, mBuf) /* pack Elmnt */ +#define cmPkElmntInst1(x, mBuf) SPkS16(x, mBuf) /* pack ElmntInst1 */ +#define cmPkElmntInst2(x, mBuf) SPkS16(x, mBuf) /* pack ElmntInst2 */ +#define cmPkElmntInst3(x, mBuf) SPkS16(x, mBuf) /* pack ElmntInst3 */ +#define cmPkRegion(x, mBuf) SPkU8(x, mBuf) /* pack Region */ +#define cmPkPool(x, mBuf) SPkU8(x, mBuf) /* pack Pool */ +#ifdef LONG_MSG +#define cmPkMsgLen(x, mBuf) SPkS32(x, mBuf) /* pack MsgLen */ +#else +#define cmPkMsgLen(x, mBuf) SPkS16(x, mBuf) /* pack MsgLen */ +#endif +#ifdef DOS +#define cmPkSize(x, mBuf) SPkU16(x, mBuf) /* pack Size */ +#else +#define cmPkSize(x, mBuf) SPkU32(x, mBuf) /* pack Size */ +#endif /* DOS */ + +/* general typedefs */ + +#define cmPkSelector(x, mBuf) SPkU8(x, mBuf) /* pack Selector */ +#define cmPkEvent(x, mBuf) SPkU8(x, mBuf) /* pack Event */ +#define cmPkCntr(x, mBuf) SPkS32(x, mBuf) /* pack Cntr */ +#define cmPkStsCntr(x, mBuf) SPkU32(x, mBuf) /* pack StsCntr */ +#define cmPkLnkNmb(x, mBuf) SPkS16(x, mBuf) /* pack LnkNmb */ +#define cmPkSuId(x, mBuf) SPkS16(x, mBuf) /* pack SuId */ +#define cmPkSpId(x, mBuf) SPkS16(x, mBuf) /* pack SpId */ +#define cmPkSuInstId(x, mBuf) SPkS16(x, mBuf) /* pack SuInstId */ +#define cmPkSpInstId(x, mBuf) SPkS16(x, mBuf) /* pack SpInstId */ +#define cmPkSapi(x, mBuf) SPkU8(x, mBuf) /* pack Sapi */ +#define cmPkTei(x, mBuf) SPkU8(x, mBuf) /* pack Tei */ +#define cmPkchNo(x, mBuf) SPkU8(x, mBuf) /* pack Channel Number */ +#define cmPkCes(x, mBuf) SPkU8(x, mBuf) /* pack Ces */ +#define cmPkDlci(x, mBuf) SPkU32(x, mBuf) /* pack Dlci */ +#define cmPkCalRef(x, mBuf) SPkU16(x, mBuf) /* pack CalRef */ +#define cmPkOrigin(x, mBuf) SPkS16(x, mBuf) /* pack Origin */ +#define cmPkNwId(x, mBuf) SPkU16(x, mBuf) /* pack NwId */ +#define cmPkSwtch(x, mBuf) SPkS16(x, mBuf) /* pack Swtch */ +#define cmPkCause(x, mBuf) SPkU8(x, mBuf) /* pack Cause */ +#define cmPkDgn(x, mBuf) SPkU8(x, mBuf) /* pack Dgn */ +#define cmPkAction(x, mBuf) SPkS16(x, mBuf) /* pack Action */ +#define cmPkSeqS16(x, mBuf) SPkS16(x, mBuf) /* pack SeqS16 */ +#define cmPkSeqU16(x, mBuf) SPkU16(x, mBuf) /* pack SeqU16 */ +#define cmPkSeqS24(x, mBuf) SPkS32(x, mBuf) /* pack SeqS24 */ +#define cmPkSeqU24(x, mBuf) SPkU32(x, mBuf) /* pack SeqU24 */ +#define cmPkSetUpArb(x, mBuf) SPkU8(x, mBuf) /* pack SetUpArb */ +#define cmPkEvntType(x, mBuf) SPkU8(x, mBuf) /* pack EvntType */ +#define cmPkState(x, mBuf) SPkU8(x, mBuf) /* pack State */ +#define cmPkMode(x, mBuf) SPkU8(x, mBuf) /* pack Mode */ +#define cmPkConnId(x, mBuf) SPkS32(x, mBuf) /* pack ConnId */ +#define cmPkUConnId(x, mBuf) SPkU32(x, mBuf) /* pack unsigned ConnId */ +#define cmPkMibOpCode(x, mBuf) SPkU16(x, mBuf) /* pack mib opCode*/ +#define cmPkMibStatus(x, mBuf) SPkU16(x, mBuf) /* Pack mib cfm status*/ +#define cmPkMibTblType(x, mBuf) SPkU16(x, mBuf) /* Pack mib table type */ +#define cmPkMibReqId(x, mBuf) SPkS32(x, mBuf) /* Pack mib request Id */ +#define cmPkProfileId(x, mBuf) SPkU8(x, mBuf) /* Pack HCC Profile Id */ +#define cmPkIntfId(x, mBuf) SPkU16(x, mBuf) /* Pack intf id */ +#define cmPkIntfVer(x, mBuf) SPkU16(x, mBuf) /* Pack intf ver */ +#define cmPkuaType(x, mBuf) SPkU8(x, mBuf) /* Pack uaType */ +/* scc specific typedefs */ + +#define cmPkBaud(x, mBuf) SPkS16(x, mBuf) /* pack Baud */ +#define cmPkPhysIntType(x, mBuf) SPkS16(x, mBuf) /* pack PhysIntType */ +#define cmPkPathConnType(x, mBuf) SPkS16(x, mBuf) /* pack PathConnType */ +#define cmPkParity(x, mBuf) SPkS16(x, mBuf) /* pack Parity */ +#define cmPkCharLength(x, mBuf) SPkS16(x, mBuf) /* pack CharLength */ +#define cmPkStopBits(x, mBuf) SPkS16(x, mBuf) /* pack StopBits */ + +/* tcp/ip specific typedefs */ + +#define cmPkIpAddr(x, mBuf) SPkU32(x, mBuf) /* pack IpAddr */ +#define cmPkPort(x, mBuf) SPkU16(x, mBuf) /* pack Port */ +#define cmPkCmd(x, mBuf) SPkU8(x, mBuf) /* pack Cmd */ +#define cmPkFlags(x, mBuf) SPkU8(x, mBuf) /* pack Flags */ +#define cmPkTtl(x, mBuf) SPkU8(x, mBuf) /* pack Ttl */ +#define cmPkPrec(x, mBuf) SPkU8(x, mBuf) /* pack Prec */ +#define cmPkWindow(x, mBuf) SPkU32(x, mBuf) /* pack Window */ + +/* LLC/SNAP specific defines */ + +#define cmPkOui(x, mBuf) SPkU32(x, mBuf) /* pack Oui */ +#define cmPkPid(x, mBuf) SPkU16(x, mBuf) /* pack Pid */ +#define cmPkLlcId(x, mBuf) SPkU32(x, mBuf) /* pack LLcId */ + + +/* unpacking macros */ + +/* system services typedefs */ + +#define cmUnpkBool(x, mBuf) SUnpkU8(x, mBuf) /* unpack Bool */ +#define cmUnpkStatus(x, mBuf) SUnpkS16(x, mBuf) /* unpack Status */ +#define cmUnpkTicks(x, mBuf) SUnpkU32(x, mBuf) /* unpack Ticks */ +#define cmUnpkQLen(x, mBuf) SUnpkS16(x, mBuf) /* unpack QLen */ +#define cmUnpkOrder(x, mBuf) SUnpkS16(x, mBuf) /* unpack Order */ +#define cmUnpkData(x, mBuf) SUnpkU8(x, mBuf) /* unpack Data */ +#define cmUnpkRandom(x, mBuf) SUnpkU16(x, mBuf) /* unpack Random */ +#define cmUnpkSeq(x, mBuf) SUnpkS16(x, mBuf) /* unpack Seq */ +#define cmUnpkReason(x, mBuf) SUnpkS16(x, mBuf) /* unpack Reason */ +#define cmUnpkProcId(x, mBuf) SUnpkU16(x, mBuf) /* unpack ProcId */ +#define cmUnpkVectNmb(x, mBuf) SUnpkS16(x, mBuf) /* unpack VectNmb */ +#define cmUnpkPrior(x, mBuf) SUnpkU8(x, mBuf) /* unpack Prior */ +#define cmUnpkPriority(x, mBuf) cmUnpkPrior(x, mBuf) /* unpack Priority */ +#define cmUnpkRoute(x, mBuf) SUnpkU8(x, mBuf) /* unpack Route */ +#define cmUnpkTtype(x, mBuf) SUnpkS16(x, mBuf) /* unpack Ttype */ +#define cmUnpkSema(x, mBuf) SUnpkS8(x, mBuf) /* unpack Sema */ +#define cmUnpkTxt(x, mBuf) SUnpkS8(x, mBuf) /* unpack Txt */ +#define cmUnpkEnt(x, mBuf) SUnpkU8(x, mBuf) /* unpack Ent */ +#define cmUnpkInst(x, mBuf) SUnpkU8(x, mBuf) /* unpack Inst */ +#define cmUnpkElmnt(x, mBuf) SUnpkS16(x, mBuf) /* unpack Elmnt */ +#define cmUnpkElmntInst1(x, mBuf) SUnpkS16(x, mBuf) /* unpack ElmntInst1 */ +#define cmUnpkElmntInst2(x, mBuf) SUnpkS16(x, mBuf) /* unpack ElmntInst2 */ +#define cmUnpkElmntInst3(x, mBuf) SUnpkS16(x, mBuf) /* unpack ElmntInst3 */ +#define cmUnpkRegion(x, mBuf) SUnpkU8(x, mBuf) /* unpack Region */ +#define cmUnpkPool(x, mBuf) SUnpkU8(x, mBuf) /* unpack Pool */ +#ifdef LONG_MSG +#define cmUnpkMsgLen(x, mBuf) SUnpkS32(x, mBuf) /* unpack MsgLen */ +#else +#define cmUnpkMsgLen(x, mBuf) SUnpkS16(x, mBuf) /* unpack MsgLen */ +#endif +#ifdef DOS +#define cmUnpkSize(x, mBuf) SUnpkU16(x, mBuf) /* unpack Size */ +#else +#define cmUnpkSize(x, mBuf) SUnpkU32(x, mBuf) /* unpack Size */ +#endif /* DOS */ + +/* general typedefs */ + +#define cmUnpkSelector(x, mBuf) SUnpkU8(x, mBuf) /* unpack Selector */ +#define cmUnpkEvent(x, mBuf) SUnpkU8(x, mBuf) /* unpack Event */ +#define cmUnpkCntr(x, mBuf) SUnpkS32(x, mBuf) /* unpack Cntr */ +#define cmUnpkStsCntr(x, mBuf) SUnpkU32(x, mBuf) /* unpack StsCntr */ +#define cmUnpkLnkNmb(x, mBuf) SUnpkS16(x, mBuf) /* unpack LnkNmb */ +#define cmUnpkSuId(x, mBuf) SUnpkS16(x, mBuf) /* unpack SuId */ +#define cmUnpkSpId(x, mBuf) SUnpkS16(x, mBuf) /* unpack SpId */ +#define cmUnpkSuInstId(x, mBuf) SUnpkS16(x, mBuf) /* unpack SuInstId */ +#define cmUnpkSpInstId(x, mBuf) SUnpkS16(x, mBuf) /* unpack SpInstId */ +#define cmUnpkSapi(x, mBuf) SUnpkU8(x, mBuf) /* unpack Sapi */ +#define cmUnpkTei(x, mBuf) SUnpkU8(x, mBuf) /* unpack Tei */ +#define cmUnpkchNo(x, mBuf) SUnpkS8(x, mBuf) /* unpack Channel Number */ +#define cmUnpkCes(x, mBuf) SUnpkU8(x, mBuf) /* unpack Ces */ +#define cmUnpkDlci(x, mBuf) SUnpkU32(x, mBuf) /* unpack Dlci */ +#define cmUnpkCalRef(x, mBuf) SUnpkU16(x, mBuf) /* unpack CalRef */ +#define cmUnpkOrigin(x, mBuf) SUnpkS16(x, mBuf) /* unpack Origin */ +#define cmUnpkNwId(x, mBuf) SUnpkU16(x, mBuf) /* unpack NwId */ +#define cmUnpkSwtch(x, mBuf) SUnpkS16(x, mBuf) /* unpack Swtch */ +#define cmUnpkCause(x, mBuf) SUnpkU8(x, mBuf) /* unpack Cause */ +#define cmUnpkDgn(x, mBuf) SUnpkU8(x, mBuf) /* unpack Dgn */ +#define cmUnpkAction(x, mBuf) SUnpkS16(x, mBuf) /* unpack Action */ +#define cmUnpkSeqS16(x, mBuf) SUnpkS16(x, mBuf) /* unpack SeqS16 */ +#define cmUnpkSeqU16(x, mBuf) SUnpkU16(x, mBuf) /* unpack SeqU16 */ +#define cmUnpkSeqS24(x, mBuf) SUnpkS32(x, mBuf) /* unpack SeqS24 */ +#define cmUnpkSeqU24(x, mBuf) SUnpkU32(x, mBuf) /* unpack SeqU24 */ +#define cmUnpkSetUpArb(x, mBuf) SUnpkU8(x, mBuf) /* unpack SetUpArb */ +#define cmUnpkEvntType(x, mBuf) SUnpkU8(x, mBuf) /* unpack EvntType */ +#define cmUnpkState(x, mBuf) SUnpkU8(x, mBuf) /* unpack State */ +#define cmUnpkMode(x, mBuf) SUnpkU8(x, mBuf) /* unpack Mode */ +#define cmUnpkConnId(x, mBuf) SUnpkS32(x, mBuf) /* unpack ConnId */ +#define cmUnpkUConnId(x, mBuf) SUnpkU32(x, mBuf) /* unpack uns ConnId */ +#define cmUnpkMibOpCode(x, mBuf) SUnpkU16(x, mBuf) /* unpack mib opCode*/ +#define cmUnpkMibStatus(x, mBuf) SUnpkU16(x, mBuf) /* unpack mib cfm status*/ +#define cmUnpkMibTblType(x, mBuf) SUnpkU16(x, mBuf) /* Pack mib table type */ +#define cmUnpkMibReqId(x, mBuf) SUnpkS32(x, mBuf) /* Pack mib request Id */ +#define cmUnpkProfileId(x, mBuf) SUnpkU8(x, mBuf) /* Pack HCC Profile Id */ +#define cmUnpkIntfId(x, mBuf) SUnpkU16(x, mBuf) /* unpack intf id */ +#define cmUnpkIntfVer(x, mBuf) SUnpkU16(x, mBuf) /* unpack intf ver */ +#define cmUnpkuaType(x, mBuf) SUnpkU8(x, mBuf) /* Unpack uaType */ +/* scc specific typedefs */ + +#define cmUnpkBaud(x, mBuf) SUnpkS16(x, mBuf) /* unpack Baud */ +#define cmUnpkPhysIntType(x, mBuf) SUnpkS16(x, mBuf) /* unpack PhysIntType */ +#define cmUnpkPathConnType(x, mBuf) SUnpkS16(x, mBuf) /* unpack PathConnType */ +#define cmUnpkParity(x, mBuf) SUnpkS16(x, mBuf) /* unpack Parity */ +#define cmUnpkCharLength(x, mBuf) SUnpkS16(x, mBuf) /* unpack CharLength */ +#define cmUnpkStopBits(x, mBuf) SUnpkS16(x, mBuf) /* unpack StopBits */ + +/* tcp/ip specific typedefs */ + +#define cmUnpkIpAddr(x, mBuf) SUnpkU32(x, mBuf) /* unpack IpAddr */ +#define cmUnpkPort(x, mBuf) SUnpkU16(x, mBuf) /* unpack Port */ +#define cmUnpkCmd(x, mBuf) SUnpkU8(x, mBuf) /* unpack Cmd */ +#define cmUnpkFlags(x, mBuf) SUnpkU8(x, mBuf) /* unpack Flags */ +#define cmUnpkTtl(x, mBuf) SUnpkU8(x, mBuf) /* unpack Ttl */ +#define cmUnpkPrec(x, mBuf) SUnpkU8(x, mBuf) /* unpack Prec */ +#define cmUnpkWindow(x, mBuf) SUnpkU32(x, mBuf) /* unpack Window */ + +/* LLC/SNAP specific defines */ + +#define cmUnpkOui(x, mBuf) SUnpkU32(x, mBuf) /* unpack Oui */ +#define cmUnpkPid(x, mBuf) SUnpkU16(x, mBuf) /* unpack Pid */ +#define cmUnpkLlcId(x, mBuf) SUnpkU32(x, mBuf) /* unpack LLcId */ + +/* packing and unpacking for token strings */ + +#define CMPKTKNSTR(tknStr, mBuf) \ +{ \ + Cntr i; \ + \ + if(tknStr->pres) \ + { \ + /* Value */ \ + for (i = 0; i < (S16) tknStr->len; i++) \ + { \ + CMCHKPK(SPkU8, tknStr->val[i], mBuf); \ + } \ + \ + /* Length */ \ + CMCHKPK(SPkU8, tknStr->len, mBuf); \ + } \ + \ + /* Token Header */ \ + CMCHKPK(SPkU8, tknStr->pres, mBuf); \ +} + +#define CMUNPKTKNSTR(tknStr, mBuf) \ +{ \ + Cntr i; \ + \ + /* Token Header */ \ + CMCHKUNPK(SUnpkU8, &tknStr->pres, mBuf); \ + \ + if(tknStr->pres) \ + { \ + /* Length */ \ + CMCHKUNPK(SUnpkU8, &tknStr->len, mBuf); \ + \ + /* Value */ \ + for (i = 1; i <= (S16) tknStr->len; i++) \ + { \ + CMCHKUNPK(SUnpkU8, &tknStr->val[tknStr->len - i], mBuf); \ + } \ + } \ + \ +} + +#endif /* CMFILE_REORG_1 */ + +#define cmPkTranId(x, mBuf) SPkU32(x, mBuf) /* Pack transaction Id */ +#define cmUnpkTranId(x, mBuf) SUnpkU32(x, mBuf) /* unpack transaction Id */ + +#ifdef L2_L3_SPLIT +typedef struct _debugInfo +{ + U32 mBuf; + U32 res[8]; + U32 count; +} DebugInfo; + +EXTERN DebugInfo debugInfo; +#endif + +#endif /* __GENH__ */ + + +/********************************************************************30** + + End of file +**********************************************************************/ diff --git a/src/cm/gen.x b/src/cm/gen.x new file mode 100755 index 000000000..689d5cf37 --- /dev/null +++ b/src/cm/gen.x @@ -0,0 +1,1721 @@ +/******************************************************************************* +################################################################################ +# Copyright (c) [2017-2019] [Radisys] # +# # +# 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. # +################################################################################ +*******************************************************************************/ + +/********************************************************************20** + + Name: general layer + + Type: C include file + + Desc: Structures, variables and typedefs required by two + or more layer service user interfaces. + + File: gen.x + +*********************************************************************21*/ + +#ifndef __GENX__ +#define __GENX__ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef RGL_SPECIFIC_CHANGES +#include "cm_debug.h" +#endif + + +/* typedefs */ + +typedef S8 Txt; /* text */ + +typedef U8 Ent; /* entity */ + +typedef U8 Inst; /* instance */ + +typedef struct entityId /* entity id */ +{ + Ent ent; /* entity */ + Inst inst; /* instance */ +} EntityId; + +/* element id */ + +typedef S16 Elmnt; /* element */ + +typedef S16 ElmntInst1; /* element instance 1 */ + +typedef S16 ElmntInst2; /* element instance 2 */ + +typedef S16 ElmntInst3; /* element instance 3 */ + +typedef struct elmntId /* element id */ +{ + Elmnt elmnt; /* element */ + ElmntInst1 elmntInst1; /* element instance 1 */ + ElmntInst2 elmntInst2; /* element instance 2 */ + ElmntInst3 elmntInst3; /* element instance 3 */ +} ElmntId; + +typedef U8 Region; /* region */ + +typedef U8 Pool; /* pool */ + +typedef U8 Prior; /* priority */ + +typedef Prior Priority; /* priority */ + +typedef U8 Route; /* route */ + +typedef U8 Data; /* data */ + +typedef U8 Selector; /* selector */ + +typedef S16 Reason; /* reason */ + +typedef U16 ProcId; /* processor id */ + +typedef U8 Event; /* event */ + +typedef U32 TranId; /* transaction Id */ + +typedef S16 IntNum; /* Interface Number */ + +typedef U16 TranNum; /* Transaction Number */ + +typedef U16 CmIntfId; /* Interface identifier */ +typedef U16 CmIntfVer; /* Interface version */ + +#ifdef TDS_ROLL_UPGRADE_SUPPORT +typedef struct cmIntf /* Attributes of an interface */ +{ + CmIntfId intfId; /* Interface identifier */ + CmIntfVer intfVer; /* Interface version */ +} CmIntf; +#endif + +/* post structure *** ALIGNED & ORDERED *** */ +typedef struct pst /* parameters for SPstTsk */ +{ + ProcId dstProcId; /* destination processor id (U16) */ + ProcId srcProcId; /* source processor id (U16) */ + + Ent dstEnt; /* destination entity (U8) */ + Inst dstInst; /* destination instance (U8) */ + Ent srcEnt; /* source entity (U8) */ + Inst srcInst; /* source instance (U8) */ + + Prior prior; /* priority (U8) */ + Route route; /* route (U8) */ + Event event; /* event (U8) */ + Region region; /* region (U8) */ + + Pool pool; /* pool (U8) */ + Selector selector; /* selector (U8) */ + CmIntfVer intfVer; /* interface version (U16) */ +} Pst; + +/* systemId structure */ + +typedef struct systemId /* system id */ +{ + S16 mVer; /* main version */ + S16 mRev; /* main revision */ + S16 bVer; /* branch version */ + S16 bRev; /* branch revision */ + Txt *ptNmb; /* part number */ +} SystemId; + +/* Protocol Address Structure */ +/* Note: The Order of variables should not be changed as it breaks MPC/MPS + * code in PLOA + */ +typedef struct protAddr +{ + U16 protType; /* Protocol Type */ + U8 len; /* Protocol Address Length in bytes */ + U8 preLen; /* prefix length in bits */ + U8 address[MAX_PROTADDR_LEN]; /* Protocol Address */ +#ifdef CM_ARI2 + Bool autoSysIdPres; /* Is Autonomous System Id Present */ + U32 autoSysId; /* Autonomous System Id */ +#endif /* CM_ARI2 */ + +}ProtAddr; + +typedef struct protAddrTbl +{ + U8 count; /* Number of addresses */ + ProtAddr addr[MAX_PROT_ADDRS]; /* Protocol Address List */ +}ProtAddrTbl; + +/* addrs structure */ + +typedef struct addrs /* address */ +{ + U8 length; /* length (bytes or nibbles) */ + U8 strg[ADRLEN]; /* address */ +} Addrs; + +typedef struct shrtAddr /* short address */ +{ + U8 length; /* length bytes */ + U8 strg[SHRTADRLEN]; /* address */ +} ShrtAddrs; + +typedef struct lngAddr /* long address */ +{ + U8 length; /* length bytes */ + U8 strg[LNGADRLEN]; /* address */ +} LngAddrs; + +/* bndCfg structure */ + +typedef struct bndCfg /* bind configuration */ +{ + Txt *usrId; /* user id */ + U8 bufOwnshp; /* buffer ownership */ + U8 flcTyp; /* flow control type */ + U8 wdw; /* window */ + Ent ent; /* entity */ + Inst inst; /* instance */ + Region region; /* region */ + Pool pool; /* pool */ + Prior prior; /* priority */ + Route route; /* route */ + Addrs sapAdr; /* SAP Address */ + Selector selector; /* selector */ +} BndCfg; + +/* gen_x_001.main_91 : Added Definition of Circular Buffer Structure */ +/* Circular Buffer Structure */ +#ifdef CBUF_ENABLE +typedef struct cb { + U32 cBufIdx; + U32 cBufSize; + U8 *cBufPtr; + S8 tmpBuf[CBUFPRNTSZE]; +}cBuffer; +#endif /* CBUF_ENABLE */ + +/* tskInit structure */ + +typedef struct tskInit /* task initialization */ +{ +#ifdef SS_MULTIPLE_PROCS + ProcId proc; /* processor */ +#endif /* SS_MULTIPLE_PROCS */ + Ent ent; /* entity */ + Inst inst; /* instance */ + Region region; /* static region */ + Pool pool; /* static pool */ + Reason reason; /* reason */ + Bool cfgDone; /* configuration done */ + Bool acnt; /* accounting */ + Bool usta; /* unsolicited status */ + Bool trc; /* trace */ +#ifdef DEBUGP + U32 dbgMask; /* debug mask */ + Txt prntBuf[PRNTSZE]; /* print buffer */ +#endif + Txt *prntCirBuf; /* print buffer for each system task */ +#ifdef SS_DIAG + /* gen_x_001.main_96 :Added logmask */ + U32 logMask; /* Logging mask */ +#endif + BndCfg lmBnd; /* layer management bind */ + ProcId procId; /* processor id */ + Pst lmPst; /* layer management post */ + /* gen_x_001.main_91 : Added cBuffer in task initialisation strucutre */ +#ifdef CBUF_ENABLE + cBuffer cBuf; /* Circular Buffer */ +#endif /* CBUF_ENABLE */ + /* gen_x_001.main_92 : Added timestamp related parameter */ + /* gen_x_001.main_93 : Guarding the Timestamp related changes in the compile time flag*/ +#ifdef DBG_TIMESTAMP + SLockId dbgLock; /* write lock for the log files */ + Bool lyrMtFlag; /* Layer is Multithreaded or not flag */ +#endif + +} TskInit; + + +typedef S32 Cntr; /* counter */ + +typedef U32 StsCntr; /* Statistics counter */ + +typedef S16 LnkNmb; /* link number */ + +typedef S8 VBit; /*V Bit */ + +typedef S16 SuId; /* service user sap id */ + +typedef S16 SpId; /* service provider sap id */ + +typedef S16 SuInstId; /* service user instance id */ + +typedef S16 SpInstId; /* service provider instance id */ + +typedef U16 PortId; /* port id */ + +typedef U8 Sapi; /* service access point id */ + +typedef U8 Tei; /* terminal endpoint id */ + +typedef U8 Ces; /* connection endpoint suffix */ + +typedef U32 Dlci; /* data link control identifier */ + +typedef U16 CalRef; /* call Reference */ + +typedef S16 Origin; /* origin */ + +typedef U16 NwId; /* Network Identifier */ + +typedef S16 Swtch; /* switch */ + +typedef U8 Cause; /* cause code */ + +typedef U8 Dgn; /* diagnostic code */ + +typedef S16 Action; /* action */ + +typedef S16 SeqS16; /* signed 16 bit sequence number */ + +typedef U16 SeqU16; /* unsigned 16 bit sequence number */ + +typedef S32 SeqS24; /* signed 24 bit sequence number */ + +typedef U32 SeqU24; /* unsigned 24 bit sequence number */ + +typedef U8 SetUpArb; /* set up arbitration (PASSIVE/ACTIVE) */ + +typedef U8 EvntType; /* event type */ + +typedef U8 State; /* state */ + +typedef U8 Mode; /* mode */ + +typedef S32 ConnId; /* connection id */ + +typedef U32 UConnId; /* unsigned connection id */ + +typedef U16 ProtId; /* protocol id */ + +typedef U16 ChannelId; /* channel id */ + +typedef U8 Arr64U8[64]; /* Array of 64 of type U8*/ + +typedef U16 Efa; /* Envelope Address Function */ + +typedef U32 BitState; /* Sa Bit ID and Value */ + +typedef U8 CChanId; /* V5UA Channel ID */ + +typedef U16 MibOpCode; /* Op code for Mib Request MIB_REQUEST_GET, + MIB_REQUEST_GET_FIRST, MIB_REQUEST */ + +typedef U16 MibStatus; /* Status returned in Mib Cfm */ + +typedef U16 MibTblType; /* table type */ + +typedef S32 MibReqId; /* request identifier */ + +typedef U8 UstaType; /* unsolicited status type */ +typedef S8 ChannelNo; /* Channel Number */ + +/* ATM typedefs */ + +#ifndef CMFILE_REORG_1 + +typedef U16 AtmVpci; /* ATM virtual path connection id */ +typedef U16 AtmVpi; /* ATM virtual path id */ + + +typedef U16 AtmVci; /* ATM virtual channel id */ + +typedef U8 AtmLp; /* ATM loss priority */ + +typedef U8 AtmCi; /* ATM congestion indication */ + +typedef U8 AtmRs; /* ATM reception status */ + +typedef U8 AtmUu; /* ATM user-to-user field in CPCS PDUs */ + +typedef U32 AtmUui; /* ATM user-to-user indication field in SSCOP PDUs */ + +typedef U8 AtmPt; /* ATM cell payload type */ + +typedef struct atmQos /* ATM quality of service */ +{ + U8 qosFwd; /* qos in forward direction */ + U8 qosBwd; /* qos in backward direction */ +} AtmQos; + +/* Vitual channel structure */ + +typedef struct amVccId /* virtual channel connection identifier */ +{ + AtmVpci vpci; /* virtual path connection identifier */ + AtmVci vci; /* virtual channel identifier */ +} AmVccId; + +/* VCC id */ +typedef struct atmVccId /* VCC id */ +{ + AtmVpi vpi; /* VPI */ + AtmVci vci; /* VCI */ +} AtmVccId; + +/* VCC table */ +typedef struct atmVccTbl /* VCC table */ +{ + U16 count; /* number of VCCs */ + AtmVccId tbl[MAX_ATMVCCTBL_SZ]; /* VCC list */ +} AtmVccTbl; + +/* Generic ATM address */ +typedef struct atmAddr +{ + U8 type; /* type of Address (AESA or E.164) */ + U8 len; /* length (bytes) */ + U8 strg[ADRLEN]; /* address string */ +} AtmAddr; + +/* ATM address table */ +typedef struct atmAddrTbl /* ATM address table */ +{ + U16 count; /* number of ATM addresses */ + AtmAddr tbl[MAX_ATMADDRTBL_SZ]; /* ATM address list */ +} AtmAddrTbl; + +typedef struct atmTfcDesc /* ATM traffic descriptor */ +{ + U32 fwdPeakCellRate0; /* forward peak cell rate, CLP = 0 */ + U32 bwdPeakCellRate0; /* backward peak cell rate, CLP = 0 */ + U32 fwdPeakCellRate1; /* forward peak cell rate, CLP = 0+1 */ + U32 bwdPeakCellRate1; /* backward peak cell rate, CLP = 0+1 */ + U32 fwdSustCellRate0; /* forward sust. cell rate, CLP = 0 */ + U32 bwdSustCellRate0; /* backward sust. cell rate, CLP = 0 */ + U32 fwdSustCellRate1; /* forward sust. cell rate, CLP = 0+1 */ + U32 bwdSustCellRate1; /* backward sust. cell rate, CLP = 0+1 */ + U32 fwdMeanBurstSize0; /* forward mean burst size, CLP = 0 */ + U32 bwdMeanBurstSize0; /* backward mean burst size, CLP = 0 */ + U32 fwdMeanBurstSize1; /* forward mean burst size, CLP = 0+1 */ + U32 bwdMeanBurstSize1; /* backward mean burst size, CLP = 0+1 */ + Bool bstEffortReq; /* best effort requested */ + Bool fwdTagReq; /* tagging requested in forward direction */ + Bool bwdTagReq; /* tagging requested in backward direction */ +} AtmTfcDesc; + +#endif /* CMFILE_REORG_1 */ + + +/* scc typedefs */ + +typedef S16 Baud; /* baud */ + +typedef S16 PhysIntType; /* physical interface type */ + +typedef S16 PathConnType; /* path connection type */ + +typedef S16 Parity; /* parity */ + +typedef S16 CharLength; /* character length */ + +typedef S16 StopBits; /* stop bits */ + +/* tcp/ip typedefs */ + +typedef U32 IpAddr; /* IP address */ + +typedef U16 Port; /* TCP/UDP port */ + +typedef U8 Cmd; /* command */ + +typedef U8 Flags; /* TCP/UDP flags */ + +typedef U8 Ttl; /* time to live */ + +typedef U8 Prec; /* TCP/UDP precedence */ + +typedef U32 Window; /* TCP/UDP window */ + +typedef U8 MtpStatus; /* MTP status */ + +typedef U8 Credit; /* credit */ + +/* ISUP typedefs */ + +typedef U32 CirId; /* circuit Id */ + +typedef U16 Cic; /* cic */ + +typedef U32 SiInstId; /* instance id */ + +/* B-ISUP typedefs */ + +typedef U32 BiInstId; /* instance id */ + +/* TUP typedefs */ + +typedef U32 TpInstId; /* instance id */ + +/* LLC/SNAP definitions */ + +typedef U32 Oui; /* 3-octet OUI in SNAP header */ +typedef U16 Pid; /* 2-octet protocol id in SNAP header */ +typedef U32 LlcId; /* LLC id */ + + +#ifndef CMFILE_REORG_1 + +/* q.93b typedefs */ + +typedef S32 AmInstId; /* service user/provider instance id */ +typedef U16 AmEndptRefType; /* endpoint reference */ +typedef U32 AmSeqNmb; /* sequence number */ + +/* q.saal typedefs */ + +typedef U16 AsErrorCode; /* q.saal error code (Q.SAAL1 Appendix 1) */ + +/* ume typedefs */ + +typedef U32 UmInteger; /* ume integer */ + +typedef struct umObjId /* ume object identifier */ +{ + Data length; /* length of string */ + UmInteger strg[UM_MAXLEN_OBJ_ID]; /* string of sub-identifiers */ +} UmObjId; + +typedef struct umMib UmMib; /* ume mib */ + + +/* + * LAN Emulation typedefs + */ + +/* general typedefs */ + +typedef U16 LecId; /* LEC Id */ +typedef U8 Protocol; /* protocol */ +typedef U8 Version; /* version */ +typedef U16 OpCode; /* op code in control frames */ +typedef U16 LaneStatus; /* status in control frames */ +typedef U32 TransId; /* transaction id */ +typedef U16 LaneFlags; /* flags in control frames */ +typedef U8 LanType; /* LAN type */ +typedef U8 MtuIdx; /* max frame size - index */ +typedef U16 MtuVal; /* max frame size - value */ +typedef U16 Tag; /* tag indicating LAN destination type */ +typedef U8 VccNature; /* VCC nature - SVC, PVC, etc. */ +typedef U8 VccType; /* VCC type - control, data, etc */ +typedef U8 ProfileId; /* HCC profile id */ + + +typedef struct lanName /* LAN name */ +{ + U8 length; /* length of string */ + U8 strg[MAX_LANNAME]; /* name string */ +} LanName; + +/* LAN destination typedefs */ + +typedef struct macAddr /* MAC address */ +{ + U8 strg[MACADDRLEN]; /* address string */ +} MacAddr; + +typedef struct macAddrTblEntry /* entry in table of MAC addresses */ +{ + U8 proxyClass; /* proxy class - local, learned */ + MacAddr macAddr; /* MAC address */ +} MacAddrTblEntry; + +typedef struct macAddrTbl /* table of MAC addresses */ +{ + U8 count; /* number of entries */ + MacAddrTblEntry tbl[MAX_MACADDRTBL]; /* table of MAC addresses */ +} MacAddrTbl; + +typedef struct rd /* route designator */ +{ + U16 lanId; /* LAN id, segment id - 12 bits */ + U8 bridgeId; /* bridge id - 4 bits */ +} Rd; + +typedef struct rdTblEntry /* entry in table of route designators */ +{ + Rd rd; /* route designator */ +} RdTblEntry; + +typedef struct rdTbl /* table of route designators */ +{ + U8 count; /* number of entries */ + RdTblEntry tbl[MAX_RDTBL];/* table of route designator */ +} RdTbl; + +typedef struct lanDst /* LAN destination - MAC addr, route desg */ +{ + Tag tag; /* LAN destination type */ + union + { + MacAddr macAddr; /* MAC address */ + Rd rd; /* route designator */ + } ld; +} LanDst; + + +/* control frame typedefs */ + +typedef struct laneCtrlHdr /* control frame header */ +{ + LecId marker; /* control frame marker */ + Protocol protocol; /* LANE protocol */ + Version version; /* LANE version */ + OpCode opCode; /* operation code */ + LaneStatus status; /* request status */ + TransId transId; /* transaction id */ + LecId reqLecId; /* requestor LEC id */ + LaneFlags flags; /* bit flags */ + LanDst srcLanDst; /* source LAN destination */ + LanDst dstLanDst; /* target LAN destination */ + Addrs srcAtmAddr; /* source ATM address */ + Addrs dstAtmAddr; /* target ATM address */ + LanType lanType; /* LAN type */ + MtuIdx mtuIdx; /* MTU */ + U8 nmbTLV; /* number of TLV entries in list */ + LanName lanName; /* LAN name */ +} LaneCtrlHdr; + +typedef struct laneTLVEnt /* type-length-value entry */ +{ + U32 type; /* type of value */ + U8 length; /* length of value */ + U8 value[MAX_TLV_LEN]; /* value */ +} LaneTLVEnt; + +typedef struct laneCfg /* configuration frame */ +{ + LaneTLVEnt tlvTbl[MAX_TLV_TBL]; /* list of TLV entries */ +} LaneCfg; + +typedef struct laneCtrlFrame /* all control frames */ +{ + LaneCtrlHdr hdr; /* frame header */ + union /* remainder of frame */ + { + LaneCfg cfg; /* configuration frame */ + } m; +} LaneCtrlFrame; + +/* PNNI typedefs */ + +/* pnni port id */ +typedef U32 PnPortId; + +/* pnni node Id */ +typedef struct pnNodeId +{ + U8 id[PN_NODEID_LEN]; +} PnNodeId; + +#endif /* CMFILE_REORG_1 */ + + + +/* header typedefs */ + +typedef struct octStrg /* octet string */ +{ + S32 length; /* length */ + U8 val[MF_SIZE_TKNSTR]; /* value */ +} OctStrg; + +typedef struct tknHdr /* token header */ +{ + U8 pres; /* present */ + U8 spare1; /* for 16 bit alignment */ + U16 spare2; /* for 32 bit alignment */ +#ifdef ALIGN_64BIT + U32 spare3; /* for 64 bit alignment */ +#endif +} TknHdr; + +typedef struct elmtHdr /* element header */ +{ + U8 pres; /* present */ + U8 actnInd; /* action indicator */ + U16 compInd; /* for alignment */ +#ifdef ALIGN_64BIT + U32 spare; /* for 64 bit alignment */ +#endif +} ElmtHdr; + +/* token typedefs */ + +typedef struct tknU8 /* token U8 */ +{ + U8 pres; /* present flag */ + U8 val; /* value */ + U16 spare1; /* for alignment */ +#ifdef ALIGN_64BIT + U32 spare2; /* for 64 bit alignment */ +#endif +} TknU8; + +typedef struct tknS8 /* token S8 */ +{ + U8 pres; /* present flag */ + S8 val; /* value */ + U16 spare1; /* for alignment */ +#ifdef ALIGN_64BIT + U32 spare2; /* for 64 bit alignment */ +#endif +} TknS8; + +typedef struct tknU16 /* token U16 */ +{ + U8 pres; /* present flag */ + U8 spare1; /* for alignment */ + U16 val; /* value */ +#ifdef ALIGN_64BIT + U32 spare2; /* for 64 bit alignment */ +#endif +} TknU16; + +typedef struct tknU32 /* token U32 */ +{ + U8 pres; /* present flag */ + U8 spare1; /* for alignment */ + U16 spare2; /* for alignment */ + U32 val; /* value */ +} TknU32; + +typedef struct tknS32 /* token S32 */ +{ + U8 pres; /* present flag */ + U8 spare1; /* for alignment */ + U16 spare2; /* for alignment */ + S32 val; /* value */ +} TknS32; + +typedef struct tknStrS /* token string */ +{ + U8 pres; /* present flag */ + U8 len; /* length */ + U16 spare1; /* for alignment */ +#ifdef ALIGN_64BIT + U32 spare2; /* for 64 bit alignment */ + U8 val[(MF_SIZE_TKNSTRS + 7) & 0xff8]; /* string value */ +#else + U8 val[(MF_SIZE_TKNSTRS + 3) & 0xffc]; /* string value */ +#endif +} TknStrS; + +typedef struct tknStrM /* token string */ +{ + U8 pres; /* present flag */ + U8 len; /* length */ + U16 spare1; /* for alignment */ +#ifdef ALIGN_64BIT + U32 spare2; /* for 64 bit alignment */ + U8 val[(MF_SIZE_TKNSTRM + 7) & 0xff8]; /* string value */ +#else + U8 val[(MF_SIZE_TKNSTRM + 3) & 0xffc]; /* string value */ +#endif +} TknStrM; + +typedef struct tknStr /* token string */ +{ + U8 pres; /* present flag */ + U8 len; /* length */ + U16 spare1; /* for alignment */ +#ifdef ALIGN_64BIT + U32 spare2; /* for 64 bit alignment */ + U8 val[(MF_SIZE_TKNSTR + 7) & 0xff8]; /* string value */ +#else + U8 val[(MF_SIZE_TKNSTR + 3) & 0xffc]; /* string value */ +#endif +} TknStr; + +typedef struct tknStrE /* token string extended */ +{ + U8 pres; /* present flag */ + U8 len; /* length */ + U16 spare1; /* for alignment */ +#ifdef ALIGN_64BIT + U32 spare2; /* for 64 bit alignment */ + U8 val[(MF_SIZE_TKNSTRE + 7) & 0xff8]; /* string value */ +#else + U8 val[(MF_SIZE_TKNSTRE + 3) & 0xffc]; /* string value */ +#endif +} TknStrE; + +typedef struct tknStrXL /* token string extra long */ +{ + U16 len; /* length */ + U8 pres; /* present flag */ + U8 spare1; /* for alignment */ +#ifdef ALIGN_64BIT + U32 spare2; /* for 64 bit alignment */ +#endif + U8 *val; /* string value (use allocated memory) */ +} TknStrXL; + +typedef struct tknStr4 /* token string */ +{ + U8 pres; /* present flag */ + U8 len; /* length */ + U16 spare1; /* for alignment */ +#ifdef ALIGN_64BIT + U32 spare2; /* for 64 bit alignment */ + U8 val[8]; /* string value - 8 byte alligned */ +#else + U8 val[4]; /* string value - 4 byte alligned */ +#endif /* ALIGN_64BIT */ +} TknStr4; + +typedef struct tknStr12 /* token string */ +{ + U8 pres; /* present flag */ + U8 len; /* length */ + U16 spare1; /* for alignment */ +#ifdef ALIGN_64BIT + U32 spare2; /* for 64 bit alignment */ + U8 val[16]; /* string value - 8 byte alligned */ +#else + U8 val[12]; /* string value - 4 byte alligned */ +#endif /* ALIGN_64BIT */ +} TknStr12; + +typedef struct tknStr32 /* token string */ +{ + U8 pres; /* present flag */ + U8 len; /* length */ + U16 spare1; /* for alignment */ +#ifdef ALIGN_64BIT + U32 spare2; /* for 64 bit alignment */ +#endif + U8 val[32]; /* string value - 4 byte alligned */ +} TknStr32; + +typedef struct tknStr64 /* token string */ +{ + U8 pres; /* present flag */ + U8 len; /* length */ + U16 spare1; /* for alignment */ +#ifdef ALIGN_64BIT + U32 spare2; /* for 64 bit alignment */ +#endif + U8 val[64]; /* string value - 4 byte alligned */ +} TknStr64; + +typedef struct tknStr132 /* token string */ +{ + U8 pres; /* present flag */ + U8 len; /* length */ + U16 spare1; /* for alignment */ +#ifdef ALIGN_64BIT + U32 spare2; /* for 64 bit alignment */ + U8 val[136]; /* string value - 8 byte alligned */ +#else + U8 val[132]; /* string value - 4 byte alligned */ +#endif /* ALIGN_64BIT */ +} TknStr132; + +typedef struct tknStr256 /* token string */ +{ + U8 pres; /* present flag */ + U8 len; /* length */ + U16 spare1; /* for alignment */ +#ifdef ALIGN_64BIT + U32 spare2; /* for 64 bit alignment */ +#endif + U8 val[256]; /* string value - 4 byte alligned */ +} TknStr256; + +typedef struct tknOid /* Object Identifier */ +{ + U8 pres; /* present flag */ + U8 len; /* length */ + U16 spare1; /* for alignment */ +#ifdef ALIGN_64BIT + U32 spare2; /* for 64 bit alignment */ +#endif + /* gen_x_001.main_81 : changed val from U32 to U16 with comilation flag + * TKNOID_U16 */ +#ifndef TKNOID_U16 + U32 val[32]; /* max 32 integers of less than 64k value */ +#else + U16 val[32]; /* max 32 integers of less than 64k value */ +#endif +} TknOid; + +typedef struct tknBits /* token bits */ +{ + U8 pres; /* present flag */ + U8 len; /* for alignment */ + U16 spare1; /* for alignment */ +#ifdef ALIGN_64BIT + U32 spare2; /* for 64 bit alignment */ + U8 val[(MF_SIZE_TKNBITS + 7) & 0xff8]; /* string value */ +#else + U8 val[(MF_SIZE_TKNBITS + 3) & 0xffc]; /* string value */ +#endif +} TknBits; + +typedef struct elmtStr /* element string */ +{ + ElmtHdr eh; /* element header */ + TknStr str; /* network specific information */ +} ElmtStr; + +typedef struct cdPtyNmb /* called party number tokens */ +{ + ElmtHdr eh; /* element header */ + TknU8 nmbPlanId; /* numbering plan identification */ + TknU8 typeNmb0; /* type of number */ +#ifdef CDPTYNMB_32DIGIT + TknStrM nmbDigits; /* number digits */ +#else + TknStrS nmbDigits; /* number digits */ +#endif /* CDPTYNMB_32DIGIT */ +} CdPtyNmb; + +typedef struct redirNmb /* redirecting number tokens */ +{ + ElmtHdr eh; /* element header */ + TknU8 nmbPlanId; /* numbering plan identification */ + TknU8 typeNmb; /* type of number */ + TknU8 screenInd; /* screening indicator */ + TknU8 presInd; /* presentation indicator */ + TknU8 rsnRedirect; /* reason for redirection */ + TknStrS nmbDigits; /* number digits */ +} RedirNmb; + +typedef struct srvClass /* service class */ +{ + U8 type; /* type */ + union + { + struct /* frame relay */ + { + Bool cr; /* command response bit */ + Bool de; /* discard eligibility bit */ + } fr; + struct /* mac */ + { + Prior prior; /* priority */ + } ma; + } s; +} SrvClass; + +/* ip header, without options */ + +typedef struct _ip /* ip header */ +{ + U8 ip_hl; /* header length */ + Prec ip_tos; /* type of service */ + U16 ip_len; /* total length */ + U16 ip_id; /* identification */ + U16 ip_off; /* fragment offset field */ + Ttl ip_ttl; /* time to live */ + U8 ip_p; /* protocol */ + U16 ip_sum; /* checksum */ + IpAddr ip_src; /* source address */ + IpAddr ip_dst; /* dest address */ +} Ip; + + +/* ATM structures */ + +#ifndef CMFILE_REORG_1 + +/* info elements that can be used for routing calls */ + +typedef struct amCdPtySad /* Called Party Sub Address Tokens */ +{ + ElmtHdr eh; /* element header */ + TknU8 oddEvenInd; /* odd/even indicator */ + TknU8 typeSad; /* type of sub address */ + TknStrS sadInfo; /* address/number information */ +} AmCdPtySad; + +typedef struct amBHiLyrInfo /* Broadband High Layer Information Tokens */ +{ + ElmtHdr eh; /* element header */ + TknU8 hiLyrInfoType; /* high layer information type */ + TknStrS hiLyrInfo; /* high layer information */ +} AmBHiLyrInfo; + +typedef struct amBBearCap /* Broadband Bearer Capability Tokens */ +{ + ElmtHdr eh; /* element header */ + TknU8 bearClass; /* bearer class */ + TknU8 timingReq; /* timing requirement */ + TknU8 tfcType; /* traffic type */ + TknU8 atmTfrCap; /* ATM transfer capability */ + TknU8 usrPlaneConCfg; /* user plane connection configuration */ + TknU8 suscClip; /* susceptability to clipping */ +} AmBBearCap; + +typedef struct amQosParam /* Quality of Service Parameter Tokens */ +{ + ElmtHdr eh; /* element header */ + TknU8 qosClassFwd; /* quality of service class forward */ + TknU8 qosClassBwd; /* quality of service class backward */ +} AmQosParam; + +typedef struct amEtoeDly /* End To End Transit Delay Tokens */ +{ + ElmtHdr eh; /* element header */ + TknU8 cumTransDlyId; /* cumulative transit delay id */ + TknU16 cumTransDly; /* cumulative transit delay value */ + TknU8 reqTransDlyId; /* requested max end to end transit delay id */ + TknU16 reqTransDly; /* maximum end to end transit delay value */ + TknU8 pnniAccFMCTDId; /* PNNI acceptable forward max. CTD ID */ + TknU32 pnniAccFMCTD; /* PNNI acceptable forward max. CTD */ + TknU8 pnniCumFMCTDId; /* PNNI acceptable forward max. CTD ID */ + TknU32 pnniCumFMCTD; /* PNNI acceptable forward max. CTD */ + TknU8 netGenInd; /* network generated indicator */ +} AmEtoeDly; + +typedef struct amOamTfcDesc /* OAM Traffic Descriptor Tokens */ +{ + ElmtHdr eh; /* element header */ + TknU8 usrNetFaultMgmt; /* user network fault management indicator */ + TknU8 compInd; /* compliance indicator */ + TknU8 shapingInd; /* shaping indicator */ + TknU8 bwdEtoeOamF5FlInd; /* backward e-to-e OAM F5 flow indicator */ + TknU8 fwdEtoeOamF5FlInd; /* forward e-to-e OAM F5 flow indicator */ +} AmOamTfcDesc; + +typedef struct amEndptRef /* Endpoint Reference Tokens */ +{ + ElmtHdr eh; /* element header */ + TknU8 endptRefType; /* endpoint reference type */ + TknU16 endptRefVal; /* endpoint reference value */ +} AmEndptRef; + +typedef struct amAalParam /* AAL Parameters Tokens */ +{ + ElmtHdr eh; /* element header */ + TknU8 aalType; /* AAL type */ + + /* Token definition for AAL-1 */ + TknU8 subTypeId; /* Subtype Identifier */ + TknU8 subType; /* Subtype */ + TknU8 cbrRateId; /* CBR Rate Identifier */ + TknU8 cbrRate; /* CBR Rate */ + TknU8 multId; /* Multiplier Identifier */ + TknU16 multVal; /* Multiplier value */ + TknU8 srcClkFreqMetId; /* Source clock Frequency method identifier */ + TknU8 srcClkFreqMet; /* Source Clock frequency method */ + TknU8 errCrMetId; /* Error correction method identifier */ + TknU8 errCrMet; /* Error correction method */ + TknU8 strDatTxBlkszId; /* Structured data transfer blocksize Id. */ + TknU8 strDatTxBlksz0; /* Structured data transfer blocksize - oct 1*/ + + /* Token definition for AAL-1, except in UNI 3.0 */ + TknU8 strDatTxBlksz1; /* Structured data transfer blocksize - oct 2*/ + + /* Token definition for AAL-1 */ + TknU8 prtFillCellId; /* Partially filled cells Identifier */ + TknU8 prtFillCellMet; /* Partially filled cells method */ + + /* Token definition for AAL-3/4 and AAL-5 */ + TknU8 fwdMaxCpcsSduSzId; /* Forward maximum CPCS-SDU size identifier */ + TknU16 fwdMaxCpcsSduSz; /* Forward maximum CPCS-SDU size */ + TknU8 bwdMaxCpcsSduSzId; /* Forward maximum CPCS-SDU size identifier */ + TknU16 bwdMaxCpcsSduSz; /* Forward maximum CPCS-SDU size */ + + /* Token definition for AAL-3/4 only */ + TknU8 midRangeId; /* MID Range identifier */ + TknU16 loMidRange; /* MID Range value */ + + /* Token definition for AAL-3/4 only, except in UNI 3.0 */ + TknU16 hiMidRange; /* MID Range value */ + + /* Token definition for AAL-3/4 and AAL-5 and only for UNI 3.0 */ + TknU8 modeId; /* Mode identifier */ + TknU8 mode; /* Mode - Streaming/Message */ + + /* Token definition for AAL-3/4 and AAL-5 */ + TknU8 sscsTypeId; /* SSCS Type Identifier */ + TknU8 sscsType; /* SSCS Type */ + + /* Token definition for User defined AAL */ + TknU32 usrDefAalInfo; /* User defined AAL information */ +} AmAalParam; + +typedef struct amBLoLyrInfo /* Broadband Low Layer Information Tokens */ +{ + ElmtHdr eh; /* element header */ + TknU8 usrInfoLyr1Prot; /* user information layer 1 protocol */ + TknU8 lyr1Id; /* Layer 1 id */ + TknU8 usrInfoLyr2Prot; /* user information layer 2 protocol */ + TknU8 lyr2Id; /* Layer 2 id */ + TknU8 q933Use; /* Q.933 use */ + TknU8 lyr2OprMode; /* Mode of operation */ + TknU8 winSize; /* Window size */ + TknU8 usrSpecLyr2ProtInfo; /* User specified layer 2 protocol info */ + TknU8 usrInfoLyr3Prot; /* user information layer 3 protocol */ + TknU8 lyr3Id; /* Layer 3 id */ + TknU8 lyr3OprMode; /* Mode of operation */ + TknU8 defPktSize; /* Default packet size */ + TknU8 pktWinSize; /* Default packet size */ + TknU8 usrSpecLyr3ProtInfo; /* User specified layer 3 protocol info */ + TknU8 initProtId; /* Initial protocol Identifier bits 8-2 */ + TknU8 snapId; /* SNAP identifier */ + TknU32 oui; /* Organisation unique identifier */ + TknU16 protId; /* Protocol identifier */ +} AmBLoLyrInfo; + +typedef struct amAtmTfcDesc /* ATM Traffic Descriptor Tokens */ +{ + ElmtHdr eh; /* element header */ + TknU8 fwdPeakCellRateId0; /* forward peak cell rate id, CLP = 0 */ + TknU32 fwdPeakCellRate0; /* forward peak cell rate, CLP = 0 */ + TknU8 bwdPeakCellRateId0; /* backward peak cell rate id, CLP = 0 */ + TknU32 bwdPeakCellRate0; /* backward peak cell rate, CLP = 0 */ + TknU8 fwdPeakCellRateId1; /* forward peak cell rate id, CLP = 0+1 */ + TknU32 fwdPeakCellRate1; /* forward peak cell rate, CLP = 0+1 */ + TknU8 bwdPeakCellRateId1; /* backward peak cell rate id, CLP = 0+1 */ + TknU32 bwdPeakCellRate1; /* backward peak cell rate, CLP = 0+1 */ + TknU8 fwdSustCellRateId0; /* forward sust. cell rate id, CLP = 0 */ + TknU32 fwdSustCellRate0; /* forward sust. cell rate, CLP = 0 */ + TknU8 bwdSustCellRateId0; /* backward sust. cell rate id, CLP = 0 */ + TknU32 bwdSustCellRate0; /* backward sust. cell rate, CLP = 0 */ + TknU8 fwdSustCellRateId1; /* forward sust. cell rate id, CLP = 0+1 */ + TknU32 fwdSustCellRate1; /* forward sust. cell rate, CLP = 0+1 */ + TknU8 bwdSustCellRateId1; /* backward sust. cell rate id, CLP = 0+1 */ + TknU32 bwdSustCellRate1; /* backward sust. cell rate, CLP = 0+1 */ + TknU8 fwdMeanBurstSizeId0; /* forward mean burst size id, CLP = 0 */ + TknU32 fwdMeanBurstSize0; /* forward mean burst size, CLP = 0 */ + TknU8 bwdMeanBurstSizeId0; /* backward mean burst size id, CLP = 0 */ + TknU32 bwdMeanBurstSize0; /* backward mean burst size, CLP = 0 */ + TknU8 fwdMeanBurstSizeId1; /* forward mean burst size id, CLP = 0+1 */ + TknU32 fwdMeanBurstSize1; /* forward mean burst size, CLP = 0+1 */ + TknU8 bwdMeanBurstSizeId1; /* backward mean burst size id, CLP = 0+1 */ + TknU32 bwdMeanBurstSize1; /* backward mean burst size, CLP = 0+1 */ + TknU8 bstEffortReq; /* best effort requested */ + TknU8 tfcMgmtOptId; /* traffic management options identifier */ + TknU8 fwdTagReq; /* tagging requested in forward direction */ + TknU8 bwdTagReq; /* tagging requested in backward direction */ + TknU8 bwdFrmDisc; /* frame discard in backward direction */ + TknU8 fwdFrmDisc; /* frame discard in forward direction */ + TknU8 fwdAbrMinCellRateId; /* forward ABR min. cell rate id, CLP = 0+1 */ + TknU32 fwdAbrMinCellRate; /* forward ABR min. cell rate, CLP = 0+1 */ + TknU8 bwdAbrMinCellRateId; /* backward ABR min. cell rate id, CLP = 0+1 */ + TknU32 bwdAbrMinCellRate; /* backward ABR min. cell rate, CLP = 0+1 */ +} AmAtmTfcDesc; + +typedef struct amCauseDgn /* Cause and Diagnostics Tokens */ +{ + ElmtHdr eh; /* element header */ + TknU8 location; /* location */ + TknU8 causeVal; /* cause value */ + TknStrM dgnVal; /* Diagnostics value */ +} AmCauseDgn; + +typedef struct amCgPtyNmb /* Calling Party Number Tokens */ +{ + ElmtHdr eh; /* element header */ + TknU8 nmbPlanId; /* address/numbering plan identification */ + TknU8 typeNmb; /* type of number */ + TknU8 screenInd; /* screening indicator */ + TknU8 presInd; /* presentation indicator */ + TknStrS nmbDigits; /* address/number information */ +} AmCgPtyNmb; + +typedef struct amCgPtySad /* Calling Party Sub Address Tokens */ +{ + ElmtHdr eh; /* element header */ + TknU8 oddEvenInd; /* odd/even indicator */ + TknU8 typeSad; /* type of sub address */ + TknStrS sadInfo; /* address/number information */ +} AmCgPtySad; + +typedef struct amNBearCap /* Narrowband Bearer Capability Tokens */ +{ + ElmtHdr eh; /* element header */ + TknU8 infoTranCap; /* information transfer capability */ + TknU8 codingStd; /* coding standard */ + TknU8 infoTranRate0; /* information transfer rate */ + TknU8 tranMode; /* transfer mode */ + TknU8 establish; /* establishment */ + TknU8 cfg; /* configuration */ + TknU8 chanStruct; /* structure */ + TknU8 infoTranRate1; /* information transfer rate */ + TknU8 symmetry; /* symmetry */ + TknU8 usrInfoLyr1Prot; /* usr information layer 1 protocol */ + TknU8 lyr1Ident; /* layer 1 identity */ + TknU8 usrRate; /* user rate */ + TknU8 negot; /* negotiation */ + TknU8 syncAsync; /* synchronous/asynchronous */ +/*------------------------------------------------------------------------*/ +/* The following six tokens represent a uinon of octets 5b.1 and 5b.2 of */ +/* the Narrow Band Bearer Capability. */ +/*------------------------------------------------------------------------*/ + TknU8 FlcRx_BandNeg; /* flow control on reception or + inband/outband negotiation */ + TknU8 FlcTx_Assgn; /* flow control on transmission or + assignor/assignee*/ + TknU8 NicRx_LLINeg; /* network independent clock on reception or + logical link identifier negotiation */ + TknU8 NicTx_Mode; /* network independent clock on transmission or + mode of operation */ + TknU8 Rate_MFrm; /* intermediate rate (low bit) or Multi + frame support */ + TknU8 Rate_Hdr; /* intermediate rate (high bit) or rate + adaptation Hdr/ no Headr */ + TknU8 parity; /* parity information */ + TknU8 nmbDatBits; /* number of data bits excluding parity bit */ + TknU8 nmbStopBits; /* number of stop bits */ + TknU8 modemType; /* modem type */ + TknU8 duplexMode; /* duplex mode */ + TknU8 usrInfoLyr2Prot; /* user information layer 2 protocol */ + TknU8 lyr2Ident; /* layer 2 identity */ + TknU8 usrInfoLyr3Prot; /* user information layer 3 protocol */ + TknU8 lyr3Ident0; /* layer 3 identity */ +} AmNBearCap; + +typedef struct amNLoLyrComp /* Narrowband Low Layer Compatibility Tokens */ +{ + ElmtHdr eh; /* element header */ + TknU8 infoTranCap; /* information transfer capability */ + TknU8 codingStd; /* coding standard */ + TknU8 negInd; /* negotiation indicator */ + TknU8 infoTranRate0; /* information transfer rate */ + TknU8 tranMode; /* transfer mode */ + TknU8 establish; /* establishment */ + TknU8 cfg; /* configuration */ + TknU8 chanStruct; /* structure */ + TknU8 infoTranRate1; /* information transfer rate */ + TknU8 symmetry; /* symmetry */ + TknU8 usrInfoLyr1Prot; /* usr information layer 1 protocol */ + TknU8 lyr1Ident; /* layer 1 identity */ + TknU8 usrRate; /* user rate */ + TknU8 negot; /* negotiation */ + TknU8 syncAsync; /* synchronous/asynchronous */ +/*------------------------------------------------------------------------*/ +/* The following six tokens represent a uinon of octets 5b.1 and 5b.2 of */ +/* the Narrow Band Lower Layer Compatibility */ +/*------------------------------------------------------------------------*/ + TknU8 FlcRx_BandNeg; /* flow control on reception or + inband/outband negotiation */ + TknU8 FlcTx_Assgn; /* flow control on transmission or + assignor/assignee*/ + TknU8 NicRx_LLINeg; /* network independent clock on reception or + logical link identifier negotiation */ + TknU8 NicTx_Mode; /* network independent clock on transmission or + mode of operation */ + TknU8 Rate_MFrm; /* intermediate rate (low bit) or Multi + frame support */ + TknU8 Rate_Hdr; /* intermediate rate (high bit) or rate + adaptation Hdr/ no Headr */ + TknU8 parity; /* parity information */ + TknU8 nmbDatBits; /* number of data bits excluding parity bit */ + TknU8 nmbStopBits; /* number of stop bits */ + TknU8 modemType; /* modem type */ + TknU8 duplexMode; /* duplex mode */ + TknU8 usrInfoLyr2Prot; /* user information layer 2 protocol */ + TknU8 lyr2Ident; /* layer 2 identity */ + TknU8 optLyr2ProtInfo; /* optional layer 2 protocol information */ + TknU8 usrInfoLyr3Prot; /* user information layer 3 protocol */ + TknU8 lyr3Ident1; /* layer 3 identity */ + TknU8 optLyr3ProtInfo; /* optional layer 3 protocol information */ +} AmNLoLyrComp; + +typedef struct amNHiLyrComp /* Narrowband High Layer Compatibility Tokens */ +{ + ElmtHdr eh; /* element header */ + TknU8 presMethod; /* presentation method */ + TknU8 interpretation; /* interpretation */ + TknU8 codingStd; /* coding standard */ + TknU8 highLyrCharId; /* high layer characteristics identification */ + TknU8 extHighLyrCharId; /* extended high layer characteristics id */ +} AmNHiLyrComp; + +typedef struct amProgInd /* Progress Indicator Tokens */ +{ + ElmtHdr eh; /* element header */ + TknU8 progLocation; /* location */ + TknU8 codingStd; /* coding standard */ + TknU8 progDesc; /* progress description */ +} AmProgInd; + +#if (DEF_SIG_PNNI | DEF_SIG_AINI) +typedef struct amCrankback /* Crankback Tokens */ +{ + ElmtHdr eh; /* element header */ + TknU8 cbLevel; /* crankback level */ + TknU8 blkTransType; /* blocked transit type */ +#ifdef SIG_PNNI + TknStrS blkNodeId; /* blocked node id */ + TknStrS blkLinkPreNodeId; /* blocked link's preceeding node id */ + TknU32 blkLinkPortId; /* blocked link port id */ + TknStrS blkLinkSuccNodeId; /* blocked link's succeding node id */ +#endif /* SIG_PNNI */ + TknU8 cbCause; /* crankback cause */ +#ifdef SIG_PNNI + TknStrM cbDgn; /* crankback cause diagnostics */ +#endif /* SIG_PNNI */ +} AmCrankback; + +typedef struct amCdPtySoftPvc /* Called Party Soft PVPC/PVCC Tokens */ +{ + ElmtHdr eh; /* element header */ + TknU8 selType; /* VPI/VCI selection Type */ + TknU8 vpiId; /* VPI id */ + TknU16 vpi; /* VPI */ + TknU8 vciId; /* VCI id */ + TknU16 vci; /* VCI */ +#ifdef SPVC_FR + TknU8 dlciId; /* DLCI Identifer */ + TknU32 dlci; /* Dlci Value */ +#endif /* SPVC_FR */ +} AmCdPtySoftPvc; + +typedef struct amCgPtySoftPvc /* Calling Party Soft PVPC/PVCC Tokens */ +{ + ElmtHdr eh; /* element header */ + TknU8 vpiId; /* VPI id */ + TknU16 vpi; /* VPI */ + TknU8 vciId; /* VCI id */ + TknU16 vci; /* VCI */ +#ifdef SPVC_FR + TknU8 dlciId; /* DLCI Identifer */ + TknU32 dlci; /* Dlci Value */ +#endif /* SPVC_FR */ +} AmCgPtySoftPvc; +#endif /* DEF_SIG_PNNI | DEF_SIG_AINI */ + +typedef struct amConnNmb /* Connected Number Tokens */ +{ + ElmtHdr eh; /* element header */ + TknU8 nmbPlanId; /* address/numbering plan identification */ + TknU8 typeNmb; /* type of number */ + TknU8 screenInd; /* screening indicator */ + TknU8 presInd; /* presentation indicator */ + TknStrS nmbDigits; /* address/number information */ +} AmConnNmb; + +#if (DEF_SIG_PNNI | DEF_SIG_AINI | DEF_UNI40) +typedef struct amConnSad /* Calling Party Sub Address Tokens */ +{ + ElmtHdr eh; /* element header */ + TknU8 oddEvenInd; /* odd/even indicator */ + TknU8 typeSad; /* type of sub address */ + TknStrS sadInfo; /* address/number information */ +} AmConnSad; + +typedef struct amGenIdTrans /* Generic Identifier Transport Tokens */ +{ + ElmtHdr eh; /* element header */ + TknStrM genId; /* generic identifier */ +} AmGenIdTrans; + +typedef AmAtmTfcDesc AmAltAtmTfcDesc; /* Alternative ATM Traffic Desc. */ + +typedef struct amMinAccAtmTfcDesc /* Minimum acceptable ATM Traffic Desc. */ +{ + ElmtHdr eh; /* element header */ + TknU8 fwdPeakCellRateId0; /* forward peak cell rate id, CLP = 0 */ + TknU32 fwdPeakCellRate0; /* forward peak cell rate, CLP = 0 */ + TknU8 bwdPeakCellRateId0; /* backward peak cell rate id, CLP = 0 */ + TknU32 bwdPeakCellRate0; /* backward peak cell rate, CLP = 0 */ + TknU8 fwdPeakCellRateId1; /* forward peak cell rate id, CLP = 0+1 */ + TknU32 fwdPeakCellRate1; /* forward peak cell rate, CLP = 0+1 */ + TknU8 bwdPeakCellRateId1; /* backward peak cell rate id, CLP = 0+1 */ + TknU32 bwdPeakCellRate1; /* backward peak cell rate, CLP = 0+1 */ +} AmMinAccAtmTfcDesc; + +typedef struct amExtQosParam /* Extended QOS parameter */ +{ + ElmtHdr eh; /* element header */ + TknU8 origin; /* origin of this IE */ + TknU8 accFwdPpCDVId; /* acceptable forward peak-to-peak cell + * delay variation identifier */ + TknU32 accFwdPpCDV; /* acceptable forward peak-to-peak cell + * delay variation */ + TknU8 accBwdPpCDVId; /* acceptable backward peak-to-peak cell + * delay variation identifier */ + TknU32 accBwdPpCDV; /* acceptable backward peak-to-peak cell + * delay variation */ + TknU8 cumFwdPpCDVId; /* cumulative forward peak-to-peak cell + * delay variation identifier */ + TknU32 cumFwdPpCDV; /* cumulative forward peak-to-peak cell + * delay variation */ + TknU8 cumBwdPpCDVId; /* cumulative backward peak-to-peak cell + * delay variation identifier */ + TknU32 cumBwdPpCDV; /* cumulative backward peak-to-peak cell + * delay variation */ + TknU8 accFwdCLRId; /* acceptable forward cell loss ratio + * identifier */ + TknU8 accFwdCLR; /* acceptable forward cell loss ratio */ + TknU8 accBwdCLRId; /* acceptable backward cell loss ratio + * identifier */ + TknU8 accBwdCLR; /* acceptable backward cell loss ratio */ +} AmExtQosParam; + +typedef struct amAbrAddParam /* ABR additional parameters */ +{ + ElmtHdr eh; /* element header */ + TknU8 fwdAddParamRecId; /* forward additional parameters record identifier */ + TknU32 fwdAddParamRec; /* forward additional parameters record */ + TknU8 bwdAddParamRecId; /* backward additional parameters record identifier */ + TknU32 bwdAddParamRec; /* backward additional parameters record */ +} AmAbrAddParam; + +typedef struct amAbrSetupParam /* ABR Setup parameters */ +{ + ElmtHdr eh; /* element header */ + TknU8 fwdAbrICRId; /* forward ABR initial cell rate identifier */ + TknU32 fwdAbrICR; /* forward ABR initial cell rate */ + TknU8 bwdAbrICRId; /* backward ABR initial cell rate identifier */ + TknU32 bwdAbrICR; /* backward ABR initial cell rate */ + TknU8 fwdAbrTBEId; /* forward ABR transient buffer exposure identifier */ + TknU32 fwdAbrTBE; /* forward ABR transient buffer exposure */ + TknU8 bwdAbrTBEId; /* backward ABR transient buffer exposure identifier */ + TknU32 bwdAbrTBE; /* backward ABR transient buffer exposure */ + TknU8 cumRmFRTTId; /* cumulative RM fixed round trip time identifier */ + TknU32 cumRmFRTT; /* cumulative RM fixed round trip time */ + TknU8 fwdRIFId; /* forward rate increment factor identifier */ + TknU8 fwdRIF; /* forward rate increment factor */ + TknU8 bwdRIFId; /* backward rate increment factor identifier */ + TknU8 bwdRIF; /* backward rate increment factor */ + TknU8 fwdRDFId; /* forward rate decrement factor identifier */ + TknU8 fwdRDF; /* forward rate decrement factor */ + TknU8 bwdRDFId; /* backward rate decrement factor identifier */ + TknU8 bwdRDF; /* backward rate decrement factor */ +} AmAbrSetupParam; +#endif /* DEF_SIG_PNNI | DEF_SIG_AINI | DEF_UNI40 */ + +#if (DEF_Q2931 | DEF_SIG_PNNI | DEF_SIG_AINI | DEF_UNI40) +typedef struct amNotInd /* Notification Indicator Tokens */ +{ + ElmtHdr eh; /* element header */ + TknStrE notDesc; /* notification description */ +} AmNotInd; +#endif /* DEF_Q2931 | DEF_SIG_PNNI | DEF_SIG_AINI | DEF_UNI40 */ + + +/* AAL structure */ + +typedef struct aalConParam /* connection parameters for AAL */ +{ + AmAalParam aalParam; /* AAL Parameters */ + AmAtmTfcDesc atmTfcDesc; /* ATM Traffic Descriptor */ + AmBBearCap bBearCap; /* Broadband Bearer Capability */ + AmQosParam qosParam; /* Qos parameters */ + AmEtoeDly etoeDly; /* End to End Transit Delay */ + AmOamTfcDesc oamTfcDesc; /* OAM Traffic Descriptor */ +} AalConParam; + +typedef struct amCdPtyNmb /* Called Party Number Tokens */ +{ + ElmtHdr eh; /* element header */ + TknU8 nmbPlanId; /* address/numbering plan identification */ + TknU8 typeNmb; /* type of number */ + TknStrS nmbDigits; /* address/number information */ +} AmCdPtyNmb; + +#endif /* CMFILE_REORG_1 */ + + + +/* management structures */ + +typedef struct smCfg /* stack manager */ +{ + Ent ent; /* entity */ + Inst inst; /* instance */ + Region region; /* region */ + Pool pool; /* pool */ + Priority prior; /* priority */ + Route route; /* route */ + Selector selector; /* selector */ +} SmCfg; + +typedef struct mem /* memory */ +{ + Region region; /* region */ + Pool pool; /* pool */ + U16 spare; /* spare for alignment */ +} Mem; + +typedef Mem MemoryId; /* memory id */ + + +typedef struct resp +{ + Selector selector; /* selector */ + Priority prior; /* priority */ + Route route; /* route */ + MemoryId mem; /* memory */ +}Resp; + +typedef struct tds_header /* header */ +{ + U16 msgLen; /* message length - optional */ + U8 msgType; /* message type - mandatory */ + U8 version; /* version - optional */ + U16 seqNmb; /* sequence number - optional */ + EntityId entId; /* entity id - mandatory */ + ElmntId elmId; /* element id - mandatory */ +#ifdef LMINT3 + TranId transId; /* transaction Id - mandatory */ + Resp response; /* response parameters - mandatory */ +#endif /* LMINT3 */ +} Header; + +typedef struct tmrCfg /* timer configuration structure */ +{ + Bool enb; /* enable */ + U16 val; /* value */ +} TmrCfg; + +typedef struct asyncCfg /* asynchronous configuration */ +{ + StopBits stopBits; /* stop bits */ + CharLength charLength; /* character length */ + Parity rxParity; /* receive parity */ + Parity txParity; /* transmit parity */ +} AsyncCfg; + + +/* dateTime structure */ + +typedef struct dateTime /* date and time */ +{ + U8 month; /* month */ + U8 day; /* day */ + U8 year; /* year */ + U8 hour; /* hour - 24 hour clock */ + U8 min; /* minute */ + U8 sec; /* second */ + U8 tenths; /* tenths of second */ + /*-- gen_x_001.main_90 - Added variable for microseconds in DateTime--*/ +#ifdef SS_DATETIME_USEC + U32 usec; /* micro seconds */ +#endif /*-- SS_DATETIME_USEC --*/ +} DateTime; +/* gen_x_001.main_94: Additions */ +/* gen_x_001.main_95: Modifications */ +typedef U64 EpcTime; + +/* common status */ +typedef struct cmStatus +{ + U16 status; /* status of request */ + U16 reason; /* failure reason */ +}CmStatus; + +/* common alarm */ +typedef struct cmAlarm +{ + DateTime dt; /* data and time */ + U16 category; /* alarm category*/ + U16 event; /* alarm event */ + U16 cause; /* alarm cause */ +}CmAlarm; + +/* duration structure */ + +typedef struct duration /* duration */ +{ + U8 days; /* days */ + U8 hours; /* hours */ + U8 mins; /* minutes */ + U8 secs; /* seconds */ + U8 tenths; /* tenths of seconds */ +} Duration; + + + + + +#ifdef CMFILE_REORG_1 + +#ifdef SS +typedef struct ssmsgb Buffer; + +#ifdef FLAT_BUFFER_OPT +typedef struct _flatBuffer +{ + U8* startAddr; + U8* ptr; + U32 len; +}FlatBuffer; +#endif + +#else /* SS */ + +#ifdef WINNT_IATM /* Windows NT Integrated ATM */ +#ifndef CFG_APP /* Don't include ndis.h for config app. */ +#include "ndis.h" /* to support NDIS calls (listed above) */ +#endif /* CFG_APP */ + +typedef struct _NDIS_PACKET Buffer; /* forward definition - buffer */ +#else +typedef struct ss_buffer Buffer; /* forward definition - buffer */ + +#endif /* WINNT_IATM */ +#endif /* SS */ + +typedef struct tknBuf +{ + U8 pres; /* Present Flag */ + U8 spare1; /* for alignment */ + U16 spare2; /* for 32 bit alignment */ +#ifdef ALIGN_64BIT + U32 spare3; /* for 64 bit alignment */ +#endif + Buffer *val; /* Buffer type (use allocated memory) */ +} TknBuf; + +/* defining the CmIpAddr and CmIpAddr6 */ +/* socket typedefs and structs */ +typedef U32 CmIpAddr; /* 4 byte IP address */ +#ifdef IPV6_SUPPORTED +typedef U8 CmIpAddr6[16]; /* 16 byte IPV6 address */ +#endif /* IPV6_SUPPORTED */ + +/* common packing functions */ + +/* system services structures */ +EXTERN S16 cmPkDateTime ARGS((DateTime *dateTime, Buffer *mBuf)); +EXTERN S16 cmPkDuration ARGS((Duration *duration, Buffer *mBuf)); +EXTERN S16 cmPkPtr ARGS((PTR ptr, Buffer *mBuf)); +EXTERN S16 cmPkEntityId ARGS((EntityId *entityId, Buffer *mBuf)); +EXTERN S16 cmPkElmntId ARGS((ElmntId *elmntId, Buffer *mBuf)); +EXTERN S16 cmPkMemoryId ARGS((MemoryId *memoryId, Buffer *mBuf)); + +/* general structures */ +EXTERN S16 cmPkSystemId ARGS((SystemId *systemId, Buffer *mBuf)); +EXTERN S16 cmPkAddrs ARGS((Addrs *addrs, Buffer *mBuf)); +EXTERN S16 cmPkProtAddr ARGS((ProtAddr *protAddr, Buffer *mBuf)); +EXTERN S16 cmPkProtAddrTbl ARGS((ProtAddrTbl *protAddr, Buffer *mBuf)); +EXTERN S16 cmPkShrtAddrs ARGS((ShrtAddrs *addrs, Buffer *mBuf)); +EXTERN S16 cmPkAddrMask ARGS((U8 *mask, Buffer *mBuf)); +EXTERN S16 cmPkBndCfg ARGS((BndCfg *bndCfg, Buffer *mBuf)); +EXTERN S16 cmPkPst ARGS((Pst *pst, Buffer *mBuf)); +EXTERN S16 cmPkElmtHdr ARGS((ElmtHdr *m, Buffer *mBuf)); +EXTERN S16 cmPkTknU8 ARGS((TknU8 *tknU8, Buffer *mBuf)); +EXTERN S16 cmPkTknS8 ARGS((TknS8 *tknS8, Buffer *mBuf)); +EXTERN S16 cmPkTknU16 ARGS((TknU16 *tknU16, Buffer *mBuf)); +EXTERN S16 cmPkTknU32 ARGS((TknU32 *tknU32, Buffer *mBuf)); +EXTERN S16 cmPkTknStr ARGS((TknStr *tknStr, Buffer *mBuf)); +EXTERN S16 cmPkTknStrM ARGS((TknStrM *tknStr, Buffer *mBuf)); +EXTERN S16 cmPkTknStrS ARGS((TknStrS *tknStr, Buffer *mBuf)); +EXTERN S16 cmPkTknStrE ARGS((TknStrE *tknStr, Buffer *mBuf)); + +EXTERN S16 cmPkTknStr4 ARGS((TknStr4 *tknStr, Buffer *mBuf)); +EXTERN S16 cmPkTknStr12 ARGS((TknStr12 *tknStr, Buffer *mBuf)); +EXTERN S16 cmPkTknStr32 ARGS((TknStr32 *tknStr, Buffer *mBuf)); +EXTERN S16 cmPkTknStr64 ARGS((TknStr64 *tknStr, Buffer *mBuf)); +EXTERN S16 cmPkTknStr132 ARGS((TknStr132 *tknStr, Buffer *mBuf)); +EXTERN S16 cmPkTknStr256 ARGS((TknStr256 *tknStr, Buffer *mBuf)); + +PUBLIC S16 cmPkTknS32 ARGS((TknS32 *tknS32, Buffer *mBuf)); +PUBLIC S16 cmPkTknOid ARGS((TknOid *tknOid, Buffer *mBuf)); +PUBLIC S16 cmPkTknBuf ARGS((TknBuf *tknBuf, Buffer *mBuf)); + +#ifdef TDS_ROLL_UPGRADE_SUPPORT +PUBLIC S16 cmPkIntf ARGS((CmIntf *intf, Buffer *mBuf)); +#endif + +/* layer management structures */ +EXTERN S16 cmPkHeader ARGS((Header *header, Buffer *mBuf)); +EXTERN S16 cmPkSmCfg ARGS((SmCfg *smCfg, Buffer *mBuf)); +EXTERN S16 cmPkTmrCfg ARGS((TmrCfg *tmrCfg, Buffer *mBuf)); +EXTERN S16 cmPkCmStatus ARGS((CmStatus *status, Buffer *mBuf)); +EXTERN S16 cmPkCmAlarm ARGS((CmAlarm *alrm, Buffer *mBuf)); + + +/* common unpacking functions */ + +/* system services structures */ +EXTERN S16 cmUnpkDateTime ARGS((DateTime *dateTime, Buffer *mBuf)); +EXTERN S16 cmUnpkDuration ARGS((Duration *duration, Buffer *mBuf)); +EXTERN S16 cmUnpkPtr ARGS((PTR *ptr, Buffer *mBuf)); +EXTERN S16 cmUnpkEntityId ARGS((EntityId *entityId, Buffer *mBuf)); +EXTERN S16 cmUnpkElmntId ARGS((ElmntId *elmntId, Buffer *mBuf)); +EXTERN S16 cmUnpkMemoryId ARGS((MemoryId *memoryId, Buffer *mBuf)); + +/* general structures */ +EXTERN S16 cmUnpkSystemId ARGS((SystemId *systemId, Buffer *mBuf)); +EXTERN S16 cmUnpkAddrs ARGS((Addrs *addrs, Buffer *mBuf)); +EXTERN S16 cmUnpkProtAddr ARGS((ProtAddr *protAddr, Buffer *mBuf)); +EXTERN S16 cmUnpkProtAddrTbl ARGS((ProtAddrTbl *protAddr, Buffer *mBuf)); +EXTERN S16 cmUnpkShrtAddrs ARGS((ShrtAddrs *addrs, Buffer *mBuf)); +EXTERN S16 cmUnpkAddrMask ARGS((U8 *mask, Buffer *mBuf)); +EXTERN S16 cmUnpkBndCfg ARGS((BndCfg *bndCfg, Buffer *mBuf)); +EXTERN S16 cmUnpkPst ARGS((Pst *pst, Buffer *mBuf)); +EXTERN S16 cmUnpkElmtHdr ARGS((ElmtHdr *m, Buffer *mBuf)); +EXTERN S16 cmUnpkTknU8 ARGS((TknU8 *tknU8, Buffer *mBuf)); +EXTERN S16 cmUnpkTknS8 ARGS((TknS8 *tknS8, Buffer *mBuf)); +EXTERN S16 cmUnpkTknU16 ARGS((TknU16 *tknU16, Buffer *mBuf)); +EXTERN S16 cmUnpkTknU32 ARGS((TknU32 *tknU32, Buffer *mBuf)); +EXTERN S16 cmUnpkTknStr ARGS((TknStr *tknStr, Buffer *mBuf)); +EXTERN S16 cmUnpkTknStrM ARGS((TknStrM *tknStr, Buffer *mBuf)); +EXTERN S16 cmUnpkTknStrS ARGS((TknStrS *tknStr, Buffer *mBuf)); +EXTERN S16 cmUnpkTknStrE ARGS((TknStrE *tknStr, Buffer *mBuf)); + +EXTERN S16 cmUnpkTknStr4 ARGS((TknStr4 *tknStr, Buffer *mBuf)); +EXTERN S16 cmUnpkTknStr12 ARGS((TknStr12 *tknStr, Buffer *mBuf)); +EXTERN S16 cmUnpkTknStr32 ARGS((TknStr32 *tknStr, Buffer *mBuf)); +EXTERN S16 cmUnpkTknStr64 ARGS((TknStr64 *tknStr, Buffer *mBuf)); +EXTERN S16 cmUnpkTknStr132 ARGS((TknStr132 *tknStr, Buffer *mBuf)); +EXTERN S16 cmUnpkTknStr256 ARGS((TknStr256 *tknStr, Buffer *mBuf)); + +PUBLIC S16 cmUnpkTknS32 ARGS((TknS32 *tknS32, Buffer *mBuf)); +PUBLIC S16 cmUnpkTknOid ARGS((TknOid *tknOid, Buffer *mBuf)); +PUBLIC S16 cmUnpkTknBuf ARGS((TknBuf *tknBuf, Buffer **mBuf)); + +#ifdef TDS_ROLL_UPGRADE_SUPPORT +PUBLIC S16 cmUnpkIntf ARGS((CmIntf *intf, Buffer *mBuf)); +#endif + +/* layer management structures */ +EXTERN S16 cmUnpkHeader ARGS((Header *header, Buffer *mBuf)); +EXTERN S16 cmUnpkSmCfg ARGS((SmCfg *smCfg, Buffer *mBuf)); +EXTERN S16 cmUnpkTmrCfg ARGS((TmrCfg *tmrCfg, Buffer *mBuf)); +EXTERN S16 cmUnpkCmStatus ARGS((CmStatus *status, Buffer *mBuf)); +EXTERN S16 cmUnpkCmAlarm ARGS((CmAlarm *alrm, Buffer *mBuf)); + +#endif /* CMFILE_REORG_1 */ +#ifdef XEON_SPECIFIC_CHANGES +void * mtGetWlsHdl(); +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* __GENX__ */ + + +/********************************************************************30** + + End of file +**********************************************************************/ diff --git a/src/cm/kwu.h b/src/cm/kwu.h new file mode 100755 index 000000000..da1b35f63 --- /dev/null +++ b/src/cm/kwu.h @@ -0,0 +1,133 @@ +/******************************************************************************* +################################################################################ +# Copyright (c) [2017-2019] [Radisys] # +# # +# 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. # +################################################################################ +*******************************************************************************/ + +/********************************************************************20** + + Name: KWU user interface + + Type: C include file + + Desc: This file Contains the Data structures and prototypes + for KWU Interface + + File: kwu.h + +*********************************************************************21*/ + +#ifndef __KWU_H__ +#define __KWU_H__ + +#ifdef __cplusplus +EXTERN "C" { +#endif /*for extern "C"*/ + +/** @file kwu.h + @brief KWU Interface File (kwu.h) +*/ + +/* KWU Interface Hash Defines */ + +/* CKW Interface Hash Defines */ +/* selector(coupling) values */ +#define KWU_SEL_LC 0 +#define KWU_SEL_LWLC 3 + +/*********************************************************************** + Defines for KWU Interface Events + ***********************************************************************/ +#define KWU_EVT_BND_REQ 0x50 /*!< Bind Request */ +#define KWU_EVT_BND_CFM 0x51 /*!< Bind Confirm */ +#define KWU_EVT_UBND_REQ 0x52 /*!< Unbind Request */ +#ifdef L2_L3_SPLIT +#define KWU_EVT_CPLANE_DAT_REQ 0x53 /*!< C-Plane Data Request */ +#define KWU_EVT_UPLANE_DAT_REQ 0x5b /*!< U-Plane Data Request */ +#endif +#define KWU_EVT_DAT_REQ 0x53 /*!< Data Request */ +#define KWU_EVT_TTI_IND 0x5c /*!srcEnt, _pst->srcInst, _pst->srcProcId, \ + __FILE__, __LINE__, _errCls, _errCode, _errVal, _errDesc) + +/* Error Codes */ +#define ERRLKW 0 +#define ELKWXXX 0 + +#define ELKW001 (ERRLKW + 1) /* lkw.c: 203 */ +#define ELKW002 (ERRLKW + 2) /* lkw.c: 218 */ +#define ELKW003 (ERRLKW + 3) /* lkw.c: 272 */ +#define ELKW004 (ERRLKW + 4) /* lkw.c: 322 */ +#define ELKW005 (ERRLKW + 5) /* lkw.c: 337 */ +#define ELKW006 (ERRLKW + 6) /* lkw.c: 390 */ +#define ELKW007 (ERRLKW + 7) /* lkw.c: 436 */ +#define ELKW008 (ERRLKW + 8) /* lkw.c: 451 */ +#define ELKW009 (ERRLKW + 9) /* lkw.c: 505 */ +#define ELKW010 (ERRLKW + 10) /* lkw.c: 556 */ +#define ELKW011 (ERRLKW + 11) /* lkw.c: 604 */ +#define ELKW012 (ERRLKW + 12) /* lkw.c: 619 */ +#define ELKW013 (ERRLKW + 13) /* lkw.c: 672 */ +#define ELKW014 (ERRLKW + 14) /* lkw.c: 720 */ +#define ELKW015 (ERRLKW + 15) /* lkw.c: 735 */ +#define ELKW016 (ERRLKW + 16) /* lkw.c: 789 */ +#define ELKW017 (ERRLKW + 17) /* lkw.c: 835 */ +#define ELKW018 (ERRLKW + 18) /* lkw.c: 850 */ +#define ELKW019 (ERRLKW + 19) /* lkw.c: 902 */ +#define ELKW020 (ERRLKW + 20) /* lkw.c: 956 */ +#define ELKW021 (ERRLKW + 21) /* lkw.c:1008 */ +#define ELKW022 (ERRLKW + 22) /* lkw.c:1061 */ +#define ELKW023 (ERRLKW + 23) /* lkw.c:1294 */ +#define ELKW024 (ERRLKW + 24) /* lkw.c:1309 */ +#define ELKW025 (ERRLKW + 25) /* lkw.c:1358 */ +#define ELKW026 (ERRLKW + 26) /* lkw.c:1375 */ +#define ELKW027 (ERRLKW + 27) /* lkw.c:1393 */ +#define ELKW028 (ERRLKW + 28) /* lkw.c:1445 */ +#define ELKW029 (ERRLKW + 29) /* lkw.c:1460 */ +#define ELKW030 (ERRLKW + 30) /* lkw.c:1511 */ +#define ELKW031 (ERRLKW + 31) /* lkw.c:1526 */ + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* __LKW_H__ */ + + +/********************************************************************30** + End of file +**********************************************************************/ diff --git a/src/cm/lkw.x b/src/cm/lkw.x new file mode 100755 index 000000000..af84ad55b --- /dev/null +++ b/src/cm/lkw.x @@ -0,0 +1,803 @@ +/******************************************************************************* +################################################################################ +# Copyright (c) [2017-2019] [Radisys] # +# # +# 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. # +################################################################################ +*******************************************************************************/ + +/********************************************************************20** + + Name: LKW RLC Layer Manager Interface + + Type: C include file + + Desc: This file Contains the Data structures and prototypes + for LKW Interface + + File: lkw.x + +*********************************************************************21*/ + +#ifndef __LKW_X__ +#define __LKW_X__ + +#ifdef __cplusplus +EXTERN "C" { +#endif /* __cplusplus */ + + +/** @brief + General Configuration Structure. */ +typedef struct kwGenCfg +{ + Pst lmPst; /*!< Post structure for communicating + with LM. */ + U32 maxUe; /*!< Maximum number of UEs supported + by RLC. */ + U16 maxKwuSaps; /*!< Maximum KWU SAPs. */ +/* Supported by SPLIT Architecture */ + U16 maxUdxSaps; /*!< Maximum Udx SAPs. */ +/* Supported by SPLIT Architecture ends */ + Ticks timeRes; /*!< Time resolution. */ +/* Supported by SPLIT Architecture */ + U8 rlcMode; /*!< RLC_DL or RLC_UL */ +/* Supported by SPLIT Architecture ends */ + U16 maxRguSaps; /*!< Maximum RGU SAPs. */ +}KwGenCfg; + +/** @brief + SAP Configuration Structure */ +typedef struct kwSapCfg +{ + Selector selector; /*!< Selector for LC/TC. */ + MemoryId mem; /*!< Region and pool. */ + ProcId procId; /*!< Processor ID. */ + Ent ent; /*!< Entity ID. */ + Inst inst; /*!< Instance ID. */ + SpId sapId; /*!< SAP ID. */ + U16 bndTmrIntvl; /*!< Bind timer interval. */ + Priority priority; /*!< Priority. */ + Route route; /*!< Route. */ +}KwSapCfg; + +/** @brief +* Configuration Structure +*/ +typedef struct kwCfg +{ + union + { + KwGenCfg gen; /*!< General configuraton. */ + KwSapCfg sap; /*!< SAP configuration. */ + }s; +}KwCfg; + +/** @brief + General Statistics Structure */ +typedef struct kwGenSts +{ + CntrSts numUe; /*!< Total number of UEs. */ + CntrSts pdusRecv; /*!< Number of PDUs received. */ + CntrSts pdusSent; /*!< Number of PDUs sent. */ + CntrSts pdusRetx; /*!< Number of PDUs retransmitted. */ + CntrSts bytesRecv; /*!< Number of bytes received. */ + CntrSts bytesSent; /*!< Number of bytes sent. */ + CntrSts unexpPdusRecv; /*!< Unexpected PDU received. */ + CntrSts errorPdusRecv; /*!< Format error pdus received. */ + CntrSts protTimeOut; /*!< Number of protocol time outs leading + to retransmission. */ + CntrSts numOfRb; /*!< Total number of RBs in RLC. */ + CntrSts numSduDisc; /*!< Number of SDUs discarded. */ +}KwGenSts; + +/** @brief + RLC Upper SAP statistics */ +typedef struct kwKwuSapSts +{ + /* lkw_x_001.main_2, changed from suId to spId */ + SpId spId; /*!< Service Provider ID. */ + CntrSts sduRx; /*!< Number of SDUs received. */ + CntrSts sduTx; /*!< Number of tranxmitted SDUs. */ +}KwKwuSapSts; + +/** @brief + RRC Control SAP Statistics */ +typedef struct kwCkwCntSts +{ + CntrSts statMsgs; /*!< Number of Status Messages send. */ +}KwCkwCntSts; + +/** @brief + Statistics Structure */ +typedef struct kwSts +{ + DateTime dt; /*!< Date and Time structure. */ + union + { + KwGenSts gen; /*!< General Statistics. */ + KwKwuSapSts kwuSap; /*!< RLC upper SAP statistics. */ + KwCkwCntSts ckwSap; /*!< RRC control SAP. */ + }s; +}KwSts; + +/** @brief + MAC Upper SAP Status Structure */ +typedef struct kwRguSapSta +{ + SuId suId; /*!< Service user ID. */ + State state; /*!< State of the SAP. */ +}KwRguSapSta; + +/** @brief + RLC Upper SAP Status Structure */ +typedef struct kwKwuSapSta +{ + SpId spId; /*!< Service provider ID. */ + State state; /*!< State of the SAP. */ +}KwKwuSapSta; + +/** @brief + RRC Control SAP Status Structure */ +typedef struct kwCkwCntSapSta +{ + SpId spId; /*!< Service provider ID. */ + State state; /*!< State of the SAP. */ +}KwCkwCntSapSta; + +/** @brief + Status Structure */ +typedef struct kwSSta +{ + DateTime dt; /*!< Date and Time structure. */ + union + { + SystemId sysId; /*!< System ID. */ + KwRguSapSta rguSap; /*!< RLC lower SAP (MAC) status. */ + KwKwuSapSta kwuSap; /*!< RLC Upper SAP status. */ + KwCkwCntSapSta ckwSap; /*!< RRC Control SAP Status. */ + }s; +}KwSSta; + +/** @brief + Trace Control Structure */ +typedef struct kwTrcCntrl +{ + U8 trcMask; /*!< Trace mask. */ + S16 trcLen; /*!< Trace length. */ +}KwTrcCntrl; + +/** @brief + Debug Control Structure */ +typedef struct kwDbgCntrl +{ + U32 dbgMask; /*!< Debug mask. Assign non zero value to enable + and zero to disable debug */ +}KwDbgCntrl; + +/** @brief + SAP Control Structure */ +typedef struct kwSapCntrl +{ + SuId suId; /*!< Service user ID. */ + SpId spId; /*!< Service provider ID. */ +}KwSapCntrl; + +/** @brief + Control Structure */ +typedef struct kwCntrl +{ + DateTime dt; /*!< Date and Time structure. */ + U8 action; /*!< Action. */ + U8 subAction; /*!< Sub action. */ + union + { + KwTrcCntrl trcCntrl; /*!< Trace Control Structure. */ + KwDbgCntrl dbgCntrl; /*!< Debug Control Structure. */ + KwSapCntrl sapCntrl; /*!< SAP Control Structure. */ +#ifdef SS_DIAG + U32 logMask; /*!< Logging Control Structure. */ +#endif + }s; +}KwCntrl; + +/** @brief + Unsolicited Status Structure */ +typedef struct kwUSta +{ + DateTime dt; /*!< Date and Time structure. */ + CmAlarm alarm; /*!< Alarm. */ + SuId suId; /*!< Service user ID. */ + U32 ueId; /*!< Urnti UE ID. */ + /* lkw_x_001.main_2, added support for L2 measurement */ +#ifdef LTE_L2_MEAS + U8 qci; /*!< Qci value */ +#endif +}KwUSta; + +/** @brief + Trace Structure */ +typedef struct kwTrc +{ + DateTime dt; /*!< Date and Time structure. */ + U16 event; /*!< Event. Events defined in the differenct RLC + interfaces are pssible values here.*/ +}KwTrc; + +/** @brief + Layer Management Structure */ +typedef struct _kwMngmt +{ + Header hdr; /*!< Common header. */ + CmStatus cfm; /*!< Status of confirmation. */ + union + { + KwCfg cfg; /*!< General Configuration. */ + KwCntrl cntrl; /*!< Control Structure. */ + KwSts sts; /*!< Statistics. */ + KwSSta ssta; /*!< Status. */ + KwUSta usta; /*!< Unsolicited Status. */ + KwTrc trc; /*!< Trace Structre. */ + }t; +}KwMngmt; + +/* lkw_x_001.main_2, added support for L2 measurement */ +#ifdef LTE_L2_MEAS + +/** @brief Measurement Request Params Structure. */ +typedef struct kwL2MeasReqInfo +{ + U8 measType; /*!< Measurement type, bit 1 to 4 (LSB nibble) + will be used for non IP Throughput and + bit 5 and 6 will be used for DL and UL + Ipthroughput respectively */ + union + { + struct + { + U16 numSamples; /*! + LRG_USTA_DGNVAL_MEM Dynamic memory allocation failure.
+ LRG_USTS_DGNVAL_HARQ Harq Process is busy. + */ + }u; +} RgUstaDgn; + +/** + * @brief + This structure holds MAC's Unsolicited Status information. */ +typedef struct rgUsta +{ + CmAlarm cmAlarm; /*!< Alarms */ + RgUstaDgn dgn; /*!< Alarm diagnostics */ +}RgUsta; + +/** + * @brief + This structure holds MAC's Trace Indication information. */ +typedef struct rgTrc +{ + DateTime dt; /*!< Date and time */ + /*lrg_x_001.main_3 - changed for documentation*/ + U8 evnt; /*!< Event
+ EVTRGUDATREQ Trace for Dedicated channel Data Request.
+ EVTRGUCDATREQ Trace for common channel data request.
+ */ +}RgTrc; + +/** + * @brief + This structure holds MAC's Debug Control information. */ +typedef struct rgDbgCntrl +{ + U32 dbgMask; /*!< iThe Layer Manager electively enables or disables various levels of Debug printing
+ Following are the values:
+ DBGMASK_PRM Enable/Disable function parameter debug prints
+ DBGMASK_ERR Enable/Disable error prints
+ DBGMASK_INFO Enable/Disable informational prints. + */ +}RgDbgCntrl; + +/** + * @brief + This structure holds MAC's SAP Control information. */ +typedef struct rgSapCntrl +{ + SuId suId; /*!< Service user ID */ + SpId spId; /*!< Service provider ID */ +}RgSapCntrl; + +#ifdef PHY_ERROR_LOGING +typedef struct rgSchUlAllocCntrl +{ + U8 mcs; + U16 numOfRb; + U16 rbStart; + Bool testStart; + Bool enaLog; + U16 logTime; +}RgSchUlAllocCntrl; +#endif + +/** + * @brief + This structure holds MAC's Control information. */ +typedef struct rgCntrl +{ + DateTime dt; /*!< Date and Time */ + U8 action; /*!< Action */ + U8 subAction; /*!< Sub-action */ + U8 instId; /*!< Scheduler instance ID */ + union + { + RgDbgCntrl rgDbgCntrl; /*!< Debug Control */ + /*lrg_x_001.main_3 - Changed for documentation.*/ + S16 trcLen; /*!< Trace Length
+ i)LRG_FULL_TRACE Give full message
+ ii)LRG_NO_TRACE Disable Trace
+ iii)Or any valid S16 value in case where only the specified number + of bytes, as indicated by trcLen, are to be sent.*/ + RgSapCntrl rgSapCntrl; /*!< SAP Control */ + U32 logMask; /*!< Logging control Mask */ +#ifdef PHY_ERROR_LOGING + RgSchUlAllocCntrl rgSchUlAllocCntrl; /* For setting MCS,Number of RB and RB start */ +#endif + }s; +}RgCntrl; + +/** + * @brief + This structure holds MAC's Configuration and Control Management Information. */ +typedef struct rgMngmt +{ + Header hdr; /*!< Header */ + CmStatus cfm; /*!< Confirmation */ + union + { + RgCfg cfg; /*!< Configuration */ + RgSts sts; /*!< Statistics */ + RgSsta ssta; /*!< Solicited Status */ + RgUsta usta; /*!< Unsolicited Status */ + RgTrc trc; /*!< Trace */ + RgCntrl cntrl; /*!< Control */ + }t; +}RgMngmt; + +/* lrg_x_001.main_3 - ADD - Data structures for LTE_L2_MEAS */ +#ifdef LTE_L2_MEAS +/** + * @brief + To measure Average Number of PRB's used per QCI for a time period + timePrd +*/ +typedef struct lrgAvgPrbQCI +{ + U8 numQci; /*!< Numner of QCI's in requests */ + U8 qci[LRG_MAX_QCI_PER_REQ]; /*!< QCI for which PRB has to be measured */ +} LrgAvgPrbQCI; + +/** + * @brief + To measure number of Active UE's per QCI for the given time period + timePrd +**/ +typedef struct lrgNmbActvUeQCI +{ + U8 sampPrd; /*!< sampling prd for which active UE's measured + Where sampling period is in milli seconds + value can be at most 100ms */ + U8 numQci; /*!< Numner of QCI's in requests */ + U8 qci[LRG_MAX_QCI_PER_REQ]; /*!< QCI for which UE has to be considered */ +} LrgNmbActvUeQCI; + +/** + * * @brief + This structure will be used by Layer Manager to L2 Measurement Request + Information +**/ +typedef struct lrgSchMeasReqInfo +{ + Header hdr; /*!< Header */ + U16 measType; /*!< For type of measurement Following are the */ + /*!< allowed values */ + /*!< LRG_L2MEAS_AVG_PRB_DL , LRG_L2MEAS_AVG_PRB_UL*/ + /*!< LRG_L2MEAS_AVG_PRB_PER_QCI_DL */ + /*!< LRG_L2MEAS_AVG_PRB_PER_QCI_UL */ + /*!< LRG_L2MEAS_RA_PREAMBLE */ + /*!< LRG_L2MEAS_NMB_ACTV_UE_PER_QCI_UL */ + /*!< LRG_L2MEAS_NMB_ACTV_UE_PER_QCI_DL */ + /*!< LRG_L2MEAS_TB_TRANS_DL_COUNT */ + /*!< LRG_L2MEAS_TB_TRANS_DL_FAULTY_COUNT */ + /*!< LRG_L2MEAS_TB_TRANS_UL_COUNT */ + /*!< LRG_L2MEAS_TB_TRANS_UL_FAULTY_COUNT */ + U32 timePrd; /*!< Time period UNITS and value will differ depending + on the action. Might be milli seconds/seconds. */ + CmLteCellId cellId; /*!< CELL Id for which measurement is Done */ + LrgAvgPrbQCI avgPrbQciUl; /*!< Average PRB usage per QCI in UL */ + LrgAvgPrbQCI avgPrbQciDl; /*!< Average PRB usage per QCI in DL */ + LrgNmbActvUeQCI nmbActvUeQciUl; /*!< Number of active UE's per QCI in UL */ + LrgNmbActvUeQCI nmbActvUeQciDl; /*!< Number of active UE's per QCI in DL */ +} LrgSchMeasReqInfo; + +typedef struct lrgSchMeasSndReqInfo +{ + Header hdr; /*!< Header */ + U16 measType; /*!< For type of measurement Following are the */ + /*!< allowed values */ + /*!< LRG_L2MEAS_AVG_PRB_DL , LRG_L2MEAS_AVG_PRB_UL*/ + /*!< LRG_L2MEAS_AVG_PRB_PER_QCI_DL */ + /*!< LRG_L2MEAS_AVG_PRB_PER_QCI_UL */ + /*!< LRG_L2MEAS_RA_PREAMBLE */ + /*!< LRG_L2MEAS_NMB_ACTV_UE_PER_QCI_UL */ + /*!< LRG_L2MEAS_NMB_ACTV_UE_PER_QCI_DL */ + U32 timePrd; /*!< Time period UNITS and value will differ depending + on the action. Might be milli seconds/seconds. */ + CmLteCellId cellId; /*!< CELL Id for which measurement is Done */ + // LrgAvgPrbQCI avgPrbQciUl; /*!< Average PRB usage per QCI in UL */ + // LrgAvgPrbQCI avgPrbQciDl; /*!< Average PRB usage per QCI in DL */ + // LrgNmbActvUeQCI nmbActvUeQciUl; /*!< Number of active UE's per QCI in UL */ + // LrgNmbActvUeQCI nmbActvUeQciDl; /*!< Number of active UE's per QCI in DL */ +} LrgSchMeasSndReqInfo; + +typedef struct lrgSchMeasStopReqInfo +{ + Header hdr; /*!< Header */ + U16 measType; /*!< For type of measurement Following are the */ + /*!< allowed values */ + /*!< LRG_L2MEAS_AVG_PRB_DL , LRG_L2MEAS_AVG_PRB_UL*/ + /*!< LRG_L2MEAS_AVG_PRB_PER_QCI_DL */ + /*!< LRG_L2MEAS_AVG_PRB_PER_QCI_UL */ + /*!< LRG_L2MEAS_RA_PREAMBLE */ + /*!< LRG_L2MEAS_NMB_ACTV_UE_PER_QCI_UL */ + /*!< LRG_L2MEAS_NMB_ACTV_UE_PER_QCI_DL */ + /* U16 timePrd; */ /*!< Time period UNITS and value will differ depending + on the action. Might be milli seconds/seconds. */ + CmLteCellId cellId; /*!< CELL Id for which measurement is Done */ + /* LrgAvgPrbQCI avgPrbQciUl; */ /*!< Average PRB usage per QCI in UL */ + // LrgAvgPrbQCI avgPrbQciDl; /*!< Average PRB usage per QCI in DL */ + // LrgNmbActvUeQCI nmbActvUeQciUl; /*!< Number of active UE's per QCI in UL */ + // LrgNmbActvUeQCI nmbActvUeQciDl; /*!< Number of active UE's per QCI in DL */ +} LrgSchMeasStopReqInfo; + +/** + *@brief + Structure to hold Received Random Access Preambles. +**/ +typedef struct lrgRaPreambles +{ + U16 dedPreambles; /*!< Dedicated RA Preamble received */ + U16 randSelPreLowRange; /*!< Randomly selected preambles in low range */ + U16 randSelPreHighRange; /*!< Randomly selected preambles in high range */ +} LrgRaPreamblesCfm; + +/** + * @brief + * Staructure to send Avg PRB for a given Time Period + * */ +typedef struct lrgAvgPrbcfm +{ + U8 prbPerc; /*!< PRB usage in percentage for UL */ +} LrgAvgPrbCfm; + +/*LRG : Review Tag*/ +typedef struct prbPercQci +{ + U8 qciValue; + U8 prbPercQci; +}PrbPercQci; + +typedef struct numActvUeQci +{ + U8 qciValue; + U8 numActvUeQci; +}NumActvUeQci; +/*LRG : Review Tag*/ +/** + * @brief + * Structure to send Avg PRB for a given period per QCI + * */ +typedef struct lrgAvgPrbQCICfm +{ + U8 numQci; /*!< number of QCI */ +/*LRG : Review Tag*/ + PrbPercQci prbPercQci[LRG_MAX_QCI_PER_REQ]; /*!< PRB usage in percentage per QCI for UL/DL */ +/*LRG : Review Tag*/ +} LrgAvgPrbQCICfm; + +/** + *@brief + Structure to send number of Active UE's per QCI + */ +typedef struct lrgNumActvUeQCICfm +{ + U8 numQci; /*!< Numner of QCI's in requests */ +/*LRG : Review Tag*/ + NumActvUeQci numActvUeQci[LRG_MAX_QCI_PER_REQ]; /*!< Number of Active UE's in UL/DL per QCI */ +/*LRG : Review Tag*/ +} LrgNumActvUeQCICfm; +/** + @brief + Structure to send L2 Measurement confirm +**/ +typedef struct lrgSchMeasCfmInfo +{ + Header hdr; /*!< Header information */ + U16 measType; /*!< Type of measurement */ + CmStatus cfm; /*!< Confirmation possible Values when measType + is invalid status -> NOK and reason -> INVALID + */ + CmLteCellId cellId; /*!< Cell for which measurement is done */ + LrgAvgPrbCfm avgPrbUl; /*!< PRB usage in percentage per QCI for UL */ + LrgAvgPrbCfm avgPrbDl; /*!< PRB usage in percentage per QCI for DL */ + LrgAvgPrbQCICfm avgPrbQciUlCfm; /*!< PRB usage in percentage per QCI for UL */ + LrgAvgPrbQCICfm avgPrbQciDlCfm; /*!< PRB usage in percentage per QCI for DL */ + LrgRaPreamblesCfm raPrmbsCfm; /*!< Different received RA preambles */ + LrgNumActvUeQCICfm numUeQciUlCfm; /*!< Number of Active UE's in UL per QCI */ + LrgNumActvUeQCICfm numUeQciDlCfm; /*!< Number of Active UE's in DL per QCI */ + U32 tbTransDlTotalCnt; /*!< Count of DL TB transmitteed */ + U32 tbTransDlFaulty; /*!< Count of DL TB for wich NACK not recieved from UE */ + U32 tbTransUlTotalCnt; /*!< Count of UL TB received successfully */ + U32 tbTransUlFaulty; /*!< Count of UL TB not recieved successfully */ +} LrgSchMeasCfmInfo; + +#endif /* LTE_L2_MEAS */ + +/* + Function Prototype Typedefs +. */ +typedef S16 (*LrgCfgReq) ARGS(( + Pst *pst, /* Post Structure */ + RgMngmt *cfg /* Management Structure */ + )); + +typedef S16 (*LrgSchCfgReq) ARGS(( + Pst *pst, /* Post Structure */ + RgMngmt *cfg /* Management Structure */ + )); + +typedef S16 (*LrgCfgCfm) ARGS(( + Pst *pst, /* Post Structure */ + RgMngmt *cfg /* Management Structure */ + )); + +typedef S16 (*LrgSchCfgCfm) ARGS(( + Pst *pst, /* Post Structure */ + RgMngmt *cfg /* Management Structure */ + )); + +typedef S16 (*LrgCntrlReq) ARGS(( + Pst *pst, /* Post Structure */ + RgMngmt *cntrl /* Management Structure */ + )); + +typedef S16 (*LrgSchCntrlReq) ARGS(( + Pst *pst, /* Post Structure */ + RgMngmt *cntrl /* Management Structure */ + )); + +typedef S16 (*LrgCntrlCfm) ARGS(( + Pst *pst, /* Post Structure */ + RgMngmt *cntrl /* Management Structure */ + )); + +typedef S16 (*LrgSchCntrlCfm) ARGS(( + Pst *pst, /* Post Structure */ + RgMngmt *cntrl /* Management Structure */ + )); + +/* lrg_x_001.main_3 - ADD - Data structures for LTE_L2_MEAS */ +#ifdef LTE_L2_MEAS +typedef S16 (*LrgSchL2MeasReq) ARGS(( + Pst *pst, /* Post Structure */ + LrgSchMeasReqInfo *meas /* L2 Measurement structure */ + )); +typedef S16 (*LrgSchL2MeasStopReq) ARGS(( + Pst *pst, /* Post Structure */ + LrgSchMeasStopReqInfo *meas /* L2 Measurement structure */ + )); +typedef S16 (*LrgSchL2MeasSendReq) ARGS(( + Pst *pst, /* Post Structure */ + LrgSchMeasSndReqInfo *meas /* L2 Measurement structure */ + )); +#endif +typedef S16 (*LrgStaReq) ARGS(( + Pst *pst, /* Post Structure */ + RgMngmt *sta /* Management Structure */ + )); + +typedef S16 (*LrgStaCfm) ARGS(( + Pst *pst, /* Post Structure */ + RgMngmt *sta /* Management Structure */ + )); + +typedef S16 (*LrgStaInd) ARGS(( + Pst *pst, /* Post Structure */ + RgMngmt *sta /* Management Structure */ + )); + +typedef S16 (*LrgSchStaInd) ARGS(( + Pst *pst, /* Post Structure */ + RgMngmt *sta /* Management Structure */ + )); + +typedef S16 (*LrgStsReq) ARGS(( + Pst *pst, /* Post Structure */ + RgMngmt *sts /* Management Structure */ + )); + +typedef S16 (*LrgStsCfm) ARGS(( + Pst *pst, /* Post Structure */ + RgMngmt *sts /* Management Structure */ + )); + +typedef S16 (*LrgTrcInd) ARGS(( + Pst *pst, /* Post Structure */ + RgMngmt *trc, /* Management Structure */ + Buffer *mBuf /* Message Buffer */ + )); + +/* lrg_x_001.main_3 - ADD - Data structures for LTE_L2_MEAS */ +#ifdef LTE_L2_MEAS +typedef S16 (*LrgSchL2MeasCfm) ARGS(( + Pst *pst, /* Post Structure */ + LrgSchMeasCfmInfo *schL2MeasCfm /* Measurement Info */ + )); +typedef S16 (*LrgSchL2MeasStopCfm) ARGS(( + Pst *pst, /* Post Structure */ + LrgSchMeasCfmInfo *schL2MeasCfm /* Measurement Info */ + )); +#endif /* LTE_L2_MEAS */ +/* + Function Prototypes. + */ +#ifdef RG +/* lrg_x_001.main_3 - ADD - Added the comments for the following function */ + /** @brief This primitive is sent from Layer manager to MAC. It carries + * configuration information towards MAC. + * @details This primitive can be used by layer manager to configure the + * following entities at MAC. + * -# General configuration + * -# RGU SAP i.e. SAP towards RLC + * -# CRG SAP i.e. SAP towards RRC + * -# TFU SAP i.e. SAP towards Physical layer + * + * @param pst pointer to Pst + * @param cfg pointer to RgMngmt + * @return ROK/RFAILED + */ +EXTERN S16 RgMiLrgCfgReq ARGS((Pst *pst, RgMngmt *cfg)); + + /** @brief This primitive carries the Confirmation for a Configuration Request + * sent from the layer manager to MAC. + * @details This primitive is used by MAC to inform Layer manager about the + * status of a Configuration Request. + * @param pst Pointer to the post structure. + * @param cfm pointer to RgMngmt + * @return ROK/RFAILED + */ +EXTERN S16 RgMiLrgCfgCfm ARGS((Pst *pst, RgMngmt *cfm)); + + /** @brief This primitive is sent from Layer manager to Scheduler. It carries + * configuration information towards MAC. + * @details This primitive can be used by layer manager to configure the + * following entities at Scheduler. + * -# General configuration + * -# RGR SAP i.e. SAP towards RRM + * -# TFU SAP i.e. SAP towards Physical layer + * + * @param pst pointer to Pst + * @param cfg pointer to RgMngmt + * @return ROK/RFAILED + */ +EXTERN S16 RgMiLrgSchCfgReq ARGS((Pst *pst, RgMngmt *cfg)); + + /** @brief This primitive carries the Confirmation for a Configuration Request + * sent from the layer manager to Scheduler. + * @details This primitive is used by Scheduler to inform Layer manager about the + * status of a Configuration Request. + * @param pst Pointer to the post structure. + * @param cfm pointer to RgMngmt + * @return ROK/RFAILED + */ +EXTERN S16 RgMiLrgSchCfgCfm ARGS((Pst *pst, RgMngmt *cfm)); + + /** @brief This primitive carries the Request for statistics from MAC layer + * sent from the layer manager. + * @details This primitive is used by layer manager to request for statistics + * on the following + * -# General statistics + * -# RGU SAP statistics + * -# CRG SAP statistics + * -# TFU SAP statistics + * @param pst Pointer to the post structure. + * @param sts pointer to RgMngmt + * @return ROK/RFAILED + */ +EXTERN S16 RgMiLrgStsReq ARGS((Pst *pst, RgMngmt *sts)); + + /** @brief This primitive carries the Statistics for a Statistics Request + * sent from the layer manager to MAC. + * @details This primitive is used by MAC to inform Layer manager about the + * Statistics requested earlier. + * @param pst Pointer to the post structure. + * @param cfm pointer to RgMngmt + * @return ROK/RFAILED + */ +EXTERN S16 RgMiLrgStsCfm ARGS((Pst *pst, RgMngmt *cfm)); + + /** @brief This primitive carries the Status request + * sent from the layer manager to MAC. + * @details This primitive is used by the layer manager to request + * status from the MAC layer. + * @param pst Pointer to the post structure. + * @param cfm pointer to RgMngmt + * @return ROK/RFAILED + */ +EXTERN S16 RgMiLrgStaReq ARGS((Pst *pst, RgMngmt *sta)); + + /** @brief This primitive carries the Confirmation for a Status Request + * sent from the layer manager to MAC. + * @details This primitive is used by MAC to send a response for the status + * Request sent by the layer manager. + * @param pst Pointer to the post structure. + * @param cfm pointer to RgMngmt + * @return ROK/RFAILED + */ +EXTERN S16 RgMiLrgStaCfm ARGS((Pst *pst, RgMngmt *cfm)); + + /** @brief This primitive carries the Unsolicited status indications from MAC + * to the layer manager i.e. Alarms. + * @details This primitive is used by MAC to inform Layer manager about some + * error conditions or bind confirmations. + * @param pst Pointer to the post structure. + * @param usta pointer to RgMngmt + * @return ROK/RFAILED + */ +EXTERN S16 RgMiLrgStaInd ARGS((Pst *pst, RgMngmt *usta)); + /** @brief This primitive carries the Unsolicited status indications from + * scheduler to the layer manager i.e. Alarms. + * @details This primitive is used by Scheduler to inform Layer manager about some + * error conditions or bind confirmations. + * @param pst Pointer to the post structure. + * @param usta pointer to RgMngmt + * @return ROK/RFAILED + */ +EXTERN S16 RgMiLrgSchStaInd ARGS((Pst *pst, RgMngmt *usta)); + + /** @brief This primitive carries the control request sent from the layer + * manager to MAC layer. + * @details This primitive is sent from the layer manager to control the MAC + * layer. The following entities could be controlled using this primitive. + * -# Debug printing + * -# TRACE functionality + * -# Binding of lower SAPs + * @param pst Pointer to the post structure. + * @param cfm pointer to RgMngmt + * @return ROK/RFAILED + */ +EXTERN S16 RgMiLrgCntrlReq ARGS((Pst *pst, RgMngmt *cntrl)); + /** @brief This primitive carries the Confirmation for a Control Request + * sent from the layer manager to MAC. + * @details This primitive is used by MAC to inform Layer manager about the + * status of a Control Request. + * @param pst Pointer to the post structure. + * @param cfm pointer to RgMngmt + * @return ROK/RFAILED + */ +EXTERN S16 RgMiLrgCntrlCfm ARGS(( Pst *pst, RgMngmt *cfm)); + /** @brief This primitive carries the control request sent from the layer + * manager to MAC layer. + * @details This primitive is sent from the layer manager to control the MAC + * layer. The following entities could be controlled using this primitive. + * -# Debug printing + * -# TRACE functionality + * -# Binding of lower SAPs + * @param pst Pointer to the post structure. + * @param cfm pointer to RgMngmt + * @return ROK/RFAILED + */ +EXTERN S16 RgMiLrgSchCntrlReq ARGS((Pst *pst, RgMngmt *cntrl)); + /** @brief This primitive carries the Confirmation for a Control Request + * sent from the layer manager to MAC. + * @details This primitive is used by MAC to inform Layer manager about the + * status of a Control Request. + * @param pst Pointer to the post structure. + * @param cfm pointer to RgMngmt + * @return ROK/RFAILED + */ +EXTERN S16 RgMiLrgSchCntrlCfm ARGS(( Pst *pst, RgMngmt *cfm)); + /** @brief This primitive carries the a copy of the received buffer from MAC to + * the layer manager. This is called the Tracing functionality of the layer. + * @details This primitive is used by MAC to send a copy of the received buffer + * to the layer manager, if Tracing is enabled via a control request. + * @param pst Pointer to the post structure. + * @param trc pointer to RgMngmt + * @param mBuf pointer to Buffer contains the portion of the received message. + * @return ROK/RFAILED + */ +EXTERN S16 RgMiLrgTrcInd ARGS((Pst *pst, RgMngmt *trc, Buffer *mBuf)); +#ifdef LTE_L2_MEAS + /** @brief This primitive is to enable L2 (layer 2) measurements at the MAC + * layer. + * + * @details Enables the L2 Measurements. + * + * @param pst Pointer to the post structure. + * @param schL2MeasInfo pointer to LrgSchMeasReqInfo + * @return ROK/RFAILED + */ +EXTERN S16 RgMiLrgSchL2MeasReq ARGS((Pst *pst, LrgSchMeasReqInfo *schL2MeasInfo)); + /** @brief This primitive carries the results of the L2 Measurements gathered + * by MAC to the layer manager. + * + * @details Carries the Measurements gathered by MAC. + * + * @param pst Pointer to the post structure. + * @param schL2MeasCfm pointer to LrgSchMeasCfmInfo + * @return ROK/RFAILED + */ +EXTERN S16 RgMiLrgSchL2MeasCfm ARGS((Pst *pst, LrgSchMeasCfmInfo *schL2MeasCfm)); + /** @brief This primitive is to Stop L2 (layer 2) measurements at the MAC + * layer. + * + * @details Enables the L2 Measurements. + * + * @param pst Pointer to the post structure. + * @param schL2MeasInfo pointer to LrgSchMeasReqInfo + * @return ROK/RFAILED + */ + +EXTERN S16 RgMiLrgSchL2MeasStopReq ARGS((Pst *pst, LrgSchMeasStopReqInfo *schL2MeasInfo)); + /** @brief This primitive is to used to send L2 (layer 2) measurements at the MAC + * layer. + * + * @details Enables the L2 Measurements. + * + * @param pst Pointer to the post structure. + * @param schL2MeasInfo pointer to LrgSchMeasReqInfo + * @return ROK/RFAILED + */ + +EXTERN S16 RgMiLrgSchL2MeasSendReq ARGS((Pst *pst,LrgSchMeasSndReqInfo *schL2MeasInfo)); + /** @brief This primitive carries the confrmratoin of the L2 Measurements gathered + * by MAC to the layer manager. + * + * @details Carries the Measurements gathered by MAC. + * + * @param pst Pointer to the post structure. + * @param schL2MeasCfm pointer to LrgSchMeasCfmInfo + * @return ROK/RFAILED + */ + +EXTERN S16 RgMiLrgSchL2MeasStopCfm ARGS((Pst *pst, LrgSchMeasCfmInfo *schL2MeasCfm)); +#endif /* LTE_L2_MEAS */ +#endif /* RG. */ + +#ifdef SM +EXTERN S16 smRgActvInit ARGS((Ent ent,Inst inst, Region region,Reason reason)); +EXTERN S16 smRgActvTsk ARGS((Pst *pst, Buffer *mBuf)); +EXTERN S16 SmMiLrgCfgReq ARGS((Pst *pst, RgMngmt *cfg)); +EXTERN S16 SmMiLrgCfgCfm ARGS((Pst *pst, RgMngmt *cfm)); +EXTERN S16 SmMiLrgSchCfgReq ARGS((Pst *pst, RgMngmt *cfg)); +EXTERN S16 SmMiLrgSchCfgCfm ARGS((Pst *pst, RgMngmt *cfm)); +EXTERN S16 SmMiLrgStsReq ARGS((Pst *pst, RgMngmt *sts)); +EXTERN S16 SmMiLrgStsCfm ARGS((Pst *pst, RgMngmt *cfm)); +EXTERN S16 SmMiLrgStaReq ARGS((Pst *pst, RgMngmt *sta)); +EXTERN S16 SmMiLrgStaCfm ARGS((Pst *pst, RgMngmt *cfm)); +EXTERN S16 SmMiLrgStaInd ARGS((Pst *pst, RgMngmt *usta)); +EXTERN S16 SmMiLrgCntrlReq ARGS((Pst *pst, RgMngmt *cntrl)); +EXTERN S16 SmMiLrgSchStaInd ARGS((Pst *pst, RgMngmt *usta)); +EXTERN S16 SmMiLrgCntrlCfm ARGS(( Pst *pst, RgMngmt *cfm)); +EXTERN S16 SmMiLrgSchCntrlReq ARGS((Pst *pst, RgMngmt *cntrl)); +EXTERN S16 SmMiLrgSchCntrlCfm ARGS(( Pst *pst, RgMngmt *cfm)); +EXTERN S16 SmMiLrgTrcInd ARGS((Pst *pst, RgMngmt *trc, Buffer *mBuf)); +/* lrg_x_001.main_3 - ADD - Added the following functions for LTE_L2_MEAS */ +#ifdef LTE_L2_MEAS +EXTERN S16 SmMiLrgSchL2MeasStartReq ARGS((Pst *pst, LrgSchMeasReqInfo *schL2MeasReq)); +EXTERN S16 SmMiLrgSchL2MeasCfm ARGS((Pst *pst, LrgSchMeasCfmInfo *schL2MeasCfm)); +EXTERN S16 SmMiLrgSchL2MeasStopReq ARGS((Pst *pst, LrgSchMeasStopReqInfo *schL2MeasReq)); +EXTERN S16 SmMiLrgSchL2MeasSendReq ARGS((Pst *pst, LrgSchMeasSndReqInfo *schL2MeasReq)); +EXTERN S16 SmMiLrgSchL2MeasStopCfm ARGS((Pst *pst, LrgSchMeasCfmInfo *schL2MeasCfm)); +EXTERN S16 SmMiLrgSchL2MeasReq ARGS((Pst *pst, LrgSchMeasReqInfo *meas)); +EXTERN S16 SmMiLrgSchL2SendMeasReq ARGS((Pst *pst, LrgSchMeasSndReqInfo *meas)); +EXTERN S16 SmMiLrgSchL2StopMeasReq ARGS((Pst *pst, LrgSchMeasStopReqInfo *meas)); +#endif /* LTE_L2_MEAS */ +#endif /* SM. */ + +/* + Function Prototypes for Packing and Unpacking the primitives. + */ +#if (defined(LCLRG)) +/** @brief This API is used to send a +Config Request from LM to MAC.*/ +EXTERN S16 cmPkLrgCfgReq ARGS(( + Pst * pst, + RgMngmt * cfg +)); +/** @brief This API is used to send a +Configuration Request from LM to MAC. */ +EXTERN S16 cmUnpkLrgCfgReq ARGS(( + LrgCfgReq func, + Pst * pst, + Buffer *mBuf +)); +/** @brief This API is used to send a +Configuration Request from LM to SCH. */ +EXTERN S16 cmPkLrgSchCfgReq ARGS(( + Pst * pst, + RgMngmt * cfg +)); +/** @brief This API is used to send a +Configuration Request from LM to SCH. */ +EXTERN S16 cmUnpkLrgSchCfgReq ARGS(( + LrgSchCfgReq func, + Pst * pst, + Buffer *mBuf +)); +/* lrg_x_001.main_3 - ADD - Added the following pack/unpack functions for LTE_L2_MEAS */ +#ifdef LTE_L2_MEAS +/** @brief This API is used to send a +L2 Measurement Request from LM to SCH. */ +EXTERN S16 cmPkLrgSchL2MeasReq ARGS(( + Pst * pst, + LrgSchMeasReqInfo * meas +)); +/** @brief This API is used to send a +L2 Measurement Request from LM to SCH. */ +EXTERN S16 cmUnpkLrgSchL2MeasReq ARGS(( + LrgSchL2MeasReq func, + Pst * pst, + Buffer *mBuf +)); +EXTERN S16 cmPkLrgSchL2MeasCfm ARGS(( + Pst * pst, + LrgSchMeasCfmInfo *measInfo +)); +EXTERN S16 cmUnpkLrgSchL2MeasCfm ARGS(( + LrgSchL2MeasCfm func, + Pst *pst, + Buffer *mBuf +)); +EXTERN S16 cmPkLrgSchL2MeasReq ARGS(( + Pst * pst, + LrgSchMeasReqInfo * meas +)); +/** @brief This API is used to send a +L2 Measurement Request from LM to SCH. */ +EXTERN S16 cmUnpkLrgSchL2MeasReq ARGS(( + LrgSchL2MeasReq func, + Pst * pst, + Buffer *mBuf +)); +/** @brief This API is used to send a +L2 Measurement Stop Request from LM to SCH. */ +EXTERN S16 cmPkLrgSchL2MeasSendReq ARGS(( + Pst * pst, + LrgSchMeasSndReqInfo * meas +)); +/** @brief This API is used to send a +L2 Measurement Request from LM to SCH. */ +EXTERN S16 cmUnpkLrgSchL2MeasSendReq ARGS(( + LrgSchL2MeasSendReq func, + Pst * pst, + Buffer *mBuf +)); +/** @brief This API is used to send a +L2 Measurement Stop Request from LM to SCH. */ +EXTERN S16 cmPkLrgSchL2MeasStopReq ARGS(( + Pst * pst, + LrgSchMeasStopReqInfo * meas +)); +/** @brief This API is used to send a +L2 Measurement Request from LM to SCH. */ +EXTERN S16 cmUnpkLrgSchL2MeasStopReq ARGS(( + LrgSchL2MeasStopReq func, + Pst * pst, + Buffer *mBuf +)); +/** @brief This API is used to carry +L2 Measurement Cfm from SCH. */ +EXTERN S16 cmPkLrgSchL2MeasStopCfm ARGS(( + Pst * pst, + LrgSchMeasCfmInfo *measInfo +)); +/** @brief This API is used to carrya +L2 Measurement Cfm from SCH. */ +EXTERN S16 cmUnpkLrgSchL2MeasStopCfm ARGS(( + LrgSchL2MeasStopCfm func, + Pst *pst, + Buffer *mBuf +)); +#endif +/** @brief This API is used to send a +Configuration Confirm from MAC to LM. */ +EXTERN S16 cmPkLrgCfgCfm ARGS(( + Pst * pst, + RgMngmt * cfm +)); +/** @brief This API is used to send a +Configuration Confirm from MAC to LM. */ +EXTERN S16 cmUnpkLrgCfgCfm ARGS(( + LrgCfgCfm func, + Pst * pst, + Buffer *mBuf +)); +/** @brief This API is used to send a +Configuration Confirm from SCH to LM. */ +EXTERN S16 cmPkLrgSchCfgCfm ARGS(( + Pst * pst, + RgMngmt * cfg +)); +/** @brief This API is used to send a +Configuration Confirm from SCH to LM. */ +EXTERN S16 cmUnpkLrgSchCfgCfm ARGS(( + LrgSchCfgCfm func, + Pst * pst, + Buffer *mBuf +)); +/** @brief This API is used to send a +Statistics Request from LM to MAC. */ +EXTERN S16 cmPkLrgStsReq ARGS(( + Pst * pst, + RgMngmt * sts +)); +/** @brief This API is used to send a +Statistics Request from LM to MAC. */ +EXTERN S16 cmUnpkLrgStsReq ARGS(( + LrgStsReq func, + Pst * pst, + Buffer *mBuf +)); +/** @brief This API is used to send a +Statistics Confirm from MAC to LM. */ +EXTERN S16 cmPkLrgStsCfm ARGS(( + Pst * pst, + RgMngmt * cfm +)); +/** @brief This API is used to send a +Statistics Confirm from MAC to LM. */ +EXTERN S16 cmUnpkLrgStsCfm ARGS(( + LrgStsCfm func, + Pst * pst, + Buffer *mBuf +)); +/** @brief This API is used to send a +Status Request from LM to MAC. */ +EXTERN S16 cmPkLrgStaReq ARGS(( + Pst * pst, + RgMngmt * sta +)); +/** @brief This API is used to send a +Status Request from LM to MAC. */ +EXTERN S16 cmUnpkLrgStaReq ARGS(( + LrgStaReq func, + Pst * pst, + Buffer *mBuf +)); +/** @brief This API is used to send a +Status Confirm from MAC to LM. */ +EXTERN S16 cmPkLrgStaCfm ARGS(( + Pst * pst, + RgMngmt * cfm +)); +/** @brief This API is used to send a +Status Confirm from MAC to LM. */ +EXTERN S16 cmUnpkLrgStaCfm ARGS(( + LrgStaCfm func, + Pst * pst, + Buffer *mBuf +)); +/** @brief This API is used to send a +Status Indication from MAC to LM. */ +EXTERN S16 cmPkLrgStaInd ARGS(( + Pst * pst, + RgMngmt * usta +)); +/** @brief This API is used to send a +Status Indication from MAC to LM. */ +EXTERN S16 cmUnpkLrgStaInd ARGS(( + LrgStaInd func, + Pst * pst, + Buffer *mBuf +)); +/** @brief This API is used to send a +Status Indication from SCH to LM. */ +EXTERN S16 cmPkLrgSchStaInd ARGS(( + Pst * pst, + RgMngmt * sta +)); +/** @brief This API is used to send a +Status Indication from SCH to LM. */ +EXTERN S16 cmUnpkLrgSchStaInd ARGS(( + LrgSchStaInd func, + Pst * pst, + Buffer *mBuf +)); +/** @brief This API is used to send a +Control Request from LM to MAC. */ +EXTERN S16 cmPkLrgCntrlReq ARGS(( + Pst * pst, + RgMngmt * cntrl +)); +/** @brief This API is used to send a +Control Request from LM to MAC. */ +EXTERN S16 cmUnpkLrgCntrlReq ARGS(( + LrgCntrlReq func, + Pst * pst, + Buffer *mBuf +)); +/** @brief This API is used to send a +Control Request from LM to SCH. */ +EXTERN S16 cmPkLrgSchCntrlReq ARGS(( + Pst * pst, + RgMngmt * cntrl +)); +/** @brief This API is used to send a +Control Request from LM to SCH. */ +EXTERN S16 cmUnpkLrgSchCntrlReq ARGS(( + LrgSchCntrlReq func, + Pst * pst, + Buffer *mBuf +)); +/** @brief This API is used to send a +Control Confirm from MAC to LM.*/ +EXTERN S16 cmPkLrgCntrlCfm ARGS(( + Pst * pst, + RgMngmt * cfm +)); +/** @brief This API is used to send a +Control Confirm from MAC to LM. */ +EXTERN S16 cmUnpkLrgCntrlCfm ARGS(( + LrgCntrlCfm func, + Pst * pst, + Buffer *mBuf +)); +/** @brief This API is used to send a +Control Confirm from SCH to LM. */ +EXTERN S16 cmPkLrgSchCntrlCfm ARGS(( + Pst * pst, + RgMngmt * cntrl +)); +/** @brief This API is used to send a +Control Confirm from SCH to LM. */ +EXTERN S16 cmUnpkLrgSchCntrlCfm ARGS(( + LrgSchCntrlCfm func, + Pst * pst, + Buffer *mBuf +)); +/** @brief This API is used to send a +Trace Indication from MAC to LM. */ +EXTERN S16 cmPkLrgTrcInd ARGS(( + Pst * pst, + RgMngmt * trc, + Buffer * trcBuf +)); +/** @brief This API is used to send a +Trace Indication from MAC to LM. */ +EXTERN S16 cmUnpkLrgTrcInd ARGS(( + LrgTrcInd func, + Pst * pst, + Buffer *mBuf +)); +EXTERN S16 cmPkRgGenCfg ARGS(( + RgGenCfg *param, + Buffer *mBuf +)); +EXTERN S16 cmUnpkRgGenCfg ARGS(( + RgGenCfg *param, + Buffer *mBuf +)); +EXTERN S16 cmPkRgUpSapCfg ARGS(( + RgUpSapCfg *param, + Buffer *mBuf +)); +EXTERN S16 cmUnpkRgUpSapCfg ARGS(( + RgUpSapCfg *param, + Buffer *mBuf +)); +EXTERN S16 cmPkRgLowSapCfg ARGS(( + RgLowSapCfg *param, + Buffer *mBuf +)); +EXTERN S16 cmUnpkRgLowSapCfg ARGS(( + RgLowSapCfg *param, + Buffer *mBuf +)); +EXTERN S16 cmPkRgGenSts ARGS(( + RgGenSts *param, + Buffer *mBuf +)); + +#ifdef MAC_SCH_STATS +EXTERN S16 cmPkRgSchHqRetxStats ARGS(( + RgSchHqRetxStats *param, + Buffer *mBuf +)); +EXTERN S16 cmPkRgSchNackAckStats ARGS(( + RgSchNackAckStats *param, + Buffer *mBuf +)); +EXTERN S16 cmPkRgHqNumRetx ARGS(( + RgSchHqNumRetx *param, + Buffer *mBuf +)); +EXTERN S16 cmPkRgAckNack ARGS(( + RgAckNack *param, + Buffer *mBuf +)); + +EXTERN S16 cmUnpkRgSchHqRetxStats ARGS(( + RgSchHqRetxStats *param, + Buffer *mBuf +)); +EXTERN S16 cmUnpkRgSchNackAckStats ARGS(( + RgSchNackAckStats *param, + Buffer *mBuf +)); +EXTERN S16 cmUnpkRgHqNumRetx ARGS(( + RgSchHqNumRetx *param, + Buffer *mBuf +)); +EXTERN S16 cmUnpkRgAckNack ARGS(( + RgAckNack *param, + Buffer *mBuf +)); +#endif /* MAC_SCH_STATS */ + +EXTERN S16 cmUnpkRgGenSts ARGS(( + RgGenSts *param, + Buffer *mBuf +)); +EXTERN S16 cmPkRgSapSts ARGS(( + RgSapSts *param, + Buffer *mBuf +)); +EXTERN S16 cmUnpkRgSapSts ARGS(( + RgSapSts *param, + Buffer *mBuf +)); +EXTERN S16 cmPkRgSchInstCfg ARGS(( + RgSchInstCfg *param, + Buffer *mBuf +)); +EXTERN S16 cmUnpkRgSchInstCfg ARGS(( + RgSchInstCfg *param, + Buffer *mBuf +)); +EXTERN S16 cmPkRgCfg ARGS(( + RgCfg *param, + S16 elmnt, + Buffer *mBuf +)); +EXTERN S16 cmUnpkRgCfg ARGS(( + RgCfg *param, + S16 elmnt, + Buffer *mBuf +)); +EXTERN S16 cmPkRgSapSta ARGS(( + RgSapSta *param, + Buffer *mBuf +)); +EXTERN S16 cmUnpkRgSapSta ARGS(( + RgSapSta *param, + Buffer *mBuf +)); +EXTERN S16 cmPkRgSts ARGS(( + RgSts *param, + S16 elmnt, + Buffer *mBuf +)); +EXTERN S16 cmUnpkRgSts ARGS(( + RgSts *param, + S16 elmnt, + Buffer *mBuf +)); +/* lrg_x_001.main_3 - MODIFY - Modified the below function to hold the event type */ +#ifdef LRG_V1 +EXTERN S16 cmPkRgSsta ARGS(( + Pst *pst, + RgSsta *param, + S16 elmnt, + /*ccpu00118255 - ADD - eventType param */ + U8 eventType, + Buffer *mBuf +)); +#else /*LRG_V1 not defined */ +EXTERN S16 cmPkRgSsta ARGS(( + Pst *pst, + RgSsta *param, + S16 elmnt, + Buffer *mBuf +)); +#endif /* LRG_V1 endif */ +EXTERN S16 cmUnpkRgSsta ARGS(( + Pst *pst, + RgSsta *param, + S16 elmnt, + Buffer *mBuf +)); +EXTERN S16 cmPkRgUstaDgn ARGS(( + RgUstaDgn *param, + Buffer *mBuf +)); +EXTERN S16 cmUnpkRgUstaDgn ARGS(( + RgUstaDgn *param, + Buffer *mBuf +)); +EXTERN S16 cmPkRgUsta ARGS(( + RgUsta *param, + Buffer *mBuf +)); +EXTERN S16 cmUnpkRgUsta ARGS(( + RgUsta *param, + Buffer *mBuf +)); +EXTERN S16 cmPkRgTrc ARGS(( + RgTrc *param, + Buffer *mBuf +)); +EXTERN S16 cmUnpkRgTrc ARGS(( + RgTrc *param, + Buffer *mBuf +)); +EXTERN S16 cmPkRgDbgCntrl ARGS(( + RgDbgCntrl *param, + Buffer *mBuf +)); +EXTERN S16 cmUnpkRgDbgCntrl ARGS(( + RgDbgCntrl *param, + Buffer *mBuf +)); +EXTERN S16 cmPkRgSapCntrl ARGS(( + RgSapCntrl *param, + Buffer *mBuf +)); +EXTERN S16 cmUnpkRgSapCntrl ARGS(( + RgSapCntrl *param, + Buffer *mBuf +)); +EXTERN S16 cmPkRgCntrl ARGS(( + RgCntrl *param, + S16 elmnt, + Buffer *mBuf +)); +EXTERN S16 cmUnpkRgCntrl ARGS(( + RgCntrl *param, + S16 elmnt, + Buffer *mBuf +)); +EXTERN S16 cmPkRgMngmt ARGS(( + Pst *pst, + RgMngmt *param, + U8 eventType, + Buffer *mBuf +)); +EXTERN S16 cmUnpkRgMngmt ARGS(( + Pst *pst, + RgMngmt *param, + U8 eventType, + Buffer *mBuf +)); + +#ifdef PHY_ERROR_LOGING +EXTERN S16 cmPkRgSchUlAllocCntrl ARGS(( + RgSchUlAllocCntrl *param, + Buffer *mBuf +)); + +EXTERN S16 cmUnpkRgSchUlAllocCntrl ARGS(( + RgSchUlAllocCntrl *param, + Buffer *mBuf +)); +#endif +/* lrg_x_001.main_4 ccpu00117036 - C++ support */ +#ifdef __cplusplus +} +#endif +#endif + +#endif /* __LRGX__. */ + + +/********************************************************************** + End of file +**********************************************************************/ diff --git a/src/cm/nlu.h b/src/cm/nlu.h new file mode 100755 index 000000000..c5b83f558 --- /dev/null +++ b/src/cm/nlu.h @@ -0,0 +1,59 @@ +/******************************************************************************* +################################################################################ +# Copyright (c) [2017-2019] [Radisys] # +# # +# 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. # +################################################################################ +*******************************************************************************/ + +/********************************************************************20** + + Name: ESON layer management + + Type: + + Desc: This file contains the + + + File: nlu.h + +*********************************************************************21*/ +#ifndef __NLUH__ +#define __NLUH__ + +#define NLU_SEL_LC 0 +#define NLU_SEL_TC 1 +#define NLU_SEL_LWLC 2 + +#define EVTNLUBNDREQ 1 +#define EVTNLUBNDCFM 2 +#define EVTNLUNHBRREQ 3 +#define EVTNLUPCIMODINDCFM 4 +#define EVTNLUPERCELLSRCHRSP 5 +#define EVTNLUUEMEASRPTIND 6 +#define EVTNLUUECQIRPTIND 7 +#define EVTNLUUEIND 8 + +#define NLU_MAX_NGH_CELL_INFO 16 +#define NLU_MAX_REPORTS 8 +#define NLU_MAX_NGH_NGH_CELL_INFO 16 +#define NLU_MAX_NGH_ENB_CFG 16 +/* Periodic REM for TPM */ +#define NLU_REM_MAX_CELL_SEARCH 16 +/* Periodic REM for TPM End */ +#define LWR_LTEU_MAX_EARFCN 10 +#endif /* __NLUH__ */ +/********************************************************************30** + + End of file +**********************************************************************/ diff --git a/src/cm/pj_tenb_stats.h b/src/cm/pj_tenb_stats.h new file mode 100755 index 000000000..059a72535 --- /dev/null +++ b/src/cm/pj_tenb_stats.h @@ -0,0 +1,55 @@ +/******************************************************************************* +################################################################################ +# Copyright (c) [2017-2019] [Radisys] # +# # +# 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. # +################################################################################ +*******************************************************************************/ + +/********************************************************************** + + Name: + + Type: + + Desc: + + File: pj_tenb_stats.h + +**********************************************************************/ + +/** @file pj_tenb_stats.h +*/ + +#ifdef TENB_STATS +#ifndef __TENBSTATSH__ +#define __TENBSTATSH__ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ +/*MCELL changes*/ +#define L2_STATS_MAX_CELLS 5 +#ifdef XEON_SPECIFIC_CHANGES +#define L2_STATS_MAX_UES TENB_MAX_UE_SUPPORTED /* ANOOP changed */ +#define L2_STATS_MAX_RNTIS 61 + TENB_MAX_UE_SUPPORTED +#else +#define L2_STATS_MAX_UES 120 +#define L2_STATS_MAX_RNTIS 500 +#endif + +#endif +#endif /* TENB_STATS */ +/********************************************************************** + End of file +**********************************************************************/ diff --git a/src/cm/pj_tenb_stats.x b/src/cm/pj_tenb_stats.x new file mode 100755 index 000000000..38166de9d --- /dev/null +++ b/src/cm/pj_tenb_stats.x @@ -0,0 +1,85 @@ +/******************************************************************************* +################################################################################ +# Copyright (c) [2017-2019] [Radisys] # +# # +# 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. # +################################################################################ +*******************************************************************************/ + +/********************************************************************** + + Name: + + Type: + + Desc: + + File: pj_tenb_stats.x + +**********************************************************************/ + +/** @file pj_tenb_stats.x +*/ + +#ifdef TENB_STATS +#ifndef __TENBSTATSL2X__ +#define __TENBSTATSL2X__ + +#include "cm_tenb_stats.x" +#include "pj_tenb_stats.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +typedef TSInfL2CellStats TSL2CellStatsCb; + +typedef struct tSL2UeStatsCb +{ + CmLList lnk; + U32 inUse; + + TSInfL2UeStats stats; +}TSL2UeStatsCb; + +EXTERN Void TSL2AllocStatsMem ARGS(( + Region region, + Pool pool +)); +EXTERN TSL2UeStatsCb* TSL2AllocUeStatsBlk ARGS(( + U16 rnti +)); +EXTERN Void TSL2DeallocUeStatsBlk ARGS(( + U16 rnti, + TSL2UeStatsCb *statsCb +)); +EXTERN TSL2CellStatsCb* TSL2AllocCellStatsBlk ARGS(( + U32 cellId +)); +EXTERN Void TSL2DeallocCellStatsBlk ARGS(( + U32 cellId +)); +EXTERN Void TSL2SendStatsToApp ARGS(( + Pst *pst, + SuId suId +)); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* __TENBSTATSL2X__ */ +#endif /* TENB_STATS */ + +/********************************************************************** + End of file +**********************************************************************/ diff --git a/src/cm/rgm.h b/src/cm/rgm.h new file mode 100755 index 000000000..99363df57 --- /dev/null +++ b/src/cm/rgm.h @@ -0,0 +1,80 @@ +/******************************************************************************* +################################################################################ +# Copyright (c) [2017-2019] [Radisys] # +# # +# 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. # +################################################################################ +*******************************************************************************/ + +/********************************************************************** + Name: Upper Layer Interface - RLC + + Type: C header file + + Desc: Structures, variables and typedefs required by + RGM interface + + File: rgm.h + +*********************************************************************21*/ + + +#ifndef __RGMH__ +#define __RGMH__ +#ifdef __cplusplus +extern "C" { +#endif + +/** + @file rgm.h + @brief Defines for RGM interface. + */ + + +/*********************************************************************** + Macro Definitions + ***********************************************************************/ + +/* Event corresponding to each primitive at this interface */ +#define EVTRGMBASEEVT 0 /*!< Bind Request */ +#define EVTRGMBNDREQ 1 /*!< Bind Request */ +#define EVTRGMUBNDREQ 2 /*!< Un-Bind Request */ +#define EVTRGMBNDCFM 3 /*!< Bind Confirm */ +#define EVTRGMCFGPRBRPRT 4 /*!< PRB Report Configuration */ +#define EVTRGMPRBRPRTIND 5 /*!< PRB report Indication */ +#define EVTRGMTRANSMODEIND 6 /*!< Trans Mode Chg Indication */ +#define EVTRGMMAX 7 + + +/* selector(coupling) values */ +#define RGM_SEL_LC 0 +#define RGM_SEL_LWLC 1 +#define RGM_SEL_TC 2 + +#define RGM_UBNDREQ_MNGMT 1 /*!< TFU sap unbind reason */ +/* RRM_SP1_START */ +/* Rgm Prb Usage Info */ +#define RGM_PRB_USAGE_UL 1 /* Only UL - Mode TDD */ +#define RGM_PRB_USAGE_DL 2 /* Only DL - Mode TDD */ +/* RRM_SP1_END */ + + +#ifdef __cplusplus +} +#endif +#endif /* __RGMH__ */ + +/********************************************************************30** + + End of file +**********************************************************************/ diff --git a/src/cm/rgm.x b/src/cm/rgm.x new file mode 100755 index 000000000..e554fee52 --- /dev/null +++ b/src/cm/rgm.x @@ -0,0 +1,420 @@ +/******************************************************************************* +################################################################################ +# Copyright (c) [2017-2019] [Radisys] # +# # +# 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. # +################################################################################ +*******************************************************************************/ + +/********************************************************************** + Name: Upper Layer Interface + + Type: C header file + + Desc: Structures, variables and typedefs required by + RGU interface + + File: rgu.x + +*********************************************************************21*/ + + +#ifndef __RGMX__ +#define __RGMX__ +#ifdef __cplusplus +extern "C" { +#endif + +/** + @file rgu.x + @brief Structure declarations and definitions for RGU interface. + */ + +/*********************************************************************** + typedefs and data structures + ***********************************************************************/ + +#define RGM_PRB_REPORT_STOP 0 +#define RGM_PRB_REPORT_START 1 + +#define RGM_MAX_QCI_REPORTS 4 + +typedef struct rgmPrbRprtCfg +{ + U16 usPrbAvgPeriodicty; /* It is in milli sec */ + U8 bConfigType; + U8 bCellId; +}RgmPrbRprtCfg; + +/* RRM_SP1_START */ +typedef struct rgmPrbRptPerQci +{ + U8 bQci; + U8 bAvgPrbUlUsage; + U8 bAvgPrbDlUsage; +}RgmPrbRptPerQci; + +typedef struct rgmPrbRprtInd +{ + RgmPrbRptPerQci stQciPrbRpts[RGM_MAX_QCI_REPORTS]; +/* RRM_SP1_END */ + U8 bCellId; + /* TDD: DL PRB Usage pres = 2 and + * UL PRB Usage pres = 1 + * FDD: DL and UL Usage Pres = 3 + */ + U8 bPrbUsageMask; +}RgmPrbRprtInd; + +typedef enum +{ + RGM_TXN_MODE1, + RGM_TXN_MODE2, + RGM_TXN_MODE3, + RGM_TXN_MODE4, + RGM_TXN_MODE5, + RGM_TXN_MODE6, + RGM_TXN_MODE7, + RGM_TXN_MODE8 +} RgmTxnMode; + +typedef struct rgmTransModeInd +{ + RgmTxnMode eMode; /* Indicate TM Mode */ + U16 usCrnti; /* UE Crnti value */ + U8 bCellId; /* Cell Id */ +}RgmTransModeInd; +/*********************************************************************** + type definitions for upper layer interface - RLC primitives + ***********************************************************************/ +/** @brief Bind Request from RLC to MAC to bind the interface SAPs */ +typedef S16 (*RgmBndReq) ARGS(( + Pst* pst, + SuId suId, + SpId spId)); +/** @brief Unbind Request from RLC to MAC to unbind the interface SAPs */ +typedef S16 (*RgmUbndReq) ARGS(( + Pst* pst, + SpId spId, + Reason reason)); +/** @brief Bind Confirmation from MAC to RLC for the bind/unbind + * request for the interface SAPs */ +typedef S16 (*RgmBndCfm) ARGS(( + Pst* pst, + SuId suId, + U8 status)); +/** @brief Data Request from RLC to MAC for forwarding SDUs on common + * channel for transmission */ +typedef S16 (*RgmCfgPrbRprtFptr) ARGS(( + Pst* pst, + SpId spId, + RgmPrbRprtCfg * prbRprtCfg)); +/** @brief Data Indication from MAC to RLC to + * forward the data received for common channels */ +typedef S16 (*RgmPrbRprtIndFptr) ARGS(( + Pst* pst, + SuId suId, + RgmPrbRprtInd * prbRprtInd)); + +typedef S16 (*RgmTransModeIndFptr) ARGS(( + Pst* pst, + SuId suId, + RgmTransModeInd * transModeInd)); +#ifdef RG +/** @brief Bind Request from RLC to MAC to bind the interface SAPs + * @param pst Pointer to the post structure. + * @param suId SAP ID of the service user. + * @param spId SAP ID of the service provider. + * @return ROK/RFAILED +*/ +EXTERN S16 RgUiRgmBndReq ARGS((Pst* pst,SuId suId,SpId spId)); +/** @brief Unbind Request from RLC to MAC to unbind the interface SAPs + * @param pst Pointer to the post structure. + * @param spId SAP ID of the service provider. + * @param reason Reason for unbind request. + * @return ROK/RFAILED +*/ +EXTERN S16 RgUiRgmUbndReq ARGS((Pst* pst,SpId spId,Reason reason)); +/** @brief Bind Confirmation from MAC to RLC for the bind and unbind + * request for the interface SAPs + * @param pst Pointer to the post structure. + * @param suId SAP ID of the service user. + * @param status Status of the bind request. + * @return ROK/RFAILED +*/ +EXTERN S16 RgUiRgmBndCfm ARGS((Pst* pst,SuId suId,U8 status)); +/** @brief Data Request from RLC to MAC for forwarding SDUs on common + * channel for transmission + * @param pst Pointer to the post structure. + * @param spId SAP ID of the service provider. + * @param prbRprtCfg Data request for common channels (BCCH, PCCH and CCCH). + * @return ROK/RFAILED +*/ +EXTERN S16 RgUiRgmCfgPrbRprt ARGS((Pst* pst,SuId suId,RgmPrbRprtCfg *prbRprtCfg)); +/** @brief Data Indication from MAC to RLC to + * forward the data received for common channels + * @param pst Pointer to the post structure. + * @param suId SAP ID of the service user. + * @param prbRprtInd Data indication on CCCH. + * @return ROK/RFAILED +*/ +EXTERN S16 RgUiRgmPrbRprtInd ARGS((Pst* pst,SuId suId,RgmPrbRprtInd *prbRprtInd)); + +#endif + +#ifdef RM_INTF +/** @brief Request from RLC to MAC to bind the interface saps */ +EXTERN S16 RmLiRgmBndReq ARGS(( + Pst* pst, + SuId suId, + SpId spId +)); +/** @brief Request from RLC to MAC to Unbind the interface saps */ +EXTERN S16 RmLiRgmUbndReq ARGS(( + Pst* pst, + SpId spId, + Reason reason +)); +/** @brief Confirmation from MAC to RLC for the bind/Unbind + * request for the interface saps */ +EXTERN S16 RmLiRgmBndCfm ARGS(( + Pst* pst, + SuId suId, + U8 status +)); +/** @brief Request from RLC to MAC for forwarding SDUs on common + * channel for transmission */ +EXTERN S16 RmLiRgmCfgPrbRprt ARGS(( + Pst* pst, + SpId spId, + RgmPrbRprtCfg* prbRprtCfg +)); +/** @brief Data Indication from MAC to RLC to + * forward the data received for common channels*/ +EXTERN S16 RmLiRgmPrbRprtInd ARGS(( + Pst* pst, + SuId suId, + RgmPrbRprtInd* prbRprtInd +)); +/** @brief Data Indication from MAC to RRM to + * change the transmission mode*/ +EXTERN S16 RmLiRgmTransModeInd ARGS(( + Pst* pst, + SuId suId, + RgmTransModeInd* transModeInd +)); +#endif + +#ifdef RGM_LWLC +/** @brief Request from RLC to MAC to bind the interface saps */ +EXTERN S16 cmPkLwLcRgmBndReq ARGS(( + Pst* pst, + SuId suId, + SpId spId +)); +/** @brief Request from RLC to MAC to bind the interface saps */ +EXTERN S16 cmUnpkLwLcRgmBndReq ARGS(( + RgmBndReq func, + Pst* pst, + Buffer *mBuf +)); +/** @brief Request from RLC to MAC to Unbind the interface saps */ +EXTERN S16 cmPkLwLcRgmUbndReq ARGS(( + Pst* pst, + SpId spId, + Reason reason +)); +/** @brief Request from RLC to MAC to Unbind the interface saps */ +EXTERN S16 cmUnpkLwLcRgmUbndReq ARGS(( + RgmUbndReq func, + Pst* pst, + Buffer *mBuf +)); +/** @brief Confirmation from MAC to RLC for the bind/Unbind + * request for the interface saps */ +EXTERN S16 cmPkLwLcRgmBndCfm ARGS(( + Pst* pst, + SuId suId, + U8 status +)); +/** @brief Confirmation from MAC to RLC for the bind/Unbind + * request for the interface saps */ +EXTERN S16 cmUnpkLwLcRgmBndCfm ARGS(( + RgmBndCfm func, + Pst* pst, + Buffer *mBuf +)); +/** @brief Request from RLC to MAC for forwarding SDUs on common + * channel for transmission */ +EXTERN S16 cmPkLwLcRgmCfgPrbRprt ARGS(( + Pst* pst, + SpId spId, + RgmPrbRprtCfg * prbRprtCfg +)); +/** @brief Request from RLC to MAC for forwarding SDUs on common + * channel for transmission */ +EXTERN S16 cmUnpkLwLcRgmCfgPrbRprt ARGS(( + RgmCfgPrbRprtFptr func, + Pst* pst, + Buffer *mBuf +)); +/** @brief Data Indication from MAC to RLC to + * forward the data received for common channels*/ +EXTERN S16 cmPkLwLcRgmPrbRprtInd ARGS(( + Pst* pst, + SuId suId, + RgmPrbRprtInd * prbRprtInd +)); +/** @brief Data Indication from MAC to RLC to + * forward the data received for common channels*/ +EXTERN S16 cmUnpkLwLcRgmPrbRprtInd ARGS(( + RgmPrbRprtIndFptr func, + Pst* pst, + Buffer *mBuf +)); +#endif + + +/** @brief Request from RLC to MAC to bind the interface saps */ +EXTERN S16 cmPkRgmBndReq ARGS(( + Pst* pst, + SuId suId, + SpId spId +)); +/** @brief Request from RLC to MAC to bind the interface saps */ +EXTERN S16 cmUnpkRgmBndReq ARGS(( + RgmBndReq func, + Pst* pst, + Buffer *mBuf +)); +/** @brief Request from RLC to MAC to Unbind the interface saps */ +EXTERN S16 cmPkRgmUbndReq ARGS(( + Pst* pst, + SpId spId, + Reason reason +)); +/** @brief Request from RLC to MAC to Unbind the interface saps */ +EXTERN S16 cmUnpkRgmUbndReq ARGS(( + RgmUbndReq func, + Pst* pst, + Buffer *mBuf +)); +/** @brief Confirmation from MAC to RLC for the bind/Unbind + * request for the interface saps */ +EXTERN S16 cmPkRgmBndCfm ARGS(( + Pst* pst, + SuId suId, + U8 status +)); +/** @brief Confirmation from MAC to RLC for the bind/Unbind + * request for the interface saps */ +EXTERN S16 cmUnpkRgmBndCfm ARGS(( + RgmBndCfm func, + Pst* pst, + Buffer *mBuf +)); +/** @brief Request from RLC to MAC for forwarding SDUs on common + * channel for transmission */ +EXTERN S16 cmPkRgmCfgPrbRprt ARGS(( + Pst* pst, + SpId spId, + RgmPrbRprtCfg * prbRprtCfg +)); + + +EXTERN S16 cmPkCfgPrbRprt ARGS(( +RgmPrbRprtCfg * prbRprtCfg, +Buffer *mBuf +)); + +EXTERN S16 cmPkPrbRprtInd ARGS(( +RgmPrbRprtInd * prbRprtInd, +Buffer *mBuf +)); + +/** @brief Request from RLC to MAC for forwarding SDUs on common + * channel for transmission */ +EXTERN S16 cmUnpkRgmCfgPrbRprt ARGS(( + RgmCfgPrbRprtFptr func, + Pst* pst, + Buffer *mBuf +)); + +EXTERN S16 cmUnPkCfgPrbRprt ARGS(( +RgmPrbRprtCfg * prbRprtCfg, +Buffer *mBuf +)); + +/** @brief Data Indication from MAC to RLC to + * forward the data received for common channels*/ +EXTERN S16 cmPkRgmPrbRprtInd ARGS(( + Pst* pst, + SuId suId, + RgmPrbRprtInd * prbRprtInd +)); + + +EXTERN S16 cmUnpkPrbRprtInd ARGS(( +RgmPrbRprtInd * prbRprtInd, +Buffer *mBuf +)); + +EXTERN S16 cmPkTransModeInd ARGS(( +RgmTransModeInd *transModeInd, +Buffer *mBuf +)); + +EXTERN S16 cmUnpkTransModeInd ARGS(( +RgmTransModeInd *transModeInd, +Buffer *mBuf +)); +EXTERN S16 cmPkRgmTransModeInd ARGS(( + Pst* pst, + SuId suId, + RgmTransModeInd *transModeInd +)); + + +EXTERN S16 cmUnpkRgmTransModeInd ARGS(( + RgmTransModeIndFptr func, + Pst* pst, + Buffer *mBuf + )); + +/** @brief Data Indication from MAC to RLC to + * forward the data received for common channels*/ +EXTERN S16 cmUnpkRgmPrbRprtInd ARGS(( + RgmPrbRprtIndFptr func, + Pst* pst, + Buffer *mBuf +)); + +EXTERN S16 cmPkRgmPrbQciRpt ARGS(( +RgmPrbRptPerQci *qciPrbRprt, +Buffer *mBuf +)); + +EXTERN S16 cmUnpkRgmPrbQciRpt ARGS(( +RgmPrbRptPerQci *qciPrbRprt, +Buffer *mBuf +)); + +#ifdef __cplusplus +} +#endif +#endif /* __RGUX__ */ + +/********************************************************************30** + + End of file +**********************************************************************/ diff --git a/src/cm/rgr.h b/src/cm/rgr.h new file mode 100755 index 000000000..fe416f43f --- /dev/null +++ b/src/cm/rgr.h @@ -0,0 +1,427 @@ +/******************************************************************************* +################################################################################ +# Copyright (c) [2017-2019] [Radisys] # +# # +# 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. # +################################################################################ +*******************************************************************************/ + +/********************************************************************** + Name: LTE-MAC layer + + Type: C include file + + Desc: Defines required by the LTE MAC-RRM control (RGR) interface. + + File: rgr.h + +**********************************************************************/ + +#ifndef __RGR_H__ +#define __RGR_H__ +#include "nlu.h" +/** + @file rgr.h + @brief Macros for RGR interface. + */ +#define RGR_LTEU_MAX_EARFCN 10 +#define RGR_MAX_SUBBANDS 110 +#define RGR_MIN_CMN_LC_PER_CELL 4 /*!< BCCH-BCH, BCCH-DLSCH , PCCH, + CCCH (bi-directional) */ +#define RGR_MAX_CMN_LC_PER_CELL 6 /*!< BCCH-BCH, BCCH-DLSCH (can be 2), PCCH, + CCCH (can be 2 - UL and DL, if given differently) */ +#define RGR_MAX_NUM_QCI 9 /*!< Maximum number of Supported QCIs */ + +/* LTE_ADV_FLAG_REMOVED_START */ +#define RGR_ABS_PATTERN_LEN 40 + +#define RGR_MAX_NBR_ENB 2 /*Maximum there can be 2 neighbours who will have different Edge RB Range*/ +/* LTE_ADV_FLAG_REMOVED_END */ + +/*rgr_h_001.main_8 ADD added changes for L2 Measurements*/ +#ifdef LTE_L2_MEAS +#define RGR_MAX_LC_PER_LCG 10 /*!< Number of Logical Channels per LCG */ +#endif /* LTE_L2_MEAS*/ + +/* Configuration/Reconfiguration MACROs*/ +#define RGR_CONFIG 1 /*!< Macro for Configuration Request*/ +#define RGR_RECONFIG 2 /*!< Macro for Reconfiguration Request*/ +#define RGR_DELETE 3 /*!< Macro for Delete Request*/ +#define RGR_RESET 4 /*!< Macro for Reset Request*/ +#define RGR_SON_CFG 5 /*!< Macro for SON configuration Request*/ +#ifdef LTE_ADV +#define RGR_SCELL_ACT 6 /*!< Macro for Activation of SCell */ +#define RGR_SCELL_DEACT 7 /*!< Macro for De-activation of SCell */ +#define RGR_SCELL_READY 8 /*!< Macro Indicating that SCELL is ready for activation */ +#endif /* LTE_ADV */ +/* Cell/UE specific MACROs*/ +#define RGR_CELL_CFG 1 /*!< Macro for Cell Configuration Type */ +#define RGR_UE_CFG 2 /*!< Macro for UE Configuration Type */ +#define RGR_LCH_CFG 3 /*!< Macro for Logical Channel Configuration Type */ +#define RGR_LCG_CFG 4 /*!< Macro for Logical Group Configuration Type */ +#define RGR_SCELL_UE_CFG 5 /*!< MACRO for Scell release */ +#define RGR_ENB_CFG 6 /*!< MACRO for ENB Scheduler Configuration Type */ + +/* Cell-wide reconfiguration MACROs */ +#define RGR_CELL_DL_CMNRATE_RECFG (1<<0) /*!< Macro for Downlink Common Coderate Reconfiguration */ +#define RGR_CELL_CFI_RECFG (1<<1) /*!< Macro for CFI Reconfiguration */ +#define RGR_CELL_TRGCQI_RECFG (1<<2) /*!< Macro for Target CFI Reconfiguration */ +#define RGR_CELL_PUSCH_SB_RECFG (1<<3) /*!< Macro for PUSCH SB Reconfiguration */ +#define RGR_CELL_UL_CMNRATE_RECFG (1<<4) /*!< Macro for Uplink Common Coderate Reconfiguration */ +#define RGR_CELL_DL_HARQ_RECFG (1<<5) /*!< Macro for Downlink HARQ Reconfiguration */ +#define RGR_CELL_PUCCH_RECFG (1<<6) /*!< Macro for PUCCH Reconfiguration */ +#define RGR_CELL_SRS_RECFG (1<<7) /*!< Macro for SRS Reconfiguration */ +#define RGR_CELL_RACH_RECFG (1<<8) /*!< Macro for RACH Reconfiguration */ +#define RGR_CELL_DLFS_RECFG (1<<9) /*!< Macro for DLFS Reconfiguration */ +#define RGR_CELL_PWR_RECFG (1<<10) /*!< Macro for Power Reconfiguration */ +/* rgr_h_001.main_3:ADD-Added for SI Enhancement. */ +/** @name RGR_SI_SCH */ +/** @{ */ +#ifdef RGR_SI_SCH +#define RGR_CELL_SI_RECFG (1<<11) /*!< Hash define for SI Re-cfg */ +/* ccpu00136659: CMAS ETWS design changes */ +#define RGR_MAX_WARNING_SI_SEG 64 /*!< Max no of SI Warning Segements */ +#endif /*RGR_SI_SCH*/ +/** @} */ +#define RGR_CELL_TMRS_RECFG (1<<12) /*!< t300 Timer reconfiguration */ + +/* LTE_ADV_FLAG_REMOVED_START */ +#define RGR_CELL_LTEA_FEATURE_RECFG (1<<13) /*! SCH -> APP) (Received at X2AP)*/ + +#define EVTRGRLOADINFREQ 15 /*!< LOAD INF Request (APP -> MAC -> SCTP) (To Remote X2AP) */ +/* LTE_ADV_FLAG_REMOVED_END */ +/** @} */ +/* Activation time limit in terms of number of frames */ +#define RGR_ACTV_WIN_SIZE 20 /*!< Size of activation time window + (in terms of number of frames) */ + +/* rgr_h_001.main_3-ADD-Added for SI Enhancement. */ +/** @name RGR_SI_SCH */ +/** @{ */ +#ifdef RGR_SI_SCH +/*SI Scheduling Specific */ +#define RGR_MAX_NUM_SI 16 /*!< Maximum Number of SI */ +#endif /*RGR_SI_SCH*/ +/*EMTC */ +#ifdef EMTC_ENABLE +#define RGR_MAX_CE_LEVEL 4 /*max number of CE LEVEL */ +#define RGR_MAX_NUM_MPDCCH_MONITOR 2 /*max number of CE LEVEL */ +#endif +/*EMTC*/ +/** @} */ +/*CA-Dev */ +#define RGR_MAX_SCELL_PER_UE 7 +/*rgr_h_001.main_8 ADD added changes for CQI Management*/ +/** @name RGR_CQI_REPT */ +/** @{ */ +/* DL Power Control Constants/Macros */ +/* ccpu00117452 - MOD - Changed macro name from + RGR_RRM_DLPWR_CNTRL to RGR_CQI_REPT */ +#ifdef RGR_CQI_REPT +#define RGR_CQIRPTS_MAXN 16 /*!< Maximum number of CQI report collation + allowed */ +#endif +#define RGR_MAX_DL_CQI_SUBBAND 13 /*!< Maximum number of Sub-Bands */ +/** @} */ +/* Selector(coupling) values */ +#define RGR_SEL_TC 1 /*!< For Tight Coupling */ +#define RGR_SEL_LC 0 /*!< For Loose coupling */ + +/* Pack/ Unpack error code */ +#define ERGRXXX 0 +#define ERRRGR 0 +/*rgr_h_001.main_8 ADD added changes for ERR Val*/ + +#define ERGR001 (ERRRGR + 1) /* rgr.c: 155 */ +#define ERGR002 (ERRRGR + 2) /* rgr.c: 163 */ +#define ERGR003 (ERRRGR + 3) /* rgr.c: 172 */ +#define ERGR004 (ERRRGR + 4) /* rgr.c: 221 */ +#define ERGR005 (ERRRGR + 5) /* rgr.c: 230 */ +#define ERGR006 (ERRRGR + 6) /* rgr.c: 276 */ +#define ERGR007 (ERRRGR + 7) /* rgr.c: 284 */ +#define ERGR008 (ERRRGR + 8) /* rgr.c: 293 */ +#define ERGR009 (ERRRGR + 9) /* rgr.c: 343 */ +#define ERGR010 (ERRRGR + 10) /* rgr.c: 352 */ +#define ERGR011 (ERRRGR + 11) /* rgr.c: 397 */ +#define ERGR012 (ERRRGR + 12) /* rgr.c: 405 */ +#define ERGR013 (ERRRGR + 13) /* rgr.c: 414 */ +#define ERGR014 (ERRRGR + 14) /* rgr.c: 463 */ +#define ERGR015 (ERRRGR + 15) /* rgr.c: 472 */ +#define ERGR016 (ERRRGR + 16) /* rgr.c: 520 */ +#define ERGR017 (ERRRGR + 17) /* rgr.c: 529 */ +#define ERGR018 (ERRRGR + 18) /* rgr.c: 539 */ +#define ERGR019 (ERRRGR + 19) /* rgr.c: 549 */ +#define ERGR020 (ERRRGR + 20) /* rgr.c: 559 */ +#define ERGR021 (ERRRGR + 21) /* rgr.c: 611 */ +#define ERGR022 (ERRRGR + 22) /* rgr.c: 620 */ +#define ERGR023 (ERRRGR + 23) /* rgr.c: 628 */ +#define ERGR024 (ERRRGR + 24) /* rgr.c: 641 */ +#define ERGR025 (ERRRGR + 25) /* rgr.c: 756 */ +#define ERGR026 (ERRRGR + 26) /* rgr.c: 764 */ +#define ERGR027 (ERRRGR + 27) /* rgr.c: 774 */ +#define ERGR028 (ERRRGR + 28) /* rgr.c: 825 */ +#define ERGR029 (ERRRGR + 29) /* rgr.c: 834 */ +#define ERGR030 (ERRRGR + 30) /* rgr.c: 849 */ +#define ERGR031 (ERRRGR + 31) /* rgr.c: 897 */ +#define ERGR032 (ERRRGR + 32) /* rgr.c: 905 */ +#define ERGR033 (ERRRGR + 33) /* rgr.c: 914 */ +#define ERGR034 (ERRRGR + 34) /* rgr.c: 923 */ +#define ERGR035 (ERRRGR + 35) /* rgr.c: 973 */ +#define ERGR036 (ERRRGR + 36) /* rgr.c: 982 */ +#define ERGR037 (ERRRGR + 37) /* rgr.c: 991 */ +#define ERGR038 (ERRRGR + 38) /* rgr.c:1040 */ +#define ERGR039 (ERRRGR + 39) /* rgr.c:1048 */ +#define ERGR040 (ERRRGR + 40) /* rgr.c:1057 */ +#define ERGR041 (ERRRGR + 41) /* rgr.c:1066 */ +#define ERGR042 (ERRRGR + 42) /* rgr.c:1117 */ +#define ERGR043 (ERRRGR + 43) /* rgr.c:1126 */ +#define ERGR044 (ERRRGR + 44) /* rgr.c:1135 */ +#define ERGR045 (ERRRGR + 45) /* rgr.c:7376 */ +#define ERGR046 (ERRRGR + 46) /* rgr.c:7386 */ +#define ERGR047 (ERRRGR + 47) /* rgr.c:7397 */ +#define ERGR048 (ERRRGR + 48) /* rgr.c:7408 */ +#define ERGR049 (ERRRGR + 49) /* rgr.c:7420 */ +#define ERGR050 (ERRRGR + 50) /* rgr.c:7471 */ +#define ERGR051 (ERRRGR + 51) /* rgr.c:7480 */ +#define ERGR052 (ERRRGR + 52) /* rgr.c:7489 */ +#define ERGR053 (ERRRGR + 53) /* rgr.c:7503 */ +#define ERGR054 (ERRRGR + 54) /* rgr.c:7721 */ +#define ERGR055 (ERRRGR + 55) /* rgr.c:7733 */ +#define ERGR056 (ERRRGR + 56) /* rgr.c:7745 */ +#define ERGR057 (ERRRGR + 57) /* rgr.c:7759 */ +#define ERGR058 (ERRRGR + 58) /* rgr.c:7808 */ +#define ERGR059 (ERRRGR + 59) /* rgr.c:7819 */ +#define ERGR060 (ERRRGR + 60) /* rgr.c:7833 */ +#define ERGR061 (ERRRGR + 61) /* rgr.c:7703 */ +#define ERGR062 (ERRRGR + 62) /* rgr.c:7714 */ +#define ERGR063 (ERRRGR + 63) /* rgr.c:7727 */ +#define ERGR064 (ERRRGR + 64) /* rgr.c:7740 */ +#define ERGR065 (ERRRGR + 65) /* rgr.c:7757 */ +#define ERGR066 (ERRRGR + 66) /* rgr.c:7811 */ +#define ERGR067 (ERRRGR + 67) /* rgr.c:7822 */ +#define ERGR068 (ERRRGR + 68) /* rgr.c:7833 */ +#define ERGR069 (ERRRGR + 69) /* rgr.c:7851 */ +#define ERGR070 (ERRRGR + 70) /* rgr.c:8023 */ +#define ERGR071 (ERRRGR + 71) /* rgr.c:8035 */ +#define ERGR072 (ERRRGR + 72) /* rgr.c:8083 */ +#define ERGR073 (ERRRGR + 73) /* rgr.c:7833 */ +#define ERGR074 (ERRRGR + 74) /* rgr.c:8138 */ +#define ERGR075 (ERRRGR + 75) /* rgr.c:8148 */ +#define ERGR076 (ERRRGR + 76) /* rgr.c:8159 */ +#define ERGR077 (ERRRGR + 77) /* rgr.c:8170 */ +#define ERGR078 (ERRRGR + 78) /* rgr.c:8181 */ +#define ERGR079 (ERRRGR + 79) /* rgr.c:8234 */ +#define ERGR080 (ERRRGR + 80) /* rgr.c:8245 */ +#define ERGR081 (ERRRGR + 81) /* rgr.c:8256 */ +#define ERGR082 (ERRRGR + 82) /* rgr.c:8038 */ +#define ERGR083 (ERRRGR + 83) /* rgr.c:8110 */ + +#endif /* __RGR_H__ */ + + +/********************************************************************** + + End of file +**********************************************************************/ diff --git a/src/cm/rgr.x b/src/cm/rgr.x new file mode 100755 index 000000000..7987f8c6a --- /dev/null +++ b/src/cm/rgr.x @@ -0,0 +1,4549 @@ +/******************************************************************************* +################################################################################ +# Copyright (c) [2017-2019] [Radisys] # +# # +# 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. # +################################################################################ +*******************************************************************************/ + +/********************************************************************** + + Name: LTE-MAC layer + + Type: C Include File + + Desc: Structures, variables, and typedefs required by the LTE MAC-RRM + Control (RGR) interface. + + File: rgr.x + +**********************************************************************/ + +#ifndef __RGR_X__ +#define __RGR_X__ + +#ifdef __cplusplus +extern "C" { +#endif +#define MAX_5GTF_SUBFRAME_INFO 10 +/** + @file rgr.x + @brief Structure declarations and definitions for RGR interface. + */ +/** Group power formats */ +typedef enum rgrGrpPwrFormat +{ + RGR_PWR_FORMAT_3, /**< Power Format 3 */ + RGR_PWR_FORMAT_3A /**< Power Format 3A */ +} RgrGrpPwrFormat; + +/** @name LTE_TDD */ +/** @{ */ +#ifdef LTE_TDD +/** Indicates one of the two TDD ACK/NACK feedback modes */ +typedef enum rgrTddAckNackMode +{ + /* rgr_x_001.main_10. Added changes of TFU_UPGRADE */ + RGR_TDD_ACKNACK_MODE_BUNDL, /**< TDD Ack/Nack Mode Bundle */ + RGR_TDD_ACKNACK_MODE_MULT /**< TDD Ack/Nack Mode Multiplex */ +} RgrTddAckNackMode; +#endif /* LTE_TDD */ +/** @} */ + +/** Periodicity of Downlink CQI Transmission per UE */ +typedef enum rgrCqiPrdicity +{ + RGR_CQI_PRD_MS2 = 2, /**< CQI Periodicity of 2ms */ + RGR_CQI_PRD_MS5 = 5, /**< CQI Periodicity of 5ms */ + RGR_CQI_PRD_MS10 = 10, /**< CQI Periodicity of 10ms */ + RGR_CQI_PRD_MS20 = 20, /**< CQI Periodicity of 20ms */ + RGR_CQI_PRD_MS32 = 32, /**< CQI Periodicity of 32ms */ + RGR_CQI_PRD_MS40 = 40, /**< CQI Periodicity of 40ms */ + RGR_CQI_PRD_MS64 = 64, /**< CQI Periodicity of 64ms */ + RGR_CQI_PRD_MS80 = 80, /**< CQI Periodicity of 80ms */ + RGR_CQI_PRD_MS128 = 128, /**< CQI Periodicity of 128ms */ + RGR_CQI_PRD_MS160 = 160, /**< CQI Periodicity of 160ms */ + RGR_CQI_PRD_MS256 = 256, /**< CQI Periodicity of 256ms */ + RGR_CQI_PRD_MSOff /**< CQI Periodicity OFF */ +} RgrCqiPrdicity; + +/** + * Periodic CQI Transmission Modes */ +typedef enum rgrPrdCqiMode +{ + RGR_PRD_CQI_MOD10,/**< Periodic CQI Mode 1-0 */ + RGR_PRD_CQI_MOD11,/**< Periodic CQI Mode 1-1 */ + RGR_PRD_CQI_MOD20,/**< Periodic CQI Mode 2-0 */ + RGR_PRD_CQI_MOD21 /**< Periodic CQI Mode 2-1 */ +} RgrPrdCqiMode; + +/** Different values for Power Aplha parameter. Divide it by 10 to get + * the actual value of the enum that is 0, 0.4, 0.5, 0.6 etc...*/ +typedef enum rgrPwrAlpha +{ + RGR_PWR_ALPHA0 = 0, /**< Power Aplha Value 0*/ + RGR_PWR_ALPHA4 = 4, /**< Power Aplha Value 0.4*/ + RGR_PWR_ALPHA5 = 5, /**< Power Aplha Value 0.5*/ + RGR_PWR_ALPHA6 = 6, /**< Power Aplha Value 0.6*/ + RGR_PWR_ALPHA7 = 7, /**< Power Aplha Value 0.7*/ + RGR_PWR_ALPHA8 = 8, /**< Power Aplha Value 0.8*/ + RGR_PWR_ALPHA9 = 9, /**< Power Aplha Value 0.9*/ + RGR_PWR_ALPHAALL = 10 /**< Power Aplha Value 1*/ +} RgrPwrAlpha; + +/** Different Values for ACK/NACK Repetition Factor*/ +typedef enum rgrAckNackRepFactor +{ + RGR_ACKNACK_REPFACT_N2 = 2, /**< ACK/NACK Repetition Factor value 2 */ + RGR_ACKNACK_REPFACT_N4 = 4, /**< ACK/NACK Repetition Factor value 4 */ + RGR_ACKNACK_REPFACT_N6 = 6 /**< ACK/NACK Repetition Factor value 6 */ +} RgrAckNackRepFactor; + +/* rgr_x_001.main_8 - Changes for MIMO feature addition */ +/** @{ */ +/** + * UE Transmission Modes state transition in case of recfg */ +typedef enum rgrTxModeTrnstn +{ + RGR_TXMODE_RECFG_CMPLT = 0, + RGR_TXMODE_RECFG_START +}RgrTxModeTrnstn; + +/** @} */ +/** + * UE Transmission Modes */ +typedef enum rgrTxMode +{ + RGR_UE_TM_1 = 1, /**< Transmission Mode 1 */ + RGR_UE_TM_2, /**< Transmission Mode 2 */ + RGR_UE_TM_3, /**< Transmission Mode 3 */ + RGR_UE_TM_4, /**< Transmission Mode 4 */ + RGR_UE_TM_5, /**< Transmission Mode 5 */ + RGR_UE_TM_6, /**< Transmission Mode 6 */ + RGR_UE_TM_7, /**< Transmission Mode 7 */ + RGR_UE_TM_8 /**< Transmission Mode 8 */ +#ifdef LTE_ADV + , + RGR_UE_TM_9 /**< Transmission Mode 9 */ +#endif +} RgrTxMode; +/** + * Random access system frame number */ +typedef enum rgrRaSfn +{ + RGR_SFN_EVEN, /**< Even Sub Frame */ + RGR_SFN_ANY, /**< Any Sub Frame */ +/** @name LTE_TDD */ +/** @{ */ +#ifdef LTE_TDD + RGR_SFN_ODD, /**< Odd Sub Frame */ +#endif /*LTE_TDD */ +/** @} */ + RGR_SFN_NA /**< Sub Frame Not Available */ +} RgrRaSfn; +/** + * Configuration period per Cell for SRS */ +typedef enum rgrSrsCfgPrd +{ + RGR_SRS_CFG_PRD_1 = 1, /**< Sounding Reference signal periodicity 1ms */ + RGR_SRS_CFG_PRD_2 = 2, /**< Sounding Reference signal periodicity 2ms */ + RGR_SRS_CFG_PRD_5 = 5, /**< Sounding Reference signal periodicity 5ms */ + RGR_SRS_CFG_PRD_10 = 10, /**< Sounding Reference signal periodicity 10ms */ + RGR_SRS_CFG_PRD_INF /**< Sounding Reference signal periodicity Infinite */ +} RgrSrsCfgPrd; + +/** + * SRS Bandwidth Configuration per cell for SRS */ +typedef enum rgrSrsBwCfg +{ + RGR_SRS_BWCFG_0 = 0, /**< Sounding Reference Signal BW CFG 0 */ + RGR_SRS_BWCFG_1 = 1, /**< Sounding Reference Signal BW CFG 1 */ + RGR_SRS_BWCFG_2 = 2, /**< Sounding Reference Signal BW CFG 2 */ + RGR_SRS_BWCFG_3 = 3, /**< Sounding Reference Signal BW CFG 3 */ + RGR_SRS_BWCFG_4 = 4, /**< Sounding Reference Signal BW CFG 4 */ + RGR_SRS_BWCFG_5 = 5, /**< Sounding Reference Signal BW CFG 5 */ + RGR_SRS_BWCFG_6 = 6, /**< Sounding Reference Signal BW CFG 6 */ + RGR_SRS_BWCFG_7 = 7 /**< Sounding Reference Signal BW CFG 7 */ +} RgrSrsBwCfg; + + +/** + * Ng values for PHICH For more details refer to 36.211 Sec 6.9*/ +typedef enum rgrPhichNg +{ + RGR_NG_ONESIXTH, /**< PHICH Ng Values 1/6 */ + RGR_NG_HALF, /**< PHICH Ng Values 1/2 */ + RGR_NG_ONE, /**< PHICH Ng Values 1 */ + RGR_NG_TWO /**< PHICH Ng Values 2 */ +} RgrPhichNg; +/** + * Aperiodic CQI Transmission Modes */ +typedef enum rgrAprdCqiMode +{ + RGR_APRD_CQI_MOD12, /**< Aperiodic CQI Mode 1-2 */ + RGR_APRD_CQI_MOD20, /**< Aperiodic CQI Mode 2-0 */ + RGR_APRD_CQI_MOD22, /**< Aperiodic CQI Mode 2-2 */ + RGR_APRD_CQI_MOD30, /**< Aperiodic CQI Mode 3-0 */ + RGR_APRD_CQI_MOD31 /**< Aperiodic CQI Mode 3-1 */ +} RgrAprdCqiMode; +/*rgr_x_001.main_9 - Added support for SPS*/ +/** +* Number of empty transmissions for Implicit Release */ +/*rgr_x_001.main_11 MOD added comments*/ +typedef enum rgrSpsImplRelCnt +{ + RGR_SPS_E2 = 2, /**< SPS Implicit release count 2 */ + RGR_SPS_E3 = 3, /**< SPS Implicit release count 3 */ + RGR_SPS_E4 = 4, /**< SPS Implicit release count 4 */ + RGR_SPS_E8 = 8 /**< SPS Implicit release count 8 */ +} RgrSpsImplRelCnt; + +/** + * TODO: Check if needed this way + * SPS Periodicty values */ +/*rgr_x_001.main_11 MOD added comments*/ +typedef enum rgrSpsPrd +{ + RGR_SPS_PRD_10SF = 10, /**< SPS peridicity 10 */ + RGR_SPS_PRD_20SF = 20, /**< SPS peridicity 20 */ + RGR_SPS_PRD_32SF = 32, /**< SPS peridicity 32 */ + RGR_SPS_PRD_40SF = 40, /**< SPS peridicity 40 */ + RGR_SPS_PRD_64SF = 64, /**< SPS peridicity 64 */ + RGR_SPS_PRD_80SF = 80, /**< SPS peridicity 80 */ + RGR_SPS_PRD_128SF = 128, /**< SPS peridicity 128 */ + RGR_SPS_PRD_160SF = 160, /**< SPS peridicity 160 */ + RGR_SPS_PRD_320SF = 320, /**< SPS peridicity 320 */ + RGR_SPS_PRD_640SF = 640, /**< SPS peridicity 640 */ + RGR_SPS_PRD_INVALID /**< SPS peridicity invalid */ +} RgrSpsPrd; + + + +/* rgr_x_001.main_5:ADD-Added for SI Enhancement. */ + +/**@name RGR_SI_SCH */ +/**@{ */ +#ifdef RGR_SI_SCH +/** + * SIs Periodicity */ +typedef enum _rgrSiPerd +{ + RGR_SI_PERD_8 = 8, /**< SI Periodicity 8 RF */ + RGR_SI_PERD_16 = 16, /**< SI Periodicity 16 RF */ + RGR_SI_PERD_32 = 32, /**< SI Periodicity 32 RF */ + RGR_SI_PERD_64 = 64, /**< SI Periodicity 64 RF */ + RGR_SI_PERD_128 = 128, /**< SI Periodicity 128 RF */ + RGR_SI_PERD_256 = 256, /**< SI Periodicity 256 RF */ + RGR_SI_PERD_512 = 512 /**< SI Periodicity 512 RF */ +} RgrSiPeriodicity; + +/*rgr_x_001.main_11 ccpu00115364 ADD changed U8 to enum for modPrd*/ +/*modification period = (modificationPeriodCoeff * defaultPagingCycle)%m*/ +/*where modificationPeriodCoeff={2,4,8,16} defaultPagingCycle={32,64,128,256}*/ +/** + @brief Modification period Periodicity */ +typedef enum _rgrModPerd +{ + RGR_MOD_PERD_64 = 64, /**< modification period 64 RF */ + RGR_MOD_PERD_128 = 128, /**< modification period 128 RF */ + RGR_MOD_PERD_256 = 256, /**< modification period 256 RF */ + RGR_MOD_PERD_512 = 512, /**< modification period 512 RF */ + RGR_MOD_PERD_1024 = 1024 /**< modification period 1024 RF */ +} RgrModPeriodicity; + +/** SI Configuration Type */ +typedef enum rgrSiCfgType +{ + RGR_SI_CFG_TYPE_MIB = 0, /**< SI CFG Type MIB */ + RGR_SI_CFG_TYPE_SIB1, /**< SI CFG TYPE SIB1 */ + RGR_SI_CFG_TYPE_SI, /**< SI CFG TYPE SI */ + RGR_SI_CFG_TYPE_SIB1_PWS, /**< SI CFG TYPE SIB1 PWS */ + RGR_SI_CFG_TYPE_SIB8_CDMA, /**< SI CFG TYPE SIB8 */ + RGR_SI_STOP +#ifdef EMTC_ENABLE + , + RGR_SI_CFG_EMTC_TYPE_SIB1_BR, + RGR_SI_CFG_EMTC_TYPE_SIB1_BR_PER, + RGR_SI_CFG_EMTC_TYPE_SI, + RGR_SI_CFG_EMTC_TYPE_SI_PER +#endif +} RgrSiCfgType; +#endif /*RGR_SI_SCH*/ +/**@} */ + +/*rgr_x_001.main_11 ADD added changes for DRX*/ +/** + * @brief DRX Timer Period */ +typedef enum _rgrDrxTmrPerd +{ + RGR_DRX_PRD_0PSF = 0, /**< DRX timer period 0 PDCCH sf */ + RGR_DRX_PRD_1PSF = 1, /**< DRX timer period 1 PDCCH sf */ + RGR_DRX_PRD_2PSF = 2, /**< DRX timer period 2 PDCCH sf */ + RGR_DRX_PRD_3PSF = 3, /**< DRX timer period 3 PDCCH sf */ + RGR_DRX_PRD_4PSF = 4, /**< DRX timer period 4 PDCCH sf */ + RGR_DRX_PRD_5PSF = 5, /**< DRX timer period 5 PDCCH sf */ + RGR_DRX_PRD_6PSF = 6, /**< DRX timer period 6 PDCCH sf */ + RGR_DRX_PRD_8PSF = 8, /**< DRX timer period 8 PDCCH sf */ + RGR_DRX_PRD_10PSF = 10, /**< DRX timer period 10 PDCCH sf */ + RGR_DRX_PRD_16PSF = 16, /**< DRX timer period 16 PDCCH sf */ + RGR_DRX_PRD_20PSF = 20, /**< DRX timer period 20 PDCCH sf */ + RGR_DRX_PRD_24PSF = 24, /**< DRX timer period 24 PDCCH sf */ + RGR_DRX_PRD_30PSF = 30, /**< DRX timer period 30 PDCCH sf */ + RGR_DRX_PRD_33PSF = 33, /**< DRX timer period 33 PDCCH sf */ + RGR_DRX_PRD_40PSF = 40, /**< DRX timer period 40 PDCCH sf */ + RGR_DRX_PRD_50PSF = 50, /**< DRX timer period 50 PDCCH sf */ + RGR_DRX_PRD_60PSF = 60, /**< DRX timer period 60 PDCCH sf */ + RGR_DRX_PRD_64PSF = 64, /**< DRX timer period 64 PDCCH sf */ + RGR_DRX_PRD_80PSF = 80, /**< DRX timer period 80 PDCCH sf */ + RGR_DRX_PRD_96PSF = 96, /**< DRX timer period 96 PDCCH sf */ + RGR_DRX_PRD_100PSF = 100, /**< DRX timer period 100 PDCCH sf */ + RGR_DRX_PRD_112PSF = 112, /**< DRX timer period 112 PDCCH sf */ + RGR_DRX_PRD_128PSF = 128, /**< DRX timer period 128 PDCCH sf */ + RGR_DRX_PRD_160PSF = 160, /**< DRX timer period 160 PDCCH sf */ + RGR_DRX_PRD_200PSF = 200, /**< DRX timer period 200 PDCCH sf */ + RGR_DRX_PRD_300PSF = 300, /**< DRX timer period 300 PDCCH sf */ + RGR_DRX_PRD_320PSF = 320, /**< DRX timer period 320 PDCCH sf */ + RGR_DRX_PRD_400PSF = 400, /**< DRX timer period 300 PDCCH sf */ + RGR_DRX_PRD_500PSF = 500, /**< DRX timer period 500 PDCCH sf */ + RGR_DRX_PRD_600PSF = 600, /**< DRX timer period 600 PDCCH sf */ + RGR_DRX_PRD_750PSF = 750, /**< DRX timer period 750 PDCCH sf */ + RGR_DRX_PRD_800PSF = 800, /**< DRX timer period 800 PDCCH sf */ + RGR_DRX_PRD_1000PSF = 1000, /**< DRX timer period 1000 PDCCH sf */ + RGR_DRX_PRD_1200PSF = 1200, /**< DRX timer period 1200 PDCCH sf */ + RGR_DRX_PRD_1280PSF = 1280, /**< DRX timer period 1280 PDCCH sf */ + RGR_DRX_PRD_1600PSF = 1600, /**< DRX timer period 1600 PDCCH sf */ + RGR_DRX_PRD_1920PSF = 1920, /**< DRX timer period 1920 PDCCH sf */ + RGR_DRX_PRD_2560PSF = 2560 /**< DRX timer period 2560 PDCCH sf */ +}RgrDrxTmrPrd; + + +/*rgr_x_001.main_11 ADD added changes for DRX*/ +/** + * @brief DRX Cycle Period */ +typedef enum _rgrDrxCyclePerd +{ + RGR_DRX_PRD_2SF = 2, /**< DRX cycle period 2 sf */ + RGR_DRX_PRD_5SF = 5, /**< DRX cycle period 5 sf */ + RGR_DRX_PRD_8SF = 8, /**< DRX cycle period 8 sf */ + RGR_DRX_PRD_10SF = 10, /**< DRX cycle period 10 sf */ + RGR_DRX_PRD_16SF = 16, /**< DRX cycle period 16 sf */ + RGR_DRX_PRD_20SF = 20, /**< DRX cycle period 20 sf */ + RGR_DRX_PRD_32SF = 32, /**< DRX cycle period 32 sf */ + RGR_DRX_PRD_40SF = 40, /**< DRX cycle period 40 sf */ + RGR_DRX_PRD_64SF = 64, /**< DRX cycle period 64 sf */ + RGR_DRX_PRD_80SF = 80, /**< DRX cycle period 80 sf */ + RGR_DRX_PRD_128SF = 128, /**< DRX cycle period 128 sf */ + RGR_DRX_PRD_160SF = 160, /**< DRX cycle period 160 sf */ + RGR_DRX_PRD_256SF = 256, /**< DRX cycle period 256 sf */ + RGR_DRX_PRD_320SF = 320, /**< DRX cycle period 320 sf */ + RGR_DRX_PRD_512SF = 512, /**< DRX cycle period 512 sf */ + RGR_DRX_PRD_640SF = 640, /**< DRX cycle period 640 sf */ + RGR_DRX_PRD_1024SF = 1024, /**< DRX cycle period 1024 sf */ + RGR_DRX_PRD_1280SF = 1280, /**< DRX cycle period 1280 sf */ + RGR_DRX_PRD_2048SF = 2048, /**< DRX cycle period 2048 sf */ + RGR_DRX_PRD_2560SF = 2560 /**< DRX cycle period 2560 sf */ +}RgrDrxCyclePrd; + +/*rgr_x_001.main_11 ADD added changes for DRX*/ +/** + * @brief DRX Short Cycle Timer values */ +typedef enum _rgrDrxShortCycleTmr +{ + RGR_DRX_SHRTCYCLE_MIN = 1, /**< min DRX short cycle timer val */ + RGR_DRX_SHRTCYCLE_MAX = 16 /**< max DRX short cycle timer val */ +}RgrDrxShrtCycleTmr; + +/*rgr_x_001.main_11 ADD added changes for R9*/ +/**@name LTEMAC_R9 */ +/**@{ */ +#ifdef LTEMAC_R9 +/** + * @brief DRX CQI Mask */ +typedef enum _rgrDrxCqiMask +{ + RGR_DRX_SETUP = 0 /**< DRX CQI mask value */ +}RgrDrxCqiMask; +#endif +/**@} */ + +/*rgr_x_001.main_11 ADD added changes for CQI management*/ +/** + @brief Enumerated P_A Values */ +typedef enum +{ + RGRUE_DLPWRCNTRL_PA_DB_6 = 0, + RGRUE_DLPWRCNTRL_PA_DB_4DOT77, + RGRUE_DLPWRCNTRL_PA_DB_3, + RGRUE_DLPWRCNTRL_PA_DB_1DOT77, + RGRUE_DLPWRCNTRL_PA_DB0, + RGRUE_DLPWRCNTRL_PA_DB1, + RGRUE_DLPWRCNTRL_PA_DB2, + RGRUE_DLPWRCNTRL_PA_DB3 +} RgrUeDlPwrCntrlPaCfg; + +/*f1b_Sprint3*/ +typedef enum rgrSchFrmt1b3TypEnum +{ + RG_SCH_UCI_FORMAT1A_1B, + RG_SCH_UCI_FORMAT1B_CS, + RG_SCH_UCI_FORMAT3, + RG_SCH_UCI_FORMAT_NON_CA +}RgrSchFrmt1b3TypEnum; +/*f1b_Sprint3*/ + +/** @brief Transaction ID between MAC and RRM */ +typedef struct rgrCfgTransId +{ + U8 trans[RGR_CFG_TRANSID_SIZE]; /*!< RRM Transaction ID */ +} RgrCfgTransId; + +/** @brief Downlink HARQ configuration per Cell */ +typedef struct rgrDlHqCfg +{ + U8 maxDlHqTx; /*!< Maximum number of DL HARQ Transmissions. + Minimum value is 1, maximum can be defined + by the user */ + U8 maxMsg4HqTx; /*!< Maximum msg4(Random Access) HARQ Transmissions + Minimum value is 1, Maximum can be defined by + the user */ +} RgrDlHqCfg; + +/** @brief Range of RNTIs managed by MAC */ +typedef struct rgrRntiCfg +{ + CmLteRnti startRnti; /*!< Start RNTI for the range managed by MAC */ + U16 size; /*!< Indicates contiguous range of RNTI managed by + MAC */ +} RgrRntiCfg; + +/** @brief Downlink common channel code rate configuration per cell */ +typedef struct rgrDlCmnCodeRateCfg +{ + U16 bcchPchRaCodeRate; /*!< BCCH on DLSCH, PCH and RARsp coding rate. + * This defines the actual number of bits per 1024 + * physical layer bits */ + U16 pdcchCodeRate; /*!< PDCCH code rate defines actual number of bits + * per 1024 physical layer bits. This is used to + * calculate aggregation level for PDCCH meant + * for broadcasting RNTIs */ + U8 ccchCqi; /*!< Default CQI to be used for Msg4 in case where + * no CQI is available for the UE. ccchCqi ranges + * from 1 to 15.*/ +} RgrDlCmnCodeRateCfg; + +/** @brief Control Format Indicator (CFI) configuration per cell */ +typedef struct rgrCfiCfg +{ + U8 cfi; /*!< CFI for PDCCH: a value in set {1,2,3} */ +} RgrCfiCfg; + +/** @brief PUSCH sub-band configuration per cell */ +typedef struct rgrPuschSubBandCfg +{ + U8 subbandStart; /*!< Sub-band start */ + U8 numSubbands; /*!< Number of equal sized sub-bands */ + U8 size; /*!< Size of a sub-band */ + U8 dmrs[RGR_MAX_SUBBANDS]; /*!< DMRS information per sub-band */ +} RgrPuschSubBandCfg; + +/** @brief Uplink common channel code rate configuration per cell */ +typedef struct rgrUlCmnCodeRateCfg +{ + U8 ccchCqi; /*!< CCCH CQI index, also used as default + * initial CQI for UEs */ +} RgrUlCmnCodeRateCfg; + +/* rgr_x_001.main_1: Removing unwanted srMcs Configuration structure */ + +/** @brief Target Uplink CQI to achieve through group power control configured per cell */ +typedef struct rgrUlTrgCqiCfg +{ + U8 trgCqi; /*!< Target UL CQI to be achieved through power + control.Range is defined is between 1 to 15 */ +} RgrUlTrgCqiCfg; +/** + @brief Bandwidth configuration per cell */ +typedef struct rgrBwCfg +{ + U8 dlTotalBw; /*!< Total Dowlink Bandwidth */ + U8 ulTotalBw; /*!< Total Uplink Bandwidth */ +} RgrBwCfg; + +/** + @brief PHICH configuration per cell */ +typedef struct rgrPhichCfg +{ + RgrPhichNg ngEnum; /*!< Ng value for PHICH */ + Bool isDurExtend; /*!< PHICH Duration: TRUE-extended/FALSE-normal */ +} RgrPhichCfg; + +/** + @brief PUCCH configuration per cell */ +typedef struct rgrPucchCfg +{ + U8 resourceSize; /*!< PUCCH resource-size or N^(2)_RB (in RBs) */ + U16 n1PucchAn; /*!< N^(1)_PUCCH */ + U8 deltaShift; /*!< Delta Shift for PUCCH: a value in set {1,2,3} */ + U8 cyclicShift; /*!< Cyclic Shift for PUCCH (N^(1)_CS): a value in + range [0-7] */ + U8 maxPucchRb; /*!< The max number of RBs for PUCCH. This will be + used to limit the max CFI value when dynamic + CFI feature is enabled. If there is no + limitation on the max PUCCH RBs, this variable + should be set to 0 */ +} RgrPucchCfg; +/** + @brief SRS configuration per cell */ +typedef struct rgrSrsCfg +{ + /*ccpu00130768 - ADD - SRS CFG Present flag to enable/disable cell specific SRS*/ + Bool isSrsCfgSetup; /*!< cell specific SRS CFG enable/disable flag */ + RgrSrsCfgPrd srsCfgPrdEnum; /*!< SRS configuration period (in subframes).*/ + RgrSrsBwCfg srsBwEnum; /*!< SRS Bandwidth configuration per cell. + Range - [0-7] */ + U8 srsSubFrameCfg;/*!< SRS subframe configuration index per cell. + Range - [0-15] */ +} RgrSrsCfg; +/** + @brief RACH configuration per cell */ +typedef struct rgrRachCfg +{ + U8 preambleFormat; /*!< RACH Preamble format: a value in set {0,1,2,3} */ + U8 raWinSize; /*!< RA Window size */ + /** @brief Ocassion at Which Random Access Is Expected */ + struct raOccasionS + { + U8 size; /*!< Number of subframe numbers */ + RgrRaSfn sfnEnum; /*!< System Frame Number */ + U8 subFrameNum[RGR_MAX_SUBFRAME_NUM]; /*!< Subframe numbers */ + } raOccasion; /*!< Random access occasions */ + U8 maxMsg3Tx; /*!< Maximum number of message 3 transmissions */ + U8 numRaPreamble; /*!< Number of RA Preambles */ + U8 sizeRaPreambleGrpA; /*!< Size of RA Preamble in Group A */ + U16 msgSizeGrpA; /*!< MESSAGE_SIZE_GROUP_A */ + U8 prachResource; /*!< N^RA_PRB: PRACH resource for random access */ +/**@name RGR_V1 */ +/**@{ */ +#ifdef RGR_V1 + /* rgr_x_001.main_7: [ccpu00112372] Added contention resolution timer */ + U8 contResTmr; /*!< Contention resolution timer */ +#endif +/**@} */ +} RgrRachCfg; + +/** + @brief SI Configuration per cell +*/ +typedef struct rgrSiCfg +{ + U8 siWinSize; /*!< SI window size */ + U8 retxCnt; /*!< Retransmission count */ + /* rgr_x_001.main_5-ADD-Added for SI Enhancement. */ +/**@name RGR_SI_SCH */ +/**@{ */ +#ifdef RGR_SI_SCH +/*rgr_x_001.main_11 ccpu00115364 MOD changed U8 to enum for modPrd*/ + RgrModPeriodicity modPrd; /*!< Modificiation Period for SI */ + U8 numSi; /*! 10000, + representing -6 dB to 4 dB in 0.001 + dB steps */ + U16 pcchTxPwrOffset; /*!< Tx Pwr Offset for PCCH tx. + Offset to the reference signal + power. Value: 0 -> 10000, + representing -6 dB to 4 dB in 0.001 + dB steps */ + U16 rarTxPwrOffset; /*!< Tx Pwr Offset for RAR tx. + Offset to the reference signal + power. Value: 0 -> 10000, + representing -6 dB to 4 dB in 0.001 + dB steps */ + /* ccpu00138898 - Added Tx pwr offset for PHICH Tx*/ + U16 phichTxPwrOffset; /*!< Tx Pwr Offset for PHICH tx. + Offset to the reference signal + power. Value: 0 -> 10000, + representing -6 dB to 4 dB in 0.001 + dB steps */ + Bool isDynCfiEnb; /*!< To indicate whether Dynamic CFI is enabled + or not */ + Bool isAutoCfgModeEnb; /*!< To indicate whether AutoCfg Mode + change is enabled or not */ + RgrUeDlPwrCntrlPaCfg msg4pAVal; /*!< Default value (Enum) of PA that is + used by Scheduler for msg4 */ + RgrLteUCfg lteUCfg; /*!< Flag to identify LAA or LTE-U*/ +#ifdef LTE_ADV + Bool isPucchFormat3Sptd; /*!< Flag for Format 3 Support */ +#endif +#ifdef EMTC_ENABLE + Bool emtcEnable; + RgrEmtcCellCfg emtcCellCfg; +#endif +#ifdef RG_5GTF + Rgr5gtfCellCfg Cell5gtfCfg; +#endif +} RgrCellCfg; +/** + @brief Downlink Aperiodic CQI reporting related configuration per UE */ +typedef struct rgrUeAprdDlCqiCfg +{ + Bool pres; /*!< Indicates presence of aperiodic + DL CQI configuration */ + RgrAprdCqiMode aprdModeEnum; /*!< Aperiodic CQI reporting mode */ + /* These two fields are only valid for Pcell*/ +#ifdef LTE_ADV + U8 triggerSet1; /*!< Trigger set one*/ + U8 triggerSet2; /*!< Trigger set two*/ +#endif +} RgrUeAprdDlCqiCfg; + +/* rgr_x_001.main_10. Added changes of TFU_UPGRADE */ +#ifndef TFU_UPGRADE +/** + @brief Downlink Periodic CQI reporting related configuration per UE */ +typedef struct rgrUePrdDlCqiCfg +{ + Bool pres; /*!< Indicates presence of periodic + DL CQI configuration. */ + RgrPrdCqiMode prdModeEnum; /*!< Peiodic CQI reporting mode. */ + RgrCqiPrdicity prdicityEnum; /*!< Periodicity values for CQI. + Currently, this is unused parameter. */ + U8 subframeOffst; /*!< Subframe offset. + Currently, this is unused parameter. */ + S8 cqiOffst; /*!< Delta^cqi_offset: (actual_value*10). + Currently, this is unused parameter. */ + U8 k; /*!< k value: range [1-4] */ + U16 cqiPmiCfgIdx; /*!< CQI-PMI configuration index. */ +} RgrUePrdDlCqiCfg; + +#else /* TFU_UPGRADE */ + +/** +* @brief Periodic CQI Setup configuration parameters information +*/ +/* Reference: 36.313: CQI-ReportPeriodic */ +typedef struct rgrUeDlPCqiSetup +{ + U16 cqiPResIdx; /*!< cqi-PUCCH-ResourceIndex (0.. 1185) */ + U16 cqiPCfgIdx; /*!< cqi-pmi-ConfigIndex (0..1023) */ + U8 cqiRepType; /*!< Wideband CQI = 1 Subband CQI =2 */ + U8 k; /*!< Ref: 36.213 [23, 7.2.2] (1..4). + Valid only for Subband CQI */ + U8 riEna; /*!< Rand Indicator is Enabled TRUE(1) FALSE(0) */ + U16 riCfgIdx; /*!< ri-ConfigIndex (0..1023) */ + Bool sANCQI; /*!< simultaneousAckNackAndCQI TRUE(1) FALSE(0) */ + RgrPrdCqiMode prdModeEnum; /*!< Peiodic CQI reporting mode */ +}RgrUeDlPCqiSetup; + + +/** +* @brief Periodic CQI/PMI/RI configuration parameters information +*/ +typedef struct rgrUeDlPCqiCfg +{ + U8 type; /*!< Setup(1) or Release(0) */ + RgrUeDlPCqiSetup cqiSetup; /*!< Periodic CQI Setup */ +} RgrUePrdDlCqiCfg; + + + +/*rgr_x_001.main_11 MOD added comments*/ +/** +* @ brief Different values for UL SRS BW information +*/ +typedef enum rgrUlSrsBwInfo +{ + RGR_ULSRS_BW_0 = 0, /**< UL SRS BW info 0 */ + RGR_ULSRS_BW_1 = 1, /**< UL SRS BW info 1 */ + RGR_ULSRS_BW_2 = 2, /**< UL SRS BW info 2 */ + RGR_ULSRS_BW_3 = 3 /**< UL SRS BW info 3 */ +} RgrUlSrsBwInfo; + + +/*rgr_x_001.main_11 MOD added comments*/ +/** +* @brief Different values for UL SRS Hoping BW information +*/ +typedef enum rgrUlSrsHoBwInfo +{ + RGR_ULSRS_HOP_BW_0 = 0, /**< UL SRS Hopping BW info 0 */ + RGR_ULSRS_HOP_BW_1 = 1, /**< UL SRS Hopping BW info 1 */ + RGR_ULSRS_HOP_BW_2 = 2, /**< UL SRS Hopping BW info 2 */ + RGR_ULSRS_HOP_BW_3 = 3 /**< UL SRS Hopping BW info 3 */ +} RgrUlSrsHoBwInfo; + +/*rgr_x_001.main_11 MOD added comments*/ +/** +* @brief Different values for UL SRS Cyclic Shift information +*/ +typedef enum rgrUlSrsCycShiftInfo +{ + RGR_ULSRS_CYSHIFT_0 = 0, /**< UL SRS Cyclic shift info 0 */ + RGR_ULSRS_CYSHIFT_1 = 1, /**< UL SRS Cyclic shift info 1 */ + RGR_ULSRS_CYSHIFT_2 = 2, /**< UL SRS Cyclic shift info 2 */ + RGR_ULSRS_CYSHIFT_3 = 3, /**< UL SRS Cyclic shift info 3 */ + RGR_ULSRS_CYSHIFT_4 = 4, /**< UL SRS Cyclic shift info 4 */ + RGR_ULSRS_CYSHIFT_5 = 5, /**< UL SRS Cyclic shift info 5 */ + RGR_ULSRS_CYSHIFT_6 = 6, /**< UL SRS Cyclic shift info 6 */ + RGR_ULSRS_CYSHIFT_7 = 7 /**< UL SRS Cyclic shift info 7 */ +} RgrUlSrsCycShiftInfo; + + +/*rgr_x_001.main_11 MOD added comments*/ +/** +* @brief SRS configuration setup parameters information. + Reference 36.313 SoundingRS-UL-Config +*/ +typedef struct rgrUeUlSrsSetupCfg +{ + U16 srsCfgIdx; /*!< SRS Configuration Index ISRS + Ref: 36.213: Table 8.2-1; Range: 0-636*/ + RgrUlSrsBwInfo srsBw; /*!< SRS Bandwidth */ + RgrUlSrsHoBwInfo srsHopBw; /*!< SRS Hoping Bandwidth */ + RgrUlSrsCycShiftInfo cycShift; /*!< Cyclic Shift */ + Bool duration; /*!< Single(0) Infinite(1) */ +/*rgr_x_001.main_11 MOD added comments for doxygen*/ + Bool sANSrs; /*!< Simultaneous ACK/NACK and SRS. Note: + This param is specified as a UE specific + parameter though 3GPP TS36.331 specifies + this as a cell-specific parameter. RRM + should configure this parameter with the + same value for all the UEs configured for + the same cell. */ +/* rgr_x_001.main_13 - DEL - Removed the redeclaration of sANSrs and added the proper comment termination above */ + U8 txComb; /*!< Tranmission Comb: 0..1 */ + U8 fDomPosi; /*!< Frequency Domain Position */ +}RgrUeUlSrsSetupCfg; + + +/*rgr_x_001.main_11 MOD added comments*/ +/** + *@brief Dsr Trans maximum +*/ +typedef enum rgrUeDsrTransMax +{ + RGR_DSR_TXMAX_4=4, /**< Dsr Trans maximum 4 */ + RGR_DSR_TXMAX_16=16, /**< Dsr Trans maximum 16 */ + RGR_DSR_TXMAX_32=32, /**< Dsr Trans maximum 32 */ + RGR_DSR_TXMAX_64=64 /**< Dsr Trans maximum 64 */ +}RgrUeDsrTransMax; + + +/** +* @brief SR Setup configuration parameters information +*/ +typedef struct rgrUeSrSetupCfg +{ + U16 srResIdx; /*!< Range: 0-2047; Reference: SchedulingRequestConfig */ + U8 srCfgIdx; /*!< Range: 0 -155; Reference: SchedulingRequestConfig */ + /*ccpu00131601:DEL - dTMax will not be required by scheduler */ +}RgrUeSrSetupCfg; + +/** +* @brief SR configuration parameters information +*/ +typedef struct rgrUeSrCfg +{ + Bool type; /*!< Release(0)/Setup(1) */ + RgrUeSrSetupCfg srSetup; /*!< SR Setup Configuration */ +}RgrUeSrCfg; + +/** @brief SRS configuration parameters information. + Reference 36.313 SoundingRS-UL-Config +*/ +typedef struct rgrUeUlSrsCfg +{ + U8 type; /*!< Release=0 Setup =1 */ + RgrUeUlSrsSetupCfg srsSetup; /*!< SRS Setup Configuration */ + +}RgrUeUlSrsCfg; + +#endif /*TFU_UPGRADE */ + +#ifdef LTE_ADV/* Sprint 3*/ +typedef struct rgrUePucchFormat3Cfg +{ + U8 sCellAckN3ResAntP0Count; + U8 sCellAckN3ResAntP1Count; + U16 sCellAckN3ResAntP0[4]; + U16 sCellAckN3ResAntP1[4]; +}RgrUePucchFormat3Cfg; +typedef struct rgrUePucchFormat1BCSCfg +{ + U8 sCellAckN1ResTb1Count; /* !< num of N1 res for TB1 */ + U8 sCellAckN1ResTb2Count; /* !< num of N1 res for TB2 */ + U16 sCellAckN1ResTb1[4]; /*!< TB1 N1 resources */ + U16 sCellAckN1ResTb2[4]; /* !< TB2 N1 resources */ +}RgrUePucchFormat1BCSCfg; +typedef struct rgrUeSCellAckPucchCfg +{ + RgrSchFrmt1b3TypEnum pucchFormatType; /* !< 1B Channel selection or format 3*/ + union + { + RgrUePucchFormat1BCSCfg format1Bcs; + RgrUePucchFormat3Cfg format3; + }u; +}RgrUeSCellAckPucchCfg; +#endif +/* rgr_x_001.main_10. Added changes of TFU_UPGRADE + This structure was earlier included under MIMO flag. But it was not part + of any structure. Now after TFU_UPGRADE inclusion this shall be used for + for PUSCH Reception Request. */ +/** +* @brief PUSCH dedicated configuration parameters information. +*/ +typedef struct rgrUePuschDedCfg +{ + Bool pres; /*! Prsent TRUE(1)/FALSE(0) */ + U8 bACKIdx; /*! betaOffset-ACK-Index (0..15) */ + U8 bRIIdx; /*! betaOffset-RI-Index (0..15) */ + U8 bCQIIdx; /*! betaOffset-CQI-Index (0..15) */ +}RgrUePuschDedCfg; +/** +* @brief Downlink CQI reporting related configuration per UE +*/ +typedef struct rgrUeDlCqiCfg +{ + RgrUeAprdDlCqiCfg aprdCqiCfg; /*!< Aperiodic CQI-related information */ + RgrUePrdDlCqiCfg prdCqiCfg; /*!< Periodic CQI-related configuration */ +} RgrUeDlCqiCfg; +/** +* @brief Measurement Gap configuration for UE +*/ +typedef struct rgrUeMeasGapCfg +{ + Bool isMesGapEnabled; /*!< Is Measuremnet Gap enabled or disabled */ + U8 gapPrd; /*!< Gap period 40ms/80ms */ + U8 gapOffst; /*!< Gap offset - Vaue is 0 to 1*/ +} RgrUeMeasGapCfg; +/** + @brief DRX Long Cycle Offset */ +typedef struct rgrDrxLongCycleOffst +{ + U16 longDrxCycle; /*!< DRX Long Cycle value in subframes*/ + U16 drxStartOffst; /*!< DRX Long Cycle offset value in subframes*/ +} RgrDrxLongCycleOffst; + +/** + * @brief DRX Short Cycle Offset */ +typedef struct rgrDrxShortDrx +{ + Bool pres; /*!< Short cycle is configured or not */ + U16 shortDrxCycle; /*!< DRX Short Cycle value in sub-frames*/ + U8 drxShortCycleTmr; /*!< Value in multiples of Short DRX Cycles*/ +} RgrDrxShortDrx; + +/** + * @brief DRX configuration for UE */ +typedef struct rgrUeDrxCfg +{ + Bool isDrxEnabled; /*!< To indicate if DRX enabled or + not, this can be used in reconfiguration + to release/stop the DRX (TRUE = Enabled)*/ +/*rgr_x_001.main_11 ADD added changes for R9*/ +/** @name LTEMAC_R9 */ +/** @{ */ +#ifdef LTEMAC_R9 + TknS32 cqiMask; /*!< To indicate if cqi-Mask is setup + by higher layers. Currently supports + only a enum SETUP*/ +#endif +/** @} */ + U16 drxOnDurTmr; /*!< DRX On-duration Timer value in + PDCCH subframes */ + U16 drxInactvTmr; /*!< DRX Inactivity Timer value in + PDCCH subframes */ + U16 drxRetxTmr; /*!< DRX Retransmission Timer value in PDCCH + subframes */ + RgrDrxLongCycleOffst drxLongCycleOffst; /*!< DRX Long cycle and offset, values in subframes */ + RgrDrxShortDrx drxShortDrx; /*!< DRX Short cycle value and offset */ +#ifdef EMTC_ENABLE + U16 emtcDrxUlRetxTmr; /*Rel13 Drx Ul Retx Timer */ + Bool isEmtcUe; + Bool drxOnDurTmrR13Pres; + Bool drxRetxTmrR13Pres; +#endif +} RgrUeDrxCfg; + +/** + * @brief UE capability Configuration */ +typedef struct rgrUeCapCfg +{ + U8 pwrClass; /*!< Power class per UE */ + Bool intraSfFeqHop; /*!< Intra subframe frequency hopping for PUSCH */ + Bool resAloocType1; /*!< Resource allocation type 1 for PDSCH */ + Bool simCqiAckNack; /*!< Simultaneous CQI and ACK/NACK on PUCCH */ + Bool txAntSel; /*!< TRUE if UE capable of doing TX Antenna selection */ +/** @} */ +} RgrUeCapCfg; + +/** + * @brief UE ACK/NACK configuration */ +typedef struct rgrUeAckNackRepCfg +{ + Bool isAckNackEnabled; /*!< Is ACK/NACK enabled? This + variable can be used in reconfiguration + also to stop/release the ACK/NACK + Repetition */ + U16 pucchAckNackRep; /*!< n1PUCCH-AN-Rep */ + RgrAckNackRepFactor ackNackRepFactor; /*!< ACK/NACK Repetition factor */ +} RgrUeAckNackRepCfg; + +/** + @brief Transmission mode configuration per UE */ +typedef struct rgrUeTxModeCfg +{ + Bool pres; /*!< Indicates presence of transmission mode for UE */ + RgrTxModeTrnstn tmTrnstnState; /*!< State of Transmission Mode transition */ +/* rgr_x_001.main_9 - Added support for UE Reconfiguration */ + RgrTxMode txModeEnum; /*!< UE transmission mode */ +} RgrUeTxModeCfg; +/** + @brief Uplink HARQ configuration per UE */ +typedef struct rgrUeUlHqCfg +{ + U8 maxUlHqTx; /*!< Maximum number of UL HARQ transmissions */ + U8 deltaHqOffst; /*!< Delta HARQ offset + Currently this is unused parameter */ +} RgrUeUlHqCfg; +/** + @brief Group power configuration per UE for PUCCH and PUSCH group power control */ +typedef struct rgrUeGrpPwrCfg +{ + Bool pres; /*!< Indicates presence of UE PUCCH/PUSCH group power configuration */ + CmLteRnti tpcRnti; /*!< TPC PUCCH/PUSCH RNTI for UE */ + U8 idx; /*!< Index for format 3/3A */ +} RgrUeGrpPwrCfg; +/** + @brief Uplink power configuration per UE */ +typedef struct rgrUeUlPwrCfg +{ + RgrUeGrpPwrCfg uePuschPwr; /*!< PUSCH group power configuration per UE */ + RgrUeGrpPwrCfg uePucchPwr; /*!< PUCCH group power configuration per UE */ + Bool isAccumulated; /*!< To indicate if accumulation is enabled */ + Bool isDeltaMCSEnabled; /*!< To indicate Delta MCS Enabled */ + S8 p0UePusch; /*!< P_0UE_PUSCH*/ + S8 p0UePucch; /*!< P_0_PUCCH*/ + U8 pSRSOffset; /*!< P_SRS_OFFSET + Currently this is unused parameter */ + U8 trgCqi; /*!< CQI to aim for during PUSCH power + * control. Zero indicates absence, where + * cell-wide trgCqi is used */ +} RgrUeUlPwrCfg; +/** + @brief Downlink/Uplink QoS configuration per UE */ +typedef struct rgrUeQosCfg +{ + Bool ambrPres; /*!< Indicates presence of AMBR */ + U32 dlAmbr; /*!< DL AMBR value for UE (bytes/sec): Optional */ + U32 ueBr; /*!< UL Byte Rate value for UE (bytes/sec): Optional */ +} RgrUeQosCfg; +/** + @brief Time Alignment timer configuration per UE */ +typedef struct rgrUeTaTmrCfg +{ + Bool pres; /*!< rgr_x_001.main_7: Pres=NOTPRSNT indicates taTmr INFINITY */ + U16 taTmr; /*!< Timer configuration (in subframes) */ +} RgrUeTaTmrCfg; +/** @name RGR_V1 */ +/** @{ */ +#ifdef RGR_V1 +/* rgr_x_001.main_7: [ccpu00112398] Added periodicBSR-Timer and + retxBSR-Timer */ +/** + @brief BSR timer configuration per UE */ +typedef struct rgrUeBsrTmrCfg +{ + Bool isPrdBsrTmrPres; /*!< Indicates if periodic BSR timer is present + */ + U16 prdBsrTmr; /*!< periodicBSR-Timer configuration + (in subframes): Value 0xFFFF indicates + 'Infinity' */ + U16 retxBsrTmr; /*!< retxBSR-Timer configuration (in subframes) + : Mandatory parameter */ +} RgrUeBsrTmrCfg; +#endif +/** @{ */ + +/*rgr_x_001.main_9 - Added support for SPS*/ +/** + @brief DL SPS configuration parameters per UE */ +typedef struct rgrUeSpsDlCfg +{ + Bool isDlSpsEnabled; /*!< Bool indicating if DL SPS is enabled */ + U8 numSpsHqProc; /*!< Number of SPS harq Proc: Value in set + [1..8] */ + U8 numPucchVal; /*!< Count for configured PUCCH values */ + U32 n1PucchVal[4]; /*!< Array of n1Pucch values */ + RgrSpsPrd dlSpsPrdctyEnum; /*!< Periodicity for DL SPS */ + U16 explicitRelCnt; /*!< Number of SPS ocassions with BO = 0 after + which SPS is released */ +} RgrUeSpsDlCfg; + +typedef struct rgrUlSpsLcInfo +{ + Bool isSpsEnabled; + U8 lcId; +}RgrUlSpsLcInfo; + +/** + @brief UL SPS configuration parameters per UE */ +typedef struct rgrUeSpsUlCfg +{ + Bool isUlSpsEnabled; /*!< Bool indicating if UL SPS is + enabled */ + RgrSpsImplRelCnt implicitRelCnt; /*!< Number of SPS ocassions after which + implicit release happens */ +#ifdef LTE_TDD + Bool twoIntervalCfg; /*!< Bool indicating if two interval + config is enabled */ +#endif + Bool pwrCfgPres; /*!< Indicates if Power related + configuration is present */ + struct + { + S8 p0NominalPuschVal;/*!< Value in range [-126...24] */ + S8 p0UePuschVal; /*!< Value in range [-8....7] */ + } pwrCfg; + RgrSpsPrd ulSpsPrdctyEnum; /*!< Periodicity for UL SPS */ + U8 lcCnt; /*!< Number of logical channels */ + RgrUlSpsLcInfo spsLcInfo[RGR_MAX_SPS_LC];/*!< Array of SPS logical channels - + All these are assumed to be + mapped onto SPS lcg with ID=1 */ + + Bool isLcSRMaskEnab ; /*!< Logical Channel SR Mask Enable Flag*/ + + +} RgrUeSpsUlCfg; + +/** + @brief SPS configuration parameters per UE */ +typedef struct rgrUeSpsCfg +{ + CmLteRnti spsRnti; /*!< SPS-RNTI value */ + RgrUeSpsDlCfg dlSpsCfg; /*!< DL SPS configuration information */ + RgrUeSpsUlCfg ulSpsCfg; /*!< UL SPS configuration information */ + +} RgrUeSpsCfg; +/** @brief Transmit Antenna selection types +*/ +typedef enum rgrUeTxAntSelType +{ + RGR_UE_TX_ANT_OPENLOOP, + RGR_UE_TX_ANT_CLOSEDLOOP +} RgrUeTxAntSelType; +/** + @brief UE Transmit Antenna selection related configuration */ +typedef struct rgrUeTxAntSelCfg +{ + Bool pres; /*!< Configuration present */ + RgrUeTxAntSelType selType; /*!< Transmit Antenna selection type */ +} RgrUeTxAntSelCfg; +/** @} */ + +/*rgr_x_001.main_11 ccpu00117452 - MOD - Changed macro name from + RGR_RRM_DLPWR_CNTRL to RGR_CQI_REPT */ +#ifdef RGR_CQI_REPT +/* DL Power control related structures */ + +/** + @brief PUSH n CQI Reporting related configuration for an UE*/ +typedef struct rgrUeCqiReptCfg +{ + U8 numColltdCqiRept; /*!< Number of CQI reports to be sent in PUSH n + Reporting */ +}RgrUeCqiReptCfg; + +/** + @brief CQI for subband number subBandIdx */ +typedef struct rgrSubBandCqiInfo +{ + U8 cqi[2]; /*!< Subband CQI for two codewords */ + U8 subBandIdx; /*!< Index of the subband starting from 0, + in ascending order of frequency */ +} RgrSubBandCqiInfo; + +/*rgr_x_001.main_11 ADD added changes for CQI management*/ +/** + @brief A CQI Report used in PUSH n Reporting*/ +typedef struct rgrUeCqiRept +{ + U8 cqi[2]; /*!< Wideband CQI Value for two codewords*/ + U8 cqiMode; /*!< Reporting mode by which CQI was reported */ + RgrSubBandCqiInfo sbCqiInfo[RGR_MAX_DL_CQI_SUBBAND]; + U8 numSubBand;/*!< Number of Subbands for which CQI is + being reported */ +} RgrUeCqiRept; + +/*rgr_x_001.main_11 ADD added changes for CQI management*/ +/** + @brief Collated CQI reports */ +typedef struct RgrUeCqiInfo +{ + RgrUeCqiRept cqiRept[RGR_CQIRPTS_MAXN]; /*!< CQI reports */ + U8 numCqiRept; /*!< Number of CQI reports present */ +} RgrUeCqiInfo; + +/*rgr_x_001.main_11 ADD added changes for CQI management*/ +/** + @brief Status Indication structure passed in RgUiRgrStaInd primitive */ +typedef struct rgrStaIndInfo +{ + CmLteCellId cellId; /*!< Cell ID */ + CmLteRnti crnti; /*!< UE identifier UE ID: CRNTI */ + RgrUeCqiInfo ueCqiInfo; /*!< CQI reports*/ +}RgrStaIndInfo; +#endif + +/* LTE_ADV_FLAG_REMOVED_START */ +/** + @brief LOAD INF Indication structure passed in RgUiRgrLoadInfInd primitive */ +typedef struct rgrLoadInfIndInfo +{ + CmLteCellId cellId; /*!< Cell ID */ + U16 bw; /*!< Bandwidth */ + U32 type; + union + { + TknStrOSXL rntpInfo; /*!< RNTP Info */ + U32 absLoadInfo[RGR_ABS_PATTERN_LEN]; + } u; +}RgrLoadInfIndInfo; +/* LTE_ADV_FLAG_REMOVED_END */ + +#ifdef TFU_UPGRADE +/*rgr_x_001.main_11 ADD added changes for CQI management*/ +/** + @brief Struct for P_A configuration per UE */ +typedef struct rgrUepACfg +{ + /* PA value in db */ + RgrUeDlPwrCntrlPaCfg pA; /*!< P_A Value which as used in equation pa =\ + delta_PowerOffset + P_A + Ref: RRC 36.331, 6.3.2, PDSCH-Config*/ + Bool pAPrsnt; /*!< Indicates if pA has valid information */ +}RgrUepACfg; + +/*rgr_x_001.main_11 ADD added changes for CQI management*/ +typedef struct rgrUePdschDedCfg +{ + RgrUepACfg uepACfg; /*!< P_A Configuration, + Ref: RRC 36.331, 6.3.2, PDSCH-Config*/ +}RgrUePdschDedCfg; + +#endif + +/* LTE_ADV_FLAG_REMOVED_START */ +/* @brief UE Configuration for LTE Adv feature */ +typedef struct rgrLteAdvancedUeConfig +{ + U32 pres; + Bool isUeCellEdge; /*! Flag to indicate UE is cell edge or cell center */ + Bool isAbsUe; /*! Flag to indicate ABS UE or Not */ +} RgrLteAdvancedUeConfig; +/* LTE_ADV_FLAG_REMOVED_END */ + +typedef enum RgrAccessStratumRls +{ + RGR_REL_8, + RGR_REL_9, + RGR_REL_10, + RGR_REL_11, + RGR_REL_12, + RGR_REL_SPARE_4, + RGR_REL_SPARE_3, + RGR_REL_SPARE_2, + RGR_REL_SPARE_1, +} RgrAccessStratumRls; + +#ifdef EMTC_ENABLE +#define RGR_MAX_EPDCCH_SET 2 +typedef struct rgrExtaddgrp2 +{ + Bool pres; + U8 csiNumRep;// MAPPING + U8 mpddchPdschHop; + U8 mpdcchStartUESSFDD;// MAPPING + U16 mpdcchNumRep;// MAPPING + U32 mpddchNB;//1.. maxAvailNarrowBands-r13 +}RgrExtaddgrp2; + +typedef struct rgrRbAssignment +{ + U8 numPRBpairs; // MAPPING + U8 rbAssignment[5]; +}RgrRbAssignment; +typedef struct rgrEpdcchAddModLst +{ + U8 setConfigId; + U8 transmissionType; + RgrRbAssignment resBlkAssignment; + U32 dmrsScrambSeq; + U32 pucchResStartoffset; + TknU32 pdschRemapQLcfgId; + TknU8 mpdcchNumPRBpair; // MAPPING + RgrExtaddgrp2 extaddgrp2; +}RgrEpdcchAddModLst; + +typedef struct rgrSubFrmPatCfg +{ + Bool pres; + U8 measSfPatFDD[5]; +}RgrSubFrmPatCfg; +typedef struct rgrEpdcchConfigRel11 +{ + Bool pres; + RgrSubFrmPatCfg sfPtn; + TknU32 startSymbolr11; + RgrEpdcchAddModLst epdcchAddModLst[RGR_MAX_EPDCCH_SET]; +}RgrEpdcchConfigRel11; + +typedef struct rgrUeEmtcRecfg +{ + Bool isHdFddEnbld; /*!< Half Duplex FDD is configured: TRUE=1/FALSE=0 */ +}RgrUeEmtcRecfg; +typedef struct rgrPucchRepCfgRel13 +{ + Bool isPucchRepPres; + U8 modeANumPucchRepFormat1; + U8 modeANumPucchRepFormat2; + +}RgrPucchRepCfgRel13; + +typedef struct rgrUeEmtcCfg +{ + Bool isHdFddEnbld; /*!< Half Duplex FDD is configured: TRUE=1/FALSE=0 */ + Bool pres; + RgrEpdcchConfigRel11 emtcEpdcchCfg; + RgrPucchRepCfgRel13 emtcPucchRepCfg; + U8 pdschReptLevModeA; +}RgrUeEmtcCfg; +#endif + +#ifdef RG_5GTF +typedef struct rgrUe5gtfCfg +{ + U8 grpId; + U8 BeamId; + U8 numCC; + U8 mcs; + U8 maxPrb; +}RgrUe5gtfCfg; +#endif + + +/** + @brief UE configuration */ +typedef struct rgrUeCfg +{ + CmLteCellId cellId; /*!< Cell ID */ + CmLteRnti crnti; /*!< UE ID: CRNTI */ + RgrUeTxModeCfg txMode; /*!< UE Transmission mode: Optional */ + RgrUeDlCqiCfg ueDlCqiCfg; /*!< UE DL CQI configuration */ + RgrUeUlHqCfg ueUlHqCfg; /*!< UE-related UL HARQ configuration */ + RgrUeUlPwrCfg ueUlPwrCfg; /*!< UE UL power configuration: Optional */ + RgrUeQosCfg ueQosCfg; /*!< UE-related Dl/UL QoS configuration: AMBR */ + RgrUeTaTmrCfg ueTaTmrCfg; /*!< UE TA timer configuration: Optional */ +/** @name RGR_V1 */ +/** @{ */ +#ifdef RGR_V1 + /* rgr_x_001.main_7: [ccpu00112398] Added periodicBSR-Timer and + retxBSR-Timer */ + RgrUeBsrTmrCfg ueBsrTmrCfg; /*!< UE BSR timer configuration: + Mandatory */ +#endif +/** @} */ + CmLteUeCategory ueCatEnum; /*!< UE category */ +/*rgr_x_001.main_11 ADD added changes for DRX*/ +/**@{ */ + RgrUeDrxCfg ueDrxCfg; /*!< UE-specific DRX configuration */ +/** @} */ + Bool isTtiBundlEnabled;/*!< TtiBundling Enabled/Disabled for UE */ + RgrUeAckNackRepCfg ueAckNackCfg; /*!< ACK/NACK configuration for UE */ + RgrUeMeasGapCfg ueMesGapCfg; /*!< Measurement Gap configuration for UE */ + RgrUeCapCfg ueCapCfg; /*!< UE Capabilty reconfiguration */ + RgrCodeBookRstCfg ueCodeBookRstCfg; /*!< Number of bits in code book for + transmission modes */ + TknU8 dedPreambleId; /*!< If present, then mapping exists at + RGR user with CRNTI */ +/** @name LTE_TDD */ +/** @{ */ +#ifdef LTE_TDD + RgrTddAckNackMode ackNackModeEnum; /*!< ACK/NACK Mode Bundling or + Multiplexing */ +#endif /* LTE_TDD */ +/** @} */ + /*rgr_x_001.main_9 - Added support for SPS*/ +/** @name LTEMAC_SPS */ +/** @{ */ + RgrUeSpsCfg ueSpsCfg; /*!< SPS related configuration + parameters for UE */ +/** @} */ +/* rgr_x_001.main_10. Added changes of TFU_UPGRADE */ +/** @name TFU_UPGRADE */ +/** @{ */ +#ifdef TFU_UPGRADE + /* Periodic CQI, SRS, SR and HD-FDD Configuration */ + RgrUeUlSrsCfg srsCfg; /*!< SRS configuration information */ + RgrUeSrCfg srCfg; /*!< SR configuration information */ +#endif +/** @} */ +/*rgr_x_001.main_11 ADD added changes for HDFDD*/ +/** @name LTEMAC_HDFDD */ +/** @{ */ +#ifdef LTEMAC_HDFDD + Bool isHdFddEnbld; /*!< Half Duplex FDD is configured: TRUE=1/FALSE=0 */ +#endif /* LTEMAC_HDFDD */ +/** @} */ +/* rgr_x_001.main_8 - Changes for MIMO feature addition */ +/* rgr_x_001.main_9 - Removed dependency on MIMO compile-time flag */ + + /* rgr_x_001.main_10. Added changes of TFU_UPGRADE */ + RgrUePuschDedCfg puschDedCfg; /*!< PUSCH -Configuration that is dedicated. Refer + to 36.331 for more information */ + RgrUeTxAntSelCfg ulTxAntSel; /*!< UL Transmit antenna selection configuration */ + +/** @name RGR_CQI_REPT */ +/** @{ */ +/* rgr_x_001.main_11 ccpu00117452 - MOD - Changed macro name from + RGR_RRM_DLPWR_CNTRL to RGR_CQI_REPT */ +#ifdef RGR_CQI_REPT + RgrUeCqiReptCfg ueCqiReptCfg; /*!< PUSH n CQI Reporting + configuration */ +#endif +/** @} */ +#ifdef TFU_UPGRADE + RgrUePdschDedCfg uePdschDedCfg; /*!< PDSCH related dedicated configuration per UE */ +#endif + /* LTE_ADV_FLAG_REMOVED_START */ + RgrLteAdvancedUeConfig ueLteAdvCfg; /*!< LTE Adv configuration per UE */ + /* LTE_ADV_FLAG_REMOVED_END */ + RgrAccessStratumRls accessStratumRls; /*!< UE Access Stratum Release */ + U8 csgMmbrSta; /* CSG Membership status, refer RgrUeCsgMbrStatus */ +#ifdef EMTC_ENABLE + RgrUeEmtcCfg emtcUeCfg; +#endif +#ifdef RG_5GTF + RgrUe5gtfCfg ue5gtfCfg; +#endif +} RgrUeCfg; +/** + @brief QCI, GBR, and MBR configuration for dedicated logical channels */ +typedef struct rgrLchQosCfg +{ + U8 qci; /*!< QCI for the logical channel. + Valid Range:[0-255] (Actual QCI - 1). */ + U32 gbr; /*!< GBR value for a logical channel (bytes/sec). */ + U32 mbr; /*!< MBR value for a logical channel (bytes/sec). */ +} RgrLchQosCfg; +/*rgr_x_001.main_9 - Added support for SPS*/ +/** + @brief SPS related configuration for logical channels */ +typedef struct rgrLchSpsCfg +{ + Bool isSpsEnabled; /*!< Bool indicating if SPS is enabled for + the service */ +} RgrLchSpsCfg; +/** + @brief Logical channel configuration information for downlink logical channels */ +typedef struct rgrDlLchCfg +{ + CmLteTrchType dlTrchType; /*!< Indicates type of DL transport channel: + Validated only for BCCH at MAC + DL Transport channel type can take following values: + CM_LTE_TRCH_BCH + CM_LTE_TRCH_PCH + CM_LTE_TRCH_DL_SCH*/ + RgrLchQosCfg dlQos; /*!< DL QoS parameters: Only for dedicated channels */ + /*rgr_x_001.main_9 - Added support for SPS*/ + RgrLchSpsCfg dlSpsCfg; /*!< SPS configuration for DL logical channel */ + U8 rlcReorderTmr; /*!< RLC reordering timer required for LAA*/ +} RgrDlLchCfg; + +/** + @brief Logical channel configuration information for uplink logical channels */ +typedef struct rgrUlLchCfg +{ + CmLteLcId lcId; /*!< LC ID for uplink logical channel*/ + U8 qci; /*!< QCI associated with LC ID */ +} RgrUlLchCfg; +/** + @brief Logical channel group configuration information for uplink logical channels */ +typedef struct rgrUlLcgCfg +{ + U8 lcgId; /*!< Logical channel group ID */ +/*rgr_x_001.main_11 ADD added changes for L2 measurements*/ +#ifdef LTE_L2_MEAS + U8 numLch; /*!< Number of LC's for this group in Uplink */ + RgrUlLchCfg lchUlCfg[RGR_MAX_LC_PER_LCG]; /*!< Logical Channel details for + this LCG*/ +#endif /*LTE_L2_MEAS */ + U32 gbr; /*!< Commulative UL GBR of all LC mapping to this LCG */ + U32 mbr; /*!< Commulative UL MBR of all LC mapping to this LCG */ +} RgrUlLcgCfg; + +/** + @brief Logical channel Uplink configuration information for dedicated channels */ +typedef struct rgrUlLchQciCfg +{ + CmLteLcId lcId; /*!< Logical channel ID */ + U8 qci; /*!< Qci */ + U8 lcgId; /*!< Logical channel group ID */ +}RgrUlLchQciCfg; + +/** + @brief Logical channel configuration information for dedicated channels */ +typedef struct rgrLchCfg +{ + CmLteCellId cellId; /*!< Cell ID */ + CmLteRnti crnti; /*!< CRNTI for DTCH and DCCH */ + CmLteLcId lcId; /*!< Logical channel ID */ + CmLteLcType lcType; /*!< Identifies the Logical channel type.lcType + can take the following values: + CM_LTE_LCH_BCCH + CM_LTE_LCH_PCCH + CM_LTE_LCH_CCCH + CM_LTE_LCH_DCCH + CM_LTE_LCH_DTCH */ + RgrDlLchCfg dlInfo; /*!< Downlink logical channel configuration information */ + RgrUlLchQciCfg ulLchQciInfo; /*!< Uplink logical channel configuration information */ + U8 lcgId; /*!< Logical channel group ID */ +} RgrLchCfg; + +/** @brief Set of parameters for logical channelgroup Configuration */ +typedef struct rgrLcgCfg +{ + CmLteCellId cellId; /*!< Cell ID */ + CmLteRnti crnti; /*!< CRNTI for DTCH and DCCH */ + RgrUlLcgCfg ulInfo; /*!< Uplink logical channel configuration information */ +} RgrLcgCfg; + + +/** @brief Basic configuration structure at RRM */ +typedef struct rgrCfg +{ + U8 cfgType; /*!< Indicates configuration type */ + union /*!< cfgType is selector */ + { + RgrCellCfg cellCfg; /*!< Cell configuration */ + RgrUeCfg ueCfg; /*!< UE configuration */ + RgrLchCfg lchCfg; /*!< Dedicated logical channel configuration */ + RgrLcgCfg lcgCfg; /*!< Dedicated logical channel Group configuration */ + RgrSchedEnbCfg schedEnbCfg; /*!< EnodeB Sched Configurations */ + } u; +} RgrCfg; + +/** + * @brief Activation time information */ +typedef struct rgrActvTime +{ + Bool pres; /*!< Indicates the presence of activation time */ + CmLteTimingInfo actvTime; /*!< Activation time information */ +} RgrActvTime; + + +/** @brief Cell reconfiguration structure at RRM */ +typedef struct rgrCellRecfg +{ + CmLteCellId cellId; /*!< Cell ID */ + U32 recfgTypes; /*!< Bitmask indicating reconfiguration types */ + RgrActvTime recfgActvTime; /*!< Activation Time for cell reconfiguration */ + RgrDlHqCfg dlHqRecfg; /*!< DL HARQ related reconfiguration */ + RgrCfiCfg cfiRecfg; /*!< CFI reconfiguration for PDCCH */ +/* rgr_x_001.main_1: Removing unwanted srMcs Configuration structure */ + RgrUlTrgCqiCfg trgUlCqi; /*!< Target UL CQI */ + RgrDlCmnCodeRateCfg dlCmnCodeRate; /*!< Coding rate for common DL channels: + Expressed in multiples of 1024 */ + RgrPuschSubBandCfg puschSubBand; /*!< UL sub-band information */ + RgrUlCmnCodeRateCfg ulCmnCodeRate; /*!< Coding rate for common UL channels: + Expressed in multiples of 1024 */ + RgrPucchCfg pucchRecfg; /*!< PUCCH configuration information */ + RgrSrsCfg srsRecfg; /*!< SRS configuration information */ + RgrRachCfg rachRecfg; /*!< RACH configuration */ + RgrDlfsCfg dlfsRecfg; /*!< Reconfiguration for DLFS scheduler */ + /* rgr_x_001.main_5-ADD-Added for SI Enhancement. */ +/** @name RGR_SI_SCH */ +/** @{ */ +#ifdef RGR_SI_SCH + RgrSiCfg siReCfg; /*!srcEnt, pst->srcInst, pst->srcProcId, __FILE__, \ + __LINE__, (ErrCls) ERRCLS_ADD_RES, errCode, (ErrVal)ret, \ + "Packing failure"); \ + RETVALUE(ret); \ + } \ + } + +#define CMCHKPKVERLOG(func, val, mBuf, errCode, pst) \ + { \ + S16 ret; \ + if ((ret = func(pst, val, mBuf)) != ROK) \ + { \ + SPutMsg(mBuf); \ + SLogError(pst->srcEnt, pst->srcInst, pst->srcProcId, __FILE__, \ + __LINE__, (ErrCls) ERRCLS_ADD_RES, errCode, (ErrVal)ret, \ + "Packing failure"); \ + RETVALUE(ret); \ + } \ + } + +#else /* (ERRCLASS & ERRCLS_ADD_RES) */ + +#define CMCHKPK(func, val, mBuf) \ + func(val, mBuf); + +#define CMCHKPKLOG(func, val, mBuf, errCode, pst) \ + func(val, mBuf); + +#define CMCHKPKVERLOG(func, val, mBuf, errCode, pst) \ + func(pst, val, mBuf); + +#endif /* (ERRCLASS & ERRCLS_ADD_RES) */ + +/* macros to validate unpacking functions */ +/*ssi_h_001.main_151 : changed check so that return value will return + * to the caller incase of unpacking failures + */ +#if (ERRCLASS & ERRCLS_ADD_RES) + +#define CMCHKUNPK(func, val, mBuf) \ + { \ + S16 ret; \ + if ((ret = func(val, mBuf)) != ROK) \ + RETVALUE(ret); \ + } + +#define CMCHKUNPKLOG(func, val, mBuf, errCode, pst) \ + { \ + S16 ret; \ + if ((ret = func(val, mBuf)) != ROK) \ + { \ + SPutMsg(mBuf); \ + SLogError(pst->dstEnt, pst->dstInst, pst->dstProcId, __FILE__, \ + __LINE__, (ErrCls) ERRCLS_ADD_RES, (ErrVal)errCode, (ErrVal)ret, \ + "Unpacking failure"); \ + RETVALUE(ret); \ + } \ + } + +#define CMCHKUNPKVERLOG(func, val, mBuf, errCode, pst) \ + { \ + S16 ret; \ + if ((ret = func(pst, val, mBuf)) != ROK) \ + { \ + SPutMsg(mBuf); \ + SLogError(pst->dstEnt, pst->dstInst, pst->dstProcId, __FILE__, \ + __LINE__, (ErrCls) ERRCLS_ADD_RES, (ErrVal)errCode, (ErrVal)ret, \ + "Unpacking failure"); \ + RETVALUE(ret); \ + } \ + } + +#else /* (ERRCLASS & ERRCLS_ADD_RES) */ + +#define CMCHKUNPK(func, val, mBuf) \ + func(val, mBuf); + +#define CMCHKUNPKLOG(func, val, mBuf, errCode, pst) \ + func(val, mBuf); + +#define CMCHKUNPKVERLOG(func, val, mBuf, errCode, pst) \ + func(pst, val, mBuf); +#endif /* (ERRCLASS & ERRCLS_ADD_RES) */ + + +/* strtIdx and endIdx for buffer.t.dat */ + +#ifdef DOS /* dos environment */ +#ifdef OD /* odi environment */ +#define DSTRTIDX 00 /* buffer start index */ +#define DENDIDX 127 /* buffer end index */ +#else /* non-odi environment */ +#define DSTRTIDX 00 /* buffer start index */ +#define DENDIDX 31 /* buffer end index */ +#endif /* DOS */ +#else /* not dos */ +#ifdef UNIX /* unix environment */ +#define DSTRTIDX 00 /* buffer start index */ +#define DENDIDX 31 /* buffer end index */ +#else /* not unix */ +#ifdef MOTADS /* motorola ads environment */ +#define DSTRTIDX 00 /* buffer start index */ +#define DENDIDX 63 /* buffer end index */ +#else /* not MOTADS */ +#ifdef PS +#define DSTRTIDX 00 /* buffer start index */ +#define DENDIDX 31 /* buffer end index */ +#else /* not PS */ +#ifdef QUICCADS +#define DSTRTIDX 00 /* buffer start index */ +#define DENDIDX 31 /* buffer end index */ +#else /* not quiccads */ +#ifdef ALC_EVAL +/* + * The ALC receive buffers should be of size + * ((n+1)*48) + 47 + * in order take care of bug ALC02001 + * where n > 0 for chaining + * + * setting n = 2, we get size = 143 + */ +#define DSTRTIDX 00 /* buffer start index */ +#define DENDIDX 142 /* buffer end index */ +#else /* not alceval */ +#ifdef ELVIS_68302 +#define DSTRTIDX 00 +#define DENDIDX 63 +#else +#ifdef ELVIS_68360 +#define DSTRTIDX 00 +#define DENDIDX 63 +#else +#define DSTRTIDX 00 /* buffer start index */ +#define DENDIDX 31 /* buffer end index */ +#endif /* ELVIS_68360 */ +#endif /* ELVIS_68302 */ +#endif /* ALC_EVAL */ +#endif /* QUICCADS */ +#endif /* PS */ +#endif /* MOTADS */ +#endif /* UNIX */ +#endif /* DOS */ + +#define DSIZE (DENDIDX+1) /* buffer size */ + +#ifdef SUNATMADPT /* sun atm adaptor */ +#define DSTRTPAD 8 +#else +#define DSTRTPAD 0 +#endif /* SUNATMADPT */ + +/* region and pool macros */ + +#define SGETBUFREGION(buf) (DFLT_REGION) +#define SGETBUFPOOL(buf) (DFLT_POOL) + +/* bufType for buffer */ + +#define BDATA 0x01 /* data buffer */ +#define BMSG 0x02 /* message buffer */ +#define BTSK 0x03 /* task buffer */ +/* #define BEXT 0x04 extension buffer */ +/* #define BDMA 0x05 dma buffer */ +#define BDPOOL 0x06 /* dynamic pool buffer */ +#define BSPOOL 0x07 /* static pool buffer */ +#define BUNK 0x08 /* unknown buffer */ + +/* ttype for SRegTsk function */ + +#define TTUND 0x00 /* undefined task */ +#define TTNORM 0x01 /* normal task - non preemptive */ +#define TTPERM 0x02 /* permanent task */ +#define TTPREEMPT 0x03 /* normal task - preemptive */ +#define TTTMR 0x04 /* timer task */ +#define TTMOS 0x05 /* MOS */ + +#ifdef MOSVER +#define MAXEXTENT 0x04 /* maximum extension entries */ +#endif +#ifdef PS +#define MAXEXTENT 0x04 /* maximum extension entries */ +#endif + + +/* priority, route, entity and instance are passed to SPostTsk function */ +/* for loosely coupled interface */ + +/* process id for mos header */ +#define PROCIDNC 0xFFFF /* processor id, not configured */ + +/* TUCL priority for Create Task */ +#ifdef HI_MULTI_THREADED +#ifndef TENB_RTLIN_CHANGES +#define HI_STSK_PRI 13 +#else +#define HI_STSK_PRI 35 +#endif +#endif + +/* priority for mos header, maximum of 16 allowed */ + +#define PRIOR0 0x00 /* priority 0 - highest */ +#define PRIOR1 0x01 /* priority 1 */ +#define PRIOR2 0x02 /* priority 2 */ +#define PRIOR3 0x03 /* priority 3 - lowest */ +#define PRIORNC 0xFF /* priority not configured */ + +/* route for mos header */ + +#define RTESPEC 0x00 /* route to specific instance */ +#define RTEFRST 0x01 /* route to first available instance */ +#define RTEALL 0x02 /* route to all available instances */ +#define RTESHM 0x03 /* route for shared memory */ +#define RTETRNQ 0x04 /* route for SWFT messages */ +#define RTEQONLY 0x05 /* for messages towards non SWFT nodes*/ +#define RTE_PROTO 0x06 /* for messages towards protocl layers*/ +#define RTE_RT_UPD 0x07 /* for messages towards standby nodes*/ +#define RTE_REV_UPD 0x08 /* for messages towards master nodes*/ +#define RTENC 0xFF /* route not configured */ + +/* entity for mos header */ + +#define ENTPRM 0x00 /* Permanent task */ +#define ENTTST 0x00 /* Test */ +#define ENTSS 0x01 /* Common System Services */ +#define ENTMS ENTSS /* Multiprocessor Operating System */ +#define ENTNS ENTSS /* NTSS */ +#define ENTSC 0x02 /* Physical Layer - SCC */ +#define ENTLB 0x03 /* Data Link Layer - LAPB */ +#define ENTLD 0x04 /* Data Link Layer - LAPD */ +#define ENTML 0x05 /* Data Link Layer - Multilink */ +#define ENTBD 0x06 /* Data Link Layer - LAPB & LAPD */ +#define ENTXI 0x07 /* Network Layer - X.25 Intermediate System */ +#define ENTXN 0x08 /* Network Layer - X.25 End System */ +#define ENTXG 0x09 /* Network Layer - X.75 */ +#define ENTIN 0x0A /* Network Layer - Q.930/Q.931 */ +#define ENTAP 0x0B /* Application Layer - Asynchronous PAD */ +#define ENTBR 0x0C /* Data Link Layer - Basic Frame Relay */ + /* OBSOLETE */ +#ifndef ENTER +#define ENTER 0x0D /* Data Link Layer - Extended Frame Relay */ +#endif + /* OBSOLETE */ +#define ENTSM 0x0E /* Stack Manager */ +#define ENTMD 0x0F /* Mos Driver */ +#define ENTAL 0x10 /* Application Program */ +#define ENTLDLM 0x11 /* Lapd Layer Manager */ +#define ENTTC 0x12 /* TCP/IP */ +#define ENTIX 0x13 /* X.31 */ +#define ENTSI 0x14 /* SS7 - isup */ +#define ENTSN 0x15 /* SS7 - mtp, level 3 */ +#define ENTSD 0x16 /* SS7 - mtp, level 2 */ +#define ENTST 0x17 /* SS7 - tcap */ +#define ENTDB 0x18 /* 68000 Debugger */ +#define ENTIS 0x19 /* Physical - ISAC-S */ +#define ENTLC 0x1A /* Data Link Layer - LLC */ +#define ENTOD 0x1B /* Novell ODI */ +#define ENTSE 0x1C /* 68302 */ +#define ENTHE 0x1D /* Hello World */ +#define ENTSP 0x1E /* SS7 - sccp */ +#define ENTCC 0x1F /* Interworking call control */ +#define ENTTU 0x20 /* SS7 - tcap user */ +#define ENTUD 0x21 /* UDP/IP (without TCP) */ +#define ENTM1 0x22 /* Dummy MAC (with MACINT1) */ +#define ENTM2 0x23 /* Dummy MAC (with MACINT2) */ +#define ENTM3 0x24 /* Dummy MAC (with MACINT3) */ +#define ENTTP 0x25 /* SS7 - tup */ +#define ENTBS 0x26 /* ATM - LANE Broadcast Server (BUS) */ +#define ENTM4 0x27 /* Dummy MAC (with MACINT4) */ +#define ENTM5 0x28 /* Dummy MAC (with MACINT5) */ +#define ENTM6 0x29 /* Dummy MAC (with MACINT6) */ +#define ENTM7 0x2A /* Dummy MAC (with MACINT7) */ +#define ENTM8 0x2B /* Dummy MAC (with MACINT8) */ +#define ENTM9 0x2C /* Dummy MAC (with MACINT9) */ +#define ENTME 0x2D /* Message Exchange */ +#define ENTAC 0x2E /* ATM - cpcs */ +#define ENTAS 0x2F /* ATM - q.saal */ +#define ENTAM 0x30 /* ATM - q.93b */ +#define ENTUM 0x31 /* ATM - ume */ +#define ENTMU 0x32 /* ATM - management user */ +#define ENTLR 0x33 /* loader */ +#define ENTLU 0x34 /* loader user */ +#define ENTRY 0x35 /* relay */ +#define ENTEC 0x36 /* ATM - LANE Client (LEC) */ +#define ENTFA 0x37 /* ATM - Fujitsu ALC driver */ +#define ENTSR 0x38 /* MTP 3 Simple Router */ +#define ENTES 0x39 /* ATM - LANE Services (LEServices) */ +#define ENTPN 0x3A /* ATM - PNNI */ +#define ENTQI 0x3B /* QUICC Driver */ +#define ENTWD 0x3C /* MTP Level 2 Wrapper */ +#define ENTWN 0x3D /* MTP Level 3 Wrapper */ +#define ENTWI 0x3E /* ISUP Wrapper */ +#define ENTWU 0x3F /* TUP Wrapper */ +#define ENTWS 0x40 /* SCCP Wrapper */ +#define ENTWC 0x41 /* TCAP Wrapper */ +#define ENTPU 0x42 /* ATM PNNI User */ +#define ENTSA 0x43 /* ATM - Q.2140 */ +#define ENTFM 0x44 /* SS7 - Fault Manager */ +#define ENTBI 0x45 /* ATM - b-isup */ +#define ENTMA 0x46 /* SS7 - MAP*/ +#define ENTFN 0x47 /* Frame Relay Network Layer - Q.933 */ +#define ENTNV 0x48 /* V5.X PSTN */ +#define ENTLV 0x49 /* LAPV5-DL */ +#define ENTEV 0x4a /* V5.X Envelope Function */ +#define ENTPL 0x4b /* ATM - PMC Sierra LASAR driver */ +#define ENTAU 0x4c /* MAP Upper User */ +#define ENTVM 0x4d /* V5.1 mac layer */ +#define ENTAF 0x4e /* Frame Relay ATM IW Layer */ +#define ENTFR 0x4f /* Frame Relay */ +#define ENTMT 0x50 /* mt_ss */ +#define ENTCV 0x51 /* V5.X Control Protocol */ +#define ENTMV 0x52 /* V5.X System Management Layer */ +#define ENTIM 0x53 /* ATM - IME */ +#define ENTBV 0x54 /* V5 - BCC. */ +#define ENTPA 0x55 /* PLOA */ +#define ENTPV 0x56 /* V5 - Protection Protocol. */ +#define ENTLK 0x57 /* V5 - LCP */ +#define ENTL1 0x58 /* V5 - Link Layer 1 */ +#define ENTIA 0x59 /* map is41 */ +#define ENTIU 0x5a /* map is41 user */ +#define ENTRM 0x5b /* Resource Manager */ +#define ENTRT 0x5c /* Router */ +#define ENTSG 0x5d /* System manager */ +#define ENTPQ 0x5e /* Power QUICC Driver */ +#define ENTMC 0x5f /* Mac over sockets */ +#define ENTIE 0x60 /* INAP */ +#define ENTBW ENTBI /* BISUP Wrapper */ +#define ENTIW ENTSI /* ISUP Wrapper */ +#define ENTQW ENTIN /* ISDN Wrapper */ +#define ENTAW ENTAM /* q.93B Wrapper */ +#define ENTSF 0x61 /* Switching Fabric */ +#define ENTVF 0x62 /* Integrated V5 layer 3 */ +#define ENTCL 0x63 /* ASN.1 encoder/decoder */ +#define ENTSH 0x65 /* System Agent */ +#define ENTMR 0x66 /* Message Router */ +#define ENTL4 0x67 /* dummy layer4 */ +#define ENTTT 0x68 /* TCAP over TCP/IP */ +#define ENTPR 0x69 /* MPC860SAR Driver */ +#define ENTGN 0x6a /* GPRS Network Service */ +#define ENTGG 0x6b /* GPRS BSSGP */ +#define ENTAR 0x6c /* ARI module */ +#define ENTGT 0x6d /* GPRS GTP */ +#define ENTGM 0x6e /* GPRS Mobility Management */ +#define ENTGR 0x6f /* GPRS Relay */ +#define ENTGW 0x70 /* GPRS Ineterworking unit */ +#define ENTGL 0x71 /* GPRS LLC */ +#define ENTGS 0x72 /* GPRS SNDCP */ +#define ENTGZ 0x73 /* GPRS RLC/MAC */ +#define ENTGY 0x74 /* GPRS SMS */ +#define ENTHI 0x75 /* TUCL */ +#define ENTHC 0x76 /* H.323 */ +#define ENTHU 0x77 /* H.323 user */ +#define ENTHR 0x78 /* RTP/RTCP */ +#define ENTNM 0x79 /* GPRS Network Management */ +#define ENTGB 0x7a /* GPRS BSS Relay */ +#define ENTGP 0x7b /* GPRS PDP at MS */ +#define ENTIQ 0x7c /* Q.930/931-Q.SAAL Convergence Layer */ +#define ENTXM 0x7d /* Connection Manager */ +#define ENTMG 0x7e /* MGCP */ +#define ENTHG 0x7f /* Annex G */ +#define ENTDN 0x80 /* LDF-MTP3 */ +#define ENTTS 0x81 /* Trillium Stack Manager */ +#define ENTVO 0x82 /* MPC8260 Driver */ +#define ENTGO 0x83 /* GTP Location-MGMT */ +#define ENTGI 0x84 /* CC-3G */ +#define ENTGH 0x85 /* GTP-Charging */ +#define ENTGU 0x86 /* Relay on IU for GTP */ +#define ENTLN 0x87 /* MPLS */ +#define ENTSB 0x88 /* SCTP */ +#define ENTIT 0x89 /* M3UA */ +#define ENTFW 0x8a /* MPLS - Forwarder */ +#define ENTRL 0x8b /* 3GPP-RLC */ +#define ENTAL2 0x8c /* AAL2 Signaling */ +#define ENTAA 0x8d /* AAL2 Signaling User */ +#define ENTRA 0x8f /* RANAP */ +#define ENTNF 0x90 /* M3UA-NIF */ +#define ENTRN 0x91 /* RNSAP */ +#define ENTDP 0x92 /* LDF-SCCP */ +#define ENTDT 0x93 /* LDF-TCAP */ +#define ENTNP 0x94 /* SUA NIF */ +#define ENTP1 0x95 /* PXY dummy for PLOA */ +#define ENTID 0x96 /* IUA */ +#define ENTND 0x97 /* IUA-NIF */ +#define ENTDM 0x98 /* IWF */ +#define ENTSO 0x99 /* SIP */ +#define ENTSU 0x9a /* SUA */ +#ifndef OP_IU +/*ssi_h_001.main_145-defined new RANAP user*/ +#define ENTRU 0x9b /* RANAP User */ +#else +/* Map ENTRU to ENTPP */ +#define ENTRU ENTPP /* RANAP User */ +#endif +#define ENTQC 0x9c /* CAP */ +#define ENTCU 0x9d /* CAP User */ +#define ENTMM 0x9e /* Mobility Management at VLR */ +#define ENTGA 0x9f /* BSSAP+ */ +#define ENTGE 0xa0 /* GMM Application at SGSN */ +#define ENTSV 0xa1 /* SIP Application */ +#define ENTMW 0xa2 /* M2UA */ +#define ENTNW 0xa3 /* M2UA-NIF */ +#define ENTDI 0xa4 /* ISUP-LDF */ +#define ENTMK 0xa5 /* 3GPP-MAC */ +#define ENTRR 0xa6 /* 3GPP-RRC */ +#define ENTIB 0xa7 /* 3GPP-NBAP */ +#define ENTPH 0xa8 /* 3GPP-PH */ +#define ENTII ENTSM /* ISM */ +#define ENTUL 0xa9 /* 3GPP-NBAP User - Dummy */ +#define ENTGD 0xaa /* RM Application at SGSN */ +#define ENTGX 0xab /* SM-APPL Application at SGSN */ +#define ENTDG 0xac /* LDF-GCP */ + +#define ENTXX 0xad /* 3GPP-RRC User */ +#define ENTPD 0xae /* 3GPP-PDCP */ +#define ENTUS 0xaf /* 3GPP-USIM */ +#define ENTBM 0xb0 /* 3GPP-BMC */ + +#define ENTLA 0xb1 /* MPLS User */ +#define ENTLT 0xb2 /* MPLS Resource Manager */ +#define ENTRD 0xb3 /* RNSAP user */ + +#define ENTGF 0xb4 /* GMM SS User */ +#define ENTDV 0xb5 /* LDF-M3UA */ +#define ENTCS 0xb6 /* SIP Compression module */ +#define ENTFP 0xb7 /* FP Layer */ +#define ENTDU 0xb8 /* NodeB IWF Dummy */ +#define ENTFU 0xb9 /* FP Control User */ +#define ENTVU 0xba /* End Driver */ +/* Nuera PS Changes - M1UA Entry */ +#define ENTMZ 0xbb /* M1UA*/ +/* M2PA changes */ +#define ENTMX 0xbc /* M2PA */ + +#define ENTD3 0xbd /* DPNSS/DASS2 L3 */ +#define ENTD2 0xbe /* DPNSS/DASS2 L3 */ + +#define ENTNDD3 0xbf /* NIF for DUA */ + +#define ENTRP 0xc0 /* LDF - RANAP */ +#define ENTDK 0xc1 /* LDF - RANAP */ +#define ENTTM 0xc2 /* TOM entity Patch ssi_h_001.main_115 */ +#define ENTSPU 0xc3 /* Generic SCCPU User */ +#define ENTGC 0xc4 /* Phy Layer */ +#define ENTLM 0xc5 /* LAPDm */ + +/**MAC-HS ssi_h_001.main_120 */ +#define ENTHS 0xc6 /* MAC-HS */ +#define ENTCH 0xc7 /*MAC-HS Control Part*/ +#define ENTUH 0xc8 /*MAC-HS User Part*/ +/**ssi_h_001.main_122: Added Diameter and Diameter User entities */ +#define ENTAQ 0xc9 /* Diameter Base Protocol */ +#define ENTAB 0xca /* Diameter User */ + +/* ssi_h_001.main_124: Added LDF-SUA & PSF-SUA User entities */ +#define ENTAH 0xcb /* LDF-SUA */ +#define ENTAE 0xcc /* PSF-SUA */ + +/* ssi_h_001.main_125 : for RRC */ +#define ENTRX 0xcd /* RRC User */ +/* ssi_h_001.main_128: Entity for FAP is added */ +/*ssi_h_001.main_149 warning removal*/ +#ifndef OP_IU +#define ENTPP ENTSM /* FAP behaves as User and SM */ +#endif +/*-- ssi_h_001.main_129 --*/ +#define ENTLX 0xce /* IuUP --*/ + +/*ssi_h_001.main_145-defined new IuUP user*/ +#ifndef OP_IU +#define ENTXU 0xcf /* IuUP user --*/ +#else +/* Map ENTXU to ENTPP */ +#define ENTXU ENTPP /* IuUP user --*/ +#endif +/* ssi_h_001.main_148: Fixed compiler warning */ +/*#define ENTXU 0xcf */ /* IuUP user --*/ + +/* ssi_h_001.main_130 - Entity for DNRC MAC user added */ +#define ENTXY 0xd0 /* App/Relay on DRNC MAC */ + +/* ssi_h_001.main_132 Entity added for S1AP and S1AP user */ +#define ENTSZ 0xd1 /* S1AP */ +#define ENTUZ 0xd2 /* S1AP User */ +/* ssi_h_001.main_134 : Adtion for eGTP protocol */ +#define ENTEG 0xd3 /* EGTP Layer */ +#define ENTEU 0xd4 /* EGTP USER */ +/* ssi_h_001.main_135 : addition of LTE related entities */ +#define ENTTF 0xd5 /* LTE-PHY */ +#define ENTRG 0xd6 /* LTE-MAC */ +#define ENTKW 0xd7 /* LTE-RLC */ +#define ENTPJ 0xd8 /* LTE-PDCP */ +#define ENTNH 0xd9 /* LTE-RRC */ + +/* ssi_h_001.main_137 : addition of LTE-X2AP related entities */ +/* ssi_h_001.main_138 : rearrange entity list */ +#define ENTNX 0xda /* LTE-RRC user */ +#define ENTCZ 0xdb /* LTE-X2AP User */ +#define ENTRS 0xdc /* LTE-X2AP */ + +/* ssi_h_001.main_139 : addition of Iuh layer entries */ +#define ENTHM 0xdd /* Iuh */ +#define ENTHX 0xde /* Iuh-HNBAP User */ + +/* ssi_h_001.main_140 : addition of ENTVE Macro */ +#define ENTVE 0xdf /* For eNodeB Application */ +#define ENTWR 0xe3 /* For WR eNodeB Application */ + +/* ssi_h_001.main_141 : addition of PDCP layer off-board entries */ +#define ENTOS 0xe0 /* Off-board Security */ +#define ENTOC 0xe1 /* Off-board Compression */ + +#define ENTPX 0xe2 /* LTE PDCP Data User */ + +#ifdef SS_FAP +/* ssi_h_001.main_128: Entity for FAP is added */ +/*ssi_h_001.main_145-FAP specific aditions*/ +/* ssi_h_001.main_148: Entity for LTE convergence layer is added */ +/* ssi_h_001.main_149 changed for warnings*/ +#ifdef OP_IU +#define ENTPP 0xe3 +#endif +#endif + +/* ssi_h_001.main_148: Entity for LTE convergence layer is added */ +#define ENTYS 0xe4 /* LTE PDCP Data User */ +/* ssi_h_001.main_150: Entity for LTE MME application layer is added */ +#define ENTVB 0xe5 /* Lte-CNE */ +#ifdef WR_DG_OAM +#define ENTOAMSOCK 0xe6 +#define ENTOAMSTAT 0xe7 +#define ENTNL 0xe8 /* LTE SON Feature*/ +#define ENTLAST ENTNL /* last entity id */ +#else /* WR_DG_OAM */ +/* ssi_h_001.main_152: Entity for SIGTRAN,IuPS,IuCS and LTES1 monitoring stack added */ +#define ENTVN 0xe6 /*SIGTRAN Trillium Integrated Monitoring Stack*/ +#define ENTQZ 0xe7 /*Iu-PS Trillium Integrated Monitoring Stack*/ +#define ENTAX 0xe8 /*Iu-CS Trillium Integrated Monitoring Stack*/ +#define ENTQB 0xe9 /*LTE-S1 Trillium Integrated Monitoring Stack*/ +#define ENTNL 0xea /* LTE SON Feature */ + +#define ENTLAST ENTNL /* last entity id */ +#endif /* WR_DG_OAM */ + +/* un-configured procId */ +#ifdef SS_MULTIPLE_PROCS +#define PROCNC 0xFFFF /* Processor not configured */ +#endif /* SS_MULTIPLE_PROCS */ + +#define ENTNC 0xFF /* Entity not configured */ + +/* instance for mos header */ + +#define INSTNC 0xFF /* Instance not configured */ + +/* service user id */ +#define SUIDNC 0xFFFF /* service user id not configured */ + +/* service provider id */ +#define SPIDNC 0xFFFF /* service provider id not configured */ + +/* region id for mos header */ +#define REGIONNC 0xFF /* region not configured */ + +/* pool id for mos header */ +#define POOLNC 0xFF /* pool not configured */ + + +/* event code for task to task header */ + +#define EVTNONE 0x00 /* None */ + +#define EVTPERM 0x01 /* Permanent */ +#define EVT_TIMEOUT 0x02 /* Timeout */ + +#define EVTBNDREQ 0x04 /* Bind request */ +/* #define EVTBNDCFM 0x05 Bind confirm */ +/* #define EVTBNDIND 0x06 Bind indication */ +/* #define EVTBNDRSP 0x07 Bind response */ + +#define EVTUBNDREQ 0x08 /* Unbind request */ +/* #define EVTUBNDCFM 0x09 Unbind confirm */ +/* #define EVTUBNDIND 0x0A Unbind indication */ +/* #define EVTUBNDRSP 0x0B Unbind response */ + +#define EVTCONREQ 0x0C /* Connect request */ +#define EVTCONCFM 0x0D /* Connect confirm */ +#define EVTCONIND 0x0E /* Connect indication */ +#define EVTCONRSP 0x0F /* Connect response */ + +#define EVTDISCREQ 0x10 /* Disconnect request */ +#define EVTDISCCFM 0x11 /* Disconnect confirm */ +#define EVTDISCIND 0x12 /* Disconnect indication */ +#define EVTDISCRSP 0x13 /* Disconnect response */ + +#define EVTDATREQ 0x14 /* Data request */ +#define EVTDATCFM 0x15 /* Data confirm */ +#define EVTDATIND 0x16 /* Data indication */ +#define EVTDATRSP 0x17 /* Data response */ + +#define EVTUDATREQ 0x18 /* Unit data request */ +#define EVTUDATCFM 0x19 /* Unit data confirm */ +#define EVTUDATIND 0x1A /* Unit data indication */ +#define EVTUDATRSP 0x1B /* Unit data response */ + +#define EVTEDATREQ 0x1C /* Expedited data request */ +#define EVTEDATCFM 0x1D /* Expedited data confirm */ +#define EVTEDATIND 0x1E /* Expedited data indication */ +#define EVTEDATRSP 0x1F /* Expedited data response */ + +#define EVTDATCHRREQ 0x20 /* Data character request */ +#define EVTDATCHRCFM 0x21 /* Data character confirm */ +#define EVTDATCHRIND 0x22 /* Data character indication */ +#define EVTDATCHRRSP 0x23 /* Data character response */ + +#define EVTDATACKREQ 0x24 /* Data acknowledge request */ +#define EVTDATACKCFM 0x25 /* Data acknowledge confirm */ +#define EVTDATACKIND 0x26 /* Data acknowledge indication */ +#define EVTDATACKRSP 0x27 /* Data acknowledge response */ + +#define EVTFLCREQ 0x28 /* Flow control request */ +/* #define EVTFLCCFM 0x29 Flow control confirm */ +#define EVTFLCIND 0x2A /* Flow control indication */ +/* #define EVTFLCRSP 0x2B Flow control response */ + +#define EVTRSTREQ 0x2C /* Reset request */ +#define EVTRSTCFM 0x2D /* Reset confirmation */ +#define EVTRSTIND 0x2E /* Reset indication */ +#define EVTRSTRSP 0x2F /* Reset response */ + +#define EVTCFGXXREQ 0x30 /* Configuration request */ +/* #define EVTCFGXXCFM 0x31 Configuration confirmation */ +/* #define EVTCFGXXIND 0x32 Configuration indication */ +/* #define EVTCFGXXRSP 0x33 Configuration response */ + +#define EVTRESMREQ 0x34 /* Call resume request */ +/* #define EVTRESCFM 0x35 Call resume confirm */ +#define EVTRESMIND 0x36 /* Call resume indication */ +/* #define EVTRESRSP 0x37 Call resume response */ + +#define EVTSUSPREQ 0x38 /* Call suspend request */ +/* #define EVTSUSPCFM 0x39 Call suspend confirm */ +#define EVTSUSPIND 0x3A /* Call suspend indication */ +/* #define EVTSUSPRSP 0x3B Call suspend response */ + +#define EVTCFGREQ 0x3C /* Configuration request */ +#define EVTCFGCFM 0x3D /* Configuration confirmation */ +#define EVTCFGIND 0x3E /* Configuration indication */ +/* #define EVTCFGXXRSP 0x3F Configuration response */ + +#define EVTSTAREQ 0x40 /* Status request */ +#define EVTSTACFM 0x41 /* Status confirm */ +#define EVTSTAIND 0x42 /* Status indication */ +/* #define EVTSTARSP 0x43 Status response */ + +#define EVTSTSREQ 0x44 /* Statistics request */ +#define EVTSTSCFM 0x45 /* Statistics confirm */ +/* #define EVTSTSIND 0x46 Statistics indication */ +/* #define EVTSTSRSP 0x47 Statistics response */ + +#define EVTTRCIND 0x48 /* Trace indication */ +/* #define EVTTRCCFM 0x49 Trace confirm */ +/* #define EVTTRCIND 0x4A Trace indication */ +/* #define EVTTRCRSP 0x4B Trace response */ + +#define EVTCNTRLREQ 0x4C /* Control request */ +#define EVTCNTRLCFM 0x4D /* Control confirm */ +#define EVTCNTRLIND 0x4E /* Control indication */ +#define EVTCNTRLRSP 0x4F /* Control response */ + +#define EVTXIDREQ 0x50 /* Exchange id request */ +#define EVTXIDCFM 0x51 /* Exchange id confirm */ +#define EVTXIDIND 0x52 /* Exchange id indication */ +#define EVTXIDRSP 0x53 /* Exchange id response */ + +#define EVTACNTREQ 0x54 /* Accounting request */ +/* #define EVTACNTCFM 0x55 Accounting confirm */ +#define EVTACNTIND 0x56 /* Accounting indication */ +/* #define EVTACNTRSP 0x57 Accounting response */ + +#define EVTCNSTREQ 0x58 /* Connection progress status request */ +/* #define EVTCNSTCFM 0x59 Connection progress status confirm */ +#define EVTCNSTIND 0x5A /* Connection progress status indication */ +/* #define EVTCNSTRSP 0x5B Connection progress status response */ + +#define EVTRELREQ 0x5C /* Connection release request */ +#define EVTRELCFM 0x5D /* Connection release confirmation */ +#define EVTRELIND 0x5E /* Connection release indication */ +#define EVTRELRSP 0x5F /* Connection release response */ + +#define EVTSSHLREQ 0x60 /* Connection suspend and hold request */ +#define EVTSSHLCFM 0x61 /* COnnection suspend and hold confirmation */ +#define EVTSSHLIND 0x62 /* COnnection suspend and hold indication */ +#define EVTSSHLRSP 0x63 /* Connection suspend and hold response */ + +#define EVTRMRTREQ 0x64 /* Call resume/retrieve request */ +#define EVTRMRTCFM 0x65 /* Call resume/retrieve confirmation */ +#define EVTRMRTIND 0x66 /* Call resume/retrieve indication */ +#define EVTRMRTRSP 0x67 /* Call resume/retrieve response */ + +#define EVTFACREQ 0x68 /* Call facility request */ +#define EVTFACCFM 0x69 /* Call facility confirm */ +#define EVTFACIND 0x6A /* Call facility indication */ +#define EVTFACRSP 0x6B /* Call facility response */ + +#define EVTSTAENQREQ 0x6C /* Status enquiry request */ +#define EVTSTAENQCFM 0x6D /* Status enquiry confirmation */ +#define EVTSTAENQIND 0x6E /* Status enquiry indication */ +#define EVTSTAENQRSP 0x6F /* Status enquiry response */ + +#define EVTSRVREQ 0x70 /* Service request */ +#define EVTSRVCFM 0x71 /* Service confirmation */ +#define EVTSRVIND 0x72 /* Service indication */ +/* #define EVTSRVRSP 0x73 Service response */ + +/* #define EVTALRTREQ 0x74 Alert request */ +/* #define EVTALRTCFM 0x75 Alert confirmation */ +#define EVTALRTIND 0x76 /* Alert indication */ +/* #define EVTALRTRSP 0x77 Alert response */ + +#define EVTSTAXXREQ 0x78 /* Status request */ +#define EVTSTAXXCFM 0x79 /* Status confirm */ +#define EVTSTAXXIND 0x7A /* Status indication */ +/* #define EVTSTAXXRSP 0x7B Status response */ + +#define EVTLMUDATREQ 0x7C /* LM - unit data request */ +/* #define EVTLMUDATCFM 0x7D LM - unit data confirm */ +#define EVTLMUDATIND 0x7E /* LM - unit data indication */ +/* #define EVTLMUDATRSP 0x7F LM - unit data response */ + +#define EVTADDREQ 0x80 /* Add request */ +#define EVTADDCFM 0x81 /* Add confirm */ +#define EVTADDIND 0x82 /* Add indication */ +#define EVTADDRSP 0x83 /* Add response */ + +#define EVTREMREQ 0x84 /* Remove request */ +#define EVTREMCFM 0x85 /* Remove confirm */ +#define EVTREMIND 0x86 /* Remove indication */ +/* #define EVTREMRSP 0x87 Remove response */ + +#define EVTSYNREQ 0x88 /* Synchronize request */ +#define EVTSYNCFM 0x89 /* Synchronize confirm */ +#define EVTSYNIND 0x8A /* Synchronize indication */ +/* #define EVTSYNRSP 0x8B Synchronize response */ + +#define EVTEXAMREQ 0x8C /* Examine request */ +#define EVTEXAMCFM 0x8D /* Examine confirm */ +/* #define EVTEXAMIND 0x8E Examine indication */ +/* #define EVTEXAMRSP 0x8F Examine response */ + +#define EVTADDPTYREQ 0x90 /* Add Party Request */ +#define EVTADDPTYCFM 0x91 /* Add Party Confirm */ +#define EVTADDPTYIND 0x92 /* Add Party Indication */ +#define EVTADDPTYRSP 0x93 /* Add Party Response */ + +#define EVTADDPTYREJREQ 0x94 /* Add Party Reject Request */ +#define EVTADDPTYREJCFM 0x95 /* Add Party Reject Confirm */ +#define EVTADDPTYREJIND 0x96 /* Add Party Reject Indication */ +#define EVTADDPTYREJRSP 0x97 /* Add Party Reject Response */ + +#define EVTDROPPTYREQ 0x98 /* Drop Party Request */ +#define EVTDROPPTYCFM 0x99 /* Drop Party Confirm */ +#define EVTDROPPTYIND 0x9A /* Drop Party Indication */ +#define EVTDROPPTYRSP 0x9B /* Drop Party Response */ + +#define EVTNEXTREQ 0x9C /* Next request */ +#define EVTNEXTCFM 0x9D /* Next confirm */ +#define EVTNEXTIND 0x9E /* Next indication */ +/* #define EVTNEXTRSP 0x9F Next response */ + +/* #define EVTERRREQ 0xA0 Error request */ +/* #define EVTERRCFM 0xA1 Error confirm */ +#define EVTERRIND 0xA2 /* Error indication */ +#define EVTERRRSP 0xA3 /* Error response */ + +#define EVT_BNDREQ 0xA4 /* Bind request */ +/* #define EVT_BNDCFM 0xA5 Bind confirm */ +/* #define EVT_BNDIND 0xA6 Bind indication */ +/* #define EVT_BNDRSP 0xA7 Bind response */ + +#define EVT_UBNDREQ 0xA8 /* Unbind request */ +/* #define EVT_UBNDCFM 0xA9 Unbind confirm */ +/* #define EVT_UBNDIND 0xAA Unbind indication */ +/* #define EVT_UBNDRSP 0xAB Unbind response */ + +#define EVT_DATREQ 0xAC /* Data request */ +#define EVT_DATCFM 0xAD /* Data confirm */ +#define EVT_DATIND 0xAE /* Data indication */ +#define EVT_DATRSP 0xAF /* Data response */ + +#define EVT_UDATREQ 0xB0 /* Unit data request */ +#define EVT_UDATCFM 0xB1 /* Unit data confirm */ +#define EVT_UDATIND 0xB2 /* Unit data indication */ +#define EVT_UDATRSP 0xB3 /* Unit data response */ + +#define EVTESTREQ 0xB4 /* Establish request */ +#define EVTESTCFM 0xB5 /* Establish confirm */ +#define EVTESTIND 0xB6 /* Establish indication */ +#define EVTESTRSP 0xB7 /* Establish response */ + +#define EVTMODREQ 0xC0 /* Modify request */ +#define EVTMODCFM 0xC1 /* Modify confirm */ +#define EVTMODIND 0xC2 /* Modify indication */ +#define EVTMODRSP 0xC3 /* Modify response */ + +#define EVTTSKDOWNREQ 0xF0 /* Task shutdown request */ +#define EVTTSKDOWNCFM 0xF1 /* Task shutdown confirm */ +/* #define EVTTSKDOWNIND 0xF2 Task shutdown indication */ +/* #define EVTTSKDOWNRSP 0xF3 Task shutdown response */ + +#define EVTTSKUPREQ 0xF4 /* Task startup request */ +#define EVTTSKUPCFM 0xF5 /* Task startup confirm */ +/* #define EVTTSKUPIND 0xF6 Task startup indication */ +/* #define EVTTSKUPRSP 0xF7 Task startup response */ + +#define EVTCRDREQ 0xF8 /* SCCP mgmt - Coordinated Request */ +#define EVTCRDCFM 0xF9 /* SCCP mgmt - Coordinated Confirm */ +#define EVTCRDIND 0xFA /* SCCP mgmt - Coordinated Indication */ +#define EVTCRDRSP 0xFB /* SCCP mgmt - Coordinated Response */ + +#define EVTSTEREQ 0xFC /* SCCP mgmt - State Request */ +#define EVTSTEIND 0xFD /* SCCP mgmt - State Indication */ +#define EVTPCSTEIND 0xFE /* SCCP mgmt - PC-State Indication */ + +#define EVTSHIFT 0xFF /* Shift to new event code set */ + + +/* + This section contains specific defines for the following operating systems: + + MOS - MOSVER + MOS, v2 - MSVER2 + psos - PS + vrtxsa - VX + vxworks - VW + Windows NT - WINNT_IATM + sslib - system service library for elvis + other - + + The defines PORTVER, MOSVER and MSVER2 are mutually exclusive. The define PORTVER + must be set in conjunction with the define PS, VX, VW or portable/other. + +*/ + + +#ifdef MOSVER /* mos version */ +/* mos defines */ + + +#else +#ifdef MSVER2 /* mos version 2 */ +/* mos version 2 defines */ +#define DFLT_REGION 0 +#define DFLT_POOL 0 + +#ifdef SS_FAP +/*ssi_h_001.main_145- Defined new region for FAP*/ +#define SS_WL_REGION 1 +#endif + +#define OWNREGION DFLT_REGION /* own region */ + +#else +#ifdef PS /* psos version */ +/* psos defines */ +#define DFLT_REGION 0 +#define DFLT_POOL 0 + +#ifdef SS_FAP +/*ssi_h_001.main_145 - Defined new region for FAP*/ +#define SS_WL_REGION 1 +#endif + +#define OWNREGION DFLT_REGION /* own region */ + +#else +#ifdef VX /* vrtxsa version */ +/* vrtxsa defines */ +#define DFLT_REGION 0 +#define DFLT_POOL 0 + +#ifdef SS_FAP +/*ssi_h_001.main_145 - Defined new region for FAP*/ +#define SS_WL_REGION 1 +#endif + +#define OWNREGION DFLT_REGION /* own region */ + +/* events */ + +#define EVTTMRTCKREQ 0x80 /* Timer Tick request */ + +/* return codes */ + +#define VX_RET_OK 0x00 /* good return value */ +#define VX_ER_IIP 0x12 /* input parameter error */ +#define VX_ER_NOCB 0x30 /* no control block error */ +#define VX_ER_NMB 0x04 /* not a memory block error */ +#define VX_ER_ID 0x31 /* ID error */ +#define VX_ER_MEM 0x03 /* no memory error */ +#define VX_ER_PID 0x0E /* partition id error */ +#define VX_ER_QID 0x0C /* queue id error */ +#define VX_ER_QFL 0x0D /* queue full error */ + +#else +#ifdef VW /* vxworks version */ + +/* vxworks defines */ +#define VW_MBUF_POOL 3 /* message header pool id */ +#define VW_TMR_POOL 2 /* timer pool id */ +#define VW_WRAP_POOL 1 /* wrapper pool id */ +#define VW_PROT_POOL 0 /* protocol pool id */ + +#define DFLT_REGION 0 +#define DFLT_POOL VW_PROT_POOL /* protocol data pool */ + +#ifdef SS_FAP +/*ssi_h_001.main_145 - Defined new region for FAP*/ +#define SS_WL_REGION 1 +#endif + +#define OWNREGION DFLT_REGION /* own region */ + +#else +#if ( defined(SSLIB) || defined(SSRYLIB) ) +#define DFLT_REGION 0 +#define DFLT_POOL 0 +#ifdef SS_FAP +/*ssi_h_001.main_145 - Defined new region for FAP*/ +#define SS_WL_REGION 1 +#endif + +#define MAXBUFSIZ 2048 +#define STARTOFFSET 1024 +#else /* portable/other version */ +#ifdef SS /* Common System Services */ + +/* CTL operation codes */ +#define SS_MEM_V_TO_P 1 +#define SS_MEM_CHK_RES 2 + +#define DFLT_REGION 0 +#define DFLT_POOL 0 +#ifdef SS_FAP +/*ssi_h_001.main_145 - Defined new region for FAP*/ +#define SS_WL_REGION 1 +#endif + +#define OWNREGION DFLT_REGION /* own region */ + +/* basic lock types */ +#define SS_LOCK_MUTEX 1 +#define SS_LOCK_SPIN 2 +#define SS_LOCK_CRITSEC 3 + +#ifdef SS_OLD_THREAD +/* flags for SGetThread() */ +#define SS_THR_NOFLAGS 0x00 +#define SS_THR_SUSPENDED 0x01 +#define SS_THR_DETACHED 0x02 +#define SS_THR_BOUND 0x04 +#define SS_THR_NEW_LWP 0x08 +#define SS_THR_DAEMON 0x10 +#endif /* SS_OLD_THREAD */ + +/* Queue Macros */ +#ifdef SS_ENABLE_MACROS +#define SQueueFirst(mBuf, q) \ + SAddQueue(mBuf, (q), 0) + +#define SDequeueFirst(mBuf, q) \ + SRemQueue(mBuf, (q), 0) + +#define SQueueLast(mBuf, q) \ + ((q) == NULLP ? RFAILED : SAddQueue(mBuf, (q), ((Queue *)(q))->crntSize)) + +#define SDequeueLast(mBuf, q) \ + ((q) == NULLP ? RFAILED : \ + (((Queue *)(q))->crntSize == 0 ? ROKDNA : SRemQueue(mBuf, q, \ + (((Queue *)q))->crntSize-1))) + +/* + * this depends on region and pool being the first two + * parameters of ssMsgInfo + */ + +#define SGetBufRegionPool(buf, region, pool) \ + (((buf) == NULLP || \ + ((region) == NULLP && (pool) == NULLP)) ? RFAILED : \ + ((region) == NULLP || \ + (*(region) = ((Region)*((Region *)((buf)->b_rptr))))),\ + ((pool) == NULLP || \ + (*(pool) = ((Pool)*((Pool *)((buf)->b_rptr + sizeof(Region)))))),\ + ROK) + +#endif /* SS_ENABLE_MACROS */ + +/* These are outside SS_ENABLE_MACROS for backward compatibility + * + * redefine these to be different from default + * these depend on region and pool being the first two + * parameters of ssMsgInfo + */ + +#undef SGETBUFREGION +#define SGETBUFREGION(buf) \ + (((buf) == NULLP) ? REGIONNC : (Region)*((Region *)(buf)->b_rptr)) + +#undef SGETBUFPOOL +#define SGETBUFPOOL(buf) \ + (((buf) == NULLP) ? POOLNC : \ + (Pool)*((Pool *)((buf)->b_rptr + sizeof(Region)))) + +/*ssi_h_001.main_147 ss_dep.h guarded under flag*/ +#ifdef SS_CAVIUM +#include "jz_dep.h" +#else +#ifdef SS_4GMX_LCORE +#include "ss_dep.h" +#else +#include "ss_dep.h" +#endif /* SS_4GMX_LCORE*/ +#endif /*SS_CAVIUM*/ + +#else /* Not SS */ +#ifdef MT /* mt version */ + +/* mtworks defines */ +#define MT_MBUF_POOL 3 /* message header pool id */ +#define MT_TMR_POOL 2 /* timer pool id */ +#define MT_WRAP_POOL 1 /* wrapper pool id */ +#define MT_PROT_POOL 0 /* protocol pool id */ + +#define DFLT_REGION 0 +#define DFLT_POOL MT_PROT_POOL /* protocol data pool */ + +#define OWNREGION DFLT_REGION /* own region (bc, use DFLT_REGION) */ + +/* thread types */ +#define MT_THR_NOFLAGS 0x00 +#define MT_THR_SUSPENDED 0x01 +#define MT_THR_DETACHED 0x02 +#define MT_THR_BOUND 0x04 +#define MT_THR_NEW_LWP 0x08 +#define MT_THR_DAEMON 0x10 + +/* thread priorities */ +#define MT_LOW_PRI 0 +#define MT_NORM_PRI 10 +#define MT_HIGH_PRI 20 + +#else /* not MT */ +#ifdef WINNT_IATM +/* WINT defines */ +#define DFLT_REGION 0 +#define DFLT_POOL 0 +#ifdef SS_FAP +/*ssi_h_001.main_145 - Defined new region for FAP*/ +#define SS_WL_REGION 1 +#endif + +#define PHY_CONTIG_REGION 1 + +#define OWNREGION DFLT_REGION /* own region */ +#else /* WINNT_IATM */ +/* portable/other defines */ +#define DFLT_REGION 0 /* required by portable */ +#define DFLT_POOL 0 /* required by portable */ +#ifdef SS_FAP +/*ssi_h_001.main_145 - Defined new region for FAP*/ +#define SS_WL_REGION 1 +#endif +#define OWNREGION DFLT_REGION /* own region */ + +/* lock data types */ +#define SsSemaId U8 +#define SLockId U8 +/* ssi_h_001.main_143: Additions */ +#define SLockInfo U8 + +/* basic lock types */ +#define SS_LOCK_MUTEX 1 +#define SS_LOCK_SPIN 2 +#define SS_LOCK_CRITSEC 3 + +#endif /* WINNT_IATM */ +#endif /* MT */ +#endif /* SS */ +#endif /* SSLIB || SSRYLIB*/ +#endif /* VW */ +#endif /* VX */ +#endif /* PS */ +#endif /* MSVER2 */ +#endif /* MOSVER */ + +/* Macros for REGION1 and REGION2 support */ +#define SS_REGION1 1 +#define SS_REGION2 2 + +/* Time in seconds from UTC EPOCH */ +#define SS_REFTIME_01_01_1970 0 +#define SS_REFTIME_01_01_2002 1009843200 + +/* Ticks per second */ +#define SS_100MS 10 +#define SS_10MS 100 +#define SS_1MS 1000 + +/*ssi_h_001.main_145-definednew value for SS_TICS_SEC for FAP*/ +#ifndef SS_FAP +#ifndef SS_TICKS_SEC +/* ssi_h_001.main_152: Modified SS_TICKS_SEC value for 4GMX */ +#ifdef SS_4GMX_LCORE +#define SS_TICKS_SEC SS_1MS +#else +#define SS_TICKS_SEC SS_100MS +#endif /*SS_4GMX_LCORE*/ +#endif +#else +#ifndef SS_TICKS_SEC +#define SS_TICKS_SEC SS_1MS +#endif +#endif + +/* procId added */ +/* ssi_h_001.main_127 Replaced SS_100MS with SS_TICKS_SEC in SRegCfgTmr/SDeregCfgTmr */ +#ifndef SS_MULTIPLE_PROCS + +/* ssi_h_001.main_146 */ +#ifndef SS_FAP +#define SRegTmr(ent,inst,period,fun) SRegCfgTmr(ent,inst,period,SS_TICKS_SEC,fun) +#define SDeregTmr(ent,inst,period,fun) SDeregCfgTmr(ent,inst,period,SS_TICKS_SEC,fun) +#else /* SS_FAP */ +#define SRegTmr(ent,inst,period,fun) SRegCfgTmr(ent,inst,period,SS_10MS,fun) +#define SDeregTmr(ent,inst,period,fun) SDeregCfgTmr(ent,inst,period,SS_10MS,fun) +#endif + +/* ssi_h_001.main_131 */ +#ifdef SS_MT_TMR +/* ssi_h_001.main_126 */ +#define SRegTmrMt(ent,inst,period,fun) SRegCfgTmrMt(ent,inst,period,SS_TICKS_SEC,fun) +#define SDeregTmrMt(ent,inst,period,fun) SDeregCfgTmrMt(ent,inst,period,SS_TICKS_SEC,fun) +#endif + +#else + +/* ssi_h_001.main_146 */ +#ifndef SS_FAP +#define SRegTmr(proc, ent,inst,period,fun)\ + SRegCfgTmr(proc, ent,inst,period,SS_TICKS_SEC,fun) +#define SDeregTmr(proc, ent,inst,period,fun)\ + SDeregCfgTmr(proc, ent,inst,period,SS_TICKS_SEC,fun) +#else /* SS_FAP */ +#define SRegTmr(proc, ent,inst,period,fun)\ + SRegCfgTmr(proc, ent,inst,period,SS_100MS,fun) +#define SDeregTmr(proc, ent,inst,period,fun)\ + SDeregCfgTmr(proc, ent,inst,period,SS_100MS,fun) +#endif + +#endif /* SS_MULTIPLE_PROCS */ + +/* RELAY ONLY DEFINES */ +#ifdef ENB_RELAY + +#define RY_SHM_KEY 0x3000 +#define RY_SHM_PERMS 0666 + +#define RY_MSG_KEY 0x2000 +#define RY_MSG_PERMS 0666 + +#define RY_BASECHANID 0 + +#ifdef INTNT_PMC860 + +/* + * Processor Id map for the Integrated Windows NT platform + * + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * |A A A A S S S R R I I I I I I I| + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * + * A - Application Id + * S - Stack Id + * R - Reserved + * I - IPM Id + * + */ + +/* processor id masks */ +#define APP_MSK 0xf +#define STK_MSK 0x7 +#define BUS_MSK 0x0 +#define VCM_MSK 0x0 +#define IPM_MSK 0x7f +#define BVM_MSK 0x0 + +/* processor id offsets */ +#define APP_OFF 12 +#define STK_OFF 9 +#define BUS_OFF 0 +#define VCM_OFF 0 +#define IPM_OFF 0 +#define BVM_OFF 0 +#else +/* processor id masks */ +#define APP_MSK 0xf +#define STK_MSK 0x7 +#define BUS_MSK 0x3 +#define VCM_MSK 0xf +#define IPM_MSK 0x7 +#define BVM_MSK 0x3f + +/* processor id offsets */ +#define APP_OFF 12 +#define STK_OFF 9 +#define BUS_OFF 7 +#define VCM_OFF 3 +#define IPM_OFF 0 +#define BVM_OFF 3 +#endif /* INTNT_PMC860 */ + +/* set processor id macros */ +#define PID_APP(a) ((a) << APP_OFF) +#define PID_STK(h) ((h) << STK_OFF) +#define PID_B_V(b, v) (((b) << BUS_OFF) | ((v) << VCM_OFF)) +#define PID_BV(bv) ((bv) << BVM_OFF) +#define PID_B_V_I(b, v, i) (((b) << BUS_OFF) | ((v) << VCM_OFF) | (i) ) +#define PID_BV_I(bv, i) (((bv) << BVM_OFF) | (i)) + +/* get processor id macros */ +#define GET_APP_ID(pid) (((pid) & (APP_MSK << APP_OFF)) >> APP_OFF) +#define GET_STK_ID(pid) (((pid) & (STK_MSK << STK_OFF)) >> STK_OFF) +#define GET_BUS_ID(pid) (((pid) & (BUS_MSK << BUS_OFF)) >> BUS_OFF) +#define GET_VCM_ID(pid) (((pid) & (VCM_MSK << VCM_OFF)) >> VCM_OFF) +#define GET_IPM_ID(pid) ((pid) & IPM_MSK) +#define GET_BV_ID(pid) (((pid) & (BVM_MSK << BVM_OFF)) >> BVM_OFF) + +#ifdef ELVIS_IMP +#define MAXBRDS 16 /* 16 MVME's */ +#endif /* ELVIS_IMP */ + +#ifdef ELVIS_BIT3 +#define MAXBRDS 64 /* 16*4 MVME's */ +#endif /* ELVIS_BIT3 */ + +#ifdef ELVIS_FORCE +#define MAXBRDS 16 /* 16 MVME's or Power Core's */ +#endif /* ELVIS_FORCE */ + +#ifdef ELVIS_68040 +#define MAXBRDS 4 /* 4 IPM's */ +#endif /* ELVIS_68040 */ + +#ifdef ELVIS_PPC60X +#define MAXBRDS 2 /* 2 PMCS's Maximum */ +#endif /* ELVIS_PPC60X */ + +#ifdef INTNT_PMC860 +#define MAXBRDS 64 /* Maximum number of PMCS in system */ +#endif /* ELVIS_PPC60X */ + +#else /* not ENB_RELAY */ +#define PID_STK(h) (h) +#endif /* ENB_RELAY */ + +/* Inter CPU messages */ +#define SS_ICPU_DATA 6 +/*ssi_h_001.main_133*/ +/*ssi_h_001.main_151 ADDED SS_AFFINITY_SUPPORT*/ +#if defined(SS_MULTICORE_SUPPORT) || defined(SS_AFFINITY_SUPPORT) +/* CPU affinity modes */ +#define SS_AFFINITY_MODE_DEFAULT 0 +#define SS_AFFINITY_MODE_SPECIFIC 1 +#define SS_AFFINITY_MODE_ASSOC 2 +#define SS_AFFINITY_MODE_EXCL 3 + +#define SS_MAX_CORES 64 +#define SS_MAX_THREADS_PER_CORE 16 +#define SS_DEFAULT_CORE ~0 + +#endif /* SS_MULTICORE_SUPPORT || SS_AFFINITY_SUPPORT*/ + +/* ssi_h_001.main_136: SSI-Phse-2, Added defines for memory + * allocation/de-allocation from static memory pool + */ +#ifdef SS_HISTOGRAM_SUPPORT +#define SGetSBuf(region, pool, bufPtr, size) SGetSBufNew(region,pool,bufPtr,size, __LINE__, (U8*)__FILE__) +#define SPutSBuf(region, pool, buf, size) SPutSBufNew(region, pool, buf, size, __LINE__, (U8*)__FILE__) +#define SGetMsg(region, pool, mBufPtr) SGetMsgNew(region, pool, mBufPtr, __LINE__, (U8*)__FILE__) +#define SPutMsg(mBuf) SPutMsgNew(mBuf, __LINE__, (U8*)__FILE__) +#elif defined(SS_LIGHT_MEM_LEAK_STS) +#define SGetSBuf(region, pool, bufPtr, size) SGetSBufNew(region,pool,bufPtr,size, __LINE__, (U8*)__func__) +#define SGetMsg(region, pool, mBufPtr) SGetMsgNew(region, pool, mBufPtr, __LINE__, (U8*)__func__) +#define SGetDBuf(region, pool, bufPtr) SGetDBufNew(region,pool,bufPtr, __LINE__, (U8*)__func__) +#define SPutSBuf(region, pool, buf, size) SPutSBufNew(region, pool, buf, size, __LINE__, (U8 *)__func__) +#define SPutMsg(mBuf) SPutMsgNew(mBuf, __LINE__, (U8*)__func__) +#define SPutDBuf(region, pool, buf) SPutDBufNew(region, pool, buf, __LINE__, (U8*)__func__) +#endif /* SS_HISTOGRAM_SUPPORT */ +/* ssi_h_001.main_142 Readwrite additions */ +/* ssi_h_001.main_144 Readwrite locks Guarded */ +#ifdef SS_RDWR_LOCK_SUPPORT +#define SRDWRLOCK 1 +#define SRDLOCK 2 +#define SWRLOCK 3 +#define STRYRDLOCK 4 +#define STRYWRLOCK 5 +#endif /* SS_RDWR_LOCK_SUPPORT */ +#ifdef SS_REC_LOCK_SUPPORT +#define SMUTEXRECUR 6 +#endif /* SS_REC_LOCK_SUPPORT */ + +/* The below range from 30001 - 30099 is for 4GMX SSI and common */ +#ifndef TENB_T2K3K_SPECIFIC_CHANGES +#define PID_SVSRALLOC_ICMSG 30001 +#define PID_SVSRSEND_ICMSG 30002 +#define PID_SVSRALLOC_MSG 30003 +#define PID_SSI_CORE3 30004 +#define PID_SSI_CORE2 30005 +#define PID_SSI_ICORE_MSG 30006 +#define PID_SSI_ICPU_MSG 30007 +#else +#define PID_SSI_TSK_L2 30005 +#define PID_PHY_RCVR_THRD 30005 +#define PID_SSI_TSK 30007 +#define PID_HI_TSK 30331 +#define PID_SB_TSK 30332 +#define PID_WR_TSK 30333 +#define PID_S1_TSK 30334 +#define PID_EG_TSK 30335 +#define PID_SVSRALLOC_MSG 30003 +#endif /* TENB_T2K3K_SPECIFIC_CHANGES */ +/* The below range from 30101 - 30199 is for CL */ +#define PID_CRC_IND_DUMMY 30101 +#define PID_CRC_IND_REAL 30102 +#define PID_CL_CNTRL_REQ_DL 30103 +#define PID_CL_DAT_REQ 30104 +#define PID_CL_RECP_REQ 30105 +#define PID_CL_SEND_TO_PHY 30106 +#define PID_CL_RXEND_IND 30107 +#define PID_CL_PHY_MSG 30108 +#define PID_CL_RXSDU_IND 30109 +#define PID_CL_RXSDUANDEND_IND 30110 +#define PID_CL_FILL_DLCHNL_DESC 30111 +#define PID_CL_FILL_TXSDU 30112 +#define PID_CL_SND_VECT_TO_PHY 30113 +#define PID_CL_PHICH_DAT_REQ 30114 +#define PID_CL_PDCCH_DAT_REQ 30115 +#define PID_CL_PDSCH_DAT_REQ 30116 +#define PID_CL_PBCH_DAT_REQ 30117 +#define PID_CL_MAC_TTI_IND 30118 +#define PID_CL_CNTRL_REQ_UL 30119 +#define PID_CL_SPACC_BATCH_UL_BLK 30120 +#define PID_CL_SPACC_BATCH_DL_BLK 30121 + + + + +/* The below range from 30200 - 30299 is for MAC/RLC/PDCP */ +#define PID_SCH_TTI_IND 30200 +#define PID_MAC_DAT_IND 30201 +#define PID_MAC_SF_ALLOC_REQ 30202 +#define PID_MAC_STA_RSP 30203 +#define PID_MAC_DL_SCHD 30204 +#define PID_MAC_DL_CQI_IND 30205 +#define PID_MAC_UL_CQI_IND 30206 +#define PID_MAC_SR_IND 30207 +#define PID_MAC_HARQ_IND 30208 +#define PID_MAC_TA_IND 30209 +#define PID_MAC_UL_SCHD 30210 +#define PID_MAC_TTI_IND 30211 +#define PID_MAC_UE_CFG 30212 +#define PID_MAC_UE_RECFG 30213 +#define PID_MAC_UE_DEL 30214 +#define PID_MAC_UE_RST 30215 +#define PID_SCH_UE_CFG 30216 +#define PID_SCH_UE_RECFG 30217 +#define PID_SCH_UE_DEL 30218 +#define PID_SCH_UE_RST 30219 +#define PID_MAC_DDATREQ 30220 +#define PID_MAC_FILLDREQ 30221 +#define PID_MAC_TFUDREQ 30222 +#define PID_SCHUTL_CMALLCEVT 30223 +#define PID_TOMUTL_CMALLCEVT 30224 +#define PID_TOMINF_CMALLCEVT 30225 +#define PID_MACUTL_CMALLCEVT 30226 +#define PID_SCH_DUMMY_TTI_IND 30227 +#define PID_MAC_TFU_DATIND 30228 +#define PID_UL_SCHEDULING 30229 /* UL scheduling: CRC indication */ +#define PID_ysMsPrcUlSchSduInd 30230 +#define PID_CL_RCV_PHY_MSG 30231 +#define PID_CL_HARQ_STA_IND 30232 +#define PID_CL_DL_BATCH_PROC 30233 +#define PID_CL_DLM_PRC_TTI_IND 30234 +#define PID_TTI_LATENCY 30235 +#define PID_RECPREQ_PROC 30236 +#define PID_MAC_UL_SRS_IND 30237 + +#define PID_RLC_STA_IND 30240 +#define PID_RLC_REASSEMBLY 30241 +#define PID_RLC_AM_SELF_PST_DL 30242 +#define PID_RLC_AM_PDU_RLS 30243 +#define PID_RLC_CHK_SDU_MAP 30244 +#define PID_RLC_SND_DAT_CFM 30245 +#define PID_RLC_AM_SELF_PDU_RSMBL 30246 +#define PID_RLC_AM_RGU_DATIND 30247 +#define PID_RLC_AM_ADDTOLIST_UL 30248 +#define PID_RLC_AM_FREEBUF 30249 +#define PID_RLC_AM_RETXLIST 30250 +#define PID_RLC_AM_POST_ULSELFMSG 30251 +#define PID_RLC_AM_UTL_RSMBL 30252 +#define PID_RLC_AM_STA_PDU 30253 +#define PID_RLC_CFG_REQ 30254 +#define PID_RLC_CFG_REQ_REEST 30255 +#define PID_RLC_CFG_REQ_REM 30256 +#define PID_RLC_AM_RLSPDUSET 30257 +#define PID_RLC_AM_RB_DELETE 30258 +#define PID_RLC_AM_REEST 30259 +#define PID_RLC_CFG_UE_DELETE 30260 +#ifndef BRDCM +#define PID_RLC_STA_IND_MEMSET 30261 +#define PID_RLC_STA_IND_PRC 30262 +#define PID_RLC_KWUDAT_IND 30263 +#endif +#define PID_RLC_UM_REEST 30264 +#define PID_RLC_AM_RLC_UE_DEL 30260 +#define PID_RLC_AM_QSDU 30261 +#define PID_RLC_TM_CSTAIND_SUCCESS 30265 +#define PID_RLC_TM_CSTAIND_FAIL 30266 +#define PID_RLC_TM_SEARCH_RNTI 30267 +#define PID_RLC_TM_QSDU 30268 + +/* UL IP THROUGHPUT PROFILING */ +#define PID_RLC_IP_TPT_INCTTI 30269 +#define PID_RLC_IP_TPT_INCVOL 30270 +#define PID_RLC_MEAS_REPORT 30271 +#define PID_RLC_MEAS_START 30272 +#define PID_RLC_MEAS_STOP 30273 +/* Discard SDU Profiling */ +#define PID_RLC_AMM_REASSEMBLE_SDUS 30274 +#define PID_RLC_AMM_DISC_SDUS 30275 +#define PID_RLC_UMM_REASSEMBLE_SDUS 30276 +#define PID_RLC_UMM_DISC_SDUS 30277 + +/* DL IP THROUGHPUT PROFILING */ +#define PID_RLC_DLIP_TPT_BURSTCALC 30278 +#define PID_RLC_DLIP_TPT_PRCHARQIND 30279 + +#define PID_MT_AM_SVSR_HDLR 30008 +#define PID_MT_AM_SVS_MSG 30009 +#define PID_MAC_AM_HARQ_RLS 30010 +#define PID_PDCP_DL_PKT 30280 +#define PID_PDCP_DAT_IND 30281 +#define PID_PDCP_CFG_REQ 30282 +#define PID_PDCP_CFG_REQ_REEST 30283 +#define PID_PDCP_CFG_REQ_REM 30284 +#define PID_PDCP_CFG_UE_DELETE 30285 + +#define PID_CM_PRC_TMR 30286 + +/* The below range is for detailed analysis of common functions */ +#define PID_SAddPstMsgMult 30600 +#define PID_SAddPreMsgMult 30601 +#define PID_SRemPreMsgMult 30602 +#define PID_SRemPstMsgMult 30603 +#define PID_SGetDataFrmMsg 30604 +#define PID_SSegMsg 30605 +#define PID_SCpyFixMsg 30607 +#define PID_SCpyMsgFix 30608 +#define PID_SCpyMsgMsg 30610 +#define PID_SAddMsgRef 30609 +#define PID_SCatMsg 30611 +#define PID_SCompressMsg 30612 +#define PID_SGetPstMsgMult 30613 +#define PID_SSwapMsg 30614 +#define PID_SCpyPartMsg 30615 +#define PID_SRepPartMsg 30616 +#define PID_SPkMsgMult 30617 +#define PID_SMovPartMsg 30618 + +#define PID_L2_PROCESSING 30998 /* Processing for all L2 tasks on CPU3 */ + +/* This captures all the processing invoked through PHY */ +#define PID_PHY_RCV_PROC 30999 + +#ifdef MSPD +#ifdef SS_4GMX_LCORE +#define RB_GET_CALLER() (__return_address()-4) +#define RB_GET_SP() (__current_sp()) +#define RB_TRC() rbCallstackPush(RB_GET_CALLER(), RB_GET_SP()) +#define RB_TRC_RET() rbCallstackPop(); +#endif + +#ifdef TENB_T2K3K_SPECIFIC_CHANGES +#ifndef XEON_SPECIFIC_CHANGES +#include "tl.h" +#else +#include "mlog_com.h" +#endif + +#define RESOURCE_LINL2 RESOURCE_L2 +#define RESOURCE_LARM RESOURCE_L2 +#ifndef XEON_SPECIFIC_CHANGES +#define GetTIMETICK() TL_MLOG_TICK +#else +#define GetTIMETICK() 0 +#endif +#ifdef PHY_SHUTDOWN_ENABLE +#define stop_printf(...) do {EXTERN U8 sndPhyShutDwn;printf(__VA_ARGS__); mtStopHndlr(); sndPhyShutDwn = 1;} while (0) +#else +#define stop_printf(...) do {printf(__VA_ARGS__); mtStopHndlr(); exit(-1);} while (0) +#endif +#define uart_printf(...) printf(__VA_ARGS__) +#ifdef XEON_SPECIFIC_CHANGES +#define MLogTask(a, b, c, d) tlMlogTask(a, c, d) +#else +#define MLogTask tlMlogTask +#endif +#define MLogAddVariables(a, b, c) +#define rbCallstackShow() +#define Ad9361RadioInit(a,b,c,d) 0 + +#ifndef CA_PHY +#define SS_MLOG_BUF_SIZE 1591328 +#else +#define SS_MLOG_BUF_SIZE 7175200 +#endif +#define SS_MEMLOG_MAXSTRLEN 256 + +#ifdef MS_MUBUF_CORRUPTION /* Should be enabled when debugging mbuf corruption */ +#define MS_BUF_ADD_CALLER()\ +{\ + extern U32 cmFreeCaller[4];\ + if(cmFreeCaller[MxGetCpuID()] == NULLP)\ + cmFreeCaller[MxGetCpuID()] = __return_address()-4;\ +} +#endif /* */ +#endif +#endif/* MSPD */ + +#ifdef BRDCM +extern char logBuf[100]; +extern int glbTime; +#define BRDCM_PROF(s) do {\ +} while(0) + +#define PID_CRC_IND_START 3000 +#define PID_CRC_IND_END 3001 +#define PID_CL_CNTRL_REQ_START 3002 +#define PID_CL_CNTRL_REQ_END 3003 +#define PID_CL_DAT_REQ_START 3004 +#define PID_CL_DAT_REQ_END 3005 +#define PID_CL_RECP_REQ_START 3006 +#define PID_CL_RECP_REQ_END 3007 +#define PID_CL_SEND_TO_PHY_START 3008 +#define PID_CL_SEND_TO_PHY_END 3009 +#define PID_CL_RXSDU_IND_START 3010 +#define PID_CL_RXSDU_IND_END 3011 +#define PID_MAC_TTI_IND_START 3400 +#define PID_MAC_TTI_IND_END 3401 +#define PID_SCH_TTI_IND_START 3402 +#define PID_SCH_TTI_IND_END 3403 +#define PID_MAC_DAT_IND_START 3404 +#define PID_MAC_DAT_IND_END 3405 +#define PID_MAC_SF_ALLOC_REQ_START 3406 +#define PID_MAC_SF_ALLOC_REQ_END 3407 +#define PID_MAC_STA_RSP_START 3408 +#define PID_MAC_STA_RSP_END 3409 +#define PID_MAC_CMN_STA_RSP_START 3410 +#define PID_MAC_CMN_STA_RSP_END 3411 +#define PID_MAC_DL_SCHD_START 3412 +#define PID_MAC_DL_SCHD_END 3413 +#define PID_MAC_DL_CQI_IND 30205 +#define PID_MAC_UL_CQI_IND 30206 +#define PID_MAC_SR_IND 30207 +#define PID_MAC_HARQ_IND 30208 +#define PID_MAC_TA_IND 30209 +#define PID_MAC_UL_SCHD 30210 +#define PID_MAC_TTI_IND 30211 +#define PID_MAC_UE_CFG 30212 +#define PID_MAC_UE_RECFG 30213 +#define PID_MAC_UE_DEL 30214 +#define PID_MAC_UE_RST 30215 +#define PID_SCH_UE_CFG 30216 +#define PID_SCH_UE_RECFG 30217 +#define PID_SCH_UE_DEL 30218 +#define PID_SCH_UE_RST 30219 +#define PID_MAC_DDATREQ 30220 +#define PID_MAC_FILLDREQ 30221 +#define PID_MAC_TFUDREQ 30222 +#define PID_SCHUTL_CMALLCEVT 30223 +#define PID_TOMUTL_CMALLCEVT 30224 +#define PID_TOMINF_CMALLCEVT 30225 +#define PID_MACUTL_CMALLCEVT 30226 +#define PID_SCH_DUMMY_TTI_IND 30227 +#define PID_MAC_TFU_DATIND 30228 +#define PID_RLC_STA_IND 30240 +#define PID_RLC_REASSEMBLY 30241 +#define PID_RLC_AM_SELF_PST_DL 30242 +#define PID_RLC_AM_PDU_RLS 30243 +#define PID_RLC_CHK_SDU_MAP 30244 +#define PID_RLC_SND_DAT_CFM 30245 +#define PID_RLC_AM_SELF_PDU_RSMBL 30246 +#define PID_RLC_AM_RGU_DATIND 30247 +#define PID_RLC_AM_ADDTOLIST_UL 30248 +#define PID_RLC_AM_FREEBUF 30249 +#define PID_RLC_AM_RETXLIST 30250 +#define PID_RLC_AM_POST_ULSELFMSG 30251 +#define PID_RLC_AM_UTL_RSMBL 30252 +#define PID_RLC_AM_STA_PDU 30253 +#define PID_RLC_CFG_REQ 30254 +#define PID_RLC_CFG_REQ_REEST 30255 +#define PID_RLC_CFG_REQ_REM 30256 +#define PID_RLC_AM_RLSPDUSET 30257 +#define PID_RLC_AM_RLSPDUSET_DATA 30258 +#define PID_RLC_AM_RLSPDUSET_REEST 30259 +#define PID_RLC_AM_RLC_UE_DEL 30260 +#define PID_RLC_AM_QSDU 30261 +#define PID_MT_AM_SVSR_HDLR 30008 +#define PID_MT_AM_SVS_MSG 30009 +#define PID_MAC_AM_HARQ_RLS 30010 +#define PID_RLC_KWUDAT_IND 30012 +#define PID_RLC_STA_IND_MEMSET 30014 +#define PID_RLC_STA_IND_PRC 30015 +#define PID_PDCP_DL_PKT 30280 +#define PID_PDCP_DAT_IND 30281 +#define PID_PDCP_CFG_REQ 30282 +#define PID_PDCP_CFG_REQ_REEST 30283 +#define PID_PDCP_CFG_REQ_REM 30284 +#define PID_SAddPstMsgMult 30600 +#define PID_SAddPreMsgMult 30601 +#define PID_SRemPreMsgMult 30602 +#define PID_SRemPstMsgMult 30603 +#define PID_SGetDataFrmMsg 30604 +#define PID_SSegMsg 30605 +#define PID_SCpyFixMsg 30607 +#define PID_SCpyMsgFix 30608 +#define PID_SCpyMsgMsg 30610 +#define PID_SAddMsgRef 30609 +#define PID_SCatMsg 30611 +#define PID_SCompressMsg 30612 +#define PID_SGetPstMsgMult 30613 +#define PID_SSwapMsg 30614 +#define PID_SCpyPartMsg 30615 +#define PID_SRepPartMsg 30616 +#define PID_SPkMsgMult 30617 +#define PID_SMovPartMsg 30618 +#define PID_cmUnpkHitUDatInd_START 3300 +#define PID_cmUnpkHitUDatInd_END 3301 +#define PID_cmPkPjuDatReq_START 3310 +#define PID_cmPkPjuDatReq_END 3311 +#endif /* BRDCM */ +#endif /* __SSIH__ */ +/* ssi_h_001.main_120 */ + +/********************************************************************30** + + End of file +**********************************************************************/ diff --git a/src/cm/ssi.x b/src/cm/ssi.x new file mode 100755 index 000000000..422a2d919 --- /dev/null +++ b/src/cm/ssi.x @@ -0,0 +1,1743 @@ +/******************************************************************************* +################################################################################ +# Copyright (c) [2017-2019] [Radisys] # +# # +# 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. # +################################################################################ +*******************************************************************************/ + +/********************************************************************20** + + Name: system services interface + + Type: C include file + + Desc: Structures, variables and typedefs required by the + System Services service user. + + File: ssi.x + +*********************************************************************21*/ + +#ifndef __SSIX__ +#define __SSIX__ + +#ifdef __cplusplus +extern "C" { +#endif + + + +/* typedefs */ + +typedef S16 Status; /* status */ + +typedef U32 Ticks; /* system clock ticks */ + +#ifdef LONG_MSG +typedef S32 MsgLen; /* message length */ +#else +typedef S16 MsgLen; /* message length */ +#endif + +typedef S16 Order; /* message or queue order */ + +#ifdef DOS +typedef U16 Size; /* size (for number of bytes per region or per s-pool) */ +#else +typedef U32 Size; /* size (for number of bytes per region or per s-pool) */ +typedef S32 PtrOff; /* signed pointer offset */ +#endif + +typedef U32 QLen; /* queue length */ + +typedef QLen BufQLen; /* buffer queue length */ + +typedef S16 RegSize; /* region size (for number of regions per processor) */ + +typedef S16 DPoolSize; /* dynamic pool size (for number of buffers per d-pool) */ + +typedef U16 Random; /* random number */ + +typedef S16 Seq; /* sequence */ +/* ssi_x_001.main_64 Additions */ +typedef U32 CoreId; /* core id */ + +/* Error */ +typedef U32 ErrCls; /* Error Class */ + +typedef U32 ErrCode; /* Error Code */ + +typedef U32 ErrVal; /* Error Value */ + +typedef S16 VectNmb; /* vector number */ + +typedef S16 Ttype; /* task type */ + +typedef S8 Sema; /* semaphore */ + + +/* post */ + + +/* + This section contains specific typedefs, structures and + prototypes for the following operating systems: + + MOS - MOSVER + MOS, v2 - MSVER2 + psos - PS + vrtxsa - VX + vxworks - VW + sslib - system service library for elvis + other - + + The defines PORTVER, MOSVER and MSVER2 are mutually exclusive. The define PORTVER + must be set in conjunction with the define PS, VX, VW or other. + +*/ + + +#ifdef MOSVER /* mos version */ +/* mos typedefs, structures and prototypes */ + +/* forward definitions */ + +#ifndef CMFILE_REORG_1 +typedef struct ss_buffer Buffer; /* forward definition - buffer */ +#endif + +typedef struct ss_queue Queue; /* forward definition - queue */ + +/* chain */ + +typedef struct chn /* chain */ +{ + Buffer *fwd; /* forward */ + Buffer *bck; /* backward */ +} Chn; + +typedef Chn Chain; /* chain */ + +/* queue - typdef'd earlier */ + +struct ss_queue /* queue - typdef'd earlier */ +{ + Chn chn; /* chain */ + QLen crntSize; /* current size */ + QLen maxSize; /* maximum size */ +}; + +/* buffer - typedef'd earlier */ + +struct ss_buffer /* buffer - typdef'd earlier */ +{ + Chn chn; /* chain */ + Mem mem; /* memory */ + S8 bufType; /* buffer type */ + union { + + struct + { + MsgLen strtIdx; /* start index */ + MsgLen endIdx; /* end index */ + MsgLen size; /* size */ + Data data[DSIZE]; /* data */ + } dat; /* data buffer */ + + struct + { + Queue bq; /* buffer queue */ + MsgLen msgLen; /* message length */ + S16 refCnt; /* reference count */ + Pst pst; /* post (optional) */ + U32 wsU32[2]; /* workspace unsigned 32 bit values (optional) */ + U16 wsU16[1]; /* workspace unsigned 16 bit values (optional) */ + U8 wsU8[2]; /* workspace unsigned 8 bit values (optional) */ + } msg; /* message buffer */ + + struct + { + Buffer *entry[MAXEXTENT];/* entry */ + } ext; /* extension buffer */ + + struct + { + Size size; /* size */ + } stc; /* static buffer */ + + struct + { + MsgLen strtIdx; /* start index */ + MsgLen endIdx; /* end index */ + MsgLen size; /* size */ + Data *data; /* data pointer */ + } dma; /* dma buffer */ + + } t; +}; + +EXTERN S16 msOptInd; +EXTERN S8 *msOptArg; +EXTERN Txt **msArgv; +EXTERN S16 msArgc; + +#else +#ifdef MSVER2 /* mos version 2 */ + +/* forward definitions */ +#ifndef CMFILE_REORG_1 +typedef struct ss_buffer Buffer; /* forward definition - buffer */ +#endif + +typedef struct sBuf SBuf; /* forward definition - static buffer */ + +typedef struct ss_queue Queue; /* forward definition - queue */ + +/* buffer identifier */ + +/* dynamic chain (4b ALIGNED) */ + +typedef struct dChn /* dynamic chain */ +{ + Buffer *prev; /* previous */ + Buffer *crnt; /* current */ + Buffer *next; /* next */ +} DChn; + +/* static chain (4b ALIGNED)*/ + +typedef struct sChn /* static chain */ +{ + SBuf *fwd; /* forward */ +} SChn; + +/* buffer queue (4b ALIGNED) */ + +typedef struct bufQ /* buffer queue */ +{ + DChn dChn; /* dynamic chain */ + BufQLen crntSize; /* current size */ +} BufQ; +/* queue (4b ALIGNED) */ + +struct ss_queue /* queue - typdef'd earlier */ +{ + DChn dChn; /* dynamic chain */ + QLen crntSize; /* current size */ +}; + +/* 4Byte aligned */ +typedef struct ss_dat /* data buffer */ +{ + MsgLen strtIdx; /* start index (2b) */ + MsgLen endIdx; /* end index (2b) */ + MsgLen size; /* size (2b) */ + Pool pool; /* size (1b); Not used for MOS as of now */ + U8 spare; /* spare for alignment (1b) */ + Data data[DSIZE]; /* data (4b) */ +} Dat; + +/* 4Byte aligned */ +typedef struct ss_msg /* message buffer */ +{ + Queue bufQ; /* buffer queue */ + Buffer *nxtDBuf; /* next DBuf */ + MsgLen msgLen; /* message length */ + Pool pool; /* size (1b); Not used for MOS as of now */ + U8 spare; /* spare for alingment */ +} Msg; + +/* buffer - typedef'd earlier */ + +struct ss_buffer /* buffer - typedef'd earlier */ +{ + DChn dChn; /* dynamic chain */ + S8 bufType; /* buffer type */ + U8 spare1; /* spare for alignment */ + U16 spare2; /* spare for alignment */ + union { + Dat dat; /* data buffer */ + Msg msg; /* message buffer */ + } t; +}; + +/* static buffer - typedef'd earlier */ + +struct sBuf /* static buffer - typedef'd earlier */ +{ + SChn sChn; /* static chain */ + Size size; /* size */ + S8 bufType; /* buffer type */ + U8 spare1; /* spare 1 */ + U16 spare2; /* spare 2 */ +}; + +EXTERN S16 msOptInd; +EXTERN S8 *msOptArg; +EXTERN Txt **msArgv; +EXTERN S16 msArgc; + +#else +#ifdef PS /* psos version */ +/* psos typedefs, structures and prototypes */ + +/* forward definitions */ + +#ifndef CMFILE_REORG_1 +typedef struct ss_buffer Buffer; /* forward definition - buffer */ +#endif + +typedef struct ss_queue Queue; /* forward definition - queue */ + +/* chain */ + +typedef struct chn /* chain */ +{ + Buffer *fwd; /* forward */ + Buffer *bck; /* backward */ +} Chn; + +/* queue - typdef'd earlier */ + +struct ss_queue /* queue - typdef'd earlier */ +{ + Chn chn; /* chain */ + QLen crntSize; /* current size */ + QLen maxSize; /* maximum size */ +}; + +/* buffer - typedef'd earlier */ + +struct ss_buffer /* buffer - typedef'd earlier */ +{ + Chn chn; /* chain */ + Mem mem; /* memory */ + S8 bufType; /* buffer type */ + union { + + struct + { + MsgLen strtIdx; /* start index */ + MsgLen endIdx; /* end index */ + MsgLen size; /* size */ + Data data[DSIZE]; /* data */ + } dat; /* data buffer */ + + struct + { + Queue bq; /* buffer queue */ + MsgLen msgLen; /* message length */ + S16 refCnt; /* reference count */ + } msg; /* message buffer */ + + struct + { + Buffer *entry[MAXEXTENT];/* entry */ + } ext; /* extension buffer */ + + struct + { + Size size; /* size */ + } stc; /* static buffer */ + + struct + { + MsgLen strtIdx; /* start index */ + MsgLen endIdx; /* end index */ + MsgLen size; /* size */ + Data *data; /* data pointer */ + } dma; /* dma buffer */ + + } t; +}; + +#else +#ifdef VX /* vrtxsa version */ +/* vrtxsa typedefs, structures and prototypes */ + +/* forward definitions */ + +#ifndef CMFILE_REORG_1 +typedef struct ss_buffer Buffer; /* forward definition - buffer */ +#endif + +typedef struct ss_queue Queue; /* forward definition - queue */ + +/* buffer - typedef'd earlier */ + +struct ss_buffer /* buffer - typedef'd earlier */ +{ + Buffer *fwd; /* forward chain pointer for queues */ + Buffer *bck; /* backward chain pointer for queues */ + U16 mPid; /* VRTXsa memory partition ID */ + S16 start; /* starting index of message in byte array */ + S16 end; /* ending index of message in byte array */ + U16 status; /* buffer status */ +}; + +/* chain */ + +typedef struct chn /* chain */ +{ + Buffer *fwd; /* forward */ + Buffer *bck; /* backward */ +} Chn; + +/* queue - typdef'd earlier */ + +struct ss_queue /* queue - typdef'd earlier */ +{ + Chn chn; /* chain */ + QLen crntSize; /* current size */ + QLen maxSize; /* maximum size */ +}; + +#else +#ifdef VW /* vxworks version */ +/* vxworks typedefs, structures and prototypes */ + +/* forward definitions */ + +#ifndef CMFILE_REORG_1 +typedef struct ss_buffer Buffer; /* forward definition - buffer */ +#endif + +typedef struct ss_queue Queue; /* forward definition - queue */ + +typedef struct dChn /* dynamic chain */ +{ + Buffer *prev; /* previous */ + Buffer *crnt; /* current */ + Buffer *next; /* next */ +} DChn; + +/* static chain (4b ALIGNED)*/ + +/* buffer queue (4b ALIGNED) */ + +typedef struct bufQ /* buffer queue */ +{ + DChn dChn; /* dynamic chain */ + BufQLen crntSize; /* current size */ +} BufQ; + +/* queue (4b ALIGNED) */ + +struct ss_queue /* queue - typdef'd earlier */ +{ + DChn dChn; /* dynamic chain */ + QLen crntSize; /* current size */ +}; + +typedef struct ss_dat /* data buffer */ +{ + MsgLen strtIdx; /* start index */ + MsgLen endIdx; /* end index */ + MsgLen size; /* size */ + Pool pool; /* pool id */ + U8 spare; /* spare */ + Data *data; /* data */ +} Dat; + +typedef struct ss_msg /* message buffer */ +{ + Queue bufQ; /* buffer queue */ + Buffer *nxtDBuf; /* next DBuf */ + MsgLen msgLen; /* message length */ + Pool pool; /* pool id */ + U8 spare; /* spare */ +} Msg; + +/* buffer - typedef'd earlier */ + +struct ss_buffer /* buffer - typedef'd earlier */ +{ + DChn dChn; /* dynamic chain */ + S8 bufType; /* buffer type */ + U8 spare1; /* spare for alignment */ + U16 spare2; /* spare for alignment */ + union { + Dat dat; /* data buffer */ + Msg msg; /* message buffer */ + } t; +}; + +#else +#ifdef SSLIB /* system service library */ +/* forward definitions */ +#ifndef CMFILE_REORG_1 +typedef struct ss_buffer Buffer; /* forward definition - buffer */ +#endif + +typedef struct sBuf SBuf; /* forward definition - static buffer */ + +typedef struct ss_queue Queue; /* forward definition - queue */ + + +/* queue - typdef'd earlier */ + +struct ss_queue /* queue - typdef'd earlier */ +{ + S16 dummy; /* dummy placeholder */ +}; + +/* buffer - typedef'd earlier */ + +struct ss_buffer /* buffer - typedef'd earlier */ +{ + S32 sIdx; /* start index */ + S32 len; /* buffer length */ + S8 dat[MAXBUFSIZ]; /* data */ +}; + +#else /* portable/other version */ +#ifdef SSRYLIB /* system service library */ +/* forward definitions */ +#ifndef CMFILE_REORG_1 +typedef struct ss_buffer Buffer; /* forward definition - buffer */ +#endif + +typedef struct sBuf SBuf; /* forward definition - static buffer */ + +typedef struct ss_queue Queue; /* forward definition - queue */ + + +typedef S16 RyBufId; +/* dynamic chain (aligned) */ +typedef struct ryDChn /* dynamic chain */ +{ + RyBufId back; /* backward (2b) */ + RyBufId crnt; /* current (2b) */ + RyBufId next; /* next (2b) */ + RyBufId pad; /* pad (2b) */ +} RyDChn; +/* + * queue - typdef'd earlier + * This is exactly same as RyBufQ + */ +struct ss_queue /* queue - typdef'd earlier */ +{ + RyDChn dChn; + QLen crntSize; /* current size */ + U16 ryChanId; /* relay channel Id */ +}; + +/* buffer - typedef'd earlier */ + +struct ss_buffer /* buffer - typedef'd earlier */ +{ + S32 sIdx; /* start index */ + S32 len; /* buffer length */ + S8 dat[MAXBUFSIZ]; /* data */ +}; + +#else /* portable/other version */ +#ifdef WINNT_IATM /* Windows NT Integrated ATM */ + +#ifndef CMFILE_REORG_1 +#ifndef CFG_APP /* Don't include ndis.h for config app. */ +#include "ndis.h" /* to support NDIS calls (listed above) */ +#endif /* CFG_APP */ + +typedef struct _NDIS_PACKET Buffer; /* forward definition - buffer */ + +#endif /* CMFILE_REORG_1 */ + +typedef struct ss_queue Queue; /* forward definition - queue */ + +/* Trillium Queue is built upon the NDIS library list functions. + * No spin locks are applied for queues. + */ + +struct ss_queue { + LIST_ENTRY ListHead; /* LIST_ENTRY to support NDIS list calls */ + QLen CurQLen; /* current queue length */ + QLen MaxQLen; /* maximum queue length */ +}; +#else /* WINNT_IATM */ +#ifdef MT /* multi-threaded version */ +/* multi-threaded typedefs, structures and prototypes */ + +/* forward definitions */ + +#ifndef CMFILE_REORG_1 +typedef struct ss_buffer Buffer; /* forward definition - buffer */ +#endif + +typedef struct ss_queue Queue; /* forward definition - queue */ + +typedef struct sBuf SBuf; /* forward definition - static buffer */ + +typedef struct dChn /* dynamic chain */ +{ + Buffer *prev; /* previous */ + Buffer *crnt; /* current */ + Buffer *next; /* next */ +} DChn; + +/* static chain (4b ALIGNED)*/ +typedef struct sChn +{ + SBuf *fwd; /* forward */ +} SChn; + +/* static chain (4b ALIGNED)*/ + +/* buffer queue (4b ALIGNED) */ + +/* queue (4b ALIGNED) */ + +struct ss_queue /* queue - typdef'd earlier */ +{ + DChn dChn; /* dynamic chain */ + QLen crntSize; /* current size */ +}; + +typedef struct ss_dat /* data buffer */ +{ + MsgLen strtIdx; /* start index */ + MsgLen endIdx; /* end index */ + MsgLen size; /* size */ + Pool pool; /* pool id */ + U8 spare; /* spare */ + Data *data; /* data */ +} Dat; + +typedef struct ss_msg /* message buffer */ +{ + Queue bufQ; /* buffer queue */ + Buffer *nxtDBuf; /* next DBuf */ + MsgLen msgLen; /* message length */ + Pool pool; /* pool id */ + U8 spare; /* spare */ +} Msg; + +/* buffer - typedef'd earlier */ + +struct ss_buffer /* buffer - typedef'd earlier */ +{ + DChn dChn; /* dynamic chain */ + S8 bufType; /* buffer type */ + U8 spare1; /* spare for alignment */ + U16 spare2; /* spare for alignment */ + union { + Dat dat; /* data buffer */ + Msg msg; /* message buffer */ + } t; +}; + +/* static buffer - typedef'd earlier */ + +struct sBuf +{ + SChn sChn; /* static chain */ + Size size; /* size */ + S8 bufType; /* buffer type */ + U8 spare1; /* spare 1 */ + U16 spare2; /* spare 2 */ +}; + +typedef S32 MtRwLockId; +typedef S32 MtSemaId; +typedef S32 MtCondId; +typedef S32 MtMtxId; +typedef S32 MtThrdId; +typedef S32 MtThrdFlags; +typedef S32 MtThrdPrior; + +typedef Void *(MtThrd) ARGS((Void *)); + +#else /* not MT */ +#ifdef PORTVER +/* portable typedefs, structures and prototypes */ + +/* forward definitions */ + +#ifndef CMFILE_REORG_1 +typedef struct ss_buffer Buffer; /* forward definition - buffer */ +#endif + +typedef struct ss_queue Queue; /* forward definition - queue */ + +/* queue - typdef'd earlier */ + +struct ss_queue /* queue - typdef'd earlier */ +{ + S16 dummy; /* dummy placeholder */ +}; + +/* buffer - typedef'd earlier */ + +struct ss_buffer /* buffer - typedef'd earlier */ +{ + S16 dummy; /* dummy placeholder */ +}; + +/* task related stuff */ +/* data range modified */ +#ifndef SS_MULTIPLE_PROCS +typedef U8 SSTskId; /* System Task Id */ +#else /* SS_MULTIPLE_PROCS */ +typedef U16 SSTskId; /* System Task Id */ +#endif /* SS_MULTIPLE_PROCS */ + +typedef S32 SSTskPrior; /* System Task Priority */ +#ifdef SS_AEHDPR_SUPPORT +typedef Void (*PISR) ARGS((PTR cxt)); /* pointer to ISR function handler */ +typedef Void (*PDPR) ARGS((PTR cxt)); /* pointer to DPR function handler */ +#endif /* SS_AEHDPR_SUPPORT */ +#else /* not PORTVER */ +#ifdef SS /* Common System Services */ + +/* for SGetOpt() */ +EXTERN S16 msOptInd; +EXTERN S8 *msOptArg; +EXTERN Txt **msArgv; +EXTERN S16 msArgc; + +/* task related stuff */ +/* data range modified */ +#ifndef SS_MULTIPLE_PROCS +typedef U8 SSTskId; /* System Task Id */ +#else /* SS_MULTIPLE_PROCS */ +typedef U16 SSTskId; /* System Task Id */ +#endif /* SS_MULTIPLE_PROCS */ + +typedef S32 SSTskPrior; /* System Task Priority */ + +#ifndef CMFILE_REORG_1 + +/* Buffer type is necessary */ +typedef struct ssmsgb Buffer; + +#endif /* CMFILE_REORG_1 */ + +/* message block */ +struct ssmsgb +{ + S8 refCnt; /* Counter to Free Buff */ + struct ssmsgb *b_next; /* next message */ + struct ssmsgb *b_prev; /* previous message */ + struct ssmsgb *b_cont; /* next message block */ + U8 *b_rptr; /* 1st unread data byte of buffer */ + U8 *b_wptr; /* 1st unwritten data byte of buffer */ + struct ssdatab *b_datap; /* pointer to data block */ +}; + +/* Queue data structure */ +typedef struct ssQueue +{ + Buffer *head; /* head of queue */ + Buffer *tail; /* tail of queue */ + QLen crntSize; /* current szie of queue */ + +} Queue; + + +/* Memory CTL operations structure */ +typedef struct sMemCtl +{ + U8 op; /* operation */ + + union + { + struct + { + Data *vaddr; /* virtual address */ + Data **paddr; /* physical address */ + } vtop; + + struct + { + Size size; /* size */ + Status *status; /* status */ + } chkres; + } u; + +} SMemCtl; + + +/* memory management handler function types */ +/* ssi_x_001.main_47 - addition for introducing additional parameter memType(static/dynamic) */ +/* ssi_x_001.main_57 : Additions */ +#ifdef SS_HISTOGRAM_SUPPORT +#ifdef SSI_DEBUG_LEVEL1 +typedef S16 (*SsAlloc) ARGS((Void *, Size *, U32, Data **, U32, U32, U8*, U8, Bool)); +#else +typedef S16 (*SsAlloc) ARGS((Void *, Size *, U32, Data **, U32, U8*, U8, Bool)); +#endif /* SSI_DEBUG_LEVEL1 */ +typedef S16 (*SsFree) ARGS((Void *, Data *, Size, U32, U8*, U8, Bool)); +typedef S16 (*SsCtl) ARGS((Void *, Event, SMemCtl *)); +#elif defined(SS_LIGHT_MEM_LEAK_STS) +typedef S16 (*SsAlloc) ARGS((Void *, Size *, U32 , Data **, U32, U32 , U8 *)); +typedef S16 (*SsFree) ARGS((Void *, Data *, Size, U32, U8 *)); +typedef S16 (*SsCtl) ARGS((Void *, Event, SMemCtl *)); +#else +#ifdef SSI_DEBUG_LEVEL1 +typedef S16 (*SsAlloc) ARGS((Void *, Size *, U32, Data **, U32)); +#else +#ifdef T2K_MEM_LEAK_DBG +typedef S16 (*SsAlloc) ARGS((Void *, Size *, U32, Data **,char*, U32)); +#else +typedef S16 (*SsAlloc) ARGS((Void *, Size *, U32, Data **)); +#endif +#endif /* SSI_DEBUG_LEVEL1 */ +#ifdef T2K_MEM_LEAK_DBG +typedef S16 (*SsFree) ARGS((Void *, Data *, Size,char*, U32)); +#else +typedef S16 (*SsFree) ARGS((Void *, Data *, Size)); +#endif +typedef S16 (*SsCtl) ARGS((Void *, Event, SMemCtl *)); +#endif /* SS_HISTOGRAM_SUPPORT */ + + +/* region information structure -- passed to SRegRegion() */ +typedef struct sRegInfo +{ + Void *regCb; /* region control block pointer */ + U32 flags; /* region characteristics flags */ +/* ssi_x_001.main_64 Additions */ +#ifdef SS_CAVIUM + cvmx_arena_list_t regArena; /* arena for the region */ +#endif + Data *start; /* start address of region */ + Size size; /* size of region */ + SsAlloc alloc; /* allocation function pointer */ + SsFree free; /* deallocation function pointer */ + SsCtl ctl; /* control request function pointer */ + +} SRegInfo; + + +#ifdef SS_OLD_THREAD + +/* types for SGetThread(), SGetMutex, etc. */ +typedef Void *(SThrd) ARGS((Void *)); + +typedef S32 SThrdId; /* thread Id */ +typedef S32 SMtxId; /* mutex Id */ +typedef S32 SCondId; /* condition Id */ + +#endif /* SS_OLD_THREAD */ + +/*ssi_x_001.main_63 ss_dep.x guarded under flag*/ +#ifdef SS_CAVIUM +#include "jz_dep.x" +#else +#ifdef SS_4GMX_LCORE +#include "ss_dep.x" +#else +#include "ss_dep.x" +#endif /* SS_4GMX_LCORE */ +#endif/*SS_CAVIUM*/ + +#endif /* SS */ +#endif /* PORTVER */ +#endif /* MT */ +#endif /* WINNT_IATM */ +#endif /* SSRYLIB */ +#endif /* SSLIB */ +#endif /* VW */ +#endif /* VX */ +#endif /* PS */ +#endif /* MSVER2 */ +#endif /* MOSVER */ +/* ssi_x_001.main_57 : Additions */ +#ifdef SS_HISTOGRAM_SUPPORT +/* +typedef struct entInfo +{ + U8 entid; +}EntInfo; + +typedef struct secondIndex +{ + EntInfo info[26]; +}SecondIndex; + +typedef struct firstIndex +{ + SecondIndex info[26]; +}FirstIndex; */ +#endif /* SS_HISTOGRAM_SUPPORT */ + + +/* functions */ + +/* procId and control block added */ +#ifndef SS_MULTIPLE_PROCS +typedef S16 (*PAIFS16) ARGS((Ent ent,Inst inst,Region region,Reason reason )); +/* ssi_x_001.main_54 */ +/* ssi_x_001.main_53 */ +/* ssi_x_001.main_69: Removed the SS_MT_TMR guard from PAIFTMRS16 + timer activation function typedef. */ + +typedef S16 (*PAIFTMRS16) ARGS((Ent ent, Inst inst)); +#else +typedef S16 (*PAIFS16) ARGS((ProcId proc, + Ent ent, + Inst inst, + Region region, + Reason reason, + Void **xxCb)); + +/* time activation function typedef */ +typedef S16 (*PAIFTMRS16) ARGS((ProcId proc, + Ent ent, + Inst inst)); +#endif /* SS_MULTIPLE_PROCS */ + +#ifndef VX +typedef S16 (*PATFS16) ARGS((Prior prior,Route route,Ent ent,Inst inst,Buffer *mBuf)); +#else +typedef void (*PATFS16) ARGS((void *vPtr)); +#endif +typedef S16 (*ActvTsk) ARGS((Pst *pst, Buffer *mBuf)); +#ifdef ENB_RELAY +typedef struct uProc UProc; /* forward definition - uproc */ +#ifdef RYINT1 +typedef void (*ISTsk) ARGS((Inst inst)); +#else /* for backward compatibility */ +typedef void (*ISTsk) ARGS((UProc *uProc)); +#endif /* RYINT1 */ + +struct uProc +{ + Inst inst; /* instance */ + ProcId low; /* procId low value */ + ProcId high; /* procId high value */ + ActvTsk actvTsk; /* activation function for drvr task */ + U16 isFlag; /* interrupt service flag */ + ISTsk isTsk; /* interrupt service task */ +}; + + +#endif /* ENB_RELAY */ + + +/* functions */ +EXTERN S16 SChekMemUtilization ARGS((Region region,Bool *memAlarm)); + +EXTERN Void prntMem ARGS((Data *strtAdr,S16 len)); +EXTERN Void prntMsg ARGS((Buffer *mBuf)); +EXTERN Void prntMsg1 ARGS((Buffer *mBuf,S16 src,S16 dst)); +EXTERN S16 tst ARGS((void )); +EXTERN S16 rdConQ ARGS((Data data)); + +EXTERN S16 SPkS8 ARGS((S8 val,Buffer *mBuf)); +EXTERN S16 SPkU8 ARGS((U8 val,Buffer *mBuf)); +EXTERN S16 SPkS16 ARGS((S16 val,Buffer *mBuf)); +EXTERN S16 SPkU16 ARGS((U16 val,Buffer *mBuf)); +EXTERN S16 SPkS32 ARGS((S32 val,Buffer *mBuf)); +EXTERN S16 SPkU32 ARGS((U32 val,Buffer *mBuf)); +/* ssi_x_001.main_49 : added packing of F32 and F64*/ +#ifdef SS_FLOAT +EXTERN S16 SPkF32 ARGS((F32 val,Buffer *mBuf)); +EXTERN S16 SPkF64 ARGS((F64 val,Buffer *mBuf)); +#endif /* SS_FLOAT */ +EXTERN S16 SUnpkS8 ARGS((S8 *val,Buffer *mBuf)); +EXTERN S16 SUnpkU8 ARGS((U8 *val,Buffer *mBuf)); +EXTERN S16 SUnpkS16 ARGS((S16 *val,Buffer *mBuf)); +EXTERN S16 SUnpkU16 ARGS((U16 *val,Buffer *mBuf)); +EXTERN S16 SUnpkS32 ARGS((S32 *val,Buffer *mBuf)); +EXTERN S16 SUnpkU32 ARGS((U32 *val,Buffer *mBuf)); +/* ssi_x_001.main_49 : added unpacking of F32 and F64*/ +#ifdef SS_FLOAT +EXTERN S16 SUnpkF32 ARGS((F32 *val,Buffer *mBuf)); +EXTERN S16 SUnpkF64 ARGS((F64 *val,Buffer *mBuf)); +#endif /* SS_FLOAT */ +EXTERN S16 SPrint ARGS((Txt *buf)); +EXTERN S16 SDisplay ARGS((S16 chan,Txt *buf)); +EXTERN S16 SPrntMsg ARGS((Buffer *mBuf,S16 src,S16 dst)); +EXTERN S16 SInitQueue ARGS((Queue *q)); +#ifndef SS_ENABLE_MACROS +EXTERN S16 SQueueFirst ARGS((Buffer *buf,Queue *q)); +EXTERN S16 SQueueLast ARGS((Buffer *buf,Queue *q)); +EXTERN S16 SDequeueFirst ARGS((Buffer * *bufPtr,Queue *q)); +EXTERN S16 SDequeueLast ARGS((Buffer * *bufPtr,Queue *q)); +#endif /* SS_ENABLE_MACROS */ +EXTERN S16 SFlushQueue ARGS((Queue *q)); +EXTERN S16 SCatQueue ARGS((Queue *q1,Queue *q2,Order order)); +EXTERN S16 SFndLenQueue ARGS((Queue *q,QLen *lngPtr)); +EXTERN S16 SExamQueue ARGS((Buffer **bufPtr,Queue *q,QLen idx)); +EXTERN S16 SAddQueue ARGS((Buffer *buf,Queue *q,QLen idx)); +EXTERN S16 SRemQueue ARGS((Buffer **bufPtr,Queue *q,QLen idx)); +#ifndef SS_ENABLE_MACROS +#ifdef T2K_MEM_LEAK_DBG +#define SGetDBuf(region,pool,buf) SGetDBufNew(region,pool,buf,__FILE__,__LINE__) +#define SPutDBuf(region,pool,buf) SPutDBufNew(region,pool,buf,file,line) +EXTERN S16 SGetDBufNew ARGS((Region region,Pool pool,Buffer * *bufPtr,char*,U32)); +EXTERN S16 SPutDBufNew ARGS((Region region,Pool pool,Buffer *buf,char*,U32)); +EXTERN S16 SAttachPtrToBufNew ARGS((Region region, Pool pool, Data + *ptr, MsgLen totalLen, Buffer** mBuf, char* file, U32 line)); +#define SAttachPtrToBuf(region,pool,ptr,totalLen,mBuf) SAttachPtrToBufNew(region,pool,ptr,totalLen,mBuf,__FILE__,__LINE__) +#define SPutZbcDBuf(region,buf) SPutZbcDBufNew(region,buf,__FILE__,__LINE__) +#elif SS_LIGHT_MEM_LEAK_STS +EXTERN S16 SGetDBufNew ARGS((Region region,Pool pool,Buffer * *bufPtr,U32 line,U8 *fnName)); +EXTERN S16 SPutDBufNew ARGS((Region region,Pool pool,Buffer *buf, U32 line, U8 *fnName)); +#else + +EXTERN S16 SGetDBuf ARGS((Region region,Pool pool,Buffer * *bufPtr)); +EXTERN S16 SPutDBuf ARGS((Region region,Pool pool,Buffer *buf)); +#endif +#else /* SS_ENABLE_MACROS */ +#ifdef T2K_MEM_LEAK_DBG +#define SGetDBuf(region,pool,buf) SGetDBufNew(region,pool,buf,__FILE__,__LINE__) +#define SPutDBuf(region,pool,buf) SPutDBufNew(region,pool,buf,__FILE__,__LINE__) +EXTERN S16 SGetDBufNew ARGS((Region region,Pool pool,Buffer * *bufPtr,char*,U32)); +EXTERN S16 SPutDBufNew ARGS((Region region,Pool pool,Buffer *buf,char*,U32)); +#elif SS_LIGHT_MEM_LEAK_STS +EXTERN S16 SGetDBufNew ARGS((Region region,Pool pool,Buffer * *bufPtr,U32 line,U8 *fnName)); +EXTERN S16 SPutDBufNew ARGS((Region region,Pool pool,Buffer *buf, U32 line, U8 *fnName)); +#else +EXTERN S16 SGetDBuf ARGS((Region region,Pool pool,Buffer * *bufPtr)); +EXTERN S16 SPutDBuf ARGS((Region region,Pool pool,Buffer *buf)); +#endif +#endif /* SS_ENABLE_MACROS */ +EXTERN S16 SPutMsgToRegion ARGS((Region region, Buffer *buf)); +#ifdef SS_USE_ICC_MEMORY +EXTERN Void *ssGetIccHdl ARGS((Region region)); +#endif /* SS_USE_ICC_MEMORY */ + +/* ssi_x_001.main_57 : Additions */ +/* ssi_x_001.main_59 : Added compile time flag */ +#ifdef SS_LIGHT_MEM_LEAK_STS +EXTERN S16 SGetMsgNew ARGS((Region region, Pool pool, Buffer * *mBufPtr, U32 line, U8 *fnName)); +EXTERN S16 SGetSBufNew ARGS((Region region,Pool pool, Data * *bufPtr, Size size, U32 line, U8* fnName)); +EXTERN S16 SPutMsgNew ARGS((Buffer *mBuf, U32 line, U8 *fnName)); +EXTERN S16 SPutSBufNew ARGS((Region region, Pool pool, Data *buf, Size size, U32 line, U8 *fnName)); +#else /*SS_LIGHT_MEM_LEAK_STS */ +#ifdef SS_HISTOGRAM_SUPPORT +EXTERN S16 SPutMsgNew ARGS((Buffer *mBuf, U32 line, U8 *fileName)); +EXTERN S16 SGetMsgNew ARGS((Region region, Pool pool, Buffer * *mBufPtr, U32 line, U8 *fileName)); +EXTERN S16 SGetSBufNew ARGS((Region region,Pool pool, Data * *bufPtr, Size size, U32 line, U8 *fileName)); +EXTERN S16 SPutSBufNew ARGS((Region region, Pool pool, Data *buf, Size size, U32 line, U8 *fileName)); +#else +/*ssi_x_001.main_67 : RMIOS specific changes*/ +#ifndef SS_RMIOS +#ifdef T2K_MEM_LEAK_DBG +#define SPutMsg(mBuf) SPutMsgNew(mBuf,__FILE__,__LINE__) +#define SGetMsg(region,pool,mBuf) SGetMsgNew(region,pool,mBuf,__FILE__,__LINE__) +EXTERN S16 SPutMsgNew ARGS((Buffer *mBuf,char*, U32)); +EXTERN S16 SGetMsgNew ARGS((Region region, Pool pool, Buffer * *mBufPtr, char*,U32)); +#else +EXTERN S16 SPutMsg ARGS((Buffer *mBuf)); +EXTERN S16 SGetMsg ARGS((Region region, Pool pool, Buffer * *mBufPtr)); +#endif +#else +#define SPutMsg(m) SPutMsgRmi(__FILE__, __LINE__, m) +#define SGetMsg(r, p, m) SGetMsgRmi(__FILE__, __LINE__, r, p, m) +EXTERN S16 SPutMsgRmi ARGS((char *file, int line, Buffer *mBuf)); +EXTERN S16 SGetMsgRmi ARGS((char *file, int line, Region region, Pool pool, Buffer * *mBufPtr)); +#endif +#if (defined(SSI_STATIC_MEM_LEAK_DETECTION)|| defined(T2K_MEM_LEAK_DBG)) +#define SGetSBuf(region,pool,bufPtr,size) SGetSBuf1(region,pool,bufPtr,size,__FILE__,__LINE__) +EXTERN S16 SGetSBuf1 ARGS((Region region,Pool pool, Data * *bufPtr, Size size, char* file, U32 line)); +EXTERN void DumpStaticMemLeakFiles ARGS((void)); +EXTERN void DumpT2kMemLeakInfoToFile ARGS((void)); +#define SPutSBuf(region,pool,buf,size) SPutSBuf1(region,pool,buf,size,__FILE__,__LINE__) +EXTERN S16 SPutSBuf1 ARGS((Region region, Pool pool, Data *buf, Size size, char*, U32)); +#else +EXTERN S16 SGetSBuf ARGS((Region region,Pool pool, Data * *bufPtr, Size size)); +EXTERN S16 SPutSBuf ARGS((Region region, Pool pool, Data *buf, Size size)); +#endif +#endif /* SS_HISTOGRAM_SUPPORT */ +#endif /*SS_LIGHT_MEM_LEAK_STS */ +#ifdef INTEL_WLS +#ifdef T2K_MEM_LEAK_DBG +#define SGetSBufWls(region,pool,bufPtr,size) SGetSBufWls1(region,pool,bufPtr,size,__FILE__,__LINE__) +#define SPutSBufWls(region,pool,bufPtr,size) SPutSBufWls1(region,pool,bufPtr,size,__FILE__,__LINE__) +EXTERN S16 SPutSBufWls1(Region region, Pool pool, Data *ptr, Size size,char* file, U32 line); +EXTERN S16 SGetSBufWls1(Region region, Pool pool, Data **ptr, Size size,char* file, U32 line); +#define SAttachWlsPtrToMBuf(region,pool,bufPtr,rPtr,size,pLen,mBuf) SAttachWlsPtrToMBuf1(region,pool,bufPtr,rPtr,size,pLen,mBuf,__FILE__,__LINE__) +EXTERN S16 SAttachWlsPtrToMBuf1(Region region, Pool pool, Data *ptr, Data *readPtr, MsgLen totalLen, MsgLen ptrLen, Buffer** mBuf,char* file, U32 line); +#define SAttachPtrToMBuf(region,pool,bufPtr,size,pLen,mBuf) SAttachPtrToMBuf1(region,pool,bufPtr,size,pLen,mBuf,__FILE__,__LINE__) + +#else +EXTERN S16 SPutSBufWls(Region region, Pool pool, Data *ptr, Size size); +EXTERN S16 SGetSBufWls(Region region, Pool pool, Data **ptr, Size size); +EXTERN S16 SAttachWlsPtrToMBuf(Region region, Pool pool, Data *ptr, Data *readPtr, MsgLen totalLen, MsgLen ptrLen, Buffer** mBuf); +#endif +#endif +EXTERN S16 SGetStaticBuffer ARGS((Region region,Pool pool, Data * *bufPtr, Size size, U8 memType)); +EXTERN S16 SPutStaticBuffer ARGS((Region region, Pool pool, Data *buf, Size size, U8 memType)); +/* ssi_x_001.main_65: Additions */ +#ifdef SS_SEUM_CAVIUM +EXTERN S16 ssInitRcvWork ARGS((void)); +EXTERN S16 SConvPtrPhy ARGS(( Buffer **mBuf)); +EXTERN S16 SConvPhyPtr ARGS((Buffer **workPtr)); +EXTERN S16 SCpyFpaMsg ARGS((Buffer *srcBuf, Region dstRegion,Pool dstPool, Buffer **dstBuf)); +EXTERN S16 SCpyMsgFpa ARGS(( Buffer *srcBuf, Buffer **dstBuf)); +EXTERN S16 SPutFpaMsg ARGS(( Buffer *fpaBuf)); +#endif /* SS_SEUM_CAVIUM */ + +EXTERN S16 SGetSMem ARGS((Region region,Size size,Pool *poolPtr)); +EXTERN S16 SPutSMem ARGS((Region region,Pool pool)); +EXTERN S16 SInitMsg ARGS((Buffer *mBuf)); +EXTERN S16 SAddPreMsg ARGS((Data data,Buffer *mBuf)); +EXTERN S16 SAddPstMsg ARGS((Data data,Buffer *mBuf)); +/* ssi_x_001.main_70 - Added prototype for SAddPreMsgMultInOrder */ +EXTERN S16 SAddPreMsgMultInOrder ARGS((Data *src,MsgLen cnt,Buffer *mBuf)); +EXTERN S16 SRemPreMsg ARGS((Data *dataPtr,Buffer *mBuf)); +EXTERN S16 SRemPreMsgRegion ARGS((Region region, Data *dataPtr,Buffer *mBuf)); +EXTERN S16 SCatMsgRegion ARGS((Region region, Buffer *mBuf1,Buffer *mBuf2,Order order)); +EXTERN S16 SSegMsgRegion ARGS((Region region, Buffer *mBuf1,MsgLen idx,Buffer **mBuf2)); +EXTERN int SCreatePThread ARGS((pthread_t* tid, pthread_attr_t* attr, void *(*start_routine) (void *), void* arg)); +EXTERN S16 SRemPstMsg ARGS((Data *dataPtr,Buffer *mBuf)); +#ifdef T2K_MEM_LEAK_DBG +#define SAddPreMsgMult(src, cnt, mBuf) SAddPreMsgMult1(src, cnt, mBuf, __FILE__,__LINE__) +#define SAddPstMsgMult(src, cnt, mBuf) SAddPstMsgMult1(src, cnt, mBuf, __FILE__,__LINE__) + +EXTERN S16 SAddPreMsgMult1 ARGS((Data *src,MsgLen cnt,Buffer *mBuf, char *file, U32 line)); +EXTERN S16 SAddPstMsgMult1 ARGS((Data *src,MsgLen cnt,Buffer *mBuf, char *file, U32 line)); +#else +EXTERN S16 SAddPreMsgMult ARGS((Data *src,MsgLen cnt,Buffer *mBuf)); +EXTERN S16 SAddPstMsgMult ARGS((Data *src,MsgLen cnt,Buffer *mBuf)); +#endif +EXTERN S16 SGetPstMsgMult ARGS((MsgLen cnt,Buffer *mBuf)); +EXTERN S16 SRemPreMsgMult ARGS((Data *dst,MsgLen cnt,Buffer *mBuf)); +EXTERN S16 SRemPstMsgMult ARGS((Data *dst,MsgLen cnt,Buffer *mBuf)); +EXTERN S16 SRepMsg ARGS((Data data,Buffer *mBuf,MsgLen idx)); +EXTERN S16 SExamMsg ARGS((Data *dataPtr,Buffer *mBuf,MsgLen idx)); +/*ssi_x_001.main_60 */ +EXTERN S16 SGetDataFrmMsg ARGS ((Buffer *mBuf, Data *dataPtr, MsgLen idx, MsgLen dataLen)); +EXTERN S16 SFndLenMsg ARGS((Buffer *mBuf,MsgLen *lngPtr)); +EXTERN S16 SCatMsg ARGS((Buffer *mBuf1,Buffer *mBuf2,Order order)); +#ifdef T2K_MEM_LEAK_DBG +#define SSegMsg(mBuf1, idx, mBuf2) SSegMsgNew(mBuf1, idx, mBuf2, __FILE__, __LINE__) +EXTERN S16 SSegMsgNew ARGS((Buffer *mBuf1,MsgLen idx,Buffer **mBuf2,char*,U32)); +#else +EXTERN S16 SSegMsg ARGS((Buffer *mBuf1,MsgLen idx,Buffer **mBuf2)); +#endif +EXTERN S16 SSwapMsg ARGS((Buffer *mBuf1, Buffer *mBuf2)); +EXTERN S16 SCpyMsgFix ARGS((Buffer *srcMbuf,MsgLen srcIdx,MsgLen cnt, + Data *dstBuf,MsgLen *cCnt)); +EXTERN S16 SCpyFixMsg ARGS((Data *srcBuf,Buffer *dstMbuf, + MsgLen dstIdx,MsgLen cnt,MsgLen *cCnt)); +EXTERN S16 SCompressMsg ARGS((Buffer *mBuf)); +#ifdef T2K_MEM_LEAK_DBG +#define SAddMsgRef(mBuf,region,pool,dstBuf) SAddMsgRefNew(mBuf,region,pool,dstBuf,__FILE__,__LINE__) +#define SCpyMsgMsg(mBuf,region,pool, dstBuf) SCpyMsgMsgNew(mBuf,region,pool, dstBuf, __FILE__, __LINE__) +EXTERN S16 SAddMsgRefNew ARGS((Buffer *mBuf, Region region, Pool pool, + Buffer **dstBuf,char*,U32)); +EXTERN S16 SCpyMsgMsgNew ARGS((Buffer *mBuf, Region region, Pool pool, + Buffer **dstBuf,char* , U32)); +#else +EXTERN S16 SCpyMsgMsg ARGS((Buffer *mBuf, Region region, Pool pool, + Buffer **dstBuf)); +EXTERN S16 SAddMsgRef ARGS((Buffer *mBuf, Region region, Pool pool, + Buffer **dstBuf)); +EXTERN S16 SIncMsgRef(Buffer *srcBuf, Region dstRegion, Pool dstPool, Buffer **dstBuf); + +#ifdef SS_RBUF +/* EXTERN S16 SIncMsgRef ARGS((Buffer *srcBuf, Buffer **dstBuf)); */ +EXTERN Void SIncMsgLen ARGS((Buffer *mBuf)); +#endif +#endif +EXTERN S16 SChkRes ARGS((Region region,Pool pool,Status *status)); +EXTERN S16 SChkResUtl ARGS((Region region,U8 *wSum)); +EXTERN S16 SSetDateTime ARGS((DateTime *dt)); +EXTERN S16 SGetDateTime ARGS((DateTime *dt)); +#ifdef L2_OPTMZ +EXTERN Void SResetMBuf ARGS ((Buffer *mBuf)); +#endif + /* ssi_x_001.main_57 : Additions */ + /* ssi_x_001.main_58 : Additions */ + /* ssi_x_001.main_60 : Modifications */ +EXTERN S16 SGetEpcTime ARGS((EpcTime *et)); +/* ssi_x_001.main_48: Added Timestamp changes */ +EXTERN S16 SGetTimeStamp ARGS(( S8 *ts)); +EXTERN S16 SGetSysTime ARGS((Ticks *sysTime)); +EXTERN S16 SGetRefTime ARGS((U32 refTime, U32 *sec, U32 *usec)); +EXTERN S16 SRandom ARGS((Random *value)); +EXTERN S16 SError ARGS((Seq seq,Reason reason)); +EXTERN Void SLogError ARGS((Ent ent, Inst inst, ProcId procId, Txt *file, + S32 line, ErrCls errCls, ErrCode errCode, + ErrVal errVal, Txt *errDesc)); +/* ssi_x_001.main_49 : added prototype for SGetSystemTsk() */ +EXTERN U32 SGetSystemTsk ARGS ((Void)); +/* changes to support multiple processors in single SSI */ +/* multiple proc id changes: + these functions are not supported with multiple proc Ids */ +#ifndef SS_MULTIPLE_PROCS +EXTERN S16 SRegInit ARGS((Ent ent,Inst inst,PAIFS16 initFnct)); +EXTERN S16 SRegActvTsk ARGS((Ent ent,Inst inst,Ttype ttype,Prior prior, + ActvTsk actvTsk)); +#endif /* SS_MULTIPLE_PROCS */ + +/* multiple proc id changes: procId added and time function type modified */ +#ifndef SS_MULTIPLE_PROCS +EXTERN S16 SRegCfgTmr ARGS((Ent ent, + Inst inst, + S16 period, + S16 units, + PFS16 tmrFnct)); +#ifdef SS_MT_TMR +/* ssi_x_001.main_53 */ +EXTERN S16 SRegCfgTmrMt ARGS((Ent ent, + Inst inst, + S16 period, + S16 units, + PAIFTMRS16 tmrFnctMt)); +#endif +EXTERN S16 SDeregCfgTmr ARGS((Ent ent, + Inst inst, + S16 period, + S16 units, + PFS16 tmrFnct)); +#ifdef SS_MT_TMR +/* ssi_x_001.main_53 */ +EXTERN S16 SDeregCfgTmrMt ARGS((Ent ent, + Inst inst, + S16 period, + S16 units, + PAIFTMRS16 tmrFnctMt)); +#endif +#else +EXTERN S16 SRegCfgTmr ARGS((ProcId proc, + Ent ent, + Inst inst, + S16 period, + S16 units, + PAIFTMRS16 tmrFnct)); +EXTERN S16 SDeregCfgTmr ARGS((ProcId proc, + Ent ent, + Inst inst, + S16 period, + S16 units, + PAIFTMRS16 tmrFnct)); +#endif /* SS_MULTIPLE_PROCS */ + +EXTERN S16 SPstTsk ARGS((Pst *pst, Buffer *mBuf)); + +#ifdef SS_ROUTE_MSG_CORE1 +EXTERN S16 SPstTskIcpu ARGS((Pst *pst, Buffer *mBuf)); +#endif + +#ifdef ENB_RELAY +EXTERN S16 SRegDrvrTsk ARGS((Inst inst, ProcId low, ProcId high, + ActvTsk actvTsk, ISTsk isTsk)); +/*ssi_x_001.main_56*/ +EXTERN S16 SDeregDrvrTsk ARGS((Inst channel)); +#endif /* ENB_RELAY */ + +#ifdef SS_RTR_SUPPORT +EXTERN S16 SRegRtrTsk ARGS((Route *, Cntr, ActvTsk)); +EXTERN S16 SDeregRtrTsk ARGS((Route *, Cntr)); +#endif /* SS_RTR_SUPPORT */ + +#ifdef SS_USE_ZBC_MEMORY +EXTERN S16 SAttachPtrToBuf ARGS(( +Region region, +Pool pool, +Data *ptr, +MsgLen totalLen, +Buffer** mBuf +)); +#endif +/* multi-core support ssi_x_001.main_55 */ +/*ssi_x_001.main_68 Added SS_AFFINITY_SUPPORT*/ +#if defined(SS_MULTICORE_SUPPORT) || defined(SS_AFFINITY_SUPPORT) + +typedef S8 SsAffinityMode; + + +typedef struct { + U32 numCores; /* total number of cores available */ + U32 threadsPerCore; /* total number of threads available per core */ + U32 threadRegister[SS_MAX_CORES]; /* available threads per core */ +} SCpuInfo; + +EXTERN S16 SRegCpuInfo ARGS((SCpuInfo *cpuInfo)); +EXTERN S16 SSetAffinity ARGS((SSTskId *tskId, SsAffinityMode mode, U32 coreId, SSTskId *tskAssociatedTskId)); +EXTERN S16 SGetAffinity ARGS((SSTskId *tskId, U32 *coreId)); + +#endif /* SS_MULTICORE_SUPPORT || SS_AFFINITY_SUPPORT*/ + +#ifdef SS_AEHDPR_SUPPORT +EXTERN S16 SSetAehDpr ARGS((ProcId procId, VectNmb vectNmb,PISR pisr,PTR ptr1,PDPR pdpr,PTR ptr2)); +EXTERN S16 SRemoveAehDpr ARGS((ProcId chipNum, VectNmb vectNmb)); +#endif +EXTERN S16 SAddDBufPst ARGS((Buffer *mBuf, Buffer *dBuf)); +EXTERN S16 SAddDBufPre ARGS((Buffer *mBuf, Buffer *dBuf)); +EXTERN S16 SRemDBufPst ARGS((Buffer *mBuf, Buffer **dBuf)); +EXTERN S16 SRemDBufPre ARGS((Buffer *mBuf, Buffer **dBuf)); +EXTERN S16 SGetDataRx ARGS((Buffer *dBuf, MsgLen pad, Data **dat, MsgLen *mLen)); +EXTERN S16 SGetDataTx ARGS((Buffer *dBuf, Data **dat, MsgLen *mLen)); +EXTERN S16 SUpdMsg ARGS((Buffer *mBuf, Buffer *dBuf, MsgLen mLen)); +EXTERN S16 SCacheFlush ARGS( (U16 cache_type, Data *addr, Size size)); +EXTERN S16 SCacheInvalidate ARGS( (U16 cache_type, Data *addr, Size size)); +EXTERN S16 SAlignDBufEven ARGS((Buffer *dBuf)); +EXTERN S16 SAlignDBuf ARGS((Buffer *dBuf, U32 align)); +EXTERN S16 SInitNxtDBuf ARGS((Buffer *mBuf)); +EXTERN S16 SGetNxtDBuf ARGS((Buffer *mBuf, Buffer **dBuf)); +EXTERN S16 SChkNxtDBuf ARGS((Buffer *mBuf)); +EXTERN S16 SSetIntPend ARGS((U16 id, Bool flag)); +EXTERN S16 SChkMsg ARGS((Buffer *mBuf)); +EXTERN S16 SDeregInitTskTmr ARGS((Ent ent,Inst inst)); +EXTERN S16 SExitTsk ARGS((void )); +EXTERN S16 SExitInt ARGS((void )); +EXTERN S16 SHoldInt ARGS((void )); +EXTERN S16 SRelInt ARGS((void )); +EXTERN S16 SEnbInt ARGS((void )); +EXTERN S16 SDisInt ARGS((void )); +EXTERN S16 SGetVect ARGS((VectNmb vectNmb,PIF *vectFnct)); +EXTERN S16 SPutVect ARGS((VectNmb vectNmb,PIF vectFnct)); +#ifdef WINNT_KERN +EXTERN S16 SPutIsrDpr ARGS((VectNmb vectNmb, Void *context, PIF isrFnct, + PIF dprFnct)); +EXTERN S16 SSyncInt ARGS((U16 adapterNmb, PFVOID syncFnct, + Void *syncContext)); +#endif +EXTERN S16 SInitSema ARGS((Region region, Sema *sema)); +EXTERN S16 SRelSema ARGS((Region region, Sema sema)); +EXTERN S16 SGetSema ARGS((Region region, Sema sema)); +EXTERN S16 SActvInit ARGS((Ent ent,Inst inst,Region region,Reason reason)); +EXTERN S16 SActvTsk ARGS((Prior prior,Route route,Ent srcEnt, + Inst srcInst,Buffer *mBuf)); +EXTERN S16 SActvTmr ARGS((void )); +EXTERN S16 SGetOpt ARGS((int argc,char **argv,char *opts)); +/* multiple proc id changes: + These functions not supported with multiple procIds */ +#ifndef SS_MULTIPLE_PROCS +EXTERN S16 SGetEntInst ARGS((Ent *ent, Inst *inst)); +EXTERN S16 SSetEntInst ARGS((Ent ent, Inst inst)); +EXTERN ProcId SFndProcId ARGS((void)); +EXTERN Void SSetProcId ARGS((ProcId pId)); +#endif /* SS_MULTIPLE_PROCS */ + +EXTERN S16 SGetDBufSiz ARGS((Region region, Pool pool, S16 *size)); +EXTERN S16 SGetStrtIdx ARGS((Region region, Pool pool, S16 *idx)); +EXTERN S16 SGetEndIdx ARGS((Region region, Pool pool, S16 *idx)); +EXTERN S16 SGetStrtPad ARGS((Region region, Pool pool, S16 *pad)); +/* multiple proc id changes: control block retrieval function */ +#ifdef SS_MULTIPLE_PROCS +EXTERN S16 SGetXxCb ARGS((ProcId proc, Ent ent, Inst inst, Void **xxCb)); +#endif /* SS_MULTIPLE_PROCS */ + +#ifdef MT +/* + * These routines are only available for multi-threaded + * system service implementations + */ +EXTERN S16 SGetMutex ARGS((MtMtxId *mId)); +EXTERN S16 SPutMutex ARGS((MtMtxId mId)); +EXTERN S16 SLockMutex ARGS((MtMtxId mId)); +EXTERN S16 SUnlockMutex ARGS((MtMtxId mId)); +EXTERN S16 SGetCond ARGS((MtCondId *cId)); +EXTERN S16 SPutCond ARGS((MtCondId cId)); +EXTERN S16 SCondWait ARGS((MtMtxId mId,MtCondId cId)); +EXTERN S16 SCondSignal ARGS((MtCondId cId)); +EXTERN S16 SCondBroadcast ARGS((MtCondId cId)); +EXTERN S16 SGetThread ARGS((MtThrd thrd, MtThrdFlags thr_flgs, + Ptr arg, MtThrdId *thrdId)); +EXTERN S16 SPutThread ARGS((MtThrdId thrdId)); +EXTERN Void SThreadYield ARGS((void)); +EXTERN Void SThreadExit ARGS((Ptr *status)); +EXTERN Void SSetThrdPrior ARGS((MtThrdId tId, MtThrdPrior tPr)); +EXTERN Void SGetThrdPrior ARGS((MtThrdId tId, MtThrdPrior *tPr)); +#endif /* MT */ + +EXTERN Void SExit ARGS((Void)); +#ifdef SS +/* multiple proc id changes: procId added */ +#ifndef SS_MULTIPLE_PROCS + +EXTERN S16 SRegTTsk ARGS((Ent ent, + Inst inst, + Ttype type, + Prior prior, + PAIFS16 initTsk, + ActvTsk actvTsk)); +/* ssi_x_001.main_60 */ +EXTERN S16 SRegCbTsk ARGS((Ent ent, + Inst inst, + ActvTsk actvTsk)); +EXTERN S16 SDeregTTsk ARGS((Ent ent, Inst inst)); + +#else + +EXTERN S16 SRegTTsk ARGS((ProcId proc, + Ent ent, + Inst inst, + Ttype type, + Prior prior, + PAIFS16 initTsk, + ActvTsk actvTsk)); +EXTERN S16 SDeregTTsk ARGS((ProcId proc, Ent ent, Inst inst)); + +EXTERN S16 SRegCbTsk ARGS((ProcId proc, + Ent ent, + Inst inst, + ActvTsk actvTsk)); +#endif /* SS_MULTIPLE_PROCS */ + +EXTERN S16 SCreateSTsk ARGS((SSTskPrior tskPrior, SSTskId *tskId)); +EXTERN S16 SDestroySTsk ARGS((SSTskId tskId)); +/* multiple proc id changes: procId added */ +#ifndef SS_MULTIPLE_PROCS + +EXTERN S16 SAttachTTsk ARGS((Ent ent, Inst inst, SSTskId tskId)); +EXTERN S16 SDetachTTsk ARGS((Ent ent, Inst inst)); + +#else + +EXTERN S16 SAttachTTsk ARGS((ProcId proc, Ent ent, Inst inst, SSTskId tskId)); +EXTERN S16 SDetachTTsk ARGS((ProcId proc, Ent ent, Inst inst)); + +#endif /* SS_MULTIPLE_PROCS */ +EXTERN S16 SRegRegion ARGS((Region region, SRegInfo *regInfo)); +EXTERN S16 SDeregRegion ARGS((Region region)); +EXTERN S16 SRegDynRegion ARGS((Region region, SRegInfo *regInfo)); +/*ssi_x_001.main_62-prototype for SAlloc and SFree, gaurded under flag*/ +#ifndef SS_FAP + /* ssi_x_001.main_57 : Additions */ +#ifdef SS_HISTOGRAM_SUPPORT +EXTERN S16 SAlloc ARGS((Region region, Size *size, U32 flags, Data **ptr,U32 line, U8 *fileName, U8 entId)); +EXTERN S16 SFree ARGS((Region region, Data *ptr, Size size, U32 line, U8 *fileName, U8 entId)); +#else +#ifdef T2K_MEM_LEAK_DBG +#define SAlloc(region,size,flags,ptr) SAllocNew(region,size,flags,ptr,file,line) +#define SFree(region,ptr,size) SFreeNew(region,ptr,size,file,line) +EXTERN S16 SAllocNew ARGS((Region region, Size *size, U32 flags, Data **ptr,char*,U32)); +EXTERN S16 SFreeNew ARGS((Region region, Data *ptr, Size size,char*,U32)); +#elif defined(SS_LIGHT_MEM_LEAK_STS) +EXTERN S16 SAlloc ARGS((Region region, Size *size, U32 flags, Data **ptr,U32 line, U8 *fnName)); +EXTERN S16 SFree ARGS((Region region, Data *ptr, Size size, U32 line, U8 *fnName)); +#else +EXTERN S16 SAlloc ARGS((Region region, Size *size, U32 flags, Data **ptr)); +EXTERN S16 SFree ARGS((Region region, Data *ptr, Size size)); +#endif +#endif +EXTERN S16 SGetBufRegionPool ARGS((Buffer *mBuf, Region *region, Pool *pool)); +#endif /* SS_ENABLE_MACROS */ + +#ifdef SS_OLD_THREAD +EXTERN S16 SGetMutex ARGS((SMtxId *mId)); +EXTERN S16 SPutMutex ARGS((SMtxId mId)); +EXTERN S16 SLockMutex ARGS((SMtxId mId)); +EXTERN S16 SUnlockMutex ARGS((SMtxId mId)); +EXTERN S16 SGetCond ARGS((SCondId *cId)); +EXTERN S16 SPutCond ARGS((SCondId cId)); +EXTERN S16 SCondWait ARGS((SMtxId mId,SCondId cId)); +EXTERN S16 SCondSignal ARGS((SCondId cId)); +EXTERN S16 SCondBroadcast ARGS((SCondId cId)); +EXTERN S16 SGetThread ARGS((SThrd thrd, S32 thr_flgs, + Ptr arg, SThrdId *thrdId)); +EXTERN S16 SPutThread ARGS((SThrdId thrdId)); +EXTERN Void SThreadYield ARGS((void)); +EXTERN Void SThreadExit ARGS((Ptr status)); +EXTERN Void SSetThrdPrior ARGS((SThrdId tId, S32 tPr)); +EXTERN Void SGetThrdPrior ARGS((SThrdId tId, S32 *tPr)); +EXTERN Void SExit ARGS((void)); +#else /* SS_OLD_THREAD */ +EXTERN S16 SThreadYield ARGS((void)); +#endif /* SS_OLD_THREAD */ + +EXTERN S16 SInitLock ARGS((SLockId *lock,U8 type)); +EXTERN S16 SLock ARGS((SLockId *lock)); +EXTERN S16 SUnlock ARGS((SLockId *lock)); +EXTERN S16 SDestroyLock ARGS((SLockId *lock)); + + +EXTERN S16 SInitSemaphore ARGS((SsSemaId *sem, U8 value)); +EXTERN S16 SWaitSemaphore ARGS((SsSemaId *sem)); +EXTERN S16 SPostSemaphore ARGS((SsSemaId *sem)); +EXTERN S16 SDestroySemaphore ARGS((SsSemaId *sem)); + +/* multiple proc id changes: + new function required to implement multiple procIds */ +#ifdef SS_MULTIPLE_PROCS +EXTERN S16 SAddProcIdLst ARGS((U16 numPIds, ProcId *pIdLst)); +EXTERN S16 SRemProcIdLst ARGS((U16 numPIds, ProcId *pIdLst)); +EXTERN S16 SGetProcIdLst ARGS((U16 *numPIds, ProcId *pIdLst)); +#endif /* SS_MULTIPLE_PROCS */ + +#endif /* SS */ + +#ifdef SS_SEGV_SIG_HDLR +#ifndef SS_MULTIPLE_PROCS +EXTERN S16 SRegIntrptHdlr ARGS((Ent ent, Inst inst, PFS16 intrptActvFn)); +#else +EXTERN S16 SRegIntrptHdlr ARGS((ProcId proc, Ent ent, Inst inst, PFS16 intrptActvFn)); +#endif/*SS_MULTIPLE_PROCS*/ +#endif /* SS_SEGV_SIG_HDLR */ + +#ifdef PORTVER +/* procId added */ +#ifndef SS_MULTIPLE_PROCS +EXTERN S16 SRegTTsk ARGS((Ent ent, + Inst inst, + Ttype type, + Prior prior, + PAIFS16 initTsk, + ActvTsk actvTsk)); +/* ssi_x_001.main_60 */ +EXTERN S16 SRegCbTsk ARGS((Ent ent, + Inst inst, + ActvTsk actvTsk)); +EXTERN S16 SDeregTTsk ARGS((Ent ent, Inst inst)); +EXTERN S16 SAttachTTsk ARGS((Ent ent, Inst inst, SSTskId tskId)); +EXTERN S16 SDetachTTsk ARGS((Ent ent, Inst inst)); +#else +EXTERN S16 SRegTTsk ARGS((ProcId proc, + Ent ent, + Inst inst, + Ttype type, + Prior prior, + PAIFS16 initTsk, + ActvTsk actvTsk)); +EXTERN S16 SRegCbTsk ARGS((ProcId proc, + Ent ent, + Inst inst, + ActvTsk actvTsk)); +EXTERN S16 SDeregTTsk ARGS((ProcId proc, Ent ent, Inst inst)); +EXTERN S16 SAttachTTsk ARGS((ProcId proc, Ent ent, Inst inst, SSTskId tskId)); +EXTERN S16 SDetachTTsk ARGS((ProcId proc, Ent ent, Inst inst)); +#endif /* SS_MULTIPLE_PROCS */ + +EXTERN S16 SCreateSTsk ARGS((SSTskPrior tskPrior, SSTskId *tskId)); +EXTERN S16 SDestroySTsk ARGS((SSTskId tskId)); +#ifndef SS_ENABLE_MACROS +EXTERN S16 SGetBufRegionPool ARGS((Buffer *mBuf, Region *region, Pool *pool)); +#endif /* SS_ENABLE_MACROS */ + +EXTERN S16 SInitLock ARGS((SLockId *lock,U8 type)); +EXTERN S16 SLock ARGS((SLockId *lock)); +EXTERN S16 SUnlock ARGS((SLockId *lock)); +EXTERN S16 SDestroyLock ARGS((SLockId *lock)); + +EXTERN S16 SInitSemaphore ARGS((SsSemaId *sem, U8 value)); +EXTERN S16 SWaitSemaphore ARGS((SsSemaId *sem)); +EXTERN S16 SPostSemaphore ARGS((SsSemaId *sem)); +EXTERN S16 SDestroySemaphore ARGS((SsSemaId *sem)); +/* functions required to implement multiple procIds */ +#ifdef SS_MULTIPLE_PROCS +EXTERN S16 SAddProcIdLst ARGS((U16 numPIds, ProcId *pIdLst)); +EXTERN S16 SRemProcIdLst ARGS((U16 numPIds, ProcId *pIdLst)); +EXTERN S16 SGetProcIdLst ARGS((U16 *numPIds, ProcId *pIdLst)); +#endif /* SS_MULTIPLE_PROCS */ + +#endif /* PORTVER */ + + +/* function prototypes */ + +/* stack manager initialization function */ +/* multiple proc id changes: procId added */ +#ifndef SS_MULTIPLE_PROCS +EXTERN S16 smActvInit ARGS((Ent ent, Inst inst, Region region, Reason reason)); +#else /* SS_MULTIPLE_PROCS */ +EXTERN S16 smActvInit ARGS((ProcId proc, + Ent ent, + Inst inst, + Region region, + Reason reason, + Void **xxCb)); +#endif /* SS_MULTIPLE_PROCS */ + +/* stack manager external initialization function */ +EXTERN S16 smInitExt ARGS((void)); + +/* stack manager activation function */ +EXTERN S16 smActvTsk ARGS((Pst *pst, Buffer *mBuf)); + +/* ssi_x_001.main_54 */ +#ifdef SS_SID_CHANGE +/* ssi_x_001.main_53 */ +EXTERN S16 SGetInDepSId ARGS((SystemId *s)); +EXTERN S16 SGetDepSId ARGS((SystemId *s)); +#endif + +/* Macros... */ + +#define SS_INITDCHN(chn) (chn)->next = NULLP; (chn)->prev = NULLP +#define SS_INITQUE(qu) \ + SS_INITDCHN(&(qu)->dChn); (qu)->crntSize = 0 +#define SS_QLEN(bq) ((bq)->crntSize) +#define SS_MLEN(mb) ((mb)->t.msg.msgLen) + +/* ssi_x_001.main_50 : Added declarations for mutex related functions + * to protect demand queue and memory allocation + */ +/* ssi_x_001.main_51 : Added control flag as these are only used by windows */ +#ifdef SS_WIN +EXTERN S16 WTInitLock ARGS((SLockId *lock,U8 type)); +EXTERN S16 WTLock ARGS((SLockId *lock)); +EXTERN S16 WTUnlock ARGS((SLockId *lock)); +EXTERN S16 WTDestroyLock ARGS((SLockId *lock)); +#endif /* End of SS_WIN */ + /* ssi_x_001.main_57 : Additions */ +#ifdef SS_LOGGER_SUPPORT +EXTERN S16 SRegLogCfg ARGS(( U8 mode, S8 *path, U32 size, S8 *IPA, U16 port)); +EXTERN S16 SWrtLogBuf ARGS(( Txt *buf )); +/* ssi_x_001.main_60 */ +EXTERN S16 SDeregLogCfg ARGS((Void )); +#endif /* SS_LOGGER_SUPPORT */ + +#ifdef SS_HISTOGRAM_SUPPORT +EXTERN S16 SRegForHstGrm ARGS((Ent ent)); +EXTERN S16 SHstGrmInfoShow ARGS((Ent *entId)); +EXTERN S16 SFillEntIds ARGS((Void)); +EXTERN S16 SGetEntInd ARGS((Ent *entId, U8 *fileName)); +#endif /* SS_HISTOGRAM_SUPPORT */ +/* ssi_x_001.main_68 Multiple declaration removed , one already in cm_task.x */ +/* ssi_x_001.main_61: Lock support guraded under the flag */ +#ifdef SS_LOCK_SUPPORT +EXTERN S16 SLockNew ARGS((SLockInfo *LockId, U8 lockType)); +EXTERN S16 SInitLockNew ARGS((SLockInfo *LockId, U8 lockType)); +EXTERN S16 SUnlockNew ARGS((SLockInfo *LockId, U8 lockType)); +EXTERN S16 SDestroyLockNew ARGS((SLockInfo *LockId, U8 lockType)); +#endif /* SS_LOCK_SUPPORT */ +EXTERN S8* SGetConfigPath ARGS((Void)); + +/* ssi_x_001.main_66 : Added new Buffer manegement APIs */ +EXTERN S16 SCpyPartMsg ARGS((Buffer *srcBuf, MsgLen idx, MsgLen cnt, Buffer *dstBuf)); +EXTERN S16 SRepPartMsg ARGS((Buffer *srcBuf, MsgLen idx, MsgLen cnt, Buffer *dstBuf)); +EXTERN S16 SMovPartMsg ARGS((Buffer *srcBuf, MsgLen idx, Buffer *dstBuf)); +EXTERN S16 SPkMsgMult ARGS((Data *src, MsgLen cnt, Buffer *mBuf)); +EXTERN S16 SGetReadPtr ARGS((Buffer *mBuf, U8** data, MsgLen *len)); + +typedef enum +{ + SS_SHARABLE_MEMORY, + SS_NON_SHARABLE_MEMORY +}ssMemoryType; +#ifdef TENB_T2K3K_SPECIFIC_CHANGES +EXTERN S16 SReInitTmr ARGS((Void )); +#endif +/* ssi_x_001.main_69: Added MSPD debug macro */ +#ifdef MSPD +extern U32 ysGT; +extern char ys_global_printbuf[256]; +EXTERN Void rbCallstackShow ARGS((Void)); +EXTERN Void rbCallstackShowForCore ARGS((U32 coreId)); +EXTERN U32 MacGetTick ARGS ((void)); +#endif /* MSPD */ +#ifdef LTE_L2_MEAS +extern U64 glblTtiCnt; +#endif + +EXTERN S16 SStartTask ARGS((VOLATILE U32 *startTime, U32 tarkId)); +EXTERN S16 SStopTask ARGS((VOLATILE U32 startTime,U32 taskId)); +#ifdef MSPD_MLOG_NEW +/* Removed for C++ Compilation +EXTERN unsigned int MLogTask (unsigned int taskid, unsigned int resourceid , + unsigned int ticksstart,unsigned int ticksstop); +--*/ +#endif + +#if defined(MSPD) && defined(MSPD_DBG_ENABLE) +#define MSPD_DBG_RLC(...) +#ifdef TENB_T2K3K_SPECIFIC_CHANGES +#ifndef ALIGN_64BIT +#define MSPD_DBG(...) do { \ + char _local_printbuf[SS_MEMLOG_MAXSTRLEN]; \ + int _len1 = snprintf(_local_printbuf, SS_MEMLOG_MAXSTRLEN, "%s():%u @%lu ", __func__, __LINE__, ysGT); \ + int _len2 = snprintf(&_local_printbuf[_len1],SS_MEMLOG_MAXSTRLEN - _len1, __VA_ARGS__) + _len1; \ + ssMemlog(_local_printbuf, _len2); \ +} while (0) +#else +#define MSPD_DBG(...) do { \ + char _local_printbuf[SS_MEMLOG_MAXSTRLEN]; \ + int _len1 = snprintf(_local_printbuf, SS_MEMLOG_MAXSTRLEN, "%s():%u @%u ", __func__, __LINE__, ysGT); \ + int _len2 = snprintf(&_local_printbuf[_len1],SS_MEMLOG_MAXSTRLEN - _len1, __VA_ARGS__) + _len1; \ + ssMemlog(_local_printbuf, _len2); \ +} while (0) +#endif +#define MSPD_DBG_RAW(...) do { \ + char _local_printbuf[SS_MEMLOG_MAXSTRLEN]; \ + int _len = snprintf(_local_printbuf,SS_MEMLOG_MAXSTRLEN, __VA_ARGS__); \ + ssMemlog(_local_printbuf, _len); \ +} while (0) +#ifndef ALIGN_64BIT +#define MSPD_LOG(...) do { \ + char _local_printbuf[SS_MEMLOG_MAXSTRLEN]; \ + int _len1 = snprintf(_local_printbuf, SS_MEMLOG_MAXSTRLEN,"%s():%u @%lu ", __func__, __LINE__, ysGT); \ + int _len2 = snprintf(&_local_printbuf[_len1],SS_MEMLOG_MAXSTRLEN - _len1, __VA_ARGS__) + _len1; \ + ssMemlog(_local_printbuf, _len2); \ +} while (0) +#else +#define MSPD_LOG(...) do { \ + char _local_printbuf[SS_MEMLOG_MAXSTRLEN]; \ + int _len1 = snprintf(_local_printbuf, SS_MEMLOG_MAXSTRLEN,"%s():%u @%u ", __func__, __LINE__, ysGT); \ + int _len2 = snprintf(&_local_printbuf[_len1],SS_MEMLOG_MAXSTRLEN - _len1, __VA_ARGS__) + _len1; \ + ssMemlog(_local_printbuf, _len2); \ +} while (0) + +#endif +#ifndef ALIGN_64BIT +#define MSPD_ERR(...) do { \ + char _local_printbuf[SS_MEMLOG_MAXSTRLEN]; \ + int _len1 = snprintf(_local_printbuf, SS_MEMLOG_MAXSTRLEN, "ERROR: %s():%u @%lu ", __func__, __LINE__, ysGT); \ + int _len2 = snprintf(&_local_printbuf[_len1],SS_MEMLOG_MAXSTRLEN - _len1, __VA_ARGS__) + _len1; \ + ssMemlog(_local_printbuf, _len2); \ +} while (0) +#else +#define MSPD_ERR(...) do { \ + char _local_printbuf[SS_MEMLOG_MAXSTRLEN]; \ + int _len1 = snprintf(_local_printbuf, SS_MEMLOG_MAXSTRLEN, "ERROR: %s():%u @%u ", __func__, __LINE__, ysGT); \ + int _len2 = snprintf(&_local_printbuf[_len1],SS_MEMLOG_MAXSTRLEN - _len1, __VA_ARGS__) + _len1; \ + ssMemlog(_local_printbuf, _len2); \ +} while (0) + +#endif + +EXTERN Void ssMlogInit(Void); +EXTERN Void ssMlogIncrCounter(Void); +EXTERN Void ssMemlogInit(Void); +EXTERN Void ssMemlog(char *, U32 size); +EXTERN Void ssMemlogWrite(Void); + +#endif /* TENB_T2K3K_SPECIFIC_CHANGES */ +#endif + +#ifdef __cplusplus +} +#endif + +EXTERN Void SIncrementTtiCount(Void); +EXTERN Ticks SGetTtiCount(Void); +#ifdef TENB_T2K3K_SPECIFIC_CHANGES +EXTERN Void mtStopHndlr(Void); +#endif + +#ifdef TENB_RTLIN_CHANGES +EXTERN Void ysPrntBkTrace(Void); +EXTERN Void ssMlogInit(Void); +EXTERN Void ssMlogIncrCounter(Void); +#endif +#ifdef SS_THR_REG_MAP +EXTERN Void ssRegMainThread(Void); +#endif + +#ifdef T2K_MEM_LEAK_DBG +#define ssGetDBufOfSize(region,size,dBuf) ssGetDBufOfSizeNew(region,size,dBuf,__FILE__,__LINE__) +PUBLIC S16 ssGetDBufOfSizeNew ARGS((Region region, Size size, Buffer **dBuf,char*,U32)); +#else +EXTERN S16 ssGetDBufOfSize(Region region,Size size,Buffer **dBuf); +#endif + +/* ssi_x_001.main_69: Added MSPD debug macro */ +#ifdef MSPD +EXTERN void SEND_DBG_MSG(U8 *str, ...); +#endif + +#endif /* __SSIX__ */ + + +/********************************************************************30** + + End of file +**********************************************************************/ diff --git a/src/cm/tfu.h b/src/cm/tfu.h new file mode 100755 index 000000000..1ea29a597 --- /dev/null +++ b/src/cm/tfu.h @@ -0,0 +1,295 @@ +/******************************************************************************* +################################################################################ +# Copyright (c) [2017-2019] [Radisys] # +# # +# 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. # +################################################################################ +*******************************************************************************/ + +/********************************************************************** + Name: Lower layer interface - TFU + + Type: C header file + + Desc: Constants needed for TFU interface + + File: tfu.h + +*********************************************************************21*/ + +/** + @file tfu.h + @brief Defines for TFU interface. + */ + +#ifndef __TFU_H__ +#define __TFU_H__ + +/* Define for the block size for memory allocation */ +/** @name TFU_TDD */ +/** @{ */ +#define TFU_MAX_HQ_RES 4 /*!< n^1 Pucch resources for + HARQ feedback */ + +#ifdef TFU_5GTF +#define TFU_RIV_324 324 /*!< RV value 324 */ +#define TFU_RIV_325 325 /*!< RV value 325 */ +#define TFU_RIV_326 326 /*!< RV value 326 */ +#endif + +#ifdef TFU_TDD +#define TFU_BLKSZ 2048 /*!< Block size for memory allocations. */ +#else +/* tfu_h_001.main_3 Changing from 4096 to 1500 to align with max bucket-max + * packet sizes - optimization*/ +#define TFU_BLKSZ 1500 /*!< Block size for memory allocations. */ +#endif +/* tfu_h_001.main_6. Added changes of TFU_UPGRADE */ +#ifdef TFU_UPGRADE +#define TFU_MAX_UL_RB 110 /*!< Maximum number of RBs in UL */ +#define TFU_MAX_CQI_BYTES 9 /*!< Maximum number of CQI Bytes length */ +#define TFU_MAX_PHY_ANTENNA 4 /*!< Maximum number of Physical Antennas */ +#endif /* TFU_UPGRADE */ + +#define TFU_MAX_RAPID_IN_SUBFRAME 64 /*!< Maximum number of Random access preambes in a subframe. */ +#define TFU_MAX_UL_SUBBAND 110 /*!< Maxiumum number of Uplink Subbands.*/ +#define TFU_MAX_DL_SUBBAND 110 /*!< Maxiumum number of Downlink Subbands.*/ +#define TFU_MAX_TB 2 /*!< Maximum number of Transport blocks per UE. */ +#ifdef L2_OPTMZ +#define TFU_MAX_PDU 8 /*!< This No is mapped to RGU_MAX_PDU*/ +#define TFU_MAX_LC 10 /*!< This No is mapped to RGU_MAX_LC*/ +#endif +#define TFU_MAX_M 4 /*!< Maximum value of "M" for HARQ Feedback multiplexing. */ +#define TFU_MAX_2BIT_TPC 16 /*!< Maximum number of 2 bit TPC commands. */ +#define TFU_MAX_1BIT_TPC 32 /*!< Maximum number of 1 bit TPC commands. */ +/*tfu_h_001.main_5 - Added support for SPS*/ +/* Tunable parameter */ +#define TFU_MAX_MEMBLK_SIZE 1500 /* tfu_h_001.main_3 Changing from 2048 to 1500 + for alignment and optimization */ + +#define TFU_UBNDREQ_MNGMT 1 /*!< TFU sap unbind reason */ + +#ifdef LTE_ADV +#define TFU_MAX_FDD_HARQ_FDBKS 10 +#define TFU_MAX_HARQ_FDBKS 20 /*For Rel10 UE + Considering 10 bit requirement of PUCCH Format 3*/ +#else +#define TFU_MAX_HARQ_FDBKS TFU_MAX_TB /*For Rel8/Rel9 UE*/ +#endif/*LTE_ADV*/ + +/* Event corresponding to each primitive at this interface */ +#define EVTTFUBNDREQ 1 /*!< Bind Request */ +#define EVTTFUBNDCFM 2 /*!< Bind Confirm */ +#define EVTTFUUBNDREQ 3 /*!< Unbind Request */ +#define EVTTFUSCHBNDREQ 4 /*!< Bind Request */ +#define EVTTFUSCHBNDCFM 5 /*!< Bind Confirm */ +#define EVTTFUSCHUBNDREQ 6 /*!< Unbind Request */ +#define EVTTFURAREQIND 7 /*!< Random access request indication. */ +#define EVTTFURECPREQ 8 /*!< Reception Request. */ +#define EVTTFUULCQIIND 9 /*!< Uplink CQI indication.*/ +#define EVTTFUHQIND 10 /*!< HARQ Feedback indication. */ +#define EVTTFUDLCQIIND 11 /*!< Downlink CQI indication. */ +#define EVTTFUSRIND 12 /*!< Scheduling Request indication.*/ +#define EVTTFUDATIND 13 /*!< Data indication.*/ +#define EVTTFUCRCIND 14 /*!< CRC indication. */ +#define EVTTFUTIMINGADVIND 15 /*!< Timing advance indication.*/ +#define EVTTFUDATREQ 16 /*!< Data Request.*/ +#define EVTTFUTTIIND 17 /*!< TTI indication.*/ +#define EVTTFUSCHTTIIND 18 /*!< TTI indication for scheduler.*/ +#define EVTTFUCNTRLREQ 19 /*!< Control Request.*/ +#define EVTTFUPUCCHDELPWR 20 /*!< PUCCH Delta power. */ +#define EVTTFUDOAIND 21 /*!< PUCCH Delta power. */ +/* tfu_h_001.main_6. Added changes of TFU_UPGRADE */ +#ifdef TFU_UPGRADE +#define EVTTFURAWCQIIND 22 +#define EVTTFUSRSIND 23 +#endif +#if defined(TENB_T2K3K_SPECIFIC_CHANGES) && defined(LTE_TDD) +#define EVTTFUNONRTIND 24 /*!< Non-RT indication.*/ +#endif +#define EVTTFUERRIND 25 /*!< TFU Error Indication */ +/** @} */ + +/* selector(coupling) values */ +#define TFU_SEL_TC 1 /*!< Selector for Tight coupling. */ +#define TFU_SEL_LC 0 /*!< Selector for Loose coupling. */ +#define TFU_SEL_LWLC 2 /*!< Selector for Light-weight loose coupling. */ +#define TFU_MAX_ALLOC_BYTES 4 +/* pack unpack error code */ +#define ETFUXXX 0 +#define ERRTFU 0 +/* tfu_h_001.main_2 - ccpu00110457 DTX Changes Start */ +#define TFU_HQFDB_NACK FALSE +#define TFU_HQFDB_ACK TRUE +/* tfu_h_001.main_6. Added changes of TFU_UPGRADE */ +#define TFU_HQFDB_DTX 4 +#define TFU_HQFDB_INVALID 0xFF + +/*tfu_h_001.main_7 - DEL - ERR Codes*/ +#define ETFU001 (ERRTFU + 1) /* tfu.c: 162 */ +#define ETFU002 (ERRTFU + 2) /* tfu.c: 170 */ +#define ETFU003 (ERRTFU + 3) /* tfu.c: 179 */ +#define ETFU004 (ERRTFU + 4) /* tfu.c: 232 */ +#define ETFU005 (ERRTFU + 5) /* tfu.c: 241 */ +#define ETFU006 (ERRTFU + 6) /* tfu.c: 290 */ +#define ETFU007 (ERRTFU + 7) /* tfu.c: 298 */ +#define ETFU008 (ERRTFU + 8) /* tfu.c: 307 */ +#define ETFU009 (ERRTFU + 9) /* tfu.c: 360 */ +#define ETFU010 (ERRTFU + 10) /* tfu.c: 369 */ +#define ETFU011 (ERRTFU + 11) /* tfu.c: 418 */ +#define ETFU012 (ERRTFU + 12) /* tfu.c: 426 */ +#define ETFU013 (ERRTFU + 13) /* tfu.c: 435 */ +#define ETFU014 (ERRTFU + 14) /* tfu.c: 488 */ +#define ETFU015 (ERRTFU + 15) /* tfu.c: 497 */ +#define ETFU016 (ERRTFU + 16) /* tfu.c: 546 */ +#define ETFU017 (ERRTFU + 17) /* tfu.c: 554 */ +#define ETFU018 (ERRTFU + 18) /* tfu.c: 563 */ +#define ETFU019 (ERRTFU + 19) /* tfu.c: 616 */ +#define ETFU020 (ERRTFU + 20) /* tfu.c: 625 */ +#define ETFU021 (ERRTFU + 21) /* tfu.c: 674 */ +#define ETFU022 (ERRTFU + 22) /* tfu.c: 682 */ +#define ETFU023 (ERRTFU + 23) /* tfu.c: 691 */ +#define ETFU024 (ERRTFU + 24) /* tfu.c: 744 */ +#define ETFU025 (ERRTFU + 25) /* tfu.c: 753 */ +#define ETFU026 (ERRTFU + 26) /* tfu.c: 802 */ +#define ETFU027 (ERRTFU + 27) /* tfu.c: 810 */ +#define ETFU028 (ERRTFU + 28) /* tfu.c: 819 */ +#define ETFU029 (ERRTFU + 29) /* tfu.c: 872 */ +#define ETFU030 (ERRTFU + 30) /* tfu.c: 881 */ +#define ETFU031 (ERRTFU + 31) /* tfu.c: 934 */ +#define ETFU032 (ERRTFU + 32) /* tfu.c: 944 */ +#define ETFU033 (ERRTFU + 33) /* tfu.c: 956 */ +#define ETFU034 (ERRTFU + 34) /* tfu.c:1018 */ +#define ETFU035 (ERRTFU + 35) /* tfu.c:1030 */ +#define ETFU036 (ERRTFU + 36) /* tfu.c:1045 */ +#define ETFU037 (ERRTFU + 37) /* tfu.c:1108 */ +#define ETFU038 (ERRTFU + 38) /* tfu.c:1118 */ +#define ETFU039 (ERRTFU + 39) /* tfu.c:1130 */ +#define ETFU040 (ERRTFU + 40) /* tfu.c:1202 */ +#define ETFU041 (ERRTFU + 41) /* tfu.c:1214 */ +#define ETFU042 (ERRTFU + 42) /* tfu.c:1229 */ +#define ETFU043 (ERRTFU + 43) /* tfu.c:1283 */ +#define ETFU044 (ERRTFU + 44) /* tfu.c:1293 */ +#define ETFU045 (ERRTFU + 45) /* tfu.c:1305 */ +#define ETFU046 (ERRTFU + 46) /* tfu.c:1368 */ +#define ETFU047 (ERRTFU + 47) /* tfu.c:1380 */ +#define ETFU048 (ERRTFU + 48) /* tfu.c:1396 */ +#define ETFU049 (ERRTFU + 49) /* tfu.c:1450 */ +#define ETFU050 (ERRTFU + 50) /* tfu.c:1460 */ +#define ETFU051 (ERRTFU + 51) /* tfu.c:1472 */ +#define ETFU052 (ERRTFU + 52) /* tfu.c:1534 */ +#define ETFU053 (ERRTFU + 53) /* tfu.c:1546 */ +#define ETFU054 (ERRTFU + 54) /* tfu.c:1562 */ +#define ETFU055 (ERRTFU + 55) /* tfu.c:1615 */ +#define ETFU056 (ERRTFU + 56) /* tfu.c:1625 */ +#define ETFU057 (ERRTFU + 57) /* tfu.c:1637 */ +#define ETFU058 (ERRTFU + 58) /* tfu.c:1698 */ +#define ETFU059 (ERRTFU + 59) /* tfu.c:1710 */ +#define ETFU060 (ERRTFU + 60) /* tfu.c:1726 */ +#define ETFU061 (ERRTFU + 61) /* tfu.c:1777 */ +#define ETFU062 (ERRTFU + 62) /* tfu.c:1787 */ +#define ETFU063 (ERRTFU + 63) /* tfu.c:1799 */ +#define ETFU064 (ERRTFU + 64) /* tfu.c:1857 */ +#define ETFU065 (ERRTFU + 65) /* tfu.c:1869 */ +#define ETFU066 (ERRTFU + 66) /* tfu.c:1885 */ +#define ETFU067 (ERRTFU + 67) /* tfu.c:1944 */ +#define ETFU068 (ERRTFU + 68) /* tfu.c:1954 */ +#define ETFU069 (ERRTFU + 69) /* tfu.c:2014 */ +#define ETFU070 (ERRTFU + 70) /* tfu.c:2026 */ +#define ETFU071 (ERRTFU + 71) /* tfu.c:2082 */ +#define ETFU072 (ERRTFU + 72) /* tfu.c:2092 */ +#define ETFU073 (ERRTFU + 73) /* tfu.c:2151 */ +#define ETFU074 (ERRTFU + 74) /* tfu.c:2163 */ +#define ETFU075 (ERRTFU + 75) /* tfu.c:2221 */ +#define ETFU076 (ERRTFU + 76) /* tfu.c:2231 */ +#define ETFU077 (ERRTFU + 77) /* tfu.c:2243 */ +#define ETFU078 (ERRTFU + 78) /* tfu.c:2304 */ +#define ETFU079 (ERRTFU + 79) /* tfu.c:2316 */ +#define ETFU080 (ERRTFU + 80) /* tfu.c:2332 */ +#define ETFU081 (ERRTFU + 81) /* tfu.c:2389 */ +#define ETFU082 (ERRTFU + 82) /* tfu.c:2399 */ +#define ETFU083 (ERRTFU + 83) /* tfu.c:2411 */ +#define ETFU084 (ERRTFU + 84) /* tfu.c:2476 */ +#define ETFU085 (ERRTFU + 85) /* tfu.c:2488 */ +#define ETFU086 (ERRTFU + 86) /* tfu.c:2504 */ +#define ETFU087 (ERRTFU + 87) /* tfu.c:2558 */ +#define ETFU088 (ERRTFU + 88) /* tfu.c:2568 */ +#define ETFU089 (ERRTFU + 89) /* tfu.c:2580 */ +#define ETFU090 (ERRTFU + 90) /* tfu.c:2642 */ +#define ETFU091 (ERRTFU + 91) /* tfu.c:2654 */ +#define ETFU092 (ERRTFU + 92) /* tfu.c:2670 */ +#define ETFU093 (ERRTFU + 93) /* tfu.c:2726 */ +#define ETFU094 (ERRTFU + 94) /* tfu.c:2736 */ +#define ETFU095 (ERRTFU + 95) /* tfu.c:2748 */ +#define ETFU096 (ERRTFU + 96) /* tfu.c:2812 */ +#define ETFU097 (ERRTFU + 97) /* tfu.c:2824 */ +#define ETFU098 (ERRTFU + 98) /* tfu.c:2840 */ +#define ETFU099 (ERRTFU + 99) /* tfu.c:2897 */ +#define ETFU100 (ERRTFU + 100) /* tfu.c:2907 */ +#define ETFU101 (ERRTFU + 101) /* tfu.c:2919 */ +#define ETFU102 (ERRTFU + 102) /* tfu.c:2984 */ +#define ETFU103 (ERRTFU + 103) /* tfu.c:2996 */ +#define ETFU104 (ERRTFU + 104) /* tfu.c:3012 */ +#define ETFU105 (ERRTFU + 105) /* tfu.c:3065 */ +#define ETFU106 (ERRTFU + 106) /* tfu.c:3075 */ +#define ETFU107 (ERRTFU + 107) /* tfu.c:3087 */ +#define ETFU108 (ERRTFU + 108) /* tfu.c:3098 */ +#define ETFU109 (ERRTFU + 109) /* tfu.c:3155 */ +#define ETFU110 (ERRTFU + 110) /* tfu.c:3164 */ +#define ETFU111 (ERRTFU + 111) /* tfu.c:3179 */ +#define ETFU112 (ERRTFU + 112) /* tfu.c:3231 */ +#define ETFU113 (ERRTFU + 113) /* tfu.c:3241 */ +#define ETFU114 (ERRTFU + 114) /* tfu.c:3253 */ +#define ETFU115 (ERRTFU + 115) /* tfu.c:3264 */ +#define ETFU116 (ERRTFU + 116) /* tfu.c:3320 */ +#define ETFU117 (ERRTFU + 117) /* tfu.c:3329 */ +#define ETFU118 (ERRTFU + 118) /* tfu.c:3344 */ +#define ETFU119 (ERRTFU + 119) /* tfu.c:3396 */ +#define ETFU120 (ERRTFU + 120) /* tfu.c:3406 */ +#define ETFU121 (ERRTFU + 121) /* tfu.c:3418 */ +#define ETFU122 (ERRTFU + 122) /* tfu.c:3477 */ +#define ETFU123 (ERRTFU + 123) /* tfu.c:3489 */ +#define ETFU124 (ERRTFU + 124) /* tfu.c:3504 */ +#define ETFU125 (ERRTFU + 125) /* tfu.c:10783 */ +#define ETFU126 (ERRTFU + 126) /* tfu.c:10793 */ +#define ETFU127 (ERRTFU + 127) /* tfu.c:10850 */ +#define ETFU128 (ERRTFU + 128) /* tfu.c:10862 */ + +#define TFU_PERIODIC_CQI_TYPE 0 +#define TFU_APERIODIC_CQI_TYPE 1 + +#define TFU_FREE_MSG(_buf)\ +{\ + if (NULLP != (_buf)) \ + { \ + SPutMsg((_buf)); \ + _buf = NULLP; \ + } \ +} + +#define TFU_FREE_MEM(_mem)\ +{\ + if (NULLP != (_mem)) \ + { \ + cmFreeMem((_mem)); \ + _mem = NULLP; \ + } \ +} + + +#endif /* __TFU_H__ */ + +/********************************************************************30** + + End of file +**********************************************************************/ diff --git a/src/cm/tfu.x b/src/cm/tfu.x new file mode 100755 index 000000000..69bf8e855 --- /dev/null +++ b/src/cm/tfu.x @@ -0,0 +1,4503 @@ +/******************************************************************************* +################################################################################ +# Copyright (c) [2017-2019] [Radisys] # +# # +# 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. # +################################################################################ +*******************************************************************************/ + +/********************************************************************** + Name: Lower layer interface - TFU + + Type: C header file + + Desc: Structures, variables and typedefs required by + TFU interface + + File: tfu.x + +*********************************************************************21*/ + +/** + @file tfu.x + @brief Structure declarations and definitions for TFU interface. + */ + + +#ifndef __TFUX__ +#define __TFUX__ +#ifdef __cplusplus +extern "C" { +#endif + +/*********************************************************************** + typedefs and data structures + ***********************************************************************/ +/** @enum TfuDciFormat + * This Enum has values for the DCI format types. + */ +typedef enum +{ + TFU_DCI_FORMAT_0, /*!< DCI format 0 */ + TFU_DCI_FORMAT_1, /*!< DCI format 1 */ + TFU_DCI_FORMAT_1A, /*!< DCI format 1A */ + TFU_DCI_FORMAT_1B, /*!< DCI format 1B */ + TFU_DCI_FORMAT_1C, /*!< DCI format 1C */ + TFU_DCI_FORMAT_1D, /*!< DCI format 1D */ + TFU_DCI_FORMAT_2, /*!< DCI format 2 */ + TFU_DCI_FORMAT_2A, /*!< DCI format 2A */ + TFU_DCI_FORMAT_3, /*!< DCI format 3 */ + TFU_DCI_FORMAT_3A /*!< DCI format 3A */ +#ifdef TFU_5GTF + ,TFU_DCI_FORMAT_A1, /*!< 5GTF: DCI format A1 */ + TFU_DCI_FORMAT_A2, /*!< 5GTF: DCI format A2 */ + TFU_DCI_FORMAT_B1, /*!< 5GTF: DCI format B1 */ + TFU_DCI_FORMAT_B2 /*!< 5GTF: DCI format B2 */ +#endif +#ifdef EMTC_ENABLE + ,TFU_DCI_FORMAT_6_0A, /*!< DCI format 6-0 A */ + TFU_DCI_FORMAT_6_0B, /*!< DCI format 6-0 B */ + TFU_DCI_FORMAT_6_1A, /*!< DCI format 6-1 A */ + TFU_DCI_FORMAT_6_1B, /*!< DCI format 6-1 B */ + TFU_DCI_FORMAT_6_2 /*!< DCI format 6-2 */ +#endif + /*tfu_x_001.main_6 - Added support for SPS*/ +#ifdef LTEMAC_SPS + ,TFU_DCI_FORMAT_INVALID /*!< Invalid DCI format value */ +#endif +} TfuDciFormat; + +/** @enum TfuModScheme + * This enum contains the values for the modulation schemes possible. + */ +typedef enum +{ + TFU_MOD_BPSK = 1, + TFU_MOD_QPSK = 2, + TFU_MOD_16QAM = 4, + TFU_MOD_64QAM = 6 +} TfuModScheme; + + +/** @enum TfuDlCqiPucchMode + * This enum contains values for the CQI reporting modes. + */ +typedef enum +{ + TFU_PUCCH_CQI_MODE10, + TFU_PUCCH_CQI_MODE11, + TFU_PUCCH_CQI_MODE20, + TFU_PUCCH_CQI_MODE21 +} TfuDlCqiPucchMode; + +/** @enum TfuRptType + * This enum contains values for Type of UEs CQI reporting. + */ +typedef enum +{ + TFU_RPT_CQI, + TFU_RPT_RI +} TfuRptType; + + +#ifdef PHY_ERROR_LOGING +typedef struct _rgSchUlAllocCntr RgSchUlAllocCntr; + +struct _rgSchUlAllocCntr +{ + U8 mcs; + U16 numOfRb; + U16 rbStart; + Bool testStart; + Bool enaLog; + U16 logTime; + U32 crcOk; + U32 crcErr; + U32 numUlPackets; + U32 numPrach; + U32 taZero; +}; + +EXTERN RgSchUlAllocCntr rgSchUlAllocCntr; + +#endif +//Chandan +#ifdef DLHQ_STATS +typedef struct rgSchDlHqStats +{ + U16 sfn; + U8 sf; + U8 ack; + U8 cellId; + U8 ulDai; + U8 dlDai; + U8 fdbkIdx; + U8 ue; + U8 ack0; + U8 ack1; + U8 ack2; + U8 ack3; + U8 ack4; + U8 ack5; + U8 ack6; + U8 ack7; +}RgSchDlHqStats; +typedef struct ysMsDlHqStats +{ + U16 sfn; + U8 sf; + U8 mode; /*1 = PUCCH 2= PUSCH*/ + U8 M; + U8 o0; /*For PUCCH n1PUCCH*/ + U8 o1; /*For PUCCH Invalid*/ + U8 o2; + U8 o3; + U8 ack0; + U8 ack1; + U8 ack2; + U8 ack3; + U8 ack4; + U8 ack5; + U8 ack6; + U8 ack7; +}YsMsDlHqStats; +#define MAX_STATS_CNT +#endif + +#ifdef TFU_5GTF +/* Considers case where RIV is <= 324 for DCI format A1 */ +typedef struct tfuRbAssignA1Val324 +{ + U8 hqProcId; /*!< HARQ process ID */ + U8 mcs; /*!< 4 bits for MCS */ + Bool ndi; /*!< 1 bit for new data indicator */ +} TfuRbAssignA1Val324; + +/* Considers case where RIV is <= 324 for DCI format B1 */ +typedef struct tfuRbAssignB1Val324 +{ + U8 hqProcId; /*!< HARQ process ID */ + U8 mcs; /*!< 4 bits for MCS */ + Bool ndi; /*!< 1 bit for new data indicator */ + U8 RV; /*!< 2 bits Redundancy version */ + U8 bmiHqAckNack; /* BMI: Bit Mapping Index for Harq-Ack + Refer sec 8.5 of 213 spec */ +} TfuRbAssignB1Val324; + +/* Considers case where RIV is == 326 */ +typedef struct tfuRbAssignVal326 +{ + U8 FreqBandIdx; /* nRACH: Frequency band index Value:0 -> 7 */ + Bool OCCInd; /* nOCC: OCC indicator Value:0 -> 1 */ + U8 CyclicShiftInd; /* nNcs: Cyclic shift indicator Value:0 -> 3 */ +} TfuRbAssignVal326; + + +/* DCI format A1: UL xPDCCH */ +typedef struct tfuDciFormatA1Info +{ + Bool formatType; /* Format Descriminator 00: A1, 01:A2 */ + U8 xPUSCHRange; /* 0 : the stopping of xPUSCH is the 12th symbol, + 1 : the stopping of xPUSCH is the 13th symbol, + 2 : the stopping of xPUSCH is the final (14th) symbol */ + U8 xPUSCH_TxTiming; /* Transmission timing of xPUSCH Value: 0->7 + l E {0,1,...,7}*/ + U16 RBAssign; /*!< same as phy i/f RBAssign: RIV as defined in V5G.213 + Value <= 324: this field assigns morethan zero RB. + Value ==325: this format assigns zero RB. + Value ==326: this format assigns zero RB and used + for Randon Access procedure initiated by xPDCCH order. */ + U8 beamIndex; /*!< transmit beam index: Value: 0->7 */ + U8 symbIdx; /*!< OFDM symbol index for the xPDCCH: Value: 0->1 */ + U8 rv; /*!< HARQ redundancy version, Value: 0 -> 3 */ + + /* Based on RBAssign/RIV value*/ + union + { + TfuRbAssignA1Val324 rbAssignA1Val324; + TfuRbAssignVal326 rbAssignVal326; + }u; + + U8 CSI_BSI_BRI_Req; /* CSI / BSI / BRI request Value:0 -> 7 */ + U8 CSIRS_BRRS_TxTiming; /* Transmission timing of CSI-RS / BRRS, Value:0 -> 3 + m E {0,1,2,3} */ +#ifdef FIVEGTF_PHY_API + U16 rbgStart; + U16 rbgSize; +#endif + + /* ToDo: following 4 fields can be made as union with an indicator type*/ + U8 CSIRS_BRRS_SymbIdx; /* Indication of OFDM symbol index for CSI-RS / BRRS allocations + Value:0 -> 3 */ + U8 CSI_BRRS_Indicator; /* If this DCI format allocates either of + CSI-RS or BRRS transmission Value:0 -> 3 */ + U8 CSIRS_BRRS_ProcInd; /* Process indicator : Value:0 -> 3 */ + U8 numBSI_Reports; /* Number of BSI reports Value:0 -> 3 */ + + Bool uciOnxPUSCH; /* "UCI on xPUSCH w/o xUL-SCH data" indicator. Value:0 -> 1 */ + Bool beamSwitch; /* beam switch indication. Value:0 -> 1 */ + + U8 SRS_Config; /* Indication of SRS configurations Value:0 -> 3 + 00 : {No SRS request}, 01 : {Config. #0}, + 10 : {Config. #1}, 11 : {Config. #2} */ + Bool SRS_Symbol; /* If SRS is requested, 0: SRS transmission on the 13th OFDM symbol + and 1: SRS transmission on the 14th OFDM symbol */ + + U8 REMapIdx_DMRS_PCRS_numLayers; /* RE Mapping index, Ki for DMRS/PCRS and number of layers + Value: 0 -> 7 + 0: 1 Layer, k0 = 0, 1: 1 Layer, k0 = 1 + 2: 1 Layer, k0 = 2, 3: 1 Layer, k0 = 3 + 4: 2 Layers, k0 = 0 and k1 = 1 + 5: 2 Layers, k0 = 2 and k1 = 3 + 6,7: Reserved */ + Bool SCID; /* nSCID is applied for both DMRS in subframe n and + CSI-RS in subframe n+m Value: 0 -> 1 */ + U8 PMI; /* Precoding matrix indicator Value:0 -> 7 */ +#ifdef FIVEGTF_PHY_API + U8 AntPorts_numLayers; + U8 TransmissionScheme; +#endif + Bool UL_PCRS; /* UL dual PCRS Value: 0 -> 1 */ + U8 tpcCmd; /*!< 2 bits for TPC command for xPUSCH, Values: 0->3 */ +} TfuDciFormatA1Info; + +/* DCI format A2: UL xPDCCH */ +typedef TfuDciFormatA1Info TfuDciFormatA2Info; + +/* DCI format B1: DL xPDCCH */ +typedef struct tfuDciFormatB1Info +{ + Bool formatType; /* Format Descriminator 2: B1, 3:B2 */ + U8 xPDSCHRange; /* MSB (starting of xPDSCH including DMRS symbol) : + 0 is the second symbol, 1 is the third symbol. + LSB (stopping of xPDSCH): 0 is the 12th symbol, + 1 is the 14th symbol */ + U16 RBAssign; /*!< same as phy i/f RBAssign: RIV as defined in V5G.213 + Value <= 324: this field assigns morethan zero RB. + Value ==325: this format assigns zero RB. + Value ==326: this format assigns zero RB and used + for Randon Access procedure initiated by xPDCCH order. */ + U8 beamIndex; /*!< transmit beam index: Value: 0->7 */ + U8 symbIdx; /*!< OFDM symbol index for the xPDCCH: Value: 0->1 */ + /* Based on RBAssign/RIV value*/ + union + { + TfuRbAssignB1Val324 rbAssignB1Val324; + TfuRbAssignVal326 rbAssignVal326; + }u; + + U8 CSI_BSI_BRI_Req; /* CSI / BSI / BRI request Value:0 -> 7 */ + U8 CSIRS_BRRS_TxTiming; /* Transmission timing of CSI-RS / BRRS, Value:0 -> 3 + m E {0,1,2,3} */ + /* ToDo: following 4 fields can be made as union with an indicator type*/ + U8 CSIRS_BRRS_SymbIdx; /* Indication of OFDM symbol index for CSI-RS / BRRS allocations + Value:0 -> 3 */ + U8 CSI_BRRS_Indicator; /* If this DCI format allocates either of + CSI-RS or BRRS transmission Value:0 -> 3 */ + U8 CSIRS_BRRS_ProcInd; /* Process indicator : Value:0 -> 3 */ + U8 numBSI_Reports; /* Number of BSI reports Value:0 -> 3 */ + + Bool xPUCCH_TxTiming; /* field indicates transmission time offset value k.{0, 1, ., 7} */ + U8 freqResIdx_xPUCCH; /* Frequency resource index of xPUCCH for UCI report */ + Bool beamSwitch; /* beam switch indication. Value:0 -> 1 */ + + U8 SRS_Config; /* Indication of SRS configurations Value:0 -> 3 + 00 : {No SRS request}, 01 : {Config. #0}, + 10 : {Config. #1}, 11 : {Config. #2} */ + Bool SRS_Symbol; /* If SRS is requested, 0: SRS transmission on the 13th OFDM symbol + and 1: SRS transmission on the 14th OFDM symbol */ + + U8 AntPorts_numLayers; + + Bool SCID; /* nSCID is applied for both DMRS in subframe n and + CSI-RS in subframe n+m Value: 0 -> 1 */ + U8 tpcCmd; /*!< 2 bits for TPC command for xPUCCH, Values: 0->3 */ + Bool DL_PCRS; /* DL PCRS Value: 0 -> 3 + 00 : {No PCRS }, 01 : {PCRS on AP 60}, + 10 : {PCRS on AP 61}, 11 : {PCRS on AP 60 and 61}*/ + +} TfuDciFormatB1Info; + +/* DCI format B2: DL xPDCCH */ +typedef TfuDciFormatB1Info TfuDciFormatB2Info; +#endif /* TFU_5GTF */ + +/** @brief This structure contains the information needed to convey DCI format 0. + */ +typedef struct tfuDciFormat0Info +{ + Bool isSrGrant; /*!< This is to aid a counter which prints num successful SR Grants SR_RACH_STATS */ + Bool isMsg4PdcchWithCrnti; /* This is to aid rgNumMsg4PdcchWithCrnti counter which counts + num of PDCCH scrambled with CRNTI for CRNTI Based contention resolution */ + Bool hoppingEnbld; /*!< TRUE, if hopping is enabled */ + U8 rbStart; /*!< Starting RB */ + U8 numRb; /*!< Number of RBs */ +#ifdef TFU_UPGRADE + U32 riv; /*!< RIV as defined in 213 + section 7.1.6.3 - used only for + SPS release */ +#endif + U8 hoppingBits; /*!< Hopping bits as mentioned in 213 section 8.4 */ + U8 mcs; /*!< 5 bits for MCS and RV */ + Bool ndi; /*!< 1 bit for new data indicator */ + U8 tpcCmd; /*!< 2 bits for TPC command */ +/** @name TFU_TDD */ +/** @{ */ +#ifdef TFU_TDD + U8 ulIdx; /*!< UL index applicable only for TDD */ + U8 dai; /*!< The downlink assignement index */ +#endif +/** @} */ + U8 nDmrs; /*!< 3 bits for DMRS cyclic shift */ + U8 cqiReq; /*!< 1 bit for CQI non-CA while value 00, 01, 10 and 11 for CA */ + U8 numCqiBit; /*!< Number of CsiReq Bit(s) Values : 1 or 2(CA)*/ + U8 txAntenna; /*!< Antenna selection - 213 section 8.7 */ + + /* tfu_x_001.main_4: Adding hqProcId */ + U8 hqProcId; /*!< HARQ process ID */ +} TfuDciFormat0Info; + +/** @enum TfuAllocType + * This enum contains the values for the allocation types. + */ +typedef enum +{ + TFU_ALLOC_TYPE_MAP= 1, + TFU_ALLOC_TYPE_RIV +} TfuAllocType; + +/** @brief This Structure contains either a resource allocation bit map OR a + * RIV Value as defined in 213 section 7.1.6. + */ +typedef struct tfuAllocMapOrRiv +{ + TfuAllocType type; /*!< Allocation type RIV or resAllocMap */ + union + { + + U32 riv; /*!< RIV as defined in 213 section 7.1.6.3. */ + /*tfu_x_001.main_8 - ADD - TFU_RESMAP_CHANGE support */ +#ifndef TFU_RESMAP_CHANGE + U8 resAllocMap[TFU_MAX_ALLOC_BYTES]; /*!< Resource + allocation bitmap. LSB aligns with the + LSB of the allocation bits.*/ +#else /* TFU_RESMAP_CHANGE */ + TfuAllocMap allocMap; /*!< Allocation Map. */ +#endif + }u; +} TfuAllocMapOrRiv; + +/** @enum TfuAllocSubType + * This enum contains the values for the allocation types. + */ +typedef enum +{ + TFU_ALLOC_TYPE_0= 1, + TFU_ALLOC_TYPE_1 +} TfuAllocSubType; + + +#ifdef LTEMAC_SPS +/** @brief This Structure contains either a resource allocation bitmap for + * for resource allocation type 0/1. + * TODO: This structure can be made part of all DCI format having alloction + * type 0/1. + */ +typedef struct tfuAllocMap +{ + TfuAllocSubType type; /*!< Allocation type: 0/1 */ + union + { + struct + { + U32 allocMask; /*!< Allocation Mask for RBGs */ + } allocType0; + struct + { + U8 rbgSubset; /*!< RBG Subset number: Value in set + {0,1,2,3} */ + U8 shift; /*!< Shift value for RBG mask: Value in + set {0,1} */ + U32 allocMask; /*!< Allocation bitmask */ + } allocType1; + } u; +} TfuAllocMap; +#endif + +/** @brief This structure contains only the allocation information, that is part + * of DCI format 1. + * @details Allocation information also contains parameters necessary + * for Physical layer to process Downlink data. This structure accompanies the + * Data that is sent from MAC to PHY in the TfUiTfuDatReq primitive. + * @sa TfuDciFormat1Info + */ +typedef struct tfuDciFormat1AllocInfo +{ + Bool isAllocType0; /*!< TRUE, if allocation type is 0 */ + U8 resAllocMap[TFU_MAX_ALLOC_BYTES]; /*!< Resource allocation bitmap. + LSB aligns with the LSB of the + allocation bits.*/ + U8 harqProcId; /*!< HARQ process ID */ + Bool ndi; /*!< 1 bit for new data indicator */ + U8 mcs; /*!< 5 bits for MCS */ + U8 rv; /*!< Redundancy version */ +} TfuDciFormat1AllocInfo; + +/** @brief This structure contains the information needed to convey DCI format 1. + * @details Allocation information is separated from the other control + * information carried in this format. This separation is needed as Data must + * also carry some control information, essentially, allocation information + * along with it, in order to aid physical layer processing of the data. + */ +typedef struct tfuDciFormat1Info +{ + TfuDciFormat1AllocInfo allocInfo; /*!< Allocation Information to map data on PDSCH */ +/** @name TFU_TDD */ +/** @{ */ +#ifdef TFU_TDD + U8 dai; /*!< The downlink assignement index */ +#endif +/** @} */ + U8 tpcCmd; /*!< 2 bits for TPC command */ +} TfuDciFormat1Info; + +/** @brief This structure contains the TB level DCI signalling + * parameters in case of DCI formats 2 and 2A */ +typedef struct tfuDciFormatTbInfo +{ + Bool ndi; /*!< New data indicator */ + U8 rv; /*!< Redundancy version Indicator */ + U8 mcs; /*!< 5 bits for MCS */ +}TfuDciFormatTbInfo; +/** @} */ +/** @brief This structure contains only the allocation information, that is part + * of DCI format 2A. + * @details Allocation information also contains parameters necessary + * for Physical layer to process Downlink data. This structure accompanies the + * Data that is sent from MAC to PHY in the TfUiTfuDatReq primitive. + * @sa TfuDciFormat2AInfo + */ +typedef struct tfuDciFormat2AAllocInfo +{ + Bool isAllocType0; /*!< TRUE, if allocation type is 0 */ + /*tfu_x_001.main_8 - ADD - TFU_RESMAP_CHANGE support */ +#ifndef TFU_RESMAP_CHANGE + U8 resAllocMap[TFU_MAX_ALLOC_BYTES]; /*!< Resource allocation bitmap. + LSB aligns with the LSB of the + allocation bits.*/ +#else + TfuAllocMap allocMap; /*!< Allocation Map */ +#endif /* TFU_RESMAP_CHANGE */ + U8 harqProcId; /*!< HARQ process ID */ + TfuDciFormatTbInfo tbInfo[2]; /*!< DCI Format 2/2A info per TB */ + U8 precoding; /*!< Precoding information bit */ + Bool transSwap; /*!< Transport block to codeword swap flag */ +} TfuDciFormat2AAllocInfo; + + +/** @brief This structure contains the information carried by DCI format 2A. + * @details It carries the allocation information and other control information. + */ +typedef struct tfuDciFormat2AInfo +{ + TfuDciFormat2AAllocInfo allocInfo; /*!< Allocation Information to map data on PDSCH */ +/** @name TFU_TDD */ +/** @{ */ +#ifdef TFU_TDD + U8 dai; /*!< The downlink assignement index */ +#endif +/** @} */ + U8 tpcCmd; /*!< 2 bits for TPC command */ +} TfuDciFormat2AInfo; + +/** @brief This structure contains only the allocation information, that is part + * of DCI format 2. + * @details Allocation information also contains parameters necessary + * for Physical layer to process Downlink data. This structure accompanies the + * Data that is sent from MAC to PHY in the TfUiTfuDatReq primitive. + * @sa TfuDciFormat2Info + */ +typedef struct tfuDciFormat2AllocInfo +{ + Bool isAllocType0; /*!< TRUE, if allocation type is 0 */ +#ifndef TFU_RESMAP_CHANGE + U8 resAllocMap[TFU_MAX_ALLOC_BYTES]; /*!< Resource + allocation bitmap. LSB aligns + with the LSB of the allocation + bits.*/ +#else + TfuAllocMap allocMap; /*!< Allocation Map.*/ +#endif +/** @} */ +/** @name TFU_TDD */ +/** @{ */ +#ifdef TFU_TDD + U8 dai; /*!< The downlink assignement index */ +#endif +/** @} */ + Bool transSwap; /*!< Transport block to codeword swap + flag */ + U8 precoding; /*!< Precoding information bit */ + U8 harqProcId; /*!< HARQ process ID */ + TfuDciFormatTbInfo tbInfo[2]; /*!< DCI Format 2/2A info per TB */ +} TfuDciFormat2AllocInfo; + + + /** @brief This structure contains the information carried by DCI format 2. + * @details Allocation information is separated from the other control + * information carried in this format. This separation is needed as Data must + * also carry some control information, essentially, allocation information + * along with it, in order to aid physical layer processing of the data. + */ +typedef struct tfuDciFormat2Info +{ + TfuDciFormat2AllocInfo allocInfo; /*!< Allocation Information to map + data on PDSCH */ + U8 tpcCmd; /*!< 2 bits for TPC command */ +/** @{ */ +/** @name TFU_TDD */ +/** @{ */ +#ifdef TFU_TDD + U8 dai; /*!< The downlink assignment index */ +#endif +/** @} */ +/** @} */ +} TfuDciFormat2Info; + + /** @brief This structure contains the information carried in DCI format 3. + */ +typedef struct tfuDciFormat3Info +{ + U8 tpcCmd[TFU_MAX_2BIT_TPC]; /*!< 2 bits for TPC command. + LSB corresponds to the 1st bit of the 1st + byte.*/ + U8 isPucch; /*!< 1 if the TPC meant for PUCCH, 0 if the TPC meant for PUSCH */ + +} TfuDciFormat3Info; + + /** @brief This structure contains the information carried by DCI format 3A. + */ +typedef struct tfuDciFormat3AInfo +{ + U8 tpcCmd[TFU_MAX_1BIT_TPC]; /*!< 1 bit for TPC command. + LSB corresponds to the 1st bit of the + 1st byte.*/ + U8 isPucch; /*!< 1 if the TPC meant for PUCCH, 0 if the TPC meant for PUSCH */ +} TfuDciFormat3AInfo; + + + + /** @brief This structure contains only the allocation information that is part + * of DCI format 1D. + * @details Allocation information also contains parameters necessary + * for Physical layer to process Downlink data. This structure accompanies the + * Data that is sent from MAC to PHY in the TfUiTfuDatReq primitive. + * @sa TfuDciFormat1dInfo + */ +typedef struct tfuDciFormat1dAllocInfo +{ + Bool isLocal; /*!< TRUE, if localised VRB */ + TknU8 nGap2; /*!< 1 indicates Ngap=Ngap,1 and 2 indicates Ngap,2 */ + TfuAllocMapOrRiv alloc; /*!< Allocation represented as a bit-map or RIV */ + U8 mcs; /*!< 5 bits for MCS */ + U8 rv; /*!< Redundancy version */ + U8 tPmi; /*!< PMI */ +} TfuDciFormat1dAllocInfo; + + /** @brief This structure contains the information carried by DCI format 1D. + * @details Allocation information is separated from the other control + * information carried in this format. This separation is needed as Data must + * also carry some control information, essentially, allocation information + * along with it, in order to aid physical layer processing of the data. + */ +typedef struct tfuDciFormat1dInfo +{ + TfuDciFormat1dAllocInfo allocInfo; /*!< Allocation information */ + U8 harqProcId; /*!< HARQ process ID */ + Bool ndi; /*!< 1 bit for new data indicator */ + U8 tpcCmd; /*!< 2 bits for TPC command */ +/** @name TFU_TDD */ +/** @{ */ +#ifdef TFU_TDD + U8 dai; /*!< The downlink assignement index */ +#endif +/** @} */ + U8 dlPwrOffset; /*!< Downlink power offset */ +} TfuDciFormat1dInfo; + + + /** @brief This structure contains only the allocation information, that is part + * of DCI format 1C. + * @details Allocation information also contains parameters necessary + * for Physical layer to process Downlink data. This structure accompanies the + * Data that is sent from MAC to PHY in the TfUiTfuDatReq primitive. + * @sa TfuDciFormat1CInfo + */ +typedef struct tfuDciFormat1cInfo +{ + TknU8 nGap2; /*!< 1 indicates Ngap=Ngap,1 and 2 indicates Ngap,2 */ + TfuAllocMapOrRiv alloc; /*!< Allocation represented as a bit-map or RIV */ + U8 iTbs; /*!< 5 bits for I-tbs */ +} TfuDciFormat1cInfo; + + + /** @brief This structure contains only the allocation information, that is part + * of DCI format 1 B. + * @details Allocation information also contains parameters necessary + * for Physical layer to process Downlink data. This structure accompanies the + * Data that is sent from MAC to PHY in the TfUiTfuDatReq primitive. + * @sa TfuDciFormat1BInfo + */ +typedef struct tfuDciFormat1bAllocInfo +{ + Bool isLocal; /*!< TRUE, if localised VRB */ + TknU8 nGap2; /*!< 1 indicates Ngap=Ngap,1 and 2 indicates Ngap,2 */ + TfuAllocMapOrRiv alloc; /*!< Allocation represented as a bit-map or RIV */ + U8 mcs; /*!< 5 bits for MCS */ + U8 rv; /*!< Redundancy version */ + U8 harqProcId; /*!< HARQ process ID */ + Bool ndi; /*!< 1 bit for new data indicator */ + U8 tPmi; /*!< PMI */ + Bool pmiCfm; /*!< PMI confirmation bit */ +} TfuDciFormat1bAllocInfo; + + + /** @brief This structure contains the information that is carried in DCI + * format 1A for a PDCCH order. + */ +typedef struct tfuPdcchOrderInfo +{ + U8 preambleIdx; /*!< Dedicated preamble index */ + U8 prachMaskIdx; /*!< PRACH Mask index used to determine the + subframe to be used for RACH */ +} TfuPdcchOrderInfo; + + /** @brief This structure contains only the allocation information that is part + * of DCI format 1A. + * @details Allocation information also contains parameters necessary + * for Physical layer to process Downlink data. This structure accompanies the + * Data that is sent from MAC to PHY in the TfUiTfuDatReq primitive. + * @sa TfuDciFormat1AInfo + */ +typedef struct tfuDciFormat1aAllocInfo +{ + Bool isLocal; /*!< TRUE, if localised VRB */ + TknU8 nGap2; /*!< 1 indicates Ngap=Ngap,1 and 2 indicates Ngap,2 */ + TfuAllocMapOrRiv alloc; /*!< Allocation carries RIV or a bitmap */ + U8 mcs; /*!< 5 bits for MCS */ + U8 rv; /*!< Redundancy version */ + TknU8 harqProcId; /*!< HARQ process ID. Reserved + if RA-RNTI, P-RNTI, SI-RNTI is used */ + Bool ndi; /*!< 1 bit for new data indicator */ +} TfuDciFormat1aAllocInfo; + + /** @brief This structure contains the information carried in DCI format 1A + * when it is NOT used for a PDCCH order. + */ +typedef struct tfudciformat1aPdsch +{ + TfuDciFormat1aAllocInfo allocInfo; /*!< Allocation information. */ +/** @name TFU_TDD */ +/** @{ */ +#ifdef TFU_TDD + TknU8 dai; /*!< The downlink assignement index. Reserved + if RA-RNTI, P-RNTI, SI-RNTI is used. */ +#endif +/** @} */ + U8 tpcCmd; /*!< 2 bits for TPC command. */ + Bool isTBMsg4; /*!< This field is added to help counting num of Msg4 Tx failures */ +} Tfudciformat1aPdsch; +/*tfu_x_001.main_6 - Added for SPS support*/ +/** @brief This structure contains the information needed to convey DCI format 1A. + * @details Format can possibly carry PDSCH allocation or information needed for + * a PDCCH order, used to initiate a RACH procedure in cases where UE looses + * synchronization with eNodeB. + */ +typedef struct tfuDciFormat1aInfo +{ + /*tfu_x_001.main_6- Added for SPS support*/ + Bool isPdcchOrder; + union + { + TfuPdcchOrderInfo pdcchOrder; /*!< PDDCH order information */ + Tfudciformat1aPdsch pdschInfo; /*!< PDSCH allocation information */ + /*tfu_x_001.main_6 - Added for SPS support*/ + }t; +} TfuDciFormat1aInfo; + +/** @brief This structure contains the information needed to convey DCI format 1A. + * @details Allocation information is separated from the other control + * information carried in this format. This separation is needed as Data must + * also carry some control information, essentially, allocation information + * along with it, in order to aid physical layer processing of the data. + */ +typedef struct tfuDciFormat1bInfo +{ + TfuDciFormat1bAllocInfo allocInfo; /*!< Allocation information */ +/** @name TFU_TDD */ +/** @{ */ +#ifdef TFU_TDD + U8 dai; /*!< The downlink assignement index */ +#endif +/** @} */ + U8 tpcCmd; /*!< 2 bits for TPC command */ +} TfuDciFormat1bInfo; +#ifdef EMTC_ENABLE +/** @brief This structure contains the information needed to convey DCI format 6-0A. + */ +typedef struct tfuDciFormat60aInfo +{ + Bool hoppingEnbld; /*!< TRUE, if hopping is enabled */ + U32 riv; /*!<9 bits, type2 allocation, RIV as defined in 213 section 7.1.6.3. */ + U8 mcs; /*!< 4 bits for MCS and RV */ + U8 rep; /*!< 2 bits, repetion number */ + U8 hqProcId; /*!< HARQ process ID */ + Bool ndi; /*!< 1 bit for new data indicator */ + U8 rv; /*!< 2 bits - Redundancy version */ + U8 tpcCmd; /*!< 2 bits for TPC command */ +#ifdef TFU_TDD +/* TODO_Mavericks: Check if DAI is required for FDD also */ + U8 ulIdx; /*!< UL index applicable only for TDD */ + U8 dai; /*!< The downlink assignement index */ +#endif + Bool cqiReq; /*!< 1 bit for CQI */ + Bool isSrs; /*!< 1 bit for SRS */ + U8 dciRep; /*!< 2 bits for DCI Subframe repetition */ +} TfuDciFormat60aInfo; +/** @brief This structure contains only the allocation information, that is part + * of DCI format 6-1A. + * @details Allocation information also contains parameters necessary + * for Physical layer to process Downlink data. This structure accompanies the + * Data that is sent from MAC to PHY in the TfUiTfuDatReq primitive. + * @sa TfuDciFormat61AInfo + */ +typedef struct tfuDciFormat61AllocInfo +{ + U32 riv; /*!<9 bits, type2 allocation, RIV as defined in 213 section 7.1.6.3. */ +/* TODO_EMTC: Add start RB, number of RB, Narrow band if required */ + U8 harqProcId; /*!< HARQ process ID */ + Bool ndi; /*!< 1 bit for new data indicator */ + U8 mcs; /*!< 4 bits for MCS and RV */ + U8 rv; /*!< 2 bits - Redundancy version */ + U32 scramblerInitValue; /*!< Scrambler init(Cinit) value as per 36.211 */ +} TfuDciFormat61AllocInfo; + + /** @brief This structure contains the information carried in DCI format 6-1A + * when it is NOT used for a PDCCH order. + */ +typedef struct tfudciformat61aPdsch +{ + TfuDciFormat61AllocInfo allocInfo; /* Allocation info for 6-1A */ + Bool hoppingEnbld; /*!< TRUE, if hopping is enabled */ + U8 rep; /*!< 2 bits, repetion number */ + U8 tpcCmd; /*!< 2 bits for TPC command */ +#ifdef TFU_TDD +/* TODO_Maveri: Check if DAI is required for FDD also */ + U8 dai; /*!< The downlink assignement index */ +#endif + U8 antPortAndScrId; /*!< 2 bits - Antenna port(s) and scrambling identity */ + Bool isSrs; /*!< 1 bit for SRS */ + U8 tPmi; /*!< 2 0r 4 bits: TPMI information for precoding */ + U8 pmiCfm; /*!< 1 bit, PMI confirmation for precoding */ + U8 harqAckOffst; /*!< 2 bits, HARQ-ACK resource offset */ + U8 dciRep; /*!< 2 bits for DCI Subframe repetition */ + Bool isTBMsg4; /*!< This field is added to help counting num of Msg4 Tx failures */ +} Tfudciformat61aPdsch; +typedef struct tfuPdcchOrderInfoEmtc +{ + U32 riv; /*!<9 bits, type2 allocation, RIV as defined in 213 section 7.1.6.3. */ + U8 preambleIdx; /*!< Dedicated preamble index */ + U8 prachMaskIdx; /*!< PRACH Mask index used to determine the + subframe to be used for RACH */ + U8 ceLevel; /*!< 2 bits, Starting CE level */ +} TfuPdcchOrderInfoEmtc; + +/** @brief This structure contains the information needed to convey DCI format 6-1A. + * @details Format can possibly carry PDSCH allocation or information needed for + * a PDCCH order, used to initiate a RACH procedure in cases where UE looses + * synchronization with eNodeB. + */ +typedef struct tfuDciFormat61aInfo +{ + Bool isPdcchOrder; + union + { + TfuPdcchOrderInfoEmtc pdcchOrder; /*!< PDDCH order information */ + Tfudciformat61aPdsch pdschInfo; /*!< PDSCH allocation information */ + /*tfu_x_001.main_6 - Added for SPS support*/ + }t; +} TfuDciFormat61aInfo; + + +typedef struct tfuDciFormatForEmtcBcch +{ + U8 mcs; + U16 numOfRb; + U16 rbStart; +}TfuDciFormatForEmtcBcch; + +typedef struct tfuDirectIndication +{ + U8 directInd; /*!< 8 bit direct Indication Information*/ +}TfuDirectIndication; + +typedef struct tfuDciFormat62AllocInfo +{ + U8 riv; /*!< Narrow Band Index*/ + U8 mcs; /*! UCI is in xPUCCH, + 1 -> UCI is in xPUSCH */ + U8 pucchIndex; /*!< Frequency resource index of xPUCCH + for UCI report. [0-15] */ + U8 SCID; /*!< SCID : 0 or 1 */ + U8 bsiRpt; /*!< total num of BSI report[0,1,2,4] */ + U8 briRpt; /*!< total num of BRI report[0,1,2,4] */ +} TfuUePucchBsiBriRecpInfo; + +/** @brief This structure is sent from scheduler to PHY in order to request the + * reception of UCI (CQI, HQ, RI) information on PUCCH. + */ +typedef struct tfuUePucchUciRecpInfo +{ + U8 numBits; /*!< 1-22, 1-Only HQ, 5-Only CQI/RI, 6- both HQ CQI/RI */ + U8 pucchIndex; /*!< 0-15, PUCCH Freq Res Idx */ + U8 SCID; /*!< SCID : 0 or 1 */ +} TfuUePucchUciRecpInfo; +#endif + +/** @brief This structure is sent from scheduler to PHY in order to request the + * reception of UCI on PUCCH. This may contain the following: + * -# HARQ + * -# SR + * -# SRS + * -# CQI + * -# HARQ+SR + * -# HARQ+SRS + * -# HARQ+CQI + * -# HARQ+SR+SRS + * -# HARQ+SR+CQI + * -# SR+SRS + * -# SR+CQI + */ +typedef struct tfuUePucchRecpReq +{ + TfuUePucchRecpType uciInfo; /*!< Bitmask for the combination of UCI + to be received */ + TfuUePucchCqiRecpInfo cqiInfo; /*!< Info needed to receive CQI. Valid + if CQI is included in uciInfo */ + TfuUePucchSrRecpInfo srInfo; /*!< Info needed to receive SR. Valid + if SR is included in uciInfo */ + TfuUePucchHqRecpInfo hqInfo; /*!< Info needed to receive Harq-Valid + if HQ is included in uciInfo */ + TfuUePucchSrsRecpInfo srsInfo; /*!< Info needed to receive SRS. Valid + if SRS is included in uciInfo */ +#ifdef TFU_5GTF + TfuUePucchBsiBriRecpInfo bsiBriInfo; /*!< Info needed to receive BSI_BRI. Valid + if BSI_BRI is included in uciInfo */ + TfuUePucchUciRecpInfo uciPduInfo; /*!< Info needed to receive HQ/CQI/RI.*/ +#endif +#ifdef EMTC_ENABLE + U16 format1aRepNumber; + U16 format2aRepNumber; + U32 catMScramblerInitVal; +#endif +} TfuUePucchRecpReq; + +typedef enum +{ + TFU_PUSCH_DATA, + TFU_PUSCH_DATA_SRS, + TFU_PUSCH_DATA_HARQ, + TFU_PUSCH_DATA_HARQ_SRS, + TFU_PUSCH_DATA_CQI, + TFU_PUSCH_DATA_CQI_SRS, + TFU_PUSCH_DATA_CQI_HARQ, + TFU_PUSCH_DATA_CQI_HARQ_SRS +#ifdef TFU_5GTF + /* Message types possible on xPUCCH and xPUSCH : UL Data, UCIs: HARQ-ACK, SR, BSI, BRI, CQI/PMI/RI etc */ + /* for now only TFU_PUSCH_DATA can be considered */ +#endif +} TfuUePuschRecpType; + + /** @brief This structure is sent from scheduler to PHY in order to request the + * reception of UEs data on ULSCH. + */ +typedef struct tfuUeUlSchRecpInfo +{ + U16 size; /*!< Length of the Data in bytes*/ + /* ToDo : rbStart and numRb is kept for legacy, need to remove later */ + U8 rbStart; /*!< Start of Resource Block of + allocation */ + U8 numRb; /*!< Number of RBs allocated */ + TfuModScheme modType; /*!< Modulation order */ + U8 nDmrs; /*!< 3 bits for DMRS cyclic shift */ + Bool hoppingEnbld; /*!< TRUE, if hopping is enabled */ + U8 hoppingBits; /*!< Hopping bits as mentioned in + 213 8.4 */ + Bool isRtx; /*!< TRUE, if this is a retx */ + Bool ndi; /*!< New Data Indication */ + U8 rv; /*!< Redundancy version */ + U8 harqProcId; /*!< HARQ process ID */ + U8 txMode; /*!< UE's UL transmission mode: + 0 = SISO/SIMO, 1 = MIMO */ + U8 crntTxNb; /*!< Current Harq Tx Cntr of this TB. + Valid if frequency hopping is + enabled */ + Bool nSrs; /*!< Indicates if RBs for this TB + overlap with SRS configuration. + FALSE = No overlap,TRUE=overlap */ + U8 mcs; /*!< MCS */ +#ifdef EMTC_ENABLE + U32 repetitionNumber; + U32 scramblerInitValue; +#endif +#ifdef TFU_5GTF + U8 rbgStart; /* The starting resource block group for + this xPUSCH allocation.*/ + U8 numRbg; /* The number of resource block groups + allocated to this ULSCH grant.*/ + U8 xPUSCHRange; /* 0 : the stopping of xPUSCH is the 12th symbol, + 1 : the stopping of xPUSCH is the 13th symbol + 2 : the stopping of xPUSCH is the final (14th) symbol */ + U8 nAntPortLayer;/* 0:1 Layer, port 40 1:1 Layer, port 41 2:1 Layer, port 42 + 3:1 Layer, port 43 4:2 Layers, ports {40, 41} + 5:2 Layers, ports {42, 43} */ + U8 SCID; /*SCID : 0 or 1 */ + U8 PMI; /* Precoding matrix indicator, see V5G.211 section Table 5.3.3A.2-1 */ + Bool uciWoTBFlag; /* 0: UCI without transmit block + 1: with transmit block */ + U8 beamIndex; /* Receiving beam index Value: 0->7 */ +#endif +} TfuUeUlSchRecpInfo; + +/** @brief This structure is sent from scheduler to PHY in order to request the + * reception of CQI_RI information on PUSCH. + */ +typedef struct tfuUePuschCqiRecpInfo +{ + U8 reportType; /*! Type of CSI report. + 0 = periodic report. + 1 = aperiodic report */ + U8 cCNum; /*! The number of CC in the aperiodic report. + Value: 1->5 */ + U8 cqiPmiSzR1[CM_LTE_MAX_CELLS]; /*!< Size of DL CQI/PMI in bits for + rank 1 report[0-255] */ + U8 cqiPmiSzRn1[CM_LTE_MAX_CELLS]; /*!< Size of DL CQI/PMI in bits for + rank > 1 report[0-255] */ + TknU8 riSz[CM_LTE_MAX_CELLS]; /*!< Size of RI in bits[1-2]. Value will + be 0 (present flag-false) in frames + with no RI Occasion*/ + U8 cqiBetaOff; /*!< Beta offset for CQI[0-15]. Given + by RRC */ + U8 riBetaOff; /*!< Beta offset for RI[0-15]. Given + by RRC */ +} TfuUePuschCqiRecpInfo; + +/** @brief This structure is sent from scheduler to PHY in order to request the + * reception of HARQ information on PUSCH. + */ +typedef struct tfuUePuschHqRecpInfo +{ + U8 hqSz; /*!< Number of feedback bits: + FDD- 1 or 2 TDD- 1 to 4*/ + U8 hqBetaOff; /*!< Beta offset for Harq[0-15]. Given + by RRC */ +#ifdef TFU_TDD + TfuAckNackMode hqFdbkMode; /*!< Feedback mode in TDD */ + U8 nBundled; /*!< nBundled value intended for PHY */ + U8 ulDai; /*!< Ul Dai */ +#endif +} TfuUePuschHqRecpInfo; + +typedef TfuUePucchSrsRecpInfo TfuUePuschSrsRecpInfo; + /** @brief This structure is sent from scheduler to PHY in order to request the + * reception of UEs data on PUSCH. This may contain the following: + * -# Data + * -# Data + SRS + * -# Data + HARQ + * -# Data + HARQ + SRS + * -# Data + CQI/RI + * -# Data + CQI/RI + SRS + * -# Data + CQI/RI + HARQ + * -# Data + CQI/RI + HARQ + SRS + */ +typedef struct tfuUePuschRecpReq +{ + TfuUePuschRecpType rcpInfo; /*!< Bitmask for the combination of + information to be received */ + TfuUeUlSchRecpInfo ulSchInfo; /*!< Info needed to receive data pdu + on PUSCH. Valid if data is included + in rcpInfo */ + TfuUePuschCqiRecpInfo cqiRiInfo; /*!< Info needed to receive CQI/RI on + PUSCH. Valid if CQI is included + in rcpInfo */ + TfuUePuschHqRecpInfo hqInfo; /*!< Info needed to receive Harq on + PUSCH. Valid if HARQ is included + in rcpInfo */ + TfuUePuschSrsRecpInfo srsInfo; /*!< Info needed to receive SRS. Valid + if SRS is included in rcpInfo */ + TknU8 initialNSrs; /*!< Not present in case of only data + [0/1]. 0 = last OFDM symbol is + not punctured. 1 = last OFDM + symbol is punctured */ + TknU8 initialNumRbs; /*!< Number of RBs for initial + transmission of this TB. Not + present in case of only data */ +} TfuUePuschRecpReq; + +/** @enum TfuRecpReqType + * This enum contains values for types of Reception Request. + */ +typedef enum +{ + TFU_RECP_REQ_PUCCH, + TFU_RECP_REQ_PUSCH, + TFU_RECP_REQ_INVLD +} TfuRecpReqType; + +/** @brief This structure is a Per UE reception request for either PUCCH or PUSCH + * data. This contains information needed by PHY to decode the data sent by the + * UE. + */ +typedef struct tfuUeRecpReqInfo +{ + CmLList lnk; /*!< Link of Linked List */ + CmLteRnti rnti; /*!< RNTI of the scheduled UE */ +#ifdef TFU_5GTF + U8 groupId; /*!< UE Group ID */ +#endif + TfuRecpReqType type; /*!< Type indicating PUCCH or PUSCH */ + union + { + TfuUePucchRecpReq pucchRecpReq; /*!< Reception request for PUCCH */ + TfuUePuschRecpReq puschRecpReq; /*!< Reception request for PUSCH */ + }t; +} TfuUeRecpReqInfo; + +#else /* TFU_UPGRADE */ + +/** @enum TfuUciType + * This enum has values for the various types of UCI information present. + */ +typedef enum +{ + TFU_UCI_SR, /*!< Only a scheduling request */ + TFU_UCI_HARQ, /*!< Only HARQ-ACK feedback */ + TFU_UCI_CQI, /*!< Only CQI (periodic) report */ + TFU_UCI_HARQ_CQI, /*!< HARQ and CQI together */ + TFU_UCI_HARQ_SR /*!< HARQ and SR together */ +} TfuUciType; + +/** @enum TfuHqRecpReqType + * This enum contains values for types of HARQ Reception Request. + */ +typedef enum +{ + TFU_HQ_RECP_REQ_NORMAL, + TFU_HQ_RECP_REQ_N1PUCCH +} TfuHqRecpReqType; + + + + /** @brief This structure is sent from Scheduler to PHY in order to request the + * reception of an UE's data on PUCCH. This may contain the following: + * -# HARQ-ACK + * -# Scheduling Request (SR) + * -# HARQ-ACK and SR + * -# CQI + * -# CQI and HARQ-ACK + */ +typedef struct tfuUePucchRecpReq +{ + + TfuHqRecpReqType hqType; /*!< Type of HARQ Reception Request */ + union + { +/** @name TFU_TDD */ +/** @{ */ +#ifndef TFU_TDD + U16 nCce; /*!< Number of first CCE used for transmission of + the corresponding DCI assignment. Used to decode + HARQ-ACK. */ +#else + U16 nCce[TFU_MAX_M]; /*!< nCCE is an array in the case of TDD + HARQ ACK multiplexing. This value is + needed for the calculation of + (n^1 PUCCH,i) for i = {0,1,2,3} */ +#endif +/** @} */ + U16 n1Pucch; /*!< n1 PUCCH for ACK NACK repetition. + This is the resource that UE must + transmit the HARQ Feedback except + the first one. */ + }t; + TfuUciType type; /*!< Type of Uplink control information - value + must be one of the following: + -# TFU_UCI_SR + -# TFU_UCI_HARQ + -# TFU_UCI_CQI + -# TFU_UCI_HARQ_CQI + -# TFU_UCI_HARQ_SR + */ +/** @name TFU_TDD */ +/** @{ */ +#ifdef TFU_TDD + U8 multCnt; /*!< Number of ACK/NACK resources present */ + U8 M; /*!< Number of elements in the set K - tb. + 10.1-1 213 */ + U8 m[TFU_MAX_M]; /*!< Values utilized for TDD HARQ-ACK bundling + mode */ + U8 p[TFU_MAX_M]; /*!< "p" from 10.1 in 213 */ +#endif +/** @} */ +} TfuUePucchRecpReq; + + +/** @enum TfuRecpReqType + * This enum contains values for types of Reception Request. + */ +typedef enum +{ + TFU_RECP_REQ_PUCCH, + TFU_RECP_REQ_MSG3, + TFU_RECP_REQ_PUSCH +} TfuRecpReqType; + + + /** @brief This structure is sent from scheduler to PHY in order to request the + * reception of UEs data sent as MSG3 for Random access. + */ +typedef struct tfuUeMsg3RecpReq +{ + Bool hoppingEnbld; /*!< TRUE, if hopping is enabled */ + U8 rbStart; /*!< Start of Resource Block of allocation */ + U8 numRb; /*!< Number of RBs allocated */ + U8 mcs; /*!< 3 bits for MCS */ + Bool expCqi; /*!< TRUE, if CQI report along + with PUSCH data is expected */ + Bool ulDelay; /*!< UL Delay bit 6.2 of 213 */ + /* tfu_x_001.main_2: Presently not used, it is useful when + * Non-adaptive retransmission is implemented */ + Bool isRtx; /*!< TRUE, if this is a Msg3 retransmission */ + /*ccpu00128993 - ADD - fix for msg3 softcombining bug*/ + U8 harqProcId; /*!< HARQ process ID */ + Bool ndi; /*!< 1 bit for new data indicator */ + U8 rv; /*!< Redundancy version */ + U8 nDmrs; /*!< 3 bits for DMRS cyclic shift */ + /* tfu_x_001.main_2:107387:To include the size and ModOrder in DataRecp Request */ + U16 size; /*!< Length of the Data in bytes */ + TfuModScheme modType; /*!< Modulation order */ +} TfuUeMsg3RecpReq; + + /** @brief This structure is sent from scheduler to PHY in order to request the + * reception of UEs data on PUSCH. This may contain the following: + * -# Data + * -# Data + CQI and RI + * -# Data + CQI and HARQ + */ +typedef struct tfuUePuschRecpReq +{ + Bool hoppingEnbld; /*!< TRUE, if hopping is enabled */ + U8 hoppingBits; /*!< Hopping bits as mentioned in 213 8.4 */ + U8 rbStart; /*!< Start of Resource Block of allocation */ + U8 numRb; /*!< Number of RBs allocated */ + U8 mcs; /*!< 5 bits for MCS and RV */ + U8 harqProcId; /*!< HARQ process ID */ + Bool ndi; /*!< 1 bit for new data indicator */ + Bool isRtx; /*!< TRUE, if this is a retransmission */ + U8 rv; /*!< Redundancy version */ + U8 nDmrs; /*!< 3 bits for DMRS cyclic shift */ + Bool expCqi; /*!< TRUE, if CQI report along + with PUSCH data is expected */ + Bool expHarq; /*!< TRUE, if HARQ feedback along + with PUSCH data is expected */ + TfuDlCqiPuschMode mode; /*!< CQI reporting mode configured. Note + this value is valid, only if expCqi is + TRUE. */ + /* tfu_x_001.main_2:107387:To include the size and ModOrder in DataRecp Req.*/ + U16 size; /*!< Length of the Data in bytes*/ + TfuModScheme modType; /*!< Modulation order */ +} TfuUePuschRecpReq; + +/** @brief This structure is a Per UE reception request for either PUCCH or PUSCH + * data. This contains information needed by PHY to decode the data sent by the + * UE. + */ +typedef struct tfuUeRecpReqInfo +{ + CmLList lnk; /*!< Link of Linked List */ + CmLteRnti rnti; /*!< RNTI of the scheduled UE */ + TfuRecpReqType type; /*!< Type indicating PUCCH or MSG3 or PUSCH */ + union + { + TfuUePucchRecpReq pucchRecpReq; /*!< Reception request for PUCCH Data */ + TfuUeMsg3RecpReq msg3RecpReq; /*!< Reception request for PUCCH Data */ + TfuUePuschRecpReq puschRecpReq; /*!< Reception request for PUSCH Data */ + }t; +} TfuUeRecpReqInfo; + +#endif /* TFU_UPGRADE */ + +/** @brief This structure contains CQI information received over PUCCH or PUSCH. + */ +typedef union tfuDlCqiInfo +{ + TfuDlCqiPucch pucchCqi; /*!< PUCCH CQI information */ + struct { + U8 numOfCells; + TfuDlCqiPusch puschCqi[CM_LTE_MAX_CELLS]; /*!< PUSCH CQI information */ + }pusch; +} TfuDlCqiInfo; + +/** @brief This structure is sent from Scheduler to PHY. This includes parameters + * needed by PHY to decode the following: + * -# DATA on PUSCH + * -# HARQ Feedback on PUCCH + * -# CQI Report + * -# RI Report + * -# SR Indications + * This structure carries the reception information for all the scheduled UEs. + */ +typedef struct tfuRecpReqInfo +{ + CmMemListCp memCp; /*!< Memory control point */ + CmLteCellId cellId; /*!< Cell ID */ + CmLteTimingInfo timingInfo; /*!< Timing information */ + CmLListCp ueRecpReqLst; /*!< Linked List of reception requests + TfuUeRecpReqInfo */ +#ifdef EMTC_ENABLE + CmLListCp emtcUeRecpReqLst; /*!< Linked List of reception requests + TfuUeRecpReqInfo */ +#endif + /*tfu_x_001.main_8 - ADD - New Pucch RR Info Combination support */ + /*ccpu00116923 - ADD - SRS present support*/ +#ifdef TFU_UPGRADE + Bool srsPres; /*!< SRS present information (For Cell + Specific SRS notification) + 0: No SRS in this subframe + 1: SRS present in this subframe */ +#endif +} TfuRecpReqInfo; + + /** @brief This structure contains the PDCCH to be sent on PHY, that is, DCI + * formats. This information is associated with an RNTI. + */ + typedef struct tfuPdcchInfo +{ + CmLList lnk; /*!< Link of Linked List */ + CmLteRnti rnti; /*!< RNTI of the allocation */ +#ifdef LTEMAC_SPS + Bool isSpsRnti; /*!< TRUE if rnti is SPS RNTI */ + CmLteRnti crnti; /*!< crnti in case rnti is SPS RNTI */ +#endif + U16 nCce; /*!< CCE index */ + CmLteAggrLvl aggrLvl; /*!< Aggregation level possible values are + {1, 2, ...,8}. */ + U8 dciNumOfBits; /*!< The size of DCI in bits */ + TfuDciInfo dci; /*!< PDCCH DCI format */ +#ifdef EMTC_ENABLE + U8 distributedAlloc; + U8 localizedAntPortIndex; + U16 dmrs_txpowerControl; + U8 nRBxm; + U8 startRB; + U32 scramblerInit; + U32 demodRSInitValue; +#endif +#ifdef TFU_5GTF + U8 sectorId; /* Sector index of the 5GNB. Value: 0->2 */ + U8 sccIdx; /* Serving Cell index in the given sector. Value: 0->7 */ + U8 grpId; /* Ue group Id */ +#endif +} TfuPdcchInfo; + +/** @brief This structure contains one PHICH information. In order to locate the + * resources to be used for PHICH, the following information is provided along + * with the feedback: + * -# rbStart + * -# nDmrs + * -# iPhich + * -# txPower + * */ +typedef struct tfuPhichInfo +{ + CmLList lnk; /*!< Link of Linked List */ + U8 rbStart; /*!< Starting RB */ + U8 nDmrs; /*!< DMRS offset index */ + Bool isAck; /*!< TRUE, if ACK, else NACK */ + Bool isForMsg3; +#ifdef TFU_TDD + U8 iPhich; /*!< Needed to Calculate PHICH + location. For TDD only */ +#endif +/* tfu_x_001.main_8. Added changes of TFU_UPGRADE */ +#ifdef TFU_UPGRADE + U16 txPower; /*!< Offset to the ref. signal power */ +#endif +} TfuPhichInfo; + +/** @brief This structure is sent from Scheduler to PHY. This includes all the + * control information to be sent to the UE. + * -# PDCCH Physical Downlink Control Channel + * -# PHICH Physical HARQ Indicator Channel + * -# PCFICH Physical Control Format Indicator Channel + */ +typedef struct tfuCntrlReqInfo +{ + CmMemListCp memCp; /*!< Memory control point */ + CmLteCellId cellId; /*!< Cell ID */ + CmLteTimingInfo ulTiming; /*!< Timing information for UL PDCCHs and PHICH */ + CmLteTimingInfo dlTiming; /*!< Timing information for DL PDCCHs and CFI */ + U8 cfi; /*!< CFI value that goes on the PCFICH control channel */ + U32 numDlActvUes; /*!< Active Ues reqrd for rgu dyna delta*/ + CmLListCp ulPdcchLst; /*!< List of Uplink PDCCHs (DCI format 0) for the TfuPdcchInfo subframe */ + CmLListCp dlPdcchLst; /*!< List of Downlink PDCCHs for the TfuPdcchInfo subframe */ + CmLListCp phichLst; /*!< List of PHICHs for the TfuPhichInfo subframe */ +#ifdef LTEMAC_SPS /* SPS_NEW_CHGS */ + Bool isSPSOcc; /*!< TRUE if this is an SPS Occasion */ +#endif +#ifdef EMTC_ENABLE + CmLListCp ulMpdcchLst; /*!< List of Uplink PDCCHs (DCI format 0) for the TfuPdcchInfo subframe */ + CmLListCp dlMpdcchLst; /*!< List of Downlink PDCCHs for the TfuPdcchInfo subframe */ +#endif + +} TfuCntrlReqInfo; + + /** @brief This structure carries the control information that is needed + * by the Physical layer to process the data to be sent on PDSCH. + */ +typedef struct tfuPdschDciInfo +{ + TfuDciFormat format; /*!< Selector for the union*/ + union + { + TfuDciFormat1AllocInfo format1AllocInfo; /*!< Format 1 allocation information.*/ + TfuDciFormat1aAllocInfo format1aAllocInfo; /*!< Format 1A allocation information.*/ + TfuDciFormat1bAllocInfo format1bAllocInfo; /*!< Format 1B allocation information.*/ + TfuDciFormat1cInfo format1cAllocInfo; /*!< Format 1C allocation information.*/ + TfuDciFormat1dAllocInfo format1dAllocInfo; /*!< Format 1D allocation information.*/ + TfuDciFormat2AllocInfo format2AllocInfo; /*!< Format 2A allocation information.*/ + TfuDciFormat2AAllocInfo format2AAllocInfo; /*!< Format 2AA allocation information.*/ +#ifdef EMTC_ENABLE + TfuDciFormat61AllocInfo format61AllocInfo; /*!< Format 6-1A allocation information.*/ + TfuDciFormat62AllocInfo format62AllocInfo; /*!< Formtat 6-2 allocation information */ +#endif +#ifdef TFU_5GTF + TfuDciFormatA1Info formatA1Info; /*!< 5GTF: Format A1 information */ + TfuDciFormatA2Info formatA2Info; /*!< 5GTF: Format A1 information */ + TfuDciFormatB1Info formatB1Info; /*!< 5GTF: Format B1 information */ + TfuDciFormatB2Info formatB2Info; /*!< 5GTF: Format B2 information */ +#endif + } u; +} TfuPdschDciInfo; + +/** + * UE Transmission Modes */ +typedef enum tfuTxMode +{ + TFU_UE_TM_1 = 1, /** Transmission Mode 1 */ + TFU_UE_TM_2, /** Transmission Mode 2 */ + TFU_UE_TM_3, /** Transmission Mode 3 */ + TFU_UE_TM_4, /** Transmission Mode 4 */ + TFU_UE_TM_5, /** Transmission Mode 5 */ + TFU_UE_TM_6, /** Transmission Mode 6 */ + TFU_UE_TM_7 /** Transmission Mode 7 */ +} TfuTxMode; + +/* tfu_x_001.main_8. Added changes of TFU_UPGRADE */ +#ifdef TFU_UPGRADE + /** @brief This structure carries the Beam Forming Vector Information + * needed by the Physical layer to process the data to be sent on PDSCH. + */ + typedef struct tfuBfVectorInfo + { + U8 sbIndex; /** Subband Index */ + U8 numPhyAnt; /** Number of Physical Antennas */ + U16 bfValue[TFU_MAX_PHY_ANTENNA]; /** Beam forming vector element for + physical antenna #i real 8 bits followed by imaginary 8 bits */ + }TfuBfVectorInfo; + #endif + +#ifdef L2_OPTMZ +/** + * @brief DatReq Information of a logical channel. + */ +typedef struct tfuDatReqLchInfo +{ + Bool freeBuff; /* !< If TRUE, the buffer is to be freed by MAC */ + U32 numPdu; /*!< No of PDUs */ + Buffer *mBuf[TFU_MAX_PDU]; /*!10000, + representing -6 dB to 4 dB in + 0.001 dB steps */ +/* LTE_ADV_FLAG_REMOVED_START */ + U8 pa; /*!< ratio of PDSCH EPRE to cell-specific RS + EPRE among PDSCH REs */ +#endif + U8 isEnbSFR; /*to tell if SFR is enabled*/ +} TfuDatReqPduInfo; + + +/** @brief This structure contains the Data PDUs. + * @details This structure contains Data meant to be sent on both PBCH and + * PDSCH. Control information necessary for processing of the data is sent along + * with the Data. + */ +typedef struct tfuDatReqInfo +{ + CmMemListCp memCp; /*!< Memory control point */ + CmLteCellId cellId; /*!< Cell ID */ + CmLteTimingInfo timingInfo; /*!< Timing information */ + TknBuf bchDat; /*!< BCCH mapped onto BCH Buffer, if + present */ +#ifdef EMTC_ENABLE + TknBuf emtcBcchDat; /*!< BCCH mapped onto BCH Buffer, if + present */ +#endif + CmLListCp pdus; /*!< Linked List of TfuDatReqPduInfo PDUs */ +} TfuDatReqInfo; + + /** @brief This structure contains the Data PDU and the RNTI of the UE. + */ +typedef struct tfuDatInfo +{ + CmLList lnk; /*!< Link of Linked List */ + CmLteRnti rnti; /*!< RNTI of the UE */ +#ifdef FIVEGTF_PHY_API + TfuPdcchInfo *grantInfo; /*!< UL Grant Info */ +#endif + Buffer *mBuf; /*!< Data PDU */ +} TfuDatInfo; + +/** @brief This structure contains the Data PDUs received at Physical layer. + * @details All the PDUs received by Physical layer in one subframe are clubbed + * together into a single data structure and sent to MAC for processing. + */ +typedef struct tfuDatIndInfo +{ + CmMemListCp memCp; /*!< Memory control point */ + CmLteCellId cellId; /*!< Cell ID */ + CmLteTimingInfo timingInfo; /*!< Timing information */ + CmLListCp datIndLst; /*!< List of data PDUs - TfuDatInfo */ +#ifdef TFU_5GTF + U8 sectorId; /* Sector index of the 5GNB. Value: 0->2 */ + U8 sccIdx; /* Serving Cell index in the given sector. Value: 0->7 */ +#endif +} TfuDatIndInfo; + + /** @brief This structure contains the SR indication for an UE, identified by + * the given RNTI. The structure also contains a PUCCH Delta power, that is + * calculated by the physical layer, and is used by the scheduler for Power + * control of the UE. + */ +typedef struct tfuSrInfo +{ + CmLList lnk; /*!< Link of Linked List */ + CmLteRnti rnti; /*!< UEs RNTI */ +} TfuSrInfo; + + /** @brief This structure contains all the Scheduling Requests (SR) indications + * received in a subframe. + */ +typedef struct tfuSrIndInfo +{ + CmMemListCp memCp; /*!< Memory control point */ + CmLteCellId cellId; /*!< Cell ID */ + CmLteTimingInfo timingInfo; /*!< Timing information */ + CmLListCp srLst; /*!< List of SR indications - TfuSrInfo */ +} TfuSrIndInfo; + +/* tfu_x_001.main_8. Added changes of TFU_UPGRADE */ +//#ifdef TFU_UPGRADE +/** @enum TfuHqFdbk + * This enum contains the possible values for the HARQ feedback. + */ +typedef enum +{ + TFU_HQ_ACK=1, + TFU_HQ_NACK, + TFU_HQ_ACK_OR_NACK, + TFU_HQ_DTX, + TFU_HQ_ACK_OR_DTX, + TFU_HQ_NACK_OR_DTX, + TFU_HQ_ACK_OR_NACK_OR_DTX, + TFU_HQ_INVALID = 255 +} TfuHqFdbk; +//#endif + + /** @brief This structure contains the HARQ feedback for a single UE. + * @details RNTI is present to identify the UE. + * For FDD, a single feedback is present. + * For TDD HARQ multiplexing, a list of HARQ feedbacks is present. + */ +/* tfu_x_001.main_8. Added changes of TFU_UPGRADE */ +typedef struct tfuHqInfo +{ + CmLList lnk; /*!< Link of Linked List */ + CmLteRnti rnti; /*!< RNTI of the UE */ + TfuAckNackMode hqFdbkMode; /*!< Feedback mode */ + U8 noOfTbs; /*!< Number of TBs */ +#ifdef TFU_TDD + U8 M; /*!< Number of feedbacks multiplexed */ +#endif /* TFU_TDD */ + TfuHqFdbk isAck[TFU_MAX_HARQ_FDBKS]; /*!< Harq feedbacks */ + Bool isPusch; /*!< Indicates if this HARQ feedback is + received on PUSCH */ + /* Note: isPusch is not a field + * specified by Femto Forum. */ +} TfuHqInfo; + + /** @brief This structure contains a list of HARQ feedbacks for a number of UEs. + * @details All the HARQ feedback received in the subframe are clubbed together + * in this data structure and given to the scheduler for processing. + */ +typedef struct tfuHqIndInfo +{ + CmMemListCp memCp; /*!< Memory control point */ + CmLteCellId cellId; /*!< Cell ID */ + CmLteTimingInfo timingInfo; /*!< Timing information */ + CmLListCp hqIndLst; /*!< List of HARQ feedback - TfuHqInfo */ +} TfuHqIndInfo; + + +/** @brief This structure conveys the Uplink CQI information for a single sub-band. + */ +typedef struct tfuUlCqiInfo +{ + TfuSubbandCqiInfo subbandCqi; /*!< CQI associated with a sub-band */ +} TfuUlCqiInfo; + + /** @brief This structure contains the UL CQI estimated by the physical layer. + * @details The report can be wide-band CQI or sub-band CQI or both. + */ +typedef struct tfuUlCqiRpt +{ + CmLList lnk; /*!< Link of Linked List */ + CmLteRnti rnti; /*!< RNTI */ + Bool isTxPort0; /*!< TRUE, if TX port is + 0, else TX port is 1 */ + U8 wideCqi; /*!< Wide-band CQI*/ + U8 numSubband; /*!< Number of sub-bands */ + TfuUlCqiInfo ulCqiInfoArr[TFU_MAX_UL_SUBBAND]; /*!< UL CQI information array */ +} TfuUlCqiRpt; + +/** @brief This structure conveys the Uplink CQI information. + * @details Uplink CQI is calculated by the physical layer, and this + * information is provided to the scheduler. + * This data structure clubs together the UL CQI estimates for all the UEs that + * are scheduled in the subframe for uplink transmission. + */ +typedef struct tfuUlCqiIndInfo +{ + CmMemListCp memCp; /*!< Memory control point */ + CmLteCellId cellId; /*!< Cell ID */ + CmLteTimingInfo timingInfo; /*!< Timing information */ + CmLListCp ulCqiRpt; /*!< List of UL CQI reports - TfuUlCqiRpt */ +} TfuUlCqiIndInfo; + + /** @brief This structure contains the DOA estimated by the physical layer. + * @details DOA for a given UE. + */ +typedef struct tfuDoaRpt +{ + CmLList lnk; /*!< Link of Linked List */ + CmLteRnti rnti; /*!< RNTI */ + U32 doa; /*!< DOA for rnti */ +} TfuDoaRpt; + +/** @brief This structure conveys the DOA (Direction Of Arrival) indicator. + * @details DOA is calculated by the physical layer, and this + * information is provided to the scheduler. + * This data structure clubs together the DOAs for all the UEs + * calculated by PHY in this subframe. + */ +typedef struct tfuDoaIndInfo +{ + CmMemListCp memCp; /*!< Memory control point */ + CmLteCellId cellId; /*!< Cell ID */ + CmLListCp doaRpt; /*!< List of DOA reports - TfuDoaRpt */ +} TfuDoaIndInfo; +/** @} */ + /** @brief This structure contains the DL CQI report for a single UE. + * @details The report can either be described on PUCCH or PUSCH, a flag + * conveys this information. + */ +typedef struct tfuDlCqiRpt +{ + CmLList lnk; /*!< Link of Linked List */ + CmLteRnti rnti; /*!< RNTI */ + Bool isPucchInfo; /*!< Indicates whether PUCCH or PUSCH information */ + TfuDlCqiInfo dlCqiInfo; /*!< DL CQI information */ +} TfuDlCqiRpt; + +/** @brief This structure contains a list of Downlink CQI reports transmitted by + * UEs. + * @details This structure clubs together DL CQI reports for a number of UEs. + */ +typedef struct tfuDlCqiIndInfo +{ + CmMemListCp memCp; /*!< Memory control point */ + CmLteCellId cellId; /*!< Cell ID */ + CmLteTimingInfo timingInfo; /*!< Timing information */ + CmLListCp dlCqiRptsLst; /*!< List of DL CQI reports TfuDlCqiRpt */ +} TfuDlCqiIndInfo; + + /** @brief This structure contains the CRC indication for a single + * UE. + */ +typedef struct tfuCrcInfo +{ + CmLList lnk; /*!< Link of Linked List */ + CmLteRnti rnti; /*!< RNTI of the UE */ + Bool isFailure; /*!< TRUE, if CRC check fails */ + TknU8 rv; /*!< Redundancy version provided by PHY */ + Bool isDtx; /*! If SNR < 0 , set to TRUE */ +} TfuCrcInfo; + +/** @brief This structure contains information that is passed as a part of the + * CRC Indication from PHY to MAC. + * @details This structure clubs together all the CRC indications for + * a single subframe and conveys this information to the scheduler. + */ +typedef struct tfuCrcIndInfo +{ + CmMemListCp memCp; /*!< Memory control point */ + CmLteCellId cellId; /*!< Cell ID */ + CmLteTimingInfo timingInfo; /*!< Timing information */ + CmLListCp crcLst; /*!< List of CRC indications - TfuCrcInfo */ +#ifdef TFU_5GTF + U8 sectorId; /* Sector index of the 5GNB. Value: 0->2 */ + U8 sccIdx; /* Serving Cell index in the given sector. Value: 0->7 */ +#endif +} TfuCrcIndInfo; + + /** @brief This structure contains the timing advance information for a single + * UE. + */ + typedef struct tfuTimingAdvInfo +{ + CmLList lnk; /*!< Link of Linked List */ + CmLteRnti rnti; /*!< RNTI */ + U8 timingAdv; /*!< Value of the Timing advance */ +} TfuTimingAdvInfo; + + +/** @brief This structure contains information that is passed as part of the Timing + * Advance indication from PHY to MAC. + * @details This structure clubs together timing advances for a number of UEs. + * + */ +typedef struct tfuTimingAdvIndInfo +{ + CmMemListCp memCp; /*!< Memory control point */ + CmLteCellId cellId; /*!< Cell ID */ + CmLteTimingInfo timingInfo; /*!< Timing information */ + CmLListCp timingAdvLst; /*!< List of timing advances - TfuTimingAdvInfo */ +} TfuTimingAdvIndInfo; + +/** @brief This structure contains information that is passed as part of the TTI + * indication sent from CL to MAC and SCH. + */ +typedef struct tfuTtiCellInfo +{ + CmLteCellId cellId; /*!< Cell ID */ + CmLteTimingInfo timingInfo; /*!< SFN, SF for each cell */ + Bool isDummyTti; /*!< Flag to indicate dummy TTI */ + /* 4UE_TTI_DELTA */ + U8 schTickDelta; /*!< Dynamic Delta for SCH. Value will vary + according to num of active UEs */ + U8 dlBlankSf; /*!< TODO */ + U8 ulBlankSf; /*!< TODO */ + +} TfuTtiCellInfo; + +/** @brief This structure contains information that is passed as part of the TTI + * indication sent from CL to MAC and SCH. + */ +typedef struct tfuTtiIndInfo +{ + U8 numCells; /*!< Num of Cells */ + TfuTtiCellInfo cells[CM_LTE_MAX_CELLS]; /*!< Array of Cell timing info */ + +} TfuTtiIndInfo; + +/** @brief This structure contains the information for a single Random Access Request. + * @details The information present in this structure is for a single preamble. + * Associated with each preamble are fields that the physical layer calculates + * based on the reception of the Random Access Request. These are the following: + * -# Timing Advance + * -# TPC + * -# CQI (optional) + */ +typedef struct tfuRaReqInfo +{ + U8 rapId; /*!< ID of the preamble choosen by the UE for Random Acess.*/ + U16 ta; /*!< Amount of Timing advance needed by the UE for it + to be uplink synchronized, this is calculated by Physical layer. */ + U8 tpc; /*!< Transmit power control command that the physical + layer calculates from the RA request received.*/ + Bool cqiPres; /*!< TRUE, if CQI present. */ + U8 cqiIdx; /*!< This is the Channel Quality Index of the UL channel estimated by the + physical layer. This aids MAC in the scheduling of this UE. */ + +} TfuRaReqInfo; + + /** @brief This structure contains RACH request information for a single RA-RNTI. + */ +typedef struct tfuRachInfo +{ + CmLteRnti raRnti; /*!< RA-RNTI */ + U8 numRaReqInfo; /*!< Number of RA requests */ +#ifdef PRACH_5GTF + U8 nPreambleFormat; + U8 nPRACHConfiguration; + U8 nRootSeq; + U8 nCyclicShift; + U8 nf1Value; + U8 nPRACHSymbIndex; + U16 nPwrFactor; +#endif + TfuRaReqInfo *raReqInfoArr; /*!< RA requests */ +} TfuRachInfo; + +/** @brief This structure contains the list of Random Access Requests received in a single TTI. + * @details Random Access Request is associated with a RA-RNTI, which remains + * common for all the random access requests within a subframe. This structure + * thus carries the RA-RNTI and a list of Random Access Request information. + * This information consists of the following: + * -# preamble-id - this corresponds to the Index of the Preamble choosen by the + * UE. + * -# Timing Advance - this corresponds to the timing adjustment that the UE + * needs to be uplink synchronized. This value is calculated by physical layer. + * -# tpc - this is the power control command that the physical layer calculates + * from the received RA request. This value is transmitted in the RA Response + * sent out by MAC. + * -# CQI - this is the Channel Quality Index of the UL channel estimated by the + * physical layer. This aids MAC in the scheduling of this UE. + */ +typedef struct tfuRaReqIndInfo +{ + CmMemListCp memCp; /*!< Memory control point */ + CmLteCellId cellId; /*!< Cell ID */ + CmLteTimingInfo timingInfo; /*!< Timing information */ + U8 nmbOfRaRnti; /*!< Number of RA-RNTIs present for FDD this + must be 1 for TDD, it can be a max of 6. */ + TfuRachInfo *rachInfoArr; /*!< Array of + RACH information per + RA-RNTI */ +} TfuRaReqIndInfo; + +/** @brief This structure contains PUCCH Delta power for a single UE. + */ +typedef struct tfuPucchDeltaPwr +{ + CmLList lnk; /*!< Link of Linked List */ + CmLteRnti rnti; /*!< Memory control */ + S8 pucchDeltaPwr; /*!< PUCCH delta power to be sent by PHY. */ +} TfuPucchDeltaPwr; + +/** @brief This structure contains information that is passed as part of the + * PUCCH Delta power indication from PHY to SCH. + * @details This structure clubs together PUCCH Delta power values for a number + * of UEs. + */ +typedef struct tfuPucchDeltaPwrIndInfo +{ + CmMemListCp memCp; /*!< Memory control point */ + CmLteCellId cellId; /*!< Cell ID */ + CmLteTimingInfo timingInfo; /*!< Timing information */ + CmLListCp pucchDeltaPwrLst; /*!< List of PUCCH Delta power + TfuPucchDeltaPwr */ +} TfuPucchDeltaPwrIndInfo; /* TODO renamed this from Del -> Delta. not changed tfu.c */ + + /** @brief LAA:This structure contains the cell Id and subframe information for + * which the transmission failed. + */ +typedef struct tfuErrIndInfo +{ + CmLteCellId cellId; /*!< Cell ID */ + CmLteTimingInfo timingInfo; /*!< Timing information */ +} TfuErrIndInfo; + +#ifdef L2_OPTMZ +/** @brief :This structure contains the cell Id and UeId to inform CL + * to delete datReq if it exists in CL but UeId got changed or similar other + * scenarios.These scenarios are possible only when L2_OPTMZ flag is enabled. + */ +typedef struct tfuDelDatReqInfo +{ + CmLteCellId cellId; /*!< Cell ID */ + CmLteRnti ueId; /*!< CRNTI of the UE */ +} TfuDelDatReqInfo; +#endif + + +typedef S16 (*TfuBndReq) ARGS(( + Pst* pst, + SuId suId, + SpId spId)); +typedef S16 (*TfuBndCfm) ARGS(( + Pst* pst, + SuId suId, + U8 status)); +typedef S16 (*TfuUbndReq) ARGS(( + Pst* pst, + SpId spId, + Reason reason)); + +typedef S16 (*TfuSchBndReq) ARGS(( + Pst* pst, + SuId suId, + SpId spId)); +typedef S16 (*TfuSchBndCfm) ARGS(( + Pst* pst, + SuId suId, + U8 status)); +typedef S16 (*TfuSchUbndReq) ARGS(( + Pst* pst, + SpId spId, + Reason reason)); + +typedef S16 (*TfuRaReqInd) ARGS(( + Pst * pst, + SuId suId, + TfuRaReqIndInfo *raReqInd)); + +typedef S16 (*TfuRecpReq) ARGS(( + Pst * pst, + SpId spId, + TfuRecpReqInfo *recpReq)); + +typedef S16 (*TfuUlCqiInd) ARGS(( + Pst * pst, + SuId suId, + TfuUlCqiIndInfo * ulCqiInd)); + +typedef S16 (*TfuDoaInd) ARGS(( + Pst * pst, + SuId suId, + TfuDoaIndInfo * doaInd)); +typedef S16 (*TfuHqInd) ARGS(( + Pst * pst, + SuId suId, + TfuHqIndInfo * hqInd)); + +typedef S16 (*TfuSrInd) ARGS(( + Pst * pst, + SuId suId, + TfuSrIndInfo * srInd)); + +typedef S16 (*TfuDlCqiInd) ARGS(( + Pst * pst, + SuId suId, + TfuDlCqiIndInfo * dlCqiInd)); +/* tfu_x_001.main_8. Added changes of TFU_UPGRADE */ +#ifdef TFU_UPGRADE +typedef S16 (*TfuRawCqiInd) ARGS(( + Pst *pst, + SuId suId, + TfuRawCqiIndInfo *rawCqiInd)); + +typedef S16 (*TfuSrsInd) ARGS(( + Pst *pst, + SuId suId, + TfuSrsIndInfo *srsInd)); +#endif /* TFU_UPGRADE */ + +typedef S16 (*TfuDatInd) ARGS(( + Pst * pst, + SuId suId, + TfuDatIndInfo * datInd)); + +typedef S16 (*TfuCrcInd) ARGS(( + Pst * pst, + SuId suId, + TfuCrcIndInfo * crcInd)); + +typedef S16 (*TfuTimingAdvInd) ARGS(( + Pst * pst, + SuId suId, + TfuTimingAdvIndInfo * timingAdvInd)); + +typedef S16 (*TfuDatReq) ARGS(( + Pst * pst, + SpId spId, + TfuDatReqInfo * datReq)); + +#ifdef L2_OPTMZ +typedef S16 (*TfuDelDatReq) ARGS(( + Pst * pst, + SpId spId, + TfuDelDatReqInfo * datReq)); +#endif + +typedef S16 (*TfuCntrlReq) ARGS(( + Pst *pst, + SpId spId, + TfuCntrlReqInfo *cntrlReq)); +/* CA dev Start */ +typedef S16 (*TfuTtiCell) ARGS(( + Pst * pst, + SuId suId, + TfuTtiCellInfo * ttiInd)); +/* CA dev End */ +typedef S16 (*TfuTtiInd) ARGS(( + Pst * pst, + SuId suId, + TfuTtiIndInfo * ttiInd)); + +#if defined(TENB_T2K3K_SPECIFIC_CHANGES) && defined(LTE_TDD) +typedef S16 (*TfuNonRtInd) ARGS(( + Pst * pst, + SuId suId)); +#endif + +typedef S16 (*TfuSchTtiInd) ARGS(( + Pst * pst, + SuId suId, + TfuTtiIndInfo * ttiInd)); + +typedef S16 (*TfuPucchDeltaPwrInd) ARGS(( + Pst * pst, + SuId suId, + TfuPucchDeltaPwrIndInfo * pucchDeltaPwr)); + +/*LAA: Error Indication on LAA SCell*/ +typedef S16 (*TfuErrInd) ARGS(( + Pst * pst, + SuId suId, + TfuErrIndInfo * errInd)); + +/** @brief This API is used to send a Bind Request from MAC to PHY. + * @param pst Pointer to the post structure. + * @param suId SAP ID of the service user. + * @param spId SAP ID of the service provider. + * @return ROK/RFAILED + */ +EXTERN S16 TfUiTfuBndReq ARGS((Pst *pst, SuId suId, SpId spId)); + +/** @brief This API is used to send a Bind Request from Scheduler to PHY. + * @param pst Pointer to the post structure. + * @param suId SAP ID of the service user. + * @param spId SAP ID of the service provider. + * @return ROK/RFAILED + */ +EXTERN S16 TfUiTfuSchBndReq ARGS((Pst *pst, SuId suId, SpId spId)); + + +/** @brief This API is used to receive a Bind Confirm from PHY to MAC. + * @param pst Pointer to the post structure. + * @param suId SAP ID of the service user. + * @param status Status of the bind request. + * @return ROK/RFAILED + */ +EXTERN S16 TfUiTfuBndCfm ARGS((Pst *pst, SuId suId, U8 status)); + +/** @brief This API is used to receive a Bind Confirm from PHY to Scheduler. + * @param pst Pointer to the post structure. + * @param suId SAP ID of the service user. + * @param status Status of the bind request. + * @return ROK/RFAILED + */ +EXTERN S16 TfUiTfuSchBndCfm ARGS((Pst *pst, SuId suId, U8 status)); + + +/** @brief This API is used to send an Unbind Request from MAC to PHY. + * @param pst Pointer to the post structure. + * @param spId SAP ID of the service provider. + * @param reason Reason for Unbind request. + * @return ROK/RFAILED + */ +EXTERN S16 TfUiTfuUbndReq ARGS((Pst *pst, SpId spId, Reason reason)); + +/** @brief This API is used to send an Unbind Request from Scheduler to PHY. + * @param pst Pointer to the post structure. + * @param spId SAP ID of the service provider. + * @param reason Reason for Unbind request. + * @return ROK/RFAILED + */ +EXTERN S16 TfUiTfuSchUbndReq ARGS((Pst *pst, SpId spId, Reason reason)); + + +/** @brief This API is used to indication Random Access Request reception from + * PHY to Scheduler. + * @details This primitive is used by physical layer to indicate the reception + * of a Random Access Request from a set of UEs. The information passed consists + * of the RA-RNTI and the list of preambles received. + * @param pst Pointer to the post structure. + * @param suId SAP ID of the service user. + * @param raReqInd Pointer to the TfuRaReqIndInfo structure. + * @return ROK/RFAILED + */ +EXTERN S16 TfUiTfuRaReqInd ARGS((Pst *pst, SuId suId, TfuRaReqIndInfo + *raReqInd)); + + +/** @brief This primitive is sent from Scheduler to PHY. + * @details This primitive provides PHY with all the information required by + * PHY to decode transmissions from the UE on either PUCCH or PUSCH. + * -# On PUCCH, UE can transmit the following: + * -# SR + * -# HARQ feedback + * -# CQI report + * -# HARQ + CQI + * -# HARQ + SR + * -# On PUSCH, UE can transmit the following: + * -# Data + * -# Data + CQI + * -# Data + HARQ Feedback + * This primitive carries all the information for the expected subframe for all + * the UEs that are scheduled to transmit. + * @param pst Pointer to the post structure. + * @param spId SAP ID of the service provider. + * @param recpReq Pointer to the TfuRecpReqInfo structure. + * @return ROK/RFAILED + */ +EXTERN S16 TfUiTfuRecpReq ARGS((Pst *pst, SpId spId, TfuRecpReqInfo *recpReq)); + + /** @brief This primitive is sent from Scheduler to PHY. It provides PHY with + * all the control information. + * @details This primitive carries the information sent on the following + * channels: + * -# PDCCH + * -# PHICH + * -# PCFICH + * + * @param pst + * @param spId + * @param cntrlReq pointer to TfuCntrlReqInfo + * @return ROK/RFAILED + */ +EXTERN S16 TfUiTfuCntrlReq ARGS((Pst *pst, SpId spId, TfuCntrlReqInfo *cntrlReq)); + + /** @brief This primitive carries the Data PDUs from MAC to PHY for transmission. + * @details The data being sent in this primitive is meant to be transmitted on + * the downlink channel PDSCH and PBCH (if present). To facilitate physical + * layer processing, requisite control information is also sent along with the + * data. + * @sa TfUiTfuCntrlReq + * @param pst + * @param spId + * @param datReq pointer to TfuDatReqInfo + * @return + */ +EXTERN S16 TfUiTfuDatReq ARGS((Pst *pst, SpId spId, TfuDatReqInfo *datReq)); + +#ifdef L2_OPTMZ +/** @brief This primitive carries the cellId and UeId for which datReq need to + * deleted in CL. + * @details This primitive is used to delete datReq PDUs present in CL for + * which got changed or similar other scenarios. These scenarios are possible + * only when L2_OPTMZ flag is enabled. + * @sa TfUiTfuDelDatReq + * @param pst + * @param spId + * @param datReq pointer to TfuDelDatReqInfo + * @return + */ + +EXTERN S16 TfUiTfuDelDatReq ARGS((Pst *pst, SpId spId, TfuDelDatReqInfo *datReq)); +#endif + +/** @brief This Primitive carries the Data PDUs from PHY to MAC. + * @details The Uplink Data, that is, the data transmitted by the UEs received by the + * physical layer at the eNodeB in the subframe (indicated by the timingInfo), + * is relayed to MAC using this primitive. + * @param pst + * @param suId + * @param datInd pointer to TfuDatIndInfo + * @return + */ +EXTERN S16 TfUiTfuDatInd ARGS((Pst *pst, SuId suId, TfuDatIndInfo *datInd)); + +/** @brief This primitive carries the HARQ Feedback from PHY to Scheduler. + * @details HARQ feedback is sent by the UE to the eNodeB, an ACK is sent if UE + * can successfully recieve the data transmitted by the eNodeB, else a NACK is + * sent. This feedback is utilized by MAC for further scheduling, for instance + * it can schedule an adaptive retransmission of the same data. + * @param pst + * @param suId + * @param hqInd pointer to TfuHqIndInfo + * @return + */ +EXTERN S16 TfUiTfuHqInd ARGS((Pst *pst, SuId suId, TfuHqIndInfo *hqInd)); + +/** @brief This primitive carries the SR Indication from PHY to Scheduler. + * @details Scheduling Request (SR) is sent by the UE to the eNodeB to request + * for Uplink (UL) grant. This primitive carries a list of SRs for a number of + * UEs received in the indicated subframe. + * @param pst + * @param suId + * @param srInd pointer to TfuSrIndInfo + * @return + */ +EXTERN S16 TfUiTfuSrInd ARGS((Pst *pst, SuId suId, TfuSrIndInfo *srInd)); + +/** @brief This API is used to indicate CQI reporting from PHY to Scheduler. + * @details This primitive carries an estimate of the Uplink Channel Quality + * Index (CQI) for a list of UEs. This is an estimate of the uplink channel + * quality, that is, the transmission from UE as calculated at the Physical layer at + * the eNodeB. + * It carries a list of sub-band CQIs for each UE. + * @param pst Pointer to the post structure. + * @param suId SAP ID of the service user. + * @param ulCqiInd Pointer to the TfuUlCqiIndInfo structure. + * @return ROK/RFAILED + */ +EXTERN S16 TfUiTfuUlCqiInd ARGS((Pst *pst, SuId suId, + TfuUlCqiIndInfo *ulCqiInd)); + +/** @brief This API is used by the Physical layer to indicate if the CRC Check + * on the PUSCH Data is successful or not. + * @details This primitive carries CRC indication for a list of UEs. This + * is utilized in the scenario where MAC requested the reception of Uplink data + * for a particular UE. On reception of the PUSCH data, the CRC check on it + * failed. This CRC failure is indicated to MAC, which utillizes this + * information for further scheduling. + * Physical layer indicates failure or success for each PUSCH transmission. + * @param pst Pointer to the post structure. + * @param suId SAP ID of the service user. + * @param crcIndInfo Pointer to the TfuCrcIndInfo. + * @return ROK/RFAILED + */ +EXTERN S16 TfUiTfuCrcInd ARGS((Pst *pst, SuId suId, + TfuCrcIndInfo *crcIndInfo)); + +/** @brief This API is used to indicate a Timing Advance from PHY to Scheduler. + * @details This primitive carries timing advance information for a number of + * UEs that may need timing advance. Timing advance information is an estimate + * of the timing adjustment that an UE needs to apply in order to be + * synchronized in Uplink. This estimate is to be calculated by physical layer. + * @param pst Pointer to the post structure. + * @param suId SAP ID of the service user. + * @param timingAdvInd Pointer to the TfuTimingAdvIndInfo structure. + * @return ROK/RFAILED + */ +EXTERN S16 TfUiTfuTimingAdvInd ARGS((Pst *pst, SuId suId, + TfuTimingAdvIndInfo *timingAdvInd)); + +/* CA dev Start */ +/** @brief This API is the TTI indication from CL to MAC and SCH + * @details This primitive provides the timing information (SFN and subframe) + * which is currently running on the physical layer. + * @param pst Pointer to the post structure. + * @param suId SAP ID of the service user. + * @param ttiInd Pointer to the TfuTtiCellInfo structure. + * @return ROK/RFAILED + */ +EXTERN S16 TfUiTfuTtiCell ARGS((Pst *pst, SuId suId, + TfuTtiCellInfo *ttiInd)); +/* CA dev End */ + +/** @brief This API is the TTI indication from CL to MAC and SCH + * @details This primitive provides the timing information (SFN and subframe) + * which is currently running on the physical layer. + * @param pst Pointer to the post structure. + * @param suId SAP ID of the service user. + * @param ttiInd Pointer to the TfuTtiIndInfo structure. + * @return ROK/RFAILED + */ +EXTERN S16 TfUiTfuTtiInd ARGS((Pst *pst, SuId suId, + TfuTtiIndInfo *ttiInd)); + +/** @brief This API is the TTI indication from PHY to Scheduler. + * @details This primitive provides the timing information (SFN and subframe) + * which is currently running on the physical layer. + * @param pst Pointer to the post structure. + * @param suId SAP ID of the service user. + * @param ttiInd Pointer to the TfuTtiIndInfo structure. + * @return ROK/RFAILED + */ +EXTERN S16 TfUiTfuSchTtiInd ARGS((Pst *pst, SuId suId, + TfuTtiIndInfo *ttiInd)); + + +/** @brief This API is used to indicate the reception of CQI report from PHY to + * Scheduler and also carries the Rank Index information. + * @details This primitive carries the CQI (Channel Quality Index) report + * for the downlink channel, sent by the UE. It is also used to report RI and + * PMI. + * @param pst Pointer to the post structure. + * @param suId SAP ID of the service user. + * @param dlCqiInd Pointer to the TfuDlCqiIndInfo structure. + * @return ROK/RFAILED + */ +EXTERN S16 TfUiTfuDlCqiInd ARGS((Pst *pst, SuId suId, + TfuDlCqiIndInfo *dlCqiInd)); +/** @brief This API is used to indicate the calculated DOA value report from PHY to + * Scheduler. + * @details This primitive carries the DOA(Direction of arrival) report + * calculated at PHYSICAL LAYER, for an UE. + * @param pst Pointer to the post structure. + * @param suId SAP ID of the service user. + * @param doaInd Pointer to the TfuDoaIndInfo structure. + * @return ROK/RFAILED + */ +EXTERN S16 TfUiTfuDoaInd ARGS((Pst *pst, SuId suId, + TfuDoaIndInfo *doaInd)); + + +/** @brief This primitive is used to convey PUCCH Delta Power calculated by the + * Physical layer. + * @details This primitive is used to convey PUCCH Delta Power calculated by the + * Physical layer. This information is utilized by the scheduler to perform + * power control for the UEs. + * @param pst Pointer to the post structure. + * @param suId SAP ID of the service user. + * @param pucchDeltaPwr Pointer to the TfuPucchDeltaPwrIndInfo structure. + * @return ROK/RFAILED + */ +EXTERN S16 TfUiTfuPucchDeltaPwrInd ARGS((Pst *pst, SuId suId, + TfuPucchDeltaPwrIndInfo *pucchDeltaPwr)); + +/** @brief LAA:This primitive carries the Error Indication from PHY to Scheduler. + * This primitive is invoked when the transmission on the unlicensed Scell + * fails. + * @param pst + * @param suId + * @param errInd pointer to TfuErrIndInfo + * @return + */ + +EXTERN S16 TfUiTfuErrInd ARGS((Pst *pst, SuId suId, + TfuErrIndInfo *errInd)); +/* tfu_x_001.main_8. Added changes of TFU_UPGRADE */ +#ifdef TFU_UPGRADE + +/** @brief This primitive is used to convey the information derived by the + * physical layer from the SRS transmission from the UE. + * @details This primitive carries information derived from the SRS transmission + * from the UE. + * + * @param pst Pointer to the post structure. + * @param suId SAP ID of the service user. + * @param srsInd Pointer to the TfuSrIndInfo structure. + * @return ROK/RFAILED + */ +EXTERN S16 TfUiTfuSrsInd ARGS((Pst *pst, SuId suId, + TfuSrsIndInfo *srsInd)); + + +/** @brief This primitive is used to convey the Raw CQI information + * transmitted by the UE. + * @details Raw CQI report is the actual bits transmitted by the UE when + * reporting CQI/PMI/RI. The interpretation of these bits to CQI/sub-band CQI + * and so on, are done by MAC. + * + * @param pst Pointer to the post structure. + * @param suId SAP ID of the service user. + * @param cqiInd Pointer to the TfuRawCqiIndInfo structure. + * @return ROK/RFAILED + */ +EXTERN S16 TfUiTfuRawCqiInd ARGS((Pst *pst, SuId suId, + TfuRawCqiIndInfo *cqiInd)); + +#endif /* TFU_UPGRADE */ + +#ifdef RG +EXTERN S16 RgLiTfuBndReq ARGS(( + Pst* pst, + SuId suId, + SpId spId +)); +EXTERN S16 RgLiTfuBndCfm ARGS(( + Pst* pst, + SuId suId, + U8 status +)); +EXTERN S16 RgLiTfuUbndReq ARGS(( + Pst* pst, + SpId spId, + Reason reason +)); + +EXTERN S16 RgLiTfuSchBndReq ARGS(( + Pst* pst, + SuId suId, + SpId spId +)); +EXTERN S16 RgLiTfuSchBndCfm ARGS(( + Pst* pst, + SuId suId, + U8 status +)); +EXTERN S16 RgLiTfuSchUbndReq ARGS(( + Pst* pst, + SpId spId, + Reason reason +)); + +EXTERN S16 RgLiTfuRaReqInd ARGS(( + Pst * pst, + SpId spId, + TfuRaReqIndInfo * raReq +)); + + +EXTERN S16 RgLiTfuRecpReq ARGS(( + Pst * pst, + SpId spId, + TfuRecpReqInfo * recpReq +)); + +EXTERN S16 RgLiTfuUlCqiInd ARGS(( + Pst * pst, + SuId suId, + TfuUlCqiIndInfo * ulCqiInd +)); + +EXTERN S16 RgLiTfuDoaInd ARGS(( + Pst * pst, + SuId suId, + TfuDoaIndInfo * doaInd +)); + +EXTERN S16 RgLiTfuHqInd ARGS(( + Pst * pst, + SuId suId, + TfuHqIndInfo * hqInd +)); + +EXTERN S16 RgLiTfuSrInd ARGS(( + Pst * pst, + SuId suId, + TfuSrIndInfo * srInd +)); + +EXTERN S16 RgLiTfuDlCqiInd ARGS(( + Pst * pst, + SuId suId, + TfuDlCqiIndInfo * dlCqiInd +)); + +/* tfu_x_001.main_8. Added changes of TFU_UPGRADE */ +#ifdef TFU_UPGRADE +EXTERN S16 RgLiTfuRawCqiInd ARGS(( + Pst *pst, + SuId suId, + TfuRawCqiIndInfo *rawCqiInd + )); +EXTERN S16 RgLiTfuSrsInd ARGS(( + Pst *pst, + SuId suId, + TfuSrsIndInfo *srsIndInfo + )); +#endif +EXTERN S16 RgLiTfuDatInd ARGS(( + Pst * pst, + SuId suId, + TfuDatIndInfo * datInd +)); + +EXTERN S16 RgLiTfuCrcInd ARGS(( + Pst * pst, + SuId suId, + TfuCrcIndInfo * crcInd +)); + +EXTERN S16 RgLiTfuTimingAdvInd ARGS(( + Pst * pst, + SuId suId, + TfuTimingAdvIndInfo * timingAdvInd +)); + +EXTERN S16 RgLiTfuDatReq ARGS(( + Pst * pst, + SpId spId, + TfuDatReqInfo * datReq +)); + +EXTERN S16 RgLiTfuCntrlReq ARGS(( + Pst * pst, + SpId spId, + TfuCntrlReqInfo * cntrlReq +)); + +EXTERN S16 RgLiTfuTtiInd ARGS(( + Pst * pst, + SuId suId, + TfuTtiIndInfo * ttiInd +)); + +EXTERN S16 RgLiTfuSchTtiInd ARGS(( + Pst * pst, + SuId suId, + TfuTtiIndInfo * ttiInd +)); + +#if defined(TENB_T2K3K_SPECIFIC_CHANGES) && defined(LTE_TDD) +EXTERN S16 RgLiTfuNonRtInd ARGS(( + Pst * pst, + SuId suId +)); +#endif + +EXTERN S16 RgLiTfuPucchDeltaPwrInd ARGS(( + Pst * pst, + SuId suId, + TfuPucchDeltaPwrIndInfo *pucchDeltaPwr + )); +#endif + +/** @brief LAA:This primitive carries the Error Indication from PHY to Scheduler. + * This primitive is invoked when the transmission on the unlicensed Scell + * fails. + * @param pst + * @param suId + * @param errInd pointer to TfuErrIndInfo + * @return + */ +EXTERN S16 RgLiTfuErrInd ARGS((Pst *pst, SuId suId, TfuErrIndInfo *errInd)); + +#ifdef L2_OPTMZ +/** @brief This primitive carries the cellId and UeId for which datReq need to + * deleted in CL. + * @details This primitive is used to delete datReq PDUs present in CL for + * which got changed or similar other scenarios. These scenarios are possible + * only when L2_OPTMZ flag is enabled. + * @sa TfUiTfuDelDatReq + * @param pst + * @param spId + * @param datReq pointer to TfuDelDatReqInfo + * @return + */ +EXTERN S16 RgLiTfuDelDatReq ARGS((Pst *pst, SuId suId, TfuDelDatReqInfo *delDatReq)); +#endif + +#if (defined(LCTFU)) +/** @brief This API is used to send a Bind Request from MAC to PHY. + */ +#ifdef TFU_5GTF +EXTERN S16 cmPkTfuRbAssignA1Val324 ARGS(( +TfuRbAssignA1Val324 *param, +Buffer *mBuf +)); +EXTERN S16 cmPkTfuRbAssignB1Val324 ARGS(( +TfuRbAssignB1Val324 *param, +Buffer *mBuf +)); +EXTERN S16 cmPkTfuRbAssignVal326 ARGS(( +TfuRbAssignVal326 *param, +Buffer *mBuf +)); +EXTERN S16 cmUnpkTfuRbAssignA1Val324 ARGS(( +TfuRbAssignA1Val324 *param, +Buffer *mBuf +)); +EXTERN S16 cmUnpkTfuRbAssignB1Val324 ARGS(( +TfuRbAssignB1Val324 *param, +Buffer *mBuf +)); +EXTERN S16 cmUnpkTfuRbAssignVal326 ARGS(( +TfuRbAssignVal326 *param, +Buffer *mBuf +)); +EXTERN S16 cmPkTfuDciFormatA1A2Info ARGS(( +TfuDciFormatA1Info *param, +Buffer *mBuf +)); +EXTERN S16 cmPkTfuDciFormatB1B2Info ARGS(( +TfuDciFormatB1Info *param, +Buffer *mBuf +)); +EXTERN S16 cmUnpkTfuDciFormatA1A2Info ARGS(( +TfuDciFormatA1Info *param, +Buffer *mBuf +)); +EXTERN S16 cmUnpkTfuDciFormatB1B2Info ARGS(( +TfuDciFormatB1Info *param, +Buffer *mBuf +)); +#endif /* TFU_5GTF */ + +EXTERN S16 cmPkTfuBndReq ARGS(( + Pst* pst, + SuId suId, + SpId spId +)); +/** @brief This API is used to send a Bind Request from MAC to PHY. + */ +EXTERN S16 cmUnpkTfuBndReq ARGS(( + TfuBndReq func, + Pst* pst, + Buffer *mBuf +)); +/** @brief This API is used to receive a Bind Confirm from PHY to MAC. + */ +EXTERN S16 cmPkTfuBndCfm ARGS(( + Pst* pst, + SuId suId, + U8 status +)); +/** @brief This API is used to receive a Bind Confirm from PHY to MAC. + */ +EXTERN S16 cmUnpkTfuBndCfm ARGS(( + TfuBndCfm func, + Pst* pst, + Buffer *mBuf +)); +/** @brief This API is used to send an Unbind Request from MAC to PHY. + */ +EXTERN S16 cmPkTfuUbndReq ARGS(( + Pst* pst, + SpId spId, + Reason reason +)); +/** @brief This API is used to send an Unbind Request from MAC to PHY. + */ +EXTERN S16 cmUnpkTfuUbndReq ARGS(( + TfuUbndReq func, + Pst* pst, + Buffer *mBuf +)); +/** @brief This API is used to send a Bind Request from SCH to PHY. + */ +EXTERN S16 cmPkTfuSchBndReq ARGS(( + Pst* pst, + SuId suId, + SpId spId +)); +/** @brief This API is used to send a Bind Request from SCH to PHY. + */ +EXTERN S16 cmUnpkTfuSchBndReq ARGS(( + TfuSchBndReq func, + Pst* pst, + Buffer *mBuf +)); +/** @brief This API is used to receive a Bind Confirm from PHY to SCH. + */ +EXTERN S16 cmPkTfuSchBndCfm ARGS(( + Pst* pst, + SuId suId, + U8 status +)); +/** @brief This API is used to receive a Bind Confirm from PHY to SCH. + */ +EXTERN S16 cmUnpkTfuSchBndCfm ARGS(( + TfuSchBndCfm func, + Pst* pst, + Buffer *mBuf +)); +/** @brief This API is used to send an Unbind Request from SCH to PHY. + */ +EXTERN S16 cmPkTfuSchUbndReq ARGS(( + Pst* pst, + SpId spId, + Reason reason +)); +/** @brief This API is used to send an Unbind Request from SCH to PHY. + */ +EXTERN S16 cmUnpkTfuSchUbndReq ARGS(( + TfuSchUbndReq func, + Pst* pst, + Buffer *mBuf +)); +/** @brief This API is used to indication Random Access Request reception from + * PHY to MAC. + */ +EXTERN S16 cmPkTfuRaReqInd ARGS(( + Pst * pst, + SuId suId, + TfuRaReqIndInfo * raReqInd +)); +/** @brief This API is used to indication Random Access Request reception from + * PHY to MAC. + */ +EXTERN S16 cmUnpkTfuRaReqInd ARGS(( + TfuRaReqInd func, + Pst * pst, + Buffer *mBuf +)); +/** @brief This API is used to indication Random Access Request reception from + * PHY to MAC. + */ +EXTERN S16 cmPkTfuRecpReq ARGS(( + Pst * pst, + SpId spId, + TfuRecpReqInfo * recpReq +)); +/** @brief This API is used to indication Random Access Request reception from + * PHY to MAC. + */ +EXTERN S16 cmUnpkTfuRecpReq ARGS(( + TfuRecpReq func, + Pst * pst, + Buffer *mBuf +)); +/** @brief This API is used to indicate CQI reporting from PHY to MAC. + */ +EXTERN S16 cmPkTfuUlCqiInd ARGS(( + Pst * pst, + SuId suId, + TfuUlCqiIndInfo * ulCqiInd +)); +/** @brief This API is used to indicate CQI reporting from PHY to MAC. + */ +EXTERN S16 cmUnpkTfuUlCqiInd ARGS(( + TfuUlCqiInd func, + Pst * pst, + Buffer *mBuf +)); + +EXTERN S16 cmPkTfuHqInd ARGS(( + Pst * pst, + SuId suId, + TfuHqIndInfo * hqInd +)); + +EXTERN S16 cmUnpkTfuHqInd ARGS(( + TfuHqInd func, + Pst * pst, + Buffer *mBuf +)); +/** @brief This API is used to indicate a SR reception from PHY to MAC. + */ +EXTERN S16 cmPkTfuSrInd ARGS(( + Pst * pst, + SuId suId, + TfuSrIndInfo * srInd +)); +/** @brief This API is used to indicate a SR reception from PHY to MAC. + */ +EXTERN S16 cmUnpkTfuSrInd ARGS(( + TfuSrInd func, + Pst * pst, + Buffer *mBuf +)); +/** @brief This API is used to indicate the reception of CQI report from PHY to + * MAC. + */ +EXTERN S16 cmPkTfuDlCqiInd ARGS(( + Pst * pst, + SuId suId, + TfuDlCqiIndInfo * dlCqiInd +)); +/** @brief This API is used to indicate the reception of CQI report from PHY to + * MAC. + */ +EXTERN S16 cmUnpkTfuDlCqiInd ARGS(( + TfuDlCqiInd func, + Pst * pst, + Buffer *mBuf +)); + +/** @brief This API is used to indicate the Calculated DOA value report from PHY to + * MAC.*/ +EXTERN S16 cmUnpkTfuDoaInd ARGS(( + TfuDoaInd func, + Pst * pst, + Buffer *mBuf +)); +/** @brief This API is used to indicate the calculated DOA Value report from PHY to + * MAC. + */ +EXTERN S16 cmPkTfuDoaInd ARGS(( + Pst * pst, + SuId suId, + TfuDoaIndInfo * doaInd + )); + +/** @brief This API is used to indicate Data Reception from PHY to MAC. + */ +EXTERN S16 cmPkTfuDatInd ARGS(( + Pst * pst, + SuId suId, + TfuDatIndInfo * datInd +)); +/** @brief This API is used to indicate Data Reception from PHY to MAC. + */ +EXTERN S16 cmUnpkTfuDatInd ARGS(( + TfuDatInd func, + Pst * pst, + Buffer *mBuf +)); +/** @brief This API is used to indicate Decode failure from PHY to MAC. + */ +EXTERN S16 cmPkTfuCrcInd ARGS(( + Pst * pst, + SuId suId, + TfuCrcIndInfo * crcInd +)); +/** @brief This API is used to indicate Decode failure from PHY to MAC. + */ +EXTERN S16 cmUnpkTfuCrcInd ARGS(( + TfuCrcInd func, + Pst * pst, + Buffer *mBuf +)); + +EXTERN S16 cmPkTfuCntrlReq ARGS(( + Pst * pst, + SpId spId, + TfuCntrlReqInfo * cntrlReq +)); + +EXTERN S16 cmUnpkTfuCntrlReq ARGS(( + TfuCntrlReq func, + Pst * pst, + Buffer *mBuf +)); +/** @brief This API is used to indicate a Timing Advance from PHY to MAC. + */ +EXTERN S16 cmPkTfuTimingAdvInd ARGS(( + Pst * pst, + SuId suId, + TfuTimingAdvIndInfo * timingAdvInd +)); +/** @brief This API is used to indicate a Timing Advance from PHY to MAC. + */ +EXTERN S16 cmUnpkTfuTimingAdvInd ARGS(( + TfuTimingAdvInd func, + Pst * pst, + Buffer *mBuf +)); +/** @brief This API is used to send Data Request from MAC to PHY. + */ +EXTERN S16 cmPkTfuDatReq ARGS(( + Pst * pst, + SpId spId, + TfuDatReqInfo * datReq +)); +/** @brief This API is used to send Data Request from MAC to PHY. + */ +EXTERN S16 cmUnpkTfuDatReq ARGS(( + TfuDatReq func, + Pst * pst, + Buffer *mBuf +)); +/* CA dev Start */ +/** @brief This API is the TTI indication from CL to MAC and SCH. + */ +EXTERN S16 cmPkTfuTtiCell ARGS(( + Pst * pst, + SuId suId, + TfuTtiCellInfo * ttiInd +)); +/** @brief This API is the TTI indication from CL to MAC and SCH. + */ +EXTERN S16 cmUnpkTfuTtiCell ARGS(( + TfuTtiCell func, + Pst * pst, + Buffer *mBuf +)); +/* CA dev End */ + +/** @brief This API is the TTI indication from PHY to MAC. + */ +EXTERN S16 cmPkTfuTtiInd ARGS(( + Pst * pst, + SuId suId, + TfuTtiIndInfo * ttiInd +)); +/** @brief This API is the TTI indication from PHY to MAC. + */ +EXTERN S16 cmUnpkTfuTtiInd ARGS(( + TfuTtiInd func, + Pst * pst, + Buffer *mBuf +)); + +#if defined(TENB_T2K3K_SPECIFIC_CHANGES) && defined(LTE_TDD) +/** @brief This API is the non-rt indication from PHY to MAC. + */ +EXTERN S16 cmPkTfuNonRtInd ARGS(( + Pst * pst, + SuId suId +)); + +/** @brief This API is the non-rt indication from PHY to MAC. + */ +EXTERN S16 cmUnpkTfuNonRtInd ARGS(( + TfuNonRtInd func, + Pst * pst, + Buffer *mBuf +)); +#endif + +/** @brief This API is the TTI indication from PHY to SCH. + */ +EXTERN S16 cmPkTfuSchTtiInd ARGS(( + Pst * pst, + SuId suId, + TfuTtiIndInfo * ttiInd +)); +/** @brief This API is the TTI indication from PHY to SCH. + */ +EXTERN S16 cmUnpkTfuSchTtiInd ARGS(( + TfuSchTtiInd func, + Pst * pst, + Buffer *mBuf +)); + +/** @brief This API is used to convey the PUCCH delta power from PHY to SCH. + */ +EXTERN S16 cmPkTfuPucchDeltaPwrInd ARGS(( + Pst * pst, + SuId suId, + TfuPucchDeltaPwrIndInfo * pucchDeltaPwr +)); +/** @brief This API is used to indicate Decode failure from PHY to MAC. + */ +EXTERN S16 cmUnpkTfuPucchDeltaPwrInd ARGS(( + TfuPucchDeltaPwrInd func, + Pst * pst, + Buffer *mBuf +)); + + +#ifdef TFU_PHASE_2 +/** @brief This API is used to send Group Power Control Request from MAC to PHY. + */ +EXTERN S16 cmPkTfuGrpPwrCntrlReq ARGS(( + Pst * pst, + SpId spId, + TfuGrpPwrCntrlReqInfo * grpPwrCntrlReq +)); +/** @brief This API is used to send Group Power Control Request from MAC to PHY. + */ +EXTERN S16 cmUnpkTfuGrpPwrCntrlReq ARGS(( + TfuGrpPwrCntrlReq func, + Pst * pst, + Buffer *mBuf +)); +#endif +EXTERN S16 cmPkTfuDciFormat0Info ARGS(( + TfuDciFormat0Info *param, + Buffer *mBuf +)); +EXTERN S16 cmUnpkTfuDciFormat0Info ARGS(( + TfuDciFormat0Info *param, + Buffer *mBuf +)); +EXTERN S16 cmPkTfuAllocMapOrRiv ARGS(( + TfuAllocMapOrRiv *param, + Buffer *mBuf +)); +EXTERN S16 cmUnpkTfuAllocMapOrRiv ARGS(( + TfuAllocMapOrRiv *param, + Buffer *mBuf +)); +EXTERN S16 cmPkTfuDciFormat1AllocInfo ARGS(( + TfuDciFormat1AllocInfo *param, + Buffer *mBuf +)); +EXTERN S16 cmUnpkTfuDciFormat1AllocInfo ARGS(( + TfuDciFormat1AllocInfo *param, + Buffer *mBuf +)); +EXTERN S16 cmPkTfuDciFormat1Info ARGS(( + TfuDciFormat1Info *param, + Buffer *mBuf +)); +EXTERN S16 cmUnpkTfuDciFormat1Info ARGS(( + TfuDciFormat1Info *param, + Buffer *mBuf +)); + +EXTERN S16 cmPkTfuDciFormatTbInfo ARGS(( + TfuDciFormatTbInfo *param, + Buffer *mBuf +)); +EXTERN S16 cmUnpkTfuDciFormatTbInfo ARGS(( + TfuDciFormatTbInfo *param, + Buffer *mBuf +)); +/** @} */ +EXTERN S16 cmPkTfuDciFormat2AAllocInfo ARGS(( + TfuDciFormat2AAllocInfo *param, + Buffer *mBuf +)); +EXTERN S16 cmUnpkTfuDciFormat2AAllocInfo ARGS(( + TfuDciFormat2AAllocInfo *param, + Buffer *mBuf +)); +EXTERN S16 cmPkTfuDciFormat2AInfo ARGS(( + TfuDciFormat2AInfo *param, + Buffer *mBuf +)); +EXTERN S16 cmUnpkTfuDciFormat2AInfo ARGS(( + TfuDciFormat2AInfo *param, + Buffer *mBuf +)); +EXTERN S16 cmPkTfuDciFormat2AllocInfo ARGS(( + TfuDciFormat2AllocInfo *param, + Buffer *mBuf +)); +EXTERN S16 cmUnpkTfuDciFormat2AllocInfo ARGS(( + TfuDciFormat2AllocInfo *param, + Buffer *mBuf +)); +EXTERN S16 cmPkTfuDciFormat2Info ARGS(( + TfuDciFormat2Info *param, + Buffer *mBuf +)); +EXTERN S16 cmUnpkTfuDciFormat2Info ARGS(( + TfuDciFormat2Info *param, + Buffer *mBuf +)); +EXTERN S16 cmPkTfuDciFormat3Info ARGS(( + TfuDciFormat3Info *param, + Buffer *mBuf +)); +EXTERN S16 cmUnpkTfuDciFormat3Info ARGS(( + TfuDciFormat3Info *param, + Buffer *mBuf +)); +EXTERN S16 cmPkTfuDciFormat3AInfo ARGS(( + TfuDciFormat3AInfo *param, + Buffer *mBuf +)); +EXTERN S16 cmUnpkTfuDciFormat3AInfo ARGS(( + TfuDciFormat3AInfo *param, + Buffer *mBuf +)); +EXTERN S16 cmPkTfuDciFormat1dAllocInfo ARGS(( + TfuDciFormat1dAllocInfo *param, + Buffer *mBuf +)); +EXTERN S16 cmUnpkTfuDciFormat1dAllocInfo ARGS(( + TfuDciFormat1dAllocInfo *param, + Buffer *mBuf +)); +EXTERN S16 cmPkTfuDciFormat1dInfo ARGS(( + TfuDciFormat1dInfo *param, + Buffer *mBuf +)); +EXTERN S16 cmUnpkTfuDciFormat1dInfo ARGS(( + TfuDciFormat1dInfo *param, + Buffer *mBuf +)); +EXTERN S16 cmPkTfuDciFormat1cInfo ARGS(( + TfuDciFormat1cInfo *param, + Buffer *mBuf +)); +EXTERN S16 cmUnpkTfuDciFormat1cInfo ARGS(( + TfuDciFormat1cInfo *param, + Buffer *mBuf +)); +EXTERN S16 cmPkTfuDciFormat1bAllocInfo ARGS(( + TfuDciFormat1bAllocInfo *param, + Buffer *mBuf +)); +EXTERN S16 cmUnpkTfuDciFormat1bAllocInfo ARGS(( + TfuDciFormat1bAllocInfo *param, + Buffer *mBuf +)); +EXTERN S16 cmPkTfuPdcchOrderInfo ARGS(( + TfuPdcchOrderInfo *param, + Buffer *mBuf +)); +EXTERN S16 cmUnpkTfuPdcchOrderInfo ARGS(( + TfuPdcchOrderInfo *param, + Buffer *mBuf +)); +EXTERN S16 cmPkTfuDciFormat1aAllocInfo ARGS(( + TfuDciFormat1aAllocInfo *param, + Buffer *mBuf +)); +EXTERN S16 cmUnpkTfuDciFormat1aAllocInfo ARGS(( + TfuDciFormat1aAllocInfo *param, + Buffer *mBuf +)); +/*tfu_x_001.main_6 - Added for SPS support*/ +EXTERN S16 cmPkTfudciformat1aPdsch ARGS(( + Tfudciformat1aPdsch *param, + Buffer *mBuf +)); +EXTERN S16 cmUnpkTfudciformat1aPdsch ARGS(( + Tfudciformat1aPdsch *param, + Buffer *mBuf +)); +EXTERN S16 cmPkTfuDciFormat1aInfo ARGS(( + TfuDciFormat1aInfo *param, + Buffer *mBuf +)); +EXTERN S16 cmUnpkTfuDciFormat1aInfo ARGS(( + TfuDciFormat1aInfo *param, + Buffer *mBuf +)); +EXTERN S16 cmPkTfuDciFormat1bInfo ARGS(( + TfuDciFormat1bInfo *param, + Buffer *mBuf +)); +EXTERN S16 cmUnpkTfuDciFormat1bInfo ARGS(( + TfuDciFormat1bInfo *param, + Buffer *mBuf +)); +EXTERN S16 cmPkTfuDciInfo ARGS(( + TfuDciInfo *param, + Buffer *mBuf +)); +EXTERN S16 cmUnpkTfuDciInfo ARGS(( + TfuDciInfo *param, + Buffer *mBuf +)); +EXTERN S16 cmPkTfuSubbandInfo ARGS(( + TfuSubbandInfo *param, + Buffer *mBuf +)); +EXTERN S16 cmUnpkTfuSubbandInfo ARGS(( + TfuSubbandInfo *param, + Buffer *mBuf +)); +EXTERN S16 cmPkTfuSubbandDlCqiInfo ARGS(( + TfuSubbandDlCqiInfo *param, + Buffer *mBuf +)); +EXTERN S16 cmUnpkTfuSubbandDlCqiInfo ARGS(( + TfuSubbandDlCqiInfo *param, + Buffer *mBuf +)); +/** @} */ +EXTERN S16 cmPkTfuSubbandCqiInfo ARGS(( + TfuSubbandCqiInfo *param, + Buffer *mBuf +)); +EXTERN S16 cmUnpkTfuSubbandCqiInfo ARGS(( + TfuSubbandCqiInfo *param, + Buffer *mBuf +)); +EXTERN S16 cmPkTfuPdcchCceInfo ARGS(( + TfuPdcchCceInfo *param, + Buffer *mBuf +)); +EXTERN S16 cmUnpkTfuPdcchCceInfo ARGS(( + TfuPdcchCceInfo *param, + Buffer *mBuf +)); +EXTERN S16 cmPkTfuCqiPucchMode10 ARGS(( + TfuCqiPucchMode10 *param, + Buffer *mBuf +)); +EXTERN S16 cmUnpkTfuCqiPucchMode10 ARGS(( + TfuCqiPucchMode10 *param, + Buffer *mBuf +)); +EXTERN S16 cmPkTfuCqiMode11Cqi ARGS(( + TfuCqiMode11Cqi *param, + Buffer *mBuf +)); +EXTERN S16 cmUnpkTfuCqiMode11Cqi ARGS(( + TfuCqiMode11Cqi *param, + Buffer *mBuf +)); +EXTERN S16 cmPkTfuCqiPucchMode11 ARGS(( + TfuCqiPucchMode11 *param, + Buffer *mBuf +)); +EXTERN S16 cmUnpkTfuCqiPucchMode11 ARGS(( + TfuCqiPucchMode11 *param, + Buffer *mBuf +)); +EXTERN S16 cmPkTfuCqiMode20SubCqi ARGS(( + TfuCqiMode20SubCqi *param, + Buffer *mBuf +)); +EXTERN S16 cmUnpkTfuCqiMode20SubCqi ARGS(( + TfuCqiMode20SubCqi *param, + Buffer *mBuf +)); +EXTERN S16 cmPkTfuCqiMode20Cqi ARGS(( + TfuCqiMode20Cqi *param, + Buffer *mBuf +)); +EXTERN S16 cmUnpkTfuCqiMode20Cqi ARGS(( + TfuCqiMode20Cqi *param, + Buffer *mBuf +)); +EXTERN S16 cmPkTfuCqiPucchMode20 ARGS(( + TfuCqiPucchMode20 *param, + Buffer *mBuf +)); +EXTERN S16 cmUnpkTfuCqiPucchMode20 ARGS(( + TfuCqiPucchMode20 *param, + Buffer *mBuf +)); +EXTERN S16 cmPkTfuCqiMode21SubCqi ARGS(( + TfuCqiMode21SubCqi *param, + Buffer *mBuf +)); +EXTERN S16 cmUnpkTfuCqiMode21SubCqi ARGS(( + TfuCqiMode21SubCqi *param, + Buffer *mBuf +)); +EXTERN S16 cmPkTfuCqiMode21WideCqi ARGS(( + TfuCqiMode21WideCqi *param, + Buffer *mBuf +)); +EXTERN S16 cmUnpkTfuCqiMode21WideCqi ARGS(( + TfuCqiMode21WideCqi *param, + Buffer *mBuf +)); +EXTERN S16 cmPkTfuCqiMode21Cqi ARGS(( + TfuCqiMode21Cqi *param, + Buffer *mBuf +)); +EXTERN S16 cmUnpkTfuCqiMode21Cqi ARGS(( + TfuCqiMode21Cqi *param, + Buffer *mBuf +)); +EXTERN S16 cmPkTfuCqiPucchMode21 ARGS(( + TfuCqiPucchMode21 *param, + Buffer *mBuf +)); +EXTERN S16 cmUnpkTfuCqiPucchMode21 ARGS(( + TfuCqiPucchMode21 *param, + Buffer *mBuf +)); +EXTERN S16 cmPkTfuDlCqiPucch ARGS(( + TfuDlCqiPucch *param, + Buffer *mBuf +)); +EXTERN S16 cmUnpkTfuDlCqiPucch ARGS(( + TfuDlCqiPucch *param, + Buffer *mBuf +)); +EXTERN S16 cmPkTfuSubbandMode12 ARGS(( + TfuSubbandMode12 *param, + Buffer *mBuf +)); +EXTERN S16 cmUnpkTfuSubbandMode12 ARGS(( + TfuSubbandMode12 *param, + Buffer *mBuf +)); +EXTERN S16 cmPkTfuCqiPuschMode12 ARGS(( + TfuCqiPuschMode12 *param, + Buffer *mBuf +)); +EXTERN S16 cmUnpkTfuCqiPuschMode12 ARGS(( + TfuCqiPuschMode12 *param, + Buffer *mBuf +)); +EXTERN S16 cmPkTfuCqiPuschMode20 ARGS(( + TfuCqiPuschMode20 *param, + Buffer *mBuf +)); +EXTERN S16 cmUnpkTfuCqiPuschMode20 ARGS(( + TfuCqiPuschMode20 *param, + Buffer *mBuf +)); +EXTERN S16 cmPkTfuCqiPuschMode22 ARGS(( + TfuCqiPuschMode22 *param, + Buffer *mBuf +)); +EXTERN S16 cmUnpkTfuCqiPuschMode22 ARGS(( + TfuCqiPuschMode22 *param, + Buffer *mBuf +)); +EXTERN S16 cmPkTfuSubbandMode30 ARGS(( + TfuSubbandMode30 *param, + Buffer *mBuf +)); +EXTERN S16 cmUnpkTfuSubbandMode30 ARGS(( + TfuSubbandMode30 *param, + Buffer *mBuf +)); +EXTERN S16 cmPkTfuCqiPuschMode30 ARGS(( + TfuCqiPuschMode30 *param, + Buffer *mBuf +)); +EXTERN S16 cmUnpkTfuCqiPuschMode30 ARGS(( + TfuCqiPuschMode30 *param, + Buffer *mBuf +)); +EXTERN S16 cmPkTfuSubbandMode31 ARGS(( + TfuSubbandMode31 *param, + Buffer *mBuf +)); +EXTERN S16 cmUnpkTfuSubbandMode31 ARGS(( + TfuSubbandMode31 *param, + Buffer *mBuf +)); +EXTERN S16 cmPkTfuCqiPuschMode31 ARGS(( + TfuCqiPuschMode31 *param, + Buffer *mBuf +)); +EXTERN S16 cmUnpkTfuCqiPuschMode31 ARGS(( + TfuCqiPuschMode31 *param, + Buffer *mBuf +)); +EXTERN S16 cmPkTfuDlCqiPusch ARGS(( + TfuDlCqiPusch *param, + Buffer *mBuf +)); +EXTERN S16 cmUnpkTfuDlCqiPusch ARGS(( + TfuDlCqiPusch *param, + Buffer *mBuf +)); + +EXTERN S16 cmPkTfuDlCqiPuschInfo ARGS(( + TfuDlCqiPuschInfo *param, + Buffer *mBuf +)); +EXTERN S16 cmUnpkTfuDlCqiPuschInfo ARGS(( + TfuDlCqiPuschInfo *param, + Buffer *mBuf +)); + +EXTERN S16 cmPkTfuDoaRpt ARGS(( + TfuDoaRpt *param, + Buffer *mBuf +)); +EXTERN S16 cmUnpkTfuDoaRpt ARGS(( + TfuDoaRpt *param, + Buffer *mBuf +)); +EXTERN S16 cmPkTfuDoaIndInfo ARGS(( + TfuDoaIndInfo *param, + Buffer *mBuf +)); +EXTERN S16 cmUnpkTfuDoaIndInfo ARGS(( + TfuDoaIndInfo *param, + Ptr memCp, + Buffer *mBuf +)); + +EXTERN S16 cmPkTfuDlCqiInfo ARGS(( + U8 selector, + TfuDlCqiInfo *param, + Buffer *mBuf +)); +EXTERN S16 cmUnpkTfuDlCqiInfo ARGS(( + U8 selector, + TfuDlCqiInfo *param, + Buffer *mBuf +)); + + +/* tfu_x_001.main_8. Added changes of TFU_UPGRADE */ +#ifndef TFU_UPGRADE +EXTERN S16 cmPkTfuUeMsg3RecpReq ARGS(( + TfuUeMsg3RecpReq *param, + Buffer *mBuf +)); +EXTERN S16 cmUnpkTfuUeMsg3RecpReq ARGS(( + TfuUeMsg3RecpReq *param, + Buffer *mBuf +)); +#endif + + +/*tfu_x_001.main_8 - ADD - Prototype for TfuUePuschRecpReq Pk/Unpk functions */ +EXTERN S16 cmPkTfuUePuschRecpReq ARGS(( + TfuUePuschRecpReq *param, + Buffer *mBuf +)); +EXTERN S16 cmUnpkTfuUePuschRecpReq ARGS(( + TfuUePuschRecpReq *param, + Buffer *mBuf +)); +EXTERN S16 cmPkTfuUePucchRecpReq ARGS(( + TfuUePucchRecpReq *param, + Buffer *mBuf +)); +EXTERN S16 cmUnpkTfuUePucchRecpReq ARGS(( + TfuUePucchRecpReq *param, + Buffer *mBuf +)); + +EXTERN S16 cmPkTfuRecpReqInfo ARGS(( + TfuRecpReqInfo *param, + Buffer *mBuf +)); +EXTERN S16 cmUnpkTfuRecpReqInfo ARGS(( + TfuRecpReqInfo *param, + Ptr memCp, + Buffer *mBuf +)); +EXTERN S16 cmPkTfuPdcchInfo ARGS(( + TfuPdcchInfo *param, + Buffer *mBuf +)); +EXTERN S16 cmUnpkTfuPdcchInfo ARGS(( + TfuPdcchInfo *param, + Buffer *mBuf +)); +EXTERN S16 cmPkTfuPhichInfo ARGS(( + TfuPhichInfo *param, + Buffer *mBuf +)); +EXTERN S16 cmUnpkTfuPhichInfo ARGS(( + TfuPhichInfo *param, + Buffer *mBuf +)); +EXTERN S16 cmPkTfuCntrlReqInfo ARGS(( + TfuCntrlReqInfo *param, + Buffer *mBuf +)); +EXTERN S16 cmUnpkTfuCntrlReqInfo ARGS(( + TfuCntrlReqInfo *param, + Ptr memCp, + Buffer *mBuf +)); +EXTERN S16 cmPkTfuPdschDciInfo ARGS(( + TfuPdschDciInfo *param, + Buffer *mBuf +)); +EXTERN S16 cmUnpkTfuPdschDciInfo ARGS(( + TfuPdschDciInfo *param, + Buffer *mBuf +)); +EXTERN S16 cmPkTfuDatReqPduInfo ARGS(( + TfuDatReqPduInfo *param, + Buffer *mBuf +)); +EXTERN S16 cmUnpkTfuDatReqPduInfo ARGS(( + TfuDatReqPduInfo *param, + Buffer *mBuf +)); +EXTERN S16 cmPkTfuDatReqInfo ARGS(( + TfuDatReqInfo *param, + Buffer *mBuf +)); +EXTERN S16 cmUnpkTfuDatReqInfo ARGS(( + TfuDatReqInfo *param, + Ptr memCp, + Buffer *mBuf +)); +EXTERN S16 cmPkTfuDatInfo ARGS(( + TfuDatInfo *param, + Buffer *mBuf +)); +EXTERN S16 cmUnpkTfuDatInfo ARGS(( + TfuDatInfo *param, + Buffer *mBuf +)); +EXTERN S16 cmPkTfuDatIndInfo ARGS(( + TfuDatIndInfo *param, + Buffer *mBuf +)); +EXTERN S16 cmUnpkTfuDatIndInfo ARGS(( + TfuDatIndInfo *param, + Ptr memCp, + Buffer *mBuf +)); +EXTERN S16 cmPkTfuSrInfo ARGS(( + TfuSrInfo *param, + Buffer *mBuf +)); +EXTERN S16 cmUnpkTfuSrInfo ARGS(( + TfuSrInfo *param, + Buffer *mBuf +)); +EXTERN S16 cmPkTfuSrIndInfo ARGS(( + TfuSrIndInfo *param, + Buffer *mBuf +)); +EXTERN S16 cmUnpkTfuSrIndInfo ARGS(( + TfuSrIndInfo *param, + Ptr memCp, + Buffer *mBuf +)); +EXTERN S16 cmPkTfuHqInfo ARGS(( + TfuHqInfo *param, + Buffer *mBuf +)); +EXTERN S16 cmUnpkTfuHqInfo ARGS(( + TfuHqInfo *param, + Buffer *mBuf +)); +EXTERN S16 cmPkTfuHqIndInfo ARGS(( + TfuHqIndInfo *param, + Buffer *mBuf +)); +EXTERN S16 cmUnpkTfuHqIndInfo ARGS(( + TfuHqIndInfo *param, + Ptr memCpm, + Buffer *mBuf +)); +EXTERN S16 cmPkTfuUlCqiInfo ARGS(( + TfuUlCqiInfo *param, + Buffer *mBuf +)); +EXTERN S16 cmUnpkTfuUlCqiInfo ARGS(( + TfuUlCqiInfo *param, + Buffer *mBuf +)); +EXTERN S16 cmPkTfuUlCqiRpt ARGS(( + TfuUlCqiRpt *param, + Buffer *mBuf +)); +EXTERN S16 cmUnpkTfuUlCqiRpt ARGS(( + TfuUlCqiRpt *param, + Buffer *mBuf +)); +EXTERN S16 cmPkTfuUlCqiIndInfo ARGS(( + TfuUlCqiIndInfo *param, + Buffer *mBuf +)); +EXTERN S16 cmUnpkTfuUlCqiIndInfo ARGS(( + TfuUlCqiIndInfo *param, + Ptr memCp, + Buffer *mBuf +)); +EXTERN S16 cmPkTfuDlCqiRpt ARGS(( + TfuDlCqiRpt *param, + Buffer *mBuf +)); +EXTERN S16 cmUnpkTfuDlCqiRpt ARGS(( + TfuDlCqiRpt *param, + Buffer *mBuf +)); +EXTERN S16 cmPkTfuDlCqiIndInfo ARGS(( + TfuDlCqiIndInfo *param, + Buffer *mBuf +)); +EXTERN S16 cmUnpkTfuDlCqiIndInfo ARGS(( + TfuDlCqiIndInfo *param, + Ptr memCp, + Buffer *mBuf +)); +EXTERN S16 cmPkTfuPucchDeltaPwr ARGS(( + Pst * pst, + SuId suId, + TfuPucchDeltaPwrIndInfo * pucchDeltaPwr)); + +EXTERN S16 cmPkTfuPucchDeltaPwrInfo ARGS(( + TfuPucchDeltaPwr *param, + Buffer *mBuf +)); + +EXTERN S16 cmUnpkTfuPucchDeltaPwr ARGS(( + TfuPucchDeltaPwrInd func, + Pst * pst, + Buffer *mBuf +)); +EXTERN S16 cmUnpkTfuPucchDeltaPwrInfo ARGS(( + TfuPucchDeltaPwr *param, + Buffer *mBuf +)); + +EXTERN S16 cmPkTfuCrcInfo ARGS(( + TfuCrcInfo *param, + Buffer *mBuf +)); +EXTERN S16 cmUnpkTfuCrcInfo ARGS(( + TfuCrcInfo *param, + Buffer *mBuf +)); +EXTERN S16 cmPkTfuCrcIndInfo ARGS(( + TfuCrcIndInfo *param, + Buffer *mBuf +)); +EXTERN S16 cmUnpkTfuCrcIndInfo ARGS(( + TfuCrcIndInfo *param, + Ptr memCp, + Buffer *mBuf +)); + +EXTERN S16 cmPkTfuPucchDeltaPwrIndInfo ARGS(( + TfuPucchDeltaPwrIndInfo *param, + Buffer *mBuf +)); +EXTERN S16 cmUnpkTfuPucchDeltaPwrIndInfo ARGS(( + TfuPucchDeltaPwrIndInfo *param, + Ptr memCp, + Buffer *mBuf +)); +EXTERN S16 cmPkTfuTimingAdvInfo ARGS(( + TfuTimingAdvInfo *param, + Buffer *mBuf +)); +EXTERN S16 cmUnpkTfuTimingAdvInfo ARGS(( + TfuTimingAdvInfo *param, + Buffer *mBuf +)); +EXTERN S16 cmPkTfuTimingAdvIndInfo ARGS(( + TfuTimingAdvIndInfo *param, + Buffer *mBuf +)); +EXTERN S16 cmUnpkTfuTimingAdvIndInfo ARGS(( + TfuTimingAdvIndInfo *param, + Ptr memCp, + Buffer *mBuf +)); +/* CA dev Start */ +EXTERN S16 cmPkTfuTtiCellInfo ARGS(( + TfuTtiCellInfo *param, + Buffer *mBuf +)); +EXTERN S16 cmUnpkTfuTtiCellInfo ARGS(( + TfuTtiCellInfo *param, + Buffer *mBuf +)); +/* CA dev End */ +EXTERN S16 cmPkTfuTtiIndInfo ARGS(( + TfuTtiIndInfo *param, + Buffer *mBuf +)); +EXTERN S16 cmUnpkTfuTtiIndInfo ARGS(( + TfuTtiIndInfo *param, + Buffer *mBuf +)); +EXTERN S16 cmPkTfuRaReqInfo ARGS(( + TfuRaReqInfo *param, + Buffer *mBuf +)); +EXTERN S16 cmUnpkTfuRaReqInfo ARGS(( + TfuRaReqInfo *param, + Buffer *mBuf +)); +EXTERN S16 cmPkTfuRachInfo ARGS(( + CmMemListCp memCp, + TfuRachInfo *param, + Buffer *mBuf +)); +EXTERN S16 cmUnpkTfuRachInfo ARGS(( + CmMemListCp memCp, + TfuRachInfo *param, + Buffer *mBuf +)); +EXTERN S16 cmPkTfuRaReqIndInfo ARGS(( + TfuRaReqIndInfo *param, + Buffer *mBuf +)); +EXTERN S16 cmUnpkTfuRaReqIndInfo ARGS(( + TfuRaReqIndInfo *param, + Buffer *mBuf +)); +EXTERN S16 cmPkBuffer ARGS(( + Buffer **param, + Buffer *mBuf +)); +EXTERN S16 cmUnpkBuffer ARGS(( + Buffer **param, + Buffer *mBuf +)); + +/* tfu_x_001.main_8. Added changes of TFU_UPGRADE */ +#ifdef TFU_UPGRADE +EXTERN S16 cmPkTfuSrsRpt ARGS(( + TfuSrsRpt *param, + Buffer *mBuf +)); +EXTERN S16 cmUnpkTfuSrsRpt ARGS(( + TfuSrsRpt *param, + Buffer *mBuf +)); +EXTERN S16 cmPkTfuSrsIndInfo ARGS(( + TfuSrsIndInfo *param, + Buffer *mBuf +)); +EXTERN S16 cmUnpkTfuSrsIndInfo ARGS(( + TfuSrsIndInfo *param, + Ptr memCp, + Buffer *mBuf +)); +EXTERN S16 cmPkTfuRawCqiRpt ARGS(( + TfuRawCqiRpt *param, + Buffer *mBuf +)); +EXTERN S16 cmUnpkTfuRawCqiRpt ARGS(( + TfuRawCqiRpt *param, + Buffer *mBuf +)); +EXTERN S16 cmPkTfuRawCqiIndInfo ARGS(( + TfuRawCqiIndInfo *param, + Buffer *mBuf +)); +EXTERN S16 cmUnpkTfuRawCqiIndInfo ARGS(( + TfuRawCqiIndInfo *param, + Ptr memCp, + Buffer *mBuf +)); + +#ifdef TFU_TDD + +EXTERN S16 cmPkTfuUePucchHqRecpInfo ARGS(( + TfuUePucchHqRecpInfo *param, + Buffer *mBuf +)); +EXTERN S16 cmUnpkTfuUePucchHqRecpInfo ARGS(( + TfuUePucchHqRecpInfo *param, + Buffer *mBuf +)); + +#endif + +#ifndef TFU_TDD /* else of TFU_TDD */ + +EXTERN S16 cmPkTfuUePucchHqRecpInfo ARGS(( + TfuUePucchHqRecpInfo *param, + Buffer *mBuf +)); +EXTERN S16 cmUnpkTfuUePucchHqRecpInfo ARGS(( + TfuUePucchHqRecpInfo *param, + Buffer *mBuf +)); + + +#endif +EXTERN S16 cmPkTfuUePucchSrRecpInfo ARGS(( + TfuUePucchSrRecpInfo *param, + Buffer *mBuf +)); +EXTERN S16 cmUnpkTfuUePucchSrRecpInfo ARGS(( + TfuUePucchSrRecpInfo *param, + Buffer *mBuf +)); +EXTERN S16 cmPkTfuUePucchCqiRecpInfo ARGS(( + TfuUePucchCqiRecpInfo *param, + Buffer *mBuf +)); +EXTERN S16 cmUnpkTfuUePucchCqiRecpInfo ARGS(( + TfuUePucchCqiRecpInfo *param, + Buffer *mBuf +)); +EXTERN S16 cmPkTfuUePucchSrsRecpInfo ARGS(( + TfuUePucchSrsRecpInfo *param, + Buffer *mBuf +)); +EXTERN S16 cmUnpkTfuUePucchSrsRecpInfo ARGS(( + TfuUePucchSrsRecpInfo *param, + Buffer *mBuf +)); +EXTERN S16 cmPkTfuUeUlSchRecpInfo ARGS(( + TfuUeUlSchRecpInfo *param, + Buffer *mBuf +)); +EXTERN S16 cmUnpkTfuUeUlSchRecpInfo ARGS(( + TfuUeUlSchRecpInfo *param, + Buffer *mBuf +)); +EXTERN S16 cmPkTfuUePuschCqiRecpInfo ARGS(( + TfuUePuschCqiRecpInfo *param, + Buffer *mBuf +)); +EXTERN S16 cmUnpkTfuUePuschCqiRecpInfo ARGS(( + TfuUePuschCqiRecpInfo *param, + Buffer *mBuf +)); +EXTERN S16 cmPkTfuUePuschHqRecpInfo ARGS(( + TfuUePuschHqRecpInfo *param, + Buffer *mBuf +)); +EXTERN S16 cmUnpkTfuUePuschHqRecpInfo ARGS(( + TfuUePuschHqRecpInfo *param, + Buffer *mBuf +)); + +EXTERN S16 cmPkTfuBfVectorInfo ARGS (( +TfuBfVectorInfo *param, +Buffer *mBuf +)); + +EXTERN S16 cmUnpkTfuBfVectorInfo ARGS (( + TfuBfVectorInfo *param, + Buffer *mBuf +)); +#endif /* TFU_UPGRADE */ +/* tfu_x_001.main_8. Added changes of TFU_UPGRADE */ +EXTERN S16 cmPkTfuUeRecpReqInfo ARGS(( + TfuUeRecpReqInfo *param, + Buffer *mBuf +)); +EXTERN S16 cmUnpkTfuUeRecpReqInfo ARGS(( + TfuUeRecpReqInfo *param, + Buffer *mBuf +)); + +/* tfu_x_001.main_8. Added changes of TFU_UPGRADE */ +#ifdef TFU_UPGRADE +/** @brief This primitive is used to convey the Raw CQI information + * transmitted by the UE. + * @details Raw CQI report is the actual bits transmitted by the UE when + * reporting CQI/PMI/RI. The interpretation of these bits to CQI/sub-band CQI + * and so on, are done by MAC. + * + * @param pst Pointer to the post structure. + * @param suId SAP ID of the service user. + * @param cqiInd Pointer to the TfuRawCqiIndInfo structure. + * @return ROK/RFAILED + */ +EXTERN S16 cmPkTfuRawCqiInd ARGS(( + Pst * pst, + SuId suId, + TfuRawCqiIndInfo * rawCqiInd +)); +/** @brief This primitive is used to convey the Raw CQI information + * transmitted by the UE. + * @details Raw CQI report is the actual bits transmitted by the UE when + * reporting CQI/PMI/RI. The interpretation of these bits to CQI/sub-band CQI + * an so on, are done by MAC. + * + * @param pst Pointer to the post structure. + * @param suId SAP ID of the service user. + * @param cqiInd Pointer to the TfuRawCqiIndInfo structure. + * @return ROK/RFAILED + */ +EXTERN S16 cmUnpkTfuRawCqiInd ARGS(( + TfuRawCqiInd func, + Pst * pst, + Buffer *mBuf +)); +/** @brief This primitive is used to convey the information derived by the + * physical layer from the SRS transmission from the UE. + * @details This primitive carries information derived from the SRS transmission + * from the UE. + * + * @param pst Pointer to the post structure. + * @param suId SAP ID of the service user. + * @param srsInd Pointer to the TfuSrIndInfo structure. + * @return ROK/RFAILED + */ +EXTERN S16 cmPkTfuSrsInd ARGS(( + Pst * pst, + SuId suId, + TfuSrsIndInfo * srsInd +)); +/** @brief This primitive is used to convey the information derived by the + * physical layer from the SRS transmission from the UE. + * @details This primitive carries information derived from the SRS transmission + * from the UE. + * + * @param pst Pointer to the post structure. + * @param suId SAP ID of the service user. + * @param srsInd Pointer to the TfuSrIndInfo structure. + * @return ROK/RFAILED + */ +EXTERN S16 cmUnpkTfuSrsInd ARGS(( + TfuSrsInd func, + Pst * pst, + Buffer *mBuf +)); +#endif + +/*tfu_x_001.main_6 - Added for SPS support*/ +#ifdef LTEMAC_SPS +EXTERN S16 cmPkTfuAllocMap ARGS(( + TfuAllocMap *param, + Buffer *mBuf +)); +EXTERN S16 cmUnpkTfuAllocMap ARGS(( + TfuAllocMap *param, + Buffer *mBuf + )); +#ifdef EMTC_ENABLE +EXTERN S16 cmPkTfuDciFormat6AAllocInfo ARGS(( + TfuDciFormat61AllocInfo *param, + Buffer *mBuf + )); +EXTERN S16 cmUnpkTfuDciFormat6AAllocInfo ARGS(( + TfuDciFormat61AllocInfo *param, + Buffer *mBuf + )); +EXTERN S16 cmUnpkTfuDciFormat61aInfo ARGS(( + TfuDciFormat61aInfo *param, + Buffer *mBuf + )); +EXTERN S16 cmUnpkTfuDciFormat62Info ARGS(( + TfuDciFormat62Info *param, + Buffer *mBuf + )); + +EXTERN S16 cmUnpkTfudciformat61aPdsch ARGS(( + Tfudciformat61aPdsch *param, + Buffer *mBuf + )); +EXTERN S16 cmPkTfuDciFormat61aInfo ARGS(( + TfuDciFormat61aInfo *param, + Buffer *mBuf + )); + +#endif + + +#endif + +/* LTE_UNLICENSED */ +EXTERN S16 cmPkTfuErrInd ARGS(( + Pst * pst, + SuId suId, + TfuErrIndInfo * errInd +)); + +EXTERN S16 cmUnpkTfuErrInd ARGS(( + TfuErrInd func, + Pst * pst, + Buffer *mBuf +)); +#endif /*LCTFU*/ + + +#ifdef __cplusplus +} +#endif +#endif /* __TFUX__ */ + +/********************************************************************30** + + End of file +**********************************************************************/ diff --git a/src/mt/mt_ss.h b/src/mt/mt_ss.h new file mode 100755 index 000000000..d4876e347 --- /dev/null +++ b/src/mt/mt_ss.h @@ -0,0 +1,382 @@ +/******************************************************************************* +################################################################################ +# Copyright (c) [2017-2019] [Radisys] # +# # +# 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. # +################################################################################ +*******************************************************************************/ + +/********************************************************************20** + + Name: MTSS -- implementation specific definitions + + Type: C include file + + Desc: Various macro definitions demanded by systems services. + The contents of these are for the MTSS implementation. + + File: mt_ss.h + +*********************************************************************21*/ + + +#ifndef __MTSSH__ +#define __MTSSH__ + + +/* --- interface to SS --- */ + +/* general */ +#define SS_PROC_ID PID_STK(1) + +/* task related */ +/* mt028.201: addition: multiple procs support related changes */ +#ifdef SS_MULTIPLE_PROCS +#define SS_MAX_PROCS 100 /* max entries for proc list */ +#endif /* SS_MULTIPLE_PROCS */ + +#define SS_MAX_ENT 255 +#define SS_MAX_INST 8 + +/* mt028.201: modification: multiple procs support related changes */ +#ifndef SS_MULTIPLE_PROCS +#define SS_MAX_TTSKS 100 + +#ifndef SS_MULTICORE_SUPPORT +#define SS_MAX_STSKS 7 +#else +/* mt001.301 : Additions */ +#ifdef SPLIT_RLC_DL_TASK +#ifdef L2_L3_SPLIT +#define SS_MAX_STSKS 4 +#else +#define SS_MAX_STSKS 5 +#endif +#else +#define SS_MAX_STSKS 4 +#endif +#endif /* SS_MULTICORE_SUPPORT */ + +#else /* SS_MULTIPLE_PROCS */ +#define SS_MAX_TTSKS 1000 +#define SS_MAX_STSKS 7 +#endif /* SS_MULTIPLE_PROCS */ + +#ifdef SS_DRVR_SUPPORT +#define SS_MAX_DRVRTSKS 70 +#endif + +#ifdef SS_RTR_SUPPORT + /* mt0012.21 : Addition */ +#define SS_MAX_RTRTSKS 255 +#endif + + +/* timer related */ +#define SS_MAX_TMRS 45 + +/* memory related */ +/* mt022.201 - Modification for shared memory relay and memcal regions */ +#ifdef SS_MULTICORE_SUPPORT +#define SS_MAX_REGS SS_MAX_STSKS +#else +#define SS_MAX_REGS 1 +#endif + +#ifdef CMM_MAX_BKT_ENT +#define SS_MAX_POOLS_PER_REG CMM_MAX_BKT_ENT +#else +#define SS_MAX_POOLS_PER_REG 5 +#endif +/* mt001.301 : Additions */ +#ifdef SS_WATCHDOG +#define ENTDW 0xcd +#define ENTHB 0xce +#define INST0 0x00 +#define SS_TMR_HRTBT 0x00 +#define EVTSSHRTBTREQ 0x00 +#define EVTSSHRTBTRSP 0x01 +#define SS_LOOSE_COUPLING 0x00 +#endif /* SS_WATCHDOG */ + +/* locks */ +#define SS_STSKTBL_LOCK SS_LOCK_MUTEX +#define SS_STSKENTRY_LOCK SS_LOCK_MUTEX +#define SS_TMRTBL_LOCK SS_LOCK_MUTEX +#define SS_DMNDQ_LOCK SS_LOCK_MUTEX +#define SS_DRVRENTRY_LOCK SS_LOCK_MUTEX +#define SS_RTRENTRY_LOCK SS_LOCK_MUTEX + +#ifdef TENB_T2K3K_SPECIFIC_CHANGES +#define MIPS_FILE "/sys/devices/virtual/mmonitor/mmonitor/mips_stat" +#define GET_CPU_MAX(x, y) ((x) >= (y) ? (x) : (y)) +#define MIPS_STRING_LEN 24 +#endif + + +/* types needed by common SSI code */ +#define SsSemaId sem_t +#define SLockId pthread_mutex_t + + +/* calls needed by common SSI code */ +#ifndef TENB_RTLIN_CHANGES +#define SInitLock(l, t) pthread_mutex_init(l, NULL) +#endif +/*extern U32 gt[128]; */ +/*#define SLock(l) (((gt[0x000000FF &((U32)pthread_self())]=MacGetTick())&&pthread_mutex_lock(l)&&MLogTask(30340, RESOURCE_LINL2, gt[0x000000FF &((U32)pthread_self())], MacGetTick()))?0:0)*/ +#define SLock(l) pthread_mutex_lock(l) +#define SUnlock(l) pthread_mutex_unlock(l) +#define SDestroyLock(l) pthread_mutex_destroy(l) + +#define ssInitSema(s, c) sem_init(s, 0, c) +#define ssWaitSema(s) sem_wait(s) +#define ssPostSema(s) sem_post(s) +#define ssDestroySema(s) sem_destroy(s) + +#define SS_CHECK_CUR_STSK(t) (pthread_equal(pthread_self(), \ + (t)->dep.tId)) + /* mt013.21: Addition */ +#define SInitSemaphore(s, c) sem_init(s, 0, c) +#define SWaitSemaphore(s) sem_wait(s) +#define SPostSemaphore(s) sem_post(s) +#define SDestroySemaphore(s) sem_destroy(s) + +#define ssdPstTsk(p, m, t) + +/* added SExit() for exiting process : mt017.21 */ +/* mt001.301 : Additions */ +#ifndef SS_LOGGER_SUPPORT +#define SExit() exit(0) +#else +#define SExit() \ +{ \ +SCleanUp(); \ +exit(0); \ +} +#endif /* SS_LOGGER_SUPPORT */ + + /* mt007.21 addition */ +/* calls needed by Message Functions */ +#define SMemCpy(d,s,c) memcpy(d,s,c) +#define SMemSet(s,c,n) memset(s,c,n) +/* --- internal to MTSS-Solaris --- */ + + +/*mt041.201 Value of MT_TICK_CNT changed*/ +/*mt004.301- defining the MT_TICK_CNT in Micro seconds (usecs) */ +/* mt010.301 Removed #ifdef SS_FAP portion and enabled oroginal code */ +#define MT_TICK_CNT (((U32)0x0F4240)/SS_TICKS_SEC) + +#define MT_MAX_TICK_CNT_VAL 35 +#define MT_MIN_TICK_CNT_VAL 1 + + +/* interrupt service flags */ +#define MT_IS_SET 0 +#define MT_IS_UNSET 1 +#define MT_IS_RESET 2 + +/****************************************************************** + mt018.201 - Memory Configuration. + +Memory block sizes and counts for memory manager configuration +There is no restriction in the size of each block for the bucket. +However, it is recommended that the bucket size should be word aligned. +The CMM (Common Memory Manager) also create a look up table which map +the size to the bucket index. +The number of entry in the lookup table (CMM_MAX_MAP_ENT, defined in +cm_mem.h) = ((maximum bucket size)/(bucket quantum size)) + 1. +The CMM_MAX_MAP_ENT should be changed depending on the bucket sizes +that are configured below. +*******************************************************************/ + +/* Bucket 0 configuration */ +/* mt032.201 changed MT_BKT_0_DSIZE from 120 to 128 for 64k compilation */ +#define MT_BKT_0_DSIZE 256 +/*mt004.301-changed for FAP*/ +#ifndef SS_FAP +#ifdef XEON_SPECIFIC_CHANGES +#define MT_BKT_0_NUMBLKS 5248 /* 10500 Modified from 3500 to 10500 */ +#else +#define MT_BKT_0_NUMBLKS 10000 /* 10500 Modified from 3500 to 10500 */ +#endif +#else +#define MT_BKT_0_NUMBLKS 10000 +#endif + +/* Bucket 1 configuration */ +/*mt004.301-changed for FAP*/ +#ifndef SS_FAP +#ifdef XEON_SPECIFIC_CHANGES +#define MT_BKT_1_DSIZE 1024 /* Modified from 256 to 4096 */ +#else +#define MT_BKT_1_DSIZE 2048 /* Modified from 256 to 4096 */ +#endif +#define MT_BKT_1_NUMBLKS 10496 /* 1000*/ +#else +/*mt010.301*/ +#define MT_BKT_1_DSIZE 256 +#define MT_BKT_1_NUMBLKS 2000 +#endif + +/* Bucket 2 configuration */ +/*mt010.301*/ +#ifdef SS_FAP +#define MT_BKT_2_DSIZE 1376 /* Fill in this value as required */ +#define MT_BKT_2_NUMBLKS 4000 /* Fill in this value as required */ +#else +#ifdef XEON_SPECIFIC_CHANGES +#define MT_BKT_2_DSIZE 1768 /* 1664 2048 */ +#define MT_BKT_2_NUMBLKS 5248 /* 10496 */ +#else +#define MT_BKT_2_DSIZE 8196 /* 1664 2048 */ +#define MT_BKT_2_NUMBLKS 2000 /* 10496 */ +#endif +#endif + + +/* Bucket 3 configuration */ +/*mt010.301*/ +#ifdef SS_FAP +#define MT_BKT_3_DSIZE 2592 /* Fill in this value as required */ +#define MT_BKT_3_NUMBLKS 1500 /* Fill in this value as required */ +#else +#ifdef XEON_SPECIFIC_CHANGES +#define MT_BKT_3_DSIZE 4224 /* Fill in this value as required */ +#define MT_BKT_3_NUMBLKS 5248 /*10496 */ /* Fill in this value as required */ +#else +#define MT_BKT_3_DSIZE 16896 /* Fill in this value as required */ +#define MT_BKT_3_NUMBLKS 1000 /*10496 */ /* Fill in this value as required */ +#endif +#endif + +/* For Non-Sharable regions/static regions */ +#ifdef XEON_SPECIFIC_CHANGES +#define MT_BKT_0_STATIC_NUMBLKS 500000 /* Fill in this value as required */ +#define MT_BKT_1_STATIC_NUMBLKS 500000 /* Fill in this value as required */ +#define MT_BKT_2_STATIC_NUMBLKS 200000 /* Fill in this value as required */ +#define MT_BKT_3_STATIC_NUMBLKS 40960 /* Fill in this value as required */ +#define MT_BKT_4_STATIC_NUMBLKS 4096 /* Fill in this value as required */ +#else +#define MT_BKT_0_STATIC_NUMBLKS 10000 /* Fill in this value as required */ +#define MT_BKT_1_STATIC_NUMBLKS 1000 /* Fill in this value as required */ +#define MT_BKT_2_STATIC_NUMBLKS 2000 /* Fill in this value as required */ +#define MT_BKT_3_STATIC_NUMBLKS 1000 /* Fill in this value as required */ +#endif +/*mt010.301*/ +#ifdef RGL_SPECIFIC_CHANGES +#define MT_MAX_BKTS 5 +#else +#define MT_MAX_BKTS 4 +#endif + +/* mt029.201 corrected typos */ +/* memory pool data size definitions for pool-to-size mapping table */ +#define MT_POOL_3_DSIZE (MT_BKT_3_DSIZE-(sizeof(SsMblk)+sizeof(SsDblk))) +#define MT_POOL_2_DSIZE (MT_BKT_2_DSIZE-(sizeof(SsMblk)+sizeof(SsDblk))) +#define MT_POOL_1_DSIZE (MT_BKT_1_DSIZE-(sizeof(SsMblk)+sizeof(SsDblk))) +#define MT_POOL_0_DSIZE (MT_BKT_0_DSIZE-(sizeof(SsMblk)+sizeof(SsDblk))) + + + +/* mt026.201 - Modification to increase default heap size */ +/* memory size used for heap by the memory manager (2MB) */ +/* mt001.301 : Additions */ +/*mt004.301- changed heap size for FAP */ +#ifdef SS_FAP +#define MT_HEAP_SIZE 5242880U +#else +#ifdef XEON_SPECIFIC_CHANGES +#define MT_HEAP_SIZE 6194304U +#else +#define MT_HEAP_SIZE 6194304U /*PAL FIX: 4MB to 6MB flexran */ +#endif +#endif + +#ifndef USE_MEMCAL +#define STATIC_MEM_CFG +#endif + +/* mt022.201 - definition of MT_BKTQNSIZE */ +/*mt010.301*/ +#define MT_BKTQNSIZE 128 + + +/* mt021.201 - Addition for setting stack size for threads */ +/* Configuration for stack size (in bytes) of spawned threads + * Size of zero gives default of 1 MB or 2 MB for 32 bit or 64 bit + * compilers, respectively */ +#define MT_TASK_STACK NULLD /* stack size for task handler */ +#define MT_ISTASK_STACK NULLD /* stack size for IS task handler */ +#define MT_TMRTASK_STACK NULLD /* stack size for timer handler */ +#define MT_CONSOLE_STACK NULLD /* stack size for console handler */ + +/* mt001.301 : Additions Logger support */ +#ifdef SS_LOGGER_SUPPORT +#ifndef SS_MAX_LOGBUF_SIZE +#define SS_MAX_LOGBUF_SIZE 8192 +#endif +#ifndef SS_MAX_PATH +#define SS_MAX_PATH 1024 +#endif +#endif /* SS_LOGGER_SUPPORT */ +/* mt005.301: Cavium changes: */ +#ifdef SS_SEUM_CAVIUM +/* Cavium related hashdefines */ +#define SS_CVMX_GRP_MASK (1 << osCp.procId) + +#define SS_CVMX_NUM_PKT_BUFFERS 0 +#define SS_CVMX_NUM_WQE_BUFFERS 100 +#define SS_CVMX_NUM_PKO_BUFFERS 0 +#define SS_CVMX_NUM_TIM_BUFFERS 1000 +#define SS_CVMX_NUM_DFA_BUFFERS 0 + +/* fpa pool 0 configuration */ +#define SS_CVMX_POOL_0_NUMBLKS 3000 + +/* fpa pool 1 configuration */ +#define SS_CVMX_POOL_1_NUMBLKS 100 + +/* fpa pool 2 configuration */ +#define SS_CVMX_POOL_2_NUMBLKS 10 /* Fill in this value as required */ + +/* fpa pool 3 configuration */ +#define SS_CVMX_POOL_3_NUMBLKS 2500 /* Fill in this value as required */ + +#define SS_CVMX_TICK_TIME 1000 /* the value is in micorsec */ +#define SS_CVMX_MAX_TICKS 1000 +#define SS_CVMX_TICKS 500 + +#define SS_CVMX_TMR_TAG 1000 +#define SS_CVMX_MBUF_TAG 1001 +#endif /* SS_SEUM_CAVIUM */ + +/* mt011.301: Pool definition for both 64 bit and 32 bit Cavium */ +#ifndef SS_CVMX_WQE_POOL +#ifdef BIT_64 +#define SS_CVMX_WQE_POOL CVMX_FPA_WQE_POOL +#else +#define SS_CVMX_WQE_POOL SS_CVMX_POOL_0 +#endif +#endif + + +#endif /* __MTSSH__ */ + + + +/********************************************************************30** + + End of file +**********************************************************************/ diff --git a/src/mt/mt_ss.x b/src/mt/mt_ss.x new file mode 100755 index 000000000..d7cdcccc6 --- /dev/null +++ b/src/mt/mt_ss.x @@ -0,0 +1,173 @@ +/******************************************************************************* +################################################################################ +# Copyright (c) [2017-2019] [Radisys] # +# # +# 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. # +################################################################################ +*******************************************************************************/ + +/********************************************************************20** + + Name: MTSS -- implementation specific definitions + + Type: C include file + + Desc: Data structure definitions demanded by systems services. + The contents of these are for the MTSS implementation. + + File: mt_ss.x + +*********************************************************************21*/ + + +#ifndef __MTSSX__ +#define __MTSSX__ + +/* mt001.301: Addition */ +#ifdef SS_LOGGER_SUPPORT +/* #define __USE_POSIX */ +#include +#include +#endif /* SS_LOGGER_SUPPORT */ + +/* TAPA task entry doesn't need anything extra for MTSS */ +typedef S8 SsdTTskEntry; + + +/* System task entry */ +typedef struct ssdSTskEntry +{ + pthread_t tId; + Ent ent; + Inst inst; + SLockId lock; + +#ifdef SS_MULTICORE_SUPPORT + U32 lwpId; +#endif /* SS_MULTICORE_SUPPORT */ +} SsdSTskEntry; + + +#ifdef SS_DRVR_SUPPORT +/* Driver task entry */ +typedef struct ssdDrvrTskEntry +{ + Bool flag; + +} SsdDrvrTskEntry; +#endif + + +/* timer entry--MTSS uses common timers */ +typedef struct ssdTmrEntry +{ + CmTimer timers[TMR_DEF_MAX]; + +} SsdTmrEntry; + + +/* dynamic pool doesn't need anything extra for MTSS */ +typedef S8 SsdDPoolEntry; + + +/* static pool -- information for the memory management scheme */ +typedef S8 SsdSPoolEntry; + + +/* generic pool doesn't need anything extra for MTSS */ +typedef S8 SsdPoolEntry; + + +/* region doesn't need anything extra for MTSS */ +typedef S8 SsdRegionEntry; + + +/* system services control point--tick count, timer implementation, + * console implementation, IS task implementation + */ +typedef struct ssdOs +{ + unsigned randSeed; /* random number generator seed */ + + Ticks sysTicks; /* elapsed system ticks */ + + pthread_t tmrHdlrTID; /* timer handler thread */ + CmTqCp tmrTqCp; /* common timer control point */ + CmTqType tmrTq[SS_MAX_TMRS]; /* common timer queue */ + + sem_t ssStarted; /* posted when SS completes init */ +#ifdef CONAVL + FILE *conInFp; /* console input file pointer */ + FILE *conOutFp; /* console output file pointer */ + pthread_t conHdlrTID; /* console handler thread ID */ +#endif + +#ifndef NOFILESYS + FILE *fileOutFp; /* output file pointer */ +#endif + +#ifdef SS_DRVR_SUPPORT + pthread_t isTskHdlrTID; /* IS task handler thread ID */ + int isFildes[2]; /* pipe for SSetIntPend to isTskHdlr */ +#endif + Bool sigEvnt; /*mt010.301 Flag to check interupt signal(SIGINT)*/ + +} SsdOs; + +/* mt018.201 - added for memory configuration */ +typedef struct mtBktCfg +{ + Size blkSize; /* bucket quantum size */ + U32 numBlks; /* the total blocks in the bucket */ +} MtBktCfg; + +typedef struct mtRegCfg +{ + Region regionId; + U16 numBkts; + Size heapsize; + MtBktCfg bkt[SS_MAX_POOLS_PER_REG]; +} MtRegCfg; + +typedef struct mtMemCfg +{ + U8 numRegions; + MtRegCfg region[SS_MAX_REGS]; +} MtMemCfg; + + +/* mt003.301 Readwrite lock additions */ +#ifdef SS_LOCK_SUPPORT +typedef struct sLockInfo +{ + union + { +#ifdef SS_RDWR_LOCK_SUPPORT + pthread_rwlock_t rdWrLockId; +#endif /* SS_RDWR_LOCK_SUPPORT */ +#ifdef SS_REC_LOCK_SUPPORT + pthread_mutex_t recurLock; +#endif /* SS_REC_LOCK_SUPPORT */ + }l; +}SLockInfo; +#endif /* SS_LOCK_SUPPORT */ + +extern U32 gt[128]; +#endif /* __MTSSX__ */ + + + +/********************************************************************30** + + End of file +**********************************************************************/ diff --git a/src/mt/ss_dep.h b/src/mt/ss_dep.h new file mode 100755 index 000000000..1df1167a8 --- /dev/null +++ b/src/mt/ss_dep.h @@ -0,0 +1,139 @@ +/******************************************************************************* +################################################################################ +# Copyright (c) [2017-2019] [Radisys] # +# # +# 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. # +################################################################################ +*******************************************************************************/ + +/********************************************************************20** + + Name: System Services -- implementation specific definitions + + Type: C include file + + Desc: This file conditionally includes various implementation + specific files. + + File: ss_dep.h + +*********************************************************************21*/ + + +#ifndef __SSDEPH__ +#define __SSDEPH__ + +#ifdef __cplusplus +extern "C" { +#endif + +/*ss014.301 : 4GMX SSI specific includes*/ +#ifdef SS_4GMX_LCORE +#include "rb_include.h" +#include +#include +#else +/*ss011.301 : RMI SSI specific includes*/ +#ifdef SS_RMIOS +#include +#include "uc_ss.h" +#include "string.h" +#include "byteorder.h" +#include "cm5.h" +#else +#ifdef SS_MT +#ifndef _POSIX_C_SOURCE +#define _POSIX_C_SOURCE 199309L +#endif +#include +#include +#include +#include "cm5.h" +#include "mt_ss.h" + /* ss003.13: addition */ +#include +#include +#include +#include +#else /* not SS_MT */ + +#ifdef SS_PS +#include +#include "cm5.h" +#include "ps.h" +#include "ps_ss.h" + /* ss009.13: addition */ +#include +#else /* not SS_PS */ + +#ifdef SS_VW + /* ss002.13: addition */ +#include +#include "vw_ss.h" +#include +#include +#include +#include +#include +#include "cm5.h" +#else /* not SS_VW */ + +#ifdef NS +#ifdef FAR +#undef FAR +#endif +#ifdef NEAR +#undef NEAR +#endif +#ifdef NU +#include +#include "windows.h" +#include "winbase.h" +#endif /* NU */ + +#ifdef NK +#include "ntddk.h" +#endif /* NK */ +#include "ns_err.h" +#include "ns_task.h" +#include "ns_timer.h" +#include "ns_gen.h" +#else /* not NS */ + +#ifdef SS_SK +#include "sk_ss.h" +#else /* not SS_SK */ + +#error "Specify an implementation" + +#endif /* SS_SK */ +#endif /* NS */ +#endif /* SS_VW */ +#endif /* SS_PS */ +#endif /* SS_MT */ +#endif /* SS_RMIOS */ +#endif /* SS_4GMX_LCORE */ + + +#ifdef __cplusplus +} +#endif + +#endif /* __SSDEPH__ */ + + + +/********************************************************************30** + + End of file +**********************************************************************/ diff --git a/src/mt/ss_dep.x b/src/mt/ss_dep.x new file mode 100755 index 000000000..8085412e4 --- /dev/null +++ b/src/mt/ss_dep.x @@ -0,0 +1,99 @@ +/******************************************************************************* +################################################################################ +# Copyright (c) [2017-2019] [Radisys] # +# # +# 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. # +################################################################################ +*******************************************************************************/ + +/********************************************************************20** + + Name: System Services -- implementation specific definitions + + Type: C include file + + Desc: This file conditionally includes implementation + specific files. + + File: ss_dep.x + +*********************************************************************21*/ + + +#ifndef __SSDEPX__ +#define __SSDEPX__ + +#ifdef __cplusplus +extern "C" { +#endif + +/*ss014.301 : 4GMX SSI specific includes*/ +#ifdef SS_4GMX_LCORE +#else + +/*ss011.301 : RMI SSI specific includes*/ +#ifdef SS_RMIOS +#include "cm5.x" +#include "uc_ss.x" +#else + +#ifdef SS_MT +#include "cm5.x" +#include "mt_ss.x" +#else /* not SS_MT */ + +#ifdef SS_PS +#include "cm5.x" +#include "ps.x" +#include "ps_ss.x" +#else /* not SS_PS */ + +#ifdef SS_VW +#include "vw_ss.x" +#include "cm5.x" +#else /* not SS_VW */ + +#ifdef NS +#include "ns_task.x" +#include "ns_timer.x" +#include "cm5.x" +#include "ns_gen.x" +#else /* not NS */ + +#ifdef SS_SK +#include "sk_ss.x" +#else /* not SS_SK */ + +#error "Specify an implementation" + +#endif /* SS_SK */ +#endif /* NS */ +#endif /* SS_VW */ +#endif /* SS_PS */ +#endif /* SS_MT */ +#endif /* SS_RMIOS*/ +#endif /* SS_4GMX_LCORE*/ + + +#ifdef __cplusplus +} +#endif + +#endif /* __SSDEPX__ */ + + + +/********************************************************************30** + + End of file +**********************************************************************/ diff --git a/src/mt/ss_drvr.x b/src/mt/ss_drvr.x new file mode 100755 index 000000000..3b308b0c3 --- /dev/null +++ b/src/mt/ss_drvr.x @@ -0,0 +1,76 @@ +/******************************************************************************* +################################################################################ +# Copyright (c) [2017-2019] [Radisys] # +# # +# 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. # +################################################################################ +*******************************************************************************/ + +/********************************************************************20** + + Name: System Services -- Driver tasks + + Type: C include file + + Desc: Data structure definitions required for driver tasks. + + File: ss_drvr.x + +*********************************************************************21*/ + + +#ifndef __SSDRVRX__ +#define __SSDRVRX__ + +#ifdef __cplusplus +extern "C" { +#endif + + +#ifdef SS_DRVR_SUPPORT + +/* individual entry in the table of driver tasks */ +typedef struct ssDrvrTskEntry +{ + /* Any implementation specific content */ + SsdDrvrTskEntry dep; + + + /* Common content */ + Bool used; /* entry is used or not */ + Inst channel; /* channel ID */ + ActvTsk actvTsk; /* activation function */ + ISTsk isTsk; /* interrupt service task */ + ProcId low; /* processor ID -- low */ + ProcId high; /* processor ID -- high */ + + SLockId lock; /* to serialize calls to the + activation function */ + +} SsDrvrTskEntry; + +#endif /* SS_DRVR_SUPPORT */ + + +#ifdef __cplusplus +} +#endif + +#endif /* __SSDRVRX__ */ + + + +/********************************************************************30** + + End of file +**********************************************************************/ diff --git a/src/mt/ss_gen.h b/src/mt/ss_gen.h new file mode 100755 index 000000000..9fc4851c0 --- /dev/null +++ b/src/mt/ss_gen.h @@ -0,0 +1,296 @@ +/******************************************************************************* +################################################################################ +# Copyright (c) [2017-2019] [Radisys] # +# # +# 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. # +################################################################################ +*******************************************************************************/ + +/********************************************************************20** + + Name: System Services -- general + + Type: C include file + + Desc: Macro definitions that are used by all implementations + of system services. + + File: ss_gen.h + +*********************************************************************21*/ + + +#ifndef __SSGENH__ +#define __SSGENH__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* ss040.103: addition */ +/* ss002.301 : errno.h is required for all */ +#include + +/* the new driver support define */ +#ifdef ENB_RELAY +#ifndef SS_DRVR_SUPPORT +#define SS_DRVR_SUPPORT +#endif +#endif + + + +/* general */ +#ifndef SS_PROC_ID +#error "SS_PROC_ID undefined!" +#endif + +#ifndef SS_MAX_ENT +#error "SS_MAX_ENT undefined!" +#endif + +#ifndef SS_MAX_INST +#error "SS_MAX_INST undefined!" +#endif + + +/* ss029.103: modification: the data type of array modified */ +#ifndef SS_MULTIPLE_PROCS +#define SS_INVALID_IDX 0xFF +#else /* SS_MULTIPLE_PROCS */ +#define SS_INVALID_IDX 0xFFFF +#endif /* SS_MULTIPLE_PROCS */ + + +/* task related */ +#ifndef SS_MAX_TTSKS +#error "SS_MAX_TTSKS undefined!" +#endif + +#ifndef SS_MAX_STSKS +#error "SS_MAX_STSKS undefined!" +#endif + +#ifdef SS_DRVR_SUPPORT +#ifndef SS_MAX_DRVRTSKS +#error "SS_MAX_DRVRTSKS undefined!" +#endif +#endif /* SS_DRVR_SUPPORT */ + +#ifdef SS_RTR_SUPPORT +#ifndef SS_MAX_RTRTSKS +#error "SS_MAX_RTRTSKS undefined!" +#endif +#endif /* SS_RTR_SUPPORT */ + +/* ss029.103: modification: the data type of array modified */ +#ifndef SS_MULTIPLE_PROCS +#define SS_TSKNC 0xFF +#else /* SS_MULTIPLE_PROCS */ +#define SS_TSKNC 0xFFFF +#endif /* SS_MULTIPLE_PROCS */ + + +/* timer related */ +#ifndef SS_MAX_TMRS +#error "SS_MAX_TMRS undefined!" +#endif + + + +/* memory related */ +#ifndef SS_MAX_REGS +#error "SS_MAX_REGS undefined!" +#endif + +#ifndef SS_MAX_POOLS_PER_REG +#error "SS_MAX_POOLS_PER_REG undefined!" +#endif + + +/* event types */ +#define SS_EVNT_DATA 0 +#define SS_EVNT_TIMER 1 +#define SS_EVNT_TERM 2 +#define SS_EVNT_PERMTICK 3 +/* + * SDeRegTTsk patch + */ +#define SS_EVNT_TTSK_TERM 4 + +/* ss001.301: SSI Phase 2 watchdog feature additions */ +#ifdef SS_WATCHDOG +#define SS_MAX_WD_NODES 256 +#define SS_WD_HB_MSG_VER "1.0" +#define SS_WD_HB_REQ 0x0001 +#define SS_WD_HB_RSP 0x0010 +#define SS_WD_HB_MSG_SIZE 24 +#define SS_WD_WDPORT 8888 +#define SS_WD_WDPROC 99 +#endif /* SS_WATCHDOG */ + +/* Logger support */ +#ifdef SS_LOGGER_SUPPORT +#ifndef SS_MAX_LOGBUF_SIZE +#define SS_MAX_LOGBUF_SIZE 8192 +#endif +#ifndef SS_MAX_PATH +#define SS_MAX_PATH 1024 +#endif +#endif /* SS_LOGGER_SUPPORT */ + + +/* object lock types */ +#if (!defined(SS_STSKTBL_LOCK) \ + || !defined(SS_STSKENTRY_LOCK) \ + || !defined(SS_TMRTBL_LOCK) \ + || !defined(SS_DMNDQ_LOCK) \ + || !defined(SS_DRVRENTRY_LOCK) \ + || !defined(SS_RTRENTRY_LOCK)) +#error "SS_?_LOCK undefined!" +#endif + +/* The define used for mapping the memory region with threadId */ +#ifdef SS_THR_REG_MAP +/* Maximum times SSI retries to create a thread in case if it + * gets same pthread_self() id which already mapped with other + * thread. Once this limit is hit, SSI will exit. In ideal case + * this should not happen + */ +#define SS_MAX_THREAD_CREATE_RETRY 100 + +/* Maximum thread to region mapping. The same is used to + * to get the reminder which is used as index for memory mapping + * array. This is kept as 10 to avoid any issues as we see + * the thread IDs are always even number and we have 4 thread + * at this time + */ +#define SS_MAX_THREAD_REGION_MAP 16 +#ifdef LTE_PAL_ENB +#define SS_MEM_THREAD_ID_SHIFT 24 +#else +#define SS_MEM_THREAD_ID_SHIFT 16 +#endif + +#define SS_INVALID_THREAD_REG_MAP 0xFF + +#define SS_GET_THREAD_MEM_REGION() \ + osCp.threadMemoryRegionMap[((pthread_self() >> SS_MEM_THREAD_ID_SHIFT) % SS_MAX_THREAD_REGION_MAP)] +#else +#define SS_GET_THREAD_MEM_REGION() region +#endif /* SS_THR_REG_MAP */ + + /* ss040.103 changed how ssWaitSema is called */ + /* ss013.13: addition */ +/* locking macros */ +/*ss014.301 SSI-4GMX specific changes*/ +#ifndef SS_4GMX_LCORE +#define SS_ACQUIRE_ALL_SEMA(s, ret) \ + { \ + S16 q; \ + ret = ROK; \ + for (q = 0; q < SS_MAX_STSKS; q++) \ + { \ + while ((ret = ssWaitSema(s) != ROK) && (errno == EINTR)) \ + continue; \ + if ( ret != ROK)\ + {\ + SSLOGERROR(ERRCLS_DEBUG, ESSXXX, ERRZERO,\ + "Could not lock the Semaphore");\ + }\ + if (ret != ROK) \ + { \ + while (q > 0) \ + { \ + ret = ssPostSema(s); \ + if ( ret != ROK)\ + {\ + SSLOGERROR(ERRCLS_DEBUG, ESSXXX, ERRZERO,\ + "Could not unlock the Semaphore");\ + }\ + q--; \ + } \ + break; \ + } \ + } \ + if (q == 0) \ + ret = RFAILED; \ + } + + + /* ss006.13: addition */ +#define SS_RELEASE_ALL_SEMA(s) \ + { \ + S16 q; \ + for (q = 0; q < SS_MAX_STSKS; q++) \ + {\ + if ( (ssPostSema(s)) != ROK)\ + {\ + SSLOGERROR(ERRCLS_DEBUG, ESSXXX, ERRZERO,\ + "Could not unlock the Semaphore");\ + RETVALUE(RFAILED);\ + }\ + }\ + } + +/* ss040.103 changed how ssWaitSema is called */ +#define SS_ACQUIRE_SEMA(s, ret) \ + while ((ret = ssWaitSema(s) != ROK) && (errno == EINTR)) \ + continue;\ +/* ss041.103 removed exta lines */ + + + + /* ss006.13: addition */ +#define SS_RELEASE_SEMA(s) \ + ssPostSema(s) + +/* ss029.103: addition: multiple procIds related changes */ +#ifdef SS_MULTIPLE_PROCS +#define SS_INV_PROCID_IDX 0xFFFF /* invalid index in procId table */ +#define SS_INV_PROCID 0xFFFF /* invalid proc id */ + +#define SS_HASH_IDX(_proc) (_proc % SS_MAX_PROCS) + +#endif /* SS_MULTIPLE_PROCS */ +#else +#define SS_ACQUIRE_ALL_SEMA(s, ret) \ + { \ + ret = ssWaitSema(s); \ + } + + +#define SS_RELEASE_ALL_SEMA(s) \ + { \ + ssPostSema(s);\ + } + +#define SS_ACQUIRE_SEMA(s, ret) \ + ret = ssWaitSema(s) + +#define SS_RELEASE_SEMA(s) \ + ssPostSema(s) +#endif /* SS_4GMX_LCORE */ + +#ifdef __cplusplus +} +#endif + +#endif /* __SSGENH__ */ + + + +/********************************************************************30** + + End of file +**********************************************************************/ diff --git a/src/mt/ss_gen.x b/src/mt/ss_gen.x new file mode 100755 index 000000000..03cffaa20 --- /dev/null +++ b/src/mt/ss_gen.x @@ -0,0 +1,472 @@ +/******************************************************************************* +################################################################################ +# Copyright (c) [2017-2019] [Radisys] # +# # +# 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. # +################################################################################ +*******************************************************************************/ + +/********************************************************************20** + + Name: System Services -- general + + Type: C include file + + Desc: Data structure definitions that are used by all + implementations of system services. + + File: ss_gen.x + +*********************************************************************21*/ + + +#ifndef __SSGENX__ +#define __SSGENX__ + +#ifdef __cplusplus +extern "C" { +#endif + +struct cmMmGlobRegCb; +/* ss029.103: addition: multiple procIds related changes */ +#ifdef SS_MULTIPLE_PROCS +typedef struct { + U16 free; + ProcId procId[SS_MAX_PROCS]; +} ProcIdLst; +#endif /* SS_MULTIPLE_PROCS */ + +/* multi-core enhancements */ +/*ss013.301 : changes for SS_AFFINITY_SUPPORT*/ +#if defined(SS_MULTICORE_SUPPORT) || defined(SS_AFFINITY_SUPPORT) + +typedef struct { + SCpuInfo cpuInfo; /* the info about the cores/threads per core */ + + + /* the currently used core */ + U32 currentCore; + + /*COMMENT: add the thread id for use on hyperthreading machines */ + struct { + U32 thrs; /* available no. of threads per core */ + S8 exclusive; /* exclusive flag */ + SSTskId tskPerCoreLst[SS_MAX_THREADS_PER_CORE]; /* System tasks running on this core */ + } coreInfo[SS_MAX_CORES]; +} SMultiCoreInfo; +#endif /* SS_MULTICORE_SUPPORT || SS_AFFINITY_SUPPORT */ + +/* ss001.301: additions */ +/* ss002.301: Modifications */ +#ifdef SS_THREAD_PROFILE +#ifdef SS_MULTIPLE_PROCS +EXTERN S16 SGetThrdProf(SSTskId *sTskId,ProcId procId,Ent ent,Inst inst,Event *curEvent,U32 *curEvtTime,U64 *totTime); +#else +EXTERN S16 SGetThrdProf(SSTskId *sTskId,Ent ent,Inst inst,Event *curEvent,U32 *curEvtTime,U64 *totTime); +#endif /* SS_MULTIPLE_PROCS */ +#endif /* SS_THERAD_PROFILE */ + +#ifdef SS_WATCHDOG + +typedef void (*WdUserCallback)(void *); + +typedef struct { +#ifdef SS_WATCHDOG_IPV6 + struct in6_addr addr; +#else + struct in_addr addr; /* configured node addr */ +#endif /* SS_WATCHDOG_IPV6 */ + U16 port; /* configured watchdog port */ + U8 status; /* HB ACK status */ +} watchDogStatus; + +typedef struct ssWd { + U32 timeout; /* configured HB timer */ + U8 watchdogStop; /* watchdog stop flag */ + int numNodes; /* configured nodes */ +#ifdef SS_WIN + unsigned int sock; /* HB socket descriptor */ +#else + int sock; +#endif /* SS_WIN */ + + watchDogStatus wdsta[SS_MAX_WD_NODES]; /* node config or status */ + WdUserCallback callback; /* user callback */ + void *data; /* user callback data */ +} SsWd; + +typedef struct ssWdCp{ + SSTskId watchDgTskId; + SSTskId watchDgRcvrTskId; + Pst watchDgPst; + CmTqCp watchDgTqCp; /* timing queue control point : WatchDog */ + CmTqType watchDgTs[2]; /*timing queue */ + CmTimer watchDgTmr[2]; + ProcId watchDgprocId; + SsWd globWd; + SLockId wdLock; +} SsWdCp; +EXTERN S16 SInitWatchdog(U16 port); +EXTERN S16 SRegCfgWd(U32 numNodes, U8 *addr[], U16 port[], U32 timeout, WdUserCallback callback, void *data); +EXTERN S16 SDeregCfgWd(void); +EXTERN S16 SStartHrtBt(U8 timeInterval); +EXTERN S16 SStopHrtBt(void); +#endif /* SS_WATCHDOG */ + +#ifdef SS_LOGGER_SUPPORT +/* Logger Info */ +typedef struct sloggerInfo +{ + Bool started; /* flag to indicate logger status */ + + Bool configured; /* flag to indicate whether logger is configured */ + + Bool opt; /* write to file/socket based on the flags provided*/ + + FILE* filep; + S8 filePath[SS_MAX_PATH]; + + S32 socketdes; + struct sockaddr_in remoteAddr; + + U16 curNumFlush; + U16 maxNumFlush; + + S8 buffer[SS_MAX_LOGBUF_SIZE]; + U32 maxBufSiz; /*The size of this is determined by the + system on which its running.*/ + U32 curBufSiz; + SLockId bufLock; /* lock for global buffer access */ +} SLoggerInfo; +#endif /* SS_LOGGER_SUPPORT */ + +#ifdef INTEL_WLS +typedef struct _MtWls +{ + Void *intf; + Void *allocAddr; +}SsMtWls; +#endif /* INTEL_WLS */ + + +#ifdef NTL_LIB +typedef struct _MtNtl +{ + U32 hdl; +}SsMtNtl; +#endif /* NTL_LIB */ + + + +/* SS control point */ +typedef struct ssos +{ + + SsdOs dep; /* implementation specific */ + +/* ss029.103: modification: + with multiple procId support, SSI shall keep list of registered procIds */ +#ifndef SS_MULTIPLE_PROCS + ProcId procId; /* processor ID */ + + /* TAPA task info */ + SsIdx tTskIds[SS_MAX_ENT][SS_MAX_INST]; +#else + ProcIdLst procLst; /* processor ID list */ + SsIdx tTskIds[SS_MAX_PROCS][SS_MAX_ENT][SS_MAX_INST]; + /* TAPA task info */ +#endif /* SS_MULTIPLE_PROCS */ + /* index table */ + SsTTskEntry tTskTbl[SS_MAX_TTSKS]; /* task table */ + SsCntr numTTsks; /* count of tasks */ + SsIdx nxtTTskEntry; /* next available slot */ + + SsSemaId tTskTblSem; /* lock for table access */ + + + /* system task info */ + SsSTskEntry sTskTbl[SS_MAX_STSKS]; /* task table */ + + /* Thread to region mapping. The array is indexed with reminder + of thread ID after deviding it with SS_MAX_THREAD_REGION_MAP + */ +#ifdef SS_THR_REG_MAP + Region threadMemoryRegionMap[SS_MAX_THREAD_REGION_MAP]; +#endif + SsCntr numSTsks; /* count of tasks */ + SsIdx nxtSTskEntry; /* next available slot */ + + SLockId sTskTblLock; /* lock for table access */ + + + U8 dmndQLookupTbl[256]; /* demand queue lookup table */ + + +#ifdef SS_DRVR_SUPPORT + + /* driver task info */ + SsDrvrTskEntry drvrTskTbl[SS_MAX_DRVRTSKS]; + /* task table */ + SsCntr numDrvrTsks; /* count of tasks */ + +#endif /* SS_DRVR_SUPPORT */ + + +#ifdef SS_RTR_SUPPORT + + /* router task info */ + ActvTsk rtrTskTbl[SS_MAX_RTRTSKS]; + SLockId rtrTskLocks[SS_MAX_RTRTSKS]; + +#endif /* SS_RTR_SUPPORT */ + + + /* timer info */ + SsTmrEntry tmrTbl[SS_MAX_TMRS]; /* timer table */ + SsCntr numTmrs; /* count of timers */ + SsIdx nxtTmrEntry; /* next available slot */ + + SLockId tmrTblLock; /* lock for table access */ + + /* Pointer to global region */ + struct cmMmGlobRegCb *globRegCb; /* Global Region Cb */ + + SsCntr numRegions; /* count of regions */ + SsRegionEntry regionTbl[SS_MAX_REGS]; /* region table */ + SsCntr numDynRegions; /* Number of dynamic regions */ + SsRegionEntry dynRegionTbl[SS_MAX_REGS]; /* Dynamic Region Table */ + + SsSemaId regionTblSem; /* lock for table access */ + + /* ss028.103 - Addition of lock for mBuf reference count */ + /* ss007.301 - moved the lock to RegionTbl */ + /* SLockId mBufRefLock; */ /* lock for mBuf ref access */ + +/*ss013.301 : changes for SS_AFFINITY_SUPPORT*/ +#if defined(SS_MULTICORE_SUPPORT) || defined(SS_AFFINITY_SUPPORT) + /* the Information about the CPU */ + SMultiCoreInfo mCInfo; + + SLockId mCILock; /* Lock for mCInfo access */ + +#endif /* SS_MULTICORE_SUPPORT || SS_AFFINITY_SUPPORT */ + +/* ss001.301: additions */ +#ifdef SS_WATCHDOG + SsWdCp wdCp; +#endif /* SS_WATCHDOG */ + +#ifdef SS_HISTOGRAM_SUPPORT + U8 entId[26][26]; +#endif /* SS_HISTOGRAM_SUPPORT */ + +#ifdef SS_LOGGER_SUPPORT + SLoggerInfo logger; +#endif /* SS_LOGGER_SUPPORT */ + S8 *configFilePath; +#ifdef INTEL_WLS + SsMtWls wls; +#endif + +#ifdef NTL_LIB + SsMtNtl ntl; +#endif + +} SsOs; + + + +/* configuration data structures */ + +/* pool configuration */ +typedef struct ssPoolCfg +{ + SsPoolType type; /* dynamic or static */ + Size size; /* size to use (for dynamic pools) */ + +} SsPoolCfg; + + +/* region content--pools in a region */ +typedef struct ssRegCfg +{ + Region region; /* region ID */ + SsCntr numPools; /* count of pools */ + SsPoolCfg pools[SS_MAX_POOLS_PER_REG]; /* pools configuration */ + +} SsRegCfg; + + + +/* external variable declaration */ +/*ss014.301 EXTERN osCp as VOLATILE for SSI-4GMX*/ +#ifdef SS_4GMX_LCORE +EXTERN VOLATILE SsOs osCp; +#else +EXTERN SsOs osCp; +#endif + + +/* functions */ +EXTERN S16 SInit ARGS((void)); +/*ss009.301*/ +EXTERN S16 SFini ARGS((void)); +/* ss034.103 */ +EXTERN S16 SDeInit ARGS((void)); + +/* implementation-specific functions */ +EXTERN S16 ssdInitGen ARGS((void)); +EXTERN S16 ssdInitMem ARGS((void)); +EXTERN S16 ssdInitTsk ARGS((void)); +EXTERN S16 ssdInitDrvr ARGS((void)); +EXTERN S16 ssdInitTmr ARGS((void)); +EXTERN S16 ssdReInitTmr ARGS((void)); +/* ss005.301: ssdInitFinal changed to ssdInitLog */ +EXTERN S16 ssdInitLog ARGS((void)); + +EXTERN Void ssdDeinitGen ARGS((void)); +EXTERN Void ssdDeinitMem ARGS((void)); +EXTERN Void ssdDeinitTsk ARGS((void)); +EXTERN Void ssdDeinitDrvr ARGS((void)); +EXTERN Void ssdDeinitTmr ARGS((void)); +/* ss005.301: ssdDeinitFinal changed to ssdDeinitLog */ +EXTERN Void ssdDeinitLog ARGS((void)); + +EXTERN Void ssdStart ARGS((void)); + +EXTERN S16 ssdAttachTTsk ARGS((SsTTskEntry *)); +EXTERN S16 ssdDetachTTsk ARGS((SsTTskEntry *)); +EXTERN S16 ssdCreateSTsk ARGS((SsSTskEntry *)); +EXTERN S16 ssdDestroySTsk ARGS((SsSTskEntry *)); +EXTERN S16 ssdPstTsk ARGS((Pst *, Buffer *, SsTTskEntry *)); +EXTERN S16 ssdRegTmr ARGS((SsTmrEntry *)); +EXTERN S16 ssdDeregTmr ARGS((SsTmrEntry *)); +EXTERN S16 ssdError ARGS((Seq, Reason)); +EXTERN Void ssdLogError ARGS((Ent, Inst, ProcId, Txt *, S32, \ + ErrCls, ErrCode, ErrVal, Txt *)); + +EXTERN Void mtTmrHdlrPublic ARGS ((void)); + +/* + * SDeRegTTsk patch + */ +/* for TTask Dereg */ +#ifdef SS_MULTIPLE_PROCS +EXTERN S16 ssdProcTTskTerm ARGS((ProcId proc, SsTTskEntry *tTsk, SsIdx idx)); +#else +EXTERN S16 ssdProcTTskTerm ARGS((SsTTskEntry *tTsk, SsIdx idx)); +#endif /* SS_MULTIPLE_PROCS */ + +#ifdef SS_DRVR_SUPPORT +EXTERN S16 ssdRegDrvrTsk ARGS((SsDrvrTskEntry *)); +/*ss001.301: Additions */ +EXTERN S16 ssdDeregDrvrTsk ARGS((SsDrvrTskEntry *)); +#endif + +/* ss029.103: addition: support function to implement multiple procIds */ +#ifdef SS_MULTIPLE_PROCS +EXTERN U16 SGetProcIdIdx ARGS((ProcId proc)); +#endif /* SS_MULTIPLE_PROCS */ + +/* multi-core support */ +/*ss013.301 : changes for SS_AFFINITY_SUPPORT*/ +#if defined(SS_MULTICORE_SUPPORT) || defined(SS_AFFINITY_SUPPORT) + +EXTERN S16 ssdSetAffinity ARGS((SSTskId *tskId, U32 coreId)); +EXTERN S16 ssdGetAffinity ARGS((SSTskId *tskId, U32 *coreId)); +#endif /* SS_MULTICORE_SUPPORT || SS_AFFINITY_SUPPORT */ + +/* ss001.301: additions */ +#ifdef SS_LOGGER_SUPPORT +EXTERN S16 ssdInitLogger ARGS((void)); +EXTERN S16 SFlushBufToLog ARGS (( S8 *logBuf)); +/* ss02.301: additions */ +EXTERN S16 SCleanUp ARGS ((Void )); +EXTERN Void SStartLogger ARGS ((Void )); +EXTERN Void SStopLogger ARGS ((Void )); +#endif /* SS_LOGGER_SUPPORT */ +/* ss02.301: additions */ +#ifdef SS_WATCHDOG +#ifdef SS_MULTIPLE_PROCS +EXTERN S16 ssdWatchDgActvTmr ARGS(( ProcId proc, Ent ent, Inst instVoid)); +#else +EXTERN S16 ssdWatchDgActvTmr ARGS(( Void )); +#endif /* SS_MULTIPLE_PROCS */ +EXTERN Void ssdWatchDgTmrEvt ARGS(( PTR cb, S16 event )); +EXTERN S16 watchDgActvTsk ARGS(( Pst *pst, Buffer *mBuf)); +EXTERN S16 watchDgRcvrActvTsk ARGS(( Pst *pst, Buffer *mBuf )); +EXTERN S16 ssdSndHrtBtMsg ARGS(( Bool restart, U32 type)); +EXTERN Void ssdStartWatchDgTmr ARGS(( void *cb, S16 event, U16 wait)); +EXTERN Void ssdStopWatchDgTmr ARGS(( void *cb, S16 event)); +EXTERN S16 ssdInitWatchDgPst ARGS((Pst *pst)); +EXTERN S16 ssdInitWatchDog ARGS((U16 port)); +#endif + +#ifdef SS_FBSED_TSK_REG +EXTERN S16 SRegTskInfo ARGS((U8 *cfgFile)); +#endif +/* ss002.301 Readwrite lock additions */ +#ifdef SS_LOCK_SUPPORT +EXTERN S16 ssdLockNew ARGS((SLockInfo *LockId, U8 locktype)); +EXTERN S16 ssdInitLockNew ARGS((SLockInfo *LockId, U8 lockType)); +EXTERN S16 ssdUnlockNew ARGS((SLockInfo *LockId, U8 lockType)); +EXTERN S16 ssdDestroyLockNew ARGS((SLockInfo *LockId, U8 lockType)); +#endif /* SS_LOCK_SUPPORT */ + +#ifdef SSI_STATIC_MEM_LEAK_DETECTION +/* For Static memory leak detection */ +#define MAX_MEM_ALLOCATIONS 100000 + +typedef struct _listInfo +{ + U32 nextIdx; +}ListInfo; + +typedef struct _eachAllocInfo +{ + ListInfo listInfo; + /* other info should come here */ + char *file; + U32 lineNo; + U32 age; + void *ptr; + U32 size; + /* end of other info */ +}EachAllocInfo; + +typedef struct _staticMemAllocationInfo +{ + U32 nextFreeIdx; + EachAllocInfo allocations[MAX_MEM_ALLOCATIONS]; +}StaticMemAllocInfo; + +StaticMemAllocInfo SMemLeakInfo[4]; +FILE* StaticMemLeakFileArr[4]; +/* End Static Memory leak detection */ +#endif + +#ifdef __cplusplus +} +#endif + +EXTERN void DumpSSIDemandQDebugInformation ARGS((void)); +EXTERN void mtSigSegvHndlr ARGS((void)); +EXTERN void mtSigUsr2Hndlr ARGS((void)); +#endif /* __SSGENX__ */ + + + +/********************************************************************30** + + End of file +**********************************************************************/ diff --git a/src/mt/ss_mem.h b/src/mt/ss_mem.h new file mode 100755 index 000000000..74129bd20 --- /dev/null +++ b/src/mt/ss_mem.h @@ -0,0 +1,79 @@ +/******************************************************************************* +################################################################################ +# Copyright (c) [2017-2019] [Radisys] # +# # +# 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. # +################################################################################ +*******************************************************************************/ + +/********************************************************************20** + + Name: System Services -- Memory management interface + + Type: C include file + + Desc: Various macro definitions required for the Memory + management interface. + + File: ss_mem.h + +*********************************************************************21*/ + + +#ifndef __SSMEMH__ +#define __SSMEMH__ + +#ifdef __cplusplus +extern "C" { +#endif + + + +/* region flags */ +#define SS_OUTBOARD_FLAG 16 + +/* ss036.103 - addition of a macro. This implies that we +* can hold the memory statistics of upto SS_MAX_BKT_PER_DBGTBL buckets +*/ +#define SS_MAX_BKT_PER_DBGTBL 16 + +/* ss036.103 - addition of macros for memory statistics related information */ +#ifdef SSI_DEBUG_LEVEL1 +#define SS_DYNAMIC_MEM_FLAG 0x04 /* same as CMM_DYNAMIC_MEM_FLAG */ +#define SS_STATIC_MEM_FLAG 0x08 /* same as CMM_STATIC_MEM_FLAG */ +#define SS_MEM_BLK_SIZE_PROFILE 0 /* to print size vs. numRequests */ +#define SS_MEM_BKT_ALLOC_PROFILE 1 /* to print the static/dynamic mem used */ +#endif /* SSI_DEBUG_LEVEL1 */ + +/* ss001.301: FAP related changes in SSI */ +#ifdef SS_FAP +#define SAlloc(_region, _size,_flags, _ptr) \ + ((osCp.regionTbl[(_region)].alloc)((osCp.regionTbl[(_region)].regCb), (_size), (_flags),(_ptr))) +#define SFree(_region, _ptr, _size) \ + (osCp.regionTbl[(_region)].free)(\ + (osCp.regionTbl[(_region)].regCb), ( _ptr), (_size)) + +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* __SSMEMH__ */ + + + +/********************************************************************30** + + End of file +**********************************************************************/ diff --git a/src/mt/ss_mem.x b/src/mt/ss_mem.x new file mode 100755 index 000000000..9435f5642 --- /dev/null +++ b/src/mt/ss_mem.x @@ -0,0 +1,119 @@ +/******************************************************************************* +################################################################################ +# Copyright (c) [2017-2019] [Radisys] # +# # +# 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. # +################################################################################ +*******************************************************************************/ + +/********************************************************************20** + + Name: System Services -- Memory management interface + + Type: C include file + + Desc: Data structure definitions required for the memory + management interface. + + File: ss_mem.x + +*********************************************************************21*/ + + +#ifndef __SSMEMX__ +#define __SSMEMX__ + +#ifdef __cplusplus +extern "C" { +#endif + + +/* region entry structure */ +typedef struct ssRegionEntry +{ + SsdRegionEntry dep; /* implementation specific */ + + + Bool used; /* entry used? */ + + Data *start; /* start address */ + Size size; /* size */ + + Void *regCb; /* control block */ + + U32 flags; /* flags */ + + SsPoolEntry poolTbl[SS_MAX_POOLS_PER_REG]; /* pool table */ + SsCntr numPools; /* count of pools */ + + SsAlloc alloc; /* allocator function */ + SsFree free; /* de-allocator function */ + SsCtl ctl; /* ctl function */ + /* ss006.301 */ + SLockId mBufRefLock; /* per region lock used for + data block sharing */ +} SsRegionEntry; + +/* ss036.103 - addition of data type to return the memory statistics data +* this is used in SGetRegInfo +*/ +typedef struct ssMemBktDbgInfo +{ + Size size; /* Size of the block */ + U32 numBlks; /* Total number of blocks in the bucket */ + U32 numAlloc; /* Number of blocks allocated */ +}SsMemBktDbgInfo; + +typedef struct ssMemDbgInfo +{ + Region region; /* Region Id of the memory */ + U16 numBkts; /* Number of buckets in bktDbgTbl */ + SsMemBktDbgInfo bktDbgTbl[SS_MAX_BKT_PER_DBGTBL]; + Size heapSize; /* Size of the heap pool */ + Size heapAlloc; /* Total allocated memory */ + U32 availmem; +#if (ERRCLASS & ERRCLS_DEBUG) + U16 numFragBlk; /* Number of fragmented block */ +#endif /* ERRCLASS & ERRCLS_DEBUG */ +}SsMemDbgInfo; + +/* ss036.103 - Addition of prototypes for memory statistics */ +EXTERN S16 SRegInfoShow ARGS((Region region, U32 *availmem)); +EXTERN S16 SGetRegInfo ARGS((Region region, SsMemDbgInfo *dbgInfo)); +#ifdef XEON_SPECIFIC_CHANGES +EXTERN S16 SRegReachedMemThreshold ARGS((Region region, U8 maxBkt)); +#endif +#ifdef SSI_DEBUG_LEVEL1 +EXTERN S16 SPrintRegMemStatusInfo ARGS((Region region, U8 typeFlag)); +EXTERN Void SRegMemErrHdlr ARGS((Region region, Data *ptr, S16 errCode)); +EXTERN S16 SPrintRegMemProfile ARGS((Region region)); +#endif /* SSI_DEBUG_LEVEL1 */ + +/* ss001.301: additions */ +#ifdef SS_HISTOGRAM_SUPPORT +EXTERN S16 SGetTapaTskEntIds ARGS((Ent *ent)); +EXTERN S16 SGetHstGrmInfo ARGS((Ent *entId, Bool *hstReg)); +#endif /* SS_HISTOGRAM_SUPPORT */ + +#ifdef __cplusplus +} +#endif + +#endif /* __SSMEMX__ */ + + + +/********************************************************************30** + + End of file +**********************************************************************/ diff --git a/src/mt/ss_msg.h b/src/mt/ss_msg.h new file mode 100755 index 000000000..c0a97df85 --- /dev/null +++ b/src/mt/ss_msg.h @@ -0,0 +1,105 @@ +/******************************************************************************* +################################################################################ +# Copyright (c) [2017-2019] [Radisys] # +# # +# 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. # +################################################################################ +*******************************************************************************/ + +/********************************************************************20** + + Name: System Services -- Message manipulation functions + + Type: C source file + + Desc: Macro definitions for message related functions. + + File: ss_msg.h + +*********************************************************************21*/ + +#ifndef __SSMSGH__ +#define __SSMSGH__ + +#ifdef __cplusplus +extern "C" { +#endif + + +/* default SS region ID */ +#define SS_DFLT_REGION 0 +#define SS_DFLT_POOL 0 + +#ifdef SS_MULTICORE_SUPPORT +#define SS_REGION_0 0 +#define SS_REGION_1 1 +#define SS_REGION_2 2 +#define SS_REGION_3 3 +#define SS_REGION_4 4 +#define SS_REGION_5 5 +#endif /* SS_MULTICORE_SUPPORT */ + +/* pool types */ +#define SS_POOL_UND 0 +#define SS_POOL_DYNAMIC 1 +#define SS_POOL_STATIC 2 + +/* Bucket threshold default values */ +#define SS_BLK_RELEASE_THRESHOLD 110 +#define SS_BLK_ACQUIRE_THRESHOLD 20 +#define SS_DFLT_MEM_BLK_SET_SIZE 128 +#define SS_MEM_TYPE_SSI_ZBC 0x11 +#ifdef XEON_SPECIFIC_CHANGES +#define SS_MEM_TYPE_DPDK_ZBC 0x12 +#endif + +/* utility macros */ +#define FIND_OFFSET(current, idx) \ + { \ + MsgLen bufSiz; \ + while (idx) \ + { \ + bufSiz = (current->b_wptr - current->b_rptr); \ + if (bufSiz > idx) \ + break; \ + idx -= bufSiz; \ + current = current->b_cont; \ + } \ + } + +#define FIND_OFFSET_AND_PREV(previous, current, idx) \ + { \ + MsgLen bufSiz; \ + while (idx) \ + { \ + bufSiz = (current->b_wptr - current->b_rptr); \ + if (bufSiz > idx) \ + break; \ + idx -= bufSiz; \ + previous = current; \ + current = current->b_cont; \ + } \ + } + +#ifdef __cplusplus +} +#endif + +#endif /* __SSMSGH__ */ + + + +/********************************************************************30** + + End of file +**********************************************************************/ diff --git a/src/mt/ss_msg.x b/src/mt/ss_msg.x new file mode 100755 index 000000000..69862a031 --- /dev/null +++ b/src/mt/ss_msg.x @@ -0,0 +1,116 @@ +/******************************************************************************* +################################################################################ +# Copyright (c) [2017-2019] [Radisys] # +# # +# 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. # +################################################################################ +*******************************************************************************/ + +/********************************************************************20** + + Name: System Services -- Message manipulation functions + + Type: C include file + + Desc: Data structure definitions for message related functions. + + File: ss_msg.x + +*********************************************************************21*/ + +#ifndef __SSMSGX__ +#define __SSMSGX__ + +#ifdef __cplusplus +extern "C" { +#endif + + +/* pool type -- dynamic or static */ +typedef U8 SsPoolType; + + + +/* dynamic pool */ +typedef struct ssDPoolEntry +{ + SsdDPoolEntry dep; /* implementation specific */ + Size size; /* to use for SAlloc() */ +} SsDPoolEntry; + + +/* static pool */ +typedef struct ssSPoolEntry +{ + SsdSPoolEntry dep; /* implementation specific */ +} SsSPoolEntry; + + +/* generic pool (includes dynamic and static) */ +typedef struct ssPoolEntry +{ + SsdPoolEntry dep; /* implementation specific */ + SsPoolType type; /* dynamic or static */ + union + { + SsSPoolEntry spool; /* static pool */ + SsDPoolEntry dpool; /* dynamic pool */ + } u; +} SsPoolEntry; + + +/* event information--what kind of message is this */ +typedef struct ssEventInfo +{ + U8 event; /* event type */ + union + { + struct + { + SsIdx tmrIdx; /* timer index */ + Bool inUse; /* message in use? */ + Bool dynBuf; /* dynamic buffer? */ + } tmr; /* for timer events */ + } u; +} SsEventInfo; + + +/* Information stored in the control portion of a message. + * The SGETBUFREGION, SGETBUFPOOL, SGetBufRegionPool macros + * depend on the order of the first two elements of this + * structure. Make sure the macros are consistent with the + * definition here. + */ +typedef struct ssMsgInfo +{ + Region region; /* region id of the msg chain */ + Pool pool; /* pool id of the msg chain */ + MsgLen len; /* num of bytes in the msg */ + Buffer *endptr; /* ptr to last mblk in chain */ + Buffer *next; /* for SInitNxtDBuf() */ + Pst pst; /* post for this message */ + SsEventInfo eventInfo; /* event information */ +} SsMsgInfo; + +#ifdef __cplusplus +} +#endif + +#endif /* __SSMSGX__ */ + + + +/********************************************************************30** + + End of file +**********************************************************************/ diff --git a/src/mt/ss_queue.h b/src/mt/ss_queue.h new file mode 100755 index 000000000..d4e51fce7 --- /dev/null +++ b/src/mt/ss_queue.h @@ -0,0 +1,82 @@ +/******************************************************************************* +################################################################################ +# Copyright (c) [2017-2019] [Radisys] # +# # +# 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. # +################################################################################ +*******************************************************************************/ + +/********************************************************************20** + + Name: System Services -- Queueing + + Type: C Include file + + Desc: System Services queuing functions. + + File: ss_queue.h + +*********************************************************************21*/ + + +#ifndef __SSQUEUEH__ +#define __SSQUEUEH__ + +#ifdef __cplusplus +extern "C" { +#endif + + +#define SS_MAX_TASK_PRI 4 /* maximum task priorities */ +#define SS_MAX_MSG_PRI 4 /* maximum msg priorities */ + + +#define SS_DQ_FIRST 0 /* queue at beginning */ +#define SS_DQ_LAST 1 /* queue at end */ + + +#define SS_MAX_NUM_DQ (SS_MAX_TASK_PRI * SS_MAX_MSG_PRI) + /* number of queues */ +#ifndef TENB_RTLIN_CHANGES +#define SS_DQ_BIT_MASK_LEN ((SS_MAX_NUM_DQ - 1) /8 + 1) +#endif + +#define SS_MAX_DQ_PRIOR (SS_MAX_TASK_PRI * SS_MAX_MSG_PRI) + + +/* macros for first and last calls */ +#define ssDmndQPutFirst(dQueue, mBuf, priority) \ + ssDmndQPut(dQueue, mBuf, (Prior)priority, SS_DQ_FIRST) + +#define ssDmndQPutLast(dQueue, mBuf, priority) \ + ssDmndQPut(dQueue, mBuf, (Prior)priority, SS_DQ_LAST) + +#define ssDmndQGetFirst(dQueue, mBuf) \ + ssDmndQGet(dQueue, mBuf, SS_DQ_FIRST) + +#define ssDmndQGetLast(dQueue, mBuf) \ + ssDmndQGet(dQueue, mBuf, SS_DQ_LAST) + + +#ifdef __cplusplus +} +#endif + +#endif /* __SSQUEUEH__ */ + + + +/********************************************************************30** + + End of file +**********************************************************************/ diff --git a/src/mt/ss_queue.x b/src/mt/ss_queue.x new file mode 100755 index 000000000..fba9b0daa --- /dev/null +++ b/src/mt/ss_queue.x @@ -0,0 +1,76 @@ +/******************************************************************************* +################################################################################ +# Copyright (c) [2017-2019] [Radisys] # +# # +# 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. # +################################################################################ +*******************************************************************************/ + +/********************************************************************20** + + Name: System Services -- Queueing + + Type: C include file + + Desc: System Services queuing functions. + + File: ss_queue.x + +*********************************************************************21*/ + + +#ifndef __SSQUEUEX__ +#define __SSQUEUEX__ + +#ifdef __cplusplus +extern "C" { +#endif + + +/* demand queue structure */ +typedef struct ssDmndQ +{ + SsSemaId dmndQSema; /* lock for queue access */ + SLockId dmndQLock[SS_MAX_NUM_DQ]; /* lock for each byte in + * bitmask */ + Queue queue[SS_MAX_NUM_DQ]; /* the queues */ +#ifndef TENB_RTLIN_CHANGES + U8 bitMask[SS_DQ_BIT_MASK_LEN]; /* bit mask */ +#endif +} SsDmndQ; + + + +/* functions */ +EXTERN S16 ssInitDmndQ ARGS((SsDmndQ *queue)); +EXTERN S16 ssDestroyDmndQ ARGS((SsDmndQ *queue)); +EXTERN S16 ssDmndQPut ARGS((SsDmndQ *queue, Buffer *mBuf, \ + Prior prior, Order order)); +EXTERN S16 ssDmndQGet ARGS((SsDmndQ *queue, Buffer **mBuf, \ + Order order)); +EXTERN S16 ssDmndQWait ARGS((SsDmndQ *queue)); + +EXTERN S16 ssFndLenDmndQ ARGS((SsDmndQ *queue, Prior prior, QLen *len)); + + +#ifdef __cplusplus +} +#endif + +#endif /* __SSQUEUEX__ */ + + +/********************************************************************30** + + End of file +**********************************************************************/ diff --git a/src/mt/ss_rbuf.h b/src/mt/ss_rbuf.h new file mode 100755 index 000000000..2937d1ff5 --- /dev/null +++ b/src/mt/ss_rbuf.h @@ -0,0 +1,140 @@ +/******************************************************************************* +################################################################################ +# Copyright (c) [2017-2019] [Radisys] # +# # +# 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. # +################################################################################ +*******************************************************************************/ + +/********************************************************************20** + + Name: Ring Buffer + + Type: C include file + + Desc: This file implements the funcitons required to isolate + freeing of packer buffers from Main stack processing. This will be + usefull in a hyper threaded environment where the freeing can be + done from low priority thread + + File: ss_rbuf.h + +*********************************************************************21*/ +#ifndef __SS_RBUF_H__ +#define __SS_RBUF_H__ + +#ifdef __cplusplus +extern "C" { +#endif + + +#define SS_RNG_TX 1 +#define SS_RNG_RX 0 +#ifdef XEON_SPECIFIC_CHANGES +#define SS_RNG_MAX_DLPDCP_TO_DLRLC_DQ_CNT 80 /* Max Buffer Read from Ring Buffer from PDCP to RLC in DL Direction */ +#define SS_RNG_MAX_ULMAC_TO_ULRLC_DQ_CNT 200 +#define SS_RNG_ULRLC_TO_ULPDCP_SIZE 256 +#define SS_RNG_ULPDCP_TO_ULDAM_SIZE 2048 +#define SS_RNG_MAX_ULPDCP_TO_ULDAM_DAT_IND_DQ_CNT 512 +#define SS_RNG_MAX_ULRLC_TO_ULPDCP_DAT_IND_DQ_CNT 10 +#else +#define SS_RNG_MAX_DLPDCP_TO_DLRLC_DQ_CNT 40 /* Max Buffer Read from Ring Buffer from PDCP to RLC in DL Direction */ +#define SS_RNG_MAX_ULMAC_TO_ULRLC_DQ_CNT 25 +#endif + +/* ccpu00143253: Changing SS_RNG_DLPDCP_TO_DLRLC_SIZE from 128 to 512, + * as the forwarded data packet drop observed during Handover */ +#ifdef L2_L3_SPLIT +#define SS_RNG_DLPDCP_TO_DLRLC_SIZE 5120 +#else +#define SS_RNG_DLPDCP_TO_DLRLC_SIZE 5120 +#endif + +/* Ring Size Defines, powers of 2 only */ +//#define SS_RNG_ICPU_TO_DLPDCP_SIZE 128 +#define SS_RNG_ICPU_TO_DLPDCP_SIZE 512 +#define SS_RNG_ICPU_TO_DLPDCP_NONPRIO_SIZE 20480 +//#define SS_RNG_DLPDCP_TO_DLRLC_SIZE 1024 +//#define SS_RNG_L2_RT_TO_FREE_MGR_SIZE 512 +//#define SS_RNG_L2_NRT_TO_FREE_MGR_SIZE 640 +/* Increasing from 512 to 1024 + Increasing from 1024 to 2048 to handle free after re-est */ +#define SS_RNG_L2_RT_TO_FREE_MGR_SIZE 2048 +#define SS_RNG_L2_NRT_TO_FREE_MGR_SIZE 2048 +#define SS_RNG_L2_DLRLC_TO_FREE_MGR_SIZE 2048 +#define SS_RNG_PRC_L1D_TO_CL_SIZE 32 +#define SS_RNG_PRC_FREE_TO_CL_SIZE 256 +#define SS_RNG_ICPU_TO_DAM_SIZE 1024 +#define SS_RNG_PDCP_TO_CIPH_SIZE 2048 +#define SS_RNG_CIPH_TO_PDCP_SIZE 1024 +#ifdef XEON_SPECIFIC_CHANGES +#define SS_RNG_ULMAC_TO_ULRLC_SIZE 1024 +#else +#define SS_RNG_ULMAC_TO_ULRLC_SIZE 128 +#endif +#define SS_RNG_ICCRX_TO_DLRLC_SIZE 640 +#define SS_RNG_DL_SMSG_REUSE_SIZE 384 +#define SS_RNG_DLRLC_TO_DLMAC_SIZE 512 +#define SS_RNG_BUF_MAC_HARQ_SIZE 256 +#ifndef L2_L3_SPLIT +#ifdef XEON_SPECIFIC_CHANGES +#define SS_FREE_MGR_MAX_FREE 1024 +#else +#define SS_FREE_MGR_MAX_FREE 32 +#endif +#else +#define SS_FREE_MGR_MAX_FREE 96 +#endif + +#ifdef MAC_FREE_RING_BUF +#define SS_RNG_MAC_FREE_RING_SIZE 8096 +#endif +#ifdef RLC_FREE_RING_BUF +#define SS_RNG_RLC_FREE_RING_SIZE 8096 +#endif +#ifdef LC_EGTP_THREAD +#define SS_RNG_EGTP_FREE_RING_SIZE 1024 +#endif +/* Ring Element Size Defines */ +#define SS_RNG_BUF_ELEM sizeof(SsRngBufElem) + +/*Defines for Packet Prio */ +#define SS_QCI_BASED_PRIO_UNUSED 0 +#define SS_QCI_BASED_PRIO_HIGH 1 +#define SS_QCI_BASED_PRIO_LOW 2 +#define SS_QCI_BASED_PRIO_OTHER 3 + +#ifdef XEON_SPECIFIC_CHANGES +#define SS_RNG_MAC_TO_RLC_HARQ_IND_SIZE 512 +#define SS_RNG_DLRLC_TO_DLMAC_STA_RSP_SIZE 2048 +#define SS_RNG_DLRLC_TO_DLMAC_DAT_REQ_SIZE 256 +#define SS_RNG_MAX_DLRLC_TO_DLMAC_STA_RSP_DQ_CNT 320 +#define SS_RNG_MAX_DLRLC_TO_DLMAC_DAT_REQ_DQ_CNT 40 +#define SS_RNG_MAX_DLMAC_TO_DLRLC_HARQ_STA_DQ_CNT 80 +#else +#define SS_RNG_MAC_TO_RLC_HARQ_IND_SIZE 64 +#define SS_RNG_DLRLC_TO_DLMAC_STA_RSP_SIZE 512 +#define SS_RNG_DLRLC_TO_DLMAC_DAT_REQ_SIZE 64 +#define SS_RNG_MAX_DLRLC_TO_DLMAC_STA_RSP_DQ_CNT 80 +#define SS_RNG_MAX_DLRLC_TO_DLMAC_DAT_REQ_DQ_CNT 10 +#define SS_RNG_MAX_DLMAC_TO_DLRLC_HARQ_STA_DQ_CNT 20 +#endif +#ifdef __cplusplus +} +#endif + +#endif +/************************************************************************** + End of file +**************************************************************************/ + diff --git a/src/mt/ss_rbuf.x b/src/mt/ss_rbuf.x new file mode 100755 index 000000000..cb48bb6d6 --- /dev/null +++ b/src/mt/ss_rbuf.x @@ -0,0 +1,224 @@ +/******************************************************************************* +################################################################################ +# Copyright (c) [2017-2019] [Radisys] # +# # +# 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. # +################################################################################ +*******************************************************************************/ + +/********************************************************************20** + + Name: Packet Buffers Free Manager + + Type: C include file + + Desc: This file implements the funcitons required to isolate + freeing of packer buffers from Main stack processing. This will be + usefull in a hyper threaded environment where the freeing can be + done from low priority thread + + File: ss_rbuf.x + + Sid: ss_rbuf.x@@/main/TeNB_Main_BR/3 - Mon Aug 11 16:44:15 2014 + + Prg: + +*********************************************************************21*/ +#ifndef __SS_RBUF_X__ +#define __SS_RBUF_X__ + +#ifdef __cplusplus +extern "C" { +#endif +extern Void SsRngBufEnable ARGS((Void)); +extern Void SsRngBufDisable ARGS((Void)); +extern S16 SCreateSRngBuf ARGS((U32 id, Region region, Pool pool, U32 elmSize, U32 rngSize)); +extern S16 SDestroySRngBuf ARGS((U32 id, Region region, Pool pool)); +extern S16 SAttachSRngBuf ARGS((U32 id, U32 ent, U32 txRx)); +extern S16 SEnqSRngBuf ARGS((U32 id, Void* elem)); +extern S16 SDeqSRngBuf ARGS((U32 id, Void* elem)); +extern Void* SRngGetWIndx ARGS((U32 rngId)); +extern Void* SRngGetRIndx ARGS((U32 rngId)); +extern Void SRngIncrRIndx ARGS((U32 rngId)); +extern Void SRngIncrWIndx ARGS((U32 rngId)); +extern S16 isRngEmpty ARGS((U32 rngId)); +extern S16 SConnectSRngBuf ARGS((U32 id, U32 rxEnt)); +EXTERN S16 SGetNumElemInRng ARGS(( U32 id)); +extern S16 SPrintSRngStats ARGS((Void)); +extern S16 pjBatchProc ARGS((Void)); +extern U32 ssRngBufStatus; + +#define SS_RNG_BUF_STATUS() ssRngBufStatus +/* Ring Buffer Structure */ +typedef struct +{ + U32 size; /* Number of elements in a ring */ + U32 read; /* Read Index incremented by Deque operation */ + U32 write; /* Write index incremented by Enque operation */ + U32 type; /* sizeof user specified ring element structure */ + Void* elem; /* pointer to the allocated ring Elements */ +}SsRngBuf; + +/* Ring Cfg Table */ +typedef struct +{ + U32 rngSize; + U32 elemSize; +} SsRngCfg; + +/* Global Ring Buffer Info structure */ +typedef struct +{ + SsRngBuf* r_addr; // Address of allocated ring + U32 txEnt; // Tx Entity id + U32 rxEnt; // Rx Entity id + U32 n_write; // Number of Enque operations + U32 n_read; // Number of Deque operations + U32 nReadFail; // Number of Deque failures due to ring empty + U32 nWriteFail; // Number of Enque failures due to ring full + U32 rngState; /* Ring Buffer State */ + U32 pktDrop; // Number of pkts dropped due to buffer full + U32 nPktProc; // Debug counter for pkts processed per tti + U32 pktRate; // Debug counter for icpu pkt rate +} SsRngBufTbl; + +/* Global Structure for updating Ring buffer for Flow Control */ +typedef struct +{ + U16 dlRngBuffCnt; /* Dl Ring Buffer Count */ + U16 ulRngBuffCnt; /* Ul Ring Buffer Count */ +}SsRngBufCnt; + +/* Ring Buffer Id Enum */ +typedef enum +{ + SS_RNG_BUF_DEBUG_COUNTER, + SS_RNG_BUF_ICPU_TO_DLPDCP, + SS_RNG_BUF_DLPDCP_TO_DLRLC, + SS_RNG_BUF_L2_RT_TO_FREE_MGR, + SS_RNG_BUF_L2_NRT_TO_FREE_MGR, + SS_RNG_BUF_PRC_L1D_TO_CL, + SS_RNG_BUF_PRC_FREE_TO_CL, + SS_RNG_BUF_ICPU_TO_DAM, + SS_RNG_BUF_L2_NRT_DLRLC_TO_FREE_MGR, + SS_RNG_BUF_ICPU_BATCH_START, +#ifdef SS_RBUF + SS_RNG_BUF_ICPU_BATCH_END = SS_RNG_BUF_ICPU_BATCH_START + BC_BATCH_MGR_MAX_BKT, +#endif +#ifdef CIPH_BATCH_PROC + SS_RNG_BUF_DLPDCP_TO_CIPH, + SS_RNG_BUF_CIPH_TO_DLPDCP, + SS_RNG_BUF_ULPDCP_TO_CIPH, + SS_RNG_BUF_CIPH_TO_ULPDCP, +#endif + SS_RNG_BUF_ULMAC_TO_ULRLC, + SS_RNG_BUF_RX_TO_DLRLC, + SS_RNG_BUF_RX_TO_ULPDCP, + SS_RNG_BUF_DL_SMSG_REUSE, + SS_RNG_BUF_DLRLC_TO_DLMAC, + SS_RNG_BUF_MAC_HARQ, +#if defined(SPLIT_RLC_DL_TASK) && defined(RLC_MAC_DAT_REQ_RBUF) + SS_RNG_BUF_DLRLC_TO_DLMAC_DAT_REQ, + SS_RNG_BUF_DLRLC_TO_DLMAC_STA_RSP, + SS_RNG_BUF_MAC_TO_RLC_HARQ_STA, +#endif +#ifdef MAC_FREE_RING_BUF + SS_RNG_BUF_MAC_FREE_RING, +#endif +#ifdef RLC_FREE_RING_BUF + SS_RNG_BUF_RLC_FREE_RING, +#endif +#ifdef LC_EGTP_THREAD + SS_RNG_BUF_EGTP_FREE_RING, +#endif + + SS_RNG_BUF_MAX +} SsRngBufId; + +/* Ring Buffer User Entity Enum */ +typedef enum +{ + SS_RBUF_ENT_ICPU, + SS_RBUF_ENT_DLPDCP, + SS_RBUF_ENT_DLRLC, + SS_RBUF_ENT_L2_RT, + SS_RBUF_ENT_L2_NRT, + SS_RBUF_ENT_FREE_MGR, + SS_RBUF_ENT_CL, + SS_RBUF_ENT_PRC_L1D, + SS_RBUF_ENT_PRC_FREE, + SS_RBUF_ENT_DAM +#ifdef CIPH_BATCH_PROC + , + SS_RBUF_ENT_DLCIPH, + SS_RBUF_ENT_ULCIPH +#endif + ,SS_RBUF_ENT_ULPDCP, + SS_RBUF_ENT_ULMAC, + SS_RBUF_ENT_ICCRX_DL, + SS_RBUF_ENT_ULRLC, + SS_RBUF_ENT_DLRLC_DAT_REQ, + SS_RBUF_ENT_DLMAC_DAT_REQ, + SS_RBUF_ENT_DLRLC_STA_RSP, + SS_RBUF_ENT_DLMAC_STA_RSP, + SS_RBUF_ENT_MAC_HARQ_STA, +#ifdef MAC_FREE_RING_BUF + SS_RBUF_ENT_MAC_FREE_REQ, + SS_RBUF_ENT_MAC_BUF_FREE, +#endif +#ifdef RLC_FREE_RING_BUF + SS_RBUF_ENT_RLC_FREE_REQ, + SS_RBUF_ENT_RLC_BUF_FREE, +#endif +#ifdef LC_EGTP_THREAD + SS_RBUF_ENT_EGTP_FREE_REQ, + SS_RBUF_ENT_EGTP_BUF_FREE, +#endif + SS_RBUF_ENT_RLC_HARQ_STA +}SsRngUserEnt; +/* Ring Buffer State Enum */ + +typedef enum +{ + SS_RNG_DESTROYED, + SS_RNG_CREATED, + SS_RNG_TX_ATTACHED, + SS_RNG_RX_ATTACHED, + SS_RNG_READY, + SS_RNG_EMPTY, + SS_RNG_FULL +}SsRngBufState; + +/* User defined Ring Element structures */ +typedef struct +{ + Buffer* mBuf; +} SsRngBufElem; + +EXTERN SsRngBufTbl SsRngInfoTbl[SS_RNG_BUF_MAX]; + +#if (defined (MAC_FREE_RING_BUF) || defined (RLC_FREE_RING_BUF)) +extern S16 mtAddBufToRing(SsRngBufId ringId,void *bufPtr,U8 freeType); +#ifdef XEON_SPECIFIC_CHANGES +typedef struct rgKwBufFreeInfo +{ + Void *bufToFree; + U8 freeType; /* 0- SPutMsg, 1->SPutStaticBuffer*/ +}RgKwFreeInfo; +#endif +#endif +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/mt/ss_task.h b/src/mt/ss_task.h new file mode 100755 index 000000000..0cb1982a1 --- /dev/null +++ b/src/mt/ss_task.h @@ -0,0 +1,80 @@ +/******************************************************************************* +################################################################################ +# Copyright (c) [2017-2019] [Radisys] # +# # +# 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. # +################################################################################ +*******************************************************************************/ + +/********************************************************************20** + + Name: System Services -- Task Management + + Type: C include file + + Desc: Various macro definitions required for the task mgmt. + + File: ss_task.h + +*********************************************************************21*/ + + +#ifndef __SSTASKH__ +#define __SSTASKH__ + +#ifdef __cplusplus +extern "C" { +#endif + + +/* task types */ +#define SS_TSK_UND 0 /* undefined */ +#define SS_TSK_NORMAL 1 /* normal task */ +#define SS_TSK_PERMANENT 2 /* permanent task */ + +/* ss001.301: additions */ +#ifdef SS_LOGGER_SUPPORT +#define SS_LOG_TO_FILE 0 /* write log to file */ +#define SS_LOG_TO_SOCKET 1 /* write log to socket */ +#define SS_LOG_ALL 2 /* write log to file and socket*/ +#endif /* SS_LOGGER_SUPPORT */ + +#ifdef SS_WATCHDOG +#define ENTDW 0xcd +#define ENTHB 0xce +#define INST0 0x00 +#define SS_TMR_HRTBT 0x00 +#define EVTSSHRTBTREQ 0x00 +#define EVTSSHRTBTRSP 0x01 +#define SS_LOOSE_COUPLING 0x00 +#endif /* SS_WATCHDOG */ + +/* task priorities (these are system task priorities--0 to 31) */ +#define SS_NORM_TSK_PRI 13 /* for normal tasks */ +#define SS_PERM_TSK_PRI 21 /* for permanent tasks */ + + +#define SS_LOWEST_STSK_PRIOR 31 /* lowest sys task priority */ + + +#ifdef __cplusplus +} +#endif + +#endif /* __SSTASKH__ */ + + +/********************************************************************30** + + End of file +**********************************************************************/ diff --git a/src/mt/ss_task.x b/src/mt/ss_task.x new file mode 100755 index 000000000..cc15bfd42 --- /dev/null +++ b/src/mt/ss_task.x @@ -0,0 +1,143 @@ +/******************************************************************************* +################################################################################ +# Copyright (c) [2017-2019] [Radisys] # +# # +# 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. # +################################################################################ +*******************************************************************************/ + +/********************************************************************20** + + Name: System Services -- Task Management + + Type: C include file + + Desc: Data structure definitions required for the task mgmt. + + File: ss_task.x + +*********************************************************************21*/ + + +#ifndef __SSTASKX__ +#define __SSTASKX__ + +#ifdef __cplusplus +extern "C" { +#endif + + +/* miscellaneous types */ +/* ss029.103: modification: + data type changed to allow more number of TAPA tasks */ +#ifndef SS_MULTIPLE_PROCS +typedef U8 SsCntr; +typedef U8 SsIdx; +#else /* SS_MULTIPLE_PROCS */ +typedef U16 SsCntr; +typedef U16 SsIdx; +#endif /* SS_MULTIPLE_PROCS */ + + +/* forward declaration */ +typedef struct ssSTskEntry SsSTskEntry; + + +/* individual entry in the table of TAPA tasks */ +typedef struct ssTTskEntry +{ + SsdTTskEntry dep; /* implementation specific */ + + + Bool used; /* entry is used? */ +/* ss029.103: addition: procId added */ +#ifdef SS_MULTIPLE_PROCS + ProcId proc; /* task processor ID */ +#endif /* SS_MULTIPLE_PROCS */ + Ent ent; /* task entity ID */ + Inst inst; /* task instance ID */ + Ttype tskType; /* normal/permanent/driver */ + Prior tskPrior; /* priority of task */ + PAIFS16 initTsk; /* initialization function */ + ActvTsk actvTsk; /* activation function */ + + SsSTskEntry *sTsk; /* system task */ + + + SsIdx nxt; /* table implementation */ +/* ss029.103: addition: TAPA task control block (user level) added */ +#ifdef SS_MULTIPLE_PROCS + Void *xxCb; /* protocol control block */ +#endif /* SS_MULTIPLE_PROCS */ + +/* ss001.301: additions */ +#ifdef SS_HISTOGRAM_SUPPORT + Bool hstReg; +#endif /* SS_HISTOGRAM_SUPPORT */ + +/* ss001.301: additions */ +/* ss002.301: Modifications */ +#ifdef SS_THREAD_PROFILE + Bool updated; + Event curEvent; + U32 curEvtTime; + U64 totTime; +#endif /* SS_THREAD_PROFILE */ + /* ss02.301 */ + ActvTsk cbTsk; /* call back function pointer */ + +} SsTTskEntry; + + + +/* individual entry in the table of system tasks */ +struct ssSTskEntry +{ + SsdSTskEntry dep; /* implementation specific */ + + + Bool used; /* entry is used or not */ + Bool termPend; /* termination pending */ + SSTskId tskId; /* system task ID */ + SSTskPrior tskPrior; /* system task priority */ + SsDmndQ dQ; /* demand queue */ + + + /* TAPA task information: the TAPA tasks being handled by + * this system task. + */ + SsIdx tTsks[SS_MAX_TTSKS]; /* indices into TAPA task table */ + SsCntr numTTsks; /* count of TAPA tasks */ + SLockId lock; /* lock for table access */ + + + SsIdx nxt; /* table implementation */ +#ifdef SS_MULTICORE_SUPPORT + Region region; +#endif + +}; + + +#ifdef __cplusplus +} +#endif + +#endif /* __SSTASKX__ */ + + + +/********************************************************************30** + + End of file +**********************************************************************/ diff --git a/src/mt/ss_timer.x b/src/mt/ss_timer.x new file mode 100755 index 000000000..2e7e125ac --- /dev/null +++ b/src/mt/ss_timer.x @@ -0,0 +1,102 @@ +/******************************************************************************* +################################################################################ +# Copyright (c) [2017-2019] [Radisys] # +# # +# 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. # +################################################################################ +*******************************************************************************/ + +/********************************************************************20** + + Name: System Services -- Timing + + Type: C include file + + Desc: Data structure definitions required for timing. + + File: ss_timer.x + +*********************************************************************21*/ + + +#ifndef __SSTIMERX__ +#define __SSTIMERX__ + +#ifdef __cplusplus +extern "C" { +#endif + + + +/* timer ID and type */ +typedef SsIdx SsTmrId; +/* ss015.301 Enclosed all timer activation functions in a union. */ +typedef union { +#ifdef SS_MULTIPLE_PROCS + PAIFTMRS16 tmrActvFn; +#else + PAIFTMRS16 tmrActvFnMt; + PFS16 tmrActvFn; +#endif +}pTmrActvFn; + + +typedef struct ssTmrActvFn +{ + Bool mtFlag; /* TRUE if tmrActvFnMt to be used */ + pTmrActvFn actvFnc; +}SsTmrActvFn; + + + +/* individual entry in the timer table */ +typedef struct ssTmrEntry +{ + SsdTmrEntry dep; /* implementation specific */ + + + Bool used; /* entry is used? */ + SsTmrId tmrId; /* timer ID */ +/* ss029.103: addition: procId added */ +#ifdef SS_MULTIPLE_PROCS + ProcId ownerProc; /* owner task processor ID */ +#endif /* SS_MULTIPLE_PROCS */ + Ent ownerEnt; /* owner task entity ID */ + Inst ownerInst; /* owner task instance ID */ + /* ss028.103 - Modification for SRegCfgTmr support */ + U32 interval; /* timer interval */ + /* ss029.103: modification: timer function type modified */ + /* ss015.301 Enclosed all timer activation functions in a union. */ + SsTmrActvFn ssTmrActvFn; + + Buffer *mBuf; /* timer message buffer */ + + + SsIdx nxt; /* table implementation */ + +} SsTmrEntry; + + + +#ifdef __cplusplus +} +#endif + +#endif /* __SSTIMERX__ */ + + + +/********************************************************************30** + + End of file +**********************************************************************/ diff --git a/src/rlog/rl_common.h b/src/rlog/rl_common.h new file mode 100755 index 000000000..a3813f7de --- /dev/null +++ b/src/rlog/rl_common.h @@ -0,0 +1,108 @@ +/******************************************************************************* +################################################################################ +# Copyright (c) [2017-2019] [Radisys] # +# # +# 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. # +################################################################################ +*******************************************************************************/ + +/********************************************************************20** + + Name: Radisys Logging Framework + Type: C include file + Desc: This file contains logging framework include file for library. + File: rl_common.h + +*********************************************************************21*/ +/************************************************************************* +@ description: This is header file is used by logging framework module. This +file should not be cirectly included by any other application although it is +common file to logging framework and LOG MACROs used by any applicatoin. +***************************************************************************/ + +#ifndef __RL_COMMON_H__ +#define __RL_COMMON_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + L_ALWAYS=0, + L_FATAL, + L_ERROR, + L_WARNING, + L_EVENT, + L_INFO, + L_DEBUG, + L_UNUSED, + L_MAX_LOG_LEVEL +} R_LOG_LEVEL; + +typedef enum { + DBG_CELLID, + DBG_PEERID, + DBG_ENBID, + DBG_MMEID, + DBG_CRNTI, + DBG_UEIDX, + DBG_UEID, + DBG_RBID, + DBG_LCID, + DBG_LCGID, + DBG_TRNSID, + DBG_INSTID, + DBG_MAX_IDs +} R_SPL_ARG; + +#ifdef USE_RLOG_DATA_TYPES +typedef const char* PSTR; +typedef unsigned char U8; +typedef unsigned short U16; +typedef unsigned int U32; +typedef int S32; +typedef signed short S16; +#else +#include "envdep.h" +typedef const char* PSTR; +#endif + +typedef U32 LOGID; + +#include +extern FILE* g_fp; +void logLev0(PSTR strLogLevel, PSTR modName, PSTR file, int lineno, PSTR fmtStr, ...); +void logLev1(PSTR strLogLevel, PSTR modName, PSTR file, int lineno, PSTR fmtStr, U32 arg1, ...); +void logLev2(PSTR strLogLevel, PSTR modName, PSTR file, int lineno, PSTR fmtStr, U32 arg1, U32 arg2, ...); +void logLev3(PSTR strLogLevel, PSTR modName, PSTR file, int lineno, PSTR fmtStr, U32, U32, U32, ...); +void logLev4(PSTR strLogLevel, PSTR modName, PSTR file, int lineno, PSTR fmtStr, U32, U32, U32, U32, ...); +void logLevN(int logLevel, const char* modName, const char* file, int lineno, const char* fmtStr, ...); +void logLevE(PSTR strLogLevel, PSTR modName, PSTR file, int lineno, PSTR fmtStr, R_SPL_ARG splType, + U32 splVal, U32 arg1, U32 arg2, U32 arg3, U32 arg4, ...); +void logLevH(PSTR strLogLevel, PSTR modName, PSTR file, int lineno, PSTR fmtStr, PSTR hexdump, int hexlen, ...); +void logLevS(PSTR strLogLevel, PSTR modName, PSTR file, int lineno, PSTR fmtStr, PSTR str, ...); + +void hextostr(char* p, PSTR h, int hexlen); + +extern int g_logLevel; +extern U32 g_modMask; +extern const char* g_logStr[L_MAX_LOG_LEVEL]; +extern const char* g_splStr[DBG_MAX_IDs]; + +#define RLOG_SEGFAULT_STR "Segmentation Fault Occurred\n%s" + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __RLOG_COMMON_H__ */ diff --git a/src/rlog/rl_interface.h b/src/rlog/rl_interface.h new file mode 100755 index 000000000..925ab5f23 --- /dev/null +++ b/src/rlog/rl_interface.h @@ -0,0 +1,188 @@ +/******************************************************************************* +################################################################################ +# Copyright (c) [2017-2019] [Radisys] # +# # +# 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. # +################################################################################ +*******************************************************************************/ + +/********************************************************************20** + + Name: Radisys Logging Framework + Type: C include file + Desc: This file contains logging framework include file. + File: rl_interface.h +*********************************************************************21*/ +/////////////////////////////////////////////////////////////////////////////// +// @ description: This is header file is used by applications who want to +// define LOG Macros. This file can be refered for integrating log library +// into any application. API's defined in the file should be used by the +// program to modify data at runtime. +/////////////////////////////////////////////////////////////////////////////// + +#ifndef __RL_INTERFACE_H__ + +#include "rl_common.h" + +/////////////////////////////////////////////////////////////////////////////// +// This API is used to set logging directory path. If set after the log +// initialization API, next file creation will happen in this directory +void rlSetLogPath(const char* logDir); + +/////////////////////////////////////////////////////////////////////////////// +// This API needs to be called after configuring all the required parameters +// by using below APIs. This API initializes logging framework. +// Log MACRO's should be used only after calling this API. +void rlInitLog(U8 type); + +/////////////////////////////////////////////////////////////////////////////// +// This initializes log file name. Log file name should be exclusive of +// extension. As framework appends ".bin" in case of binary file and ".txt" in +// case of plain text logging. If file name is "stdout" and TEXT logging is +// enabled, logs will be printed in console. Run time file name can be changed +// and will be applicable when next file is created. +void rlSetLogFile(const char* fileName); + +/////////////////////////////////////////////////////////////////////////////// +// This API is used to set remote logging port, where post-processor application +// (rlogapp) is used to connect on this port in order to receive live binary logs. +// This API can be used only during initialization time. +void rlSetLogPort(U32 port); + +/////////////////////////////////////////////////////////////////////////////// +// Use this API to set log level. This API supports run time modification of +// log level. +void rlSetLogLevel(R_LOG_LEVEL logLevel); + +/////////////////////////////////////////////////////////////////////////////// +// This API toggles the module mask. If logging for this module is already +// enabled, it will be disabled. If it's not enabled, it will enable. Zero +// input will disable logging mask for all modules. +void rlSetModuleMask(U32 modMask); + +/////////////////////////////////////////////////////////////////////////////// +// This API is used to set log file size limit for single file. +void rlSetLogFileSizeLimit(U32 maxFileSize); + +/////////////////////////////////////////////////////////////////////////////// +// This API sets the limit of number of log files that can be created by +// logging framework. +void rlSetNumOfLogFiles(U8 nMaxFiles); + +/////////////////////////////////////////////////////////////////////////////// +// This API is used to set circular buffer size for each thread. Based on the +// number of threads in the system this size needs to be chosen. Recommended +// minimum 100Kb buffer size. +void rlSetCircularBufferSize(U32 bufSize); + +/////////////////////////////////////////////////////////////////////////////// +// This API enables or disables remote logging application connection to see +// live binary logs. +void rlSetRemoteLoggingFlag(S32 flag); + +/////////////////////////////////////////////////////////////////////////////// +// To change or modify logging level using console, console input needs to be +// passed to this function. +int rlHandleConInput(char ch); + +/////////////////////////////////////////////////////////////////////////////// +// This API enables or disables core file generation based on the input flag +// value. 1 Enables core dump and 0 disables generating core dump. +void rlEnableDisableCore(S32 enable_core); + +/////////////////////////////////////////////////////////////////////////////// +// This API enables Bufferd IO, to disable frequent file operation +void rlEnaBleBufferedIO(void); + +/////////////////////////////////////////////////////////////////////////////// +// This API updates the RLOG Tti count baed on this time stamp will be updated +extern void rlUpdateRlogTti(void); + +/////////////////////////////////////////////////////////////////////////////// +// This API reset the RLOG rate control count and enable logging every 10 ms +extern void rlResetLogRateLmt(void); + +/////////////////////////////////////////////////////////////////////////////// +// This API reset the RLOG rate control count and enable logging every 10 ms +extern void rlResetLogRateLmt(void); + +/////////////////////////////////////////////////////////////////////////////// +// This API Start the limit the number of logs loggd into circular buffer every +// 10ms +extern void rlStartLogCountLimit(void); + +/////////////////////////////////////////////////////////////////////////////// +// This API stops restriciton of limiting number of logs every 10 ms +extern void rlStopLogCountLimit(void); + + +#ifdef WR_DBG_CIRLOG + +#include "rl_redirect.h" + +#else + +#define FMTSTR "[%d-%d-%d %d:%d:%d.%03d][%s]%s:%d\n%s:" +#define FMTSTR_S "[%d-%d-%d %d:%d:%d.%03d][%s]%s:%d\n%s:%s:%ld:" + +#define LOG_ARG0(_level, _fmtStr) \ +if( _level < g_logLevel || g_modMask & RLOG_MODULE_ID)\ +{ \ + logLev0(g_logStr[_level],RLOG_MODULE_NAME, __FILE__,__LINE__, FMTSTR _fmtStr "\n\n", RLOG_FILE_ID); \ +} + +#define LOG_ARGN(_N, _level, _fmtStr, ...) \ +if( _level < g_logLevel || g_modMask & RLOG_MODULE_ID)\ +{ \ + logLev##_N(g_logStr[_level],RLOG_MODULE_NAME, __FILE__,__LINE__, FMTSTR _fmtStr "\n\n", ##__VA_ARGS__ , RLOG_FILE_ID); \ +} + +#define LOG_SPL(_level, _splenum, _splArg, _fmtStr, ...) \ +if( _level < g_logLevel || g_modMask & RLOG_MODULE_ID)\ +{ \ + logLevE(g_logStr[_level],RLOG_MODULE_NAME, __FILE__,__LINE__, FMTSTR_S _fmtStr "\n\n", _splenum,_splArg, ##__VA_ARGS__, RLOG_FILE_ID); \ +} + +#define LOG_ARGX(_level, _fmtStr, ...) \ +if( _level < g_logLevel || g_modMask & RLOG_MODULE_ID)\ +{ \ + logLevN(_level,RLOG_MODULE_NAME, __FILE__,__LINE__, _fmtStr "\n\n", __VA_ARGS__, RLOG_FILE_ID); \ +} + +#define RLOG0(_level, _lstr) LOG_ARG0(_level, _lstr) +#define RLOG1(_level, _lstr, _arg1) LOG_ARGN(1, _level, _lstr, _arg1) +#define RLOG2(_level, _lstr, _arg1, _arg2) LOG_ARGN(2, _level, _lstr, _arg1, _arg2) +#define RLOG3(_level, _lstr, _arg1, _arg2, _arg3) LOG_ARGN(3, _level, _lstr, _arg1, _arg2, _arg3) +#define RLOG4(_level, _lstr, _arg1, _arg2, _arg3, _arg4)LOG_ARGN(4, _level, _lstr, _arg1, _arg2, _arg3, _arg4) + + +#define RLOG_STR(_level, _lstr, _strarg) LOG_ARGN(S, _level, _lstr, _strarg) +#define RLOG_HEX(_level, _lstr, _hexdata, _hexlen) LOG_ARGN(H, _level, _lstr, _hexdata, _hexlen) + +#define RLOG_ARG0(_level, _splenum, _splArg, _lstr) \ + LOG_SPL(_level, _splenum, _splArg, _lstr, 0, 0, 0, 0) + +#define RLOG_ARG1(_level, _splenum, _splArg, _lstr, _arg1) \ + LOG_SPL(_level, _splenum, _splArg, _lstr, _arg1, 0, 0, 0) + +#define RLOG_ARG2(_level, _splenum, _splArg, _lstr, _arg1, _arg2) \ + LOG_SPL(_level, _splenum, _splArg, _lstr, _arg1, _arg2, 0, 0) + +#define RLOG_ARG3(_level, _splenum, _splArg, _lstr, _arg1, _arg2, _arg3) \ + LOG_SPL(_level, _splenum, _splArg, _lstr, _arg1, _arg2, _arg3, 0) + +#define RLOG_ARG4(_level, _splenum, _splArg, _lstr, _arg1, _arg2, _arg3, _arg4) \ + LOG_SPL(_level, _splenum, _splArg, _lstr, _arg1, _arg2, _arg3, _arg4) + +#endif /* WR_DBG_CIRLOG */ +#endif /* __RLOG_INTERFACE_H__*/ diff --git a/src/rlog/rl_rlog.h b/src/rlog/rl_rlog.h new file mode 100755 index 000000000..1f465ba69 --- /dev/null +++ b/src/rlog/rl_rlog.h @@ -0,0 +1,121 @@ +/******************************************************************************* +################################################################################ +# Copyright (c) [2017-2019] [Radisys] # +# # +# 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. # +################################################################################ +*******************************************************************************/ + +/********************************************************************20** + + Name: Radisys Logging Framework + Type: C include file + Desc: This file contains logging framework include file for library. + File: rl.h + +*********************************************************************21*/ +/**************************************************************************** +@ description: This is header file is used by logging framework module. This +file should not be included by any other application. This is internal +header file logging framework. +*****************************************************************************/ + +#ifndef __RL_H__ +#define __RL_H__ + +#include +#include +#include +#include +#include +#include +#include +#include "rl_common.h" + +#define MAX_FILE_SIZE 3145728 /* 3MB */ +#define MAX_LOG_LEN 256 +#define MAX_FILENAME_LEN 300 +#define LOG_TIME_LEN 64 +#define MAX_LOG_BUF_SIZE 5000 +#define RLOG_MAX_CIRBUF_SIZE (1024*100) +#define RLOG_REMOTE_LOGGING_PORT 9099 +#define RLOG_MAX_FILES 5 +#define RLOG_MAX_TIME_STAMP 80 +#define RLOG_MAX_TAX_NAME 16 +#define RLOG_FIFO_FILE "/tmp/l2logs" +#define RLOG_CIRBUF_READ_INTERVAL 1 /* 60 seconds read interval */ +#define RLOG_MAX_THREADS 16 +#define RLOG_TIME_ZONE_LEN 8 +#define RLOG_MAX_STACK_DEPTH 24 +#define RLOG_MAX_BACKTRACE_BUFSZ 2048 +#define RLOG_READ_POS_THRESHOLD 300 +#define RLOG_FIXED_LENGTH_BUFFER_SIZE 50 +#define RLOGTICKSCNTTOPRCL2LOGS 10 + +/* Console handling */ +#define RLOG_CTRL_L 12 +#define RLOG_CTRL_Y 25 +#define RLOG_ENTER_KEY 10 +#define RLOG_SET_LOGLEVEL 1 +#define RLOG_SET_MODMASK 2 + +/*L2 Logging */ +#define PROCESS_L2LOG_TTI 10 + +typedef enum { +LOG_ARG_INT, +LOG_ARG_STR, +LOG_ARG_HEX, +LOG_ARG_SPL +} LOG_ARG_TYPE; + +typedef enum rlLogCntLmt +{ + RL_LOG_COUNT_LIMIT_START = 1, + RL_LOG_COUNT_LIMIT_STOP +}RLLogCntLmt; + +typedef struct { + + char szTaskName[RLOG_MAX_TAX_NAME]; + U8* logBuff; /* LOG Buffer */ + U32 logBufLen; /* Data Written till now */ + U32 logReadPos; /* Reader thread position */ + U8 listIndex; /* Index to global list */ + +} THREAD_DATA; + +extern void readL2LogBuff(void); +extern void processL2LogBuff(void); +extern S16 sendL2LogBuftoL3(void); +extern void rlInitL2Log(void); +/* Extern for soc specific file */ +extern void rlProcessLogBufFromL2(void *mBuf); +extern void rlInitL2SocSpecific(void); +//extern void processL2LogBuff(void); +extern void rlProcessTicks(void); +extern void rlGetL2LogBufPtr (void *mBuf, U32 *logLen,U8 **logPtr); +extern void rlInvalidateL2LogsInCache(U8 *ptr,U32 len); + +extern U8 *g_l2rlogBuf; /* buffer pointer for shared memory allocation */ +extern U8 *g_l2LogBufStartPtr; /* buffer pointer where logs has to be written */ +extern U8 *g_l2LogBufBasePtr; /* Base pointer for log buffer */ +extern U8 *g_logBufRcvdFromL2; /* Buffer pointer received from L2 at L3*/ +extern U8 *g_l2LogBaseBuff; /* Base log buffer received at L3 */ +extern U32 g_l2LogBufLen; /* Log Buffer length written at L2 */ +extern U32 startL2Logging; /* flag to start processing of L2 logs */ +extern U32 g_l2logBuffPos; /* Log Buffer block which is in use for L2 logging */ +extern U8 g_writeCirBuf; /* Flag to indicate whether to write logs or not */ +//extern Pst g_rlog_pst; + +#endif /* __RL_H__*/