summaryrefslogtreecommitdiff
path: root/Acceleration/library/icp_telephony/tdm_io_access
diff options
context:
space:
mode:
Diffstat (limited to 'Acceleration/library/icp_telephony/tdm_io_access')
-rw-r--r--Acceleration/library/icp_telephony/tdm_io_access/Makefile136
-rw-r--r--Acceleration/library/icp_telephony/tdm_io_access/icp_hssacc_address_translate.c178
-rw-r--r--Acceleration/library/icp_telephony/tdm_io_access/icp_hssacc_channel_config.c2174
-rw-r--r--Acceleration/library/icp_telephony/tdm_io_access/icp_hssacc_channel_list.c911
-rw-r--r--Acceleration/library/icp_telephony/tdm_io_access/icp_hssacc_common.c464
-rw-r--r--Acceleration/library/icp_telephony/tdm_io_access/icp_hssacc_common_timeslot_allocation.c441
-rw-r--r--Acceleration/library/icp_telephony/tdm_io_access/icp_hssacc_param_check.c95
-rw-r--r--Acceleration/library/icp_telephony/tdm_io_access/icp_hssacc_port_config.c1175
-rw-r--r--Acceleration/library/icp_telephony/tdm_io_access/icp_hssacc_port_hdma_reg_mgr.c546
-rw-r--r--Acceleration/library/icp_telephony/tdm_io_access/icp_hssacc_queues_config.c1501
-rw-r--r--Acceleration/library/icp_telephony/tdm_io_access/icp_hssacc_rx_datapath.c2014
-rw-r--r--Acceleration/library/icp_telephony/tdm_io_access/icp_hssacc_service.c2579
-rw-r--r--Acceleration/library/icp_telephony/tdm_io_access/icp_hssacc_symbols.c121
-rw-r--r--Acceleration/library/icp_telephony/tdm_io_access/icp_hssacc_timeslot_allocation.c665
-rw-r--r--Acceleration/library/icp_telephony/tdm_io_access/icp_hssacc_tx_datapath.c1023
-rw-r--r--Acceleration/library/icp_telephony/tdm_io_access/icp_hssacc_voice_bypass.c776
-rw-r--r--Acceleration/library/icp_telephony/tdm_io_access/include/icp_hssacc_address_translate.h142
-rw-r--r--Acceleration/library/icp_telephony/tdm_io_access/include/icp_hssacc_channel_config.h269
-rw-r--r--Acceleration/library/icp_telephony/tdm_io_access/include/icp_hssacc_channel_list.h137
-rw-r--r--Acceleration/library/icp_telephony/tdm_io_access/include/icp_hssacc_common.h978
-rw-r--r--Acceleration/library/icp_telephony/tdm_io_access/include/icp_hssacc_port_config.h297
-rw-r--r--Acceleration/library/icp_telephony/tdm_io_access/include/icp_hssacc_port_hdma_reg_mgr.h160
-rw-r--r--Acceleration/library/icp_telephony/tdm_io_access/include/icp_hssacc_queues_config.h275
-rw-r--r--Acceleration/library/icp_telephony/tdm_io_access/include/icp_hssacc_rings.h170
-rw-r--r--Acceleration/library/icp_telephony/tdm_io_access/include/icp_hssacc_rx_datapath.h216
-rw-r--r--Acceleration/library/icp_telephony/tdm_io_access/include/icp_hssacc_tdm_io_queue_entry.h193
-rw-r--r--Acceleration/library/icp_telephony/tdm_io_access/include/icp_hssacc_timeslot_allocation.h260
-rw-r--r--Acceleration/library/icp_telephony/tdm_io_access/include/icp_hssacc_trace.h339
-rw-r--r--Acceleration/library/icp_telephony/tdm_io_access/include/icp_hssacc_tx_datapath.h191
-rw-r--r--Acceleration/library/icp_telephony/tdm_io_access/include/icp_hssacc_voice_bypass.h115
-rw-r--r--Acceleration/library/icp_telephony/tdm_io_access/linux_2.6_kernel_space.mk76
31 files changed, 18617 insertions, 0 deletions
diff --git a/Acceleration/library/icp_telephony/tdm_io_access/Makefile b/Acceleration/library/icp_telephony/tdm_io_access/Makefile
new file mode 100644
index 0000000..04fc632
--- /dev/null
+++ b/Acceleration/library/icp_telephony/tdm_io_access/Makefile
@@ -0,0 +1,136 @@
+############################################################################
+# Targets supported
+# all - builds everything and installs
+# install - identical to all
+# depend - build dependencies
+# clean - clears derived objects except the .depend files
+# distclean- clears all derived objects and the .depend file
+#
+# @par
+# This file is provided under a dual BSD/GPLv2 license. When using or
+# redistributing this file, you may do so under either license.
+#
+# GPL LICENSE SUMMARY
+#
+# Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved.
+# Copyright(c) 2010,2011,2012 Avencall
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of version 2 of the GNU General Public License as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+# The full GNU General Public License is included in this distribution
+# in the file called LICENSE.GPL.
+#
+# BSD LICENSE
+#
+# Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved.
+# All rights reserved.
+# Copyright(c) 2010,2011,2012 Avencall
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+# * Neither the name of Intel Corporation nor the names of its
+# contributors may be used to endorse or promote products derived
+# from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+#
+#
+############################################################################
+
+
+# Ensure The ENV_DIR environmental var is defined.
+ifndef ICP_ENV_DIR
+$(error ICP_ENV_DIR is undefined. Please set the path to your environment makefile \
+ "-> setenv ENV_DIR <path>")
+endif
+
+#Add your project environment Makefile, extra comment
+include $(ICP_ENV_DIR)/environment.mk
+
+
+#include the makefile with all the default and common Make variable definitions
+include $(ICP_BUILDSYSTEM_PATH)/build_files/common.mk
+
+
+#Add the name for the executable, Library or Module output definitions
+OUTPUT_NAME=$(ICP_TDM_IO_NAME)
+
+# List of Source Files to be compiled (to be in a single line or on different lines separated by a "\" and tab.
+SOURCES= icp_hssacc_common.c \
+ icp_hssacc_channel_list.c \
+ icp_hssacc_channel_config.c \
+ icp_hssacc_voice_bypass.c \
+ icp_hssacc_service.c \
+ icp_hssacc_queues_config.c \
+ icp_hssacc_rx_datapath.c \
+ icp_hssacc_tx_datapath.c \
+ icp_hssacc_port_config.c \
+ icp_hssacc_port_hdma_reg_mgr.c \
+ icp_hssacc_common_timeslot_allocation.c \
+ $(ICP_DEVICE)$(ICP_SLASH)icp_hssacc_timeslot_allocation.c \
+ $(ICP_DEVICE)$(ICP_SLASH)icp_hssacc_address_translate.c \
+ $(ICP_DEVICE)$(ICP_SLASH)icp_hssacc_param_check.c
+
+
+# Setup include directory
+INCLUDES += -I $(src)/include \
+ -I $(PWD)/include \
+ -I $(ICP_API_DIR) \
+ -I $(ICP_API_DIR)/hss \
+ -I $(ICP_API_DIR)/accel_infra \
+ -I $(ICP_OSAL_DIR)/common/include
+
+ifeq ($(ICP_INTEL_DEV),YES)
+INCLUDES += -I $(ICP_OSAL_DIR)/common/include/modules \
+ -I $(ICP_OSAL_DIR)/common/include/modules/ddk \
+ -I $(ICP_OSAL_DIR)/common/include/modules/bufferMgt \
+ -I $(ICP_OSAL_DIR)/common/include/modules/ioMem
+endif
+
+EXTRA_CFLAGS += -DENABLE_IOMEM -DENABLE_BUFFERMGT
+
+
+#include your $(ICP_OS)_$(ICP_OS_LEVEL).mk file
+include $(ICP_TDM_IO_DIR)/$(ICP_OS)_$(ICP_OS_LEVEL).mk
+
+
+# Install the module to the output dir
+install: module
+
+
+###################Include rules and dependency makefiles########################
+include $(ICP_BUILDSYSTEM_PATH)/build_files/rules.mk
+###################End of Rules and dependency inclusion#########################
+
+
+
+
diff --git a/Acceleration/library/icp_telephony/tdm_io_access/icp_hssacc_address_translate.c b/Acceleration/library/icp_telephony/tdm_io_access/icp_hssacc_address_translate.c
new file mode 100644
index 0000000..73a1269
--- /dev/null
+++ b/Acceleration/library/icp_telephony/tdm_io_access/icp_hssacc_address_translate.c
@@ -0,0 +1,178 @@
+/******************************************************************************
+ * @file icp_hssacc_address_translate.c
+ *
+ * @description Content of this file provides the definition of
+ * address translation functions from the virtual
+ * address space to the physical and vice-versa
+ *
+ * @ingroup icp_HssAcc
+ *
+ * @Revision 1.0
+ *
+ * @par
+ * This file is provided under a dual BSD/GPLv2 license. When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * The full GNU General Public License is included in this distribution
+ * in the file called LICENSE.GPL.
+ *
+ * Contact Information:
+ * Intel Corporation
+ *
+ * BSD LICENSE
+ *
+ * Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ *
+ *
+ ******************************************************************************/
+
+#include "IxOsal.h"
+
+#include "icp.h"
+#include "icp_hssacc_common.h"
+#include "icp_hssacc_address_translate.h"
+#include "icp_hssacc_trace.h"
+
+uint32_t
+HssAccVirtToPhysAddressTranslateAndSwap(void* pVirtAddr)
+{
+ uint32_t physAddr = 0;
+ /* Convert the table base address to a physical address */
+ physAddr = HssAccVirtToPhysAddressTranslate (pVirtAddr);
+#ifdef SW_SWAPPING
+ /* Now convert the physical address to network order */
+ physAddr = IX_OSAL_SWAP_BE_SHARED_LONG(physAddr);
+#endif
+ return physAddr;
+}
+
+void *
+HssAccPhysToVirtAddressSwapAndTranslate(uint32_t physAddr)
+{
+ void * pVirtAddr = NULL;
+#ifdef SW_SWAPPING
+ /* Now convert the physical address back to little endian mode */
+ physAddr = IX_OSAL_SWAP_BE_SHARED_LONG(physAddr);
+#endif
+ /* Convert the physical address to a virtual address*/
+ pVirtAddr = HssAccPhysToVirtAddressTranslate (physAddr);
+
+ return pVirtAddr;
+}
+
+
+
+uint32_t
+HssAccVirtToPhysAddressTranslate(void * const pVirtAddr)
+{
+ uint32_t physAddr = 0;
+ /* Convert the table base address to a physical address */
+ physAddr = (uint32_t)IX_OSAL_MMU_VIRT_TO_PHYS (pVirtAddr);
+
+ return physAddr;
+}
+
+
+void *
+HssAccPhysToVirtAddressTranslate(const uint32_t physAddr)
+{
+ void * pVirtAddr = NULL;
+
+ /* Convert the physical address to a table base address*/
+ pVirtAddr = (void*)IX_OSAL_MMU_PHYS_TO_VIRT (physAddr);
+
+ return pVirtAddr;
+}
+
+
+
+void *
+HssAccDmaMemAllocate(uint32_t sizeBytes,
+ uint32_t * physOffset)
+{
+ void * pVirtAddr = NULL;
+ *physOffset = 0;
+ pVirtAddr = (void *)IX_OSAL_CACHE_DMA_MALLOC(sizeBytes);
+ if (NULL != pVirtAddr)
+ {
+ *physOffset = HssAccVirtToPhysAddressTranslate(pVirtAddr);
+ }
+ return pVirtAddr;
+
+}
+
+/* This function perform an endianness swap on each word of the provided buffer
+ it assumed that the buffer size is a multiple of word size */
+void
+HssAccDataEndiannessSwap(IX_OSAL_MBUF * const buffer)
+{
+#ifdef SW_SWAPPING
+ uint32_t index = 0;
+ uint32_t * dataPtr = (uint32_t*)IX_OSAL_MBUF_MDATA(buffer);
+#endif
+ ICP_HSSACC_TRACE_1 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Entering HssAccDataEndiannessSwap"
+ " for Buffer 0x%08X\n",
+ (uint32_t)buffer);
+#ifdef SW_SWAPPING
+ if ( 0 != (IX_OSAL_MBUF_PKT_LEN(buffer) % ICP_HSSACC_WORD_SIZE))
+ {
+ ICP_HSSACC_REPORT_ERROR("HssAccDataEndiannessSwap - Buffer Provided"
+ " has a size that is not a multiple of a "
+ "word size\n");
+ }
+ for (;
+ index < (IX_OSAL_MBUF_PKT_LEN(buffer) / ICP_HSSACC_WORD_SIZE);
+ index ++)
+ {
+ dataPtr[index] = IX_OSAL_SWAP_BE_SHARED_LONG(dataPtr[index]);
+ }
+#endif
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Exiting HssAccDataEndiannessSwap\n");
+}
diff --git a/Acceleration/library/icp_telephony/tdm_io_access/icp_hssacc_channel_config.c b/Acceleration/library/icp_telephony/tdm_io_access/icp_hssacc_channel_config.c
new file mode 100644
index 0000000..4f4da9b
--- /dev/null
+++ b/Acceleration/library/icp_telephony/tdm_io_access/icp_hssacc_channel_config.c
@@ -0,0 +1,2174 @@
+/******************************************************************************
+ *
+ * @file icp_hssacc_channel_config.c
+ *
+ * @description Contents of this file is the channel configuration module which
+ * include the implementation of the channel configuration API.
+ *
+ * @ingroup icp_HssAcc
+ *
+ * @Revision 1.0
+ *
+ * @par
+ * This file is provided under a dual BSD/GPLv2 license. When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * The full GNU General Public License is included in this distribution
+ * in the file called LICENSE.GPL.
+ *
+ * Contact Information:
+ * Intel Corporation
+ *
+ * BSD LICENSE
+ *
+ * Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ *
+ *
+ *****************************************************************************/
+#include "IxOsal.h"
+
+#include "icp.h"
+#include "icp_hssacc.h"
+#include "icp_hssacc_queues_config.h"
+#include "icp_hssacc_trace.h"
+#include "icp_hssacc_common.h"
+#include "icp_hssacc_channel_config.h"
+#include "icp_hssacc_channel_list.h"
+#include "icp_hssacc_timeslot_allocation.h"
+#include "icp_hssacc_address_translate.h"
+#include "icp_hssacc_tx_datapath.h"
+#include "icp_hssacc_rx_datapath.h"
+
+
+/* Stats */
+typedef struct icp_hssacc_channel_config_stats_s
+{
+ icp_hssacc_msg_with_resp_stats_t chanCfg;
+ icp_hssacc_msg_with_resp_stats_t chanEnable;
+ icp_hssacc_msg_with_resp_stats_t chanDisable;
+ icp_hssacc_msg_with_resp_stats_t hdlcChanCfg;
+ icp_hssacc_msg_with_resp_stats_t voiceChanCfg;
+ icp_hssacc_msg_with_resp_stats_t offsetTableLoad;
+ icp_hssacc_msg_with_resp_stats_t hdlcMaxRxCfg;
+} icp_hssacc_channel_config_stats_t;
+
+typedef enum
+ {
+ ICP_HSSACC_VOICE_NB_CHAN_SIZE = 1,
+ ICP_HSSACC_VOICE_NBL_CHAN_SIZE = 2,
+ ICP_HSSACC_VOICE_WB_CHAN_SIZE = 4,
+ ICP_HSSACC_VOICE_UWB_CHAN_SIZE = 8
+ } icp_hssacc_voice_supported_sizes_t;
+
+
+/* definition in Bytes of the maximum sample size for each type of voice
+ channel.for example, G711 30msec sample is the factor for determining max
+ size for a narrowband channel */
+
+#define ICP_HSSACC_VOICE_NB_MAX_SAMPLE_SIZE (240)
+#define ICP_HSSACC_VOICE_NBL_MAX_SAMPLE_SIZE (480)
+#define ICP_HSSACC_VOICE_WB_MAX_SAMPLE_SIZE (960)
+#define ICP_HSSACC_VOICE_UWB_MAX_SAMPLE_SIZE (1920)
+
+
+#define ICP_HSSACC_FCS_4_BYTE_WIDTH (4)
+#define ICP_HSSACC_FCS_2_BYTE_WIDTH (2)
+
+/*
+ * Sets the enable bit in the timeslot word of HSS port provision table.
+ */
+#define ICP_HSSACC_HDMA_TIMESLOT_ENABLE (BIT_SET(23))
+
+/*
+ * The channel ID must be shifted by this offset in the HSS port
+ * provision table
+ */
+#define ICP_HSSACC_HDMA_CHANNEL_OFFSET (16)
+
+
+
+
+/*
+ * ----------------------------------------------------------------------------
+ * Struct types
+ * ----------------------------------------------------------------------------
+ */
+/*
+ * ----------------------------------------------------------------------------
+ * Global variables
+ * ----------------------------------------------------------------------------
+ */
+
+/* Tracks the current channel state and configuration */
+TDM_PRIVATE icp_hssacc_channel_config_t
+hssAccChannelConfig[ICP_HSSACC_MAX_NUM_CHANNELS];
+
+
+/* This variable holds the number of channels currently allocated. */
+TDM_PRIVATE unsigned hssAccNumChansAllocated = 0;
+
+TDM_PRIVATE icp_hssacc_channel_config_stats_t hssAccChanCfgStats;
+
+TDM_PRIVATE icp_boolean_t channelConfigModuleInitialised = ICP_FALSE;
+
+
+/*
+ * ----------------------------------------------------------------------------
+ * Static function declarations
+ * ----------------------------------------------------------------------------
+ */
+
+TDM_PRIVATE icp_status_t
+HssAccChannelConfigHdlcServiceMsgSend (unsigned channelId);
+
+TDM_PRIVATE icp_status_t
+HssAccChannelConfigVoiceServiceMsgSend (unsigned channelId);
+
+
+TDM_PRIVATE icp_status_t
+HssAccChannelConfigHdlcMaxFrameSizeSend (unsigned channelId);
+
+TDM_PRIVATE icp_status_t
+HssAccChannelConfigMsgSend (unsigned channelId);
+
+TDM_PRIVATE void
+HssAccChannelConfigStateReset (unsigned channelId);
+
+
+/*****************************************************************************
+ * Abstract:
+ * The timeslot map for a given channel cannot span multiple TDM trunks,
+ * i.e. all timeslots pertaining to a channel must reside solely on
+ * line0_timeslot_bit_map, line1_timeslot_bit_map, line2_timeslot_bit_map
+ * or line3_timeslot_bit_map.
+ * This function enforces this policy as well as checking that at least 1
+ * TS as been assigned.
+ *****************************************************************************/
+inline icp_status_t HssAccTimeslotErrorCheck (icp_hssacc_timeslot_map_t tsMap)
+{
+ icp_status_t status = ICP_STATUS_SUCCESS;
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Entering HssAccTimeslotErrorCheck\n");
+ if (tsMap.line0_timeslot_bit_map != 0)
+ {
+ if ( (tsMap.line1_timeslot_bit_map | tsMap.line2_timeslot_bit_map |
+ tsMap.line3_timeslot_bit_map) != 0 )
+ {
+ ICP_HSSACC_REPORT_ERROR ("HssAccTimeslotErrorCheck - The channel "
+ "timeslot mapping cannot span "
+ "TDM lines!\n");
+ status = ICP_STATUS_INVALID_PARAM;
+ }
+ }
+ else if (tsMap.line1_timeslot_bit_map != 0)
+ {
+ if ( (tsMap.line2_timeslot_bit_map |
+ tsMap.line3_timeslot_bit_map) != 0 )
+ {
+ ICP_HSSACC_REPORT_ERROR ("HssAccTimeslotErrorCheck - The channel "
+ "timeslot mapping cannot span "
+ "TDM lines!\n");
+ status = ICP_STATUS_INVALID_PARAM; }
+ }
+ else if (tsMap.line2_timeslot_bit_map != 0)
+ {
+ if ( (tsMap.line3_timeslot_bit_map) != 0 )
+ {
+ ICP_HSSACC_REPORT_ERROR ("HssAccTimeslotErrorCheck - The channel "
+ "timeslot mapping cannot span "
+ "TDM lines!\n");
+ status = ICP_STATUS_INVALID_PARAM; }
+ }
+ else if (tsMap.line3_timeslot_bit_map == 0)
+ {
+ ICP_HSSACC_REPORT_ERROR ("HssAccTimeslotErrorCheck - Invalid timeslot"
+ " configuration, no slots were chosen!\n");
+ status = ICP_STATUS_INVALID_PARAM;
+ }
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Exiting HssAccTimeslotErrorCheck\n");
+
+ return status;
+}
+
+
+/******************************************************************************
+ * Abstract:
+ * counts the number of timeslots requested by the channel,
+ * determines the HSS line that the timeslots reside on and copies the
+ * appropriate line's TDM map to the variable chanTsMap. at least one TS
+ * must be assigned for this function to function correctly.
+ *
+ ****************************************************************************/
+void HssAccTimeslotConfigGet(icp_hssacc_timeslot_map_t tsMap,
+ unsigned * numTs,
+ icp_hssacc_line_t * lineId,
+ uint32_t * chanTsMap,
+ unsigned * firstTsPosition,
+ unsigned * lastTsPosition)
+{
+ unsigned tempNumTs = 0;
+ uint32_t bitMap = 0;
+ icp_boolean_t firstFound = ICP_FALSE;
+
+ (*lastTsPosition) = 0;
+ (*firstTsPosition) = 0;
+ if (tsMap.line0_timeslot_bit_map != 0)
+ {
+ *lineId = ICP_HSSACC_LINE_0;
+ *chanTsMap = tsMap.line0_timeslot_bit_map;
+ }
+ else if (tsMap.line1_timeslot_bit_map != 0)
+ {
+ *lineId = ICP_HSSACC_LINE_1;
+ *chanTsMap = tsMap.line1_timeslot_bit_map;
+ }
+ else if (tsMap.line2_timeslot_bit_map != 0)
+ {
+ *lineId = ICP_HSSACC_LINE_2;
+ *chanTsMap = tsMap.line2_timeslot_bit_map;
+ }
+ else if (tsMap.line3_timeslot_bit_map != 0)
+ {
+ *lineId = ICP_HSSACC_LINE_3;
+ *chanTsMap = tsMap.line3_timeslot_bit_map;
+ }
+ bitMap = *chanTsMap;
+ tempNumTs += (bitMap & 1);
+ if (bitMap & 1)
+ {
+ firstFound = ICP_TRUE;
+ }
+ bitMap >>= 1;
+ while (bitMap)
+ {
+ tempNumTs += (bitMap & 1);
+ (*lastTsPosition) ++;
+ if ((ICP_FALSE == firstFound) &&
+ (bitMap & 1))
+ {
+ firstFound = ICP_TRUE;
+ (*firstTsPosition) = (*lastTsPosition);
+ }
+ bitMap >>= 1;
+ }
+ *numTs = tempNumTs;
+}
+
+/******************************************************************************
+ * Abstract:
+ * Initialises all global variables used during channel configuration.
+ * Allocates memory for the channel offset tables.
+ * Initialises the channel configuration mutex.
+ *
+ *****************************************************************************/
+icp_status_t
+HssAccChannelConfigInit(void)
+{
+ unsigned channelId = 0;
+ icp_status_t status = ICP_STATUS_SUCCESS;
+
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Entering HssAccChannelConfigInit\n");
+
+ if (ICP_TRUE == channelConfigModuleInitialised)
+ {
+ ICP_HSSACC_REPORT_ERROR ("HssAccChannelConfigInit - "
+ "Module is already Initialised\n");
+ status = ICP_STATUS_FAIL;
+ }
+
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ /* Initialise the channel configuration struct */
+ for (channelId = 0;
+ channelId < ICP_HSSACC_MAX_NUM_CHANNELS;
+ channelId ++)
+ {
+ HssAccChannelConfigStateReset(channelId);
+ }
+
+ /* All channels are available */
+ hssAccNumChansAllocated = 0;
+ }
+
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ status = HssAccTsAllocInit();
+ }
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ /* Reset the Messaging Stats */
+ HssAccChannelConfigStatsReset();
+
+ /* Reset the Timeslot Allocation submodule Stats */
+ HssAccTsAllocStatsReset();
+
+ HssAccChannelListsReset();
+
+ channelConfigModuleInitialised = ICP_TRUE;
+ }
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Exiting HssAccChannelConfigInit\n");
+ return status;
+}
+
+
+/******************************************************************************
+ * Abstract:
+ * shuts down the channel Configuration sub-component of HSS Acc.
+ * it will reset all internal variables.
+ *
+ *****************************************************************************/
+icp_status_t
+HssAccChannelConfigShutdown(void)
+{
+ icp_status_t status = ICP_STATUS_SUCCESS;
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Entering HssAccChannelConfigShutdown\n");
+ if (ICP_FALSE == channelConfigModuleInitialised)
+ {
+ ICP_HSSACC_REPORT_ERROR ("HssAccChannelConfigShutdown - "
+ "Service is not initialised\n");
+ status = ICP_STATUS_FAIL;
+ }
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ HssAccTsAllocShutdown();
+ /* just in case, set the number of used channels to the max so that
+ no one can allocate new channels */
+ hssAccNumChansAllocated = ICP_HSSACC_MAX_NUM_CHANNELS;
+ channelConfigModuleInitialised = ICP_FALSE;
+ }
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Exiting HssAccChannelConfigShutdown\n");
+ return status;
+}
+
+/******************************************************************************
+ * Abstract:
+ * Allocate a channel on the specified port using the specified
+ * timeslots.
+ *
+ *****************************************************************************/
+icp_status_t
+icp_HssAccChannelAllocate (unsigned *pChannelId,
+ unsigned portId,
+ icp_hssacc_timeslot_map_t tsMap,
+ icp_hssacc_channel_type_t channelType)
+{
+ unsigned channelSize = 0;
+ unsigned channelId = ICP_HSSACC_MAX_NUM_CHANNELS;
+ icp_hssacc_line_t lineId = ICP_HSSACC_LINE_DELIMITER;
+ uint32_t channelTsMap = 0;
+ icp_status_t status = ICP_STATUS_SUCCESS;
+ icp_boolean_t suitableChanIdFound = ICP_FALSE;
+ icp_boolean_t mutexLocked = ICP_FALSE;
+ unsigned lastTsPos = 0;
+ unsigned firstTsPos = ICP_HSSACC_MAX_TIMESLOTS_PER_TDM_LINE;
+
+ ICP_HSSACC_TRACE_3 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Entering icp_HssAccChannelAllocate - "
+ "\n\tchannelPtr 0x%08X on port %u of type %u\n",
+ (unsigned)pChannelId, portId, channelType);
+ if (ICP_FALSE == channelConfigModuleInitialised)
+ {
+ ICP_HSSACC_REPORT_ERROR ("icp_HssAccChannelAllocate - "
+ "service not Initialised\n");
+ status = ICP_STATUS_FAIL;
+ }
+
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ /* Sanity check the parameters */
+ if ( (NULL == pChannelId) ||
+ (portId >= ICP_HSSACC_MAX_NUM_PORTS) ||
+ ICP_HSSACC_ENUM_INVALID (channelType,
+ ICP_HSSACC_CHAN_TYPE_DELIMITER) )
+ {
+ ICP_HSSACC_REPORT_ERROR ("icp_HssAccChannelAllocate - invalid "
+ "parameter\n");
+ status = ICP_STATUS_INVALID_PARAM;
+ }
+ }
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ if (HssAccPortStateGet(portId) != ICP_HSSACC_PORT_ENABLED)
+ {
+ ICP_HSSACC_REPORT_ERROR_1 ("icp_HssAccChannelAllocate - specified "
+ "port %u should be Enabled\n",
+ portId);
+ status = ICP_STATUS_RESOURCE;
+ }
+ }
+
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ /* Verify that client requested a valid timeslot configuration */
+ status = HssAccTimeslotErrorCheck (tsMap);
+ }
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ /*
+ Extract all information from the timeslot mapping for this channel;
+ this includes the number of timeslots that the channel wants to use,
+ and the line on which the timeslots reside.
+ */
+ HssAccTimeslotConfigGet (tsMap, &channelSize,
+ &lineId, &channelTsMap,
+ &firstTsPos, &lastTsPos);
+
+ ICP_HSSACC_TRACE_2 (ICP_HSSACC_DEBUG,
+ "icp_HssAccChannelAllocate -"
+ " Timeslot Config with Size=%u and lastTsPos=%u\n",
+ channelSize,
+ lastTsPos);
+
+ /* Check that the line used and timeslots used are compatible
+ with the port speed */
+ status = HssAccPortLineValidCheck(portId, lineId,
+ firstTsPos, lastTsPos);
+ }
+
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ /* If this is a voice channel then it can only use
+ 1, 2 or 4 timeslots */
+ if ( (ICP_HSSACC_CHAN_TYPE_VOICE == channelType) &&
+ (channelSize != ICP_HSSACC_VOICE_NB_CHAN_SIZE &&
+ channelSize != ICP_HSSACC_VOICE_NBL_CHAN_SIZE &&
+ channelSize != ICP_HSSACC_VOICE_WB_CHAN_SIZE))
+ {
+ ICP_HSSACC_REPORT_ERROR ("icp_HssAccChannelAllocate - "
+ "invalid number of timeslots. "
+ "A voice channel can only use"
+ " 1, 2 or 4 timeslots.\n");
+ status = ICP_STATUS_INVALID_PARAM;
+ }
+ }
+
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ /* Grab the HssAcc mutex */
+ if (ICP_STATUS_SUCCESS != ICP_HSSACC_MUTEX_LOCK())
+ {
+ ICP_HSSACC_REPORT_ERROR ("icp_HssAccChannelAllocated - "
+ "failed to lock HssAcc Mutex\n");
+
+ status = ICP_STATUS_MUTEX;
+ }
+ else
+ {
+ mutexLocked = ICP_TRUE;
+ }
+ }
+
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ /*
+ * All channels may be used, so check before looping
+ * through each channel ID
+ */
+ if (ICP_HSSACC_MAX_NUM_CHANNELS == hssAccNumChansAllocated)
+ {
+ ICP_HSSACC_REPORT_ERROR ("icp_HssAccChannelAllocate - "
+ "All channels have"
+ " been allocated!\n");
+ status = ICP_STATUS_RESOURCE;
+ }
+ }
+
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ /* Verify that the timeslots requested aren't owned by another channel */
+ if (ICP_FALSE == HssAccTsAvailableVerify (portId, lineId, channelTsMap))
+ {
+ /* The timeslots are in use by another channel */
+ ICP_HSSACC_REPORT_ERROR ("icp_HssAccChannelAllocate - The requested "
+ "timeslots have been reserved by "
+ "another channel\n");
+ status = ICP_STATUS_RESOURCE;
+ }
+ }
+
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ /*
+ * If the code makes it to here there must be
+ * at least one channel not in use; find it.
+ * channelId going out of bounds checked for
+ * paranoias sake.
+ */
+ channelId = 0;
+ while ((ICP_HSSACC_MAX_NUM_CHANNELS > channelId) &&
+ (ICP_FALSE == suitableChanIdFound))
+ {
+ if (ICP_HSSACC_CHANNEL_UNINITIALISED ==
+ hssAccChannelConfig[channelId].state)
+ {
+ hssAccNumChansAllocated ++;
+ suitableChanIdFound = ICP_TRUE;
+ }
+ else
+ {
+ channelId ++;
+ }
+ }
+
+ /* Save the channel ID to return to the client */
+ *pChannelId = channelId;
+
+
+ /* Save these timeslots as in use by this channel */
+ HssAccTsRegister (channelId, portId,
+ lineId, channelTsMap);
+
+ hssAccChannelConfig[channelId].size = channelSize;
+ hssAccChannelConfig[channelId].lineId = lineId;
+ hssAccChannelConfig[channelId].timeslotMap = channelTsMap;
+
+ }
+
+ if (ICP_STATUS_SUCCESS == status)
+ {
+
+ /* Update the channel configuration */
+ hssAccChannelConfig[channelId].state = ICP_HSSACC_CHANNEL_ALLOCATED;
+ hssAccChannelConfig[channelId].type = channelType;
+ hssAccChannelConfig[channelId].portId = portId;
+
+ HssAccTxDatapathChanTypeUpdate(channelId,
+ channelType);
+
+ /* Update the channel offset tables with these timeslots */
+ status = HssAccTsAllocUpdate (portId,
+ hssAccChannelConfig);
+
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ /* Update the Queue Manager Info */
+ status = HssAccQueueConfigQSizeUpdate(channelId, channelType);
+ }
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ status = HssAccChannelListAdd(portId, channelId, channelSize);
+ }
+ if (ICP_STATUS_SUCCESS != status)
+ {
+ /* Revert Back */
+ HssAccTsUnregister (portId,
+ hssAccChannelConfig[channelId].lineId,
+ hssAccChannelConfig[channelId].timeslotMap);
+
+ /* Clear the timeslot allocation but keep the port, we
+ need it for generating the new tables */
+ hssAccChannelConfig[channelId].lineId = ICP_HSSACC_LINE_DELIMITER;
+ hssAccChannelConfig[channelId].timeslotMap = 0;
+ hssAccChannelConfig[channelId].size = 0;
+
+ hssAccChannelConfig[channelId].state =
+ ICP_HSSACC_CHANNEL_UNINITIALISED;
+ hssAccNumChansAllocated --;
+
+ ICP_HSSACC_REPORT_ERROR("icp_HssAccChannelAllocate - Failure "
+ "in updating the TDM I/O Unit with "
+ "the new channel\n");
+ }
+ }
+
+ /* Free the HssAcc mutex */
+ if (ICP_TRUE == mutexLocked)
+ {
+ if (ICP_STATUS_SUCCESS != ICP_HSSACC_MUTEX_UNLOCK())
+ {
+ ICP_HSSACC_REPORT_ERROR ("icp_HssAccChannelAllocate - "
+ "failed to release HssAcc Mutex\n");
+ status = ICP_STATUS_MUTEX;
+ }
+ }
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ /* In case this channel was previously allocated and has
+ leftover stats */
+ status = icp_HssAccChannelStatsReset(channelId);
+ }
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Exiting icp_HssAccChannelAllocate\n");
+ return status;
+}
+
+
+
+
+/******************************************************************************
+ * Abstract:
+ * Configure the specified channel with the service agnostic parameters.
+ *
+ *****************************************************************************/
+icp_status_t
+icp_HssAccChannelConfigure (unsigned channelId,
+ icp_hssacc_data_polarity_t channelDataPolarity,
+ icp_hssacc_bit_endian_t channelBitEndianness,
+ icp_boolean_t channelByteSwapping,
+ icp_hssacc_bit_robbing_t rBitEnable,
+ icp_hssacc_robbed_bit_value_t rBitValue,
+ icp_hssacc_robbed_bit_location_t rBitLocation)
+{
+ icp_status_t status = ICP_STATUS_SUCCESS;
+ icp_boolean_t mutexLocked = ICP_FALSE;
+
+ ICP_HSSACC_TRACE_1 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Entering icp_HssAccChannelConfigure for channel %u\n",
+ channelId);
+
+ if (ICP_FALSE == channelConfigModuleInitialised)
+ {
+ ICP_HSSACC_REPORT_ERROR ("icp_HssAccChannelConfigure - "
+ "Service is not Initialised\n");
+ status = ICP_STATUS_FAIL;
+ }
+
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ if ((ICP_HSSACC_MAX_NUM_CHANNELS <= channelId) ||
+ ICP_HSSACC_ENUM_INVALID (channelBitEndianness,
+ ICP_HSSACC_BIT_ENDIAN_DELIMITER) ||
+ ICP_HSSACC_ENUM_INVALID (rBitEnable,
+ ICP_HSSACC_BIT_ROBBING_DELIMITER) ||
+ ICP_HSSACC_ENUM_INVALID (channelDataPolarity,
+ ICP_HSSACC_DATA_POLARITY_DELIMITER))
+ {
+ ICP_HSSACC_REPORT_ERROR ("icp_HssAccChannelConfigure - invalid "
+ "parameter\n");
+ status = ICP_STATUS_INVALID_PARAM;
+ }
+ }
+
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ if (ICP_HSSACC_BIT_ROBBING_ONE_BIT == rBitEnable)
+ {
+ if (ICP_HSSACC_CHAN_TYPE_VOICE ==
+ hssAccChannelConfig[channelId].type)
+ {
+ ICP_HSSACC_REPORT_ERROR ("icp_HssAccChannelConfigure - robbed "
+ "Bit cannot be used for a "
+ "voice channel\n");
+ status = ICP_STATUS_INVALID_PARAM;
+ }
+
+ if (ICP_HSSACC_ENUM_INVALID (rBitValue,
+ ICP_HSSACC_ROBBED_BIT_DELIMITER) ||
+ ICP_HSSACC_ENUM_INVALID (rBitLocation,
+ ICP_HSSACC_ROBBED_BIT_POS_DELIMITER))
+ {
+ ICP_HSSACC_REPORT_ERROR ("icp_HssAccChannelConfigure - invalid "
+ "robbed Bit parameter\n");
+ status = ICP_STATUS_INVALID_PARAM;
+ }
+ }
+ }
+
+
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ /* Grab the HssAcc mutex */
+ if (ICP_STATUS_SUCCESS != ICP_HSSACC_MUTEX_LOCK())
+ {
+ ICP_HSSACC_REPORT_ERROR ("icp_HssAccChannelConfigure - "
+ "failed to lock HssAcc Mutex\n");
+
+ status = ICP_STATUS_MUTEX;
+ }
+ else
+ {
+ mutexLocked = ICP_TRUE;
+ }
+ }
+
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ if (ICP_HSSACC_CHANNEL_ALLOCATED != hssAccChannelConfig[channelId].state)
+ {
+ ICP_HSSACC_REPORT_ERROR ("icp_HssAccChannelConfigure - Channel "
+ "is not in the correct state "
+ "for configuration\n");
+ status = ICP_STATUS_RESOURCE;
+ }
+ }
+
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ hssAccChannelConfig[channelId].dataPolarity = channelDataPolarity;
+ hssAccChannelConfig[channelId].bitEndian = channelBitEndianness;
+ hssAccChannelConfig[channelId].byteSwap = channelByteSwapping;
+ hssAccChannelConfig[channelId].bitRobbing = rBitEnable;
+ hssAccChannelConfig[channelId].rBitValue = rBitValue;
+ hssAccChannelConfig[channelId].rBitLocation = rBitLocation;
+ hssAccChannelConfig[channelId].state = ICP_HSSACC_CHANNEL_CONFIGURED;
+ status = HssAccChannelConfigMsgSend(channelId);
+ if (ICP_STATUS_SUCCESS != status)
+ {
+ ICP_HSSACC_REPORT_ERROR("icp_HssAccChannelConfigure - "
+ "failed to set channel configuration "
+ "in TDM I/O Unit\n");
+ hssAccChannelConfig[channelId].state = ICP_HSSACC_CHANNEL_ALLOCATED;
+ }
+ }
+
+ if (ICP_TRUE == mutexLocked)
+ {
+ if (ICP_STATUS_SUCCESS != ICP_HSSACC_MUTEX_UNLOCK())
+ {
+ ICP_HSSACC_REPORT_ERROR ("icp_HssAccChannelConfigure - "
+ "failed to release HssAcc Mutex\n");
+ status = ICP_STATUS_MUTEX;
+ }
+ }
+
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Exiting icp_HssAccChannelConfigure\n");
+ return status;
+}
+
+
+
+
+
+/******************************************************************************
+ * Abstract:
+ * Configure the HDLC service specific parameters for the
+ * specified channel.
+ *****************************************************************************/
+icp_status_t
+icp_HssAccChannelHdlcServiceConfigure (
+ unsigned channelId,
+ icp_hssacc_hdlc_crc_bit_width_t hdlcCrcBitWidth,
+ icp_hssacc_hdlc_sof_flag_type_t hdlcSofFlagType,
+ icp_hssacc_hdlc_idle_pattern_t hdlcRxIdlePattern,
+ icp_hssacc_hdlc_idle_pattern_t hdlcTxIdlePattern,
+ unsigned hdlcMaximumFrameSize)
+{
+ icp_status_t status = ICP_STATUS_SUCCESS;
+ icp_boolean_t mutexLocked = ICP_FALSE;
+ uint32_t maxHdlcServFrameSize = 0;
+
+ ICP_HSSACC_TRACE_1 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Entering icp_HssAccChannelHdlcServiceConfigure "
+ "for channel %u\n",
+ channelId);
+
+ if (ICP_FALSE == channelConfigModuleInitialised)
+ {
+ ICP_HSSACC_REPORT_ERROR ("icp_HssAccChannelHdlcServiceConfigure - "
+ "Service is not Initialised\n");
+ status = ICP_STATUS_FAIL;
+ }
+
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ if ((ICP_HSSACC_MAX_NUM_CHANNELS <= channelId) ||
+ ICP_HSSACC_ENUM_INVALID (hdlcCrcBitWidth,
+ ICP_HSSACC_HDLC_CRC_BIT_WIDTH_DELIMITER) ||
+ ICP_HSSACC_ENUM_INVALID (hdlcSofFlagType,
+ ICP_HSSACC_HDLC_SOF_FLAG_TYPE_DELIMITER) ||
+ ICP_HSSACC_ENUM_INVALID (hdlcRxIdlePattern,
+ ICP_HSSACC_HDLC_IDLE_PATTERN_DELIMITER) ||
+ ICP_HSSACC_ENUM_INVALID (hdlcTxIdlePattern,
+ ICP_HSSACC_HDLC_IDLE_PATTERN_DELIMITER))
+ {
+ ICP_HSSACC_REPORT_ERROR ("icp_HssAccChannelHdlcServiceConfigure - "
+ "invalid parameter\n");
+ status = ICP_STATUS_INVALID_PARAM;
+ }
+ }
+
+
+
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ /* Grab the HssAcc mutex */
+ if (ICP_STATUS_SUCCESS != ICP_HSSACC_MUTEX_LOCK())
+ {
+ ICP_HSSACC_REPORT_ERROR ("icp_HssAccChannelHdlcServiceConfigure - "
+ "failed to lock HssAcc Mutex\n");
+
+ status = ICP_STATUS_MUTEX;
+ }
+ else
+ {
+ mutexLocked = ICP_TRUE;
+ }
+ }
+
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ if (0 == hdlcMaximumFrameSize)
+ {
+ ICP_HSSACC_REPORT_ERROR ("icp_HssAccChannelHdlcServiceConfigure - "
+ "Maximum HDLC Frame Size cannot be zero\n");
+ status = ICP_STATUS_INVALID_PARAM;
+ }
+
+ maxHdlcServFrameSize =
+ HssAccRxDatapathMaxServiceFrameSizeGet(ICP_HSSACC_CHAN_TYPE_HDLC);
+ if (0 == maxHdlcServFrameSize)
+ {
+ ICP_HSSACC_REPORT_ERROR ("icp_HssAccChannelHdlcServiceConfigure - "
+ "Maximum HDLC Frame Size for the HDLC "
+ "Service is invalid\n");
+ status = ICP_STATUS_INVALID_PARAM;
+ }
+
+ if (hdlcMaximumFrameSize > maxHdlcServFrameSize)
+ {
+ ICP_HSSACC_REPORT_ERROR ("icp_HssAccChannelHdlcServiceConfigure - "
+ "Maximum HDLC Frame Size for this channel"
+ " is greater than that for the Service\n");
+ status = ICP_STATUS_INVALID_PARAM;
+ }
+
+
+ }
+
+
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ if (ICP_HSSACC_CHANNEL_CONFIGURED !=
+ hssAccChannelConfig[channelId].state)
+ {
+ ICP_HSSACC_REPORT_ERROR ("icp_HssAccChannelHdlcServiceConfigure - "
+ "Channel is not in the appropriate "
+ "State\n");
+ ICP_HSSACC_TRACE_1 (ICP_HSSACC_DEBUG,
+ "icp_HssAccChannelHdlcServiceConfigure - "
+ "Channel is in State (%u)\n",
+ hssAccChannelConfig[channelId].state);
+ status = ICP_STATUS_RESOURCE;
+ }
+ }
+
+
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ if (ICP_HSSACC_CHAN_TYPE_VOICE == hssAccChannelConfig[channelId].type)
+ {
+ ICP_HSSACC_REPORT_ERROR ("icp_HssAccChannelHdlcServiceConfigure - "
+ "attempting to configure HDLC Service "
+ "for an allocated Voice Channel\n");
+ status = ICP_STATUS_RESOURCE;
+ }
+ }
+
+
+ if (ICP_STATUS_SUCCESS == status)
+ {
+
+ hssAccChannelConfig[channelId].sofFlagType = hdlcSofFlagType;
+ hssAccChannelConfig[channelId].hdlcTxIdlePattern = hdlcTxIdlePattern;
+ hssAccChannelConfig[channelId].hdlcRxIdlePattern = hdlcRxIdlePattern;
+ hssAccChannelConfig[channelId].hdlcMaxFrSize = hdlcMaximumFrameSize;
+ hssAccChannelConfig[channelId].hdlcCrcBitWidth = hdlcCrcBitWidth;
+
+
+ status = HssAccChannelConfigHdlcServiceMsgSend(channelId);
+
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ status = HssAccChannelConfigHdlcMaxFrameSizeSend (channelId);
+ }
+
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ hssAccChannelConfig[channelId].state =
+ ICP_HSSACC_CHANNEL_SERVICE_CONFIGURED;
+ }
+ }
+
+ /* Free the channel configuration mutex */
+ if (ICP_TRUE == mutexLocked)
+ {
+ if (ICP_STATUS_SUCCESS != ICP_HSSACC_MUTEX_UNLOCK())
+ {
+ ICP_HSSACC_REPORT_ERROR ("icp_HssAccChannelHdlcServiceConfigure - "
+ "failed to release HssAcc Mutex\n");
+ status = ICP_STATUS_MUTEX;
+ }
+ }
+
+
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Exiting icp_HssAccChannelHdlcServiceConfigure\n");
+ return status;
+}
+
+
+
+/*****************************************************************************
+ * Abstract:
+ * Configure the Voice service specific parameters for the
+ * specified channel.
+ *
+ *****************************************************************************/
+icp_status_t
+icp_HssAccChannelVoiceServiceConfigure (
+ unsigned channelId,
+ icp_hssacc_channel_voice_tx_idle_action_t txIdleAction,
+ uint8_t voiceIdlePattern,
+ unsigned voicePacketSize)
+{
+ icp_status_t status = ICP_STATUS_SUCCESS;
+ unsigned maxAllowedPacketSize = 0;
+ icp_boolean_t mutexLocked = ICP_FALSE;
+ uint32_t maxVoiceServSampleSize = 0;
+
+ ICP_HSSACC_TRACE_1 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Entering icp_HssAccChannelVoiceServiceConfigure "
+ "for channel %u\n",
+ channelId);
+
+ if (ICP_FALSE == channelConfigModuleInitialised)
+ {
+ ICP_HSSACC_REPORT_ERROR ("icp_HssAccChannelVoiceServiceConfigure - "
+ "Service is not Initialised\n");
+ status = ICP_STATUS_FAIL;
+ }
+
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ if ((ICP_HSSACC_MAX_NUM_CHANNELS <= channelId) ||
+ ICP_HSSACC_ENUM_INVALID (txIdleAction,
+ ICP_HSSACC_VOICE_TX_IDLE_DELIMITER))
+ {
+ ICP_HSSACC_REPORT_ERROR ("icp_HssAccChannelVoiceServiceConfigure - "
+ "invalid parameter\n");
+ status = ICP_STATUS_INVALID_PARAM;
+ }
+ }
+
+ if (ICP_STATUS_SUCCESS == status)
+ {
+
+ /* Grab the HssAcc mutex */
+ if (ICP_STATUS_SUCCESS != ICP_HSSACC_MUTEX_LOCK())
+ {
+ ICP_HSSACC_REPORT_ERROR ("icp_HssAccChannelVoiceServiceConfigure - "
+ "failed to lock HssAcc Mutex\n");
+
+ status = ICP_STATUS_MUTEX;
+ }
+ else
+ {
+ mutexLocked = ICP_TRUE;
+ }
+
+ }
+
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ if (ICP_HSSACC_CHANNEL_CONFIGURED !=
+ hssAccChannelConfig[channelId].state)
+ {
+ ICP_HSSACC_REPORT_ERROR ("icp_HssAccChannelVoiceServiceConfigure -"
+ " Channel not in the appropriate state\n");
+ ICP_HSSACC_TRACE_1 (ICP_HSSACC_DEBUG,
+ "icp_HssAccChannelVoiceServiceConfigure - "
+ "Channel is in State (%u)\n",
+ hssAccChannelConfig[channelId].state);
+ status = ICP_STATUS_RESOURCE;
+ }
+ }
+
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ if (ICP_HSSACC_CHAN_TYPE_HDLC == hssAccChannelConfig[channelId].type)
+ {
+ ICP_HSSACC_REPORT_ERROR ("icp_HssAccChannelVoiceServiceConfigure - "
+ "attempting to configure Voice Service "
+ "for an allocated HDLC Channel\n");
+ status = ICP_STATUS_RESOURCE;
+ }
+ }
+
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ switch (hssAccChannelConfig[channelId].size)
+ {
+ case ICP_HSSACC_VOICE_NB_CHAN_SIZE:
+ maxAllowedPacketSize = ICP_HSSACC_VOICE_NB_MAX_SAMPLE_SIZE;
+ break;
+ case ICP_HSSACC_VOICE_NBL_CHAN_SIZE:
+ maxAllowedPacketSize = ICP_HSSACC_VOICE_NBL_MAX_SAMPLE_SIZE;
+ break;
+ case ICP_HSSACC_VOICE_WB_CHAN_SIZE:
+ maxAllowedPacketSize = ICP_HSSACC_VOICE_WB_MAX_SAMPLE_SIZE;
+ break;
+ case ICP_HSSACC_VOICE_UWB_CHAN_SIZE:
+ maxAllowedPacketSize = ICP_HSSACC_VOICE_UWB_MAX_SAMPLE_SIZE;
+ break;
+ default:
+ /* unreachable due to verification in Allocation function */
+ break;
+ }
+ }
+
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ if (maxAllowedPacketSize < voicePacketSize)
+ {
+ ICP_HSSACC_REPORT_ERROR_2 ("icp_HssAccChannelVoiceServiceConfigure -"
+ " Voice Sample Size (%u) too large for "
+ "channel (max Allowed is %u)\n",
+ voicePacketSize,
+ maxAllowedPacketSize);
+ status = ICP_STATUS_INVALID_PARAM;
+ }
+ if (0 == voicePacketSize)
+ {
+ ICP_HSSACC_REPORT_ERROR ("icp_HssAccChannelVoiceServiceConfigure -"
+ " Voice Sample Size cannot be zero\n");
+ status = ICP_STATUS_INVALID_PARAM;
+ }
+ maxVoiceServSampleSize =
+ HssAccRxDatapathMaxServiceFrameSizeGet(ICP_HSSACC_CHAN_TYPE_VOICE);
+ if (0 == maxVoiceServSampleSize)
+ {
+ ICP_HSSACC_REPORT_ERROR ("icp_HssAccChannelVoiceServiceConfigure - "
+ "Maximum Voice Sample Size for the Voice "
+ "Service is invalid\n");
+ status = ICP_STATUS_INVALID_PARAM;
+ }
+
+ if (voicePacketSize > maxVoiceServSampleSize)
+ {
+ ICP_HSSACC_REPORT_ERROR ("icp_HssAccChannelVoiceServiceConfigure - "
+ "Maximum Voice Sample Size for this channel"
+ " is greater than that for the Service\n");
+ status = ICP_STATUS_INVALID_PARAM;
+ }
+
+ }
+
+
+ if (ICP_STATUS_SUCCESS == status)
+ {
+
+ hssAccChannelConfig[channelId].voiceSampleSize = voicePacketSize;
+ hssAccChannelConfig[channelId].voiceIdlePattern = voiceIdlePattern;
+ hssAccChannelConfig[channelId].txIdleAction = txIdleAction;
+ hssAccChannelConfig[channelId].numBypasses = 0;
+
+ status = HssAccChannelConfigVoiceServiceMsgSend (channelId);
+
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ hssAccChannelConfig[channelId].state =
+ ICP_HSSACC_CHANNEL_SERVICE_CONFIGURED;
+ }
+ }
+ if (ICP_TRUE == mutexLocked)
+ {
+ if (ICP_STATUS_SUCCESS != ICP_HSSACC_MUTEX_UNLOCK())
+ {
+ ICP_HSSACC_REPORT_ERROR ("icp_HssAccChannelVoiceServiceConfigure - "
+ "failed to release HssAcc Mutex\n");
+ status = ICP_STATUS_MUTEX;
+ }
+ }
+
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Exiting icp_HssAccChannelVoiceServiceConfigure\n");
+ return status;
+}
+
+
+
+
+
+
+/*****************************************************************************
+ * Abstract:
+ * Bring the specified channel UP, this will enable traffic flow on the
+ * channel.
+ *
+ *****************************************************************************/
+icp_status_t
+icp_HssAccChannelUp (unsigned channelId)
+{
+ icp_status_t status = ICP_STATUS_SUCCESS;
+ IxPiuMhMessage message;
+ icp_boolean_t mutexLocked = ICP_FALSE;
+ ICP_HSSACC_TRACE_1 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Entering icp_HssAccChannelUp for channel %u\n",
+ channelId);
+ if (ICP_FALSE == channelConfigModuleInitialised)
+ {
+ ICP_HSSACC_REPORT_ERROR ("icp_HssAccChannelUp - "
+ "Service is not Initialised\n");
+ status = ICP_STATUS_FAIL;
+ }
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ if (ICP_HSSACC_MAX_NUM_CHANNELS <= channelId)
+ {
+ ICP_HSSACC_REPORT_ERROR ("icp_HssAccChannelUp - invalid "
+ "channel Number\n");
+ status = ICP_STATUS_INVALID_PARAM;
+ }
+ }
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ if ((ICP_HSSACC_CHANNEL_SERVICE_CONFIGURED !=
+ hssAccChannelConfig[channelId].state) &&
+ (ICP_HSSACC_CHANNEL_DOWN !=
+ hssAccChannelConfig[channelId].state))
+
+ {
+ ICP_HSSACC_REPORT_ERROR_1 ("icp_HssAccChannelUp - channel %u "
+ "is not in an appropriate state "
+ "for enabling\n",
+ channelId);
+ ICP_HSSACC_TRACE_2 (ICP_HSSACC_DEBUG,
+ "icp_HssAccChannelUp - channel %u "
+ "is state (%u) for enabling\n",
+ channelId,
+ hssAccChannelConfig[channelId].state);
+ status = ICP_STATUS_RESOURCE;
+ }
+ }
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ /* Grab the HssAcc mutex */
+ if (ICP_STATUS_SUCCESS != ICP_HSSACC_MUTEX_LOCK())
+ {
+ ICP_HSSACC_REPORT_ERROR ("icp_HssAccChannelUp - "
+ "failed to lock HssAcc Mutex\n");
+
+ status = ICP_STATUS_MUTEX;
+ }
+ }
+
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ mutexLocked = ICP_TRUE;
+
+ /* Construct the message to load the table */
+ HssAccComTdmIOUnitCmd8byteMsgCreate (
+ ICP_HSSACC_TDM_IO_UNIT_CHAN_FLOW_ENABLE,
+ channelId,
+ ICP_HSSACC_TDM_IO_UNIT_FLOW_DIR_BOTH,
+ 0, 0, 0, 0, 0,
+ &message);
+ /* Send the message to the TDM I/O Unit and wait for its reply */
+ status = HssAccComTdmIOUnitMsgSendAndRecv(
+ message,
+ ICP_HSSACC_TDM_IO_UNIT_CHAN_FLOW_ENABLE_RESPONSE,
+ &(hssAccChanCfgStats.chanEnable),
+ NULL);
+
+
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ hssAccChannelConfig[channelId].state = ICP_HSSACC_CHANNEL_ENABLED;
+ }
+ }
+
+ /* Free the HssAcc mutex */
+ if (ICP_TRUE == mutexLocked)
+ {
+ if (ICP_STATUS_SUCCESS != ICP_HSSACC_MUTEX_UNLOCK())
+ {
+ ICP_HSSACC_REPORT_ERROR ("icp_HssAccChannelUp - "
+ "failed to release HssAcc Mutex\n");
+ status = ICP_STATUS_MUTEX;
+ }
+ }
+
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Exiting icp_HssAccChannelUp\n");
+ return status;
+}
+
+
+
+/*****************************************************************************
+ * Abstract:
+ * Bring down the specified channel. this will stop all traffic on
+ * that channel.
+ *
+ *****************************************************************************/
+icp_status_t
+icp_HssAccChannelDown (unsigned channelId)
+{
+ icp_status_t status = ICP_STATUS_SUCCESS;
+ IxPiuMhMessage message;
+ icp_boolean_t mutexLocked = ICP_FALSE;
+ ICP_HSSACC_TRACE_1 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Entering icp_HssAccChannelDown for channel %u\n",
+ channelId);
+ if (ICP_FALSE == channelConfigModuleInitialised)
+ {
+ ICP_HSSACC_REPORT_ERROR ("icp_HssAccChannelDown - "
+ "Service is not Initialised\n");
+ status = ICP_STATUS_FAIL;
+ }
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ if (ICP_HSSACC_MAX_NUM_CHANNELS <= channelId)
+ {
+ ICP_HSSACC_REPORT_ERROR ("icp_HssAccChannelDown - invalid "
+ "channel\n");
+ status = ICP_STATUS_INVALID_PARAM;
+ }
+ }
+ if (ICP_STATUS_SUCCESS == status)
+ {
+
+ /* Grab the HssAcc mutex */
+ if (ICP_STATUS_SUCCESS != ICP_HSSACC_MUTEX_LOCK())
+ {
+ ICP_HSSACC_REPORT_ERROR ("icp_HssAccChannelDown - "
+ "failed to lock HssAcc Mutex\n");
+
+ status = ICP_STATUS_MUTEX;
+ }
+ else
+ {
+ mutexLocked = ICP_TRUE;
+ }
+
+ }
+
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ if (ICP_HSSACC_CHANNEL_ENABLED != hssAccChannelConfig[channelId].state)
+ {
+ ICP_HSSACC_REPORT_ERROR_1 ("icp_HssAccChannelDown - "
+ "channel %u is not enabled\n",
+ channelId);
+ status = ICP_STATUS_RESOURCE;
+ }
+ }
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ if (0 != hssAccChannelConfig[channelId].numBypasses)
+ {
+ ICP_HSSACC_REPORT_ERROR ("icp_HssAccChannelDown - channel is "
+ "used as part of a bypass, "
+ "disable bypass first\n");
+ status = ICP_STATUS_RESOURCE;
+ }
+ }
+
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ /* change the channel state so that the datapath puts
+ rx buffers onto the rx free queue and not into the
+ channel ring */
+ hssAccChannelConfig[channelId].state =
+ ICP_HSSACC_CHANNEL_DOWN_TRANSITION;
+
+ /* Construct the message to load the table */
+ HssAccComTdmIOUnitCmd8byteMsgCreate (
+ ICP_HSSACC_TDM_IO_UNIT_CHAN_FLOW_DISABLE,
+ channelId,
+ ICP_HSSACC_TDM_IO_UNIT_FLOW_DIR_BOTH,
+ 0, 0, 0, 0, 0,
+ &message);
+
+ /* Send the message to the TDM I/O Unit and wait for its reply */
+ status =
+ HssAccComTdmIOUnitMsgSendAndRecv(
+ message,
+ ICP_HSSACC_TDM_IO_UNIT_CHAN_FLOW_DISABLE_RESPONSE,
+ &(hssAccChanCfgStats.chanDisable),
+ NULL);
+
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ hssAccChannelConfig[channelId].state =
+ ICP_HSSACC_CHANNEL_DOWN;
+ }
+ else
+ {
+ /* restore state to enabled as the channel down failed */
+ hssAccChannelConfig[channelId].state =
+ ICP_HSSACC_CHANNEL_ENABLED;
+ }
+ }
+
+ /* Free the HssAcc mutex */
+ if (ICP_TRUE == mutexLocked)
+ {
+ if (ICP_STATUS_SUCCESS != ICP_HSSACC_MUTEX_UNLOCK())
+ {
+ ICP_HSSACC_REPORT_ERROR ("icp_HssAccChannelDown - "
+ "failed to release HssAcc Mutex\n");
+ status = ICP_STATUS_MUTEX;
+ }
+ }
+
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Exiting icp_HssAccChannelDown\n");
+ return status;
+}
+
+
+
+
+
+
+
+/*****************************************************************************
+ * Abstract:
+ * Delete the specified Channel.
+ *
+ *****************************************************************************/
+icp_status_t
+icp_HssAccChannelDelete (unsigned channelId)
+{
+ icp_status_t status = ICP_STATUS_SUCCESS;
+ icp_boolean_t mutexLocked = ICP_FALSE;
+ ICP_HSSACC_TRACE_1 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Entering icp_HssAccChannelDelete for channel %u\n",
+ channelId);
+
+ if (ICP_FALSE == channelConfigModuleInitialised)
+ {
+ ICP_HSSACC_REPORT_ERROR ("icp_HssAccChannelDelete - "
+ "Service is not Initialised\n");
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Exiting icp_HssAccChannelDelete\n");
+ return ICP_STATUS_FAIL;
+ }
+
+ if (ICP_HSSACC_MAX_NUM_CHANNELS <= channelId)
+ {
+ ICP_HSSACC_REPORT_ERROR ("icp_HssAccChannelDelete - invalid "
+ "channel\n");
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Exiting icp_HssAccChannelDelete\n");
+ return ICP_STATUS_INVALID_PARAM;
+ }
+
+
+ if (ICP_STATUS_SUCCESS != ICP_HSSACC_MUTEX_LOCK())
+ {
+ ICP_HSSACC_REPORT_ERROR ("icp_HssAccChannelDelete - "
+ "failed to lock HssAcc Mutex\n");
+
+ status = ICP_STATUS_MUTEX;
+ }
+ else
+ {
+ mutexLocked = ICP_TRUE;
+ }
+
+
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ if (!((ICP_HSSACC_CHANNEL_CONFIGURED ==
+ hssAccChannelConfig[channelId].state) ||
+ (ICP_HSSACC_CHANNEL_SERVICE_CONFIGURED ==
+ hssAccChannelConfig[channelId].state) ||
+ (ICP_HSSACC_CHANNEL_ALLOCATED ==
+ hssAccChannelConfig[channelId].state)))
+ {
+ ICP_HSSACC_REPORT_ERROR ("icp_HssAccChannelDelete - channel "
+ "not available for deletion\n");
+ status = ICP_STATUS_RESOURCE;
+ }
+ }
+ if (ICP_STATUS_SUCCESS == status)
+ {
+
+ status = HssAccChannelListRemove(hssAccChannelConfig[channelId].portId,
+ channelId,
+ hssAccChannelConfig[channelId].size);
+ }
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ /* Reset config, may have to actually send message to the
+ TDM I/O Unit to completely remove conf */
+ HssAccTsUnregister (hssAccChannelConfig[channelId].portId,
+ hssAccChannelConfig[channelId].lineId,
+ hssAccChannelConfig[channelId].timeslotMap);
+
+ /* Clear the timeslot allocation but keep the port, we
+ need it for generating the new tables */
+ hssAccChannelConfig[channelId].lineId = ICP_HSSACC_LINE_DELIMITER;
+ hssAccChannelConfig[channelId].timeslotMap = 0;
+ hssAccChannelConfig[channelId].size = 0;
+
+ /* Clear Timeslot Allocation for this channel */
+ status = HssAccTsAllocDelete(channelId,
+ hssAccChannelConfig);
+
+ /* Deregister rx callback */
+ HssAccChannelRxCallbackDeregister(channelId);
+
+ /* Deregister tx callback */
+ HssAccTxDatapathChanTxDoneCallbackDeregister(channelId);
+
+ }
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ hssAccNumChansAllocated --;
+
+ /* Clear the internal state */
+ HssAccChannelConfigStateReset(channelId);
+ }
+
+ /* Free the HssAcc mutex */
+ if (ICP_TRUE == mutexLocked)
+ {
+ if (ICP_STATUS_SUCCESS != ICP_HSSACC_MUTEX_UNLOCK())
+ {
+ ICP_HSSACC_REPORT_ERROR ("icp_HssAccChannelDelete - "
+ "failed to release HssAcc Mutex\n");
+ status = ICP_STATUS_MUTEX;
+ }
+ }
+
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Exiting icp_HssAccChannelDelete\n");
+ return status;
+}
+
+/*****************************************************************************
+ * Abstract:
+ * Sends the channel Common Configuration message to the TDM I/O Unit.
+ *
+ *****************************************************************************/
+TDM_PRIVATE icp_status_t
+HssAccChannelConfigMsgSend (unsigned channelId)
+{
+ icp_status_t status = ICP_STATUS_SUCCESS;
+ IxPiuMhMessage message;
+ uint16_t sdcCtrl = 0;
+ uint8_t sdcCtrlMsB = 0;
+ uint8_t sdcCtrlLsB = 0;
+ uint32_t inversion = ICP_HSSACC_TDM_IO_UNIT_SDC_BIT_INVERT_OFF;
+ uint8_t channelType = 0;
+ uint8_t bitReverse = ICP_HSSACC_TDM_IO_UNIT_SDC_BIT_NO_REVERSE;
+ uint8_t byteSwap = ICP_HSSACC_TDM_IO_UNIT_SDC_BYTE_NO_SWAP;
+ uint8_t bitRobbing = ICP_HSSACC_TDM_IO_UNIT_SDC_RBIT_OFF;
+ uint8_t rBitValue = ICP_HSSACC_TDM_IO_UNIT_SDC_RBIT_VALUE_ZERO;
+ uint8_t rBitLocation = ICP_HSSACC_TDM_IO_UNIT_SDC_RBIT_LOC_SEVEN;
+
+ ICP_HSSACC_TRACE_1 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Entering HssAccChannelConfigMsgSend for channel %u\n",
+ channelId);
+ /* Build SDC Ctrl Register for the TDM I/O Unit */
+ if (ICP_HSSACC_DATA_POLARITY_INVERT ==
+ hssAccChannelConfig[channelId].dataPolarity)
+ {
+ inversion = ICP_HSSACC_TDM_IO_UNIT_SDC_BIT_INVERT_ON;
+ }
+
+ if (ICP_HSSACC_CHAN_TYPE_VOICE == hssAccChannelConfig[channelId].type)
+ {
+ channelType = ICP_HSSACC_TDM_IO_UNIT_SDC_CHAN_TYPE_VOICE;
+ }
+ else
+ {
+ channelType = ICP_HSSACC_TDM_IO_UNIT_SDC_CHAN_TYPE_HDLC;
+ }
+
+ /* if channel endianness is LSB then bit reversion required */
+ if (ICP_HSSACC_BIT_ENDIAN_LSB == hssAccChannelConfig[channelId].bitEndian)
+ {
+ bitReverse = ICP_HSSACC_TDM_IO_UNIT_SDC_BIT_REVERSE;
+ }
+
+ if (ICP_TRUE == hssAccChannelConfig[channelId].byteSwap)
+ {
+ byteSwap = ICP_HSSACC_TDM_IO_UNIT_SDC_BYTE_SWAP;
+ }
+
+ if (ICP_HSSACC_BIT_ROBBING_ONE_BIT ==
+ hssAccChannelConfig[channelId].bitRobbing)
+ {
+ bitRobbing = ICP_HSSACC_TDM_IO_UNIT_SDC_RBIT_ONE_BIT_ON;
+ }
+
+ if (ICP_HSSACC_ROBBED_BIT_ONE == hssAccChannelConfig[channelId].rBitValue)
+ {
+ rBitValue = ICP_HSSACC_TDM_IO_UNIT_SDC_RBIT_VALUE_ONE;
+ }
+
+ if (ICP_HSSACC_ROBBED_BIT_POS_0 ==
+ hssAccChannelConfig[channelId].rBitLocation)
+ {
+ rBitLocation = ICP_HSSACC_TDM_IO_UNIT_SDC_RBIT_LOC_ZERO;
+ }
+
+ sdcCtrl = (bitRobbing <<
+ ICP_HSSACC_TDM_IO_UNIT_SDC_BIT_ROBBING_OFFSET) |
+ (rBitLocation <<
+ ICP_HSSACC_TDM_IO_UNIT_SDC_RBIT_LOC_OFFSET) |
+ (rBitValue <<
+ ICP_HSSACC_TDM_IO_UNIT_SDC_RBIT_VAL_OFFSET) |
+ (inversion << ICP_HSSACC_TDM_IO_UNIT_SDC_INVERT_OFFSET) |
+ (channelType << ICP_HSSACC_TDM_IO_UNIT_SDC_CHAN_TYPE_OFFSET) |
+ (bitReverse << ICP_HSSACC_TDM_IO_UNIT_SDC_BIT_REVERSE_OFFSET) |
+ (byteSwap << ICP_HSSACC_TDM_IO_UNIT_SDC_BYTE_SWAP_OFFSET);
+ ICP_HSSACC_TRACE_1(ICP_HSSACC_DEBUG,
+ "Created SDC Ctrl Register 0x%04X\n",
+ sdcCtrl);
+
+ sdcCtrlMsB = (sdcCtrl & ICP_HSSACC_TDM_IO_UNIT_SDC_CTRL_MSB_MASK) >>
+ ICP_HSSACC_TDM_IO_UNIT_SDC_CTRL_MSB_OFFSET;
+
+ sdcCtrlLsB = sdcCtrl & ICP_HSSACC_TDM_IO_UNIT_SDC_CTRL_LSB_MASK;
+ /* Construct the message to load the table */
+ HssAccComTdmIOUnitCmd8byteMsgCreate (ICP_HSSACC_TDM_IO_UNIT_HSS_CHAN_CFG,
+ channelId,
+ hssAccChannelConfig[channelId].type,
+ hssAccChannelConfig[channelId].size,
+ sdcCtrlMsB,
+ sdcCtrlLsB,
+ 0,
+ 0,
+ &message);
+
+ /* Send the message to the TDM I/O Unit and wait for its reply */
+ status = HssAccComTdmIOUnitMsgSendAndRecv(
+ message,
+ ICP_HSSACC_TDM_IO_UNIT_HSS_CHAN_CFG_RESPONSE,
+ &(hssAccChanCfgStats.chanCfg),
+ NULL);
+
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Exiting HssAccChannelConfigMsgSend\n");
+ return status;
+}
+
+
+
+
+/*****************************************************************************
+ * Abstract:
+ * Create the Transmit HDLC configuration register to be passed to the
+ * TDM I/O Unit.
+ *
+ *****************************************************************************/
+TDM_PRIVATE uint8_t
+HssAccChannelHdlcTxCfgRegCreate (unsigned channelId)
+{
+ uint8_t cfgReg = 0;
+ /* will always post tx-hdlc block bit flip in SDC co-proc */
+ uint8_t bitFlip = ICP_HSSACC_TDM_IO_UNIT_HDLC_CFG_BIT_FLIP;
+ uint8_t sofFlagType = ICP_HSSACC_TDM_IO_UNIT_HDLC_SOF_SHARED;
+ uint8_t hdlcCrcBitWidth = ICP_HSSACC_TDM_IO_UNIT_HDLC_16_BIT_CRC;
+ uint8_t hdlcTxIdlePattern = ICP_HSSACC_TDM_IO_UNIT_HDLC_IDLE_FLAG;
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Entering HssAccChannelHdlcTxCfgRegCreate\n");
+
+ if (ICP_HSSACC_HDLC_IDLE_PATTERN_ONES ==
+ hssAccChannelConfig[channelId].hdlcTxIdlePattern)
+ {
+ hdlcTxIdlePattern = ICP_HSSACC_TDM_IO_UNIT_HDLC_IDLE_ONES;
+ }
+
+ if (ICP_HSSACC_HDLC_CRC_BIT_WIDTH_32 ==
+ hssAccChannelConfig[channelId].hdlcCrcBitWidth)
+ {
+ hdlcCrcBitWidth = ICP_HSSACC_TDM_IO_UNIT_HDLC_32_BIT_CRC;
+ }
+ if (ICP_HSSACC_HDLC_SOF_ONE_FLAG ==
+ hssAccChannelConfig[channelId].sofFlagType)
+ {
+ sofFlagType = ICP_HSSACC_TDM_IO_UNIT_HDLC_SOF_ONE;
+ }
+ else if (ICP_HSSACC_HDLC_SOF_TWO_FLAGS ==
+ hssAccChannelConfig[channelId].sofFlagType)
+ {
+ sofFlagType = ICP_HSSACC_TDM_IO_UNIT_HDLC_SOF_TWO;
+ }
+
+ cfgReg =
+ (sofFlagType <<
+ ICP_HSSACC_TDM_IO_UNIT_HDLC_TX_CFG_SF_OFFSET) |
+ (hdlcCrcBitWidth <<
+ ICP_HSSACC_TDM_IO_UNIT_HDLC_TX_CFG_FCS_OFFSET) |
+ (hdlcTxIdlePattern <<
+ ICP_HSSACC_TDM_IO_UNIT_HDLC_TX_CFG_IM_OFFSET) |
+ (bitFlip <<
+ ICP_HSSACC_TDM_IO_UNIT_HDLC_TX_CFG_POSTBF_OFFSET);
+
+ ICP_HSSACC_TRACE_1 (ICP_HSSACC_DEBUG,
+ "HssAccChannelHdlcTxCfgRegCreate 0x%02X\n",
+ cfgReg);
+
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Exiting HssAccChannelHdlcTxCfgRegCreate\n");
+ return cfgReg;
+}
+
+/*****************************************************************************
+ * Abstract:
+ * Create the Receive HDLC configuration register to be passed to the
+ * TDM I/O Unit.
+ *
+ *****************************************************************************/
+TDM_PRIVATE uint8_t
+HssAccChannelHdlcRxCfgRegCreate (unsigned channelId)
+{
+ uint8_t cfgReg = 0;
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Entering HssAccChannelHdlcRxCfgRegCreate\n");
+
+
+ cfgReg =
+ (hssAccChannelConfig[channelId].hdlcCrcBitWidth <<
+ ICP_HSSACC_TDM_IO_UNIT_HDLC_RX_CFG_FCS_OFFSET) |
+ (hssAccChannelConfig[channelId].hdlcRxIdlePattern <<
+ ICP_HSSACC_TDM_IO_UNIT_HDLC_RX_CFG_IM_OFFSET);
+
+ /* always pre rx-hdlc block bit flip in SDC co-proc */
+ cfgReg |= (ICP_HSSACC_TDM_IO_UNIT_HDLC_CFG_BIT_FLIP <<
+ ICP_HSSACC_TDM_IO_UNIT_HDLC_RX_CFG_PREBF_OFFSET);
+
+ ICP_HSSACC_TRACE_1 (ICP_HSSACC_DEBUG,
+ "HssAccChannelHdlcRxCfgRegCreate 0x%02X\n", cfgReg);
+
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Exiting HssAccChannelHdlcRxCfgRegCreate\n");
+ return cfgReg;
+}
+
+
+
+/*****************************************************************************
+ * Abstract:
+ * Sends the channel HDLC Service Configuration message to
+ * the TDM I/O Unit
+ *****************************************************************************/
+TDM_PRIVATE icp_status_t
+HssAccChannelConfigHdlcServiceMsgSend (unsigned channelId)
+{
+ icp_status_t status = ICP_STATUS_SUCCESS;
+ IxPiuMhMessage message;
+ uint32_t fcsSizeB = ICP_HSSACC_FCS_4_BYTE_WIDTH;
+ uint8_t txCfg = 0, rxCfg = 0;
+ ICP_HSSACC_TRACE_1 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Entering HssAccChannelConfigHdlcServiceMsgSend "
+ "for channel %u\n",
+ channelId);
+
+ if (ICP_HSSACC_HDLC_CRC_BIT_WIDTH_16 ==
+ hssAccChannelConfig[channelId].hdlcCrcBitWidth)
+ {
+ fcsSizeB = ICP_HSSACC_FCS_2_BYTE_WIDTH;
+ }
+
+
+ /* Construct the TxCfg and RxCfg registers for the TDM I/O Unit */
+ txCfg = HssAccChannelHdlcTxCfgRegCreate(channelId);
+
+ rxCfg = HssAccChannelHdlcRxCfgRegCreate(channelId);
+
+ /* Construct the message to load the table */
+ HssAccComTdmIOUnitCmd8byteMsgCreate (ICP_HSSACC_TDM_IO_UNIT_HDLC_CHAN_CFG,
+ channelId,
+ 0,
+ 0,
+ 0,
+ rxCfg,
+ txCfg,
+ fcsSizeB,
+ &message);
+
+ /* Send the message to the TDM I/O Unit and wait for its reply */
+ status = HssAccComTdmIOUnitMsgSendAndRecv(
+ message,
+ ICP_HSSACC_TDM_IO_UNIT_HDLC_CHAN_CFG_RESPONSE,
+ &(hssAccChanCfgStats.hdlcChanCfg),
+ NULL);
+
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Exiting HssAccChannelConfigHdlcServiceMsgSend\n");
+ return status;
+}
+
+
+
+
+
+/*****************************************************************************
+ * Abstract:
+ * Sends the channel HDLC Maximum Receive Frame Size configuration message
+ * to the TDM I/O Unit.
+ *****************************************************************************/
+TDM_PRIVATE icp_status_t
+HssAccChannelConfigHdlcMaxFrameSizeSend (unsigned channelId)
+{
+ icp_status_t status = ICP_STATUS_SUCCESS;
+ IxPiuMhMessage message;
+ uint32_t hdlcMaximumFrameSize = 0;
+ ICP_HSSACC_TRACE_1 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Entering HssAccChannelConfigHdlcMaxFrameSizeSend "
+ "for channel %u\n",
+ channelId);
+
+ hdlcMaximumFrameSize =
+ hssAccChannelConfig[channelId].hdlcMaxFrSize <<
+ ICP_HSSACC_TDM_IO_UNIT_SHORT0_OFFSET;
+
+ /* Construct the message to load the table */
+ HssAccComTdmIOUnitCmd4byte1wordMsgCreate (
+ ICP_HSSACC_TDM_IO_UNIT_HDLC_CHAN_RX_MAX_SIZE_WR,
+ channelId,
+ 0,
+ 0,
+ hdlcMaximumFrameSize,
+ &message);
+
+ /* Send the message to the TDM I/O Unit and wait for its reply */
+ status = HssAccComTdmIOUnitMsgSendAndRecv(
+ message,
+ ICP_HSSACC_TDM_IO_UNIT_HDLC_CHAN_RX_MAX_SIZE_WR_RESPONSE,
+ &(hssAccChanCfgStats.hdlcMaxRxCfg),
+ NULL);
+
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Exiting HssAccChannelConfigHdlcMaxFrameSizeSend\n");
+ return status;
+}
+
+
+/*****************************************************************************
+ * Abstract:
+ * Sends the channel Voice Service Configuration message to
+ * the TDM I/O Unit
+ *****************************************************************************/
+TDM_PRIVATE icp_status_t
+HssAccChannelConfigVoiceServiceMsgSend (unsigned channelId)
+{
+ icp_status_t status = ICP_STATUS_SUCCESS;
+ IxPiuMhMessage message;
+ uint32_t msgWord = 0;
+ ICP_HSSACC_TRACE_1 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Entering HssAccChannelConfigVoiceServiceMsgSend "
+ "for channel %u\n",
+ channelId);
+ msgWord =
+ (hssAccChannelConfig[channelId].voiceIdlePattern <<
+ ICP_HSSACC_TDM_IO_UNIT_BYTE0_OFFSET) |
+ (hssAccChannelConfig[channelId].txIdleAction <<
+ ICP_HSSACC_TDM_IO_UNIT_BYTE1_OFFSET) |
+ hssAccChannelConfig[channelId].voiceSampleSize;
+
+ /* Construct the message for Channel Voice parameters setting
+ in the TDM I/O Unit */
+ HssAccComTdmIOUnitCmd4byte1wordMsgCreate (
+ ICP_HSSACC_TDM_IO_UNIT_VOICE_CHAN_CFG,
+ channelId,
+ 0,
+ 0,
+ msgWord,
+ &message);
+
+ /* Send the message to the TDM I/O Unit and wait for its reply */
+ status = HssAccComTdmIOUnitMsgSendAndRecv(
+ message,
+ ICP_HSSACC_TDM_IO_UNIT_VOICE_CHAN_CFG_RESPONSE,
+ &(hssAccChanCfgStats.voiceChanCfg),
+ NULL);
+
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Exiting HssAccChannelConfigVoiceServiceMsgSend\n");
+ return status;
+}
+
+
+
+
+
+
+/*****************************************************************************
+ * Abstract:
+ * determines if it is valid to configure a bypass using the
+ * specified channel.
+ *
+ *****************************************************************************/
+icp_boolean_t
+HssAccChannelConfigValidBypass(const unsigned channelId,
+ const unsigned portId)
+{
+ icp_boolean_t validChannel = ICP_FALSE;
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Entering HssAccChannelConfigValidBypass\n");
+
+
+ ICP_HSSACC_TRACE_3 (ICP_HSSACC_DEBUG,
+ "HssAccChannelConfigValidBypass - "
+ "Channel %u of size %u and state %u "
+ "selected for Bypass\n",
+ channelId,
+ hssAccChannelConfig[channelId].size,
+ hssAccChannelConfig[channelId].state);
+
+ if ((ICP_HSSACC_CHAN_TYPE_VOICE == hssAccChannelConfig[channelId].type) &&
+ (ICP_HSSACC_VOICE_NB_CHAN_SIZE == hssAccChannelConfig[channelId].size) &&
+ (ICP_HSSACC_CHANNEL_ENABLED == hssAccChannelConfig[channelId].state) &&
+ (portId == hssAccChannelConfig[channelId].portId))
+ {
+ validChannel = ICP_TRUE;
+ }
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Exiting HssAccChannelConfigValidBypass\n");
+ return validChannel;
+}
+
+
+
+/*****************************************************************************
+ * Abstract:
+ * reset the Channel configuration stats
+ *
+ *****************************************************************************/
+void
+HssAccChannelConfigStatsReset (void)
+{
+ memset (&hssAccChanCfgStats, 0, sizeof(icp_hssacc_channel_config_stats_t));
+ HssAccChannelListsStatsReset ();
+
+}
+
+/*****************************************************************************
+ * Abstract:
+ * Display stats for channel configuration
+ *
+ *****************************************************************************/
+void
+HssAccChannelConfigStatsShow (void)
+{
+ ixOsalLog(IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT,
+ "\nChannel Configuration Statistics:\nChannel Config messaging\n",
+ 0, 0, 0, 0, 0, 0);
+ HssAccSingleMessageStatsShow (hssAccChanCfgStats.chanCfg);
+ ixOsalLog(IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT,
+ "\nHDLC Channel Config messaging\n",
+ 0, 0, 0, 0, 0, 0);
+ HssAccSingleMessageStatsShow (hssAccChanCfgStats.hdlcChanCfg);
+ ixOsalLog(IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT,
+ "\nVoice Channel Config messaging\n",
+ 0, 0, 0, 0, 0, 0);
+ HssAccSingleMessageStatsShow (hssAccChanCfgStats.voiceChanCfg);
+ ixOsalLog(IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT,
+ "\noffset Table Load\n",
+ 0, 0, 0, 0, 0, 0);
+ HssAccSingleMessageStatsShow (hssAccChanCfgStats.offsetTableLoad);
+ ixOsalLog(IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT,
+ "\nHDLC Max Receive Frame Size Cfg messaging\n",
+ 0, 0, 0, 0, 0, 0);
+ HssAccSingleMessageStatsShow (hssAccChanCfgStats.hdlcMaxRxCfg);
+ ixOsalLog(IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT,
+ "\nChannel Enable messaging\n",
+ 0, 0, 0, 0, 0, 0);
+ HssAccSingleMessageStatsShow (hssAccChanCfgStats.chanEnable);
+ ixOsalLog(IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT,
+ "\nChannel Disable messaging\n",
+ 0, 0, 0, 0, 0, 0);
+ HssAccSingleMessageStatsShow (hssAccChanCfgStats.chanDisable);
+
+ /* Also print out the Timeslot Allocation submodule stats */
+ HssAccTsAllocStatsShow ();
+
+}
+
+
+/*****************************************************************************
+ * Abstract:
+ * display the state of the specified channel
+ *
+ *****************************************************************************/
+void
+HssAccChannelConfigStateShow (unsigned channelId)
+{
+ if (ICP_HSSACC_CHANNEL_UNINITIALISED ==
+ hssAccChannelConfig[channelId].state)
+ {
+ ixOsalLog(IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT,
+ "\nChannel %u is Uninitialised.\n",
+ channelId, 0, 0, 0, 0, 0);
+ }
+ else
+ {
+ ixOsalLog(IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT,
+ "\nChannel %u is Allocated on port %u Line %u with "
+ "%u Timeslots\nTimeslot Map is 0x%08X\n",
+ channelId,
+ hssAccChannelConfig[channelId].portId,
+ hssAccChannelConfig[channelId].lineId,
+ hssAccChannelConfig[channelId].size,
+ hssAccChannelConfig[channelId].timeslotMap, 0);
+
+ ixOsalLog(IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT,
+ "Channel has been Configured with:\n"
+ "\tData Inversion %u\n"
+ "\tBit Endianness %u\n"
+ "\tByte Endianness %u\n",
+ hssAccChannelConfig[channelId].dataPolarity,
+ hssAccChannelConfig[channelId].bitEndian,
+ hssAccChannelConfig[channelId].byteSwap, 0, 0, 0);
+ if (ICP_HSSACC_BIT_ROBBING_ONE_BIT ==
+ hssAccChannelConfig[channelId].bitRobbing)
+ {
+ ixOsalLog(IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT,
+ "Bit Robbing is Enabled with a value of %u and "
+ "a position of %d\n",
+ hssAccChannelConfig[channelId].rBitValue,
+ hssAccChannelConfig[channelId].rBitLocation ==
+ ICP_HSSACC_ROBBED_BIT_POS_7 ? 7
+ : (hssAccChannelConfig[channelId].rBitLocation ==
+ ICP_HSSACC_ROBBED_BIT_POS_0 ? 0 : -1),
+ 0, 0, 0, 0);
+ }
+
+ if (ICP_HSSACC_CHAN_TYPE_VOICE == hssAccChannelConfig[channelId].type)
+ {
+ ixOsalLog(IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT,
+ "Channel is Allocated for Voice\n", 0, 0, 0, 0, 0, 0);
+ }
+ else
+ {
+ ixOsalLog(IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT,
+ "Channel is Allocated for HDLC\n", 0, 0, 0, 0, 0, 0);
+ }
+ switch (hssAccChannelConfig[channelId].state)
+ {
+ case ICP_HSSACC_CHANNEL_ALLOCATED:
+ {
+ ixOsalLog(IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT,
+ "Channel has only been allocated\n", 0, 0, 0, 0, 0, 0);
+ break;
+
+ }
+ case ICP_HSSACC_CHANNEL_CONFIGURED:
+ {
+ ixOsalLog(IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT,
+ "Channel has been allocated and configured with "
+ "general settings\n",
+ 0, 0, 0, 0, 0, 0);
+ break;
+
+ }
+ case ICP_HSSACC_CHANNEL_SERVICE_CONFIGURED:
+ case ICP_HSSACC_CHANNEL_DOWN:
+ {
+ ixOsalLog(IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT,
+ "Channel has been allocated and service "
+ "specific parameters have been set\n", 0, 0, 0, 0, 0, 0);
+ break;
+
+ }
+ case ICP_HSSACC_CHANNEL_ENABLED:
+ {
+ ixOsalLog(IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT,
+ "Channel is Enabled\n", 0, 0, 0, 0, 0, 0);
+ break;
+
+ }
+ case ICP_HSSACC_CHANNEL_UNINITIALISED:
+ default:
+ {
+ /* This statement is unreachable due to previous error checking */
+ ICP_HSSACC_REPORT_ERROR("HssAccChannelConfigStateShow - "
+ "Invalid Channel State to be printed\n");
+ break;
+ }
+ }
+ }
+}
+
+/*****************************************************************************
+ * Abstract:
+ * reset all the internal data regarding the specified channel
+ *
+ *****************************************************************************/
+TDM_PRIVATE void
+HssAccChannelConfigStateReset (unsigned channelId)
+{
+ hssAccChannelConfig[channelId].state = ICP_HSSACC_CHANNEL_UNINITIALISED;
+ hssAccChannelConfig[channelId].type = ICP_HSSACC_CHAN_TYPE_DELIMITER;
+ hssAccChannelConfig[channelId].size = 0;
+ hssAccChannelConfig[channelId].portId = ICP_HSSACC_MAX_NUM_PORTS;
+ hssAccChannelConfig[channelId].lineId = ICP_HSSACC_LINE_DELIMITER;
+ hssAccChannelConfig[channelId].timeslotMap = 0;
+ hssAccChannelConfig[channelId].sdcCtrlReg = 0;
+ hssAccChannelConfig[channelId].rxCfg = 0;
+ hssAccChannelConfig[channelId].txCfg = 0;
+ hssAccChannelConfig[channelId].dataPolarity = ICP_HSSACC_DATA_POLARITY_SAME;
+ hssAccChannelConfig[channelId].bitEndian = ICP_HSSACC_BIT_ENDIAN_DELIMITER;
+ hssAccChannelConfig[channelId].byteSwap = ICP_FALSE;
+ hssAccChannelConfig[channelId].bitRobbing = ICP_HSSACC_BIT_ROBBING_DELIMITER;
+ hssAccChannelConfig[channelId].rBitValue = ICP_HSSACC_ROBBED_BIT_DELIMITER;
+ hssAccChannelConfig[channelId].rBitLocation =
+ ICP_HSSACC_ROBBED_BIT_POS_DELIMITER;
+ hssAccChannelConfig[channelId].hdlcMaxFrSize = 0;
+ hssAccChannelConfig[channelId].numBypasses = 0;
+ hssAccChannelConfig[channelId].sofFlagType =
+ ICP_HSSACC_HDLC_SOF_FLAG_TYPE_DELIMITER;
+ hssAccChannelConfig[channelId].hdlcTxIdlePattern =
+ ICP_HSSACC_HDLC_IDLE_PATTERN_DELIMITER;
+ hssAccChannelConfig[channelId].hdlcRxIdlePattern =
+ ICP_HSSACC_HDLC_IDLE_PATTERN_DELIMITER;
+ hssAccChannelConfig[channelId].voiceSampleSize = 0;
+ hssAccChannelConfig[channelId].voiceIdlePattern = 0;
+ hssAccChannelConfig[channelId].txIdleAction =
+ ICP_HSSACC_VOICE_TX_IDLE_DELIMITER;
+ hssAccChannelConfig[channelId].hdlcCrcBitWidth =
+ ICP_HSSACC_HDLC_CRC_BIT_WIDTH_DELIMITER;
+}
+
+/*****************************************************************************
+ * Abstract:
+ * returns the configured channel type for the specified channel
+ *
+ *****************************************************************************/
+icp_hssacc_channel_type_t
+HssAccChannelConfigTypeQuery (unsigned channelId)
+{
+ return hssAccChannelConfig[channelId].type;
+}
+
+
+/*****************************************************************************
+ * Abstract:
+ * set the specified channels as part of a bypass.
+ *
+ *****************************************************************************/
+void
+HssAccChannelBypassPairSet(unsigned srcChannelId,
+ unsigned destChannelId)
+{
+ hssAccChannelConfig[srcChannelId].numBypasses ++;
+ hssAccChannelConfig[destChannelId].numBypasses ++;
+}
+
+
+/*****************************************************************************
+ * Abstract:
+ * clear the bypassed state for the specified channels
+ *
+ *****************************************************************************/
+void
+HssAccChannelBypassPairClear(unsigned srcChannelId,
+ unsigned destChannelId)
+{
+ hssAccChannelConfig[srcChannelId].numBypasses --;
+ hssAccChannelConfig[destChannelId].numBypasses --;
+}
+
+
+/*****************************************************************************
+ * Abstract:
+ * returns the state of the specified channel
+ *
+ *****************************************************************************/
+icp_hssacc_channel_state_t
+HssAccChannelConfigStateQuery (unsigned channelId)
+{
+ return hssAccChannelConfig[channelId].state;
+}
+
+
+/*****************************************************************************
+ * Abstract:
+ * used by the datapath modules to notify for a change of channel state
+ * following the retrieval of all buffers in the channel queues.
+ *
+ *****************************************************************************/
+void
+HssAccChannelConfigBuffersClearedNotify (unsigned channelId)
+{
+ if (ICP_HSSACC_CHANNEL_DOWN == hssAccChannelConfig[channelId].state)
+ {
+ hssAccChannelConfig[channelId].state =
+ ICP_HSSACC_CHANNEL_SERVICE_CONFIGURED;
+ }
+}
+
+
+
+
+/*****************************************************************************
+ * Abstract:
+ * return ICP_TRUE if there are any allocated channels on
+ * the specified port.
+ *
+ *****************************************************************************/
+icp_boolean_t
+HssAccChannelConfigUsedChansOnPortFind (const unsigned portId)
+{
+ icp_boolean_t chanFound = ICP_FALSE;
+ unsigned index = 0;
+
+ for (index = 0; index < ICP_HSSACC_MAX_NUM_CHANNELS; index ++)
+ {
+ if ((ICP_HSSACC_CHANNEL_UNINITIALISED !=
+ hssAccChannelConfig[index].state) &&
+ (portId == hssAccChannelConfig[index].portId))
+ {
+ ICP_HSSACC_TRACE_2 (ICP_HSSACC_DEBUG,
+ "HssAccChannelConfigUsedChansOnPortFind - "
+ "Channel %u allocated on port %u\n",
+ index,
+ portId);
+ chanFound = ICP_TRUE;
+ break;
+ }
+ }
+
+ return chanFound;
+}
+
+
diff --git a/Acceleration/library/icp_telephony/tdm_io_access/icp_hssacc_channel_list.c b/Acceleration/library/icp_telephony/tdm_io_access/icp_hssacc_channel_list.c
new file mode 100644
index 0000000..5843de9
--- /dev/null
+++ b/Acceleration/library/icp_telephony/tdm_io_access/icp_hssacc_channel_list.c
@@ -0,0 +1,911 @@
+/*****************************************************************************
+ *
+ * @file icp_hssacc_channel_list.c
+ *
+ * @description Contents of this file is the implementation of the channel
+ * list manipulation functionality.
+ *
+ * @ingroup icp_HssAcc
+ *
+ * @Revision 1.0
+ *
+ * @par
+ * This file is provided under a dual BSD/GPLv2 license. When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * The full GNU General Public License is included in this distribution
+ * in the file called LICENSE.GPL.
+ *
+ * Contact Information:
+ * Intel Corporation
+ *
+ * BSD LICENSE
+ *
+ * Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ *
+ *
+ *****************************************************************************/
+
+
+#include "icp.h"
+#include "icp_hssacc.h"
+#include "icp_hssacc_trace.h"
+#include "icp_hssacc_common.h"
+
+
+
+
+
+/**
+ * Typedefs whose scope is limited to this file.
+ */
+
+
+/* Structure holding list configuration data for one channel */
+typedef struct icp_hssacc_channel_list_data_s
+{
+ uint16_t prevChannelId;
+ uint16_t nextChannelId;
+ icp_hssacc_channel_list_t listId;
+} icp_hssacc_channel_list_data_t;
+
+
+
+/* Stats for List Management*/
+typedef struct icp_hssacc_channel_list_stats_s
+{
+ icp_hssacc_msg_with_resp_stats_t nextChannelWrite;
+ icp_hssacc_msg_with_resp_stats_t portCfgChannel;
+} icp_hssacc_channel_list_stats_t;
+
+
+/* channel List Data for each channel */
+TDM_PRIVATE icp_hssacc_channel_list_data_t
+hssAccChannelData[ICP_HSSACC_MAX_NUM_CHANNELS];
+
+/* Track which channel is the last of the list for each list
+ on each port */
+TDM_PRIVATE uint32_t
+hssAccLastChannelOnList[ICP_HSSACC_MAX_NUM_PORTS]
+[ICP_HSSACC_CHANNEL_LIST_DELIMITER];
+
+/* Internal Messaging Stats for this sub-module */
+TDM_PRIVATE icp_hssacc_channel_list_stats_t hssAccChannelListStats;
+
+/* Track the amount of IO transactions represented by each
+ list on each port */
+TDM_PRIVATE uint32_t
+hssAccPortChannelListUsage[ICP_HSSACC_MAX_NUM_PORTS]
+[ICP_HSSACC_CHANNEL_LIST_DELIMITER];
+
+/* Construct and send the NextChanWrite message to the TDM IO Unit */
+TDM_PRIVATE icp_status_t
+HssAccChannelNextChanWriteMsgSend (unsigned prevChannelId,
+ unsigned nextChannelId,
+ uint8_t txRxIndicator,
+ uint8_t nullFlag);
+
+
+/*
+ * Function Prototype: HssAccChanIOUsageCalc
+ * Description: this function calculates the number
+ * of IO transactions that a specific channelSize implies
+ */
+inline unsigned HssAccChanIOUsageCalc(unsigned chanSize)
+{
+ unsigned channelUsageIO =
+ chanSize / ICP_HSSACC_TDM_IO_UNIT_MAX_TRANSACTION_SIZE_WRDS;
+ channelUsageIO ++;
+ if ( (chanSize % ICP_HSSACC_TDM_IO_UNIT_MAX_TRANSACTION_SIZE_WRDS) > 1 )
+ {
+ channelUsageIO ++;
+ }
+ return channelUsageIO;
+}
+
+
+
+
+/*
+ * Function Prototype: HssAccChannelListMap
+ * Description: this function maps internal sub-module
+ * list IDs to TDM I/O Unit list IDs
+ */
+inline icp_status_t
+HssAccChannelListMap (icp_hssacc_channel_list_t listId,
+ icp_hssacc_tdm_io_unit_channel_list_t *txList,
+ icp_hssacc_tdm_io_unit_channel_list_t *rxList)
+{
+ icp_status_t status = ICP_STATUS_SUCCESS;
+ switch (listId)
+ {
+ case ICP_HSSACC_CHANNEL_LIST_PRIMARY:
+ *txList = ICP_HSSACC_TDM_IO_UNIT_LIST_TX_PRIMARY;
+ *rxList = ICP_HSSACC_TDM_IO_UNIT_LIST_RX_PRIMARY;
+ break;
+ case ICP_HSSACC_CHANNEL_LIST_SECONDARY_0:
+ *txList = ICP_HSSACC_TDM_IO_UNIT_LIST_TX_SECONDARY_0;
+ *rxList = ICP_HSSACC_TDM_IO_UNIT_LIST_RX_SECONDARY_0;
+ break;
+ case ICP_HSSACC_CHANNEL_LIST_SECONDARY_1:
+ *txList = ICP_HSSACC_TDM_IO_UNIT_LIST_TX_SECONDARY_1;
+ *rxList = ICP_HSSACC_TDM_IO_UNIT_LIST_RX_SECONDARY_1;
+ break;
+ case ICP_HSSACC_CHANNEL_LIST_DELIMITER:
+ default:
+ ICP_HSSACC_REPORT_ERROR("HssAccChannelListMap - "
+ "Invalid List ID provided\n");
+ status = ICP_STATUS_FAIL;
+ break;
+ }
+ return status;
+}
+
+/*
+ * Function Prototype: HssAccChannelFirstChanAdd
+ * Description: this function will add a channel to an empty list of
+ * channels processed on the port.
+ */
+TDM_PRIVATE icp_status_t
+HssAccChannelFirstChanAdd (unsigned hssPortId,
+ unsigned channelId,
+ icp_hssacc_channel_list_t listId,
+ icp_hssacc_channel_list_data_t *pListData);
+
+/*
+ * Function Prototype: HssAccChannelLastChanAdd
+ * Description: this function will add a channel to the end of a list of
+ * channels processed on the port.
+ */
+TDM_PRIVATE icp_status_t
+HssAccChannelLastChanAdd (unsigned hssPortId,
+ unsigned channelId,
+ icp_hssacc_channel_list_t listId,
+ icp_hssacc_channel_list_data_t *pListData);
+
+/*
+ * Function Prototype: HssAccChannelFirstChanDel
+ * Description: this function will remove a channel that is at
+ * the start of a list of channels processed on the port.
+ */
+TDM_PRIVATE icp_status_t
+HssAccChannelFirstChanDel (unsigned hssPortId,
+ unsigned channelId,
+ icp_hssacc_channel_list_t listId,
+ icp_hssacc_channel_list_data_t *pListData);
+
+/*
+ * Function Prototype: HssAccChannelLastChanDel
+ * Description: this function will remove a channel that is at the
+ * end of a list of channels processed on the port.
+ */
+TDM_PRIVATE icp_status_t
+HssAccChannelLastChanDel (unsigned hssPortId,
+ icp_hssacc_channel_list_t listId,
+ icp_hssacc_channel_list_data_t *pListData);
+
+/*
+ * Function Prototype: HssAccChannelMiddleChanDel
+ * Description: this function will remove a channel that is in
+ * the middle of a list of channels processed on the port.
+ */
+TDM_PRIVATE icp_status_t
+HssAccChannelMiddleChanDel (icp_hssacc_channel_list_data_t *pListData);
+
+
+/*
+ * Function Prototype: HssAccChannelListsStatsReset
+ * Reset the Stats for this sub-module
+ */
+void
+HssAccChannelListsStatsReset (void)
+{
+ memset (&hssAccChannelListStats,0,sizeof(icp_hssacc_channel_list_stats_t));
+}
+
+
+
+/*
+ * Function Definition: HssAccChannelListsReset
+ */
+void HssAccChannelListsReset (void)
+{
+ unsigned index = 0;
+ icp_hssacc_channel_list_t listId = ICP_HSSACC_CHANNEL_LIST_DELIMITER;
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Entering HssAccChannelListsReset\n");
+ /* Initialise internal data,
+ set last channel IDs for each HSS Port to INVALID_CHAN */
+ for (index = 0; index < ICP_HSSACC_MAX_NUM_PORTS; index ++)
+ {
+ for (listId = 0; listId < ICP_HSSACC_CHANNEL_LIST_DELIMITER; listId ++)
+ {
+ hssAccLastChannelOnList[index][listId] = ICP_HSSACC_INVALID_CHAN;
+ hssAccPortChannelListUsage[index][listId] = 0;
+ }
+ }
+ for (index = 0; index < ICP_HSSACC_MAX_NUM_CHANNELS; index ++)
+ {
+ hssAccChannelData[index].prevChannelId = ICP_HSSACC_INVALID_CHAN;
+ hssAccChannelData[index].nextChannelId = ICP_HSSACC_INVALID_CHAN;
+ hssAccChannelData[index].listId = ICP_HSSACC_CHANNEL_LIST_DELIMITER;
+ }
+
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Exiting HssAccChannelListsReset\n");
+}
+
+
+
+/* Function definition: HssAccNextChannelListGet
+ Description: Figures out the next linked list to use when
+ commissioning a new channel
+ ASSUMPTION: The channel data for the specified channel must be valid */
+TDM_PRIVATE icp_hssacc_channel_list_t
+HssAccNextChannelListGet (uint32_t hssPortId)
+{
+ /* Get the List Id (symmetrical for Tx and Rx) */
+
+ icp_hssacc_channel_list_t smallestList = ICP_HSSACC_CHANNEL_LIST_PRIMARY;
+ uint16_t smallestSize =
+ hssAccPortChannelListUsage[hssPortId][ICP_HSSACC_CHANNEL_LIST_PRIMARY];
+
+ if (smallestSize >
+ hssAccPortChannelListUsage[hssPortId]
+ [ICP_HSSACC_CHANNEL_LIST_SECONDARY_0])
+ {
+ smallestList = ICP_HSSACC_CHANNEL_LIST_SECONDARY_0;
+ smallestSize =
+ hssAccPortChannelListUsage[hssPortId]
+ [ICP_HSSACC_CHANNEL_LIST_SECONDARY_0];
+ }
+
+#if !defined(IXP23XX) || defined(UNIT_TEST)
+ if (smallestSize >
+ hssAccPortChannelListUsage[hssPortId]
+ [ICP_HSSACC_CHANNEL_LIST_SECONDARY_1])
+ {
+ smallestList = ICP_HSSACC_CHANNEL_LIST_SECONDARY_1;
+ }
+#endif
+ return smallestList;
+
+}
+
+
+icp_status_t
+HssAccChannelListAdd (unsigned hssPortId,
+ unsigned chanId,
+ unsigned chanSize)
+{
+ icp_status_t status = ICP_STATUS_SUCCESS;
+ icp_hssacc_channel_list_t listId = ICP_HSSACC_CHANNEL_LIST_DELIMITER;
+ icp_hssacc_channel_list_data_t *pListData = NULL;
+ unsigned channelUsageIO = 0;
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Entering HssAccChannelListAdd\n");
+
+ /* check the channel isnt already in a list */
+ pListData = &(hssAccChannelData[chanId]);
+
+ if (pListData->listId != ICP_HSSACC_CHANNEL_LIST_DELIMITER)
+ {
+ ICP_HSSACC_REPORT_ERROR_2 ("HssAccChannelListAdd - "
+ "Channel %d already part of list %d\n",
+ chanId,
+ pListData->listId);
+ status = ICP_STATUS_FAIL;
+ }
+
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ /* find a list to add to */
+ listId = HssAccNextChannelListGet(hssPortId);
+
+ ICP_HSSACC_TRACE_4 (ICP_HSSACC_DEBUG,
+ "HssAccChannelListAdd - Adding Channel %d"
+ " to List %d on Port %d, current last chan is %d\n",
+ chanId,
+ listId,
+ hssPortId,
+ hssAccLastChannelOnList[hssPortId][listId]);
+
+ if (hssAccLastChannelOnList[hssPortId][listId] ==
+ ICP_HSSACC_INVALID_CHAN)
+ {
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_DEBUG,
+ "HssAccChannelListAdd - List is empty\n");
+
+ status = HssAccChannelFirstChanAdd (hssPortId,
+ chanId,
+ listId,
+ pListData);
+ }
+ else
+ {
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_DEBUG,
+ "HssAccChannelListAdd - Add to end of list\n");
+
+ status = HssAccChannelLastChanAdd (hssPortId,
+ chanId,
+ listId,
+ pListData);
+ }
+ }
+
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ /* list is selected depending on usage. usage is determined depending on
+ the amount estimated amount of IO transactions generated for that
+ list. for each channel, IO transactions is defined as
+ channelSizeInWords/transactionSize + 1 or 2
+ (if modulus greater than 1). */
+ channelUsageIO = HssAccChanIOUsageCalc(chanSize);
+
+ hssAccPortChannelListUsage[hssPortId][listId] += channelUsageIO;
+
+ }
+
+
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Exiting HssAccChannelListAdd\n");
+ return status;
+}
+
+
+
+
+icp_status_t
+HssAccChannelListRemove (unsigned hssPortId,
+ unsigned chanId,
+ unsigned chanSize)
+{
+ icp_status_t status = ICP_STATUS_SUCCESS;
+ icp_hssacc_channel_list_t listId = ICP_HSSACC_CHANNEL_LIST_DELIMITER;
+ icp_hssacc_channel_list_data_t *pListData = NULL;
+ unsigned channelUsageIO = 0;
+
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Entering HssAccChannelListRemove\n");
+ /* Get Channel Data and check that it is in a list */
+ pListData = &(hssAccChannelData[chanId]);
+
+ listId = pListData->listId;
+ if (listId == ICP_HSSACC_CHANNEL_LIST_DELIMITER)
+ {
+ ICP_HSSACC_REPORT_ERROR_1 ("HssAccChannelListRemove - "
+ "Channel %d not part of any list\n",
+ chanId);
+
+ status = ICP_STATUS_FAIL;
+ }
+
+
+ if (ICP_STATUS_SUCCESS == status)
+ {
+
+ /* The channel to be deleted is the first channel on this list */
+ if (pListData->prevChannelId == ICP_HSSACC_INVALID_CHAN)
+ {
+ status = HssAccChannelFirstChanDel (hssPortId,
+ chanId,
+ listId,
+ pListData);
+ }
+ /* The channel to be deleted is not the first channel on this list */
+ else
+ {
+ if (hssAccLastChannelOnList[hssPortId][listId] == chanId)
+ {
+ /* we are deleting the last channel of the list */
+ status = HssAccChannelLastChanDel (hssPortId,
+ listId,
+ pListData);
+ }
+ else
+ {
+ /* we are deleting a channel from the middle of the list */
+ status = HssAccChannelMiddleChanDel (pListData);
+ }
+ }
+ }
+
+ /* for the channel we are deleting, set its next pointer to point to NULL to
+ * avoid the possibility of an infinite loop when it is added later */
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ /* first set the tx 'next' pointer to NULL */
+ status =
+ HssAccChannelNextChanWriteMsgSend (
+ chanId,
+ 0,
+ IX_HSSACC_TDM_IO_UNIT_LIST_INDICATOR_TX,
+ ICP_HSSACC_TDM_IO_UNIT_CHAN_DEL_FLAG);
+ }
+
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ /* now set the rx 'next' pointer to NULL */
+ status =
+ HssAccChannelNextChanWriteMsgSend (
+ chanId,
+ 0,
+ IX_HSSACC_TDM_IO_UNIT_LIST_INDICATOR_RX,
+ ICP_HSSACC_TDM_IO_UNIT_CHAN_DEL_FLAG);
+ }
+
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ /* list is selected depending on usage. usage is determined depending on
+ the estimated amount of IO transactions generated for that
+ list. for each channel, IO transactions is defined as
+ channelSizeInWords/transactionSize+1 or 2 (if module greater
+ than 1).*/
+ channelUsageIO = HssAccChanIOUsageCalc(chanSize);
+
+ hssAccPortChannelListUsage[hssPortId][listId] -= channelUsageIO;
+
+ }
+
+
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Exiting HssAccChannelListRemove\n");
+ return status;
+}
+
+
+
+
+
+
+
+/*
+ * Function definition: HssAccChannelNextChanWriteMsgSend
+ */
+TDM_PRIVATE icp_status_t
+HssAccChannelNextChanWriteMsgSend (unsigned prevChannelId,
+ unsigned nextChannelId,
+ uint8_t txRxIndicator,
+ uint8_t nullFlag)
+{
+ icp_status_t status = ICP_STATUS_SUCCESS;
+ IxPiuMhMessage message;
+
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Entering HssAccChannelNextChanWriteMsgSend\n");
+
+ /* Create the message for the TDM I/O Unit */
+ HssAccComTdmIOUnitCmd8byteMsgCreate (ICP_HSSACC_TDM_IO_UNIT_NEXT_CHAN_WRITE,
+ prevChannelId,
+ 0, 0,
+ nextChannelId,
+ nullFlag,
+ txRxIndicator,
+ 0,
+ &message);
+
+
+ /* Send the message to the TDM I/O Unit */
+ status =
+ HssAccComTdmIOUnitMsgSendAndRecv(
+ message,
+ ICP_HSSACC_TDM_IO_UNIT_NEXT_CHAN_WRITE_RESPONSE,
+ &(hssAccChannelListStats.nextChannelWrite),
+ NULL);
+
+
+ if (ICP_STATUS_SUCCESS != status)
+ {
+ ICP_HSSACC_REPORT_ERROR_1 ("HssAccChannelNextChanWriteMsgSend - "
+ "Messaging failure for channel %d\n",
+ prevChannelId);
+ }
+
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Exiting HssAccChannelNextChanWriteMsgSend\n");
+ return status;
+}
+
+
+
+
+
+/*
+ * Function definition: HssAccChannelPortCfgMsgSend
+ */
+TDM_PRIVATE icp_status_t
+HssAccChannelPortCfgMsgSend (unsigned hssPortId,
+ unsigned channelId,
+ icp_hssacc_channel_list_t listId,
+ uint8_t nullFlag)
+{
+ icp_status_t status = ICP_STATUS_SUCCESS;
+ IxPiuMhMessage message;
+
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Entering HssAccChannelPortCfgMsgSend\n");
+
+ /* Create the message for the TDM I/O Unit*/
+ HssAccComTdmIOUnitCmd8byteMsgCreate (ICP_HSSACC_TDM_IO_UNIT_HSS_PORT_CFG,
+ hssPortId,
+ 0, 0,
+ channelId,
+ nullFlag,
+ listId,
+ 0,
+ &message);
+ /* Send the message to the TDM I/O Unit */
+ status = HssAccComTdmIOUnitMsgSendAndRecv(
+ message,
+ ICP_HSSACC_TDM_IO_UNIT_HSS_PORT_CFG_RESPONSE,
+ &(hssAccChannelListStats.portCfgChannel),
+ NULL);
+
+ if (ICP_STATUS_SUCCESS != status)
+ {
+ ICP_HSSACC_REPORT_ERROR_2 ("HssAccChannelPortCfgMsgSend - Messaging "
+ "failure for port %d, channel %d\n",
+ hssPortId,
+ channelId);
+ }
+
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Exiting HssAccChannelPortCfgMsgSend\n");
+ return status;
+}
+
+
+/*
+ * Function definition: HssAccChannelFirstChanAdd
+ */
+TDM_PRIVATE icp_status_t
+HssAccChannelFirstChanAdd (unsigned hssPortId,
+ unsigned channelId,
+ icp_hssacc_channel_list_t listId,
+ icp_hssacc_channel_list_data_t *pListData)
+{
+ icp_status_t status = ICP_STATUS_SUCCESS;
+ icp_hssacc_tdm_io_unit_channel_list_t rxList, txList =
+ ICP_HSSACC_TDM_IO_UNIT_LIST_DELIMITER;
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Entering HssAccChannelFirstChanAdd\n");
+
+ status = HssAccChannelListMap (listId, &txList, &rxList);
+
+ if (ICP_STATUS_SUCCESS == status)
+ {
+
+ status =
+ HssAccChannelPortCfgMsgSend (hssPortId,
+ channelId,
+ txList,
+ ICP_HSSACC_TDM_IO_UNIT_CHAN_ADD_FLAG);
+ }
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ status =
+ HssAccChannelPortCfgMsgSend (hssPortId,
+ channelId,
+ rxList,
+ ICP_HSSACC_TDM_IO_UNIT_CHAN_ADD_FLAG);
+ }
+
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ pListData->listId = listId;
+ pListData->prevChannelId = ICP_HSSACC_INVALID_CHAN;
+ pListData->nextChannelId = ICP_HSSACC_INVALID_CHAN;
+
+ hssAccLastChannelOnList[hssPortId][listId] = channelId;
+
+ }
+
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Exiting HssAccChannelFirstChanAdd\n");
+ return status;
+}
+
+/*
+ * Function definition: HssAccChannelLastChanAdd
+ */
+TDM_PRIVATE icp_status_t
+HssAccChannelLastChanAdd (unsigned hssPortId,
+ unsigned channelId,
+ icp_hssacc_channel_list_t listId,
+ icp_hssacc_channel_list_data_t *pListData)
+{
+ icp_status_t status = ICP_STATUS_SUCCESS;
+ unsigned prevChannelId = 0;
+ icp_hssacc_channel_list_data_t *pPrevChanList = NULL;
+
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Entering HssAccChannelLastChanAdd\n");
+
+ prevChannelId = hssAccLastChannelOnList[hssPortId][listId];
+
+ status =
+ HssAccChannelNextChanWriteMsgSend (prevChannelId,
+ channelId,
+ IX_HSSACC_TDM_IO_UNIT_LIST_INDICATOR_TX,
+ ICP_HSSACC_TDM_IO_UNIT_CHAN_ADD_FLAG);
+
+ if (ICP_STATUS_SUCCESS == status)
+ {
+
+ status =
+ HssAccChannelNextChanWriteMsgSend(
+ prevChannelId,
+ channelId,
+ IX_HSSACC_TDM_IO_UNIT_LIST_INDICATOR_RX,
+ ICP_HSSACC_TDM_IO_UNIT_CHAN_ADD_FLAG);
+ }
+
+ if (status == ICP_STATUS_SUCCESS)
+ {
+ pListData->listId = listId;
+ pListData->prevChannelId = prevChannelId;
+ pListData->nextChannelId = ICP_HSSACC_INVALID_CHAN;
+ pPrevChanList = &(hssAccChannelData[prevChannelId]);
+ pPrevChanList->nextChannelId = channelId;
+
+ hssAccLastChannelOnList[hssPortId][listId] = channelId;
+
+ }
+
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Exiting HssAccChannelLastChanAdd\n");
+ return status;
+}
+
+
+
+/*
+ * Function definition: HssAccChannelFirstChanDel
+ */
+TDM_PRIVATE icp_status_t
+HssAccChannelFirstChanDel (unsigned hssPortId,
+ unsigned channelId,
+ icp_hssacc_channel_list_t listId,
+ icp_hssacc_channel_list_data_t *pListData)
+{
+ icp_status_t status = ICP_STATUS_SUCCESS;
+ icp_hssacc_tdm_io_unit_channel_list_t rxList, txList =
+ ICP_HSSACC_TDM_IO_UNIT_LIST_DELIMITER;
+ unsigned nextChannelId = 0;
+ icp_hssacc_channel_list_data_t *pNextChanListData = NULL;
+
+
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Entering HssAccChannelFirstChanDel\n");
+
+ status = HssAccChannelListMap(listId, &txList, &rxList);
+
+ if (ICP_STATUS_SUCCESS != status)
+ {
+ return status;
+ }
+
+ /* Check if it is also the only channel processed on this list */
+ if (hssAccLastChannelOnList[hssPortId][listId] == channelId)
+ {
+ /* ChannelId parameter will be ignored by the TDM I/O Unit in
+ this case */
+ status =
+ HssAccChannelPortCfgMsgSend (hssPortId,
+ 0,
+ txList,
+ ICP_HSSACC_TDM_IO_UNIT_CHAN_DEL_FLAG);
+
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ status =
+ HssAccChannelPortCfgMsgSend (hssPortId,
+ 0,
+ rxList,
+ ICP_HSSACC_TDM_IO_UNIT_CHAN_DEL_FLAG);
+
+ }
+
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ pListData->listId = ICP_HSSACC_CHANNEL_LIST_DELIMITER;
+ hssAccLastChannelOnList[hssPortId][listId] = ICP_HSSACC_INVALID_CHAN;
+
+ }
+ }
+ else
+ {
+
+ /* Get information for the next channel on the list */
+ nextChannelId = pListData->nextChannelId;
+
+ status =
+ HssAccChannelPortCfgMsgSend (hssPortId,
+ nextChannelId,
+ txList,
+ ICP_HSSACC_TDM_IO_UNIT_CHAN_ADD_FLAG);
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ status =
+ HssAccChannelPortCfgMsgSend (hssPortId,
+ nextChannelId,
+ rxList,
+ ICP_HSSACC_TDM_IO_UNIT_CHAN_ADD_FLAG);
+ }
+
+ if (status == ICP_STATUS_SUCCESS)
+ {
+ /* current channel is decoupled from the list */
+ pListData->listId = ICP_HSSACC_CHANNEL_LIST_DELIMITER;
+ pListData->nextChannelId = ICP_HSSACC_INVALID_CHAN;
+ /* next channel now becomes the first channel on the list */
+ pNextChanListData = &(hssAccChannelData[nextChannelId]);
+ pNextChanListData->prevChannelId = ICP_HSSACC_INVALID_CHAN;
+ }
+ }
+
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Exiting HssAccChannelFirstChanDel\n");
+
+ return status;
+}
+
+/*
+ * Function definition: HssAccChannelLastChanDel
+ */
+TDM_PRIVATE icp_status_t
+HssAccChannelLastChanDel (unsigned hssPortId,
+ icp_hssacc_channel_list_t listId,
+ icp_hssacc_channel_list_data_t *pListData)
+{
+ icp_status_t status = ICP_STATUS_SUCCESS;
+ unsigned prevChannelId = 0;
+ icp_hssacc_channel_list_data_t *pPrevChanListData = NULL;
+
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Entering HssAccChannelLastChanDel\n");
+
+ prevChannelId = pListData->prevChannelId;
+ pPrevChanListData = &(hssAccChannelData[prevChannelId]);
+
+
+ status =
+ HssAccChannelNextChanWriteMsgSend (prevChannelId,
+ 0,
+ IX_HSSACC_TDM_IO_UNIT_LIST_INDICATOR_TX,
+ ICP_HSSACC_TDM_IO_UNIT_CHAN_DEL_FLAG);
+
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ status =
+ HssAccChannelNextChanWriteMsgSend (
+ prevChannelId,
+ 0,
+ IX_HSSACC_TDM_IO_UNIT_LIST_INDICATOR_RX,
+ ICP_HSSACC_TDM_IO_UNIT_CHAN_DEL_FLAG);
+ }
+ if (status == ICP_STATUS_SUCCESS)
+ {
+ pListData->listId = ICP_HSSACC_CHANNEL_LIST_DELIMITER;
+ pListData->prevChannelId = ICP_HSSACC_INVALID_CHAN;
+
+ /* The Previous channel in the list now becomes the last */
+ pPrevChanListData->nextChannelId = ICP_HSSACC_INVALID_CHAN;
+ hssAccLastChannelOnList[hssPortId][listId] = prevChannelId;
+ }
+
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Exiting HssAccChannelLastChanDel\n");
+ return status;
+}
+
+/*
+ * Function definition: HssAccChannelMiddleChanDel
+ */
+TDM_PRIVATE icp_status_t
+HssAccChannelMiddleChanDel (icp_hssacc_channel_list_data_t *pListData)
+{
+ icp_status_t status = ICP_STATUS_SUCCESS;
+ unsigned prevChannelId, nextChannelId = ICP_HSSACC_INVALID_CHAN;
+ icp_hssacc_channel_list_data_t *pPrevChanListData, *pNextChanListData = NULL;
+
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Entering HssAccChannelMiddleChanDel\n");
+
+ prevChannelId = pListData->prevChannelId;
+ nextChannelId = pListData->nextChannelId;
+ pPrevChanListData = &(hssAccChannelData[prevChannelId]);
+ pNextChanListData = &(hssAccChannelData[nextChannelId]);
+
+
+
+ status =
+ HssAccChannelNextChanWriteMsgSend (prevChannelId,
+ nextChannelId,
+ IX_HSSACC_TDM_IO_UNIT_LIST_INDICATOR_TX,
+ ICP_HSSACC_TDM_IO_UNIT_CHAN_ADD_FLAG);
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ status =
+ HssAccChannelNextChanWriteMsgSend (
+ prevChannelId,
+ nextChannelId,
+ IX_HSSACC_TDM_IO_UNIT_LIST_INDICATOR_RX,
+ ICP_HSSACC_TDM_IO_UNIT_CHAN_ADD_FLAG);
+ }
+
+ if (status == ICP_STATUS_SUCCESS)
+ {
+ pListData->listId = ICP_HSSACC_CHANNEL_LIST_DELIMITER;
+ pListData->nextChannelId = ICP_HSSACC_INVALID_CHAN;
+ pListData->prevChannelId = ICP_HSSACC_INVALID_CHAN;
+
+ pPrevChanListData->nextChannelId = nextChannelId;
+ pNextChanListData->prevChannelId = prevChannelId;
+ }
+
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Exiting HssAccChannelMiddleChanDel\n");
+
+ return status;
+}
+
+
+unsigned
+HssAccChannelListLastPortChannelGet (uint32_t portId,
+ icp_hssacc_channel_list_t listId)
+{
+ return hssAccLastChannelOnList[portId][listId];
+}
+
+
+unsigned
+HssAccChannelListPrevChannelOnListGet(uint32_t channelId)
+{
+ return hssAccChannelData[channelId].prevChannelId;
+}
diff --git a/Acceleration/library/icp_telephony/tdm_io_access/icp_hssacc_common.c b/Acceleration/library/icp_telephony/tdm_io_access/icp_hssacc_common.c
new file mode 100644
index 0000000..25dc112
--- /dev/null
+++ b/Acceleration/library/icp_telephony/tdm_io_access/icp_hssacc_common.c
@@ -0,0 +1,464 @@
+/******************************************************************************
+ * @file icp_hssacc_common.c
+ *
+ * @description Content of this file provides the implementation of
+ * common functionality used by all modules of the HSS Access component
+ *
+ * @ingroup icp_HssAcc
+ *
+ * @Revision 1.0
+ *
+ * @par
+ * This file is provided under a dual BSD/GPLv2 license. When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * The full GNU General Public License is included in this distribution
+ * in the file called LICENSE.GPL.
+ *
+ * Contact Information:
+ * Intel Corporation
+ *
+ * BSD LICENSE
+ *
+ * Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ *
+ *
+ *****************************************************************************/
+
+#include "IxOsal.h"
+
+#include "icp.h"
+#include "icp_hssacc.h"
+#include "icp_hssacc_common.h"
+#include "icp_hssacc_trace.h"
+
+/*
+ * The command ID offset for TDM I/O Unit messages
+ */
+#define HSSACC_TDM_IO_UNIT_CMD_ID_OFFSET (ICP_HSSACC_TDM_IO_UNIT_BYTE0_OFFSET)
+
+/*
+ * The mask for the command ID in TDM I/O Unit messages
+ */
+#define HSSACC_TDM_IO_UNIT_CMD_ID_MASK \
+ (0xFF << HSSACC_TDM_IO_UNIT_CMD_ID_OFFSET)
+
+/*
+ * The length of time to sleep while waiting for the TDM I/O Unit to
+ * respond (in milliseconds)
+ */
+#define HSSACC_TDM_IO_UNIT_WAIT_SLEEP_TIMEOUT (10)
+
+/*
+ * The number of times the HssAcc component will sleep while waiting for a
+ * response message from the TDM I/O Unit before triggering a time-out.
+ */
+#define HSSACC_TDM_IO_UNIT_MAX_NUM_SLEEPS (100)
+
+
+/*****************************************************************************
+ * Abstract:
+ * This struct is used to notify a function that the TDM I/O unit has
+ * replied to the message previously submitted to it.
+ * Typically, the function that submitted the message will poll
+ * respReceived. When this flag is set (in the context of this callback),
+ * the polling client knows that a response has been generated for the
+ * message it submitted.
+ *
+ * Fields:
+ * respMsg - A 2 element array which is used to save the message response.
+ * respReceived - A boolean flag used to notify the polling client of the
+ * TDM I/O Unit's response.
+ *
+ *****************************************************************************/
+typedef struct icp_hss_acc_tdm_io_unit_resp_msg_s
+{
+ IxPiuMhMessage respMsg;
+ volatile icp_boolean_t respReceived;
+} icp_hss_acc_tdm_io_unit_resp_msg_t;
+
+
+/*****************************************************************************
+ * Abstract:
+ * Static variable used to store the most recent message response from the
+ * the TDM I/O Unit.
+ *
+ *****************************************************************************/
+TDM_PRIVATE icp_hss_acc_tdm_io_unit_resp_msg_t tdmIOUnitResponseMessage;
+
+
+/*
+ * Function prototypes
+ */
+TDM_PRIVATE
+void HssAccTdmIOUnitCmdRespCallback(
+ IxPiuMhPiuId piuId,
+ IxPiuMhMessage msg);
+
+TDM_PRIVATE
+icp_status_t
+HssAccComTdmIOUnitCmdMsgWait (volatile icp_boolean_t *const flagToWaitFor);
+
+TDM_PRIVATE
+icp_status_t
+HssAccComTdmIOUnitCmdMsgSend(
+ IxPiuMhMessage message,
+ icp_boolean_t reqResp,
+ volatile icp_boolean_t *const flagToWaitFor,
+ IxPiuMhCallback respCallback,
+ uint8_t solicitedPiuMsgId);
+
+
+/*****************************************************************************
+ * Abstract:
+ * Constructs a 4-byte, 1-word TDM I/O Unit message.
+ *
+ *
+ *****************************************************************************/
+void
+HssAccComTdmIOUnitCmd4byte1wordMsgCreate (uint32_t byte0,
+ uint32_t byte1,
+ uint32_t byte2,
+ uint32_t byte3,
+ uint32_t word,
+ IxPiuMhMessage *pMessage)
+{
+ /* create the message */
+ pMessage->data[0] =
+ (byte3 << ICP_HSSACC_TDM_IO_UNIT_BYTE3_OFFSET) |
+ (byte2 << ICP_HSSACC_TDM_IO_UNIT_BYTE2_OFFSET) |
+ (byte1 << ICP_HSSACC_TDM_IO_UNIT_BYTE1_OFFSET) |
+ (byte0 << ICP_HSSACC_TDM_IO_UNIT_BYTE0_OFFSET);
+ pMessage->data[1] = word;
+ ICP_HSSACC_TRACE_2 (ICP_HSSACC_DEBUG,
+ "HssAccComTdmIOUnitCmd4byte1wordMsgCreate "
+ "0x%08X 0x%08X\n",
+ pMessage->data[0], pMessage->data[1]);
+}
+
+
+/*****************************************************************************
+ * Abstract:
+ * Constructs an 8-byte TDM I/O Unit message.
+ *
+ *
+ *****************************************************************************/
+void
+HssAccComTdmIOUnitCmd8byteMsgCreate (uint32_t byte0,
+ uint32_t byte1,
+ uint32_t byte2,
+ uint32_t byte3,
+ uint32_t byte4,
+ uint32_t byte5,
+ uint32_t byte6,
+ uint32_t byte7,
+ IxPiuMhMessage *pMessage)
+{
+
+
+ /* Create the TDM I/O Unit message format */
+ pMessage->data[0] =
+ (byte3 << ICP_HSSACC_TDM_IO_UNIT_BYTE3_OFFSET) |
+ (byte2 << ICP_HSSACC_TDM_IO_UNIT_BYTE2_OFFSET) |
+ (byte1 << ICP_HSSACC_TDM_IO_UNIT_BYTE1_OFFSET) |
+ (byte0 << ICP_HSSACC_TDM_IO_UNIT_BYTE0_OFFSET);
+
+ pMessage->data[1] =
+ (byte7 << ICP_HSSACC_TDM_IO_UNIT_BYTE3_OFFSET) |
+ (byte6 << ICP_HSSACC_TDM_IO_UNIT_BYTE2_OFFSET) |
+ (byte5 << ICP_HSSACC_TDM_IO_UNIT_BYTE1_OFFSET) |
+ (byte4 << ICP_HSSACC_TDM_IO_UNIT_BYTE0_OFFSET);
+
+ ICP_HSSACC_TRACE_2(ICP_HSSACC_DEBUG,
+ "HssAccComTdmIOUnitCmd8byteMsgCreate 0x%08X 0x%08X\n",
+ pMessage->data[0], pMessage->data[1]);
+}
+
+
+
+
+
+/*****************************************************************************
+ * Abstract:
+ * Submits a message to the TDM I/O Unit, waits for a response and verifies
+ * that the correct response was received, response word is
+ * passed back to client
+ *
+ *
+ *****************************************************************************/
+icp_status_t
+HssAccComTdmIOUnitMsgSendAndRecv(IxPiuMhMessage message,
+ uint8_t response,
+ icp_hssacc_msg_with_resp_stats_t * stats,
+ uint32_t * responseWord)
+{
+ icp_status_t status = ICP_STATUS_SUCCESS;
+ uint8_t cmdType = 0;
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Entering HssAccTdmIOUnitMsgSendAndRecv\n");
+ status =
+ HssAccComTdmIOUnitCmdMsgSend (message,
+ TRUE,
+ &(tdmIOUnitResponseMessage.respReceived),
+ HssAccTdmIOUnitCmdRespCallback,
+ response);
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ stats->numTdmIOUnitMessagesSent ++;
+ stats->numTdmIOUnitRespReceived ++;
+ /* Extract the command ID from the message */
+ cmdType = ( (tdmIOUnitResponseMessage.respMsg.data[0] &
+ HSSACC_TDM_IO_UNIT_CMD_ID_MASK) >>
+ HSSACC_TDM_IO_UNIT_CMD_ID_OFFSET );
+
+ if (cmdType != response)
+ {
+ stats->numTdmIOUnitInvalidResp ++;
+ ICP_HSSACC_REPORT_ERROR_2("HssAccComTdmIOUnitmsgSendAndRecv - "
+ "TDM I/O Unit provided invalid response\n"
+ "Expected %u Cmd and got %u\n",
+ cmdType, response);
+ status = ICP_STATUS_FATAL;
+ }
+ }
+ else if (ICP_STATUS_FATAL == status)
+ {
+ stats->numTdmIOUnitMessagesSent ++;
+ stats->numTdmIOUnitTimeoutErrs ++;
+ }
+
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ if (NULL != responseWord)
+ {
+ *responseWord =
+ tdmIOUnitResponseMessage.respMsg.data[1];
+ }
+ }
+
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Exiting HssAccTdmIOUnitMsgSendAndRecv\n");
+ return status;
+}
+
+
+/*****************************************************************************
+ * Abstract:
+ * This callback is triggered by the TDM I/O unit in response to a message.
+ *
+ *
+ *****************************************************************************/
+TDM_PRIVATE
+void HssAccTdmIOUnitCmdRespCallback(IxPiuMhPiuId piuId,
+ IxPiuMhMessage msg)
+{
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Entering HssAccTdmIOUnitCmdRespCallback\n");
+
+ tdmIOUnitResponseMessage.respMsg = msg;
+
+ ICP_HSSACC_TRACE_3 (ICP_HSSACC_DEBUG,
+ "HssAccTdmIOUnitCmdRespCallback 0x%08X 0x%08X "
+ "from TDM I/O Unit %u\n",
+ msg.data[0], msg.data[1],
+ piuId);
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Exiting HssAccTdmIOUnitCmdRespCallback\n");
+
+ /* This must be the last step in the callback */
+ tdmIOUnitResponseMessage.respReceived = TRUE;
+}
+
+
+/*****************************************************************************
+ * Abstract:
+ * Sleeps until the specified flag is set (this occurs in
+ * HssAccTdmIOUnitCmdRespCallback), or times out and returns an error.
+ *
+ *
+ *****************************************************************************/
+TDM_PRIVATE
+icp_status_t
+HssAccComTdmIOUnitCmdMsgWait (volatile icp_boolean_t *const flagToWaitFor)
+{
+ icp_status_t status = ICP_STATUS_SUCCESS;
+ uint32_t numSleepsWithNoResp = 0;
+
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Entering HssAccComTdmIOUnitCmdMsgWait\n");
+
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_DEBUG,
+ "HssAccComTdmIOUnitCmdMsgWait - "
+ "Waiting on the TDM I/O Unit to respond...\n");
+
+ /* wait until a response is received */
+ while (numSleepsWithNoResp < HSSACC_TDM_IO_UNIT_MAX_NUM_SLEEPS)
+ {
+ if (TRUE == *flagToWaitFor)
+ {
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_DEBUG,
+ "HssAccComTdmIOUnitCmdMsgWait - "
+ "TDM I/O Unit responded\n");
+ break;
+ }
+ numSleepsWithNoResp ++;
+ ixOsalSleep (HSSACC_TDM_IO_UNIT_WAIT_SLEEP_TIMEOUT);
+ }
+
+ /* check for timeout */
+ if (HSSACC_TDM_IO_UNIT_MAX_NUM_SLEEPS == numSleepsWithNoResp)
+ {
+ ICP_HSSACC_REPORT_ERROR("HssAccComTdmIOUnitCmdMsgWait - "
+ "TDM I/O Unit failed to respond in time\n");
+ status = ICP_STATUS_FATAL;
+ }
+
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Exiting HssAccComTdmIOUnitCmdMsgWait\n");
+
+ return status;
+}
+
+
+/*****************************************************************************
+ * Abstract:
+ * Submits a message to the TDM I/O Unit and waits for the specified
+ * response from the TDM I/O Unit (if specified).
+ *
+ *
+ *****************************************************************************/
+TDM_PRIVATE
+icp_status_t
+HssAccComTdmIOUnitCmdMsgSend(
+ IxPiuMhMessage message,
+ icp_boolean_t reqResp,
+ volatile icp_boolean_t *const flagToWaitFor,
+ IxPiuMhCallback respCallback,
+ uint8_t solicitedPiuMsgId)
+{
+ icp_status_t status = ICP_STATUS_SUCCESS;
+ IX_STATUS mhStatus = IX_SUCCESS;
+
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Entering HssAccComTdmIOUnitCmdMsgSend\n");
+
+ ICP_HSSACC_TRACE_2 (ICP_HSSACC_DEBUG,
+ "HssAccComTdmIOUnitCmdMsgSend\n",
+ message.data[0], message.data[1]);
+
+ /* check if a response is required */
+ if (TRUE == reqResp)
+ {
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_DEBUG,
+ "HssAccComTdmIOUnitCmdMsgSend - "
+ "Calling ixPiuMhMessageWithResponseSend\n");
+
+ /* Send the message to the Programmable I/O Unit
+ (TDM I/O Unit in this case) */
+ *flagToWaitFor = FALSE;
+ mhStatus = ixPiuMhMessageWithResponseSend(IX_PIUMH_PIUID_PIU0,
+ message,
+ solicitedPiuMsgId,
+ respCallback,
+ IX_PIUMH_SEND_RETRIES_DEFAULT);
+ }
+ else
+ {
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_DEBUG,
+ "HssAccComTdmIOUnitCmdMsgSend - "
+ "Calling ixPiuMhMessageSend\n");
+
+ /* Send the message to the PiuMh */
+ mhStatus = ixPiuMhMessageSend (IX_PIUMH_PIUID_PIU0,
+ message,
+ IX_PIUMH_SEND_RETRIES_DEFAULT);
+ }
+
+ /* check the return from the Message Handler and block for response if
+ requested */
+ if (IX_SUCCESS != mhStatus)
+ {
+ /* report the error */
+ ICP_HSSACC_REPORT_ERROR ("HssAccComTdmIOUnitCmdMsgSend - "
+ "Message Handler failed to send\n");
+ /* set return status */
+ status = ICP_STATUS_FAIL;
+ }
+ else
+ {
+ /* wait for a response from the TDM I/O Unit if one is expected */
+ if (TRUE == reqResp)
+ {
+ status = HssAccComTdmIOUnitCmdMsgWait (flagToWaitFor);
+ }
+ }
+
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Exiting HssAccComTdmIOUnitCmdMsgSend\n");
+
+ return status;
+}
+
+
+
+
+/*****************************************************************************
+ * Abstract:
+ * Single message stat struct show
+ *
+ *
+ *****************************************************************************/
+void HssAccSingleMessageStatsShow (icp_hssacc_msg_with_resp_stats_t stat)
+{
+ ixOsalLog(IX_OSAL_LOG_LVL_MESSAGE,
+ IX_OSAL_LOG_DEV_STDOUT,
+ "\n\t%u messages Sent\n\t%u messages received\n\t"
+ "%u invalid responses\t\n%u timeouts\n",
+ stat.numTdmIOUnitMessagesSent, stat.numTdmIOUnitRespReceived,
+ stat.numTdmIOUnitInvalidResp, stat.numTdmIOUnitTimeoutErrs, 0, 0);
+}
diff --git a/Acceleration/library/icp_telephony/tdm_io_access/icp_hssacc_common_timeslot_allocation.c b/Acceleration/library/icp_telephony/tdm_io_access/icp_hssacc_common_timeslot_allocation.c
new file mode 100644
index 0000000..074d372
--- /dev/null
+++ b/Acceleration/library/icp_telephony/tdm_io_access/icp_hssacc_common_timeslot_allocation.c
@@ -0,0 +1,441 @@
+/******************************************************************************
+ *
+ * @file icp_hssacc_common_timeslot_allocation.c
+ *
+ * @description Content of this file is the implementation of the Timeslot
+ * allocation and de-allocation functionality used for channel Allocation
+ * and deletion common accross all platforms.
+ *
+ * @ingroup icp_HssAcc
+ *
+ * @Revision 1.0
+ *
+ * @par
+ * This file is provided under a dual BSD/GPLv2 license. When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * The full GNU General Public License is included in this distribution
+ * in the file called LICENSE.GPL.
+ *
+ * Contact Information:
+ * Intel Corporation
+ *
+ * BSD LICENSE
+ *
+ * Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ *
+ *
+ *****************************************************************************/
+#include "IxOsal.h"
+
+#include "icp_hssacc.h"
+#include "icp_hssacc_common.h"
+#include "icp_hssacc_trace.h"
+#include "icp_hssacc_timeslot_allocation.h"
+#include "icp_hssacc_port_config.h"
+#include "icp_hssacc_channel_config.h"
+
+
+
+
+/* Base address of the TDM I/O Unit channel offset table */
+TDM_PRIVATE void * hssAccHdmaProvTableVirtAddr = NULL;
+
+TDM_PRIVATE void * hssAccTdmIoUnitOffsetTableVirtAddr = NULL;
+
+/* Tracks which channel is using which timeslot(s). */
+TDM_PRIVATE unsigned
+hssAccChanTimeslotUsage[ICP_HSSACC_MAX_NUM_PORTS]
+[ICP_HSSACC_MAX_TIMESLOTS_PER_PORT];
+
+
+void * HssAccTsAllocHdmaProvTableVirtAddrGet (void)
+{
+ return hssAccHdmaProvTableVirtAddr;
+}
+
+
+
+void * HssAccTsAllocTdmIoUnitOffsetTableVirtAddrGet (void)
+{
+ return hssAccTdmIoUnitOffsetTableVirtAddr;
+}
+
+
+
+/**
+ * Function Definition
+ */
+icp_status_t HssAccTsAllocInit (void)
+{
+ icp_status_t status = ICP_STATUS_SUCCESS;
+ unsigned portId = ICP_HSSACC_MAX_NUM_PORTS;
+ unsigned tsIndex = 0;
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Entering HssAccTsAllocInit\n");
+
+ /* Mark all timeslots as unreserved */
+ for (portId = 0; portId < ICP_HSSACC_MAX_NUM_PORTS; portId ++)
+ {
+ for (tsIndex = 0;
+ tsIndex < ICP_HSSACC_MAX_TIMESLOTS_PER_PORT;
+ tsIndex ++)
+ {
+ hssAccChanTimeslotUsage[portId][tsIndex] =
+ ICP_HSSACC_INVALID_CHAN;
+ }
+ }
+
+ hssAccHdmaProvTableVirtAddr =
+ (void*)IX_OSAL_CACHE_DMA_MALLOC (ICP_HSSACC_TDM_IO_UNIT_PROV_TABLE_SZ);
+ if (NULL == hssAccHdmaProvTableVirtAddr)
+ {
+ ICP_HSSACC_REPORT_ERROR ("HssAccTsAllocInit - TDM I/O Unit Timeslot "
+ "Provision table allocation failed\n");
+ status = ICP_STATUS_FAIL;
+ }
+
+
+
+ hssAccTdmIoUnitOffsetTableVirtAddr =
+ (void*)IX_OSAL_CACHE_DMA_MALLOC (ICP_HSSACC_TDM_IO_UNIT_OFFSET_TABLE_SZ);
+
+ if (NULL == hssAccTdmIoUnitOffsetTableVirtAddr)
+ {
+ ICP_HSSACC_REPORT_ERROR ("HssAccTsAllocInit - TDM I/O Unit Channel "
+ "Offset table allocation failed\n");
+ status = ICP_STATUS_FAIL;
+ }
+
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ status = HssAccTsAllocPlatformInit ();
+ }
+ else
+ {
+ /* Best Effort shutdown */
+ HssAccTsAllocShutdown();
+ }
+
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Exiting HssAccTsAllocInit\n");
+ return status;
+}
+
+
+/**
+ * Function Definition
+ */
+void HssAccTsAllocShutdown (void)
+{
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Entering HssAccTsAllocShutdown\n");
+
+ if (NULL != hssAccHdmaProvTableVirtAddr)
+ {
+ IX_OSAL_CACHE_DMA_FREE(hssAccHdmaProvTableVirtAddr);
+ hssAccHdmaProvTableVirtAddr = NULL;
+ }
+ if (NULL != hssAccTdmIoUnitOffsetTableVirtAddr)
+ {
+ IX_OSAL_CACHE_DMA_FREE(hssAccTdmIoUnitOffsetTableVirtAddr);
+ hssAccTdmIoUnitOffsetTableVirtAddr = NULL;
+ }
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Exiting HssAccTsAllocShutdown\n");
+}
+
+
+
+
+
+/**
+ * Function definition: HssAccTsAllocTableSwap
+ */
+icp_status_t HssAccTsAllocTableSwap (unsigned hssPortId)
+{
+ icp_status_t status = ICP_STATUS_SUCCESS;
+ IxPiuMhMessage message;
+
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Entering HssAccTsAllocTableSwap\n");
+
+ /* Create Message for TDM I/O Unit */
+ HssAccComTdmIOUnitCmd4byte1wordMsgCreate (
+ ICP_HSSACC_TDM_IO_UNIT_PORT_PROV_TABLE_SWAP,
+ 0,
+ hssPortId,
+ 0,
+ 0,
+ &message);
+ /* Send the message */
+ status =
+ HssAccComTdmIOUnitMsgSendAndRecv(
+ message,
+ ICP_HSSACC_TDM_IO_UNIT_PORT_PROV_TABLE_SWAP_DONE,
+ HssAccTsAllocSwapStatsGet(),
+ NULL);
+
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Exiting HssAccTsAllocTableSwap\n");
+
+ return status;
+}
+
+
+
+
+
+/**
+ * Function definition: HssAccTsAllocDelete
+ */
+icp_status_t
+HssAccTsAllocDelete (unsigned channelId,
+ icp_hssacc_channel_config_t * hssChannelData)
+{
+ icp_status_t status = ICP_STATUS_SUCCESS;
+
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Entering HssAccTsAllocDelete\n");
+
+
+ /* Update the timeslot Allocation tables */
+ status = HssAccTsAllocUpdate(hssChannelData[channelId].portId,
+ hssChannelData);
+ if (status != ICP_STATUS_SUCCESS)
+ {
+ ICP_HSSACC_REPORT_ERROR ("HssAccTsAllocDelete -"
+ " Error updating HDMA Timeslot Tables\n");
+ }
+
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Exiting HssAccTsAllocDelete\n");
+ return status;
+}
+
+
+/**
+ * Function definition: HssAccOffsetTableWordRead
+ */
+icp_status_t
+HssAccTsAllocOffsetTableWordRead (icp_boolean_t readShadowTable,
+ uint16_t tableOffset,
+ uint32_t *tableWord)
+{
+ icp_status_t status = ICP_STATUS_SUCCESS;
+ IxPiuMhMessage message;
+ uint8_t tableSwitch = 0;
+
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Entering HssAccTsAllocOffsetTableWordRead\n");
+
+ if (ICP_TRUE == readShadowTable)
+ {
+ tableSwitch = 1;
+ }
+
+ /* Create Message for TDM I/O Unit */
+ HssAccComTdmIOUnitCmd4byte1wordMsgCreate (
+ ICP_HSSACC_TDM_IO_UNIT_OFFS_TABLE_READ,
+ tableSwitch,
+ 0,
+ 0,
+ tableOffset,
+ &message);
+ /* Send the message */
+ status = HssAccComTdmIOUnitMsgSendAndRecv(
+ message,
+ ICP_HSSACC_TDM_IO_UNIT_OFFS_TABLE_READ_RESPONSE,
+ HssAccTsAllocOffsetTableReadStatsGet(),
+ tableWord);
+
+
+ if (ICP_STATUS_SUCCESS != status)
+ {
+ ICP_HSSACC_REPORT_ERROR("HssAccTsAllocOffsetTableWordRead - "
+ "Failed to retrieve Table data from "
+ "TDM I/O Unit\n");
+ }
+
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Exiting HssAccTsAllocOffsetTableWordRead\n");
+
+ return status;
+}
+
+
+
+
+/*****************************************************************************
+ * Abstract:
+ * Marks the specified timeslots as registered by the specified channel.
+ *
+ *****************************************************************************/
+void
+HssAccTsRegister(unsigned channelId,
+ unsigned portId,
+ icp_hssacc_line_t lineId,
+ uint32_t tsMap)
+{
+ unsigned tsIndex = 0;
+ unsigned offset = 0;
+
+ ICP_HSSACC_TRACE_3 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Entering HssAccTsRegister "
+ "on port %u line %u tsMap 0x%08X\n",
+ portId, lineId, tsMap);
+
+ offset = lineId * ICP_HSSACC_MAX_TIMESLOTS_PER_TDM_LINE;
+
+ /* Reserve the timeslot(s) */
+ for (tsIndex = 0;
+ tsIndex < ICP_HSSACC_MAX_TIMESLOTS_PER_TDM_LINE;
+ tsIndex ++)
+ {
+ if (tsMap & BIT_SET(tsIndex))
+ {
+ ICP_HSSACC_TRACE_2(ICP_HSSACC_DEBUG,
+ "HssAccTsRegister - "
+ "Registering timeslot %u on port %u\n",
+ offset + tsIndex, portId);
+ hssAccChanTimeslotUsage[portId][offset + tsIndex] = channelId;
+ }
+ }
+
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Exiting HssAccTsRegister\n");
+}
+
+/*****************************************************************************
+ * Abstract:
+ * Frees the specified timeslots.
+ *
+ *****************************************************************************/
+void
+HssAccTsUnregister(unsigned portId,
+ icp_hssacc_line_t lineId,
+ uint32_t tsMap)
+{
+ unsigned tsIndex = 0;
+ unsigned offset = lineId *
+ ICP_HSSACC_MAX_TIMESLOTS_PER_TDM_LINE;
+
+ ICP_HSSACC_TRACE_3 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Entering HssAccTsUnregister "
+ "on port %u line %u timeslots 0x%08X\n",
+ portId,
+ lineId,
+ tsMap);
+
+ for (tsIndex = 0;
+ tsIndex < ICP_HSSACC_MAX_TIMESLOTS_PER_TDM_LINE;
+ tsIndex ++)
+ {
+ if (tsMap & BIT_SET(tsIndex))
+ {
+ hssAccChanTimeslotUsage[portId]
+ [offset + tsIndex] = ICP_HSSACC_INVALID_CHAN;
+ }
+ }
+
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Exiting HssAccTsUnregister\n");
+}
+
+/*****************************************************************************
+ * Abstract:
+ * Checks if the requested timeslots are available for use by a channel.
+ *
+ *****************************************************************************/
+icp_boolean_t
+HssAccTsAvailableVerify(unsigned portId,
+ icp_hssacc_line_t lineId,
+ uint32_t tsMap)
+{
+ unsigned tsIndex = 0;
+ unsigned offset = 0;
+ icp_boolean_t timeslotsAvailable = ICP_TRUE;
+
+ ICP_HSSACC_TRACE_3 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Entering HssAccTsAvailableVerify"
+ " on port %u line %u and tsMap 0x%08X\n",
+ portId,
+ lineId,
+ tsMap);
+
+ /*
+ * There are 4 lines per HSS port and each line has 32 timeslots. Since
+ * timeslot usage is recorded per port, need to offset by N*32, where
+ * N is the HSS line number.
+ */
+ offset = lineId * ICP_HSSACC_MAX_TIMESLOTS_PER_TDM_LINE;
+
+ while ((ICP_TRUE == timeslotsAvailable) &&
+ (tsIndex < ICP_HSSACC_MAX_TIMESLOTS_PER_TDM_LINE))
+ {
+ if ( (tsMap & BIT_SET(tsIndex)) &&
+ (ICP_HSSACC_INVALID_CHAN !=
+ hssAccChanTimeslotUsage[portId][offset + tsIndex])
+ )
+ {
+ ICP_HSSACC_TRACE_2(ICP_HSSACC_DEBUG,
+ "Found a Timeslot already used on port %u, "
+ "TS %u\n",
+ portId,
+ offset + tsIndex);
+ timeslotsAvailable = ICP_FALSE;
+ }
+ tsIndex ++;
+ }
+
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Exiting HssAccTsAvailableVerify\n");
+
+ return timeslotsAvailable;
+}
+
diff --git a/Acceleration/library/icp_telephony/tdm_io_access/icp_hssacc_param_check.c b/Acceleration/library/icp_telephony/tdm_io_access/icp_hssacc_param_check.c
new file mode 100644
index 0000000..d8cba6d
--- /dev/null
+++ b/Acceleration/library/icp_telephony/tdm_io_access/icp_hssacc_param_check.c
@@ -0,0 +1,95 @@
+/******************************************************************************
+ *
+ * @file icp_hssacc_param_check.c
+ *
+ * @description Content of this file is the implementation of parameter checking
+ * as valid for this specific platform. Other platforms may not support the same
+ * set of clock modes.
+ *
+ * @ingroup icp_HssAcc
+ *
+ * @Revision 1.0
+ *
+ * @par
+ * This file is provided under a dual BSD/GPLv2 license. When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * The full GNU General Public License is included in this distribution
+ * in the file called LICENSE.GPL.
+ *
+ * Contact Information:
+ * Intel Corporation
+ *
+ * BSD LICENSE
+ *
+ * Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ *
+ *
+ ******************************************************************************/
+
+#include "icp.h"
+#include "icp_hssacc.h"
+#include "icp_hssacc_port_config.h"
+#include "icp_hssacc_common.h"
+
+
+icp_boolean_t
+HssAccPortConfigTxClkModeInvalid(icp_hssacc_clk_mode_t clkMode)
+{
+ return ICP_HSSACC_ENUM_INVALID(clkMode,ICP_HSSACC_CLK_MODE_DELIMITER);
+}
+
+icp_boolean_t
+HssAccPortConfigRxClkModeInvalid(icp_hssacc_clk_mode_t clkMode)
+{
+ /* For Tolapai Rx, all listed modes are supported */
+ return ICP_HSSACC_ENUM_INVALID(clkMode,ICP_HSSACC_CLK_MODE_DELIMITER);
+}
+
+
+
diff --git a/Acceleration/library/icp_telephony/tdm_io_access/icp_hssacc_port_config.c b/Acceleration/library/icp_telephony/tdm_io_access/icp_hssacc_port_config.c
new file mode 100644
index 0000000..652c9b1
--- /dev/null
+++ b/Acceleration/library/icp_telephony/tdm_io_access/icp_hssacc_port_config.c
@@ -0,0 +1,1175 @@
+/******************************************************************************
+ * @file icp_hssacc_port_config.c
+ *
+ * @description Contents of this file provide the implementation of the
+ * Port Configuration functionality for the HSS Access component
+ *
+ * @ingroup icp_HssAcc
+ *
+ * @Revision 1.0
+ *
+ * @par
+ * This file is provided under a dual BSD/GPLv2 license. When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * The full GNU General Public License is included in this distribution
+ * in the file called LICENSE.GPL.
+ *
+ * Contact Information:
+ * Intel Corporation
+ *
+ * BSD LICENSE
+ *
+ * Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ *
+ *
+ *****************************************************************************/
+
+/* ----------------------------------------------------------------------------
+ * Includes
+ * ----------------------------------------------------------------------------
+ */
+#include "IxOsal.h"
+
+#include "icp_hssacc.h"
+#include "icp_hssacc_port_config.h"
+#include "icp_hssacc_common.h"
+#include "icp_hssacc_trace.h"
+#include "icp_hssacc_port_hdma_reg_mgr.h"
+#include "icp_hssacc_timeslot_allocation.h"
+#include "icp_hssacc_address_translate.h"
+
+/*
+ * ----------------------------------------------------------------------------
+ * Macros
+ * ----------------------------------------------------------------------------
+ */
+#define ICP_HSSACC_PORT_API_CONFIG_RESET(cfg) do { \
+ cfg.frmSyncType = ICP_HSSACC_FRM_PULSE_SYNC_TYPE_DELIMITER; \
+ cfg.frmSyncIO = ICP_HSSACC_FRM_PULSE_SYNC_IO_TYPE_DELIMITER;\
+ cfg.frmSyncClkEdge = ICP_HSSACC_CLK_EDGE_TYPE_DELIMITER;\
+ cfg.dataClkEdge = ICP_HSSACC_CLK_EDGE_TYPE_DELIMITER;\
+ cfg.clkMode = ICP_HSSACC_CLK_MODE_DELIMITER;\
+ cfg.frmPulseUsage = ICP_HSSACC_FRM_PULSE_USAGE_TYPE_DELIMITER;\
+ cfg.dataPolarity = ICP_HSSACC_DATA_POLARITY_DELIMITER;\
+ cfg.drainMode = ICP_HSSACC_TX_PINS_DRAIN_MODE_TYPE_DELIMITER;\
+ cfg.refFrame = ICP_HSSACC_REF_FRAME_DELIMITER;\
+ cfg.dataPinsEnable = ICP_HSSACC_DATA_PINS_TYPE_DELIMITER;\
+ cfg.loopback = ICP_FALSE;\
+ cfg.frm_offset = 0;\
+ cfg.fBitType = ICP_HSSACC_TX_FBIT_TYPE_DELIMITER; \
+ cfg.fBitEnable = ICP_FALSE;\
+ cfg.unassignedType = ICP_HSSACC_UNASSIGNED_DATA_DRIVE_DELIMITER; \
+ cfg.interleaving = ICP_HSSACC_INTERLEAVING_TYPE_DELIMITER; \
+} while (0);
+
+#define ICP_HSSACC_PORT_ADD_CONFIG_RESET(addCfg) do { \
+ addCfg.dataRate = ICP_HSSACC_DATA_RATE_EQUALS_CLK_RATE; \
+ addCfg.frmPulseWidth = ICP_HSSACC_RX_DFLT_FRM_PULSE_WIDTH; \
+} while (0);
+
+
+
+/*
+ * ----------------------------------------------------------------------------
+ * Struct types
+ * ----------------------------------------------------------------------------
+ */
+
+
+/* Stats */
+typedef struct icp_hssacc_port_config_stats_s
+{
+ icp_hssacc_msg_with_resp_stats_t configTableLoad;
+ icp_hssacc_msg_with_resp_stats_t portEnable;
+ icp_hssacc_msg_with_resp_stats_t portDisable;
+} icp_hssacc_port_config_stats_t;
+
+/*
+ * ----------------------------------------------------------------------------
+ * Global variables
+ * ----------------------------------------------------------------------------
+ */
+
+/* Flag used to test whether the Port Config sub-component is initialised */
+TDM_PRIVATE icp_boolean_t portConfigInitialised = ICP_FALSE;
+
+/* Tracks the current port state and configuration */
+TDM_PRIVATE icp_hssacc_port_internal_config_t
+hssAccPortConfig[ICP_HSSACC_MAX_NUM_PORTS];
+
+/* Base address of the Port Config tables */
+TDM_PRIVATE void * hssAccPortConfigTablesBaseVirtAddr = NULL;
+
+TDM_PRIVATE icp_hssacc_port_config_stats_t hssAccPortConfigStats;
+
+
+
+/*
+ * ----------------------------------------------------------------------------
+ * Static function declarations
+ * ----------------------------------------------------------------------------
+ */
+TDM_PRIVATE icp_status_t
+HssAccPortConfigTableUpdate(unsigned portId);
+
+
+TDM_PRIVATE icp_status_t
+HssAccPortConfigTableLoad(unsigned portId,
+ void * tableVirtAddr,
+ uint8_t msgId,
+ uint8_t msgRespId);
+
+
+TDM_PRIVATE icp_status_t
+HssAccPortStateSet(unsigned portId,
+ uint8_t msgId,
+ uint8_t msgRespId,
+ icp_hssacc_msg_with_resp_stats_t * stats);
+
+
+/*
+ * ----------------------------------------------------------------------------
+ * Function definitions
+ * ----------------------------------------------------------------------------
+ */
+/******************************************************************************
+ * Abstract:
+ * Initialises all global variables used for port configuration.
+ * Allocates memory for the HDMA port configuration tables.
+ * Initialises the port configuration mutex.
+ *****************************************************************************/
+icp_status_t
+HssAccPortConfigInit(void)
+{
+ icp_status_t status = ICP_STATUS_SUCCESS;
+ unsigned portId = 0;
+ icp_hssacc_hdma_port_config_t * pHdmaConfigTables = NULL;
+
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Entering HssAccPortConfigInit\n");
+
+ if (ICP_TRUE == portConfigInitialised)
+ {
+ ICP_HSSACC_REPORT_ERROR ("HssAccPortConfigInit - "
+ "component has already been initialised\n");
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Exiting HssAccPortConfigInit\n");
+ return ICP_STATUS_FAIL;
+ }
+
+ /* Allocate memory for the port config tables */
+ hssAccPortConfigTablesBaseVirtAddr =
+ (void*)IX_OSAL_CACHE_DMA_MALLOC (ICP_HSSACC_MAX_NUM_PORTS*
+ sizeof(icp_hssacc_hdma_port_config_t));
+
+ if (NULL == hssAccPortConfigTablesBaseVirtAddr)
+ {
+ ICP_HSSACC_REPORT_ERROR ("HssAccPortConfigInit - "
+ "malloc for port config tables failed\n");
+ status = ICP_STATUS_FAIL;
+ }
+ else
+ {
+ pHdmaConfigTables =
+ (icp_hssacc_hdma_port_config_t *)hssAccPortConfigTablesBaseVirtAddr;
+ }
+
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ /* Initialise the port configuration struct */
+ for (portId = 0; portId < ICP_HSSACC_MAX_NUM_PORTS; portId ++)
+ {
+ hssAccPortConfig[portId].state = ICP_HSSACC_PORT_UNCONFIGURED;
+ hssAccPortConfig[portId].hdmaPortCfgTableVirtAddr =
+ &pHdmaConfigTables[portId];
+ hssAccPortConfig[portId].clkSpeed = ICP_HSSACC_CLK_SPEED_DELIMITER;
+
+ /* Rx dir config */
+ ICP_HSSACC_PORT_API_CONFIG_RESET(hssAccPortConfig[portId].rx.cfg);
+ ICP_HSSACC_PORT_ADD_CONFIG_RESET(hssAccPortConfig[portId].rx.addCfg);
+
+
+ /* Tx dir config */
+ ICP_HSSACC_PORT_API_CONFIG_RESET(hssAccPortConfig[portId].tx.cfg);
+ ICP_HSSACC_PORT_ADD_CONFIG_RESET(hssAccPortConfig[portId].tx.addCfg);
+
+ }
+ /* Initialise the internal Stats */
+ HssAccPortConfigStatsReset();
+ portConfigInitialised = ICP_TRUE;
+ }
+
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Exiting HssAccPortConfigInit\n");
+ return status;
+}
+
+
+/******************************************************************************
+ * Abstract:
+ * Shutdown this sub-module: free any memory ...
+ *
+ *****************************************************************************/
+icp_status_t
+HssAccPortConfigShutdown(void)
+{
+ icp_status_t status = ICP_STATUS_SUCCESS;
+ unsigned portId = 0;
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Entering HssAccPortConfigShutdown\n");
+
+ if (ICP_FALSE == portConfigInitialised)
+ {
+ ICP_HSSACC_REPORT_ERROR ("HssAccPortConfigShutdown - "
+ "component has not been initialised\n");
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Exiting HssAccPortConfigShutdown\n");
+ return ICP_STATUS_FAIL;
+ }
+ for (portId = 0; portId < ICP_HSSACC_MAX_NUM_PORTS; portId ++)
+ {
+ if (hssAccPortConfig[portId].state == ICP_HSSACC_PORT_ENABLED)
+ {
+ ICP_HSSACC_REPORT_ERROR_1 ("HssAccPortConfigShutdown - "
+ "port %d is still enabled, "
+ "shut it down first\n",
+ portId);
+ status = ICP_STATUS_FAIL;
+ }
+ }
+
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ /* Free memory allocated for the port config tables */
+ IX_OSAL_CACHE_DMA_FREE(hssAccPortConfigTablesBaseVirtAddr);
+ hssAccPortConfigTablesBaseVirtAddr = NULL;
+
+ for (portId = 0; portId < ICP_HSSACC_MAX_NUM_PORTS; portId ++)
+ {
+ hssAccPortConfig[portId].state = ICP_HSSACC_PORT_UNCONFIGURED;
+ hssAccPortConfig[portId].hdmaPortCfgTableVirtAddr = NULL;
+ }
+
+ portConfigInitialised = ICP_FALSE;
+ }
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Exiting HssAccPortConfigShutdown\n");
+ return status;
+}
+
+
+/******************************************************************************
+ * Abstract:
+ * returns the number of supported HSS ports
+ *
+ *****************************************************************************/
+unsigned
+icp_HssAccNumSupportedPortsGet ( void )
+{
+ return ICP_HSSACC_MAX_NUM_PORTS;
+}
+
+
+
+/******************************************************************************
+ * Abstract:
+ * saves the specified configuration for the specified port
+ *
+ *****************************************************************************/
+icp_status_t
+icp_HssAccPortConfig (unsigned portId,
+ icp_hssacc_port_config_params_t *configParams)
+{
+ icp_status_t status = ICP_STATUS_SUCCESS;
+ icp_boolean_t mutexLocked = ICP_FALSE;
+ icp_hssacc_port_config_t * pTxPortConfig = &(configParams->txPortConfig);
+ icp_hssacc_port_config_t * pRxPortConfig = &(configParams->rxPortConfig);
+
+
+ ICP_HSSACC_TRACE_1 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Entering icp_HssAccPortConfig - port %d\n",
+ portId);
+
+ /* Check if port config component has been initialised */
+ if (ICP_FALSE == portConfigInitialised)
+ {
+ ICP_HSSACC_REPORT_ERROR ("icp_HssAccPortConfig - port config component "
+ "has not been initialised\n");
+ status = ICP_STATUS_FAIL;
+ }
+
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ /* Check Port Number */
+ if (portId >= ICP_HSSACC_MAX_NUM_PORTS)
+ {
+ ICP_HSSACC_REPORT_ERROR ("icp_HssAccPortConfig - "
+ "port number is invalid\n");
+ status = ICP_STATUS_INVALID_PARAM;
+ }
+
+
+ if (NULL == configParams)
+ {
+ ICP_HSSACC_REPORT_ERROR ("icp_HssAccPortConfig - invalid "
+ "port settings pointer\n");
+ status = ICP_STATUS_INVALID_PARAM;
+ }
+ }
+
+
+ if (ICP_STATUS_SUCCESS == status)
+ {
+
+ if (ICP_HSSACC_ENUM_INVALID(configParams->clkSpeed,
+ ICP_HSSACC_CLK_SPEED_DELIMITER))
+ {
+ ICP_HSSACC_REPORT_ERROR ("icp_HssAccPortConfig - "
+ "port clock speed is invalid\n");
+ status = ICP_STATUS_INVALID_PARAM;
+ }
+
+ /* TX Check */
+ if (ICP_HSSACC_ENUM_INVALID(pTxPortConfig->frmSyncType,
+ ICP_HSSACC_FRM_PULSE_SYNC_TYPE_DELIMITER) ||
+ ICP_HSSACC_ENUM_INVALID(pTxPortConfig->frmSyncIO,
+ ICP_HSSACC_FRM_PULSE_SYNC_IO_TYPE_DELIMITER)||
+ (pTxPortConfig->frmSyncIO ==
+ ICP_HSSACC_FRM_PULSE_SYNC_IO_TYPE_INVALID_VALUE) ||
+ ICP_HSSACC_ENUM_INVALID(pTxPortConfig->frmSyncClkEdge,
+ ICP_HSSACC_CLK_EDGE_TYPE_DELIMITER) ||
+ ICP_HSSACC_ENUM_INVALID(pTxPortConfig->dataClkEdge,
+ ICP_HSSACC_CLK_EDGE_TYPE_DELIMITER) ||
+ ICP_HSSACC_ENUM_INVALID(pTxPortConfig->frmPulseUsage,
+ ICP_HSSACC_FRM_PULSE_USAGE_TYPE_DELIMITER) ||
+ ICP_HSSACC_ENUM_INVALID(pTxPortConfig->dataPolarity,
+ ICP_HSSACC_DATA_POLARITY_DELIMITER) ||
+ ICP_HSSACC_ENUM_INVALID(pTxPortConfig->drainMode,
+ ICP_HSSACC_TX_PINS_DRAIN_MODE_TYPE_DELIMITER) ||
+ ICP_HSSACC_ENUM_INVALID(pTxPortConfig->refFrame,
+ ICP_HSSACC_REF_FRAME_DELIMITER) ||
+ ICP_HSSACC_ENUM_INVALID(pTxPortConfig->dataPinsEnable,
+ ICP_HSSACC_DATA_PINS_TYPE_DELIMITER) ||
+ ICP_HSSACC_ENUM_INVALID(pTxPortConfig->fBitType,
+ ICP_HSSACC_TX_FBIT_TYPE_DELIMITER) ||
+ ICP_HSSACC_ENUM_INVALID(pTxPortConfig->unassignedType,
+ ICP_HSSACC_UNASSIGNED_DATA_DRIVE_DELIMITER) ||
+ ICP_HSSACC_ENUM_INVALID(pTxPortConfig->interleaving,
+ ICP_HSSACC_INTERLEAVING_TYPE_DELIMITER) ||
+#ifdef IXP23xx
+ (ICP_TRUE == pTxPortConfig->loopback) ||
+#endif
+ HssAccPortConfigTxClkModeInvalid(pTxPortConfig->clkMode) )
+ {
+ ICP_HSSACC_REPORT_ERROR ("icp_HssAccPortConfig - one or more Tx port "
+ "config parameters is invalid\n");
+ status = ICP_STATUS_INVALID_PARAM;
+ }
+
+
+
+ /* RX Check */
+ if (ICP_HSSACC_ENUM_INVALID(pRxPortConfig->frmSyncType,
+ ICP_HSSACC_FRM_PULSE_SYNC_TYPE_DELIMITER) ||
+ ICP_HSSACC_ENUM_INVALID(pRxPortConfig->frmSyncIO,
+ ICP_HSSACC_FRM_PULSE_SYNC_IO_TYPE_DELIMITER)||
+ (pRxPortConfig->frmSyncIO ==
+ ICP_HSSACC_FRM_PULSE_SYNC_IO_TYPE_INVALID_VALUE) ||
+ ICP_HSSACC_ENUM_INVALID(pRxPortConfig->frmSyncClkEdge,
+ ICP_HSSACC_CLK_EDGE_TYPE_DELIMITER) ||
+ ICP_HSSACC_ENUM_INVALID(pRxPortConfig->dataClkEdge,
+ ICP_HSSACC_CLK_EDGE_TYPE_DELIMITER) ||
+ ICP_HSSACC_ENUM_INVALID(pRxPortConfig->frmPulseUsage,
+ ICP_HSSACC_FRM_PULSE_USAGE_TYPE_DELIMITER) ||
+ ICP_HSSACC_ENUM_INVALID(pRxPortConfig->dataPolarity,
+ ICP_HSSACC_DATA_POLARITY_DELIMITER) ||
+ ICP_HSSACC_ENUM_INVALID(pRxPortConfig->interleaving,
+ ICP_HSSACC_INTERLEAVING_TYPE_DELIMITER) ||
+ HssAccPortConfigRxClkModeInvalid(pRxPortConfig->clkMode) )
+ {
+ ICP_HSSACC_REPORT_ERROR ("icp_HssAccPortConfig - one or more Rx port "
+ "config parameters is invalid\n");
+ status = ICP_STATUS_INVALID_PARAM;
+ }
+
+ if ((pRxPortConfig->refFrame !=
+ ICP_HSSACC_REF_FRAME_NOT_SELECTED) &&
+ (pRxPortConfig->frmSyncIO ==
+ ICP_HSSACC_FRM_PULSE_SYNC_IO_TYPE_INPUT))
+ {
+ ICP_HSSACC_REPORT_ERROR ("icp_HssAccPortConfig - Rx Reference Frame "
+ "selection is invalid for the Frame "
+ "pulse source setting\n");
+ status = ICP_STATUS_INVALID_PARAM;
+ }
+
+ if ((pTxPortConfig->refFrame !=
+ ICP_HSSACC_REF_FRAME_NOT_SELECTED) &&
+ (pTxPortConfig->frmSyncIO ==
+ ICP_HSSACC_FRM_PULSE_SYNC_IO_TYPE_INPUT))
+ {
+ ICP_HSSACC_REPORT_ERROR ("icp_HssAccPortConfig - Tx Reference Frame "
+ "selection is invalid for the Frame "
+ "pulse source setting\n");
+ status = ICP_STATUS_INVALID_PARAM;
+ }
+
+
+ if ((ICP_HSSACC_CLK_SPEED_1544KHZ != configParams->clkSpeed) &&
+ (pRxPortConfig->fBitEnable ||
+ pTxPortConfig->fBitEnable))
+ {
+ ICP_HSSACC_REPORT_ERROR ("icp_HssAccPortConfig - "
+ "FBit is only supported for T1 speed\n");
+ status = ICP_STATUS_INVALID_PARAM;
+ }
+
+ if ((pRxPortConfig->fBitEnable &&
+ (ICP_HSSACC_FRM_PULSE_USAGE_DISABLED ==
+ pRxPortConfig->frmPulseUsage)) ||
+ (pTxPortConfig->fBitEnable &&
+ (ICP_HSSACC_FRM_PULSE_USAGE_DISABLED ==
+ pTxPortConfig->frmPulseUsage)))
+ {
+ ICP_HSSACC_REPORT_ERROR("icp_HssAccPortConfig - "
+ "fBit and Frameless operation "
+ "not permitted\n");
+ status = ICP_STATUS_INVALID_PARAM;
+ }
+
+
+ if ((ICP_TRUE == pRxPortConfig->loopback) &&
+ (ICP_TRUE == pTxPortConfig->loopback))
+ {
+ ICP_HSSACC_REPORT_ERROR("icp_HssAccPortConfig -"
+ " The port cannot be configured for "
+ "both Remote and Internal loopback\n");
+ status = ICP_STATUS_INVALID_PARAM;
+ }
+ }
+
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ /* Lock the HssAcc mutex and update port configuration */
+ if (ICP_STATUS_SUCCESS != ICP_HSSACC_MUTEX_LOCK())
+ {
+ ICP_HSSACC_REPORT_ERROR("icp_HssAccPortConfig - "
+ "Mutex Lock Error\n");
+ status = ICP_STATUS_MUTEX;
+ }
+ else
+ {
+ mutexLocked = ICP_TRUE;
+ }
+
+ }
+
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ if ((0 == memcmp(&(hssAccPortConfig[portId].rx.cfg),
+ pRxPortConfig,
+ sizeof(icp_hssacc_port_config_t))) &&
+ (0 == memcmp (&(hssAccPortConfig[portId].tx.cfg),
+ pTxPortConfig,
+ sizeof(icp_hssacc_port_config_t))))
+ {
+ /* Supplied config is identical to what is already configured */
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_DEBUG,
+ "icp_HssAccPortConfig - port already "
+ "configured with identical settings\n");
+ }
+ else
+ {
+
+ /* Check if port is in a valid state for configuration */
+ if (ICP_HSSACC_PORT_UNCONFIGURED != hssAccPortConfig[portId].state)
+ {
+ ICP_HSSACC_REPORT_ERROR ("icp_HssAccPortConfig - "
+ "port has already been "
+ "configured at some stage\n");
+ status = ICP_STATUS_FAIL;
+ }
+ else
+ {
+ /* Store Port Config Parameters in static memory */
+ hssAccPortConfig[portId].clkSpeed = configParams->clkSpeed;
+ /* Rx dir config */
+ memcpy (&(hssAccPortConfig[portId].rx.cfg),
+ pRxPortConfig,
+ sizeof(icp_hssacc_port_config_t));
+
+ /* Tx dir config */
+ memcpy (&(hssAccPortConfig[portId].tx.cfg),
+ pTxPortConfig,
+ sizeof(icp_hssacc_port_config_t));
+
+ hssAccPortConfig[portId].state = ICP_HSSACC_PORT_CONFIGURED;
+
+ }
+ }
+ }
+
+ if (ICP_TRUE == mutexLocked)
+ {
+ if (ICP_STATUS_SUCCESS != ICP_HSSACC_MUTEX_UNLOCK())
+ {
+ ICP_HSSACC_REPORT_ERROR("icp_HssAccPortConfig - "
+ "Mutex Unlock Error\n");
+ status = ICP_STATUS_MUTEX;
+ }
+ }
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Exiting icp_HssAccPortConfig\n");
+ return status;
+}
+
+
+
+
+/******************************************************************************
+ * Abstract:
+ * Enable traffic on the specified TDM port
+ *
+ *****************************************************************************/
+icp_status_t
+icp_HssAccPortUp (unsigned portId)
+{
+ icp_status_t status = ICP_STATUS_SUCCESS;
+ icp_boolean_t mutexLocked = ICP_FALSE;
+
+ ICP_HSSACC_TRACE_1 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Entering icp_HssAccPortUp - port %d\n",
+ portId);
+
+ /* Check if port config component has been initialised */
+ if (ICP_FALSE == portConfigInitialised)
+ {
+ ICP_HSSACC_REPORT_ERROR ("icp_HssAccPortUp - port config component "
+ "has not been initialised\n");
+ status = ICP_STATUS_FAIL;
+ }
+
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ /* Check Port Number */
+ if (portId >= ICP_HSSACC_MAX_NUM_PORTS)
+ {
+ ICP_HSSACC_REPORT_ERROR ("icp_HssAccPortUp - "
+ "port number is invalid\n");
+
+ status = ICP_STATUS_INVALID_PARAM;
+ }
+ }
+
+
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ /* Lock the HssAcc mutex */
+ if (ICP_STATUS_SUCCESS != ICP_HSSACC_MUTEX_LOCK())
+ {
+ ICP_HSSACC_REPORT_ERROR ("icp_HssAccPortUp - "
+ "failed to lock HssAcc Mutex\n");
+ status = ICP_STATUS_MUTEX;
+ }
+ else
+ {
+ mutexLocked = ICP_TRUE;
+ }
+ }
+
+
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ /* Check if port is already enabled */
+ if (ICP_HSSACC_PORT_ENABLED == hssAccPortConfig[portId].state)
+ {
+ if (ICP_STATUS_SUCCESS != ICP_HSSACC_MUTEX_UNLOCK())
+ {
+ ICP_HSSACC_REPORT_ERROR ("icp_HssAccPortUp - "
+ "failed to unlock HssAcc Mutex\n");
+ status = ICP_STATUS_MUTEX;
+ }
+
+ /* this port is already enabled so we dont need to do anything */
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Exiting icp_HssAccPortUp\n");
+ return status;
+ }
+
+ if (ICP_HSSACC_PORT_UNCONFIGURED == hssAccPortConfig[portId].state)
+ {
+ ICP_HSSACC_REPORT_ERROR_2 ("icp_HssAccPortUp - "
+ "port is not in an appropriate State - "
+ "port %d, state %d\n",
+ portId,
+ hssAccPortConfig[portId].state);
+ status = ICP_STATUS_FAIL;
+ }
+ }
+
+
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ status = HssAccPortConfigTableUpdate(portId);
+
+ }
+
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ status = HssAccTsAllocInitialAllocationUpdate(portId);
+ }
+
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ status = HssAccPortStateSet(portId,
+ ICP_HSSACC_TDM_IO_UNIT_PORT_ENABLE,
+ ICP_HSSACC_TDM_IO_UNIT_PORT_ENABLE_RESPONSE,
+ &(hssAccPortConfigStats.portEnable));
+ }
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ hssAccPortConfig[portId].state = ICP_HSSACC_PORT_ENABLED;
+ }
+
+ if (ICP_TRUE == mutexLocked)
+ {
+ if (ICP_STATUS_SUCCESS != ICP_HSSACC_MUTEX_UNLOCK())
+ {
+ ICP_HSSACC_REPORT_ERROR ("icp_HssAccPortUp - "
+ "failed to unlock HssAcc Mutex\n");
+ status = ICP_STATUS_MUTEX;
+ }
+ }
+
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Exiting icp_HssAccPortUp\n");
+ return status;
+
+}
+
+
+/******************************************************************************
+ * Abstract:
+ * Disables traffic on the specified TDM port.
+ *
+ *****************************************************************************/
+icp_status_t
+icp_HssAccPortDown (unsigned portId)
+{
+ icp_status_t status = ICP_STATUS_SUCCESS;
+
+ ICP_HSSACC_TRACE_1 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Entering icp_HssAccPortDown - port %d\n",
+ portId);
+
+ /* Check if port config component has been initialised */
+ if (ICP_FALSE == portConfigInitialised)
+ {
+ ICP_HSSACC_REPORT_ERROR ("icp_HssAccPortDown - port config component "
+ "has not been initialised\n");
+ status = ICP_STATUS_FAIL;
+ }
+
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ /* Check Port Number */
+ if (portId >= ICP_HSSACC_MAX_NUM_PORTS)
+ {
+ ICP_HSSACC_REPORT_ERROR ("icp_HssAccPortDown - "
+ "port number is invalid\n");
+ status = ICP_STATUS_INVALID_PARAM;
+ }
+ }
+
+ /* Check if port is enabled */
+ if (ICP_STATUS_SUCCESS == status)
+ {
+
+ /* Lock the HssAcc mutex and update port loopback configuration */
+ if (ICP_STATUS_SUCCESS == ICP_HSSACC_MUTEX_LOCK())
+ {
+ if ((ICP_HSSACC_PORT_ENABLED == hssAccPortConfig[portId].state) &&
+ (!HssAccChannelConfigUsedChansOnPortFind(portId)))
+ {
+ status =
+ HssAccPortStateSet(portId,
+ ICP_HSSACC_TDM_IO_UNIT_PORT_DISABLE,
+ ICP_HSSACC_TDM_IO_UNIT_PORT_DISABLE_RESPONSE,
+ &(hssAccPortConfigStats.portDisable));
+
+ if (ICP_STATUS_SUCCESS == status)
+ {
+
+ hssAccPortConfig[portId].state = ICP_HSSACC_PORT_CONFIGURED;
+ }
+ else
+ {
+ ICP_HSSACC_REPORT_ERROR_1 ("icp_HssAccPortDown - "
+ "unable to bring down port %d\n",
+ portId);
+ }
+ }
+ else if (ICP_HSSACC_PORT_CONFIGURED !=
+ hssAccPortConfig[portId].state)
+ {
+ ICP_HSSACC_REPORT_ERROR ("icp_HssAccPortDown - "
+ "there are still allocated channels on"
+ " this port\n");
+ status = ICP_STATUS_RESOURCE;
+ }
+
+ /* Unlock the HssAcc configuration mutex */
+ if (ICP_STATUS_SUCCESS != ICP_HSSACC_MUTEX_UNLOCK())
+ {
+ ICP_HSSACC_REPORT_ERROR ("icp_HssAccPortDown - "
+ "failed to unlock HssAcc Mutex\n");
+ status = ICP_STATUS_MUTEX;
+ }
+
+ }
+ else
+ {
+ ICP_HSSACC_REPORT_ERROR ("icp_HssAccPortDown - "
+ "failed to lock HssAcc Mutex\n");
+ status = ICP_STATUS_MUTEX;
+ }
+
+ }
+
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Exiting icp_HssAccPortDown\n");
+ return status;
+
+}
+
+
+/******************************************************************************
+ * Abstract:
+ * Update the port configuration table in the TDM I/O Unit for this port.
+ *
+ *****************************************************************************/
+TDM_PRIVATE icp_status_t
+HssAccPortConfigTableUpdate(unsigned portId)
+{
+ icp_status_t status = ICP_STATUS_SUCCESS;
+ icp_hssacc_hdma_port_config_t * pPortCfgTable = NULL;
+
+ ICP_HSSACC_TRACE_2 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Entering HssAccPortConfigTableUpdate for "
+ "port %d at speed %d\n",
+ portId,
+ hssAccPortConfig[portId].clkSpeed);
+ /* Get the base address of the port config tables */
+ pPortCfgTable = hssAccPortConfig[portId].hdmaPortCfgTableVirtAddr;
+
+ /* Clear the contents of the HDMA port config table */
+ memset (pPortCfgTable, 0,
+ sizeof(icp_hssacc_hdma_port_config_t));
+
+#ifdef IXP23XX
+ /* Need to Create the LUT for IXP23XX as it is part of the
+ Port Config Table,creating tables with all TimeSlots assigned */
+ status = HssAccHdmaMgrLUTCreate(hssAccPortConfig[portId].clkSpeed,
+ pPortCfgTable->tx_LUT);
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ status = HssAccHdmaMgrLUTCreate(hssAccPortConfig[portId].clkSpeed,
+ pPortCfgTable->rx_LUT);
+ }
+ HssAccHdmaMgrVCRCreate(&(pPortCfgTable->tx_vcr));
+ HssAccHdmaMgrVCRCreate(&(pPortCfgTable->rx_vcr));
+#endif
+
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ HssAccHdmaMgrPCRCreate (ICP_HSSACC_HDMA_TX_REG_TYPE,
+ &(hssAccPortConfig[portId].tx),
+ &(pPortCfgTable->tx_pcr));
+ HssAccHdmaMgrICRCreate (ICP_HSSACC_HDMA_TX_REG_TYPE,
+ portId,
+ &(pPortCfgTable->tx_icr));
+ HssAccHdmaMgrClkCRCreate (hssAccPortConfig[portId].clkSpeed,
+ &(pPortCfgTable->clkcr));
+
+ status = HssAccHdmaMgrFCRCreate (ICP_HSSACC_HDMA_TX_REG_TYPE,
+ hssAccPortConfig[portId].clkSpeed,
+ &(hssAccPortConfig[portId].tx),
+ &(pPortCfgTable->tx_fcr));
+ }
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ HssAccHdmaMgrPCRCreate (ICP_HSSACC_HDMA_RX_REG_TYPE,
+ &(hssAccPortConfig[portId].rx),
+ &(pPortCfgTable->rx_pcr));
+
+ HssAccHdmaMgrICRCreate (ICP_HSSACC_HDMA_RX_REG_TYPE,
+ portId,
+ &(pPortCfgTable->rx_icr));
+
+ if ((hssAccPortConfig[portId].tx.cfg.frmPulseUsage !=
+ ICP_HSSACC_FRM_PULSE_USAGE_ENABLED) ||
+ (hssAccPortConfig[portId].rx.cfg.frmPulseUsage !=
+ ICP_HSSACC_FRM_PULSE_USAGE_ENABLED))
+ {
+ HssAccHdmaMgrCWRCreate (hssAccPortConfig[portId].clkSpeed,
+ &(pPortCfgTable->cwr));
+ }
+
+ status = HssAccHdmaMgrFCRCreate (ICP_HSSACC_HDMA_RX_REG_TYPE,
+ hssAccPortConfig[portId].clkSpeed,
+ &(hssAccPortConfig[portId].rx),
+ &(pPortCfgTable->rx_fcr));
+
+ }
+
+ if (ICP_STATUS_SUCCESS == status)
+ {
+
+ /* Flush the new table to memory */
+ IX_OSAL_CACHE_FLUSH (pPortCfgTable,
+ sizeof(icp_hssacc_hdma_port_config_t));
+
+ /* Load the new HDMA port config table for this port */
+ status =
+ HssAccPortConfigTableLoad (
+ portId,
+ pPortCfgTable,
+ ICP_HSSACC_TDM_IO_UNIT_PORT_CFG_TABLE_LOAD,
+ ICP_HSSACC_TDM_IO_UNIT_PORT_CFG_TABLE_LOAD_RESPONSE);
+ }
+
+ if (ICP_STATUS_FATAL == status)
+ {
+ ICP_HSSACC_REPORT_ERROR ("HssAccPortConfigTableUpdate - HDMA port "
+ "config table update - Fatal Error "
+ "communicating with the TDM I/O unit\n");
+ }
+
+
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Exiting HssAccPortConfigTableUpdate\n");
+ return status;
+}
+
+/******************************************************************************
+ * Abstract:
+ * Send Port Configuration message to the TDM I/O Unit
+ *
+ *****************************************************************************/
+TDM_PRIVATE icp_status_t
+HssAccPortConfigTableLoad(unsigned portId,
+ void * tableVirtAddr,
+ uint8_t msgId,
+ uint8_t msgRespId)
+{
+ uint32_t physAddr = 0;
+ IxPiuMhMessage message;
+ icp_status_t status = ICP_STATUS_SUCCESS;
+
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Entering HssAccPortConfigTableLoad\n");
+
+
+
+ /* Convert the table base address to a physical address */
+ physAddr =
+ HssAccVirtToPhysAddressTranslate(tableVirtAddr);
+
+ if (0 == physAddr)
+ {
+ ICP_HSSACC_REPORT_ERROR("HssAccPortConfigTableLoad - Translation of "
+ "Virtual Address resulted in NULL value\n");
+ status = ICP_STATUS_FAIL;
+ }
+
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ /* Construct the message to load the table */
+ HssAccComTdmIOUnitCmd4byte1wordMsgCreate (
+ msgId,
+ 0,
+ portId,
+ (sizeof(icp_hssacc_hdma_port_config_t) / ICP_HSSACC_WORD_SIZE),
+ physAddr,
+ &message);
+
+ /* Send the message to the TDM I/O Unit and wait for its reply */
+ status = HssAccComTdmIOUnitMsgSendAndRecv(
+ message,
+ msgRespId,
+ &(hssAccPortConfigStats.configTableLoad),
+ NULL);
+ }
+
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Exiting HssAccPortConfigTableLoad\n");
+
+ return status;
+}
+
+
+/******************************************************************************
+ * Abstract:
+ * Set the state of the TDM port within the TDM I/O Unit.
+ *
+ *****************************************************************************/
+TDM_PRIVATE icp_status_t
+HssAccPortStateSet(unsigned portId,
+ uint8_t msgId,
+ uint8_t msgRespId,
+ icp_hssacc_msg_with_resp_stats_t * stats)
+{
+ IxPiuMhMessage message;
+ icp_status_t status = ICP_STATUS_SUCCESS;
+
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Entering HssAccPortStateSet\n");
+
+ /* Construct the message to load the table */
+ HssAccComTdmIOUnitCmd4byte1wordMsgCreate (msgId,
+ 0,
+ portId,
+ 0,
+ 0,
+ &message);
+
+ /* Send the message to the TDM I/O Unit and wait for its reply */
+ status = HssAccComTdmIOUnitMsgSendAndRecv(message,
+ msgRespId,
+ stats,
+ NULL);
+
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Exiting HssAccPortStateSet\n");
+
+ return status;
+}
+
+
+
+/******************************************************************************
+ * Abstract:
+ * check the validity of the line and last timeslot to be used using
+ * the known internal port configuration.
+ *
+ *****************************************************************************/
+icp_status_t
+HssAccPortLineValidCheck (unsigned portId,
+ icp_hssacc_line_t lineId,
+ unsigned firstTsPos,
+ unsigned lastTsPos)
+{
+ icp_status_t status = ICP_STATUS_RESOURCE;
+ ICP_HSSACC_TRACE_3 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Entering HssAccPortLineValidCheck for "
+ "Port %d, line %d and TS %d\n",
+ portId,
+ lineId,
+ lastTsPos);
+
+ if (ICP_HSSACC_LINE_0 != lineId)
+ {
+ if (((ICP_HSSACC_LINE_1 == lineId) ||
+ (ICP_HSSACC_LINE_3 == lineId) ||
+ (ICP_HSSACC_LINE_2 == lineId)) &&
+ (ICP_HSSACC_CLK_SPEED_8192KHZ == hssAccPortConfig[portId].clkSpeed))
+ {
+ ICP_HSSACC_TRACE_1 (ICP_HSSACC_DEBUG,
+ "HssAccPortLineValidCheck - "
+ "Line %d config Valid\n",
+ lineId);
+ status = ICP_STATUS_SUCCESS;
+ }
+ else
+ {
+ ICP_HSSACC_REPORT_ERROR ("HssAccPortLineValidCheck - Line specified "
+ "is not valid for current Clock speed\n");
+ }
+ }
+ else
+ {
+ if ((ICP_HSSACC_CLK_SPEED_1544KHZ ==
+ hssAccPortConfig[portId].clkSpeed) &&
+ ((lastTsPos > ICP_HSSACC_TIMESLOTS_PER_T1_LINE) ||
+ (firstTsPos == 0)))
+ {
+ ICP_HSSACC_REPORT_ERROR ("HssAccPortLineValidCheck - "
+ "Attempting to allocate Invalid "
+ "Timeslots for a T1 line\n");
+ }
+ else
+ {
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_DEBUG,
+ "HssAccPortLineValidCheck - "
+ "Line 0 config Valid\n");
+ status = ICP_STATUS_SUCCESS;
+ }
+ }
+
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Exiting HssAccPortLineValidCheck\n");
+ return status;
+}
+
+/******************************************************************************
+ * Abstract:
+ * return the current state of the specified port
+ *
+ *****************************************************************************/
+icp_hssacc_port_state_t
+HssAccPortStateGet ( unsigned portId)
+{
+ return hssAccPortConfig[portId].state;
+}
+
+
+/******************************************************************************
+ * Abstract:
+ * Reset the internal stats for this sub-module
+ *
+ *****************************************************************************/
+void
+HssAccPortConfigStatsReset (void)
+{
+ memset (&hssAccPortConfigStats, 0, sizeof(icp_hssacc_port_config_stats_t));
+}
+
+
+
+/******************************************************************************
+ * Abstract:
+ * display all the internal stats for this sub-module
+ *
+ *****************************************************************************/
+void
+HssAccPortConfigStatsShow (void)
+{
+ unsigned portId = 0;
+ icp_hssacc_hdma_port_config_t * portConfig = NULL;
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Entering HssAccPortConfigStatsShow\n");
+ if (ICP_TRUE == portConfigInitialised)
+ {
+ for (portId = 0; portId < ICP_HSSACC_MAX_NUM_PORTS; portId ++)
+ {
+ ixOsalLog(IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT,
+ "\nPort %d:\n",
+ portId,
+ 0, 0, 0, 0, 0);
+
+ if (ICP_HSSACC_PORT_UNCONFIGURED == hssAccPortConfig[portId].state)
+ {
+ ixOsalLog(IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT,
+ "\tnot configured\n",
+ 0, 0, 0, 0, 0, 0);
+ }
+ else
+ {
+ portConfig = (hssAccPortConfig[portId].hdmaPortCfgTableVirtAddr);
+ ixOsalLog(IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT,
+ "\nPort %d in State %d, Configuration:"
+ "\n\ttx_pcr 0x%08X"
+ "\n\trx_pcr 0x%08X"
+ "\n\ttx_fcr 0x%08X"
+ "\n\trx_fcr 0x%08X",
+ portId, hssAccPortConfig[portId].state,
+ portConfig->tx_pcr,
+ portConfig->rx_pcr,
+ portConfig->tx_fcr,
+ portConfig->rx_fcr);
+ ixOsalLog(IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT,
+ "\n\ttx_icr 0x%08X\n\trx_icr 0x%08X"
+ "\n\tclkcr 0x%08X\n\tcwr 0x%08X\n",
+ portConfig->tx_icr,
+ portConfig->rx_icr,
+ portConfig->clkcr,
+ portConfig->cwr, 0, 0);
+
+ switch (hssAccPortConfig[portId].clkSpeed)
+ {
+ case ICP_HSSACC_CLK_SPEED_1544KHZ:
+ ixOsalLog(IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT,
+ "\tPort Speed Configured For 1.544MHZ\n",
+ 0, 0, 0, 0, 0, 0);
+ break;
+ case ICP_HSSACC_CLK_SPEED_2048KHZ:
+ ixOsalLog(IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT,
+ "\tPort Speed Configured For 2.048MHZ\n",
+ 0, 0, 0, 0, 0, 0);
+ break;
+ case ICP_HSSACC_CLK_SPEED_8192KHZ:
+ ixOsalLog(IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT,
+ "\tPort Speed Configured For 8.192MHZ\n",
+ 0, 0, 0, 0, 0, 0);
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
+ ixOsalLog(IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT,
+ "\nPort Configuration Statistics:\n"
+ "Config Table Load Messaging\n",
+ 0, 0, 0, 0, 0, 0);
+ HssAccSingleMessageStatsShow (hssAccPortConfigStats.configTableLoad);
+ ixOsalLog(IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT,
+ "\nPort Up Messaging\n",
+ 0, 0, 0, 0, 0, 0);
+ HssAccSingleMessageStatsShow (hssAccPortConfigStats.portEnable);
+ ixOsalLog(IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT,
+ "\nPort Down Messaging\n",
+ 0, 0, 0, 0, 0, 0);
+ HssAccSingleMessageStatsShow (hssAccPortConfigStats.portDisable);
+ }
+
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Exiting HssAccPortConfigStatsShow\n");
+
+}
diff --git a/Acceleration/library/icp_telephony/tdm_io_access/icp_hssacc_port_hdma_reg_mgr.c b/Acceleration/library/icp_telephony/tdm_io_access/icp_hssacc_port_hdma_reg_mgr.c
new file mode 100644
index 0000000..66ea618
--- /dev/null
+++ b/Acceleration/library/icp_telephony/tdm_io_access/icp_hssacc_port_hdma_reg_mgr.c
@@ -0,0 +1,546 @@
+/******************************************************************************
+ * @file icp_hssacc_port_hdma_reg_mgr.c
+ *
+ * @description Contents of this file is the implementation of the HSS
+ * Port registers Creation from API parameters and internal settings.
+ *
+ * @ingroup icp_HssAcc
+ *
+ * @Revision 1.0
+ *
+ * @par
+ * This file is provided under a dual BSD/GPLv2 license. When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * The full GNU General Public License is included in this distribution
+ * in the file called LICENSE.GPL.
+ *
+ * Contact Information:
+ * Intel Corporation
+ *
+ * BSD LICENSE
+ *
+ * Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ *
+ *
+ *****************************************************************************/
+
+#include "IxOsal.h"
+
+#include "icp_hssacc.h"
+#include "icp_hssacc_port_config.h"
+#include "icp_hssacc_trace.h"
+#include "icp_hssacc_common.h"
+#include "icp_hssacc_port_hdma_reg_mgr.h"
+
+
+/**
+ * Typedefs whose scope is limited to this file.
+ */
+
+/* Structure holding HDMA Co-p system clock divider definitions */
+typedef struct icp_hssacc_hdma_sys_clk_s
+{
+ uint16_t main;
+ uint16_t num;
+ uint16_t denom;
+} icp_hssacc_hdma_sys_clk_t;
+
+
+
+/* HSS Co-p clock divider from the TDM I/O Unit system clk */
+TDM_PRIVATE icp_hssacc_hdma_sys_clk_t
+hssAccHdmaSysClk[ICP_HSSACC_CLK_SPEED_DELIMITER] =
+ {
+ ICP_HSSACC_HDMA_SYSCLK_1544KHZ,
+ ICP_HSSACC_HDMA_SYSCLK_2048KHZ,
+ ICP_HSSACC_HDMA_SYSCLK_8192KHZ
+ };
+
+TDM_PRIVATE uint32_t
+tdmPbaAddresses[ICP_HSSACC_HDMA_REG_TYPE_DELIMITER]
+ [ICP_HSSACC_MAX_NUM_PORTS] =
+ {
+ {
+ ICP_HSSACC_TDM_IO_UNIT_HSS_HDMA_RX_PBA_0,
+ ICP_HSSACC_TDM_IO_UNIT_HSS_HDMA_RX_PBA_1,
+ ICP_HSSACC_TDM_IO_UNIT_HSS_HDMA_RX_PBA_2
+#ifdef IXP23XX
+,
+ ICP_HSSACC_TDM_IO_UNIT_HSS_HDMA_RX_PBA_3
+#endif
+ },
+ {
+ ICP_HSSACC_TDM_IO_UNIT_HSS_HDMA_TX_PBA_0,
+ ICP_HSSACC_TDM_IO_UNIT_HSS_HDMA_TX_PBA_1,
+ ICP_HSSACC_TDM_IO_UNIT_HSS_HDMA_TX_PBA_2
+#ifdef IXP23XX
+,
+ ICP_HSSACC_TDM_IO_UNIT_HSS_HDMA_TX_PBA_3
+#endif
+ }
+ } ;
+
+
+
+/**
+ * Function definition: HssAccHdmaMgrPCRCreate
+ */
+void
+HssAccHdmaMgrPCRCreate (icp_hssacc_hdma_reg_trans_t type,
+ const icp_hssacc_port_full_config_t *portConfig,
+ uint32_t *pcr)
+{
+
+
+ uint32_t offsetInReg = ICP_HSSACC_TDM_IO_UNIT_HDMA_RX_PCR_LB_OFFSET;
+ uint32_t clkDirection = ICP_HSSACC_TDM_IO_UNIT_HDMA_PCR_CLKDIR_OUTPUT;
+#ifdef EP805XX
+ uint32_t clkSelect = ICP_HSSACC_TDM_IO_UNIT_HDMA_PCR_CS_INT;
+#endif
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Entering HssAccHdmaMgrPCRCreate\n");
+
+ *pcr = 0;
+
+ if (ICP_HSSACC_CLK_MODE_INPUT_EXTERNAL == portConfig->cfg.clkMode)
+ {
+ clkDirection = ICP_HSSACC_TDM_IO_UNIT_HDMA_PCR_CLKDIR_INPUT;
+ }
+#ifdef EP805XX
+ /* A single API parameter maps to 2 fields of this register
+ map 1 to 2 here starting with default values above */
+ if (ICP_HSSACC_CLK_MODE_OUTPUT_REF == portConfig->cfg.clkMode)
+ {
+ clkSelect = ICP_HSSACC_TDM_IO_UNIT_HDMA_PCR_CS_EXT_REF;
+ }
+#endif
+
+
+
+ /* create the common parts of the HSS co-p pcr register */
+ /* note: portDataBitEndianness is now ICP_HSSACC_BIT_ENDIAN_MSB
+ at all times */
+ *pcr =
+ (portConfig->cfg.frmSyncType <<
+ ICP_HSSACC_TDM_IO_UNIT_HDMA_PCR_FT_OFFSET) |
+ (portConfig->cfg.frmSyncIO <<
+ ICP_HSSACC_TDM_IO_UNIT_HDMA_PCR_FS_OFFSET) |
+ (portConfig->cfg.frmSyncClkEdge <<
+ ICP_HSSACC_TDM_IO_UNIT_HDMA_PCR_FE_OFFSET) |
+ (portConfig->cfg.dataClkEdge <<
+ ICP_HSSACC_TDM_IO_UNIT_HDMA_PCR_DE_OFFSET) |
+ (clkDirection <<
+ ICP_HSSACC_TDM_IO_UNIT_HDMA_PCR_CLKDIR_OFFSET)|
+ (portConfig->cfg.frmPulseUsage <<
+ ICP_HSSACC_TDM_IO_UNIT_HDMA_PCR_FR_OFFSET) |
+ (portConfig->addCfg.dataRate <<
+ ICP_HSSACC_TDM_IO_UNIT_HDMA_PCR_RATE_OFFSET) |
+ (portConfig->cfg.dataPolarity <<
+ ICP_HSSACC_TDM_IO_UNIT_HDMA_PCR_DP_OFFSET) |
+ (ICP_HSSACC_BIT_ENDIAN_MSB <<
+ ICP_HSSACC_TDM_IO_UNIT_HDMA_PCR_BITEND_OFFSET)|
+#ifdef EP805XX
+ (portConfig->cfg.refFrame <<
+ ICP_HSSACC_TDM_IO_UNIT_HDMA_PCR_REFF_OFFSET) |
+ (clkSelect <<
+ ICP_HSSACC_TDM_IO_UNIT_HDMA_PCR_CS_OFFSET) |
+#endif
+ (portConfig->addCfg.frmPulseWidth - 1);
+ /* width varies from 1 to 8 but input value to co-proc is 0 to 7*/
+
+
+ /* check the tx specific parameters */
+ if (ICP_HSSACC_HDMA_TX_REG_TYPE == type)
+ {
+ offsetInReg = ICP_HSSACC_TDM_IO_UNIT_HDMA_TX_PCR_LB_OFFSET;
+ /* create the tx specific parts of the HSS co-p pcr register */
+ *pcr |=
+ (portConfig->cfg.drainMode <<
+ ICP_HSSACC_TDM_IO_UNIT_HDMA_PCR_OD_OFFSET) |
+ (portConfig->cfg.dataPinsEnable <<
+ ICP_HSSACC_TDM_IO_UNIT_HDMA_PCR_EN_OFFSET) |
+ (portConfig->cfg.fBitType <<
+ ICP_HSSACC_TDM_IO_UNIT_HDMA_PCR_FB_OFFSET) |
+ (0 << ICP_HSSACC_TDM_IO_UNIT_HDMA_PCR_56KTYPE_OFFSET) |
+ (portConfig->cfg.unassignedType <<
+ ICP_HSSACC_TDM_IO_UNIT_HDMA_PCR_UTYPE_OFFSET) |
+ (0 << ICP_HSSACC_TDM_IO_UNIT_HDMA_PCR_56KEND_OFFSET ) |
+ (0 << ICP_HSSACC_TDM_IO_UNIT_HDMA_PCR_56KSEL_OFFSET );
+ }
+ if (ICP_TRUE == portConfig->cfg.loopback)
+ {
+ *pcr |= (ICP_HSSACC_TDM_IO_UNIT_HDMA_PCR_LB_ON
+ << offsetInReg);
+ }
+
+ ICP_HSSACC_TRACE_1 (ICP_HSSACC_DEBUG,
+ "HssAccHdmaMgrPCRCreate - "
+ "PCR = 0x%08X\n", *pcr);
+
+#ifdef SW_SWAPPING
+ *pcr = IX_OSAL_SWAP_BE_SHARED_LONG(*pcr);
+#endif
+
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Exiting HssAccHdmaMgrPCRCreate\n");
+}
+
+/**
+ * Function definition: HssAccHdmaMgrFCRCreate
+ */
+icp_status_t
+HssAccHdmaMgrFCRCreate (icp_hssacc_hdma_reg_trans_t type,
+ icp_hssacc_clk_speed_t clkSpeed,
+ const icp_hssacc_port_full_config_t *portConfig,
+ uint32_t *fcr)
+{
+ icp_status_t status = ICP_STATUS_SUCCESS;
+ uint8_t size = 0;
+ uint16_t offsetMaxVal = 0;
+ uint32_t offset = 0;
+ uint32_t fBitEnable = 0;
+ /* Used to indicate if this Hss Port is using MVIP or not */
+ icp_hssacc_hdma_mvip_switch_t mvipSwitch =
+ ICP_HSSACC_TDM_IO_UNIT_HDMA_FCR_MVIP_SWITCH_DELIMITER;
+ /* Used to indicate if this Hss Port is using quad MVIP or not */
+ icp_hssacc_hdma_mvip_setting_t mvipSetting =
+ ICP_HSSACC_TDM_IO_UNIT_HDMA_FCR_MVIP_SETTING_DELIMITER;
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Entering HssAccHdmaMgrFCRCreate\n");
+
+ switch (clkSpeed)
+ {
+ case ICP_HSSACC_CLK_SPEED_1544KHZ:
+ size = ICP_HSSACC_TDM_IO_UNIT_HDMA_FCR_FRAME_SIZE_T1_IN_TS;
+ mvipSwitch = ICP_HSSACC_TDM_IO_UNIT_HDMA_FCR_MVIP_SWITCH_OFF;
+ offsetMaxVal = ICP_HSSACC_TDM_IO_UNIT_HDMA_FCR_FRAME_SIZE_T1_IN_BITS;
+ if (portConfig->cfg.frm_offset >= offsetMaxVal)
+ {
+ ICP_HSSACC_REPORT_ERROR ("HssAccHdmaMgrFCRCreate - frmOffset >="
+ " T1 frame size\n");
+ status = ICP_STATUS_INVALID_PARAM;
+ }
+ break;
+
+ case ICP_HSSACC_CLK_SPEED_2048KHZ:
+ size = ICP_HSSACC_TDM_IO_UNIT_HDMA_FCR_FRAME_SIZE_E1_IN_TS;
+ mvipSwitch = ICP_HSSACC_TDM_IO_UNIT_HDMA_FCR_MVIP_SWITCH_OFF;
+ offsetMaxVal = ICP_HSSACC_TDM_IO_UNIT_HDMA_FCR_FRAME_SIZE_E1_IN_BITS;
+ if (portConfig->cfg.frm_offset >= offsetMaxVal)
+ {
+ ICP_HSSACC_REPORT_ERROR ("HssAccHdmaMgrFCRCreate - frmOffset >="
+ " E1 frame size\n");
+ status = ICP_STATUS_INVALID_PARAM;
+ }
+ break;
+
+
+ case ICP_HSSACC_CLK_SPEED_8192KHZ:
+ size = ICP_HSSACC_TDM_IO_UNIT_HDMA_FCR_FRAME_SIZE_E1_IN_TS;
+ mvipSwitch = ICP_HSSACC_TDM_IO_UNIT_HDMA_FCR_MVIP_SWITCH_ON;
+ mvipSetting = ICP_HSSACC_TDM_IO_UNIT_HDMA_FCR_MVIP_SETTING_QUAD;
+ offsetMaxVal =
+ ICP_HSSACC_TDM_IO_UNIT_HDMA_FCR_FRAME_SIZE_QUAD_MVIP_IN_BITS;
+ /* No need to check if (offset > offsetMaxVal), the service I/F has
+ done this already. */
+ break;
+
+ default:
+ /* clkSpeed is already error checked so this default is unreachable */
+ ICP_HSSACC_REPORT_ERROR_1 ("HssAccHdmaMgrFCRCreate - Invalid clock "
+ "speed (%d) in clkSpeed struct\n",
+ clkSpeed);
+ status = ICP_STATUS_INVALID_PARAM;
+ }
+
+ if ( ICP_STATUS_SUCCESS == status )
+ {
+ offset = portConfig->cfg.frm_offset;
+ if (ICP_HSSACC_HDMA_TX_REG_TYPE == type)
+ {
+ if (ICP_HSSACC_DATA_RATE_EQUALS_CLK_RATE ==
+ portConfig->addCfg.dataRate)
+ {
+ offset +=
+ ICP_HSSACC_TDM_IO_UNIT_HDMA_FCR_OFFSET_TX_ADD_CLK_RATE;
+ }
+ else if (ICP_HSSACC_DATA_RATE_HALF_CLK_RATE ==
+ portConfig->addCfg.dataRate)
+ {
+ offset +=
+ ICP_HSSACC_TDM_IO_UNIT_HDMA_FCR_OFFSET_TX_ADD_HALF_CLK_RATE;
+ }
+ /*
+ It is the modulus of the frame size that the frame pulse
+ delineates, which is expected to fit into the offset bits
+ of the FCR
+ */
+ offset %= offsetMaxVal;
+
+ /* With FBit Enabled, offset values of 0-7 are illegal */
+ if (ICP_TRUE == portConfig->cfg.fBitEnable)
+ {
+ offset += ICP_HSSACC_TDM_IO_UNIT_HDMA_FCR_OFFSET_FBIT_ADDITION;
+ }
+ }
+
+ }
+
+
+ if (ICP_STATUS_SUCCESS == status)
+ {
+
+ if (ICP_TRUE == portConfig->cfg.fBitEnable)
+ {
+ fBitEnable = 1;
+ }
+
+ *fcr = 0;
+ /* create the HSS co-proc 32bit register format */
+ *fcr =
+ (fBitEnable << ICP_HSSACC_TDM_IO_UNIT_HDMA_FCR_FBIT_OFFSET) |
+ (size << ICP_HSSACC_TDM_IO_UNIT_HDMA_FCR_FRAME_SIZE_OFFSET) |
+ (mvipSwitch << ICP_HSSACC_TDM_IO_UNIT_HDMA_FCR_MVIP_SWITCH_OFFSET) |
+ (portConfig->cfg.interleaving <<
+ ICP_HSSACC_TDM_IO_UNIT_HDMA_FCR_INT_OFFSET) |
+ (offset << ICP_HSSACC_TDM_IO_UNIT_HDMA_FCR_OFFSET_OFFSET);
+
+ if (ICP_HSSACC_TDM_IO_UNIT_HDMA_FCR_MVIP_SWITCH_ON == mvipSwitch)
+ {
+ *fcr |= mvipSetting <<
+ ICP_HSSACC_TDM_IO_UNIT_HDMA_FCR_MVIP_SETTING_OFFSET;
+ }
+ ICP_HSSACC_TRACE_1 (ICP_HSSACC_DEBUG,
+ "HssAccHdmaMgrFCRCreate - "
+ "FCR = 0x%08X\n", *fcr);
+
+#ifdef SW_SWAPPING
+ *fcr = IX_OSAL_SWAP_BE_SHARED_LONG(*fcr);
+#endif
+ }
+
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Exiting HssAccHdmaMgrFCRCreate\n");
+ return status;
+}
+
+
+
+/**
+ * Function definition: HssAccHdmaMgrICRCreate
+ */
+void
+HssAccHdmaMgrICRCreate (icp_hssacc_hdma_reg_trans_t type,
+ unsigned hssPortId,
+ uint32_t *icr)
+{
+
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Entering HssAccHdmaMgrICRCreate\n");
+
+ *icr =
+ (ICP_HSSACC_TDM_IO_UNIT_HSS_HDMA_PID_SHIFT <<
+ ICP_HSSACC_TDM_IO_UNIT_HDMA_ICR_PID_OFFSET) |
+ (tdmPbaAddresses[type][hssPortId] <<
+ ICP_HSSACC_TDM_IO_UNIT_HDMA_ICR_PBA_OFFSET);
+
+#ifdef IXP23XX
+ *icr |=
+ (ICP_HSSACC_TDM_IO_UNIT_HSS_PING_PONG_ENABLED <<
+ ICP_HSSACC_TDM_IO_UNIT_HDMA_ICR_PINGPONG_OFFSET) |
+ (ICP_HSSACC_TDM_IO_UNIT_HSS_VCH_ENABLED <<
+ ICP_HSSACC_TDM_IO_UNIT_HDMA_ICR_VOICE_CHANNELISATION_OFFSET);
+#endif
+ ICP_HSSACC_TRACE_1 (ICP_HSSACC_DEBUG,
+ "HssAccHdmaMgrICRCreate - ICR = 0x%08X\n",
+ *icr);
+
+#ifdef SW_SWAPPING
+ *icr = IX_OSAL_SWAP_BE_SHARED_LONG(*icr);
+#endif
+
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Exiting HssAccHdmaMgrICRCreate\n");
+}
+
+
+/**
+ * Function definition: HssAccHdmaMgrClkCRCreate
+ */
+void
+HssAccHdmaMgrClkCRCreate (icp_hssacc_clk_speed_t clkSpeed,
+ uint32_t *clkCR)
+{
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Entering HssAccHdmaMgrClkCRCreate\n");
+ *clkCR =
+ (hssAccHdmaSysClk[clkSpeed].main <<
+ ICP_HSSACC_TDM_IO_UNIT_HDMA_CLKCR_MAIN_OFFSET) |
+ (hssAccHdmaSysClk[clkSpeed].num <<
+ ICP_HSSACC_TDM_IO_UNIT_HDMA_CLKCR_NUM_OFFSET) |
+ (hssAccHdmaSysClk[clkSpeed].denom <<
+ ICP_HSSACC_TDM_IO_UNIT_HDMA_CLKCR_DENOM_OFFSET);
+ ICP_HSSACC_TRACE_1 (ICP_HSSACC_DEBUG,
+ "HssAccHdmaMgrClkCRCreate - CLKCR = 0x%08X\n",
+ *clkCR);
+
+#ifdef SW_SWAPPING
+ *clkCR = IX_OSAL_SWAP_BE_SHARED_LONG(*clkCR);
+#endif
+
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Exiting HssAccHdmaMgrClkCRCreate\n");
+}
+
+
+#ifdef IXP23XX
+/**
+ * Function definition: HssAccHdmaMgrVCRCreate
+ */
+void
+HssAccHdmaMgrVCRCreate (uint32_t *vcr)
+{
+ uint8_t voiceOffset = 0;
+ uint8_t lineIndex = 0;
+
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Entering HssAccHdmaMgrVCRCreate\n");
+
+ for(lineIndex = 0;
+ lineIndex < ICP_HSSACC_MAX_TDM_LINES_PER_PORT;
+ lineIndex ++)
+ {
+ if(lineIndex != 0 )
+ {
+ (*vcr) |=
+ (voiceOffset <<
+ ((lineIndex - 1) *
+ ICP_HSSACC_TDM_IO_UNIT_HDMA_VCR_FRAME_BASE_OFFSET));
+ }
+ voiceOffset += ICP_HSSACC_TDM_IO_UNIT_HSS_SUB_FRAME_DELTA_OFFSET;
+
+ }
+
+ ICP_HSSACC_TRACE_1 (ICP_HSSACC_DEBUG,
+ "HssAccHdmaMgrVCRCreate VCR = 0x%08X\n",
+ *vcr);
+
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Exiting HssAccHdmaMgrVCRCreate\n");
+}
+#endif
+
+
+/**
+ * Function definition: HssAccHdmaMgrCWRCreate
+ */
+void
+HssAccHdmaMgrCWRCreate (icp_hssacc_clk_speed_t clkSpeed,
+ uint32_t *cwr)
+{
+ uint8_t timeslotsOnLastLine = 0;
+ uint8_t numOfActiveLines = 0;
+ uint32_t cwLocation = 0;
+
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Entering HssAccHdmaMgrCWRCreate\n");
+ switch (clkSpeed)
+ {
+ case ICP_HSSACC_CLK_SPEED_1544KHZ:
+ timeslotsOnLastLine = ICP_HSSACC_TIMESLOTS_PER_T1_LINE;
+ numOfActiveLines = 1;
+ break;
+ case ICP_HSSACC_CLK_SPEED_2048KHZ:
+ timeslotsOnLastLine = ICP_HSSACC_MAX_TIMESLOTS_PER_TDM_LINE;
+ numOfActiveLines = 1;
+ break;
+ case ICP_HSSACC_CLK_SPEED_8192KHZ:
+ timeslotsOnLastLine = ICP_HSSACC_MAX_TIMESLOTS_PER_TDM_LINE;
+ numOfActiveLines = ICP_HSSACC_MAX_TDM_LINES_PER_PORT;
+ break;
+ default:
+ /* Code is not reachable under normal operation */
+ ICP_HSSACC_REPORT_ERROR ("HssAccHdmaMgrCWRCreate - invalid"
+ " clock speed\n");
+ return;
+ }
+
+
+ *cwr = /* first, shift in the enabling of the CW conditions */
+ (ICP_HSSACC_TDM_IO_UNIT_HSS_TX_CW1_ENABLED <<
+ ICP_HSSACC_TDM_IO_UNIT_HDMA_CWR_TX_CW1_ENABLE_OFFSET) |
+ (ICP_HSSACC_TDM_IO_UNIT_HSS_TX_CW2_DISABLED <<
+ ICP_HSSACC_TDM_IO_UNIT_HDMA_CWR_TX_CW2_ENABLE_OFFSET) |
+ (ICP_HSSACC_TDM_IO_UNIT_HSS_RX_CW1_ENABLED <<
+ ICP_HSSACC_TDM_IO_UNIT_HDMA_CWR_RX_CW1_ENABLE_OFFSET) |
+ (ICP_HSSACC_TDM_IO_UNIT_HSS_RX_CW2_DISABLED <<
+ ICP_HSSACC_TDM_IO_UNIT_HDMA_CWR_RX_CW2_ENABLE_OFFSET) ;
+
+ /* Calculate the location where the TDM I/O Unit is to be woken up,
+ it is at the last timeslot used on the last active line (timeslot
+ location start from 0) */
+ cwLocation = (timeslotsOnLastLine - 1) +
+ ((numOfActiveLines - 1) * ICP_HSSACC_MAX_TIMESLOTS_PER_TDM_LINE);
+ /* Now shift in the addresses of the CW offsets */
+ *cwr |=
+ (cwLocation <<
+ ICP_HSSACC_TDM_IO_UNIT_HDMA_CWR_TX_CW1_ADDRESS_OFFSET) |
+ (cwLocation <<
+ ICP_HSSACC_TDM_IO_UNIT_HDMA_CWR_RX_CW1_ADDRESS_OFFSET);
+
+ ICP_HSSACC_TRACE_1 (ICP_HSSACC_DEBUG,
+ "HssAccHdmaMgrCWRCreate CWR = 0x%08X\n",
+ *cwr);
+
+#ifdef SW_SWAPPING
+ *cwr = IX_OSAL_SWAP_BE_SHARED_LONG(*cwr);
+#endif
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Exiting HssAccHdmaMgrCWRCreate\n");
+}
diff --git a/Acceleration/library/icp_telephony/tdm_io_access/icp_hssacc_queues_config.c b/Acceleration/library/icp_telephony/tdm_io_access/icp_hssacc_queues_config.c
new file mode 100644
index 0000000..93766d5
--- /dev/null
+++ b/Acceleration/library/icp_telephony/tdm_io_access/icp_hssacc_queues_config.c
@@ -0,0 +1,1501 @@
+/******************************************************************************
+ * @file icp_hssacc_queues_config.c
+ *
+ * @description Contents of this file provide the implementation of the
+ * Tx and Rx Queues Configuration functionality
+ *
+ * @ingroup icp_HssAcc
+ *
+ * @Revision 1.0
+ *
+ * @par
+ * This file is provided under a dual BSD/GPLv2 license. When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * The full GNU General Public License is included in this distribution
+ * in the file called LICENSE.GPL.
+ *
+ * Contact Information:
+ * Intel Corporation
+ *
+ * BSD LICENSE
+ *
+ * Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ *
+ *
+ *****************************************************************************/
+#include "IxOsal.h"
+
+#include "IxQMgr.h"
+#include "icp_hssacc.h"
+#include "icp_hssacc_common.h"
+#include "icp_hssacc_trace.h"
+#include "icp_hssacc_rx_datapath.h"
+#include "icp_hssacc_queues_config.h"
+#include "icp_hssacc_address_translate.h"
+
+/*
+ * ----------------------------------------------------------------------------
+ * Macros
+ * ----------------------------------------------------------------------------
+ */
+
+/*
+ * Macros that are used to distinguish between the voice and HDLC callback
+ * routines. The same macros are used for both the Rx queues and the Rx free
+ * queues.
+ */
+#define ICP_HSSACC_VOICE_RX_QMGR_CB_ID (0)
+#define ICP_HSSACC_HDLC_RX_QMGR_CB_ID (1)
+
+
+
+#define ICP_HSSACC_CACHE_MASK (IX_OSAL_CACHE_LINE_SIZE-1)
+
+#define ICP_HSSACC_Q_NAME_SIZE 16
+#define ICP_HSSACC_Q_TYPE_NAME_SIZE 12
+
+
+
+/* Defines Virtual and Physical values for the same memory block */
+typedef struct icp_hssacc_mem_base_addr_s
+{
+ void * virt;
+ uint32_t physOffset;
+} icp_hssacc_mem_base_addr_t;
+
+/*
+ * ----------------------------------------------------------------------------
+ * Static variable declarations
+ * ----------------------------------------------------------------------------
+ */
+/* Flag used to test whether the queues have been initialised or not. */
+TDM_PRIVATE icp_boolean_t queuesConfigured = FALSE;
+
+
+/*
+ * Holds the address of the memory allocated for the queue counters.
+ */
+TDM_PRIVATE icp_hssacc_mem_base_addr_t readCountersBaseAddress =
+ {
+ NULL, 0
+ };
+
+TDM_PRIVATE icp_hssacc_mem_base_addr_t writeCountersBaseAddress =
+ {
+ NULL, 0
+ };
+
+/*
+ * the virtual Addresses of each block that will have its physical
+ * address sent to the TDM I/O Unit
+ */
+/* Block containing the Tx Queues for ALL channels */
+TDM_PRIVATE icp_hssacc_mem_base_addr_t
+txQsAddrArray[ICP_HSSACC_MAX_NUM_CHANNELS];
+
+/* Block with Rx and RxFree for HDLC */
+TDM_PRIVATE icp_hssacc_mem_base_addr_t rxHdlcQsBlockAddr =
+ {
+ NULL, 0
+ };
+/* Block with Rx and RxFree for VOICE */
+TDM_PRIVATE icp_hssacc_mem_base_addr_t rxVoiceQsBlockAddr =
+ {
+ NULL, 0
+ };
+
+/* Stores the list of Queue IDs as provided by the QMgr
+ this will be used to access the queues later.
+ we have 1 queue for each channel on Tx and 2 queues on Rx per
+ service supported */
+TDM_PRIVATE IxQMgrQId
+hssAccQueueIds[ICP_HSSACC_MAX_NUM_CHANNELS + ICP_HSSACC_NUM_RECEIVE_QS];
+
+
+TDM_PRIVATE icp_hssacc_queues_config_stats_t hssAccQueuesCfgStats;
+
+/*
+ * ----------------------------------------------------------------------------
+ * Static function declarations
+ * ----------------------------------------------------------------------------
+ */
+TDM_PRIVATE void
+HssAccQueueMemoryAlloc(icp_hssacc_mem_base_addr_t * txQsMemBaseArray,
+ icp_hssacc_mem_base_addr_t * pRxHdlcQsMemBase,
+ icp_hssacc_mem_base_addr_t * pRxVoiceQsMemBase,
+ icp_hssacc_mem_base_addr_t * pReadCounterMemBase,
+ icp_hssacc_mem_base_addr_t * pWriteCounterMemBase);
+
+TDM_PRIVATE icp_status_t
+HssAccQueuesConfig(void);
+
+TDM_PRIVATE icp_status_t
+HssAccQueueConfigMsgSubmit(uint32_t qBasePhysOffset,
+ uint32_t qDepth,
+ uint8_t msgId,
+ uint8_t msgRespId,
+ icp_hssacc_msg_with_resp_stats_t * stat);
+
+TDM_PRIVATE icp_status_t
+HssAccTxQueuesConfigMsgsSubmit(icp_hssacc_mem_base_addr_t * qTxQBaseAddresses,
+ icp_hssacc_msg_with_resp_stats_t * stat);
+
+TDM_PRIVATE icp_status_t
+HssAccQueueCounterConfigMsgSubmit(uint32_t qCounterPhysOffset,
+ uint8_t msgId,
+ uint8_t msgRespId,
+ icp_hssacc_msg_with_resp_stats_t * stat);
+
+TDM_PRIVATE icp_status_t
+HssAccTdmIOUnitQueuesConfig(void);
+
+TDM_PRIVATE icp_status_t
+HssAccTdmIOUnitQueueCountersConfig(void);
+
+
+/*
+ * ----------------------------------------------------------------------------
+ * Public function definitions
+ * ----------------------------------------------------------------------------
+ */
+/******************************************************************************
+ * Abstract:
+ * Allocates memory for all of the queues shared between the access layer
+ * and the TDM I/O unit. Also allocates memory for the head and tail
+ * counters for each queue.
+ * Verifies that the memory allocated is aligned on a cache line boundary.
+ * Registers each queue with QMgr and configures the queue watermark, etc.
+ * Submits the queue details to the TDM I/O unit.
+ *
+ *
+ *****************************************************************************/
+icp_status_t
+HssAccQueuesInit(void)
+{
+ unsigned channel = 0;
+ icp_status_t status = ICP_STATUS_SUCCESS;
+
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Entering HssAccQueuesInit\n");
+
+ if (TRUE == queuesConfigured)
+ {
+ ICP_HSSACC_REPORT_ERROR ("HssAccQueuesInit - Queues already "
+ "configured\n");
+ return ICP_STATUS_SUCCESS;
+ }
+
+ /* Allocate a block of memory for the queues and the head & tail counters */
+ HssAccQueueMemoryAlloc (txQsAddrArray,
+ &rxHdlcQsBlockAddr,
+ &rxVoiceQsBlockAddr,
+ &readCountersBaseAddress,
+ &writeCountersBaseAddress);
+
+ /* Check if the memory was correctly allocated */
+ for (channel = 0; channel < ICP_HSSACC_MAX_NUM_CHANNELS; channel++)
+ {
+ if (NULL == txQsAddrArray[channel].virt)
+ {
+ ICP_HSSACC_REPORT_ERROR_1 ("HssAccQueuesInit - "
+ "Failed to allocate Tx queue memory"
+ " for channel %d\n",
+ channel);
+ status = ICP_STATUS_FAIL;
+ break;
+ }
+ }
+
+ if ((NULL == rxHdlcQsBlockAddr.virt) ||
+ (NULL == rxVoiceQsBlockAddr.virt))
+ {
+ ICP_HSSACC_REPORT_ERROR ("HssAccQueuesInit - "
+ "Failed to allocate Rx queues memory\n");
+
+ status = ICP_STATUS_FAIL;
+ }
+
+ if ((NULL == readCountersBaseAddress.virt) ||
+ (NULL == writeCountersBaseAddress.virt))
+ {
+ ICP_HSSACC_REPORT_ERROR ("HssAccQueuesInit - "
+ "Failed to allocate queue counter memory\n");
+
+ status = ICP_STATUS_FAIL;
+ }
+
+ if (status == ICP_STATUS_SUCCESS)
+ {
+ /* Allocated memory must start on a cache boundary */
+ for (channel = 0;
+ channel < ICP_HSSACC_MAX_NUM_CHANNELS;
+ channel ++)
+ {
+ if ((((uint32_t)txQsAddrArray[channel].virt &
+ ICP_HSSACC_CACHE_MASK) != 0))
+ {
+ ICP_HSSACC_REPORT_ERROR_1 ("HssAccQueuesInit - "
+ "Allocated Tx queue memory"
+ " for channel %d is NOT on"
+ " a cache line boundary\n",
+ channel);
+ ICP_HSSACC_TRACE_1 (ICP_HSSACC_DEBUG,
+ "\tTx queue "
+ "base memory 0x%08X\n\t",
+ (uint32_t)txQsAddrArray[channel].virt);
+
+ status = ICP_STATUS_RESOURCE;
+ break;
+ }
+ }
+
+ if ((((uint32_t)rxHdlcQsBlockAddr.virt & ICP_HSSACC_CACHE_MASK) != 0) ||
+ (((uint32_t)rxVoiceQsBlockAddr.virt & ICP_HSSACC_CACHE_MASK) != 0) ||
+ (((uint32_t)readCountersBaseAddress.virt &
+ ICP_HSSACC_CACHE_MASK) != 0) ||
+ (((uint32_t)writeCountersBaseAddress.virt &
+ ICP_HSSACC_CACHE_MASK) != 0) )
+ {
+ ICP_HSSACC_REPORT_ERROR ("HssAccQueuesInit - Allocated Memory "
+ "must start on a cache line boundary\n");
+
+ ICP_HSSACC_TRACE_2 (ICP_HSSACC_DEBUG,
+ "\tqueue "
+ "read counter memory 0x%x\n\t"
+ "write counter memory 0x%x\n\t",
+ (uint32_t)readCountersBaseAddress.virt,
+ (uint32_t)writeCountersBaseAddress.virt);
+ ICP_HSSACC_TRACE_2 (ICP_HSSACC_DEBUG,
+ "\tRx Hdlc queue memory 0x%x and Rx "
+ "Voice queue memory 0x%x\n\t ",
+ (uint32_t)rxHdlcQsBlockAddr.virt,
+ (uint32_t)rxVoiceQsBlockAddr.virt);
+
+ status = ICP_STATUS_RESOURCE;
+ }
+ }
+
+ if (status == ICP_STATUS_SUCCESS)
+ {
+ /*
+ * Carve up the memory between the queues and submit the queue
+ * configuration (for each queue) to the QMgr.
+ */
+ status = HssAccQueuesConfig ();
+
+ }
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ /*
+ * Now that the Qmgr queues have been initialised, inform the
+ * TDM I/O Unit of the base address and size of each of the queues.
+ */
+ status = HssAccTdmIOUnitQueuesConfig ();
+ }
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ /*
+ * Now that the Qmgr queues have been initialised, and the queue base
+ * addresses submitted to the TDM I/O unit, submit the base address
+ * of each of the counters to TDM I/O unit.
+ */
+ status = HssAccTdmIOUnitQueueCountersConfig ();
+ }
+
+ /* This statement verifies that all queue initialisation steps succeeded */
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ /* all queues initialised and configured */
+ queuesConfigured = TRUE;
+ }
+ else
+ {
+ ICP_HSSACC_REPORT_ERROR( "HssAccQueuesInit - Cleanup\n");
+ HssAccQueuesShutdown();
+ }
+
+ /* Reset the Stats */
+ HssAccQueuesConfigStatsReset();
+
+ ICP_HSSACC_TRACE_0( ICP_HSSACC_FN_ENTRY_EXIT,
+ "Exiting HssAccQueuesInit\n" );
+
+ return status;
+}
+
+
+/*****************************************************************************
+ * Abstract:
+ * Frees the memory allocated for the queues and the queue counters, and
+ * resets the queue configuration flag.
+ *
+ *
+ *****************************************************************************/
+icp_status_t
+HssAccQueuesShutdown(void)
+{
+ unsigned channel = 0;
+ icp_status_t status = ICP_STATUS_SUCCESS;
+
+ ICP_HSSACC_TRACE_0(ICP_HSSACC_FN_ENTRY_EXIT,
+ "Entering HssAccQueuesShutdown\n" );
+
+
+ /* Best Effort cleanup, we dont care about success or failure
+ at this stage. we still try to cleanup everything. */
+ status = ixQMgrUnconfigGroup(IX_QMGR_DISPATCH_TX_HSS);
+
+ status |= ixQMgrUnconfigGroup(IX_QMGR_DISPATCH_VOICE_RX_HSS);
+
+ status |= ixQMgrUnconfigGroup(IX_QMGR_DISPATCH_HDLC_RX_HSS);
+
+ /* Only Free the memory that was allocated */
+ for (channel = 0; channel < ICP_HSSACC_MAX_NUM_CHANNELS; channel++)
+ {
+ if (NULL != txQsAddrArray[channel].virt)
+ {
+ /* Free the memory allocated for the queues */
+ IX_OSAL_CACHE_DMA_FREE(txQsAddrArray[channel].virt);
+ txQsAddrArray[channel].virt = NULL;
+
+ ICP_HSSACC_TRACE_1(ICP_HSSACC_DEBUG,
+ "HssAccQueuesShutdown - Free memory"
+ " for Tx Channel %d\n",
+ channel);
+
+ }
+ }
+
+ if (NULL != rxHdlcQsBlockAddr.virt)
+ {
+ IX_OSAL_CACHE_DMA_FREE (rxHdlcQsBlockAddr.virt);
+ rxHdlcQsBlockAddr.virt = NULL;
+ ICP_HSSACC_TRACE_0(ICP_HSSACC_DEBUG,
+ "HssAccQueuesShutdown - Free Rx Hdlc memory\n");
+
+ }
+
+ if (NULL != rxVoiceQsBlockAddr.virt)
+ {
+ IX_OSAL_CACHE_DMA_FREE (rxVoiceQsBlockAddr.virt);
+ rxVoiceQsBlockAddr.virt = NULL;
+ ICP_HSSACC_TRACE_0(ICP_HSSACC_DEBUG,
+ "HssAccQueuesShutdown - Free Rx Voice memory\n");
+
+ }
+
+ if (NULL != readCountersBaseAddress.virt)
+ {
+ /* Free the memory allocated for the queue counters */
+ IX_OSAL_CACHE_DMA_FREE (readCountersBaseAddress.virt);
+ readCountersBaseAddress.virt = NULL;
+ ICP_HSSACC_TRACE_0(ICP_HSSACC_DEBUG,
+ "HssAccQueuesShutdown - Free Read Counter memory\n");
+
+ }
+
+
+ if (NULL != writeCountersBaseAddress.virt)
+ {
+ /* Free the memory allocated for the queue counters */
+ IX_OSAL_CACHE_DMA_FREE (writeCountersBaseAddress.virt);
+ writeCountersBaseAddress.virt = NULL;
+ ICP_HSSACC_TRACE_0( ICP_HSSACC_DEBUG,
+ "HssAccQueuesShutdown - Free Write Counter memory\n");
+
+ }
+
+ /* Reset the queue configuration flag */
+ queuesConfigured = FALSE;
+
+
+ ICP_HSSACC_TRACE_0( ICP_HSSACC_FN_ENTRY_EXIT,
+ "Exiting HssAccQueuesShutdown\n" );
+ return status;
+}
+
+/*****************************************************************************
+ * Abstract:
+ * Allocates memory for all of the queues shared between the access layer
+ * and the TDM I/O unit. Also allocates memory for the head and tail
+ * counters for each queue.
+ * The memory is allocated on a cache line boundary, and each queue is an
+ * integer multiple of the cache line size. This guarantees that each queue
+ * is cache-aligned.
+ * The counter memory is also allocated on a cache boundary, and each set
+ * of counters is cache-aligned.
+ *
+ *****************************************************************************/
+TDM_PRIVATE void
+HssAccQueueMemoryAlloc(icp_hssacc_mem_base_addr_t * txQsMemBaseArray,
+ icp_hssacc_mem_base_addr_t * pRxHdlcQsMemBase,
+ icp_hssacc_mem_base_addr_t * pRxVoiceQsMemBase,
+ icp_hssacc_mem_base_addr_t * pReadCounterMemBase,
+ icp_hssacc_mem_base_addr_t * pWriteCounterMemBase)
+{
+ /*
+ * Malloc enough memory for the following queues:
+ * Voice RX free Q
+ * Voice RX Q
+ * HDLC RX free Q
+ * HDLC RX Q
+ * Max Num Chan TX Qs (1 per channel)
+ * And the Following Counters:
+ * Max Num Chan Tx Tail 8 bit ctrs (1 per chan)
+ * Max Num Chan Tx Head 8 bit ctrs (1 per chan)
+ * Voice Rx Free Head and Tail (32 bits each)
+ * HDLC Rx Free Head and Tail (32 bits each)
+ * Voice Rx Head and Tail (32 bits each)
+ * HDLC Rx Head and Tail (32 bits each)
+ */
+
+
+ /*
+ * Note 1: the rx free Q and the rx Q must be contiguous in memory.
+ * Note 2: the rx free Q and the rx Q must have the same depth.
+ * Note 3: a TX queue for an HDLC channel may be deeper than a TX queue for
+ * a Voice channel. Thus, the default TX queue depth will be that of an
+ * HDLC channel. The watermark will be moved accordingly to accomodate
+ * both depths.
+ * Each queue should be aligned on a cache line boundary, and should be a
+ * multiple of the cache line size.
+ */
+
+ uint32_t bytesToAlloc = 0;
+ unsigned channel = 0;
+
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Entering HssAccQueueMemoryAlloc\n");
+
+
+ /* Calculate the total amount of memory needed for each Tx queue */
+ bytesToAlloc = ICP_HSSACC_TX_QUEUE_SIZE_IN_BYTES;
+
+ for (channel = 0; channel < ICP_HSSACC_MAX_NUM_CHANNELS; channel++)
+ {
+ /* All queues must use memory that is aligned on a cache line boundary */
+ txQsMemBaseArray[channel].virt =
+ HssAccDmaMemAllocate(bytesToAlloc,
+ &(txQsMemBaseArray[channel].physOffset));
+ ICP_HSSACC_TRACE_4 (ICP_HSSACC_DEBUG,
+ "HssAccQueueMemoryAlloc - Allocated Tx Queue Mem from "
+ "0x%08X (phys 0x%08X) with Size %d bytes"
+ " for chan %d\n",
+ (uint32_t)(txQsMemBaseArray[channel].virt),
+ txQsMemBaseArray[channel].physOffset,
+ bytesToAlloc,
+ channel);
+ }
+
+ /* Calculate the total amount of memory needed for Rx Hdlc queues */
+ bytesToAlloc = ICP_HSSACC_HDLC_RX_QUEUE_SIZE_IN_BYTES +
+ ICP_HSSACC_HDLC_RX_FREE_QUEUE_SIZE_IN_BYTES;
+
+ /* All queues must use memory that is aligned on a cache line boundary */
+ pRxHdlcQsMemBase->virt =
+ HssAccDmaMemAllocate(bytesToAlloc,
+ &(pRxHdlcQsMemBase->physOffset));
+ ICP_HSSACC_TRACE_3 (ICP_HSSACC_DEBUG,
+ "HssAccQueueMemoryAlloc - Allocated Rx Hdlc Queue Mem "
+ "from 0x%08X (phys 0x%08X) with Size %d bytes\n",
+ (uint32_t)pRxHdlcQsMemBase->virt,
+ pRxHdlcQsMemBase->physOffset,
+ bytesToAlloc);
+
+
+ /* Calculate the total amount of memory needed for the Rx Voice queues */
+ bytesToAlloc = ICP_HSSACC_VOICE_RX_QUEUE_SIZE_IN_BYTES +
+ ICP_HSSACC_VOICE_RX_FREE_QUEUE_SIZE_IN_BYTES;
+
+ /* All queues must use memory that is aligned on a cache line boundary */
+ pRxVoiceQsMemBase->virt =
+ HssAccDmaMemAllocate(bytesToAlloc,
+ &(pRxVoiceQsMemBase->physOffset));
+ ICP_HSSACC_TRACE_3 (ICP_HSSACC_DEBUG,
+ "HssAccQueueMemoryAlloc - Allocated Rx Voice Queue Mem "
+ "from 0x%08X (phys 0x%08X) with Size %d bytes\n",
+ (uint32_t)pRxVoiceQsMemBase->virt,
+ pRxVoiceQsMemBase->physOffset,
+ bytesToAlloc);
+
+ /*
+ * Allocate memory in DRAM for the queue head & tail counters.
+ * The read (from the access layer perspective) counters need to be arranged
+ * as follows:
+ * "max num chans" bytes (packed) for the Tx tail counters. These
+ * "max num chans" bytes must be contiguous in memory.
+ * 4-byte Voice Rx free tail and 4-byte Rx head counters, which must be
+ * contiguous in memory and aligned on a cache line boundary.
+ * 4-byte HDLC Rx free tail and 4-byte Rx head counters, which must
+ * be contiguous in memory and aligned on a cache line boundary.
+ *
+ * The write counters need to be arranged as follows:
+ * "max num chans" bytes (packed) for the Tx head counters.
+ * 4-byte Voice Rx free head and 4-byte Rx tail counters, which must be
+ * contiguous in memory and aligned on a cache line boundary.
+ * 4-byte HDLC Rx free head and 4-byte Rx tail counters, which must
+ * be contiguous in memory and aligned on a cache line boundary.
+ *
+ */
+ bytesToAlloc = sizeof(icp_hssacc_queue_reader_counters_t);
+
+ pReadCounterMemBase->virt =
+ HssAccDmaMemAllocate(bytesToAlloc,
+ &(pReadCounterMemBase->physOffset));
+ ICP_HSSACC_TRACE_3 (ICP_HSSACC_DEBUG,
+ "HssAccQueueMemoryAlloc - Allocated Read Counter Memory "
+ "from 0x%08X (phys 0x%08X) with Size %d bytes\n",
+ (uint32_t)pReadCounterMemBase->virt,
+ pReadCounterMemBase->physOffset,
+ bytesToAlloc);
+
+ bytesToAlloc = sizeof(icp_hssacc_queue_write_counters_t);
+
+ pWriteCounterMemBase->virt =
+ HssAccDmaMemAllocate(bytesToAlloc,
+ &(pWriteCounterMemBase->physOffset));
+ ICP_HSSACC_TRACE_3 (ICP_HSSACC_DEBUG,
+ "HssAccQueueMemoryAlloc - Allocated Write Counter Memory "
+ "from 0x%08X (phys 0x%08X) with Size %d bytes\n",
+ (uint32_t)pWriteCounterMemBase->virt,
+ pWriteCounterMemBase->physOffset,
+ bytesToAlloc);
+
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Exiting HssAccQueueMemoryAlloc\n");
+ return;
+}
+
+
+/*****************************************************************************
+ * Abstract:
+ * Divides the queue memory between each of the queues and does likewise
+ * with the queue counter memory.
+ * Registers each queue with the QMgr and configures each queue.
+ * Configures the address of the counters to flush and invalidate for each
+ * iteration of the dispatcher loop. The counters read by the access layer
+ * will be invalidated and the counters written by the access layer will be
+ * flushed.
+ *
+ *
+ *****************************************************************************/
+TDM_PRIVATE icp_status_t
+HssAccQueuesConfig(void)
+{
+ uint32_t channel, qBaseOffset = 0;
+ IxQMgrQId qId = 0;
+ icp_status_t status = ICP_STATUS_SUCCESS;
+ icp_hssacc_queue_write_counters_t *pWriteCounters = NULL;
+ icp_hssacc_queue_reader_counters_t *pReadCounters = NULL;
+ uint8_t *pTxQueueHead = NULL;
+ uint8_t *pTxQueueTail = NULL;
+ uint32_t *pRxQueueHead = NULL;
+ uint32_t *pRxQueueTail = NULL;
+ uint32_t invalidateAddress = 0;
+ uint32_t flushAddress = 0;
+
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Entering HssAccQueuesConfig\n ");
+
+ /* Cast the counter structure to the memory allocated for the counters */
+ pWriteCounters =
+ (icp_hssacc_queue_write_counters_t *)writeCountersBaseAddress.virt;
+ pReadCounters =
+ (icp_hssacc_queue_reader_counters_t *)readCountersBaseAddress.virt;
+
+ invalidateAddress = (uint32_t)(pReadCounters->txTail);
+ flushAddress = (uint32_t)(pWriteCounters->txHead);
+
+ /*
+ * This function sets the address of the counters to be
+ * flushed/invalidated each time the QMgrDispatcher runs.
+ * The QMgr dispatcher will only check the queues that have been
+ * registered with it. In this case only the Rx queues will be serviced
+ * by the dispatcher.
+ */
+
+ /* configure the address and size to be flushed/invalidated */
+ if (ixQMgrGroupMemoryConfig (IX_QMGR_DISPATCH_TX_HSS,
+ (void *)flushAddress,
+ (void *)invalidateAddress,
+ sizeof(pReadCounters->txTail))
+ != ICP_STATUS_SUCCESS)
+ {
+ ICP_HSSACC_REPORT_ERROR("HssAccQueuesConfig - Failed Tx Queue group "
+ "configuration\n");
+ return ICP_STATUS_FAIL;
+ }
+
+ invalidateAddress = (uint32_t)&(pReadCounters->voiceRxCounters);
+ flushAddress = (uint32_t)&(pWriteCounters->voiceRxCounters);
+
+ /* configure the address and size to be flushed/invalidated for
+ voice receive q's */
+ if (ixQMgrGroupMemoryConfig (IX_QMGR_DISPATCH_VOICE_RX_HSS,
+ (void *)flushAddress,
+ (void *)invalidateAddress,
+ sizeof(pReadCounters->voiceRxCounters))
+ != ICP_STATUS_SUCCESS)
+ {
+ ICP_HSSACC_REPORT_ERROR("HssAccQueuesConfig - Failed Voice Rx "
+ "Queue group configuration\n");
+ return ICP_STATUS_FAIL;
+ }
+
+ /*
+ * Increment addresses by size of receive queue counter block
+ */
+ invalidateAddress = (uint32_t)&(pReadCounters->hdlcRxCounters);
+ flushAddress = (uint32_t)&(pWriteCounters->hdlcRxCounters);
+
+ /* configure the address and size to be flushed/invalidated for HDLC
+ receive q's */
+ if (ixQMgrGroupMemoryConfig (IX_QMGR_DISPATCH_HDLC_RX_HSS,
+ (void *)flushAddress,
+ (void *)invalidateAddress,
+ sizeof(pReadCounters->hdlcRxCounters))
+ != ICP_STATUS_SUCCESS)
+ {
+ ICP_HSSACC_REPORT_ERROR("HssAccQueuesConfig - Failed HDLC Rx Queue group "
+ "configuration\n");
+ return ICP_STATUS_FAIL;
+ }
+
+
+ /*
+ * The queues are allocated in memory in the following blocks:
+ * 1: "max num chans" Tx queues
+ * 2:Voice Rx Free queue
+ * Voice Rx queue
+ * 3:HDLC Rx Free queue
+ * HDLC Rx queue
+ * 4:Read Counters
+ * 5: Write Counters
+ */
+
+ /*
+ * Configure the Tx queues
+ */
+ for (channel = 0;
+ channel < ICP_HSSACC_MAX_NUM_CHANNELS;
+ channel ++)
+ {
+
+ char qName[ICP_HSSACC_Q_NAME_SIZE] = "HssAcc Tx Q ";
+
+ /* Append the queue number to its string identifier */
+ snprintf (&qName[ICP_HSSACC_Q_TYPE_NAME_SIZE],
+ ICP_HSSACC_Q_NAME_SIZE - ICP_HSSACC_Q_TYPE_NAME_SIZE,
+ "%u", channel);
+
+ /* Set the address of the head and tail counters for this queue */
+ pTxQueueHead = &(pWriteCounters->txHead[channel]);
+ pTxQueueTail = &(pReadCounters->txTail[channel]);
+
+ status =
+ ixQMgrQConfig (qName,
+ &qId,
+ ICP_HSSACC_TX_QUEUE_DEPTH,
+ ICP_HSSACC_QUEUE_DESC_SIZE_IN_WORDS,
+ IX_QMGR_Q_COUNT_ENTRIES,
+ IX_QMGR_Q_ALIGN_BYTE,
+ IX_QMGR_DISPATCH_TX_HSS,
+ IX_QMGR_Q_SHADOW_TAIL_ONLY,
+ txQsAddrArray[channel].virt,
+ pTxQueueHead,
+ pTxQueueTail);
+
+ if (ICP_STATUS_SUCCESS != status)
+ {
+ ICP_HSSACC_REPORT_ERROR_2 ("HssAccQueuesConfig - Failed to configure "
+ "Tx Q %u. ixQMgrQConfig() returned %u\n",
+ channel, status);
+ return ICP_STATUS_FAIL;
+ }
+
+ hssAccQueueIds[channel] = qId;
+ status = ixQMgrWatermarkSet (qId, ICP_HSSACC_TX_WATERMARK);
+ if (ICP_STATUS_SUCCESS != status)
+ {
+ ICP_HSSACC_REPORT_ERROR_2 ("HssAccQueuesConfig - Failed to set "
+ "watermark for Tx Q "
+ "%u. ixQMgrWatermarkSet() returned %u\n",
+ channel, status);
+
+ return ICP_STATUS_FAIL;
+ }
+ }
+ /*
+ * The TDM I/O Unit expects the voice Rx & Rx free queues to be contiguous
+ * in memory, with the Rx free queue preceeding the Rx queue. However, the
+ * voice Rx queue should be serviced before the voice Rx free queue.
+ * The order in which a queue is registered with the dispatcher determines
+ * the order in which it will be serviced by the QMgr dispatcher.
+ * hence all Receive Queues are first allocated then registered. registration
+ * is done at a later stage.
+ */
+
+ /*
+ * Voice Rx free queue
+ */
+
+ pRxQueueHead = &(pWriteCounters->voiceRxCounters.rxFreeHead);
+ pRxQueueTail = &(pReadCounters->voiceRxCounters.rxFreeTail);
+
+ status = ixQMgrQConfig ("Voice Rx Free Q",
+ &qId,
+ ICP_HSSACC_VOICE_RX_FREE_QUEUE_DEPTH,
+ ICP_HSSACC_QUEUE_DESC_SIZE_IN_WORDS,
+ IX_QMGR_Q_COUNT_ENTRIES,
+ IX_QMGR_Q_ALIGN_WORD,
+ IX_QMGR_DISPATCH_VOICE_RX_HSS,
+ IX_QMGR_Q_NO_SHADOWING,
+ (void*)rxVoiceQsBlockAddr.virt,
+ pRxQueueHead,
+ pRxQueueTail);
+ if (ICP_STATUS_SUCCESS != status)
+ {
+ ICP_HSSACC_REPORT_ERROR_1 ("HssAccQueuesConfig - Failed to configure "
+ "voice Rx free queue."
+ " ixQMgrQConfig() returned %u\n", status);
+ return ICP_STATUS_FAIL;
+ }
+ hssAccQueueIds[ICP_HSSACC_VOICE_RX_FREE_Q] = qId;
+
+ /*
+ * Voice Rx queue
+ */
+ qBaseOffset = ICP_HSSACC_VOICE_RX_FREE_QUEUE_SIZE_IN_BYTES;
+
+ pRxQueueHead = &(pReadCounters->voiceRxCounters.rxHead);
+ pRxQueueTail = &(pWriteCounters->voiceRxCounters.rxTail);
+
+ status =
+ ixQMgrQConfig ("Voice Rx Q",
+ &qId,
+ ICP_HSSACC_VOICE_RX_QUEUE_DEPTH,
+ ICP_HSSACC_RX_QUEUE_ENTRY_SIZE_IN_WORDS,
+ IX_QMGR_Q_COUNT_ENTRIES,
+ IX_QMGR_Q_ALIGN_WORD,
+ IX_QMGR_DISPATCH_VOICE_RX_HSS,
+ IX_QMGR_Q_NO_SHADOWING,
+ (void*)(qBaseOffset + (uint32_t)rxVoiceQsBlockAddr.virt),
+ pRxQueueHead,
+ pRxQueueTail);
+
+ if (ICP_STATUS_SUCCESS != status)
+ {
+ ICP_HSSACC_REPORT_ERROR_1 ("HssAccQueuesConfig - Failed to configure "
+ "voice Rx queue."
+ " ixQMgrQConfig() returned %u\n",
+ status);
+ return ICP_STATUS_FAIL;
+ }
+
+ hssAccQueueIds[ICP_HSSACC_VOICE_RX_Q] = qId;
+ status = ixQMgrWatermarkSet (qId, ICP_HSSACC_VOICE_RX_WATERMARK);
+ if (ICP_STATUS_SUCCESS != status)
+ {
+ ICP_HSSACC_REPORT_ERROR_1 ("HssAccQueuesConfig - Failed to set watermark "
+ "for voice Rx queue."
+ " ixQMgrWatermarkSet() returned %u\n",
+ status);
+ return ICP_STATUS_FAIL;
+ }
+
+ /* Register the callback for this Q */
+ status = ixQMgrNotificationCallbackSet (qId,
+ HssAccRxQServiceCallback,
+ ICP_HSSACC_VOICE_RX_QMGR_CB_ID);
+ if (ICP_STATUS_SUCCESS != status)
+ {
+ ICP_HSSACC_REPORT_ERROR_1 ("HssAccQueuesConfig - Failed to set "
+ "Notification callback function for voice "
+ "Rx Q. ixQMgrWatermarkSet() returned %u\n",
+ status);
+ return ICP_STATUS_FAIL;
+ }
+
+ /*
+ * HDLC Rx free queue
+ */
+
+ pRxQueueHead = &(pWriteCounters->hdlcRxCounters.rxFreeHead);
+ pRxQueueTail = &(pReadCounters->hdlcRxCounters.rxFreeTail);
+
+ status = ixQMgrQConfig ("HDLC Rx Free Q",
+ &qId,
+ ICP_HSSACC_HDLC_RX_FREE_QUEUE_DEPTH,
+ ICP_HSSACC_QUEUE_DESC_SIZE_IN_WORDS,
+ IX_QMGR_Q_COUNT_ENTRIES,
+ IX_QMGR_Q_ALIGN_WORD,
+ IX_QMGR_DISPATCH_HDLC_RX_HSS,
+ IX_QMGR_Q_NO_SHADOWING,
+ (void*)rxHdlcQsBlockAddr.virt,
+ pRxQueueHead,
+ pRxQueueTail);
+ if (ICP_STATUS_SUCCESS != status)
+ {
+ ICP_HSSACC_REPORT_ERROR_1 ("HssAccQueuesConfig - Failed to configure "
+ "HDLC Rx free queue."
+ " ixQMgrQConfig() returned %u\n", status);
+ return ICP_STATUS_FAIL;
+ }
+
+ hssAccQueueIds[ICP_HSSACC_HDLC_RX_FREE_Q] = qId;
+
+
+ /*
+ * HDLC Rx queue
+ */
+ qBaseOffset = ICP_HSSACC_HDLC_RX_FREE_QUEUE_SIZE_IN_BYTES;
+
+ pRxQueueHead = &(pReadCounters->hdlcRxCounters.rxHead);
+ pRxQueueTail = &(pWriteCounters->hdlcRxCounters.rxTail);
+
+ status =
+ ixQMgrQConfig ("HDLC Rx Q",
+ &qId,
+ ICP_HSSACC_HDLC_RX_QUEUE_DEPTH,
+ ICP_HSSACC_RX_QUEUE_ENTRY_SIZE_IN_WORDS,
+ IX_QMGR_Q_COUNT_ENTRIES,
+ IX_QMGR_Q_ALIGN_WORD,
+ IX_QMGR_DISPATCH_HDLC_RX_HSS,
+ IX_QMGR_Q_NO_SHADOWING,
+ (void*)(qBaseOffset + (uint32_t)rxHdlcQsBlockAddr.virt),
+ pRxQueueHead,
+ pRxQueueTail);
+
+ if (ICP_STATUS_SUCCESS != status)
+ {
+ ICP_HSSACC_REPORT_ERROR_1 ("HssAccQueuesConfig - Failed to configure "
+ "HDLC Rx queue."
+ " ixQMgrQConfig() returned %u\n",
+ status);
+ return ICP_STATUS_FAIL;
+ }
+
+ hssAccQueueIds[ICP_HSSACC_HDLC_RX_Q] = qId;
+ status = ixQMgrWatermarkSet (qId, ICP_HSSACC_HDLC_RX_WATERMARK);
+ if (ICP_STATUS_SUCCESS != status)
+ {
+ ICP_HSSACC_REPORT_ERROR_1 ("HssAccQueuesConfig - Failed to set watermark "
+ "for HDLC Rx queue."
+ " ixQMgrWatermarkSet() returned %u\n",
+ status);
+ return ICP_STATUS_FAIL;
+ }
+
+
+ /* Register the callback for this Q */
+ status = ixQMgrNotificationCallbackSet (qId,
+ HssAccRxQServiceCallback,
+ ICP_HSSACC_HDLC_RX_QMGR_CB_ID);
+
+ if (ICP_STATUS_SUCCESS != status)
+ {
+ ICP_HSSACC_REPORT_ERROR_1 ("HssAccQueuesConfig - Failed to set "
+ "Notification callback function for HDLC "
+ "Rx Q. ixQMgrWatermarkSet() returned %u\n",
+ status);
+ }
+
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Exiting HssAccQueuesConfig\n");
+
+ return status;
+}
+
+
+
+/******************************************************************************
+ * Abstract:
+ * Enables Notification on the Receive Queues. order of is critical here
+ * as it will determine the order of servicing in the Queue Manager Dispatcher.
+ *
+ *****************************************************************************/
+icp_status_t
+HssAccRxQueuesNotificationEnable(void)
+{
+ icp_status_t status = ICP_STATUS_SUCCESS;
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Entering HssAccRxQueuesNotificationEnable\n");
+
+ status = ixQMgrNotificationEnable (hssAccQueueIds[ICP_HSSACC_VOICE_RX_Q],
+ IX_QMGR_Q_SOURCE_ID_NOT_E);
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ status = ixQMgrNotificationEnable (hssAccQueueIds[ICP_HSSACC_HDLC_RX_Q],
+ IX_QMGR_Q_SOURCE_ID_NOT_E);
+ }
+ if (ICP_STATUS_SUCCESS != status)
+ {
+ ICP_HSSACC_REPORT_ERROR("HssAccRxQueuesNotificationEnable - "
+ "Failed to enable notifications\n");
+ }
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Exiting HssAccRxQueuesNotificationEnable\n");
+ return status;
+}
+
+
+
+/******************************************************************************
+ * Abstract:
+ * Configures all the receive queues used by the TDM I/O unit,
+ * i.e. it converts the virtual base address of the queue into a
+ * physical address and passes this address down to the TDM I/O unit.
+ * It also configures the depth of the queue.
+ *
+ *****************************************************************************/
+TDM_PRIVATE icp_status_t
+HssAccQueueConfigMsgSubmit(uint32_t qBasePhysOffset,
+ uint32_t qDepth,
+ uint8_t msgId,
+ uint8_t msgRespId,
+ icp_hssacc_msg_with_resp_stats_t * stat)
+{
+ icp_status_t status = ICP_STATUS_SUCCESS;
+ IxPiuMhMessage message;
+ uint8_t qSizeByte1, qSizeByte0 = 0;
+
+ ICP_HSSACC_TRACE_4 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Entering HssAccQueueConfigMsgSubmit - Offset=0x%08X "
+ "qDepth=0x%04X msg=0x%02X msgResp=0x%02X\n",
+ (uint32_t)qBasePhysOffset, qDepth, msgId, msgRespId);
+
+ qSizeByte1 = (qDepth&ICP_HSSACC_TDM_IO_UNIT_BYTE2_MASK) >>
+ ICP_HSSACC_TDM_IO_UNIT_BYTE2_OFFSET;
+
+ qSizeByte0 = qDepth&ICP_HSSACC_TDM_IO_UNIT_BYTE3_MASK;
+
+ /* Construct the message to configure the queue */
+ HssAccComTdmIOUnitCmd4byte1wordMsgCreate (msgId,
+ 0,
+ qSizeByte1,
+ qSizeByte0,
+ qBasePhysOffset,
+ &message);
+
+ /* Send the message to the TDM I/O Unit and wait for its reply */
+ status = HssAccComTdmIOUnitMsgSendAndRecv(message,
+ msgRespId,
+ stat,
+ NULL);
+
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Exiting HssAccQueueConfigMsgSubmit\n");
+
+ return status;
+}
+
+
+/******************************************************************************
+ * Abstract:
+ * Configures all the base addresses for the Tx Queues.
+ *
+ *****************************************************************************/
+TDM_PRIVATE icp_status_t
+HssAccTxQueuesConfigMsgsSubmit(icp_hssacc_mem_base_addr_t * pTxQBaseAddresses,
+ icp_hssacc_msg_with_resp_stats_t * stat)
+{
+
+ unsigned channel = 0;
+ icp_status_t status = ICP_STATUS_SUCCESS;
+ IxPiuMhMessage message;
+
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Entering HssAccTxQueuesConfigMsgsSubmit\n");
+
+ for (channel = 0; channel < ICP_HSSACC_MAX_NUM_CHANNELS; channel++)
+ {
+ ICP_HSSACC_TRACE_2 (ICP_HSSACC_DEBUG,
+ "HssAccTxQueuesConfigMsgsSubmit - configuring "
+ "channel %d with Offset=0x%08X\n",
+ channel,
+ pTxQBaseAddresses[channel].physOffset);
+
+ /* Construct the message to configure the queue */
+ HssAccComTdmIOUnitCmd4byte1wordMsgCreate (
+ ICP_HSSACC_TDM_IO_UNIT_TX_CHAN_Q_ADDR_CFG,
+ channel,
+ 0,
+ 0,
+ pTxQBaseAddresses[channel].physOffset,
+ &message);
+
+
+ /* Send the message to the TDM I/O Unit and wait for its reply */
+ status =
+ HssAccComTdmIOUnitMsgSendAndRecv(
+ message,
+ ICP_HSSACC_TDM_IO_UNIT_TX_CHAN_Q_ADDR_CFG_RESPONSE,
+ stat,
+ NULL);
+
+ if (ICP_STATUS_SUCCESS != status)
+ {
+ /* Error will reported in calling function */
+ ICP_HSSACC_TRACE_1 (ICP_HSSACC_DEBUG,
+ "HssAccTxQueuesConfigMsgsSubmit - Failed "
+ "configuring channel %d\n",
+ channel);
+ break;
+ }
+ }
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Exiting HssAccTxQueuesConfigMsgsSubmit\n");
+
+ return status;
+
+}
+
+
+/******************************************************************************
+ * Abstract:
+ * Converts the virtual address of the queue counter into a physical
+ * address and submits this address to the TDM I/O unit.
+ *
+ *
+ *****************************************************************************/
+TDM_PRIVATE icp_status_t
+HssAccQueueCounterConfigMsgSubmit(uint32_t qCounterPhysOffset,
+ uint8_t msgId,
+ uint8_t msgRespId,
+ icp_hssacc_msg_with_resp_stats_t * stat)
+{
+ icp_status_t status = ICP_STATUS_SUCCESS;
+ IxPiuMhMessage message;
+
+ ICP_HSSACC_TRACE_2 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Entering HssAccQueueCounterConfigMsgSubmit - "
+ "msg 0x%02X offset 0x%08X\n",
+ msgId, qCounterPhysOffset);
+
+
+ /* Construct the message to configure the queue */
+ HssAccComTdmIOUnitCmd4byte1wordMsgCreate (msgId,
+ 0,
+ 0,
+ 0,
+ qCounterPhysOffset,
+ &message);
+
+ /* Send the message to the TDM I/O Unit and wait for its reply */
+ status = HssAccComTdmIOUnitMsgSendAndRecv(message,
+ msgRespId,
+ stat,
+ NULL);
+
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Exiting HssAccQueueCounterConfigMsgSubmit\n");
+
+ return status;
+}
+
+/*****************************************************************************
+ * Abstract:
+ * Configures all of the queues used by the TDM I/O unit, i.e. it
+ * passes the phys address down to the TDM I/O unit. It also configures the
+ * depth of each queue.
+ *
+ *****************************************************************************/
+TDM_PRIVATE icp_status_t
+HssAccTdmIOUnitQueuesConfig (void)
+{
+ icp_status_t status = ICP_STATUS_SUCCESS;
+ uint32_t qDepth = 0;
+
+ ICP_HSSACC_TRACE_0(ICP_HSSACC_FN_ENTRY_EXIT,
+ "Entering HssAccTdmIOUnitQueuesConfig\n");
+
+ /*
+ * Configure the address and depth of all of the queues shared between
+ * the HssAcc I/O library and the TDM I/O unit.
+ */
+
+ /* configure Tx queues */
+ qDepth = ((ICP_HSSACC_HDLC_TX_QUEUE_DEPTH_POW_2) <<
+ ICP_HSSACC_TDM_IO_UNIT_BYTE2_OFFSET)
+ | (ICP_HSSACC_VOICE_TX_QUEUE_DEPTH_POW_2);
+
+ status =
+ HssAccQueueConfigMsgSubmit (0,
+ qDepth,
+ ICP_HSSACC_TDM_IO_UNIT_TX_Q_CFG,
+ ICP_HSSACC_TDM_IO_UNIT_TX_Q_CFG_RESPONSE,
+ &(hssAccQueuesCfgStats.txQCfg));
+ if (ICP_STATUS_SUCCESS != status)
+ {
+ ICP_HSSACC_REPORT_ERROR_1("Failed to submit Tx queue Depths "
+ "status = %u\n",
+ status);
+ }
+
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ status =
+ HssAccTxQueuesConfigMsgsSubmit(txQsAddrArray,
+ &(hssAccQueuesCfgStats.txChanQAddrCfg));
+ if (ICP_STATUS_SUCCESS != status)
+ {
+ ICP_HSSACC_REPORT_ERROR_1("Failed to submit Tx queue Base "
+ "Addresses status = %u\n",
+ status);
+ }
+ }
+
+
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ /* Configure the base address of the Voice Rx free & Rx queues */
+ status =
+ HssAccQueueConfigMsgSubmit(
+ rxVoiceQsBlockAddr.physOffset,
+ ICP_HSSACC_VOICE_RX_QUEUE_DEPTH,
+ ICP_HSSACC_TDM_IO_UNIT_VOICE_RX_Q_CFG,
+ ICP_HSSACC_TDM_IO_UNIT_VOICE_RX_Q_CFG_RESPONSE,
+ &(hssAccQueuesCfgStats.voiceRxQCfg));
+
+ if (ICP_STATUS_SUCCESS != status)
+ {
+ ICP_HSSACC_REPORT_ERROR_1("Failed to submit voice Rx queue base "
+ "address. status = %u\n", status);
+ }
+ }
+
+ /* Configure the base address of the HDLC Rx free & Rx queues */
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ status =
+ HssAccQueueConfigMsgSubmit(
+ rxHdlcQsBlockAddr.physOffset,
+ ICP_HSSACC_HDLC_RX_QUEUE_DEPTH,
+ ICP_HSSACC_TDM_IO_UNIT_HDLC_RX_Q_CFG,
+ ICP_HSSACC_TDM_IO_UNIT_HDLC_RX_Q_CFG_RESPONSE,
+ &(hssAccQueuesCfgStats.hdlcRxQCfg));
+ if (ICP_STATUS_SUCCESS != status)
+ {
+ ICP_HSSACC_REPORT_ERROR_1("Failed to submit HDLC Rx queue base "
+ "address. status = %u\n", status);
+ }
+ }
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Exiting HssAccTdmIOUnitQueuesConfig\n");
+ return status;
+}
+
+
+/*****************************************************************************
+ * Abstract:
+ * Submits the base address of each of the queue counters to the TDM I/O
+ * unit.
+ *
+ *****************************************************************************/
+TDM_PRIVATE icp_status_t
+HssAccTdmIOUnitQueueCountersConfig (void)
+{
+ icp_status_t status = ICP_STATUS_SUCCESS;
+ icp_hssacc_queue_write_counters_t *pWriteCounters = NULL;
+ icp_hssacc_queue_reader_counters_t *pReadCounters = NULL;
+
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Entering HssAccTdmIOUnitQueueCountersConfig\n");
+
+ /*
+ * Map the counter struct to the address of the memory allocated for the
+ * counters.
+ */
+ pWriteCounters =
+ (icp_hssacc_queue_write_counters_t *)writeCountersBaseAddress.physOffset;
+ pReadCounters =
+ (icp_hssacc_queue_reader_counters_t *)readCountersBaseAddress.physOffset;
+
+ /* Configure the address of the TX head counters */
+ status =
+ HssAccQueueCounterConfigMsgSubmit (
+ (uint32_t)&(pReadCounters->txTail),
+ ICP_HSSACC_TDM_IO_UNIT_TX_Q_TAIL_CTR_CFG,
+ ICP_HSSACC_TDM_IO_UNIT_TX_Q_TAIL_CTR_CFG_RESPONSE,
+ &(hssAccQueuesCfgStats.txQTailCfg));
+
+ if (ICP_STATUS_SUCCESS != status)
+ {
+ ICP_HSSACC_REPORT_ERROR_1("Failed to submit Tx Tail counter base "
+ "address. status = %u\n", status);
+ }
+ else
+ {
+
+ /* Configure the address of the TX tail counters */
+ status =
+ HssAccQueueCounterConfigMsgSubmit (
+ (uint32_t)&(pWriteCounters->txHead),
+ ICP_HSSACC_TDM_IO_UNIT_TX_Q_HEAD_CTR_CFG,
+ ICP_HSSACC_TDM_IO_UNIT_TX_Q_HEAD_CTR_CFG_RESPONSE,
+ &(hssAccQueuesCfgStats.txQHeadCfg));
+
+ if (ICP_STATUS_SUCCESS != status)
+ {
+ ICP_HSSACC_REPORT_ERROR_1("Failed to submit Tx Head counter base "
+ "address. status = %u\n", status);
+ }
+ }
+
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ /*
+ * Configure the address of the Voice Rx Free head counter and the voice
+ * Rx tail counter.
+ */
+ status =
+ HssAccQueueCounterConfigMsgSubmit (
+ (uint32_t)&(pWriteCounters->voiceRxCounters),
+ ICP_HSSACC_TDM_IO_UNIT_VOICE_RX_Q_READER_CFG,
+ ICP_HSSACC_TDM_IO_UNIT_VOICE_RX_Q_READER_CFG_RESPONSE,
+ &(hssAccQueuesCfgStats.voiceRxQReaderCfg));
+
+
+ if (ICP_STATUS_SUCCESS != status)
+ {
+ ICP_HSSACC_REPORT_ERROR_1("Failed to submit HssAcc Voice Rx Write "
+ "counters base address. status = %u\n",
+ status);
+ }
+ }
+
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ /*
+ * Configure the address of the Voice Rx Free tail counter and the voice
+ * Rx head counter.
+ */
+ status =
+ HssAccQueueCounterConfigMsgSubmit (
+ (uint32_t)&(pReadCounters->voiceRxCounters),
+ ICP_HSSACC_TDM_IO_UNIT_VOICE_RX_Q_WRITER_CFG,
+ ICP_HSSACC_TDM_IO_UNIT_VOICE_RX_Q_WRITER_CFG_RESPONSE,
+ &(hssAccQueuesCfgStats.voiceRxQWriterCfg));
+
+ if (ICP_STATUS_SUCCESS != status)
+ {
+ ICP_HSSACC_REPORT_ERROR_1("Failed to submit HssAcc Voice Rx read "
+ "counters base address. status = %u\n",
+ status);
+ }
+ }
+
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ /*
+ * Configure the address of the HDLC Rx Free head counter and the HDLC
+ * Rx tail counter.
+ */
+ status =
+ HssAccQueueCounterConfigMsgSubmit (
+ (uint32_t)&(pWriteCounters->hdlcRxCounters),
+ ICP_HSSACC_TDM_IO_UNIT_HDLC_RX_Q_READER_CFG,
+ ICP_HSSACC_TDM_IO_UNIT_HDLC_RX_Q_READER_CFG_RESPONSE,
+ &(hssAccQueuesCfgStats.hdlcRxQReaderCfg));
+
+ if (ICP_STATUS_SUCCESS != status)
+ {
+ ICP_HSSACC_REPORT_ERROR_1("Failed to submit HssAcc HDLC Rx write "
+ "counters base address. status = %u\n",
+ status);
+ }
+ }
+
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ /*
+ * Configure the address of the HDLC Rx Free tail counter and the HDLC
+ * Rx head counter.
+ */
+ status =
+ HssAccQueueCounterConfigMsgSubmit (
+ (uint32_t)&(pReadCounters->hdlcRxCounters),
+ ICP_HSSACC_TDM_IO_UNIT_HDLC_RX_Q_WRITER_CFG,
+ ICP_HSSACC_TDM_IO_UNIT_HDLC_RX_Q_WRITER_CFG_RESPONSE,
+ &(hssAccQueuesCfgStats.hdlcRxQWriterCfg));
+
+ if (ICP_STATUS_SUCCESS != status)
+ {
+ ICP_HSSACC_REPORT_ERROR_1("Failed to submit HssAcc HDLC Rx read "
+ "counters base address. status = %u\n",
+ status);
+ }
+ }
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Exiting HssAccTdmIOUnitQueueCountersConfig\n");
+
+ return status;
+}
+
+/*****************************************************************************
+ * Abstract:
+ * Updates the TDM I/O Unit with a new Q depth for a specific Q.
+ *
+ *****************************************************************************/
+icp_status_t
+HssAccQueueConfigQSizeUpdate(uint32_t channelId,
+ icp_hssacc_channel_type_t type)
+{
+ IxQMgrQSize depth = 0;
+
+ if (ICP_HSSACC_CHAN_TYPE_VOICE == type)
+ {
+ depth = ICP_HSSACC_VOICE_TX_QUEUE_DEPTH;
+ }
+ else
+ {
+ depth = ICP_HSSACC_HDLC_TX_QUEUE_DEPTH;
+ }
+ return ixQMgrQSizeReconfig (channelId, depth);
+}
+
+
+/*****************************************************************************
+ * Abstract:
+ * Retrieves the QMgr Q Id for a specific HSS Acc Queue.
+ *
+ *****************************************************************************/
+IxQMgrQId
+HssAccQueueIdGet (uint32_t qIndexId)
+{
+ return hssAccQueueIds[qIndexId];
+}
+
+
+/*****************************************************************************
+ * Abstract:
+ * Reset the Stats for this module.
+ *
+ *****************************************************************************/
+void
+HssAccQueuesConfigStatsReset (void)
+{
+ memset (&hssAccQueuesCfgStats, 0, sizeof(icp_hssacc_queues_config_stats_t));
+}
+
+
+
+/*****************************************************************************
+ * Abstract:
+ * Displays stats for this module.
+ *
+ *****************************************************************************/
+void
+HssAccQueuesConfigStatsShow (void)
+{
+ unsigned channel = 0;
+ if (TRUE == queuesConfigured)
+ {
+ for (channel = 0; channel < ICP_HSSACC_MAX_NUM_CHANNELS; channel++)
+ {
+ ixOsalLog(IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT,
+ "Tx Queue %d Base Address Location: 0x%08X\n",
+ channel,
+ (uint32_t)txQsAddrArray[channel].virt,
+ 0, 0,
+ 0, 0);
+ }
+
+ ixOsalLog(IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT,
+ "Rx Hdlc Queues Base Address Location: 0x%08X\n"
+ "Rx Voice Queues Base Address Location: 0x%08X\n"
+ "Queue Read Counter Address Location: 0x%08X\n"
+ "Queue Write Counter Address Location: 0x%08X\n",
+ (uint32_t)rxHdlcQsBlockAddr.virt,
+ (uint32_t)rxVoiceQsBlockAddr.virt,
+ (uint32_t)readCountersBaseAddress.virt,
+ (uint32_t)writeCountersBaseAddress.virt,
+ 0, 0);
+
+
+ ixOsalLog(IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT,
+ "\nQueue Configuration Statistics:\n"
+ "TX Queue Config messaging\n",
+ 0, 0, 0, 0, 0, 0);
+ HssAccSingleMessageStatsShow (hssAccQueuesCfgStats.txQCfg);
+ ixOsalLog(IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT,
+ "\nHDLC RX Queue Config messaging\n",
+ 0, 0, 0, 0, 0, 0);
+ HssAccSingleMessageStatsShow (hssAccQueuesCfgStats.hdlcRxQCfg);
+ ixOsalLog(IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT,
+ "\nVoice RX Queue Config messaging\n",
+ 0, 0, 0, 0, 0, 0);
+ HssAccSingleMessageStatsShow (hssAccQueuesCfgStats.voiceRxQCfg);
+ ixOsalLog(IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT,
+ "\nTX Q Head Counters Config messaging\n",
+ 0, 0, 0, 0, 0, 0);
+ HssAccSingleMessageStatsShow (hssAccQueuesCfgStats.txQHeadCfg);
+ ixOsalLog(IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT,
+ "\nTX Q Tail Counters Config messaging\n",
+ 0, 0, 0, 0, 0, 0);
+ HssAccSingleMessageStatsShow (hssAccQueuesCfgStats.txQTailCfg);
+ ixOsalLog(IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT,
+ "\nVoice Rx Q Reader Config messaging\n",
+ 0, 0, 0, 0, 0, 0);
+ HssAccSingleMessageStatsShow (hssAccQueuesCfgStats.voiceRxQReaderCfg);
+ ixOsalLog(IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT,
+ "\nVoice Rx Q Writer Config messaging\n",
+ 0, 0, 0, 0, 0, 0);
+ HssAccSingleMessageStatsShow (hssAccQueuesCfgStats.voiceRxQWriterCfg);
+ ixOsalLog(IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT,
+ "\nHDLC Rx Q Reader Config messaging\n",
+ 0, 0, 0, 0, 0, 0);
+ HssAccSingleMessageStatsShow (hssAccQueuesCfgStats.hdlcRxQReaderCfg);
+ ixOsalLog(IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT,
+ "\nHDLC Rx Q Writer Config messaging\n",
+ 0, 0, 0, 0, 0, 0);
+ HssAccSingleMessageStatsShow (hssAccQueuesCfgStats.hdlcRxQWriterCfg);
+ }
+
+}
diff --git a/Acceleration/library/icp_telephony/tdm_io_access/icp_hssacc_rx_datapath.c b/Acceleration/library/icp_telephony/tdm_io_access/icp_hssacc_rx_datapath.c
new file mode 100644
index 0000000..94bba23
--- /dev/null
+++ b/Acceleration/library/icp_telephony/tdm_io_access/icp_hssacc_rx_datapath.c
@@ -0,0 +1,2014 @@
+/******************************************************************************
+ * @file icp_hssacc_rx_datapath.c
+ *
+ * @description Contents of this file provide the Receive Datapath
+ * functionality for the HSS Access component
+ *
+ * @ingroup icp_HssAcc
+ *
+ * @Revision 1.0
+ *
+ * @par
+ * This file is provided under a dual BSD/GPLv2 license. When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * The full GNU General Public License is included in this distribution
+ * in the file called LICENSE.GPL.
+ *
+ * Contact Information:
+ * Intel Corporation
+ *
+ * BSD LICENSE
+ *
+ * Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ *
+ *
+ *****************************************************************************/
+
+#include "IxOsal.h"
+
+#include "icp.h"
+#include "icp_hssacc.h"
+#include "icp_hssacc_common.h"
+#include "icp_hssacc_queues_config.h"
+#include "icp_hssacc_channel_config.h"
+#include "icp_hssacc_rings.h"
+#include "icp_hssacc_tdm_io_queue_entry.h"
+#include "icp_hssacc_address_translate.h"
+#include "icp_hssacc_trace.h"
+#include "icp_hssacc_rx_datapath.h"
+
+#include "IxQMgr.h"
+
+
+/* Mutex which controls access to receive datapath service functions */
+TDM_PRIVATE IxOsalMutex hssAccRxServiceMutex[ICP_HSSACC_CHAN_TYPE_DELIMITER];
+TDM_PRIVATE
+IxOsalMutex hssAccRxFreeQServiceMutex[ICP_HSSACC_CHAN_TYPE_DELIMITER];
+
+/* Data for the descriptor to mbuf mapping queue */
+TDM_PRIVATE uint32_t
+HssAccRxDpDescPtrRingData[ICP_HSSACC_MAX_NUM_CHANNELS]
+[ICP_HSSACC_RX_DP_CHAN_DESC_PTR_RING_SZ];
+
+TDM_PRIVATE icp_hssacc_dataplane_ring_t
+HssAccRxDpDescRing[ICP_HSSACC_MAX_NUM_CHANNELS];
+
+/* Data for the descriptor to mbuf mapping queue */
+TDM_PRIVATE uint32_t
+HssAccRxDpFreeQRingData[ICP_HSSACC_CHAN_TYPE_DELIMITER]
+[ICP_HSSACC_HDLC_RX_FREE_QUEUE_DEPTH];
+
+TDM_PRIVATE icp_hssacc_dataplane_ring_t
+HssAccRxDpFreeQRing[ICP_HSSACC_CHAN_TYPE_DELIMITER];
+
+TDM_PRIVATE icp_hssacc_rx_callback_t
+HssAccRxChannelCallbacks[ICP_HSSACC_MAX_NUM_CHANNELS];
+
+TDM_PRIVATE icp_user_context_t
+HssAccRxChannelCallbackUserContexts[ICP_HSSACC_MAX_NUM_CHANNELS];
+
+TDM_PRIVATE uint32_t
+maxRxDatapathFrameSize[ICP_HSSACC_CHAN_TYPE_DELIMITER];
+
+TDM_PRIVATE icp_boolean_t
+hssAccRxServiceInitialised = ICP_FALSE;
+
+TDM_PRIVATE uint32_t
+hssAccRxDatapathNumPendPkts[ICP_HSSACC_MAX_NUM_CHANNELS];
+
+TDM_PRIVATE icp_boolean_t
+hssAccRxDatapathLastReceiveSuccess[ICP_HSSACC_MAX_NUM_CHANNELS];
+
+TDM_PRIVATE icp_boolean_t
+hssAccRxDatapathWatermarkLevelReached[ICP_HSSACC_MAX_NUM_CHANNELS];
+
+TDM_PRIVATE int32_t
+hssAccRxDatapathNumUserBuffersInRxSystem[ICP_HSSACC_CHAN_TYPE_DELIMITER];
+
+/* Stats */
+#ifndef NDEBUG
+TDM_PRIVATE uint32_t hssAccRxNumPktsAged[ICP_HSSACC_MAX_NUM_CHANNELS];
+TDM_PRIVATE uint32_t hssAccRxNumPktsReceived[ICP_HSSACC_MAX_NUM_CHANNELS];
+TDM_PRIVATE uint32_t
+hssAccRxNumPktsReplenished[ICP_HSSACC_CHAN_TYPE_DELIMITER];
+TDM_PRIVATE uint32_t hssAccRxNumReceiveFailures[ICP_HSSACC_MAX_NUM_CHANNELS];
+TDM_PRIVATE uint32_t
+hssAccRxNumReplenishFailures[ICP_HSSACC_CHAN_TYPE_DELIMITER];
+#endif
+
+
+
+/*
+ * Initialises the service mutex.
+ */
+#define ICP_HSSACC_RX_DP_SERVICE_MUTEX_INIT(service) \
+ (ixOsalMutexInit(&(hssAccRxServiceMutex[service])))
+
+/*
+ * Locks the service mutex.
+ */
+#define ICP_HSSACC_RX_DP_SERVICE_MUTEX_LOCK(service) \
+ (ixOsalMutexLock(&(hssAccRxServiceMutex[service]),ICP_HSSACC_MUTEX_TIMEOUT))
+
+/*
+ * Unlocks the service mutex.
+ */
+#define ICP_HSSACC_RX_DP_SERVICE_MUTEX_UNLOCK(service) \
+ (ixOsalMutexUnlock(&(hssAccRxServiceMutex[service])))
+
+/*
+ * Destroys the service mutex.
+ */
+#define ICP_HSSACC_RX_DP_SERVICE_MUTEX_DESTROY(service) \
+ (ixOsalMutexDestroy(&(hssAccRxServiceMutex[service])))
+
+/*
+ * Initialises the rx free q service mutex.
+ */
+#define ICP_HSSACC_RX_FREEQ_DP_SERVICE_MUTEX_INIT(service) \
+ (ixOsalMutexInit(&(hssAccRxFreeQServiceMutex[service])))
+
+/*
+ * Locks the rx free q service mutex.
+ */
+#define ICP_HSSACC_RX_FREEQ_DP_SERVICE_MUTEX_LOCK(service) \
+ (ixOsalMutexLock(&(hssAccRxFreeQServiceMutex[service]), \
+ ICP_HSSACC_MUTEX_TIMEOUT))
+
+/*
+ * Unlocks the rx free q service mutex.
+ */
+#define ICP_HSSACC_RX_FREEQ_DP_SERVICE_MUTEX_UNLOCK(service) \
+ (ixOsalMutexUnlock(&(hssAccRxFreeQServiceMutex[service])))
+
+/*
+ * Destroys the rx free q service mutex.
+ */
+#define ICP_HSSACC_RX_FREEQ_DP_SERVICE_MUTEX_DESTROY(service) \
+ (ixOsalMutexDestroy(&(hssAccRxFreeQServiceMutex[service])))
+
+
+
+
+/******************************************************************************
+ * Abstract:
+ * Return type of channel (voice or HDLC)
+ *
+ ******************************************************************************/
+TDM_PRIVATE icp_hssacc_channel_type_t
+HssAccChanTypeGet (IxQMgrQId qId)
+{
+ icp_hssacc_channel_type_t chanType = ICP_HSSACC_CHAN_TYPE_DELIMITER;
+
+ ICP_HSSACC_DP_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Entering HssAccChanTypeGet\n");
+
+ if (qId == HssAccQueueIdGet(ICP_HSSACC_HDLC_RX_Q))
+ {
+ chanType = ICP_HSSACC_CHAN_TYPE_HDLC;
+ }
+ else if (qId == HssAccQueueIdGet(ICP_HSSACC_VOICE_RX_Q))
+ {
+ chanType = ICP_HSSACC_CHAN_TYPE_VOICE;
+ }
+
+ ICP_HSSACC_DP_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Exiting HssAccChanTypeGet\n");
+ return chanType;
+}
+
+/******************************************************************************
+ * Abstract:
+ * Add hssAcc-supplied buffer to Rx Free Q for use by TDM I/O Unit
+ *
+ ******************************************************************************/
+icp_status_t
+icp_HssAccRxFreeChecklessReplenish(
+ icp_hssacc_channel_type_t channelType,
+ icp_hssacc_osal_mbuf_tdm_io_section_t *pMBufTdmIo
+ )
+{
+ icp_status_t status = ICP_STATUS_SUCCESS;
+ icp_hssacc_tdm_io_queue_entry_t qEntry;
+ icp_hssacc_tdm_io_queue_entry_t *pEntry = &qEntry;
+ IxQMgrQEntryType entry = 0;
+ IxQMgrQId qId = 0;
+ IX_OSAL_MBUF *pBuffer = NULL;
+ uint32_t buffer_len = 0;
+
+ ICP_HSSACC_DP_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Entering icp_HssAccRxFreeChecklessReplenish\n");
+ pBuffer =
+ (IX_OSAL_MBUF*) ICP_OSAL_MBUF_TDM_SECT_OSAL_MBUF_START(pMBufTdmIo);
+
+ buffer_len = IX_OSAL_MBUF_MLEN(pBuffer);
+
+ /* Set qId based on whether buffer is Voice or HDLC */
+ if (channelType == ICP_HSSACC_CHAN_TYPE_HDLC)
+ {
+ qId = HssAccQueueIdGet(ICP_HSSACC_HDLC_RX_FREE_Q);
+ }
+ else if (channelType == ICP_HSSACC_CHAN_TYPE_VOICE)
+ {
+ qId = HssAccQueueIdGet(ICP_HSSACC_VOICE_RX_FREE_Q);
+ }
+ else
+ {
+ status = ICP_STATUS_INVALID_PARAM;
+ return status;
+ }
+
+ /* Fill out Rx Free Q Entry */
+ ICP_TDM_IO_Q_ENTRY_CHANNEL_ID(pEntry) = 0;
+ ICP_TDM_IO_Q_ENTRY_STATUS(pEntry) = 0;
+
+ ICP_TDM_IO_Q_ENTRY_CURR_BUF_LEN_MSB(pEntry) =
+ ICP_OSAL_MBUF_PKT_LEN_MSB((uint16_t) buffer_len);
+
+ ICP_TDM_IO_Q_ENTRY_CURR_BUF_LEN_LSB(pEntry) =
+ ICP_OSAL_MBUF_PKT_LEN_LSB((uint16_t) buffer_len);
+
+ ICP_TDM_IO_Q_ENTRY_DATA(pEntry) =
+ (void *) HssAccVirtToPhysAddressTranslateAndSwap(
+ (void *) ICP_OSAL_MBUF_TDM_SECT_DATA(pMBufTdmIo));
+
+ ICP_TDM_IO_Q_ENTRY_PKT_LEN(pEntry) = 0;
+
+ ICP_TDM_IO_Q_ENTRY_OSAL_MBUF(pEntry) =
+ (IX_OSAL_MBUF *) HssAccVirtToPhysAddressTranslateAndSwap(
+ (void *) pMBufTdmIo);
+
+ /* Acquire service mutex */
+ if (ICP_HSSACC_RX_FREEQ_DP_SERVICE_MUTEX_LOCK(channelType) == IX_SUCCESS)
+ {
+ /* Add entry to Rx Free Q */
+ status = ixQMgrQWrite(qId, (IxQMgrQEntryType *) pEntry);
+ /* Check for overflow (only possible error returned by a Q write) */
+ if (status == ICP_STATUS_OVERFLOW)
+ {
+ ICP_HSSACC_REPORT_ERROR_1("icp_HssAccRxFreeChecklessReplenish - "
+ "Q overflow writing to Rx Free Q\n",
+ 0);
+ }
+ else
+ {
+ if ICP_HSSACC_DATAPLANE_RING_FULL(
+ HssAccRxDpFreeQRing[channelType])
+ {
+ /* If the internal ring is full, remove the oldest
+ entry before adding another one */
+ ICP_HSSACC_DATAPLANE_RING_ENTRY_REM(
+ HssAccRxDpFreeQRing[channelType], entry);
+ }
+
+ entry = (IxQMgrQEntryType)
+ ICP_OSAL_MBUF_TDM_SECT_OSAL_MBUF_START(pMBufTdmIo);
+
+ /* Add buffer to internal ring also */
+ ICP_HSSACC_DATAPLANE_RING_ENTRY_ADD(
+ HssAccRxDpFreeQRing[channelType], entry);
+ }
+
+ if (ICP_HSSACC_RX_FREEQ_DP_SERVICE_MUTEX_UNLOCK(channelType) !=
+ IX_SUCCESS)
+ {
+ if (channelType == ICP_HSSACC_CHAN_TYPE_VOICE)
+ {
+ ICP_HSSACC_REPORT_ERROR_1("icp_HssAccRxFreeChecklessReplenish - "
+ "Mutex Unlock Error for "
+ "voice service\n", 0);
+ }
+ else
+ {
+ ICP_HSSACC_REPORT_ERROR_1("icp_HssAccRxFreeChecklessReplenish - "
+ "Mutex Unlock Error for "
+ "HDLC service\n", 0);
+ }
+ status = ICP_STATUS_MUTEX;
+ }
+ }
+ else
+ {
+ if (channelType == ICP_HSSACC_CHAN_TYPE_VOICE)
+ {
+ ICP_HSSACC_REPORT_ERROR_1("icp_HssAccRxFreeChecklessReplenish - "
+ "Mutex Lock Error for "
+ "voice service\n", 0);
+ }
+ else
+ {
+ ICP_HSSACC_REPORT_ERROR_1("icp_HssAccRxFreeChecklessReplenish - "
+ "Mutex Lock Error for "
+ "HDLC service\n", 0);
+ }
+
+ status = ICP_STATUS_MUTEX;
+ }
+
+#ifndef NDEBUG
+ /* Log packet */
+ if (status != ICP_STATUS_SUCCESS)
+ {
+ hssAccRxNumReplenishFailures[channelType] ++;
+ }
+ else
+ {
+ hssAccRxNumPktsReplenished[channelType] ++;
+ }
+#endif
+
+ ICP_HSSACC_DP_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Exiting icp_HssAccRxFreeChecklessReplenish\n");
+
+ return status;
+}
+
+
+/******************************************************************************
+ * Abstract:
+ * Register rx callback and user context
+ *
+ ******************************************************************************/
+void
+HssAccChannelRxCallbackRegister(uint32_t channelId,
+ icp_hssacc_rx_callback_t rxCallback,
+ icp_user_context_t userContext)
+{
+ ICP_HSSACC_DP_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Entering HssAccChannelRxCallbackRegister\n");
+
+ HssAccRxChannelCallbacks[channelId] = rxCallback;
+ HssAccRxChannelCallbackUserContexts[channelId] = userContext;
+
+ ICP_HSSACC_DP_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Exiting HssAccChannelRxCallbackRegister\n");
+}
+
+/******************************************************************************
+ * Abstract:
+ * Register rx callback and user context
+ *
+ ******************************************************************************/
+void
+HssAccChannelRxCallbackDeregister(uint32_t channelId)
+{
+ ICP_HSSACC_DP_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Entering HssAccChannelRxCallbackDeregister\n");
+
+ HssAccRxChannelCallbacks[channelId] = NULL;
+ HssAccRxChannelCallbackUserContexts[channelId] = 0;
+
+ ICP_HSSACC_DP_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Exiting HssAccChannelRxCallbackDeregister\n");
+}
+
+/******************************************************************************
+ * Abstract:
+ * Service Rx Q and call a callback for every entry received
+ * Process receive Q, calling callbacks for each received buffer.
+ * Called from the queue processing function. The Q manager callbacks are
+ * triggered by HssAccRxDatapathService
+ *
+ ******************************************************************************/
+void
+HssAccRxQServiceCallback (IxQMgrQId qId,
+ IxQMgrCallbackId cbId)
+{
+ icp_status_t status = ICP_STATUS_SUCCESS;
+ uint32_t numEntries = 0;
+ uint32_t k = 0;
+ uint32_t chId = 0;
+ IxQMgrQEntryType qEntry = 0;
+ IxQMgrQEntryType physQEntry = 0;
+ unsigned callbacksToDo = 0;
+ icp_hssacc_osal_mbuf_tdm_io_section_t *pMBufTdmIo = NULL;
+ icp_hssacc_channel_type_t chanType = ICP_HSSACC_CHAN_TYPE_DELIMITER;
+ unsigned chanCallbackNeeded[ICP_HSSACC_MAX_NUM_CHANNELS];
+
+
+ ICP_HSSACC_DP_TRACE_2 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Entering HssAccRxQServiceCallback for "
+ "Q %d and CB Id %d\n",
+ qId, cbId);
+
+ /* Retrieve channel type */
+ chanType = HssAccChanTypeGet(qId);
+
+ memset(chanCallbackNeeded,0,ICP_HSSACC_MAX_NUM_CHANNELS*sizeof(unsigned));
+
+ /* Acquire service mutex */
+ if (IX_SUCCESS != ICP_HSSACC_RX_DP_SERVICE_MUTEX_LOCK(chanType))
+ {
+ ICP_HSSACC_REPORT_ERROR_1("HssAccRxQService - "
+ "Mutex Lock Error for service %d\n",
+ chanType);
+ return;
+ }
+
+ /* Get number of entries in q */
+ status = ixQMgrQNumEntriesGetWithChecks ( qId, &numEntries);
+
+ if (ICP_STATUS_SUCCESS != status)
+ {
+ ICP_HSSACC_REPORT_ERROR("HssAccRxQService - "
+ "Error Reading Num Entries "
+ "from the Queue\n");
+
+ if (ICP_HSSACC_RX_DP_SERVICE_MUTEX_UNLOCK(chanType) != IX_SUCCESS)
+ {
+ ICP_HSSACC_REPORT_ERROR_1("HssAccRxQService - "
+ "Mutex Unlock Error for service %d\n",
+ chanType);
+ }
+
+ return;
+ }
+
+ for (k = 0; k < numEntries; k ++)
+ {
+ status = ixQMgrQReadWithChecks (qId, &physQEntry);
+ if (ICP_STATUS_SUCCESS != status)
+ {
+ ICP_HSSACC_REPORT_ERROR("HssAccRxQServiceCallback - Error"
+ " Reading from the Queue\n");
+ continue;
+ }
+
+ /* Convert physical address (that TDM I/O Unit uses) to
+ virtual address (that Access layer uses) */
+ qEntry = (IxQMgrQEntryType)
+ HssAccPhysToVirtAddressSwapAndTranslate(physQEntry);
+
+ ICP_HSSACC_DP_TRACE_2(ICP_HSSACC_DEBUG,
+ "HssAccRxQServiceCallback - "
+ "got Phys Entry 0x%08X to Virt 0x%08X\n",
+ physQEntry,
+ qEntry);
+
+ /* Convert q Entry to a pointer to TDM I/O-specific
+ portion of OSAL MBUF */
+ pMBufTdmIo =
+ (icp_hssacc_osal_mbuf_tdm_io_section_t *) qEntry;
+ /* Retrieve channel Id */
+ chId = ICP_OSAL_MBUF_TDM_SECT_CHANNEL_ID(pMBufTdmIo);
+
+ if (ICP_HSSACC_CHANNEL_ENABLED !=
+ HssAccChannelConfigStateQuery(chId))
+ {
+ /* if channel is not enabled put the buffer on the
+ rx free q and not on the channel ring */
+ if (ICP_STATUS_SUCCESS !=
+ icp_HssAccRxFreeChecklessReplenish(chanType,
+ pMBufTdmIo))
+ {
+ ICP_HSSACC_REPORT_ERROR_1(
+ "HssAccRxQServiceCallback - "
+ " Rx Free Replenish failed for channel type %d\n",
+ chanType);
+ }
+ }
+ else
+ {
+ if (!ICP_HSSACC_DATAPLANE_RING_FULL(
+ HssAccRxDpDescRing[chId]))
+ {
+ /* VOICE PACKET AGING: check the channel type and
+ queue Level. Reject if above level and
+ previous buffer was accepted onto ring */
+ if (ICP_HSSACC_CHAN_TYPE_VOICE ==
+ HssAccChannelConfigTypeQuery(chId))
+ {
+ if(ICP_HSSACC_RX_Q_WATERMARK_LEVEL <=
+ hssAccRxDatapathNumPendPkts[chId])
+ {
+ hssAccRxDatapathWatermarkLevelReached[chId]
+ = ICP_TRUE;
+ }
+ else if ((ICP_TRUE ==
+ hssAccRxDatapathWatermarkLevelReached[chId]) &&
+ (0 == hssAccRxDatapathNumPendPkts[chId]))
+ {
+ hssAccRxDatapathWatermarkLevelReached[chId]
+ = ICP_FALSE;
+ }
+ }
+
+ if ((ICP_TRUE ==
+ hssAccRxDatapathWatermarkLevelReached[chId]) &&
+ (ICP_TRUE ==
+ hssAccRxDatapathLastReceiveSuccess[chId]))
+ {
+ /* can only be true for voice */
+ ICP_HSSACC_DP_TRACE_1(ICP_HSSACC_DEBUG,
+ "HssAccRxQServiceCallback - "
+ "Regulating Rx Flow for channel %d\n",
+ chId);
+ /* put the buffer on the rx free q and not on the
+ channel ring */
+ if (ICP_STATUS_SUCCESS !=
+ icp_HssAccRxFreeChecklessReplenish(
+ chanType,
+ pMBufTdmIo))
+ {
+ ICP_HSSACC_REPORT_ERROR_1(
+ "HssAccRxQServiceCallback - Rx Free"
+ " Replenish failed for channel type %d\n",
+ chanType);
+ }
+
+#ifndef NDEBUG
+ hssAccRxNumPktsAged[chId]++;
+#endif
+ hssAccRxDatapathLastReceiveSuccess[chId]
+ = ICP_FALSE;
+ }
+ else
+ {
+ /* Put q entry in ring associated with
+ correct channel */
+ ICP_HSSACC_DATAPLANE_RING_ENTRY_ADD(
+ HssAccRxDpDescRing[chId],
+ qEntry);
+ hssAccRxDatapathNumPendPkts[chId] ++;
+ hssAccRxDatapathLastReceiveSuccess[chId]
+ = ICP_TRUE;
+
+ /* Log which channel requires a callback and
+ increment the total num of callbacks to do */
+ if (NULL != HssAccRxChannelCallbacks[chId])
+ {
+ chanCallbackNeeded[chId] ++;
+ callbacksToDo ++;
+ }
+ }
+ }
+ else
+ {
+ ICP_HSSACC_DP_TRACE_1 (ICP_HSSACC_DEBUG,
+ "HssAccRxQServiceCallback - Internal Ring"
+ " overflow on channel %d\n",
+ chId);
+
+ /* put the buffer on the rx free q and not on the
+ channel ring */
+ if (ICP_STATUS_SUCCESS !=
+ icp_HssAccRxFreeChecklessReplenish(
+ chanType,
+ pMBufTdmIo))
+ {
+ ICP_HSSACC_REPORT_ERROR_1(
+ "HssAccRxQServiceCallback - Rx Free"
+ " Replenish failed for channel type %d\n",
+ chanType);
+ }
+
+ hssAccRxDatapathLastReceiveSuccess[chId] = ICP_FALSE;
+ continue;
+ }
+ }
+ }
+
+ if (ICP_HSSACC_RX_DP_SERVICE_MUTEX_UNLOCK(chanType) != IX_SUCCESS)
+ {
+ ICP_HSSACC_REPORT_ERROR_1("HssAccRxQServiceCallback - "
+ "Mutex Unlock Error for service %d\n",
+ chanType);
+ }
+ else
+ {
+ k = 0;
+ while (callbacksToDo)
+ {
+ while (chanCallbackNeeded[k])
+ {
+ ICP_HSSACC_DP_TRACE_2(ICP_HSSACC_DEBUG,
+ "HssAccRxQServiceCallback - channel %d, "
+ " %d callbacks left\n",
+ k, callbacksToDo-1);
+
+ HssAccRxChannelCallbacks[k](
+ HssAccRxChannelCallbackUserContexts[k]);
+ chanCallbackNeeded[k] --;
+ callbacksToDo --;
+ }
+ k ++;
+ }
+ }
+
+ ICP_HSSACC_DP_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Exiting HssAccRxQServiceCallback\n");
+
+}
+
+
+/******************************************************************************
+ * Abstract:
+ * Process receive Q *without* any calling of callbacks. Called
+ * from icp_HssAccReceive. If nothing in rx Q, returns ICP_FALSE in
+ * bufferReceived arg
+ *
+ *****************************************************************************/
+icp_status_t
+HssAccRxQService (IxQMgrQId qId,
+ unsigned channelId,
+ icp_boolean_t *bufferReceived)
+{
+ icp_status_t status = ICP_STATUS_SUCCESS;
+ uint32_t numEntries = 0;
+ uint32_t k = 0;
+ uint32_t chId = 0;
+ IxQMgrQEntryType qEntry = 0;
+ IxQMgrQEntryType physQEntry = 0;
+ icp_hssacc_osal_mbuf_tdm_io_section_t *pMBufTdmIo = NULL;
+ icp_hssacc_channel_type_t chanType = ICP_HSSACC_CHAN_TYPE_DELIMITER;
+
+ ICP_HSSACC_DP_TRACE_2 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Entering HssAccRxQService for "
+ "Q %d and channelId %d\n",
+ qId, channelId);
+
+ *bufferReceived = ICP_FALSE;
+
+ /* Retrieve channel type */
+ chanType = HssAccChanTypeGet(qId);
+
+ if (IX_SUCCESS != ICP_HSSACC_RX_DP_SERVICE_MUTEX_LOCK(chanType))
+ {
+ ICP_HSSACC_REPORT_ERROR_1("HssAccRxQService - "
+ "Mutex Lock Error for service %d\n",
+ chanType);
+ status = ICP_STATUS_MUTEX;
+ return status;
+ }
+
+ /* Get number of entries in q */
+ status = ixQMgrQNumEntriesGetWithChecks ( qId, &numEntries);
+
+ if (ICP_STATUS_SUCCESS != status)
+ {
+ ICP_HSSACC_REPORT_ERROR("HssAccRxQService - "
+ "Error Reading Num Entries "
+ "from the Queue\n");
+
+ if (ICP_HSSACC_RX_DP_SERVICE_MUTEX_UNLOCK(chanType) != IX_SUCCESS)
+ {
+ ICP_HSSACC_REPORT_ERROR_1("HssAccRxQService - "
+ "Mutex Unlock Error for service %d\n",
+ chanType);
+ }
+
+ return status;
+ }
+
+ for (k = 0; k < numEntries; k ++)
+ {
+ status = ixQMgrQReadWithChecks (qId, &physQEntry);
+
+ if (ICP_STATUS_SUCCESS != status)
+ {
+ ICP_HSSACC_REPORT_ERROR("HssAccRxQService - Error"
+ " Reading from the Queue\n");
+ continue;
+ }
+
+ /* Convert physical address (that TDM I/O Unit uses) to
+ virtual address (that Access layer uses) */
+ qEntry = (IxQMgrQEntryType)
+ HssAccPhysToVirtAddressSwapAndTranslate(physQEntry);
+
+ ICP_HSSACC_DP_TRACE_2(ICP_HSSACC_DEBUG,
+ "HssAccRxQService - "
+ "got Phys Entry 0x%08X to Virt 0x%08X\n",
+ physQEntry,
+ qEntry);
+
+ /* Convert q Entry to a pointer to TDM I/O-specific
+ portion of OSAL MBUF */
+ pMBufTdmIo =
+ (icp_hssacc_osal_mbuf_tdm_io_section_t *) qEntry;
+ /* Retrieve channel Id */
+ chId = ICP_OSAL_MBUF_TDM_SECT_CHANNEL_ID(pMBufTdmIo);
+
+ if (ICP_HSSACC_CHANNEL_ENABLED !=
+ HssAccChannelConfigStateQuery(chId))
+ {
+ /* if channel is not enabled put the buffer on the
+ rx free q and not on the channel ring */
+ if (ICP_STATUS_SUCCESS !=
+ icp_HssAccRxFreeChecklessReplenish(chanType,
+ pMBufTdmIo))
+ {
+ ICP_HSSACC_REPORT_ERROR_1(
+ "HssAccRxQService - "
+ " Rx Free Replenish failed for channel type %d\n",
+ chanType);
+ }
+ }
+ else
+ {
+ if (!ICP_HSSACC_DATAPLANE_RING_FULL(
+ HssAccRxDpDescRing[chId]))
+ {
+ /* VOICE PACKET AGING: check the channel type and
+ queue Level. Reject if above level and
+ previous buffer was accepted onto ring */
+ if (ICP_HSSACC_CHAN_TYPE_VOICE ==
+ HssAccChannelConfigTypeQuery(chId))
+ {
+ if(ICP_HSSACC_RX_Q_WATERMARK_LEVEL <=
+ hssAccRxDatapathNumPendPkts[chId])
+ {
+ hssAccRxDatapathWatermarkLevelReached[chId]
+ = ICP_TRUE;
+ }
+ else if ((ICP_TRUE ==
+ hssAccRxDatapathWatermarkLevelReached[chId]) &&
+ (0 == hssAccRxDatapathNumPendPkts[chId]))
+ {
+ hssAccRxDatapathWatermarkLevelReached[chId]
+ = ICP_FALSE;
+ }
+ }
+
+ if ((ICP_TRUE ==
+ hssAccRxDatapathWatermarkLevelReached[chId]) &&
+ (ICP_TRUE ==
+ hssAccRxDatapathLastReceiveSuccess[chId]))
+ {
+ /* can only be true for voice */
+ ICP_HSSACC_DP_TRACE_1(ICP_HSSACC_DEBUG,
+ "HssAccRxQService - "
+ "Regulating Rx Flow for channel %d\n",
+ chId);
+ /* put the buffer on the rx free q and not on the
+ channel ring */
+ if (ICP_STATUS_SUCCESS !=
+ icp_HssAccRxFreeChecklessReplenish(
+ chanType,
+ pMBufTdmIo))
+ {
+ ICP_HSSACC_REPORT_ERROR_1(
+ "HssAccRxQService - Rx Free"
+ " Replenish failed for channel type %d\n",
+ chanType);
+ }
+#ifndef NDEBUG
+ hssAccRxNumPktsAged[chId]++;
+#endif
+ hssAccRxDatapathLastReceiveSuccess[chId]
+ = ICP_FALSE;
+ }
+ else
+ {
+ /* Put q entry in ring associated with
+ correct channel */
+ ICP_HSSACC_DATAPLANE_RING_ENTRY_ADD(
+ HssAccRxDpDescRing[chId],
+ qEntry);
+ hssAccRxDatapathNumPendPkts[chId] ++;
+ hssAccRxDatapathLastReceiveSuccess[chId]
+ = ICP_TRUE;
+ if (channelId == chId)
+ {
+ ICP_HSSACC_DP_TRACE_1 (ICP_HSSACC_DEBUG,
+ "HssAccRxQService - A new "
+ "buffer was pushed into the "
+ "internal ring on channel %d\n",
+ chId);
+ /* flag a buffer has been received */
+ *bufferReceived = ICP_TRUE;
+ }
+ }
+ }
+ else
+ {
+ ICP_HSSACC_DP_TRACE_1 (ICP_HSSACC_DEBUG,
+ "HssAccRxQService - Internal Ring"
+ " overflow on channel %d\n",
+ chId);
+
+ /* put the buffer on the rx free q and not on the
+ channel ring */
+ if (ICP_STATUS_SUCCESS !=
+ icp_HssAccRxFreeChecklessReplenish(
+ chanType,
+ pMBufTdmIo))
+ {
+ ICP_HSSACC_REPORT_ERROR_1(
+ "HssAccRxQService - Rx Free"
+ " Replenish failed for channel type %d\n",
+ chanType);
+ }
+
+ hssAccRxDatapathLastReceiveSuccess[chId] = ICP_FALSE;
+ continue;
+ }
+ }
+ }
+
+ if (ICP_HSSACC_RX_DP_SERVICE_MUTEX_UNLOCK(chanType) != IX_SUCCESS)
+ {
+ ICP_HSSACC_REPORT_ERROR_1("HssAccRxQService - "
+ "Mutex Unlock Error for service %d\n",
+ chanType);
+ status = ICP_STATUS_MUTEX;
+ }
+
+ ICP_HSSACC_DP_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Exiting HssAccRxQService\n");
+
+ return status;
+
+}
+
+
+
+/******************************************************************************
+ * Abstract:
+ * Function called from icp_HssAccReceive which
+ * checks to see if there's anything in channel's internal ring.
+ * If there is, this is returned immediately, otherwise calls
+ * HssAccRxQService
+ *
+ *****************************************************************************/
+TDM_PRIVATE icp_status_t
+HssAccRxReceive (IxQMgrQId qId,
+ uint32_t channelId,
+ IX_OSAL_MBUF ** buffer)
+{
+ icp_status_t status = ICP_STATUS_SUCCESS;
+ IxQMgrQEntryType qEntry;
+ icp_hssacc_osal_mbuf_tdm_io_section_t *pMBufTdmIo;
+ icp_boolean_t bufferReceived = ICP_TRUE;
+ icp_hssacc_channel_type_t chanType = HssAccChannelConfigTypeQuery(channelId);
+
+ ICP_HSSACC_DP_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Entering HssAccRxReceive\n");
+
+ /* Return NULL buffer by default */
+ *buffer = NULL;
+
+ /* If there's anything available for channel, return it, */
+ if (ICP_HSSACC_DATAPLANE_RING_EMPTY(HssAccRxDpDescRing[channelId]))
+ {
+ /* otherwise, process queue and repeat check */
+ status = HssAccRxQService(qId, channelId, &bufferReceived);
+ }
+ else
+ {
+ bufferReceived = ICP_TRUE;
+ }
+
+ if ( (status == ICP_STATUS_SUCCESS) && (bufferReceived == ICP_TRUE) )
+ {
+
+ /* There is definitely something in channel's ring now */
+
+ /* Get an entry */
+ ICP_HSSACC_DATAPLANE_RING_ENTRY_REM(HssAccRxDpDescRing[channelId],
+ qEntry);
+ hssAccRxDatapathNumUserBuffersInRxSystem[chanType] --;
+ hssAccRxDatapathNumPendPkts[channelId] --;
+
+ /* Entry is a pointer to TDM I/O Unit-specific portion of
+ an OSAL buffer, */
+ pMBufTdmIo = (icp_hssacc_osal_mbuf_tdm_io_section_t *) qEntry;
+
+ /* look up where start of buffer is */
+ *buffer = ICP_OSAL_MBUF_TDM_SECT_OSAL_MBUF_START(pMBufTdmIo);
+ /* Set the length of received buffer in OSAL buffer fields */
+
+ IX_OSAL_MBUF_MLEN(*buffer) =
+ ( (ICP_OSAL_MBUF_TDM_SECT_CURR_BUF_LEN_MSB(pMBufTdmIo) <<
+ ICP_OSAL_MBUF_TDM_SECT_LEN_MSB_OFFSET) |
+ ICP_OSAL_MBUF_TDM_SECT_CURR_BUF_LEN_LSB(pMBufTdmIo) );
+ IX_OSAL_MBUF_PKT_LEN(*buffer) = IX_OSAL_MBUF_MLEN(*buffer);
+
+ HssAccDataEndiannessSwap(*buffer);
+
+ }/*if ( (status == ICP_STATUS_SUCCESS) && (bufferReceived == ICP_TRUE) )*/
+
+ ICP_HSSACC_DP_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Exiting HssAccRxReceive\n");
+
+ return status;
+}
+
+
+
+/******************************************************************************
+ * Abstract:
+ * This function receives a buffer. Simply checks channel type
+ * and calls HssAccRxReceive. Also logs packets.
+ *
+ *****************************************************************************/
+icp_status_t
+icp_HssAccReceive (uint32_t channelId, IX_OSAL_MBUF ** buffer)
+{
+ icp_hssacc_channel_type_t chanType = ICP_HSSACC_CHAN_TYPE_DELIMITER;
+ icp_status_t status = ICP_STATUS_SUCCESS;
+ IxQMgrQId qId = IX_QMGR_MAX_NUM_QUEUES;
+
+ ICP_HSSACC_DP_TRACE_1 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Entering icp_HssAccReceive for channel %d\n",
+ channelId);
+
+#ifndef NDEBUG
+ if (ICP_HSSACC_MAX_NUM_CHANNELS <= channelId)
+ {
+ ICP_HSSACC_REPORT_ERROR("icp_HssAccReceive - channelId "
+ "out of range\n");
+ status = ICP_STATUS_INVALID_PARAM;
+ }
+#endif
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ /* Retrieve qId for channel */
+ chanType = HssAccChannelConfigTypeQuery(channelId);
+ if (chanType == ICP_HSSACC_CHAN_TYPE_HDLC)
+ {
+ qId = HssAccQueueIdGet(ICP_HSSACC_HDLC_RX_Q);
+ }
+ else if (chanType == ICP_HSSACC_CHAN_TYPE_VOICE)
+ {
+ qId = HssAccQueueIdGet(ICP_HSSACC_VOICE_RX_Q);
+ }
+ else
+ {
+ status = ICP_STATUS_INVALID_PARAM;
+ }
+ }
+ if (status == ICP_STATUS_SUCCESS)
+ {
+ status = HssAccRxReceive(qId, channelId, buffer);
+ }
+
+#ifndef NDEBUG
+ /* Log packet */
+ if ( (status != ICP_STATUS_SUCCESS) || (*buffer == NULL) )
+ {
+ hssAccRxNumReceiveFailures[channelId] ++;
+ }
+ else
+ {
+ hssAccRxNumPktsReceived[channelId] ++;
+ }
+#endif
+
+ ICP_HSSACC_DP_TRACE_2 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Exiting icp_HssAccReceive for channel %d "
+ "with buffer 0x%08X\n",
+ channelId,
+ (uint32_t)*buffer);
+ return status;
+}
+
+
+/******************************************************************************
+ * Abstract:
+ * Function to run the Q Mgr processing function and call
+ * associated callbacks
+ *
+ ******************************************************************************/
+icp_status_t
+HssAccRxDatapathService(icp_hssacc_channel_type_t channelType)
+{
+ IxQMgrDispatchGroup group;
+ icp_status_t status = ICP_STATUS_SUCCESS;
+ ICP_HSSACC_DP_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Entering HssAccRxDatapathService\n");
+
+ /* Just call dispatcher loop for Rx Qs */
+ if (channelType == ICP_HSSACC_CHAN_TYPE_VOICE)
+ {
+ group = IX_QMGR_DISPATCH_VOICE_RX_HSS;
+ ixQMgrDispatcherLoopRun(group);
+ }
+ else if (channelType == ICP_HSSACC_CHAN_TYPE_HDLC)
+ {
+ group = IX_QMGR_DISPATCH_HDLC_RX_HSS;
+ ixQMgrDispatcherLoopRun(group);
+ }
+ else
+ {
+ status = ICP_STATUS_INVALID_PARAM;
+ }
+
+ ICP_HSSACC_DP_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Exiting HssAccRxDatapathService\n");
+ return status;
+}
+
+
+
+/******************************************************************************
+ * Abstract:
+* Reset the per-channel statistics
+*
+******************************************************************************/
+void
+HssAccRxDatapathChanStatsReset(uint32_t channelId)
+{
+#ifndef NDEBUG
+ hssAccRxNumPktsReceived[channelId] = 0;
+ hssAccRxNumReceiveFailures[channelId] = 0;
+ hssAccRxNumPktsAged[channelId] = 0;
+#endif
+}
+
+
+
+
+/******************************************************************************
+ * Abstract:
+ * Print out the per-channel statistics
+ *
+ ******************************************************************************/
+void
+HssAccRxDatapathChanStatsShow(uint32_t channelId)
+{
+#ifndef NDEBUG
+ ixOsalLog(IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT,
+ "\nRx Datapath Statistics for Channel %d\n",
+ channelId, 0, 0, 0, 0, 0);
+
+ ixOsalLog(IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT,
+ "\t\t%d Packets Received\n"
+ "\t\t%d Packet Receive Failures\n"
+ "\t\t%d Packets Aged\n",
+ hssAccRxNumPktsReceived[channelId],
+ hssAccRxNumReceiveFailures[channelId],
+ hssAccRxNumPktsAged[channelId], 0, 0, 0);
+
+#else
+ ixOsalLog(IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT,
+ "\nChannel Rx Datapath Statistics Not Supported in this Build\n",
+ 0, 0, 0, 0, 0, 0);
+#endif
+}
+
+
+
+/******************************************************************************
+ * Abstract:
+ * Function to print out stats on replenishing
+ *
+ ******************************************************************************/
+void
+HssAccRxDatapathReplenishStatsShow(icp_hssacc_channel_type_t serviceType)
+{
+#ifndef NDEBUG
+ if (serviceType == ICP_HSSACC_CHAN_TYPE_HDLC)
+ {
+ ixOsalLog(IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT,
+ "\nRx Datapath Replenish Statistics for HDLC service\n",
+ 0, 0, 0, 0, 0, 0);
+ }
+ else
+ {
+ ixOsalLog(IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT,
+ "\nRx Datapath Replenish Statistics for voice service\n",
+ 0, 0, 0, 0, 0, 0);
+ }
+ ixOsalLog(IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT,
+ "\t\t%d Packets Replenished\n"
+ "\t\t%d Packet Replenish Failures\n",
+ hssAccRxNumPktsReplenished[serviceType],
+ hssAccRxNumReplenishFailures[serviceType], 0, 0, 0, 0);
+#else
+ ixOsalLog(IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT,
+ "\nRx Datapath Service Statistics Not Supported in this Build\n",
+ 0, 0, 0, 0, 0, 0);
+#endif
+}
+
+
+
+
+/******************************************************************************
+ * Abstract:
+ * Function to reset stats on replenishing
+ *
+ *****************************************************************************/
+void
+HssAccRxDatapathReplenishStatsReset(icp_hssacc_channel_type_t serviceType)
+{
+#ifndef NDEBUG
+ hssAccRxNumPktsReplenished[serviceType] = 0;
+ hssAccRxNumReplenishFailures[serviceType] = 0;
+#endif
+}
+
+
+
+/******************************************************************************
+ * Abstract:
+ * Reset all globals
+ *
+ *****************************************************************************/
+TDM_PRIVATE icp_status_t
+HssAccRxDatapathReset(void)
+{
+ int k = 0;
+ icp_status_t status = ICP_STATUS_SUCCESS;
+
+ ICP_HSSACC_DP_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Entering HssAccRxDatapathReset\n");
+
+ for (k = 0; k < ICP_HSSACC_MAX_NUM_CHANNELS; k ++)
+ {
+
+ HssAccRxDpDescRing[k].content = &HssAccRxDpDescPtrRingData[k][0];
+ HssAccRxDpDescRing[k].size =
+ ICP_HSSACC_RX_DP_CHAN_DESC_PTR_RING_SZ;
+ HssAccRxDpDescRing[k].mask =
+ ICP_HSSACC_RX_DP_CHAN_DESC_PTR_RING_SZ - 1;
+ HssAccRxDpDescRing[k].tail = 0;
+ HssAccRxDpDescRing[k].head = 0;
+ HssAccRxChannelCallbacks[k] = NULL;
+ HssAccRxChannelCallbackUserContexts[k] = 0;
+ HssAccRxDatapathChanStatsReset(k);
+ hssAccRxDatapathNumPendPkts[k] = 0;
+ hssAccRxDatapathLastReceiveSuccess[k] = ICP_FALSE;
+ hssAccRxDatapathWatermarkLevelReached[k] = ICP_FALSE;
+ }
+
+ for (k = 0; k < ICP_HSSACC_CHAN_TYPE_DELIMITER; k ++)
+ {
+ HssAccRxDpFreeQRing[k].content = &HssAccRxDpFreeQRingData[k][0];
+ HssAccRxDpFreeQRing[k].size = ICP_HSSACC_HDLC_RX_FREE_QUEUE_DEPTH;
+ HssAccRxDpFreeQRing[k].mask = ICP_HSSACC_HDLC_RX_FREE_QUEUE_DEPTH-1;
+ HssAccRxDpFreeQRing[k].tail = 0;
+ HssAccRxDpFreeQRing[k].head = 0;
+ maxRxDatapathFrameSize[k] = 0;
+#ifndef NDEBUG
+ hssAccRxNumPktsReplenished[k] = 0;
+ hssAccRxNumReplenishFailures[k] = 0;
+#endif
+ hssAccRxDatapathNumUserBuffersInRxSystem[k] = 0;
+ }
+
+ ICP_HSSACC_DP_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Exiting HssAccRxDatapathReset\n");
+
+ return status;
+}
+
+
+
+
+/******************************************************************************
+ * Abstract:
+ * Initialise Rx datapath global variables
+ *
+ ******************************************************************************/
+icp_status_t
+HssAccRxDatapathInit(void)
+{
+ icp_status_t status = ICP_STATUS_SUCCESS;
+ uint32_t k = 0;
+
+ ICP_HSSACC_DP_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Entering HssAccRxDatapathInit\n");
+ /* Check if component has already been initialised */
+ if (ICP_TRUE == hssAccRxServiceInitialised)
+ {
+ ICP_HSSACC_REPORT_ERROR ("HssAccRxDatapathInit - "
+ "component has already been initialised\n");
+
+ status = ICP_STATUS_FAIL;
+ }
+ else /* component has never been initialised */
+ {
+
+ /* Initialise service mutexes */
+ for (k = 0; k < ICP_HSSACC_CHAN_TYPE_DELIMITER; k ++)
+ {
+ if (IX_SUCCESS != ICP_HSSACC_RX_DP_SERVICE_MUTEX_INIT(k))
+ {
+ if (k == ICP_HSSACC_CHAN_TYPE_VOICE)
+ {
+ ICP_HSSACC_REPORT_ERROR_1("HssAccRxDatapathInit - "
+ "Mutex Initialisation Error "
+ "for voice service\n", 0);
+ }
+ else
+ {
+ ICP_HSSACC_REPORT_ERROR_1("HssAccRxDatapathInit - "
+ "Mutex Initialisation "
+ "Error for HDLC service\n", 0);
+ }
+ status = ICP_STATUS_MUTEX;
+ }
+
+ if (IX_SUCCESS != ICP_HSSACC_RX_FREEQ_DP_SERVICE_MUTEX_INIT(k))
+ {
+ if (k == ICP_HSSACC_CHAN_TYPE_VOICE)
+ {
+ ICP_HSSACC_REPORT_ERROR_1("HssAccRxDatapathInit - Rx Free "
+ "Q Mutex Initialisation Error "
+ "for voice service\n", 0);
+ }
+ else
+ {
+ ICP_HSSACC_REPORT_ERROR_1("HssAccRxDatapathInit - Rx Free "
+ "Q Mutex Initialisation "
+ "Error for HDLC service\n", 0);
+ }
+ status = ICP_STATUS_MUTEX;
+ }
+ }
+
+ if (status == ICP_STATUS_SUCCESS)
+ {
+ status = HssAccRxDatapathReset();
+ if (status == ICP_STATUS_SUCCESS)
+ {
+ hssAccRxServiceInitialised = ICP_TRUE;
+ }
+ }
+ }
+
+ ICP_HSSACC_DP_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Exiting HssAccRxDatapathInit\n");
+ return status;
+}
+
+
+
+
+/******************************************************************************
+ * Abstract:
+ * Shut down Rx datapath Module.
+ *
+ *****************************************************************************/
+icp_status_t
+HssAccRxDatapathShutdown(void)
+{
+ icp_status_t status = ICP_STATUS_SUCCESS;
+ uint32_t k = 0;
+
+ ICP_HSSACC_DP_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Entering HssAccRxDatapathShutdown\n");
+
+ /* Check if component has not been initialised */
+ if (ICP_FALSE == hssAccRxServiceInitialised)
+ {
+ ICP_HSSACC_REPORT_ERROR ("HssAccRxDatapathShutdown - "
+ "component has not been initialised\n");
+ status = ICP_STATUS_FAIL;
+ }
+ else /* component has been initialised */
+ {
+ status = HssAccRxDatapathReset();
+
+ if (status == ICP_STATUS_SUCCESS)
+ {
+
+ /* Destroy service mutexes */
+ for (k = 0; k < ICP_HSSACC_CHAN_TYPE_DELIMITER; k ++)
+ {
+ if (IX_SUCCESS != ICP_HSSACC_RX_DP_SERVICE_MUTEX_DESTROY(k))
+ {
+ ICP_HSSACC_REPORT_ERROR_1("HssAccRxDatapathShutdown - "
+ "Mutex Destroy Error for "
+ "service %d\n",
+ k);
+ status = ICP_STATUS_MUTEX;
+ ICP_HSSACC_DP_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Exiting HssAccRxDatapathShutdown\n");
+ return status;
+ }
+
+ if (IX_SUCCESS != ICP_HSSACC_RX_FREEQ_DP_SERVICE_MUTEX_DESTROY(k))
+ {
+ ICP_HSSACC_REPORT_ERROR_1("HssAccRxDatapathShutdown - Rx "
+ "Free Q Mutex Destroy Error for "
+ "service %d\n",
+ k);
+ status = ICP_STATUS_MUTEX;
+ ICP_HSSACC_DP_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Exiting HssAccRxDatapathShutdown\n");
+ return status;
+ }
+ }
+ }
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ hssAccRxServiceInitialised = ICP_FALSE;
+ }
+ }
+
+ ICP_HSSACC_DP_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Exiting HssAccRxDatapathShutdown\n");
+ return status;
+}
+
+
+/******************************************************************************
+ * Abstract:
+ * Add user-supplied buffer to Rx Free Q for use by TDM I/O Unit
+ *
+ ******************************************************************************/
+icp_status_t
+icp_HssAccRxFreeReplenish (
+ icp_hssacc_channel_type_t channelType,
+ IX_OSAL_MBUF *buffer)
+{
+ icp_status_t status = ICP_STATUS_SUCCESS;
+ icp_hssacc_osal_mbuf_tdm_io_section_t *pMBufTdmIo;
+ uint32_t buffer_len = 0;
+
+ ICP_HSSACC_DP_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Entering icp_HssAccRxFreeReplenish\n");
+
+ if (channelType != ICP_HSSACC_CHAN_TYPE_HDLC
+ && channelType != ICP_HSSACC_CHAN_TYPE_VOICE)
+ {
+ status = ICP_STATUS_INVALID_PARAM;
+ return status;
+ }
+
+ /* Check that buffer is not NULL */
+ if (buffer == NULL)
+ {
+ ICP_HSSACC_REPORT_ERROR("icp_HssAccRxFreeReplenish - "
+ "Buffer pointer is NULL\n");
+ ICP_HSSACC_DP_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Exiting icp_HssAccRxFreeReplenish\n");
+ status = ICP_STATUS_INVALID_PARAM;
+ return status;
+ }
+
+ /* Check that buffer is not chained. We do not support chaining. */
+ if ((IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR(buffer) != NULL) ||
+ (IX_OSAL_MBUF_NEXT_PKT_IN_CHAIN_PTR(buffer) != NULL))
+ {
+ ICP_HSSACC_REPORT_ERROR("icp_HssAccRxFreeReplenish - "
+ "Buffer or Packet Chaining not supported "
+ "for reception\n");
+ status = ICP_STATUS_INVALID_PARAM;
+ }
+
+ if (IX_OSAL_MBUF_MDATA(buffer) == NULL)
+ {
+ ICP_HSSACC_REPORT_ERROR("icp_HssAccRxFreeReplenish - "
+ "Buffer's data pointer cannot be NULL\n");
+ status = ICP_STATUS_INVALID_PARAM;
+ }
+
+ /* Check if buffer length supplied is ok.
+ All buffers supplied need to accomodate the max frame size possible */
+ buffer_len = IX_OSAL_MBUF_MLEN(buffer);
+ if ( buffer_len < maxRxDatapathFrameSize[channelType])
+ {
+ ICP_HSSACC_REPORT_ERROR("icp_HssAccRxFreeReplenish - "
+ "Buffer is too small. Buffers supplied "
+ "must all accomodate max frame size\n");
+ status = ICP_STATUS_INVALID_PARAM;
+ }
+
+ if (status == ICP_STATUS_SUCCESS)
+ {
+
+ /* check chan type and compare num bufs in rx path to size of rx free q */
+ if (channelType == ICP_HSSACC_CHAN_TYPE_VOICE)
+ {
+ if(ICP_HSSACC_VOICE_RX_QUEUE_DEPTH
+ <= hssAccRxDatapathNumUserBuffersInRxSystem
+ [ICP_HSSACC_CHAN_TYPE_VOICE])
+ {
+ ICP_HSSACC_REPORT_ERROR_1("icp_HssAccRxFreeReplenish - "
+ "Voice Rx Datapath Max Buffer Limit Reached\n",
+ 0);
+ status = ICP_STATUS_OVERFLOW;
+ }
+ }
+ else
+ {
+ if(ICP_HSSACC_HDLC_RX_QUEUE_DEPTH
+ <= hssAccRxDatapathNumUserBuffersInRxSystem
+ [ICP_HSSACC_CHAN_TYPE_HDLC])
+ {
+ ICP_HSSACC_REPORT_ERROR_1("icp_HssAccRxFreeReplenish - "
+ "HDLC Rx Datapath Max Buffer Limit Reached\n",
+ 0);
+ status = ICP_STATUS_OVERFLOW;
+ }
+ }
+
+ if (status == ICP_STATUS_SUCCESS)
+ {
+ /* Add buffer to relevant Rx free Q */
+
+ /* First, copy info from OSAL buffer to TDM I/O
+ Unit-specific portion */
+ /* Get address of TDM I/O Unit-specific portion of OSAL buffer */
+ pMBufTdmIo =
+ (icp_hssacc_osal_mbuf_tdm_io_section_t *) &(buffer->ix_ne);
+
+ /* Copy current buffer data location */
+ ICP_OSAL_MBUF_TDM_SECT_DATA(pMBufTdmIo) =
+ (void *) IX_OSAL_MBUF_MDATA(buffer);
+
+ /* Copy current buffer location */
+ ICP_OSAL_MBUF_TDM_SECT_OSAL_MBUF_START(pMBufTdmIo) = buffer;
+
+ status = icp_HssAccRxFreeChecklessReplenish (channelType,
+ pMBufTdmIo);
+
+ if ( ICP_STATUS_SUCCESS == status )
+ {
+ hssAccRxDatapathNumUserBuffersInRxSystem[channelType] ++;
+ }
+
+ }
+
+ }
+
+ return status;
+}
+
+
+
+/******************************************************************************
+ * Abstract:
+ * Set max frame size for HDLC, must be done at init
+ *
+ *****************************************************************************/
+void
+HssAccRxDatapathHdlcInit(uint32_t maxRxFrameSize)
+{
+ ICP_HSSACC_DP_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Entering HssAccRxDatapathHdlcInit\n");
+ maxRxDatapathFrameSize[ICP_HSSACC_CHAN_TYPE_HDLC] = maxRxFrameSize;
+
+ ICP_HSSACC_DP_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Exiting HssAccRxDatapathHdlcInit\n");
+}
+
+
+
+
+/******************************************************************************
+ * Abstract:
+ * Set max frame size for voice, must be done at init
+ *
+ *****************************************************************************/
+void
+HssAccRxDatapathVoiceInit(uint32_t maxRxFrameSize)
+{
+ ICP_HSSACC_DP_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Entering HssAccRxDatapathVoiceInit\n");
+ maxRxDatapathFrameSize[ICP_HSSACC_CHAN_TYPE_VOICE] = maxRxFrameSize;
+
+ ICP_HSSACC_DP_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Exiting HssAccRxDatapathVoiceInit\n");
+}
+
+
+/******************************************************************************
+ * Abstract:
+ * Return the Max Rx Sample/Frame size configured for the specified Service
+ *
+ *****************************************************************************/
+uint32_t
+HssAccRxDatapathMaxServiceFrameSizeGet(icp_hssacc_channel_type_t servType)
+{
+ ICP_HSSACC_DP_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Called HssAccRxDatapathMaxServiceFrameSizeGet\n");
+ return maxRxDatapathFrameSize[servType];
+}
+
+
+
+
+/******************************************************************************
+ * Abstract:
+ * Checks to see if any channels exist for a specified service other than
+ * the one being worked on.
+ *
+ *****************************************************************************/
+icp_boolean_t
+HssAccRxDatapathServAllChansDisabledQuery(icp_hssacc_channel_type_t chanType,
+ const unsigned channelId)
+{
+ uint32_t chanId = 0;
+
+ ICP_HSSACC_DP_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Entering "
+ "HssAccRxDatapathServAllChansDisabledQuery\n");
+
+ for (chanId=0; chanId < ICP_HSSACC_MAX_NUM_CHANNELS; chanId ++)
+ {
+ if (chanType == HssAccChannelConfigTypeQuery(chanId) )
+ {
+ if ((HssAccChannelConfigStateQuery(chanId) !=
+ ICP_HSSACC_CHANNEL_UNINITIALISED) &&
+ (chanId != channelId))
+ {
+ ICP_HSSACC_DP_TRACE_1 (ICP_HSSACC_DEBUG,
+ "HssAccRxDatapathServAllChansDisabledQuery -"
+ " Found channel %u\n",
+ chanId);
+ ICP_HSSACC_DP_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Exiting "
+ "HssAccRxDatapathServAllChans"
+ "DisabledQuery\n");
+ return ICP_FALSE;
+ }
+ }
+ }
+ ICP_HSSACC_DP_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Exiting "
+ "HssAccRxDatapathServAllChansDisabledQuery\n");
+ return ICP_TRUE;
+}
+
+
+/******************************************************************************
+ * Abstract:
+ * Retrieve all buffers left in a specific service RxFree queue
+ *
+ *****************************************************************************/
+icp_status_t
+HssAccRxDatapathServiceSpecificRxFreeEmpty(icp_hssacc_channel_type_t chanType,
+ IX_OSAL_MBUF * * ppStartChainBuffer,
+ IX_OSAL_MBUF * * ppEndChainBuffer)
+{
+ icp_status_t status = ICP_STATUS_SUCCESS;
+ IX_OSAL_MBUF * pCurrentBuffer = NULL;
+ IxQMgrQId rxfreeqId = IX_QMGR_MAX_NUM_QUEUES;
+ IxQMgrQId rxqId = IX_QMGR_MAX_NUM_QUEUES;
+ unsigned numEntries = 0;
+ IxQMgrQEntryType freeQEntry;
+ icp_boolean_t bufferReceived = ICP_FALSE;
+
+ ICP_HSSACC_DP_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Entering HssAccRxDatapathServiceSpecificRxFreeEmpty\n");
+
+ if (chanType == ICP_HSSACC_CHAN_TYPE_HDLC)
+ {
+ rxfreeqId = HssAccQueueIdGet(ICP_HSSACC_HDLC_RX_FREE_Q);
+ rxqId = HssAccQueueIdGet(ICP_HSSACC_HDLC_RX_Q);
+ }
+ else if (chanType == ICP_HSSACC_CHAN_TYPE_VOICE)
+ {
+ rxfreeqId = HssAccQueueIdGet(ICP_HSSACC_VOICE_RX_FREE_Q);
+ rxqId = HssAccQueueIdGet(ICP_HSSACC_VOICE_RX_Q);
+ }
+ else
+ {
+ status = ICP_STATUS_INVALID_PARAM;
+ return status;
+ }
+
+ /* the important part here is to drain the rx queue
+ into the rx free queue */
+ if (ICP_STATUS_SUCCESS !=
+ (status = HssAccRxQService(rxqId,
+ ICP_HSSACC_MAX_NUM_CHANNELS,
+ &bufferReceived) ))
+ {
+ return status;
+ }
+
+ /* Acquire service mutex */
+ if (IX_SUCCESS != ICP_HSSACC_RX_DP_SERVICE_MUTEX_LOCK(chanType))
+ {
+ if (chanType == ICP_HSSACC_CHAN_TYPE_VOICE)
+ {
+ ICP_HSSACC_REPORT_ERROR(
+ "HssAccRxDatapathServiceSpecificRxFreeEmpty - "
+ "Mutex Lock Error for "
+ "voice service\n");
+ }
+ else
+ {
+ ICP_HSSACC_REPORT_ERROR(
+ "HssAccRxDatapathServiceSpecificRxFreeEmpty - "
+ "Mutex Lock Error for "
+ "HDLC service\n");
+ }
+ ICP_HSSACC_DP_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Exiting HssAccRxDatapathServiceSpecificRxFreeEmpty\n");
+ return ICP_STATUS_MUTEX;
+ }
+
+ status = ixQMgrQNumEntriesGet (rxfreeqId,
+ &numEntries);
+
+ /* Chain all Rx free Q Buffers */
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ ICP_HSSACC_DP_TRACE_0 (ICP_HSSACC_DEBUG,
+ "HssAccRxDatapathServiceSpecificRxFreeEmpty - "
+ "Create Chain with Rx Free Buffers\n");
+ /* First of all read out useless entries in the ring
+ that mirrors the Rx Free Q */
+ while (ICP_HSSACC_DATAPLANE_RING_NUM_ENTRIES_GET(
+ HssAccRxDpFreeQRing[chanType]) >
+ numEntries)
+ {
+ ICP_HSSACC_DATAPLANE_RING_TAIL_INCR(HssAccRxDpFreeQRing[chanType]);
+ }
+
+ /* Wind back write pointer to Rx Free Q by number of
+ entries in Q */
+ status = ixQMgrQWriteRollback(rxfreeqId, numEntries);
+ }
+
+ if (status == ICP_STATUS_SUCCESS)
+ {
+ /* add an entry from free Q to start */
+ if ((0 != numEntries) &&
+ (!ICP_HSSACC_DATAPLANE_RING_EMPTY(HssAccRxDpFreeQRing[chanType])))
+ {
+
+ /* Remove entry from internal ring mirroring
+ entries in Rx Free Q */
+ /* Difference between ring and Q is that ring holds
+ pointers to buffers, not Rx Free Q entries */
+ ICP_HSSACC_DATAPLANE_RING_ENTRY_REM(
+ HssAccRxDpFreeQRing[chanType], freeQEntry);
+
+ hssAccRxDatapathNumUserBuffersInRxSystem[chanType] --;
+ numEntries --;
+ *ppStartChainBuffer = (IX_OSAL_MBUF *) freeQEntry;
+ pCurrentBuffer = *ppStartChainBuffer;
+ }
+ while (!ICP_HSSACC_DATAPLANE_RING_EMPTY(HssAccRxDpFreeQRing[chanType]))
+ {
+ /* Remove entry from internal ring mirroring
+ entries in Rx Free Q */
+ ICP_HSSACC_DATAPLANE_RING_ENTRY_REM(
+ HssAccRxDpFreeQRing[chanType],
+ freeQEntry);
+ if (NULL == pCurrentBuffer)
+ {
+ ICP_HSSACC_REPORT_ERROR(
+ "HssAccRxDatapathServiceSpecificRxFreeEmpty - "
+ "Corrupted Internal Receive Free ring\n");
+ status = ICP_STATUS_FATAL;
+ break;
+ }
+
+ hssAccRxDatapathNumUserBuffersInRxSystem[chanType] --;
+
+ IX_OSAL_MBUF_NEXT_PKT_IN_CHAIN_PTR(pCurrentBuffer) =
+ (IX_OSAL_MBUF *) freeQEntry;
+ pCurrentBuffer = (IX_OSAL_MBUF *) freeQEntry;
+ }
+ }
+
+
+ *ppEndChainBuffer = pCurrentBuffer;
+
+
+
+if (ICP_HSSACC_RX_DP_SERVICE_MUTEX_UNLOCK(chanType) !=
+ IX_SUCCESS)
+ {
+ if (chanType == ICP_HSSACC_CHAN_TYPE_VOICE)
+ {
+ ICP_HSSACC_REPORT_ERROR("HssAccRxDatapathServiceSpecificRxFreeEmpty -"
+ " Mutex Unlock Error for "
+ "voice service\n");
+ }
+ else
+ {
+ ICP_HSSACC_REPORT_ERROR("HssAccRxDatapathServiceSpecificRxFreeEmpty -"
+ " Mutex Unlock Error for "
+ "HDLC service\n");
+ }
+ status = ICP_STATUS_MUTEX;
+ }
+
+
+ICP_HSSACC_DP_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Exiting HssAccRxDatapathServiceSpecificRxFreeEmpty\n");
+return status;
+}
+
+
+
+/******************************************************************************
+ * Abstract:
+ * Retrieve all buffers left in a specific service RxFree queue
+ * if this is the last channel
+ *
+ *****************************************************************************/
+icp_status_t
+HssAccRxDatapathRxFreeEmpty(unsigned channelId,
+ icp_hssacc_channel_type_t chanType,
+ IX_OSAL_MBUF * * ppStartChainBuffer,
+ IX_OSAL_MBUF * * ppEndChainBuffer)
+{
+ icp_status_t status = ICP_STATUS_SUCCESS;
+
+ ICP_HSSACC_DP_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Entering HssAccRxDatapathRxFreeEmpty\n");
+
+ /* Are all channels disabled for this service?
+ (except for channelId) */
+ if (HssAccRxDatapathServAllChansDisabledQuery(chanType,
+ channelId) == ICP_TRUE)
+ {
+ /* Retrieve rxfree and rx qIds for channel */
+ if (chanType != ICP_HSSACC_CHAN_TYPE_HDLC &&
+ chanType != ICP_HSSACC_CHAN_TYPE_VOICE)
+ {
+ status = ICP_STATUS_INVALID_PARAM;
+ }
+ else
+ {
+ status = HssAccRxDatapathServiceSpecificRxFreeEmpty(
+ chanType,
+ ppStartChainBuffer,
+ ppEndChainBuffer);
+
+/*unit test code uses ixQMgrWrite() directly - bypassing the
+ internal hssAcc counter*/
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ if (0 != hssAccRxDatapathNumUserBuffersInRxSystem[chanType])
+ {
+ ICP_HSSACC_REPORT_ERROR_1("HssAccRxDatapathRxFreeEmpty - "
+ "Tracked number of user buffers in rx system "
+ "(%d) != 0\n",
+ hssAccRxDatapathNumUserBuffersInRxSystem[chanType]);
+ }
+ }
+ }
+ }
+
+ ICP_HSSACC_DP_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Exiting HssAccRxDatapathRxFreeEmpty\n");
+
+ return status;
+}
+
+
+/******************************************************************************
+ * Abstract:
+ * Retrieve all buffers in a chain from both Voice and HDLC Rx Free Qs where
+ * there are no channels enabled for the particular service
+ *
+ *****************************************************************************/
+icp_status_t
+HssAccRxFreeQsBufsRetrieve(IX_OSAL_MBUF * * ppStartChainBuffer,
+ IX_OSAL_MBUF * * ppEndChainBuffer)
+{
+ icp_status_t status = ICP_STATUS_SUCCESS;
+ icp_boolean_t chainStarted = ICP_FALSE;
+ IX_OSAL_MBUF * pStartChainRxFreeBuffer = NULL;
+ IX_OSAL_MBUF * pEndChainRxFreeBuffer = NULL;
+ int k = 0;
+
+ ICP_HSSACC_DP_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Entering HssAccRxFreeQsBufsRetrieve ");
+
+ for (k = 0; k < ICP_HSSACC_CHAN_TYPE_DELIMITER; k ++)
+ {
+ /* ICP_HSSACC_MAX_NUM_CHANNELS is used so the
+ internal check is on all channels of type k */
+ if (HssAccRxDatapathServAllChansDisabledQuery(
+ k,
+ ICP_HSSACC_MAX_NUM_CHANNELS)
+ == ICP_TRUE)
+ {
+ pStartChainRxFreeBuffer = NULL;
+ pEndChainRxFreeBuffer = NULL;
+
+ status = HssAccRxDatapathServiceSpecificRxFreeEmpty(
+ k,
+ &pStartChainRxFreeBuffer,
+ &pEndChainRxFreeBuffer);
+
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ if (NULL != pStartChainRxFreeBuffer)
+ {
+ if (ICP_TRUE == chainStarted)
+ {
+ IX_OSAL_MBUF_NEXT_PKT_IN_CHAIN_PTR(*ppEndChainBuffer)
+ = pStartChainRxFreeBuffer;
+ }
+ else
+ {
+ *ppStartChainBuffer = pStartChainRxFreeBuffer;
+ }
+ *ppEndChainBuffer = pEndChainRxFreeBuffer;
+
+ chainStarted = ICP_TRUE;
+ }
+ }
+ }
+ }
+
+ ICP_HSSACC_DP_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Exiting HssAccRxFreeQsBufsRetrieve\n");
+ return status;
+}
+
+
+/******************************************************************************
+ * Abstract:
+ * Retrieve all buffers in a chain from Rx Ring for a specified channel
+ *
+ *****************************************************************************/
+icp_status_t
+HssAccRxDatapathChanBufsRetrieve(uint32_t channelId,
+ IX_OSAL_MBUF * * ppStartChainBuffer,
+ IX_OSAL_MBUF * * ppEndChainBuffer)
+{
+ icp_status_t status = ICP_STATUS_SUCCESS;
+ uint32_t numEntries = 0;
+ uint32_t entry = 0;
+ icp_hssacc_osal_mbuf_tdm_io_section_t *pMBufTdmIo = NULL;
+ IX_OSAL_MBUF * pCurrentBuffer = NULL;
+ icp_boolean_t chainStarted = ICP_FALSE;
+ icp_hssacc_channel_type_t chanType = ICP_HSSACC_CHAN_TYPE_DELIMITER;
+ IX_OSAL_MBUF * pStartChainRxFreeBuffer = NULL;
+ IX_OSAL_MBUF * pEndChainRxFreeBuffer = NULL;
+
+ ICP_HSSACC_DP_TRACE_1 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Entering HssAccRxDatapathChanBufsRetrieve "
+ "for channel %d\n",
+ channelId);
+
+ /* Process receive Q */
+ chanType = HssAccChannelConfigTypeQuery(channelId);
+
+ if (chanType != ICP_HSSACC_CHAN_TYPE_HDLC &&
+ chanType != ICP_HSSACC_CHAN_TYPE_VOICE)
+ {
+ status = ICP_STATUS_INVALID_PARAM;
+ }
+
+ if (status == ICP_STATUS_SUCCESS)
+ {
+ numEntries =
+ ICP_HSSACC_DATAPLANE_RING_NUM_ENTRIES_GET(
+ HssAccRxDpDescRing[channelId]);
+
+ /* Special case for starting the Chain */
+ if (numEntries != 0)
+ {
+
+ ICP_HSSACC_DP_TRACE_0 (ICP_HSSACC_DEBUG,
+ "HssAccRxDatapathChanBufsRetrieve - "
+ "Start retrieving buffers\n");
+ numEntries --;
+ ICP_HSSACC_DATAPLANE_RING_ENTRY_REM(HssAccRxDpDescRing[channelId],
+ entry);
+ hssAccRxDatapathNumPendPkts[channelId] --;
+ hssAccRxDatapathNumUserBuffersInRxSystem[chanType] --;
+
+ /* Entry is a pointer to TDM I/O Unit-specific
+ portion of an OSAL buffer, */
+ pMBufTdmIo =
+ (icp_hssacc_osal_mbuf_tdm_io_section_t *) entry;
+ /* look up where start of buffer is */
+ if (NULL == pMBufTdmIo)
+ {
+ ICP_HSSACC_REPORT_ERROR("HssAccRxDatapathChanBufsRetrieve - "
+ "Corrupted Internal Receive ring\n");
+ return ICP_STATUS_FATAL;
+ }
+ *ppStartChainBuffer =
+ ICP_OSAL_MBUF_TDM_SECT_OSAL_MBUF_START(pMBufTdmIo);
+ if (NULL == *ppStartChainBuffer)
+ {
+ ICP_HSSACC_REPORT_ERROR("HssAccRxDatapathChanBufsRetrieve - "
+ "Corrupted Receive Entry\n");
+ return ICP_STATUS_FATAL;
+ }
+
+ pCurrentBuffer = *ppStartChainBuffer;
+ *ppEndChainBuffer = pCurrentBuffer;
+ chainStarted = ICP_TRUE;
+#ifndef NDEBUG
+ hssAccRxNumPktsReceived[channelId] ++;
+#endif
+ }
+
+ }
+
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ ICP_HSSACC_DP_TRACE_0 (ICP_HSSACC_DEBUG,
+ "HssAccRxDatapathChanBufsRetrieve - "
+ "Create Chain with Rx'ed Buffers\n");
+
+ while (!ICP_HSSACC_DATAPLANE_RING_EMPTY(HssAccRxDpDescRing[channelId]))
+ {
+ ICP_HSSACC_DATAPLANE_RING_ENTRY_REM(HssAccRxDpDescRing[channelId],
+ entry);
+ numEntries --;
+ hssAccRxDatapathNumPendPkts[channelId] --;
+ hssAccRxDatapathNumUserBuffersInRxSystem[chanType] --;
+
+ /* Entry is a pointer to TDM I/O-specific portion
+ of an OSAL buffer, */
+ pMBufTdmIo =
+ (icp_hssacc_osal_mbuf_tdm_io_section_t *) entry;
+ if (NULL == pMBufTdmIo)
+ {
+ ICP_HSSACC_REPORT_ERROR("HssAccRxDatapathChanBufsRetrieve"
+ " - Corrupted Internal Receive "
+ "ring\n");
+ status = ICP_STATUS_FATAL;
+ break;
+ }
+ /* look up where start of buffer is */
+ IX_OSAL_MBUF_NEXT_PKT_IN_CHAIN_PTR(pCurrentBuffer) =
+ ICP_OSAL_MBUF_TDM_SECT_OSAL_MBUF_START(pMBufTdmIo);
+
+ pCurrentBuffer =
+ ICP_OSAL_MBUF_TDM_SECT_OSAL_MBUF_START(pMBufTdmIo);
+#ifndef NDEBUG
+ hssAccRxNumPktsReceived[channelId] ++;
+#endif
+ }
+ *ppEndChainBuffer = pCurrentBuffer;
+
+ }
+
+
+ if (ICP_STATUS_SUCCESS == status)
+ {
+
+ /* Second Stage: If no channel left enabled for this service,
+ return all buffers in rx Free Q */
+ /* Check if we started a chain previously or not */
+ status = HssAccRxDatapathRxFreeEmpty(channelId,
+ chanType,
+ &pStartChainRxFreeBuffer,
+ &pEndChainRxFreeBuffer);
+ if (NULL != pStartChainRxFreeBuffer)
+ {
+ if (ICP_TRUE == chainStarted)
+ {
+ IX_OSAL_MBUF_NEXT_PKT_IN_CHAIN_PTR(*ppEndChainBuffer) =
+ pStartChainRxFreeBuffer;
+ }
+ else
+ {
+ *ppStartChainBuffer = pStartChainRxFreeBuffer;
+ }
+ *ppEndChainBuffer = pEndChainRxFreeBuffer;
+ }
+ }
+
+ ICP_HSSACC_DP_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Exiting HssAccRxDatapathChanBufsRetrieve\n");
+
+ return status;
+}
diff --git a/Acceleration/library/icp_telephony/tdm_io_access/icp_hssacc_service.c b/Acceleration/library/icp_telephony/tdm_io_access/icp_hssacc_service.c
new file mode 100644
index 0000000..71e0fbd
--- /dev/null
+++ b/Acceleration/library/icp_telephony/tdm_io_access/icp_hssacc_service.c
@@ -0,0 +1,2579 @@
+/******************************************************************************
+ * @file icp_hssacc_service.c
+ *
+ * @description Contents of this file provides the implementation of the
+ * HSS Service functions
+ *
+ * @ingroup icp_HssAcc
+ *
+ * @Revision 1.0
+ *
+ * @par
+ * This file is provided under a dual BSD/GPLv2 license. When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved.
+ * Copyright(c) 2010,2011,2012 Avencall
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * The full GNU General Public License is included in this distribution
+ * in the file called LICENSE.GPL.
+ *
+ * BSD LICENSE
+ *
+ * Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ * Copyright(c) 2010,2011,2012 Avencall
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ *
+ *
+ *****************************************************************************/
+
+/* ----------------------------------------------------------------------------
+ * Includes
+ * ----------------------------------------------------------------------------
+ */
+#include "IxOsal.h"
+
+#include "icp.h"
+#include "icp_hssacc.h"
+#include "icp_hssacc_common.h"
+#include "icp_hssacc_port_config.h"
+#include "icp_hssacc_channel_config.h"
+#include "icp_hssacc_queues_config.h"
+#include "icp_hssacc_channel_list.h"
+#include "icp_hssacc_voice_bypass.h"
+#include "icp_hssacc_timeslot_allocation.h"
+#include "icp_hssacc_tx_datapath.h"
+#include "icp_hssacc_trace.h"
+#include "icp_hssacc_rx_datapath.h"
+
+
+
+/*
+ * ----------------------------------------------------------------------------
+ * Global variables
+ * ----------------------------------------------------------------------------
+ */
+/* Mutex which controls access to control path functions */
+IxOsalMutex hssAccControlPathMutex;
+
+/* Flag to test whether the HssAcc component has been initialised or not. */
+TDM_PRIVATE icp_boolean_t serviceInitialised = ICP_FALSE;
+
+/* Stats */
+typedef struct icp_hssacc_service_stats_s
+{
+/* Internal stats for Timer configuraton messaging */
+ icp_hssacc_msg_with_resp_stats_t timerStat;
+ icp_hssacc_msg_with_resp_stats_t intStat;
+ icp_hssacc_msg_with_resp_stats_t abtAlnRead;
+ icp_hssacc_msg_with_resp_stats_t fcsMaxRead;
+ icp_hssacc_msg_with_resp_stats_t chanStatRead;
+ icp_hssacc_msg_with_resp_stats_t swErrRead;
+ icp_hssacc_msg_with_resp_stats_t swErrReset;
+} icp_hssacc_service_stats_t;
+
+TDM_PRIVATE icp_hssacc_service_stats_t hssAccServStats;
+
+/* Data structure containing all registered callbacks
+ for all channels and ports */
+TDM_PRIVATE icp_hssacc_port_error_callback_t
+hssAccPortErrorCb[ICP_HSSACC_MAX_NUM_PORTS][ICP_HSSACC_CHAN_TYPE_DELIMITER];
+
+TDM_PRIVATE icp_hssacc_error_callback_t
+hssAccErrorCb[ICP_HSSACC_CHAN_TYPE_DELIMITER];
+
+
+TDM_PRIVATE icp_user_context_t
+hssAccPortErrorCtxt[ICP_HSSACC_MAX_NUM_PORTS][ICP_HSSACC_CHAN_TYPE_DELIMITER];
+
+TDM_PRIVATE icp_user_context_t
+hssAccErrorCtxt[ICP_HSSACC_CHAN_TYPE_DELIMITER];
+
+TDM_PRIVATE uint32_t
+hssAccStaticErrorBitmask = 0;
+
+TDM_PRIVATE icp_boolean_t voiceIntEnabled = ICP_FALSE;
+TDM_PRIVATE icp_boolean_t hdlcIntEnabled = ICP_FALSE;
+
+/*
+ * ----------------------------------------------------------------------------
+ * Function definitions
+ * ----------------------------------------------------------------------------
+ */
+TDM_PRIVATE icp_status_t
+HssAccTdmIOUnitErrorMhCbRegister (IxPiuMhCallback callback);
+
+void
+HssAccTdmIOUnitErrorCallback(IxPiuMhPiuId piuId, IxPiuMhMessage message);
+
+void
+HssAccPortErrorDummyClientCb (icp_user_context_t userContext,
+ icp_hssacc_port_error_t errorType);
+
+void
+HssAccErrorDummyClientCb (icp_user_context_t userContext,
+ icp_hssacc_error_t errorType);
+
+TDM_PRIVATE icp_status_t
+HssAccTdmIOErrorStatsShow (void);
+
+TDM_PRIVATE icp_status_t
+HssAccSwErrorStatsShow (void);
+
+TDM_PRIVATE icp_status_t
+HssAccSwErrorStatsReset (void);
+
+TDM_PRIVATE icp_status_t
+HssAccChannelTdmIOErrorStatsShow(unsigned channelId);
+
+TDM_PRIVATE icp_status_t
+HssAccChannelTdmIOErrorStatsReset(unsigned channelId);
+
+TDM_PRIVATE void
+HssAccServiceStatsReset (void);
+
+TDM_PRIVATE void
+HssAccServiceStatsShow (void);
+
+TDM_PRIVATE icp_status_t
+HssAccServiceIntGenUpdate (void);
+
+/*****************************************************************************
+ * Abstract:
+ * Sets up the Dual coprocessor instructions in the TDM I/O Unit
+ *
+ *****************************************************************************/
+TDM_PRIVATE icp_status_t
+HssAccTdmUnitDualInstSet (void)
+{
+ icp_status_t status = ICP_STATUS_SUCCESS;
+ uint32_t appDualId = 0;
+ IxPiuDlAppDualInstruction appDualInstruction;
+
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Entering HssAccTdmUnitDualInstSet\n");
+
+#if defined(__ep805xx)
+ appDualInstruction.copr0 = ICP_HSSACC_TDM_IO_UNIT_CPP_COPROC;
+ appDualInstruction.inst0 = ICP_HSSACC_TDM_IO_UNIT_CPP_RD_WORD_INST;
+ appDualInstruction.copr1 = ICP_HSSACC_TDM_IO_UNIT_SDC_COPROC;
+ appDualInstruction.inst1 = ICP_HSSACC_TDM_IO_UNIT_SDC_WR_HDLC_INST;
+ status = ixPiuDlAppDualSet (
+ IX_PIUDL_PIUID_PIU0,
+ appDualId,
+ &appDualInstruction);
+ if ( ICP_STATUS_SUCCESS != status )
+ {
+ ICP_HSSACC_REPORT_ERROR ("HssAccTdmUnitDualInstSet - "
+ "Failed to set Application "
+ "specific dual in TDM I/O Unit\n");
+
+ return ICP_STATUS_FATAL;
+ }
+
+ appDualId++;
+ appDualInstruction.copr0 = ICP_HSSACC_TDM_IO_UNIT_SDC_COPROC;
+ appDualInstruction.inst0 = ICP_HSSACC_TDM_IO_UNIT_SDC_RD_HDLC_INST;
+ appDualInstruction.copr1 = ICP_HSSACC_TDM_IO_UNIT_CPP_COPROC;
+ appDualInstruction.inst1 = ICP_HSSACC_TDM_IO_UNIT_CPP_WR_WORD_INST;
+
+ status = ixPiuDlAppDualSet (
+ IX_PIUDL_PIUID_PIU0,
+ appDualId,
+ &appDualInstruction);
+ if ( ICP_STATUS_SUCCESS != status )
+ {
+ ICP_HSSACC_REPORT_ERROR ("HssAccTdmUnitDualInstSet - "
+ "Failed to set Application "
+ "specific dual in TDM I/O Unit\n");
+
+ return ICP_STATUS_FATAL;
+ }
+
+
+ appDualId++;
+ appDualInstruction.copr0 = ICP_HSSACC_TDM_IO_UNIT_CPP_COPROC;
+ appDualInstruction.inst0 = ICP_HSSACC_TDM_IO_UNIT_CPP_RD_WORD_INST;
+ appDualInstruction.copr1 = ICP_HSSACC_TDM_IO_UNIT_SDC_COPROC;
+ appDualInstruction.inst1 = ICP_HSSACC_TDM_IO_UNIT_SDC_WR_VOICE_INST;
+ status = ixPiuDlAppDualSet (
+ IX_PIUDL_PIUID_PIU0,
+ appDualId,
+ &appDualInstruction);
+ if ( ICP_STATUS_SUCCESS != status )
+ {
+ ICP_HSSACC_REPORT_ERROR ("HssAccTdmUnitDualInstSet - "
+ "Failed to set Application "
+ "specific dual in TDM I/O Unit\n");
+
+ return ICP_STATUS_FATAL;
+ }
+
+ appDualId++;
+ appDualInstruction.copr0 = ICP_HSSACC_TDM_IO_UNIT_SDC_COPROC;
+ appDualInstruction.inst0 = ICP_HSSACC_TDM_IO_UNIT_SDC_RD_VOICE_INST;
+ appDualInstruction.copr1 = ICP_HSSACC_TDM_IO_UNIT_CPP_COPROC;
+ appDualInstruction.inst1 = ICP_HSSACC_TDM_IO_UNIT_CPP_WR_WORD_INST;
+
+ status = ixPiuDlAppDualSet (
+ IX_PIUDL_PIUID_PIU0,
+ appDualId,
+ &appDualInstruction);
+ if ( ICP_STATUS_SUCCESS != status )
+ {
+ ICP_HSSACC_REPORT_ERROR ("HssAccTdmUnitDualInstSet - "
+ "Failed to set Application "
+ "specific dual in TDM I/O Unit\n");
+
+ return ICP_STATUS_FATAL;
+ }
+
+
+#endif
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Exiting HssAccTdmUnitDualInstSet\n");
+ return status;
+}
+
+
+
+/******************************************************************************
+ * Abstract:
+ * Initializes the HSS I/O Access library for the HSS TDM I/O Unit.
+ * This function is responsible for initialising resources for use by
+ * this component. It should be called before any other HSS Access
+ * function is called. Default values for configuration items affecting
+ * all ports will not be set-up; it is up to the client to call the
+ * relevant port configuration functions before enabling the port.
+ *
+ *
+ *****************************************************************************/
+icp_status_t
+icp_HssAccInit(void)
+{
+ icp_status_t status = ICP_STATUS_SUCCESS;
+ unsigned index = 0;
+ IxPiuMhMessage message;
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Entering HssAccInit\n");
+
+ /* Check if component is already initialised */
+ if (ICP_TRUE == serviceInitialised)
+ {
+ ICP_HSSACC_REPORT_ERROR ("icp_HssAccInit - "
+ "component has already been initialised\n");
+
+ status = ICP_STATUS_FAIL;
+ }
+ else /* component has never been initialised */
+ {
+ /* Initialise the Service Mutex */
+ if (ICP_STATUS_SUCCESS != ICP_HSSACC_MUTEX_INIT())
+ {
+ ICP_HSSACC_REPORT_ERROR ("icp_HssAccInit - "
+ "failed to initialise HssAcc Mutex\n");
+ status = ICP_STATUS_MUTEX;
+ }
+ }
+
+ if (status == ICP_STATUS_SUCCESS)
+ {
+ if (ICP_STATUS_SUCCESS != ICP_HSSACC_MUTEX_LOCK())
+ {
+ ICP_HSSACC_REPORT_ERROR ("icp_HssAccInit - "
+ "failed to lock HssAcc Mutex\n");
+ status = ICP_STATUS_MUTEX;
+ }
+ else
+ {
+ HssAccServiceStatsReset();
+
+ if(ICP_STATUS_SUCCESS == status)
+ {
+ if( (ICP_STATUS_SUCCESS == HssAccTdmUnitDualInstSet() ) &&
+ (ICP_STATUS_SUCCESS == HssAccPortConfigInit()) &&
+ (ICP_STATUS_SUCCESS == HssAccChannelConfigInit()) &&
+ (ICP_STATUS_SUCCESS == HssAccQueuesInit() ) &&
+ (ICP_STATUS_SUCCESS == HssAccTxDatapathInit()) &&
+ (ICP_STATUS_SUCCESS == HssAccRxDatapathInit()) &&
+ (ICP_STATUS_SUCCESS == HssAccTdmIOUnitErrorMhCbRegister
+ (HssAccTdmIOUnitErrorCallback) ))
+ {
+ HssAccVoiceBypassInit();
+
+ /* Reset all Error Callbacks for the component,
+ port Error Callbacks and service Errors callbacks */
+ for (index =0; index < ICP_HSSACC_MAX_NUM_PORTS; index ++)
+ {
+ hssAccPortErrorCb[index][ICP_HSSACC_CHAN_TYPE_VOICE] =
+ HssAccPortErrorDummyClientCb;
+ hssAccPortErrorCtxt[index][ICP_HSSACC_CHAN_TYPE_VOICE] =
+ (icp_user_context_t)index;
+ hssAccPortErrorCb[index][ICP_HSSACC_CHAN_TYPE_HDLC] =
+ HssAccPortErrorDummyClientCb;
+ hssAccPortErrorCtxt[index][ICP_HSSACC_CHAN_TYPE_HDLC] =
+ (icp_user_context_t)index;
+ }
+ hssAccErrorCb[ICP_HSSACC_CHAN_TYPE_VOICE] =
+ HssAccErrorDummyClientCb;
+ hssAccErrorCb[ICP_HSSACC_CHAN_TYPE_HDLC] =
+ HssAccErrorDummyClientCb;
+ hssAccErrorCtxt[ICP_HSSACC_CHAN_TYPE_VOICE] =
+ (icp_user_context_t)ICP_HSSACC_CHAN_TYPE_VOICE;
+ hssAccErrorCtxt[ICP_HSSACC_CHAN_TYPE_HDLC] =
+ (icp_user_context_t)ICP_HSSACC_CHAN_TYPE_HDLC;
+ }
+ else
+ {
+ ICP_HSSACC_REPORT_ERROR ("icp_HssAccInit - one or more "
+ "modules failed to initialise\n");
+
+ status = HssAccPortConfigShutdown();
+ status = HssAccChannelConfigShutdown();
+ status = HssAccQueuesShutdown();
+ status = HssAccTxDatapathShutdown();
+ status = HssAccRxDatapathShutdown();
+ /* This will deregister the Callback */
+ status = HssAccTdmIOUnitErrorMhCbRegister(NULL);
+ status = ICP_STATUS_FAIL;
+ }
+ }
+ /* Last Step enable notifications with the QMgr
+ for the Receive Side */
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ if (ICP_STATUS_SUCCESS == HssAccRxQueuesNotificationEnable())
+ {
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_DEBUG,
+ "HssAccInit - Service has "
+ "successfully initialised\n");
+ hssAccStaticErrorBitmask = 0;
+ serviceInitialised = ICP_TRUE;
+ }
+ else
+ {
+ ICP_HSSACC_REPORT_ERROR ("icp_HssAccInit - "
+ "failed notification enable\n");
+ status = HssAccVoiceBypassShutdown();
+ status = HssAccPortConfigShutdown();
+ status = HssAccChannelConfigShutdown();
+ status = HssAccQueuesShutdown();
+ status = HssAccTxDatapathShutdown();
+ status = HssAccRxDatapathShutdown();
+ /* This will deregister the Callback */
+ status = HssAccTdmIOUnitErrorMhCbRegister(NULL);
+ status = ICP_STATUS_FAIL;
+ }
+ }
+ /* Set the Timer interval for the TDM I/O Unit to enable the Unit */
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ /* Construct the message to configure the queue */
+ HssAccComTdmIOUnitCmd4byte1wordMsgCreate (
+ ICP_HSSACC_TDM_IO_UNIT_HSS_TIMER_CFG,
+ 0,
+ 0,
+ 0,
+ ICP_HSSACC_TDM_IO_UNIT_HSS_TIMER_INTERVAL,
+ &message);
+
+ /* Send the message to the TDM I/O Unit and wait for its reply */
+ if (ICP_STATUS_SUCCESS ==
+ HssAccComTdmIOUnitMsgSendAndRecv(
+ message,
+ ICP_HSSACC_TDM_IO_UNIT_HSS_TIMER_CFG_RESPONSE,
+ &(hssAccServStats.timerStat),
+ NULL) )
+ {
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_DEBUG,
+ "HssAccInit - Timer Interval "
+ "Set\n");
+ }
+ else
+ {
+
+ ICP_HSSACC_REPORT_ERROR ("icp_HssAccInit - "
+ "failed Timer Interval Set\n");
+ status = HssAccVoiceBypassShutdown();
+ status = HssAccPortConfigShutdown();
+ status = HssAccChannelConfigShutdown();
+ status = HssAccQueuesShutdown();
+ status = HssAccTxDatapathShutdown();
+ status = HssAccRxDatapathShutdown();
+ /* This will deregister the Callback */
+ status = HssAccTdmIOUnitErrorMhCbRegister(NULL);
+ status = ICP_STATUS_FAIL;
+ }
+ }
+
+ /* release the HssAcc Mutex */
+ if (ICP_STATUS_SUCCESS != ICP_HSSACC_MUTEX_UNLOCK())
+ {
+ ICP_HSSACC_REPORT_ERROR ("icp_HssAccInit - "
+ "failed to release HssAcc Mutex\n");
+ status = ICP_STATUS_MUTEX;
+ }
+ }
+ }
+
+
+ if (status != ICP_STATUS_SUCCESS)
+ {
+ /* report the error */
+ ICP_HSSACC_REPORT_ERROR ("icp_HssAccInit - "
+ "failed to initialise HssAcc\n");
+ }
+
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Exiting HssAccInit\n");
+
+ return status;
+}
+
+
+
+
+/******************************************************************************
+ * Abstract:
+ * Initialises the HDLC service specific part of the TDM I/O Unit:
+ * max frame size and whether to generate interrupts for HDLC data or not
+ *
+ *****************************************************************************/
+icp_status_t
+icp_HssAccHdlcInit(unsigned maxRxFrameSize,
+ icp_boolean_t intGenerationEnable)
+{
+ icp_status_t status = ICP_STATUS_SUCCESS;
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Entering icp_HssAccHdlcInit\n");
+
+ /* Check if component is initialised */
+ if (ICP_TRUE != serviceInitialised)
+ {
+ ICP_HSSACC_REPORT_ERROR ("icp_HssAccHdlcInit - "
+ "component has not been initialised\n");
+ status = ICP_STATUS_FAIL;
+ }
+ else
+ {
+ if (0 == maxRxFrameSize)
+ {
+ ICP_HSSACC_REPORT_ERROR ("icp_HssAccHdlcInit - "
+ "Max Rx Frame Size cannot be 0\n");
+ status = ICP_STATUS_INVALID_PARAM;
+ }
+ else
+ {
+ if (ICP_STATUS_SUCCESS != ICP_HSSACC_MUTEX_LOCK())
+ {
+ ICP_HSSACC_REPORT_ERROR ("icp_HssAccHdlcInit - "
+ "failed to lock HssAcc Mutex\n");
+ status = ICP_STATUS_MUTEX;
+ }
+
+ else
+ {
+ if (ICP_TRUE == intGenerationEnable)
+ {
+ hdlcIntEnabled = ICP_TRUE;
+ status = HssAccServiceIntGenUpdate();
+ }
+ HssAccRxDatapathHdlcInit(maxRxFrameSize);
+
+ /* release the HssAcc Mutex */
+ if (ICP_STATUS_SUCCESS != ICP_HSSACC_MUTEX_UNLOCK())
+ {
+ ICP_HSSACC_REPORT_ERROR ("icp_HssAccHdlcInit - "
+ "failed to release HssAcc Mutex\n");
+ status = ICP_STATUS_MUTEX;
+ }
+ }
+
+ }
+ }
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Exiting icp_HssAccHdlcInit\n");
+
+ return status;
+}
+
+
+
+
+/******************************************************************************
+ * Abstract:
+ * Setup the Voice service on the TDM I/O unit. provides is with the
+ * max receive frame size and whether to generate interrupts for Voice
+ * traffic or not.
+ *
+ *****************************************************************************/
+icp_status_t
+icp_HssAccVoiceInit(unsigned maxRxFrameSize,
+ icp_boolean_t intGenerationEnable)
+{
+ icp_status_t status = ICP_STATUS_SUCCESS;
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Entering icp_HssAccVoiceInit\n");
+
+ /* Check if component is already been initialised */
+ if (ICP_TRUE != serviceInitialised)
+ {
+ ICP_HSSACC_REPORT_ERROR ("icp_HssAccVoiceInit - "
+ "component has not been initialised\n");
+
+ status = ICP_STATUS_FAIL;
+ }
+ else
+ {
+ if (0 == maxRxFrameSize)
+ {
+ ICP_HSSACC_REPORT_ERROR ("icp_HssAccVoiceInit - "
+ "Max Rx Frame Size cannot be 0\n");
+ status = ICP_STATUS_INVALID_PARAM;
+ }
+ else
+ {
+ if (ICP_STATUS_SUCCESS != ICP_HSSACC_MUTEX_LOCK())
+ {
+ ICP_HSSACC_REPORT_ERROR ("icp_HssAccVoiceInit - "
+ "failed to lock HssAcc Mutex\n");
+ status = ICP_STATUS_MUTEX;
+ }
+ else
+ {
+ if (ICP_TRUE == intGenerationEnable)
+ {
+ voiceIntEnabled = ICP_TRUE;
+ status = HssAccServiceIntGenUpdate();
+ }
+ HssAccRxDatapathVoiceInit(maxRxFrameSize);
+
+ /* release the HssAcc Mutex */
+ if (ICP_STATUS_SUCCESS != ICP_HSSACC_MUTEX_UNLOCK())
+ {
+ ICP_HSSACC_REPORT_ERROR ("icp_HssAccVoiceInit - "
+ "failed to release HssAcc Mutex\n");
+ status = ICP_STATUS_MUTEX;
+ }
+ }
+ }
+ }
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Exiting icp_HssAccVoiceInit\n");
+
+ return status;
+}
+
+
+
+
+/******************************************************************************
+ * Abstract: Shutdown the HSS I/O Access Library including all its sub-modules
+ *
+ *****************************************************************************/
+icp_status_t
+icp_HssAccShutdown (void)
+{
+ icp_status_t status = ICP_STATUS_SUCCESS;
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Entering HssAccShutdown\n");
+
+ /* If the service hasnt already been initialised then
+ we dont need to do anything */
+ if (ICP_FALSE == serviceInitialised )
+ {
+ ICP_HSSACC_REPORT_ERROR ("icp_HssAccShutdown - "
+ "the service is not initialised\n");
+ status = ICP_STATUS_FAIL;
+ }
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ if (ICP_STATUS_SUCCESS != ICP_HSSACC_MUTEX_LOCK())
+ {
+ ICP_HSSACC_REPORT_ERROR ("icp_HssAccShutdown - "
+ "failed to lock HssAcc Mutex\n");
+ status = ICP_STATUS_MUTEX;
+ }
+ else
+ {
+ voiceIntEnabled = ICP_FALSE;
+ hdlcIntEnabled = ICP_FALSE;
+ status = HssAccServiceIntGenUpdate();
+ /* Shutdown Tx and Rx datapath sub-components
+ Tx: buffers in the tx queues will be sent before being freed
+ Rx: buffers in the rx queue will be freed and not sent to the client
+ */
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ status = HssAccPortConfigShutdown();
+ }
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ status = HssAccChannelConfigShutdown();
+ }
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ status = HssAccQueuesShutdown();
+ }
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ status = HssAccVoiceBypassShutdown();
+ }
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ status = HssAccTxDatapathShutdown ();
+ }
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ status = HssAccRxDatapathShutdown ();
+ }
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ /* This will deregister the Callback */
+ status = HssAccTdmIOUnitErrorMhCbRegister(NULL);
+ }
+ if (ICP_STATUS_SUCCESS != ICP_HSSACC_MUTEX_UNLOCK())
+ {
+ ICP_HSSACC_REPORT_ERROR ("icp_HssAccShutdown - "
+ "failed to release HssAcc Mutex\n");
+ status = ICP_STATUS_MUTEX;
+ }
+ }
+
+ /* Destroy HssAcc Mutex */
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ status = ICP_HSSACC_MUTEX_DESTROY();
+ }
+ serviceInitialised = ICP_FALSE;
+ }
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Exiting HssAccShutdown\n");
+ return status;
+}
+
+
+
+/******************************************************************************
+ * Abstract: register data callbacks for a channel
+ *
+ *****************************************************************************/
+icp_status_t
+icp_HssAccChannelCallbacksRegister (
+ unsigned channelId,
+ icp_user_context_t userContext,
+ icp_hssacc_rx_callback_t rxCallback,
+ icp_hssacc_tx_done_callback_t txDoneCallback)
+{
+ icp_status_t status = ICP_STATUS_SUCCESS;
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Entering icp_HssAccChannelCallbacksRegister\n");
+
+ /* If the service hasnt been initialised, report an error */
+ if (ICP_FALSE == serviceInitialised)
+ {
+ ICP_HSSACC_REPORT_ERROR ("icp_HssAccChannelCallbacksRegister - "
+ "Service has not been initialised\n");
+ status = ICP_STATUS_FAIL;
+ }
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ if (ICP_HSSACC_MAX_NUM_CHANNELS <= channelId)
+ {
+ ICP_HSSACC_REPORT_ERROR ("icp_HssAccChannelCallbacksRegister - "
+ "Channel Id is not valid\n");
+ status = ICP_STATUS_INVALID_PARAM;
+ }
+ }
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ if ((NULL == rxCallback) ||
+ (NULL == txDoneCallback))
+ {
+ ICP_HSSACC_REPORT_ERROR ("icp_HssAccChannelCallbacksRegister - "
+ "Callback function pointers invalid\n");
+ status = ICP_STATUS_INVALID_PARAM;
+ }
+ }
+
+ /* save the callbacks to an internal structure so that
+ the datapath can use them */
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ HssAccChannelRxCallbackRegister(channelId, rxCallback, userContext);
+ HssAccTxDatapathChanTxDoneCallbackRegister(channelId,
+ txDoneCallback,
+ userContext);
+ }
+ return status;
+
+}
+
+
+
+
+/******************************************************************************
+ * Abstract: register Error callbacks for a channel
+ *****************************************************************************/
+icp_status_t
+icp_HssAccErrorCallbackRegister (icp_hssacc_channel_type_t channelType,
+ icp_user_context_t userContext,
+ icp_hssacc_error_callback_t errorCallback)
+{
+ icp_status_t status = ICP_STATUS_SUCCESS;
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Entering icp_HssAccErrorCallbackRegister\n");
+
+ /* If the service hasnt already been initialised then
+ we dont need to do anything */
+ if (ICP_FALSE == serviceInitialised)
+ {
+ ICP_HSSACC_REPORT_ERROR ("icp_HssAccErrorCallbackRegister - "
+ "Service has not been initialised\n");
+ status = ICP_STATUS_FAIL;
+ }
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ if ((NULL == errorCallback) ||
+ (ICP_HSSACC_ENUM_INVALID (channelType,
+ ICP_HSSACC_CHAN_TYPE_DELIMITER)))
+ {
+ ICP_HSSACC_REPORT_ERROR ("icp_HssAccErrorCallbackRegister - "
+ "one or more parameters invalid\n");
+ status = ICP_STATUS_INVALID_PARAM;
+ }
+ }
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ hssAccErrorCb[channelType] = errorCallback;
+ hssAccErrorCtxt[channelType] = userContext;
+ }
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Exiting icp_HssAccErrorCallbackRegister\n");
+ return status;
+}
+
+
+
+
+
+/******************************************************************************
+ * Abstract:
+ * Service the datapath, Rx and Tx
+ *
+ *****************************************************************************/
+icp_status_t
+icp_HssAccDataPathService (icp_hssacc_channel_type_t channelType)
+{
+ icp_status_t status = ICP_STATUS_SUCCESS;
+ ICP_HSSACC_DP_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Entering icp_HssAccDataPathService\n");
+#ifndef NDEBUG
+ if (ICP_FALSE == serviceInitialised)
+ {
+ ICP_HSSACC_REPORT_ERROR ("icp_HssAccDataPathService - "
+ "service is not initialised\n");
+ status = ICP_STATUS_FAIL;
+ }
+
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ if (ICP_HSSACC_ENUM_INVALID(channelType, ICP_HSSACC_CHAN_TYPE_DELIMITER))
+ {
+ ICP_HSSACC_REPORT_ERROR ("icp_HssAccDataPathService - "
+ "invalid Type to service\n");
+ status = ICP_STATUS_INVALID_PARAM;
+ }
+ }
+#endif
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ /* Service Tx Direction */
+ status = HssAccTxDatapathService(channelType);
+ }
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ /* Service Rx Direction */
+ status = HssAccRxDatapathService(channelType);
+ }
+
+ ICP_HSSACC_DP_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Exiting icp_HssAccDataPathService\n");
+ return status;
+}
+
+
+
+
+/******************************************************************************
+ * Abstract:
+ * Retrive all the buffers in the TDM I/O unit associated with the
+ * specified channel. will call Rx and Tx sub-modules. If channelId is
+ * equal to ICP_HSSACC_MAX_NUM_CHANNELS then retrieve buffers from the
+ * rx free queues for any service which has all unitialized channels.
+ *
+ *****************************************************************************/
+icp_status_t
+icp_HssAccAllBuffersRetrieve (unsigned channelId,
+ IX_OSAL_MBUF * * buffer)
+{
+ icp_status_t status = ICP_STATUS_SUCCESS;
+ icp_boolean_t mutexLocked = ICP_FALSE;
+ IX_OSAL_MBUF * pEndChainBuffer = NULL;
+ IX_OSAL_MBUF * pTmpBuffer = NULL;
+ IX_OSAL_MBUF * pTmpEndChainBuffer = NULL;
+ icp_hssacc_channel_state_t channelState = ICP_HSSACC_CHANNEL_UNINITIALISED;
+
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Entering icp_HssAccAllBuffersRetrieve\n");
+
+ if (ICP_TRUE != serviceInitialised)
+ {
+ ICP_HSSACC_REPORT_ERROR ("icp_HssAccAllBuffersRetrieve - "
+ "service is not initialised\n");
+ status = ICP_STATUS_FAIL;
+ }
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ /* channelId == ICP_HSSACC_MAX_NUM_CHANNELS is allowed */
+ if (ICP_HSSACC_MAX_NUM_CHANNELS < channelId)
+ {
+ ICP_HSSACC_REPORT_ERROR ("icp_HssAccAllBuffersRetrieve - "
+ "Channel Id Invalid\n");
+ status = ICP_STATUS_INVALID_PARAM;
+ }
+ if (NULL == buffer)
+ {
+ ICP_HSSACC_REPORT_ERROR ("icp_HssAccAllBuffersRetrieve - "
+ "Buffer Pointer Invalid\n");
+ status = ICP_STATUS_INVALID_PARAM;
+ }
+
+ }
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ if (ICP_STATUS_SUCCESS != ICP_HSSACC_MUTEX_LOCK())
+ {
+ ICP_HSSACC_REPORT_ERROR ("icp_HssAccAllBuffersRetrieve - "
+ "failed to lock HssAcc Mutex\n");
+ status = ICP_STATUS_MUTEX;
+ }
+ else
+ {
+ mutexLocked = ICP_TRUE;
+
+ if (ICP_HSSACC_MAX_NUM_CHANNELS != channelId)
+ {
+ /* Check that the channel is not enabled first */
+ channelState = HssAccChannelConfigStateQuery(channelId);
+
+ if (ICP_HSSACC_CHANNEL_ENABLED == channelState
+ || ICP_HSSACC_CHANNEL_DOWN_TRANSITION == channelState)
+ {
+ ICP_HSSACC_REPORT_ERROR ("icp_HssAccAllBuffersRetrieve - "
+ "Channel is enabled\n");
+ status = ICP_STATUS_RESOURCE;
+ }
+ }
+ }
+ }
+
+
+ if (status == ICP_STATUS_SUCCESS)
+ {
+
+ *buffer = NULL;
+
+ if (ICP_HSSACC_MAX_NUM_CHANNELS > channelId)
+ {
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ /* Retrieve Tx Datapath Buffers Chain containing all leftover
+ TxDones and submitted Tx buffers that werent transmitted */
+ status = HssAccTxDatapathChannelBuffersRetrieve(
+ channelId,
+ buffer,
+ &pTmpEndChainBuffer);
+ }
+
+ if (status == ICP_STATUS_SUCCESS)
+ {
+ /* Retrieve Rx Datapath Buffer Chain */
+ status = HssAccRxDatapathChanBufsRetrieve(channelId,
+ &pTmpBuffer,
+ &pEndChainBuffer);
+ }
+ }
+ else
+ {
+ /* Retrieve Rx Free Q Buffer Chain(s) */
+ status = HssAccRxFreeQsBufsRetrieve(&pTmpBuffer,
+ &pEndChainBuffer);
+ }
+ }
+
+
+ if (status == ICP_STATUS_SUCCESS)
+ {
+ if (*buffer != NULL)
+ {
+ if (pTmpBuffer != NULL)
+ {
+ /* Link two chains together */
+ IX_OSAL_MBUF_NEXT_PKT_IN_CHAIN_PTR(pTmpEndChainBuffer) =
+ pTmpBuffer;
+ }
+ }
+ else if (pTmpBuffer != NULL)
+ {
+ /* Rx datapath or free queue buffers were retrieved so
+ operation succeeded */
+ *buffer = pTmpBuffer;
+ }
+
+ /* Notify Channel Config of success */
+ if (ICP_HSSACC_MAX_NUM_CHANNELS > channelId)
+ {
+ HssAccChannelConfigBuffersClearedNotify(channelId);
+ }
+ }
+
+
+ if (ICP_TRUE == mutexLocked)
+ {
+ /* release the HssAcc Mutex */
+ if (ICP_STATUS_SUCCESS != ICP_HSSACC_MUTEX_UNLOCK())
+ {
+ ICP_HSSACC_REPORT_ERROR ("icp_HssAccAllBuffersRetrieve - "
+ "failed to release HssAcc Mutex\n");
+ status = ICP_STATUS_MUTEX;
+ }
+ }
+
+
+
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Exiting icp_HssAccAllBuffersRetrieve\n");
+ return status;
+}
+
+
+
+
+/******************************************************************************
+ * Abstract:
+ * saves the provided callback for the specified port and service.
+ *
+ *****************************************************************************/
+icp_status_t
+icp_HssAccPortErrorCallbackRegister (
+ unsigned portId,
+ icp_hssacc_channel_type_t channelType,
+ icp_user_context_t userContext,
+ icp_hssacc_port_error_callback_t portErrorCallback)
+{
+ icp_status_t status = ICP_STATUS_SUCCESS;
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Entering icp_HssAccPortErrorCallbackRegister\n");
+
+ if (ICP_TRUE != serviceInitialised)
+ {
+ ICP_HSSACC_REPORT_ERROR ("icp_HssAccPortErrorCallbackRegister - "
+ "service is not initialised\n");
+ status = ICP_STATUS_FAIL;
+ }
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ if ((ICP_HSSACC_MAX_NUM_PORTS <= portId) ||
+ ICP_HSSACC_ENUM_INVALID (channelType,
+ ICP_HSSACC_CHAN_TYPE_DELIMITER))
+ {
+ ICP_HSSACC_REPORT_ERROR_2 ("icp_HssAccPortErrorCallbackRegister - "
+ "Invalid parameter portId %u for "
+ "service %u\n",
+ portId,
+ channelType);
+ status = ICP_STATUS_INVALID_PARAM;
+ }
+
+ if (NULL == portErrorCallback)
+ {
+ ICP_HSSACC_REPORT_ERROR_1 ("icp_HssAccPortErrorCallbackRegister - "
+ "Invalid callback provided 0x%08X\n",
+ (uint32_t)portErrorCallback);
+ status = ICP_STATUS_INVALID_PARAM;
+ }
+ }
+
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ hssAccPortErrorCb[portId][channelType] = portErrorCallback;
+ hssAccPortErrorCtxt[portId][channelType] = userContext;
+ }
+
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Exiting icp_HssAccPortErrorCallbackRegister\n");
+ return status;
+}
+
+
+
+/*****************************************************************************
+ * Abstract:
+ * display all stats within this Access module and the TDM I/O unit.
+ *
+ *****************************************************************************/
+void
+icp_HssAccStatsShow (void)
+{
+ unsigned channelId = 0;
+ icp_status_t status = ICP_STATUS_SUCCESS;
+ icp_hssacc_channel_type_t channelType = 0;
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Entering icp_HssAccStatsShow\n");
+
+ /* If the service hasnt already been initialised then we dont
+ need to do anything */
+ if (ICP_TRUE == serviceInitialised)
+ {
+ HssAccPortConfigStatsShow();
+ HssAccQueuesConfigStatsShow();
+ HssAccChannelConfigStatsShow();
+ HssAccTsAllocStatsShow();
+ HssAccBypassStatsShow();
+
+ while ((ICP_STATUS_SUCCESS == status ) &&
+ (channelId < ICP_HSSACC_MAX_NUM_CHANNELS))
+ {
+ status = icp_HssAccChannelStatsShow(channelId);
+ channelId ++;
+ }
+ while ((ICP_STATUS_SUCCESS == status ) &&
+ (channelType < ICP_HSSACC_CHAN_TYPE_DELIMITER))
+ {
+ HssAccRxDatapathReplenishStatsShow(channelType);
+ channelType ++;
+ }
+ HssAccServiceStatsShow();
+ }
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Exiting icp_HssAccStatsShow\n");
+
+}
+
+
+
+/*****************************************************************************
+ * Abstract:
+ * Reset all internal stats.
+ *
+ *****************************************************************************/
+void
+icp_HssAccStatsReset (void)
+{
+ unsigned channelId = 0;
+ icp_status_t status = ICP_STATUS_SUCCESS;
+ icp_hssacc_channel_type_t channelType = 0;
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Entering icp_HssAccStatsReset\n");
+
+ /* If the service hasnt already been initialised then we dont
+ need to do anything */
+ if (ICP_TRUE == serviceInitialised)
+ {
+ HssAccPortConfigStatsReset();
+ HssAccQueuesConfigStatsReset();
+ HssAccChannelConfigStatsReset();
+ HssAccTsAllocStatsReset();
+ HssAccBypassStatsReset();
+
+ while ((ICP_STATUS_SUCCESS == status ) &&
+ (channelId < ICP_HSSACC_MAX_NUM_CHANNELS))
+ {
+ status = icp_HssAccChannelStatsReset(channelId);
+ channelId ++;
+ }
+ while ((ICP_STATUS_SUCCESS == status ) &&
+ (channelType < ICP_HSSACC_CHAN_TYPE_DELIMITER))
+ {
+ HssAccRxDatapathReplenishStatsReset(channelType);
+ channelType ++;
+ }
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ /* Also reset here the Sw Error Stats from the TDM IO Unit */
+ status = HssAccSwErrorStatsReset ();
+ }
+ HssAccServiceStatsReset();
+ }
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Exiting icp_HssAccStatsReset\n");
+
+}
+
+
+
+/*****************************************************************************
+ * Abstract:
+ * display all stats relating to the specified channel
+ *
+ *****************************************************************************/
+icp_status_t
+icp_HssAccChannelStatsShow (unsigned channelId)
+{
+ icp_status_t status = ICP_STATUS_SUCCESS;
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Entering icp_HssAccChannelStatsShow\n");
+
+ /* If the service hasnt already been initialised then we dont
+ need to do anything */
+ if (ICP_FALSE == serviceInitialised)
+ {
+ ICP_HSSACC_REPORT_ERROR ("icp_HssAccChannelStatsShow - "
+ "Service has not been initialised\n");
+ status = ICP_STATUS_FAIL;
+ }
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ if (ICP_HSSACC_MAX_NUM_CHANNELS <= channelId)
+ {
+ ICP_HSSACC_REPORT_ERROR ("icp_HssAccChannelStatsShow - "
+ "channel number is invalid\n");
+ status = ICP_STATUS_INVALID_PARAM;
+ }
+ }
+
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ HssAccChannelConfigStateShow (channelId);
+ HssAccTxDatapathChanStatsShow(channelId);
+ HssAccRxDatapathChanStatsShow(channelId);
+
+
+ if (ICP_STATUS_SUCCESS != HssAccChannelTdmIOErrorStatsShow(channelId))
+ {
+ ICP_HSSACC_REPORT_ERROR("icp_HssAccChannelStatsShow - Error "
+ "retrieving Stats from TDM I/O Unit\n");
+ status = ICP_STATUS_RESOURCE;
+ }
+ }
+
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Exiting icp_HssAccChannelStatsShow\n");
+ return status;
+}
+
+
+
+/*****************************************************************************
+ * Abstract:
+ * reset all the stats relating to the specified channel.
+ *
+ *****************************************************************************/
+icp_status_t
+icp_HssAccChannelStatsReset (unsigned channelId)
+{
+ icp_status_t status = ICP_STATUS_SUCCESS;
+ icp_boolean_t mutexLocked = ICP_FALSE;
+
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Entering icp_HssAccChannelStatsReset\n");
+
+ /* If the service hasnt already been initialised then we
+ dont need to do anything */
+ if (ICP_FALSE == serviceInitialised)
+ {
+ ICP_HSSACC_REPORT_ERROR ("icp_HssAccChannelStatsReset - "
+ "Service has not been initialised\n");
+ status = ICP_STATUS_FAIL;
+ }
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ if (ICP_HSSACC_MAX_NUM_CHANNELS <= channelId)
+ {
+ ICP_HSSACC_REPORT_ERROR ("icp_HssAccChannelStatsReset - "
+ "channel number is invalid\n");
+ status = ICP_STATUS_INVALID_PARAM;
+ }
+ }
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ if (ICP_STATUS_SUCCESS != ICP_HSSACC_MUTEX_LOCK())
+ {
+ ICP_HSSACC_REPORT_ERROR ("icp_HssAccChannelStatsReset - "
+ "failed to lock HssAcc Mutex\n");
+ status = ICP_STATUS_MUTEX;
+ }
+ else
+ {
+ mutexLocked = ICP_TRUE;
+ }
+ }
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ /* Reset the Datapath Stats for this channel */
+ HssAccTxDatapathChanStatsReset(channelId);
+ HssAccRxDatapathChanStatsReset(channelId);
+
+ if (ICP_STATUS_SUCCESS != HssAccChannelTdmIOErrorStatsReset(channelId))
+ {
+ ICP_HSSACC_REPORT_ERROR("icp_HssAccChannelStatsShow - Error "
+ "retrieving Stats from TDM I/O Unit\n");
+ status = ICP_STATUS_RESOURCE;
+ }
+
+ }
+ if (mutexLocked == ICP_TRUE)
+ {
+ /* release the HssAcc Mutex */
+ if (ICP_STATUS_SUCCESS != ICP_HSSACC_MUTEX_UNLOCK())
+ {
+ ICP_HSSACC_REPORT_ERROR ("icp_HssAccChannelStatsReset - "
+ "failed to release HssAcc Mutex\n");
+ status = ICP_STATUS_MUTEX;
+ }
+ }
+
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Exiting icp_HssAccChannelStatsReset\n");
+ return status;
+}
+
+
+
+/*****************************************************************************
+ * Abstract:
+ * show all the stats relating to the specified port, this includes
+ * all the channels associated to timeslots on this port.
+ *
+ *****************************************************************************/
+icp_status_t
+icp_HssAccPortStatsShow (unsigned portId)
+{
+ icp_status_t status = ICP_STATUS_SUCCESS;
+ unsigned channelId = ICP_HSSACC_MAX_NUM_CHANNELS;
+ icp_hssacc_tdm_io_unit_channel_list_t listId =
+ ICP_HSSACC_TDM_IO_UNIT_LIST_TX_PRIMARY;
+
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Entering icp_HssAccPortStatsShow\n");
+
+ /* If the service hasnt already been initialised then we dont
+ need to do anything */
+ if (ICP_FALSE == serviceInitialised)
+ {
+ ICP_HSSACC_REPORT_ERROR ("icp_HssAccPortStatsShow - "
+ "Service has not been initialised\n");
+ status = ICP_STATUS_FAIL;
+ }
+ /* Check Port Number */
+ if (portId >= ICP_HSSACC_MAX_NUM_PORTS)
+ {
+ ICP_HSSACC_REPORT_ERROR ("icp_HssAccPortStatsShow - "
+ "port number is invalid\n");
+ status = ICP_STATUS_INVALID_PARAM;
+ }
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ /* For each port, the channels to be processed are split
+ into 3 lists for the TDM I/O Unit.
+ Show the channels in each list */
+ channelId = HssAccChannelListLastPortChannelGet (portId,
+ listId);
+
+ ixOsalLog(IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT,
+ "Channels on the Primary List for port %u:\n",
+ portId,
+ 0, 0, 0, 0, 0);
+ while (ICP_HSSACC_MAX_NUM_CHANNELS > channelId)
+ {
+ icp_HssAccChannelStatsShow(channelId);
+ channelId = HssAccChannelListPrevChannelOnListGet(channelId);
+ }
+
+ }
+ /* Repeat for the Secondary 0 list */
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ listId = ICP_HSSACC_TDM_IO_UNIT_LIST_TX_SECONDARY_0;
+ channelId = HssAccChannelListLastPortChannelGet (portId,
+ listId);
+
+ ixOsalLog(IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT,
+ "Channels on the Secondary 0 List for port %u:\n",
+ portId,
+ 0, 0, 0, 0, 0);
+ while (ICP_HSSACC_MAX_NUM_CHANNELS > channelId)
+ {
+ icp_HssAccChannelStatsShow(channelId);
+ channelId = HssAccChannelListPrevChannelOnListGet(channelId);
+ }
+
+ }
+
+ /* Repeat for the Secondary 1 list */
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ listId = ICP_HSSACC_TDM_IO_UNIT_LIST_TX_SECONDARY_1;
+ channelId = HssAccChannelListLastPortChannelGet (portId,
+ listId);
+
+ ixOsalLog(IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT,
+ "Channels on the Secondary 1 List for port %u:\n",
+ portId,
+ 0, 0, 0, 0, 0);
+ while (ICP_HSSACC_MAX_NUM_CHANNELS > channelId)
+ {
+ icp_HssAccChannelStatsShow(channelId);
+ channelId = HssAccChannelListPrevChannelOnListGet(channelId);
+ }
+
+
+ /* Also print out here the Sw Error Stats from the TDM IO Unit */
+ status = HssAccSwErrorStatsShow ();
+ }
+
+ if (ICP_STATUS_SUCCESS == status)
+ {
+
+ /* And overall stats for Abt, Aln, FCS and Max pkt size errors */
+ status = HssAccTdmIOErrorStatsShow ();
+ }
+
+
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Exiting icp_HssAccPortStatsShow\n");
+ return status;
+
+}
+
+
+
+
+/*****************************************************************************
+ * Abstract:
+ * reset all the stats relating to the specified port, this includes
+ * resting all the stats for channels on this port.
+ *
+ *****************************************************************************/
+icp_status_t
+icp_HssAccPortStatsReset (unsigned portId)
+{
+ icp_status_t status = ICP_STATUS_SUCCESS;
+ unsigned channelId = ICP_HSSACC_MAX_NUM_CHANNELS;
+ icp_hssacc_tdm_io_unit_channel_list_t listId =
+ ICP_HSSACC_TDM_IO_UNIT_LIST_TX_PRIMARY;
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Entering icp_HssAccPortStatsReset\n");
+
+
+ /* If the service hasnt already been initialised then we dont
+ need to do anything */
+ if (ICP_FALSE == serviceInitialised)
+ {
+ ICP_HSSACC_REPORT_ERROR ("icp_HssAccPortStatsReset - "
+ "Service has not been initialised\n");
+ status = ICP_STATUS_FAIL;
+ }
+
+ /* Check Port Number */
+ if (portId >= ICP_HSSACC_MAX_NUM_PORTS)
+ {
+ ICP_HSSACC_REPORT_ERROR ("icp_HssAccPortStatsReset - "
+ "port number is invalid\n");
+ status = ICP_STATUS_INVALID_PARAM;
+ }
+
+
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ /* For each port, the channels to be processed are split
+ into 3 lists for the TDM I/O Unit.
+ Show the channels in each list */
+ channelId = HssAccChannelListLastPortChannelGet (portId,
+ listId);
+
+ ixOsalLog(IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT,
+ "Channels on the Primary List for port %u:\n",
+ portId,
+ 0, 0, 0, 0, 0);
+ while (ICP_HSSACC_MAX_NUM_CHANNELS > channelId)
+ {
+ icp_HssAccChannelStatsReset(channelId);
+ channelId = HssAccChannelListPrevChannelOnListGet(channelId);
+ }
+
+ }
+ /* Repeat for the Secondary 0 list */
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ listId = ICP_HSSACC_TDM_IO_UNIT_LIST_TX_SECONDARY_0;
+ channelId = HssAccChannelListLastPortChannelGet (portId,
+ listId);
+
+ ixOsalLog(IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT,
+ "Channels on the Secondary 0 List for port %u:\n",
+ portId,
+ 0, 0, 0, 0, 0);
+ while (ICP_HSSACC_MAX_NUM_CHANNELS > channelId)
+ {
+ icp_HssAccChannelStatsReset(channelId);
+ channelId = HssAccChannelListPrevChannelOnListGet(channelId);
+ }
+
+ }
+
+ /* Repeat for the Secondary 1 list */
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ listId = ICP_HSSACC_TDM_IO_UNIT_LIST_TX_SECONDARY_1;
+ channelId = HssAccChannelListLastPortChannelGet (portId,
+ listId);
+
+ ixOsalLog(IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT,
+ "Channels on the Secondary 1 List for port %u:\n",
+ portId,
+ 0, 0, 0, 0, 0);
+ while (ICP_HSSACC_MAX_NUM_CHANNELS > channelId)
+ {
+ icp_HssAccChannelStatsReset(channelId);
+ channelId = HssAccChannelListPrevChannelOnListGet(channelId);
+ }
+ }
+
+
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Exiting icp_HssAccPortStatsReset\n");
+ return status;
+
+}
+
+
+
+/*****************************************************************************
+ * Abstract:
+ * return the number of channels supported by the TDM I/O unit.
+ *
+ *****************************************************************************/
+unsigned
+icp_HssAccNumSupportedChannelsGet ( void )
+{
+ return ICP_HSSACC_MAX_NUM_CHANNELS;
+}
+
+
+
+
+/*****************************************************************************
+ * Abstract:
+ * register the HSS I/O Access callback with the Message Handler.
+ *
+ *****************************************************************************/
+icp_status_t
+HssAccTdmIOUnitErrorMhCbRegister (IxPiuMhCallback callback)
+{
+ icp_status_t status = ICP_STATUS_SUCCESS;
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Entering HssAccTdmIOUnitErrorMhCbRegister\n");
+ if (ICP_STATUS_SUCCESS !=
+ ixPiuMhUnsolicitedCallbackRegister (
+ IX_PIUMH_PIUID_PIU0,
+ ICP_HSSACC_TDM_IO_UNIT_HSS_SW_ERROR_STATUS,
+ callback))
+ {
+
+ ICP_HSSACC_REPORT_ERROR ("HssAccTdmIOUnitErrorMhCbRegister - "
+ "Could not register callback\n");
+ status = ICP_STATUS_FAIL;
+ }
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Exiting HssAccTdmIOUnitErrorMhCbRegister\n");
+
+ return status;
+}
+
+
+/*****************************************************************************
+ * Abstract:
+ * this is the callback that the Message Handler will call when it
+ * receives an error message from the TDM I/O unit.
+ *
+ *****************************************************************************/
+void
+HssAccTdmIOUnitErrorCallback(IxPiuMhPiuId piuId, IxPiuMhMessage message)
+{
+ uint32_t localBitmask = 0;
+ uint32_t portBitmask = 0;
+ unsigned portId = ICP_HSSACC_MAX_NUM_PORTS;
+ icp_hssacc_port_error_t portError = ICP_HSSACC_PORT_ERROR_TX_LOS;
+ uint32_t errorOffset = 0;
+ icp_hssacc_error_t errorType = ICP_HSSACC_ERROR_DELIMITER;
+ icp_boolean_t bothServices = ICP_FALSE;
+ icp_hssacc_channel_type_t service = ICP_HSSACC_CHAN_TYPE_DELIMITER;
+ icp_status_t status = ICP_STATUS_SUCCESS;
+ ICP_HSSACC_TRACE_2 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Entering HssAccTdmIOUnitErrorCallback 0x%08X 0x%08X\n",
+ message.data[0],
+ message.data[1]);
+
+
+ if ((IX_PIUMH_PIUID_PIU0 != piuId) ||
+ ((message.data[0] >> ICP_HSSACC_TDM_IO_UNIT_BYTE0_OFFSET) !=
+ (ICP_HSSACC_TDM_IO_UNIT_HSS_SW_ERROR_STATUS)))
+ {
+ ICP_HSSACC_REPORT_ERROR ("HssAccTdmIOUnitErrorCallback - "
+ "Invalid parameters\n");
+ }
+ else
+ {
+ /* First check if we have any port errors */
+ localBitmask =
+ message.data[0] & ICP_HSSACC_TDM_IO_UNIT_ERR_ALL_PORT_MASK;
+ if (0 != localBitmask)
+ {
+ /* determine which port error triggered this message */
+ portId = 0;
+ while (0 != localBitmask)
+ {
+ portBitmask = localBitmask &
+ ICP_HSSACC_TDM_IO_UNIT_ERR_SGLE_PORT_MASK;
+ if (0 != portBitmask)
+ {
+ while ((portBitmask & 1) != 1)
+ {
+ portBitmask >>= 1;
+ portError ++;
+ }
+ ICP_HSSACC_TRACE_1 (ICP_HSSACC_DEBUG,
+ "HssAccTdmIOUnitErrorCallback - "
+ "Error Reported on port %u\n",
+ portId);
+ /* use the client callbacks */
+ hssAccPortErrorCb[portId][ICP_HSSACC_CHAN_TYPE_HDLC](
+ hssAccPortErrorCtxt[portId][ICP_HSSACC_CHAN_TYPE_HDLC],
+ portError);
+
+ hssAccPortErrorCb[portId][ICP_HSSACC_CHAN_TYPE_VOICE](
+ hssAccPortErrorCtxt[portId][ICP_HSSACC_CHAN_TYPE_VOICE],
+ portError);
+ }
+ localBitmask >>= ICP_HSSACC_TDM_IO_UNIT_NEXT_PORT_SHIFT;
+ portId ++;
+ }
+ }
+
+
+ /* now check for a software error triggering this message;
+ compare the bitmask sent with our static one */
+ localBitmask = message.data[1];
+ if ((0 != localBitmask) &&
+ (hssAccStaticErrorBitmask != localBitmask))
+ {
+ while ((localBitmask & 1) == (hssAccStaticErrorBitmask & 1))
+ {
+ localBitmask >>= 1;
+ hssAccStaticErrorBitmask >>= 1;
+ errorOffset ++;
+ }
+ switch (errorOffset)
+ {
+ case ICP_HSSACC_TDM_IO_UNIT_ERR_BITMSK_MSG_OUT_FIFO_H:
+ case ICP_HSSACC_TDM_IO_UNIT_ERR_BITMSK_MSG_OUT_FIFO_L:
+ errorType = ICP_HSSACC_ERROR_MESSAGE_FIFO_OVERFLOW;
+ bothServices = ICP_TRUE;
+ break;
+ case ICP_HSSACC_TDM_IO_UNIT_ERR_BITMSK_RX_V_FREE_UNDERF:
+ errorType = ICP_HSSACC_ERROR_RX_FREE_UNDERFLOW;
+ service = ICP_HSSACC_CHAN_TYPE_VOICE;
+ break;
+ case ICP_HSSACC_TDM_IO_UNIT_ERR_BITMSK_RX_H_FREE_UNDERF:
+ errorType = ICP_HSSACC_ERROR_RX_FREE_UNDERFLOW;
+ service = ICP_HSSACC_CHAN_TYPE_HDLC;
+ break;
+ case ICP_HSSACC_TDM_IO_UNIT_ERR_BITMSK_RX_V_INT_FIFO_OVERF:
+ case ICP_HSSACC_TDM_IO_UNIT_ERR_BITMSK_RX_V_Q_OVERF:
+ errorType = ICP_HSSACC_ERROR_RX_OVERFLOW;
+ service = ICP_HSSACC_CHAN_TYPE_VOICE;
+ break;
+ case ICP_HSSACC_TDM_IO_UNIT_ERR_BITMSK_RX_H_INT_FIFO_OVERF:
+ case ICP_HSSACC_TDM_IO_UNIT_ERR_BITMSK_RX_H_Q_OVERF:
+ errorType = ICP_HSSACC_ERROR_RX_OVERFLOW;
+ service = ICP_HSSACC_CHAN_TYPE_HDLC;
+ break;
+ default:
+ ICP_HSSACC_REPORT_ERROR ("HssAccTdmIOUnitErrorCallback - "
+ "Unknown Software Error "
+ "from TDM I/O Unit\n");
+ status = ICP_STATUS_FAIL;
+ break;
+
+ }
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_DEBUG,
+ "HssAccTdmIOUnitErrorCallback - "
+ "Firmware Error Reported\n");
+ if (ICP_TRUE == bothServices)
+ {
+ hssAccErrorCb[ICP_HSSACC_CHAN_TYPE_HDLC](
+ hssAccErrorCtxt[ICP_HSSACC_CHAN_TYPE_HDLC],
+ errorType);
+ hssAccErrorCb[ICP_HSSACC_CHAN_TYPE_VOICE](
+ hssAccErrorCtxt[ICP_HSSACC_CHAN_TYPE_VOICE],
+ errorType);
+ }
+ else
+ {
+ hssAccErrorCb[service](hssAccErrorCtxt[service],
+ errorType);
+ }
+ hssAccStaticErrorBitmask = message.data[1];
+ }
+ }
+ }
+
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Exiting HssAccTdmIOUnitErrorCallback\n");
+}
+
+
+
+/*****************************************************************************
+ * Abstract:
+ * this is a dummy callback used in the event of the client never
+ * registering its own for a port error
+ *
+ *****************************************************************************/
+void HssAccPortErrorDummyClientCb (icp_user_context_t userContext,
+ icp_hssacc_port_error_t errorType)
+{
+ ICP_HSSACC_TRACE_2 (ICP_HSSACC_DEBUG,
+ "HssAccPortErrorDummyClientCb - received "
+ "notification of Port error %u for service %u\n",
+ errorType,
+ (unsigned)userContext);
+}
+
+
+
+/*****************************************************************************
+ * Abstract:
+ * this is a dummy callback used in the event of the client never
+ * registering its own for a TDM I/O Unit firmware error.
+ *
+ *****************************************************************************/
+void HssAccErrorDummyClientCb (icp_user_context_t userContext,
+ icp_hssacc_error_t errorType)
+{
+ ICP_HSSACC_TRACE_2 (ICP_HSSACC_DEBUG,
+ "HssAccErrorDummyClientCb - "
+ "received notification of error %u for service %u\n",
+ errorType,
+ (unsigned)userContext);
+}
+
+
+
+
+
+
+
+/*****************************************************************************
+ * Abstract:
+ * display all stats provided by the TDM I/O unit relating to detected
+ * firmware errors.
+ *
+ *****************************************************************************/
+TDM_PRIVATE icp_status_t
+HssAccSwErrorStatsShow (void)
+{
+ icp_status_t status = ICP_STATUS_SUCCESS;
+ IxPiuMhMessage message;
+ unsigned statValue = 0;
+ icp_boolean_t mutexLocked = ICP_FALSE;
+
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Entering HssAccSwErrorStatsShow\n");
+
+ if (ICP_STATUS_SUCCESS != ICP_HSSACC_MUTEX_LOCK())
+ {
+ ICP_HSSACC_REPORT_ERROR ("HssAccSwErrorStatsShow - "
+ "failed to lock HssAcc Mutex\n");
+ status = ICP_STATUS_MUTEX;
+ }
+ else
+ {
+ mutexLocked = ICP_TRUE;
+ }
+
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ ixOsalLog(IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT,
+ "TDM IO Unit Firmware Error Stats:\n",
+ 0, 0, 0, 0, 0, 0);
+
+ /* Retrieve each Sw Error Count and print it */
+ HssAccComTdmIOUnitCmd4byte1wordMsgCreate (
+ ICP_HSSACC_TDM_IO_UNIT_HSS_SW_ERROR_READ,
+ ICP_HSSACC_TDM_IO_UNIT_RX_VOICE_Q_OVERFLOW, 0, 0, 0,
+ &message);
+
+ /* Send the message to the TDM I/O Unit and wait for its reply */
+ status = HssAccComTdmIOUnitMsgSendAndRecv(
+ message,
+ ICP_HSSACC_TDM_IO_UNIT_HSS_SW_ERROR_READ_RESPONSE,
+ &(hssAccServStats.swErrRead),
+ &statValue);
+ }
+
+ if ( ICP_STATUS_SUCCESS == status)
+ {
+ ixOsalLog(IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT,
+ "Receive Voice Q Overflows: %u\n",
+ statValue,
+ 0, 0, 0, 0, 0);
+
+ HssAccComTdmIOUnitCmd4byte1wordMsgCreate (
+ ICP_HSSACC_TDM_IO_UNIT_HSS_SW_ERROR_READ,
+ ICP_HSSACC_TDM_IO_UNIT_RX_HDLC_Q_OVERFLOW, 0, 0, 0,
+ &message);
+
+ /* Send the message to the TDM I/O Unit and wait for its reply */
+ status = HssAccComTdmIOUnitMsgSendAndRecv(
+ message,
+ ICP_HSSACC_TDM_IO_UNIT_HSS_SW_ERROR_READ_RESPONSE,
+ &(hssAccServStats.swErrRead),
+ &statValue);
+ }
+
+ if ( ICP_STATUS_SUCCESS == status)
+ {
+ ixOsalLog(IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT,
+ "Receive HDLC Q Overflows: %u\n",
+ statValue,
+ 0, 0, 0, 0, 0);
+
+ HssAccComTdmIOUnitCmd4byte1wordMsgCreate (
+ ICP_HSSACC_TDM_IO_UNIT_HSS_SW_ERROR_READ,
+ ICP_HSSACC_TDM_IO_UNIT_RX_VOICE_FIFO_OVERFLOW, 0, 0, 0,
+ &message);
+
+ /* Send the message to the TDM I/O Unit and wait for its reply */
+ status = HssAccComTdmIOUnitMsgSendAndRecv(
+ message,
+ ICP_HSSACC_TDM_IO_UNIT_HSS_SW_ERROR_READ_RESPONSE,
+ &(hssAccServStats.swErrRead),
+ &statValue);
+ }
+
+ if ( ICP_STATUS_SUCCESS == status)
+ {
+ ixOsalLog(IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT,
+ "Receive Voice FIFO Overflows: %u\n",
+ statValue,
+ 0, 0, 0, 0, 0);
+
+ HssAccComTdmIOUnitCmd4byte1wordMsgCreate (
+ ICP_HSSACC_TDM_IO_UNIT_HSS_SW_ERROR_READ,
+ ICP_HSSACC_TDM_IO_UNIT_RX_HDLC_FIFO_OVERFLOW, 0, 0, 0,
+ &message);
+
+ /* Send the message to the TDM I/O Unit and wait for its reply */
+ status = HssAccComTdmIOUnitMsgSendAndRecv(
+ message,
+ ICP_HSSACC_TDM_IO_UNIT_HSS_SW_ERROR_READ_RESPONSE,
+ &(hssAccServStats.swErrRead),
+ &statValue);
+ }
+
+ if ( ICP_STATUS_SUCCESS == status)
+ {
+ ixOsalLog(IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT,
+ "Receive HDLC FIFO Overflows: %u\n",
+ statValue,
+ 0, 0, 0, 0, 0);
+
+ HssAccComTdmIOUnitCmd4byte1wordMsgCreate (
+ ICP_HSSACC_TDM_IO_UNIT_HSS_SW_ERROR_READ,
+ ICP_HSSACC_TDM_IO_UNIT_RX_VOICE_FREE_Q_UNDERFLOW, 0, 0, 0,
+ &message);
+
+ /* Send the message to the TDM I/O Unit and wait for its reply */
+ status = HssAccComTdmIOUnitMsgSendAndRecv(
+ message,
+ ICP_HSSACC_TDM_IO_UNIT_HSS_SW_ERROR_READ_RESPONSE,
+ &(hssAccServStats.swErrRead),
+ &statValue);
+ }
+
+ if ( ICP_STATUS_SUCCESS == status)
+ {
+ ixOsalLog(IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT,
+ "Receive Voice Free Q Underflows: %u\n",
+ statValue,
+ 0, 0, 0, 0, 0);
+
+ HssAccComTdmIOUnitCmd4byte1wordMsgCreate (
+ ICP_HSSACC_TDM_IO_UNIT_HSS_SW_ERROR_READ,
+ ICP_HSSACC_TDM_IO_UNIT_RX_HDLC_FREE_Q_UNDERFLOW, 0, 0, 0,
+ &message);
+
+ /* Send the message to the TDM I/O Unit and wait for its reply */
+ status = HssAccComTdmIOUnitMsgSendAndRecv(
+ message,
+ ICP_HSSACC_TDM_IO_UNIT_HSS_SW_ERROR_READ_RESPONSE,
+ &(hssAccServStats.swErrRead),
+ &statValue);
+ }
+
+ if ( ICP_STATUS_SUCCESS == status)
+ {
+ ixOsalLog(IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT,
+ "Receive Voice HDLC Free Underflows: %u\n",
+ statValue,
+ 0, 0, 0, 0, 0);
+
+ HssAccComTdmIOUnitCmd4byte1wordMsgCreate (
+ ICP_HSSACC_TDM_IO_UNIT_HSS_SW_ERROR_READ,
+ ICP_HSSACC_TDM_IO_UNIT_MSG_OUT_FIFO_LP_OVERFLOW, 0, 0, 0,
+ &message);
+
+ /* Send the message to the TDM I/O Unit and wait for its reply */
+ status = HssAccComTdmIOUnitMsgSendAndRecv(
+ message,
+ ICP_HSSACC_TDM_IO_UNIT_HSS_SW_ERROR_READ_RESPONSE,
+ &(hssAccServStats.swErrRead),
+ &statValue);
+ }
+
+ if ( ICP_STATUS_SUCCESS == status)
+ {
+ ixOsalLog(IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT,
+ "Msg Out FIFO Low Priority Overflows: %u\n",
+ statValue,
+ 0, 0, 0, 0, 0);
+
+ HssAccComTdmIOUnitCmd4byte1wordMsgCreate (
+ ICP_HSSACC_TDM_IO_UNIT_HSS_SW_ERROR_READ,
+ ICP_HSSACC_TDM_IO_UNIT_MSG_OUT_FIFO_HP_OVERFLOW, 0, 0, 0,
+ &message);
+
+ /* Send the message to the TDM I/O Unit and wait for its reply */
+ status = HssAccComTdmIOUnitMsgSendAndRecv(
+ message,
+ ICP_HSSACC_TDM_IO_UNIT_HSS_SW_ERROR_READ_RESPONSE,
+ &(hssAccServStats.swErrRead),
+ &statValue);
+ }
+
+ if ( ICP_STATUS_SUCCESS == status)
+ {
+ ixOsalLog(IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT,
+ "Msg Out FIFO High Priority Overflows: %u\n",
+ statValue,
+ 0, 0, 0, 0, 0);
+
+ }
+
+ if (ICP_TRUE == mutexLocked)
+ {
+ /* release the HssAcc Mutex */
+ if (ICP_STATUS_SUCCESS != ICP_HSSACC_MUTEX_UNLOCK())
+ {
+ ICP_HSSACC_REPORT_ERROR ("HssAccSwErrorStatsShow - "
+ "failed to release HssAcc Mutex\n");
+ status = ICP_STATUS_MUTEX;
+ }
+ }
+
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Exiting HssAccSwErrorStatsShow\n");
+ return status;
+}
+
+
+/*****************************************************************************
+ * Abstract:
+ * reset the firmware error stats in the TDM I/O Unit.
+ *
+ *****************************************************************************/
+TDM_PRIVATE icp_status_t
+HssAccSwErrorStatsReset (void)
+{
+ icp_status_t status = ICP_STATUS_SUCCESS;
+ IxPiuMhMessage message;
+ uint8_t resetFlag = 1;
+
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Entering HssAccSwErrorStatsReset\n");
+
+ /* Retrieve each Sw Error Count and print it */
+ HssAccComTdmIOUnitCmd4byte1wordMsgCreate (
+ ICP_HSSACC_TDM_IO_UNIT_HSS_SW_ERROR_READ,
+ ICP_HSSACC_TDM_IO_UNIT_RX_VOICE_Q_OVERFLOW,
+ resetFlag, 0, 0,
+ &message);
+
+ /* Send the message to the TDM I/O Unit and wait for its reply */
+ status = HssAccComTdmIOUnitMsgSendAndRecv(
+ message,
+ ICP_HSSACC_TDM_IO_UNIT_HSS_SW_ERROR_READ_RESPONSE,
+ &(hssAccServStats.swErrReset),
+ NULL);
+
+ if ( ICP_STATUS_SUCCESS == status)
+ {
+
+ HssAccComTdmIOUnitCmd4byte1wordMsgCreate (
+ ICP_HSSACC_TDM_IO_UNIT_HSS_SW_ERROR_READ,
+ ICP_HSSACC_TDM_IO_UNIT_RX_HDLC_Q_OVERFLOW,
+ resetFlag, 0, 0,
+ &message);
+
+ /* Send the message to the TDM I/O Unit and wait for its reply */
+ status = HssAccComTdmIOUnitMsgSendAndRecv(
+ message,
+ ICP_HSSACC_TDM_IO_UNIT_HSS_SW_ERROR_READ_RESPONSE,
+ &(hssAccServStats.swErrReset),
+ NULL);
+ }
+
+ if ( ICP_STATUS_SUCCESS == status)
+ {
+
+ HssAccComTdmIOUnitCmd4byte1wordMsgCreate (
+ ICP_HSSACC_TDM_IO_UNIT_HSS_SW_ERROR_READ,
+ ICP_HSSACC_TDM_IO_UNIT_RX_VOICE_FIFO_OVERFLOW,
+ resetFlag, 0, 0,
+ &message);
+
+ /* Send the message to the TDM I/O Unit and wait for its reply */
+ status = HssAccComTdmIOUnitMsgSendAndRecv(
+ message,
+ ICP_HSSACC_TDM_IO_UNIT_HSS_SW_ERROR_READ_RESPONSE,
+ &(hssAccServStats.swErrReset),
+ NULL);
+ }
+
+ if ( ICP_STATUS_SUCCESS == status)
+ {
+ HssAccComTdmIOUnitCmd4byte1wordMsgCreate (
+ ICP_HSSACC_TDM_IO_UNIT_HSS_SW_ERROR_READ,
+ ICP_HSSACC_TDM_IO_UNIT_RX_HDLC_FIFO_OVERFLOW,
+ resetFlag, 0, 0,
+ &message);
+
+ /* Send the message to the TDM I/O Unit and wait for its reply */
+ status = HssAccComTdmIOUnitMsgSendAndRecv(
+ message,
+ ICP_HSSACC_TDM_IO_UNIT_HSS_SW_ERROR_READ_RESPONSE,
+ &(hssAccServStats.swErrReset),
+ NULL);
+ }
+
+ if ( ICP_STATUS_SUCCESS == status)
+ {
+ HssAccComTdmIOUnitCmd4byte1wordMsgCreate (
+ ICP_HSSACC_TDM_IO_UNIT_HSS_SW_ERROR_READ,
+ ICP_HSSACC_TDM_IO_UNIT_RX_VOICE_FREE_Q_UNDERFLOW,
+ resetFlag, 0, 0,
+ &message);
+
+ /* Send the message to the TDM I/O Unit and wait for its reply */
+ status = HssAccComTdmIOUnitMsgSendAndRecv(
+ message,
+ ICP_HSSACC_TDM_IO_UNIT_HSS_SW_ERROR_READ_RESPONSE,
+ &(hssAccServStats.swErrReset),
+ NULL);
+ }
+
+ if ( ICP_STATUS_SUCCESS == status)
+ {
+ HssAccComTdmIOUnitCmd4byte1wordMsgCreate (
+ ICP_HSSACC_TDM_IO_UNIT_HSS_SW_ERROR_READ,
+ ICP_HSSACC_TDM_IO_UNIT_RX_HDLC_FREE_Q_UNDERFLOW,
+ resetFlag, 0, 0,
+ &message);
+
+ /* Send the message to the TDM I/O Unit and wait for its reply */
+ status = HssAccComTdmIOUnitMsgSendAndRecv(
+ message,
+ ICP_HSSACC_TDM_IO_UNIT_HSS_SW_ERROR_READ_RESPONSE,
+ &(hssAccServStats.swErrReset),
+ NULL);
+ }
+
+ if ( ICP_STATUS_SUCCESS == status)
+ {
+
+ HssAccComTdmIOUnitCmd4byte1wordMsgCreate (
+ ICP_HSSACC_TDM_IO_UNIT_HSS_SW_ERROR_READ,
+ ICP_HSSACC_TDM_IO_UNIT_MSG_OUT_FIFO_LP_OVERFLOW,
+ resetFlag, 0, 0,
+ &message);
+
+ /* Send the message to the TDM I/O Unit and wait for its reply */
+ status = HssAccComTdmIOUnitMsgSendAndRecv(
+ message,
+ ICP_HSSACC_TDM_IO_UNIT_HSS_SW_ERROR_READ_RESPONSE,
+ &(hssAccServStats.swErrReset),
+ NULL);
+ }
+
+ if ( ICP_STATUS_SUCCESS == status)
+ {
+ HssAccComTdmIOUnitCmd4byte1wordMsgCreate (
+ ICP_HSSACC_TDM_IO_UNIT_HSS_SW_ERROR_READ,
+ ICP_HSSACC_TDM_IO_UNIT_MSG_OUT_FIFO_HP_OVERFLOW,
+ resetFlag, 0, 0,
+ &message);
+
+ /* Send the message to the TDM I/O Unit and wait for its reply */
+ status = HssAccComTdmIOUnitMsgSendAndRecv(
+ message,
+ ICP_HSSACC_TDM_IO_UNIT_HSS_SW_ERROR_READ_RESPONSE,
+ &(hssAccServStats.swErrReset),
+ NULL);
+ }
+
+
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Exiting HssAccSwErrorStatsReset\n");
+ return status;
+}
+
+/*****************************************************************************
+ * Abstract:
+ * display all error stats collected by the TDM I/O unit.
+ *
+ *****************************************************************************/
+icp_status_t
+HssAccTdmIOErrorStatsShow (void)
+{
+ icp_status_t status = ICP_STATUS_SUCCESS;
+ IxPiuMhMessage message;
+ unsigned statValue = 0;
+ icp_boolean_t mutexLocked = ICP_FALSE;
+
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Entering HssAccTdmIOErrorStatsShow\n");
+
+ if (ICP_STATUS_SUCCESS != ICP_HSSACC_MUTEX_LOCK())
+ {
+ ICP_HSSACC_REPORT_ERROR ("HssAccTdmIOErrorStatsShow - "
+ "failed to lock HssAcc Mutex\n");
+ status = ICP_STATUS_MUTEX;
+ }
+ else
+ {
+ mutexLocked = ICP_TRUE;
+ }
+
+
+ if ( ICP_STATUS_SUCCESS == status)
+ {
+ ixOsalLog(IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT,
+ "TDM IO Unit Global Error Stats:\n",
+ 0, 0, 0, 0, 0, 0);
+
+ /* Retrieve each hardware error Count and print it */
+ HssAccComTdmIOUnitCmd4byte1wordMsgCreate (
+ ICP_HSSACC_TDM_IO_UNIT_ABT_ALN_ERR_READ,
+ 0, 0, 0, 0,
+ &message);
+
+ /* Send the message to the TDM I/O Unit and wait for its reply */
+ status = HssAccComTdmIOUnitMsgSendAndRecv(
+ message,
+ ICP_HSSACC_TDM_IO_UNIT_ABT_ALN_ERR_READ_RESPONSE,
+ &(hssAccServStats.abtAlnRead),
+ &statValue);
+ }
+
+ if ( ICP_STATUS_SUCCESS == status)
+ {
+ ixOsalLog(IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT,
+ "Alignment Errors %u, Abort Errors %u\n",
+ statValue & ICP_HSSACC_TDM_IO_UNIT_SHORT1_MASK,
+ (statValue & ICP_HSSACC_TDM_IO_UNIT_SHORT0_MASK) >>
+ ICP_HSSACC_TDM_IO_UNIT_SHORT0_OFFSET,
+ 0, 0, 0, 0);
+
+ HssAccComTdmIOUnitCmd4byte1wordMsgCreate (
+ ICP_HSSACC_TDM_IO_UNIT_FCS_MAX_ERR_READ,
+ 0, 0, 0, 0,
+ &message);
+
+ /* Send the message to the TDM I/O Unit and wait for its reply */
+ status =
+ HssAccComTdmIOUnitMsgSendAndRecv(
+ message,
+ ICP_HSSACC_TDM_IO_UNIT_FCS_MAX_ERR_READ_RESPONSE,
+ &(hssAccServStats.fcsMaxRead),
+ &statValue);
+ }
+
+ if ( ICP_STATUS_SUCCESS == status)
+ {
+ ixOsalLog(IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT,
+ "FCS Errors %u, Max Frame Size Errors %u\n",
+ statValue & ICP_HSSACC_TDM_IO_UNIT_SHORT1_MASK,
+ (statValue & ICP_HSSACC_TDM_IO_UNIT_SHORT0_MASK) >>
+ ICP_HSSACC_TDM_IO_UNIT_SHORT0_OFFSET,
+ 0, 0, 0, 0);
+ }
+
+ if (ICP_TRUE == mutexLocked)
+ {
+ /* release the HssAcc Mutex */
+ if (ICP_STATUS_SUCCESS != ICP_HSSACC_MUTEX_UNLOCK())
+ {
+ ICP_HSSACC_REPORT_ERROR ("HssAccTdmIOErrorStatsShow - "
+ "failed to release HssAcc Mutex\n");
+ status = ICP_STATUS_MUTEX;
+ }
+ }
+
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Exiting HssAccTdmIOErrorStatsShow\n");
+ return status;
+}
+
+
+
+
+
+/*****************************************************************************
+ * Abstract:
+ * display all error stats collected by the TDM I/O Unit for the specified
+ * channel.
+ *
+ *****************************************************************************/
+TDM_PRIVATE icp_status_t
+HssAccChannelTdmIOErrorStatsShow(unsigned channelId)
+{
+ icp_status_t status = ICP_STATUS_SUCCESS;
+ IxPiuMhMessage message;
+ unsigned statValue = 0;
+ icp_boolean_t mutexLocked = ICP_FALSE;
+
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Entering HssAccChannelTdmIOErrorStatsShow\n");
+
+ if (ICP_STATUS_SUCCESS != ICP_HSSACC_MUTEX_LOCK())
+ {
+ ICP_HSSACC_REPORT_ERROR ("HssAccChannelTdmIOErrorStatsShow - "
+ "failed to lock HssAcc Mutex\n");
+ status = ICP_STATUS_MUTEX;
+ }
+ else
+ {
+ mutexLocked = ICP_TRUE;
+ }
+
+ if ( ICP_STATUS_SUCCESS == status)
+ {
+ ixOsalLog(IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT,
+ "TDM IO Unit channel Error Stats for channel %u:\n",
+ channelId, 0, 0, 0, 0, 0);
+
+
+ /* Retrieve Stats from the TDM I/O Unit */
+
+ HssAccComTdmIOUnitCmd4byte1wordMsgCreate (
+ ICP_HSSACC_TDM_IO_UNIT_STATS_READ,
+ channelId, 0,
+ ICP_HSSACC_TDM_IO_UNIT_CHAN_STAT_ABT_ALN, 0,
+ &message);
+
+ /* Send the message to the TDM I/O Unit and wait for its reply */
+ status = HssAccComTdmIOUnitMsgSendAndRecv(
+ message,
+ ICP_HSSACC_TDM_IO_UNIT_STATS_READ_RESPONSE,
+ &(hssAccServStats.chanStatRead),
+ &statValue);
+ }
+
+ if ( ICP_STATUS_SUCCESS == status)
+ {
+ ixOsalLog(IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT,
+ "Abort or Alignment: %u\n",
+ statValue,
+ 0, 0, 0, 0, 0);
+
+ HssAccComTdmIOUnitCmd4byte1wordMsgCreate (
+ ICP_HSSACC_TDM_IO_UNIT_STATS_READ,
+ channelId, 0,
+ ICP_HSSACC_TDM_IO_UNIT_CHAN_STAT_FCS, 0,
+ &message);
+
+ /* Send the message to the TDM I/O Unit and wait for its reply */
+ status = HssAccComTdmIOUnitMsgSendAndRecv(
+ message,
+ ICP_HSSACC_TDM_IO_UNIT_STATS_READ_RESPONSE,
+ &(hssAccServStats.chanStatRead),
+ &statValue);
+ }
+
+ if ( ICP_STATUS_SUCCESS == status)
+ {
+ ixOsalLog(IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT,
+ "FCS: %u\n",
+ statValue,
+ 0, 0, 0, 0, 0);
+
+ HssAccComTdmIOUnitCmd4byte1wordMsgCreate (
+ ICP_HSSACC_TDM_IO_UNIT_STATS_READ,
+ channelId, 0,
+ ICP_HSSACC_TDM_IO_UNIT_CHAN_STAT_MAX_SIZE, 0,
+ &message);
+
+ /* Send the message to the TDM I/O Unit and wait for its reply */
+ status = HssAccComTdmIOUnitMsgSendAndRecv(
+ message,
+ ICP_HSSACC_TDM_IO_UNIT_STATS_READ_RESPONSE,
+ &(hssAccServStats.chanStatRead),
+ &statValue);
+
+ }
+
+ if ( ICP_STATUS_SUCCESS == status)
+ {
+ ixOsalLog(IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT,
+ "Max Size: %u\n",
+ statValue,
+ 0, 0, 0, 0, 0);
+
+
+#ifndef NDEBUG
+ /* Retrieve Packet Rx and Tx stats */
+ HssAccComTdmIOUnitCmd4byte1wordMsgCreate (
+ ICP_HSSACC_TDM_IO_UNIT_STATS_READ,
+ channelId, 0,
+ ICP_HSSACC_TDM_IO_UNIT_CHAN_STAT_TX_PKTS, 0,
+ &message);
+
+ /* Send the message to the TDM I/O Unit and wait for its reply */
+ status = HssAccComTdmIOUnitMsgSendAndRecv(
+ message,
+ ICP_HSSACC_TDM_IO_UNIT_STATS_READ_RESPONSE,
+ &(hssAccServStats.chanStatRead),
+ &statValue);
+ }
+
+ if ( ICP_STATUS_SUCCESS == status)
+ {
+ ixOsalLog(IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT,
+ "Transmitted Packets: %u\n",
+ statValue,
+ 0, 0, 0, 0, 0);
+
+
+ HssAccComTdmIOUnitCmd4byte1wordMsgCreate (
+ ICP_HSSACC_TDM_IO_UNIT_STATS_READ,
+ channelId, 0,
+ ICP_HSSACC_TDM_IO_UNIT_CHAN_STAT_RX_PKTS, 0,
+ &message);
+
+ /* Send the message to the TDM I/O Unit and wait for its reply */
+ status = HssAccComTdmIOUnitMsgSendAndRecv(
+ message,
+ ICP_HSSACC_TDM_IO_UNIT_STATS_READ_RESPONSE,
+ &(hssAccServStats.chanStatRead),
+ &statValue);
+ }
+ if ( ICP_STATUS_SUCCESS == status)
+ {
+ ixOsalLog(IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT,
+ "Received Packets: %u\n",
+ statValue,
+ 0, 0, 0, 0, 0);
+
+
+#endif
+ }
+
+ if (ICP_TRUE == mutexLocked)
+ {
+ /* release the HssAcc Mutex */
+ if (ICP_STATUS_SUCCESS != ICP_HSSACC_MUTEX_UNLOCK())
+ {
+ ICP_HSSACC_REPORT_ERROR ("HssAccChannelTdmIOErrorStatsShow - "
+ "failed to release HssAcc Mutex\n");
+ status = ICP_STATUS_MUTEX;
+ }
+ }
+
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Exiting HssAccChannelTdmIOErrorStatsShow\n");
+ return status;
+}
+
+/*****************************************************************************
+ * Abstract:
+ * get the TDM I/O unit to reset all error stats for the specified channel.
+ *
+ *****************************************************************************/
+TDM_PRIVATE icp_status_t
+HssAccChannelTdmIOErrorStatsReset(unsigned channelId)
+{
+ icp_status_t status = ICP_STATUS_SUCCESS;
+ IxPiuMhMessage message;
+ uint8_t resetFlag = 1;
+
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Entering HssAccChannelTdmIOErrorStatsReset\n");
+
+
+
+ /* Retrieve Stats from the TDM I/O Unit */
+
+ HssAccComTdmIOUnitCmd4byte1wordMsgCreate (
+ ICP_HSSACC_TDM_IO_UNIT_STATS_READ,
+ channelId, resetFlag,
+ ICP_HSSACC_TDM_IO_UNIT_CHAN_STAT_ABT_ALN, 0,
+ &message);
+
+ /* Send the message to the TDM I/O Unit and wait for its reply */
+ status = HssAccComTdmIOUnitMsgSendAndRecv(
+ message,
+ ICP_HSSACC_TDM_IO_UNIT_STATS_READ_RESPONSE,
+ &(hssAccServStats.chanStatRead),
+ NULL);
+
+ if ( ICP_STATUS_SUCCESS == status)
+ {
+ HssAccComTdmIOUnitCmd4byte1wordMsgCreate (
+ ICP_HSSACC_TDM_IO_UNIT_STATS_READ,
+ channelId, resetFlag,
+ ICP_HSSACC_TDM_IO_UNIT_CHAN_STAT_FCS, 0,
+ &message);
+
+ /* Send the message to the TDM I/O Unit and wait for its reply */
+ status = HssAccComTdmIOUnitMsgSendAndRecv(
+ message,
+ ICP_HSSACC_TDM_IO_UNIT_STATS_READ_RESPONSE,
+ &(hssAccServStats.chanStatRead),
+ NULL);
+ }
+
+ if ( ICP_STATUS_SUCCESS == status)
+ {
+
+ HssAccComTdmIOUnitCmd4byte1wordMsgCreate (
+ ICP_HSSACC_TDM_IO_UNIT_STATS_READ,
+ channelId, resetFlag,
+ ICP_HSSACC_TDM_IO_UNIT_CHAN_STAT_MAX_SIZE, 0,
+ &message);
+
+ /* Send the message to the TDM I/O Unit and wait for its reply */
+ status = HssAccComTdmIOUnitMsgSendAndRecv(
+ message,
+ ICP_HSSACC_TDM_IO_UNIT_STATS_READ_RESPONSE,
+ &(hssAccServStats.chanStatRead),
+ NULL);
+
+ }
+
+ if ( ICP_STATUS_SUCCESS == status)
+ {
+
+#ifndef NDEBUG
+ /* Retrieve Packet Rx and Tx stats */
+ HssAccComTdmIOUnitCmd4byte1wordMsgCreate (
+ ICP_HSSACC_TDM_IO_UNIT_STATS_READ,
+ channelId, resetFlag,
+ ICP_HSSACC_TDM_IO_UNIT_CHAN_STAT_TX_PKTS, 0,
+ &message);
+
+ /* Send the message to the TDM I/O Unit and wait for its reply */
+ status = HssAccComTdmIOUnitMsgSendAndRecv(
+ message,
+ ICP_HSSACC_TDM_IO_UNIT_STATS_READ_RESPONSE,
+ &(hssAccServStats.chanStatRead),
+ NULL);
+ }
+
+ if ( ICP_STATUS_SUCCESS == status)
+ {
+ HssAccComTdmIOUnitCmd4byte1wordMsgCreate (
+ ICP_HSSACC_TDM_IO_UNIT_STATS_READ,
+ channelId, resetFlag,
+ ICP_HSSACC_TDM_IO_UNIT_CHAN_STAT_RX_PKTS, 0,
+ &message);
+
+ /* Send the message to the TDM I/O Unit and wait for its reply */
+ status = HssAccComTdmIOUnitMsgSendAndRecv(
+ message,
+ ICP_HSSACC_TDM_IO_UNIT_STATS_READ_RESPONSE,
+ &(hssAccServStats.chanStatRead),
+ NULL);
+
+#endif
+ }
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Exiting HssAccChannelTdmIOErrorStatsReset\n");
+ return status;
+}
+
+
+
+/*****************************************************************************
+ * Abstract:
+ * reset all internal stats for this sub-module only.
+ *
+ *****************************************************************************/
+TDM_PRIVATE void
+HssAccServiceStatsReset (void)
+{
+ memset (&hssAccServStats, 0, sizeof(icp_hssacc_service_stats_t));
+}
+
+
+
+
+/*****************************************************************************
+ * Abstract:
+ * display all internal stats for this sub-module.
+ *
+ *****************************************************************************/
+TDM_PRIVATE void
+HssAccServiceStatsShow (void)
+{
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Entering HssAccServiceStatsShow\n");
+ ixOsalLog(IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT,
+ "\nTDM Service Statistics:\n"
+ "Service Timer Config Messaging\n",
+ 0, 0, 0, 0, 0, 0);
+ HssAccSingleMessageStatsShow (hssAccServStats.timerStat);
+ ixOsalLog(IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT,
+ "\nInterrupt Generation Configuration Messaging\n",
+ 0, 0, 0, 0, 0, 0);
+ HssAccSingleMessageStatsShow (hssAccServStats.intStat);
+ ixOsalLog(IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT,
+ "\nAbort and Alignment Error Stats Read Messaging\n",
+ 0, 0, 0, 0, 0, 0);
+ HssAccSingleMessageStatsShow (hssAccServStats.abtAlnRead);
+ ixOsalLog(IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT,
+ "\nFCS and Max Size Error Stats Read Messaging\n",
+ 0, 0, 0, 0, 0, 0);
+ HssAccSingleMessageStatsShow (hssAccServStats.fcsMaxRead);
+ ixOsalLog(IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT,
+ "\nChannel Stats Read Messaging\n",
+ 0, 0, 0, 0, 0, 0);
+ HssAccSingleMessageStatsShow (hssAccServStats.chanStatRead);
+ ixOsalLog(IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT,
+ "\nTDM IO Unit Firmware Error Stats Read Messaging\n",
+ 0, 0, 0, 0, 0, 0);
+ HssAccSingleMessageStatsShow (hssAccServStats.swErrRead);
+ ixOsalLog(IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT,
+ "\nTDM IO Unit Firmware Error Stats Reset Messaging\n",
+ 0, 0, 0, 0, 0, 0);
+ HssAccSingleMessageStatsShow (hssAccServStats.swErrReset);
+
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Exiting HssAccServiceStatsShow\n");
+
+}
+
+
+
+/*****************************************************************************
+ * Abstract:
+ * Updates the configuration of the int generation on the TDM I/O Unit
+ *
+ *****************************************************************************/
+TDM_PRIVATE icp_status_t
+HssAccServiceIntGenUpdate (void)
+{
+ icp_status_t status = ICP_STATUS_SUCCESS;
+ uint8_t voiceTxEnabled = ICP_HSSACC_TDM_IO_UNIT_HSS_INT_DISABLED;
+ uint8_t voiceRxEnabled = ICP_HSSACC_TDM_IO_UNIT_HSS_INT_DISABLED;
+ uint8_t hdlcTxEnabled = ICP_HSSACC_TDM_IO_UNIT_HSS_INT_DISABLED;
+ uint8_t hdlcRxEnabled = ICP_HSSACC_TDM_IO_UNIT_HSS_INT_DISABLED;
+ IxPiuMhMessage message;
+
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Entering HssAccServiceIntGenUpdate\n");
+
+ if (ICP_TRUE == voiceIntEnabled)
+ {
+ voiceTxEnabled = ICP_HSSACC_TDM_IO_UNIT_HSS_INT_ENABLED;
+ voiceRxEnabled = ICP_HSSACC_TDM_IO_UNIT_HSS_INT_ENABLED;
+ }
+
+ if (ICP_TRUE == hdlcIntEnabled)
+ {
+ hdlcTxEnabled = ICP_HSSACC_TDM_IO_UNIT_HSS_INT_ENABLED;
+ hdlcRxEnabled = ICP_HSSACC_TDM_IO_UNIT_HSS_INT_ENABLED;
+ }
+
+ /* Construct the message to configure the interrupt generation */
+ HssAccComTdmIOUnitCmd8byteMsgCreate (
+ ICP_HSSACC_TDM_IO_UNIT_HSS_INT_CFG,
+ 0, 0, 0,
+ hdlcTxEnabled, hdlcRxEnabled,
+ voiceTxEnabled, voiceRxEnabled,
+ &message);
+
+ /* Send the message to the TDM I/O Unit and wait for its reply */
+ status = HssAccComTdmIOUnitMsgSendAndRecv(
+ message,
+ ICP_HSSACC_TDM_IO_UNIT_HSS_INT_CFG_RESPONSE,
+ &(hssAccServStats.intStat),
+ NULL);
+
+ if (ICP_STATUS_SUCCESS != status)
+ {
+ ICP_HSSACC_REPORT_ERROR ("HssAccServiceIntGenUpdate - "
+ "Failed to update Interrupt Gen "
+ "Config in TDM I/O Unit\n");
+ }
+
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Exiting HssAccServiceIntGenUpdate\n");
+ return status;
+}
diff --git a/Acceleration/library/icp_telephony/tdm_io_access/icp_hssacc_symbols.c b/Acceleration/library/icp_telephony/tdm_io_access/icp_hssacc_symbols.c
new file mode 100644
index 0000000..53e7855
--- /dev/null
+++ b/Acceleration/library/icp_telephony/tdm_io_access/icp_hssacc_symbols.c
@@ -0,0 +1,121 @@
+/******************************************************************************
+ * @file icp_hssacc_symbols.c
+ *
+ * @description Contents of this file provide the list of symbols to be
+ * exported by this module
+ *
+ * @ingroup icp_HssAcc
+ *
+ * @Revision 1.0
+ *
+ * @par
+ * This file is provided under a dual BSD/GPLv2 license. When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved.
+ * Copyright(c) 2010,2011,2012 Avencall
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * The full GNU General Public License is included in this distribution
+ * in the file called LICENSE.GPL.
+ *
+ * BSD LICENSE
+ *
+ * Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ * Copyright(c) 2010,2011,2012 Avencall
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ *
+ *
+ *****************************************************************************/
+
+
+#ifdef __linux
+
+
+#include <linux/module.h>
+#include "icp_hssacc.h"
+
+EXPORT_SYMBOL(icp_HssAccInit);
+EXPORT_SYMBOL(icp_HssAccHdlcInit);
+EXPORT_SYMBOL(icp_HssAccVoiceInit);
+EXPORT_SYMBOL(icp_HssAccShutdown);
+EXPORT_SYMBOL(icp_HssAccNumSupportedPortsGet);
+EXPORT_SYMBOL(icp_HssAccPortConfig);
+EXPORT_SYMBOL(icp_HssAccPortUp);
+EXPORT_SYMBOL(icp_HssAccPortDown);
+EXPORT_SYMBOL(icp_HssAccNumSupportedChannelsGet);
+EXPORT_SYMBOL(icp_HssAccChannelAllocate);
+EXPORT_SYMBOL(icp_HssAccChannelConfigure);
+EXPORT_SYMBOL(icp_HssAccChannelHdlcServiceConfigure);
+EXPORT_SYMBOL(icp_HssAccChannelVoiceServiceConfigure);
+EXPORT_SYMBOL(icp_HssAccChannelCallbacksRegister);
+EXPORT_SYMBOL(icp_HssAccErrorCallbackRegister);
+EXPORT_SYMBOL(icp_HssAccPortErrorCallbackRegister);
+EXPORT_SYMBOL(icp_HssAccNumSupportedGCTsGet);
+EXPORT_SYMBOL(icp_HssAccNumSupportedVoiceBypassesGet);
+EXPORT_SYMBOL(icp_HssAccVoiceBypassGctDownload);
+EXPORT_SYMBOL(icp_HssAccVoiceBypassEnable);
+EXPORT_SYMBOL(icp_HssAccVoiceBypassDisable);
+EXPORT_SYMBOL(icp_HssAccChannelUp);
+EXPORT_SYMBOL(icp_HssAccChannelDown);
+EXPORT_SYMBOL(icp_HssAccChannelDelete);
+EXPORT_SYMBOL(icp_HssAccTransmit);
+EXPORT_SYMBOL(icp_HssAccReceive);
+EXPORT_SYMBOL(icp_HssAccRxFreeReplenish);
+EXPORT_SYMBOL(icp_HssAccTxDoneRetrieve);
+EXPORT_SYMBOL(icp_HssAccAllBuffersRetrieve);
+EXPORT_SYMBOL(icp_HssAccDataPathService);
+EXPORT_SYMBOL(icp_HssAccChannelStatsShow);
+EXPORT_SYMBOL(icp_HssAccChannelStatsReset);
+EXPORT_SYMBOL(icp_HssAccPortStatsShow);
+EXPORT_SYMBOL(icp_HssAccPortStatsReset);
+EXPORT_SYMBOL(icp_HssAccStatsShow);
+EXPORT_SYMBOL(icp_HssAccStatsReset);
+
+#include "icp_hssacc_queues_config.h"
+
+// hacky
+EXPORT_SYMBOL(HssAccQueueIdGet);
+
+#endif
diff --git a/Acceleration/library/icp_telephony/tdm_io_access/icp_hssacc_timeslot_allocation.c b/Acceleration/library/icp_telephony/tdm_io_access/icp_hssacc_timeslot_allocation.c
new file mode 100644
index 0000000..80a9d72
--- /dev/null
+++ b/Acceleration/library/icp_telephony/tdm_io_access/icp_hssacc_timeslot_allocation.c
@@ -0,0 +1,665 @@
+/******************************************************************************
+ *
+ * @file icp_hssacc_timeslot_allocation.c
+ *
+ * @description Content of this file is the implementation of the Timeslot
+ * allocation and de-allocation functionality used for channel Allocation
+ * and deletion. This platform specific implementation compliments the
+ * file icp_hssacc_common_timeslot_allocation.c containing the common
+ * sections of this module.
+ *
+ * @ingroup icp_HssAcc
+ *
+ * @Revision 1.0
+ *
+ * @par
+ * This file is provided under a dual BSD/GPLv2 license. When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * The full GNU General Public License is included in this distribution
+ * in the file called LICENSE.GPL.
+ *
+ * Contact Information:
+ * Intel Corporation
+ *
+ * BSD LICENSE
+ *
+ * Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ *
+ *
+ *****************************************************************************/
+#include "IxOsal.h"
+
+#include "icp_hssacc.h"
+#include "icp_hssacc_common.h"
+#include "icp_hssacc_trace.h"
+#include "icp_hssacc_timeslot_allocation.h"
+#include "icp_hssacc_port_config.h"
+#include "icp_hssacc_channel_config.h"
+#include "icp_hssacc_address_translate.h"
+
+
+
+#define ICP_HSSACC_OFFSET_HALF_WD_PER_LINE (16)
+#define ICP_HSSACC_CHAN_OFFS_PER_WD (2)
+
+/* This Macro operates an endianness swap on half-words for
+ addressing purposes within the TDM I/O Unit channel offset
+ table */
+#define ICP_HSSACC_CHAN_OFFS_LOC_IN_TBL(chan) ((chan)^1)
+
+/* Stats */
+typedef struct icp_hssacc_ts_alloc_stats_s
+{
+ icp_hssacc_msg_with_resp_stats_t hssPortProvTableLoad;
+ icp_hssacc_msg_with_resp_stats_t chanOffsetTableLoad;
+ icp_hssacc_msg_with_resp_stats_t chanOffsetTableRead;
+ icp_hssacc_msg_with_resp_stats_t hssPortProvTableSwap;
+} icp_hssacc_ts_alloc_stats_t;
+
+
+TDM_PRIVATE icp_hssacc_ts_alloc_stats_t hssAccTsAllocStats;
+
+TDM_PRIVATE icp_boolean_t hssAccTsAllocated [ICP_HSSACC_MAX_NUM_PORTS];
+
+
+/**
+ * Function Definition: HssAccTsAllocSwapStatsGet
+ */
+icp_hssacc_msg_with_resp_stats_t * HssAccTsAllocSwapStatsGet(void)
+{
+ return &(hssAccTsAllocStats.hssPortProvTableSwap);
+}
+
+/**
+ * Function Definition: HssAccTsAllocOffsetTableReadStatsGet
+ */
+icp_hssacc_msg_with_resp_stats_t * HssAccTsAllocOffsetTableReadStatsGet(void)
+{
+ return &(hssAccTsAllocStats.chanOffsetTableRead);
+}
+
+/**
+ * Function Definition: HssAccTsAllocPlatformInit
+ */
+icp_status_t HssAccTsAllocPlatformInit (void)
+{
+ icp_status_t status = ICP_STATUS_SUCCESS;
+ unsigned portIndex = 0;
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Entering HssAccTsAllocPlatformInit\n");
+
+ for (portIndex = 0; portIndex < ICP_HSSACC_MAX_NUM_PORTS; portIndex ++)
+ {
+ hssAccTsAllocated[portIndex] = ICP_FALSE;
+ }
+
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Exiting HssAccTsAllocPlatformInit\n");
+ return status;
+}
+
+
+
+/**
+ * Function definition: HssAccTsAllocStatsReset
+ */
+void HssAccTsAllocStatsReset (void)
+{
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Entering HssAccTsAllocStatsReset\n");
+ memset (&hssAccTsAllocStats,
+ 0,
+ sizeof(icp_hssacc_ts_alloc_stats_t));
+
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Exiting HssAccTsAllocStatsReset\n");
+}
+
+
+
+#ifdef SW_SWAPPING
+/**
+ * Function definition: HssAccTsAllocTableWordsSwap
+ * This function assumes that the size provided is a multiple
+ * of a word size.
+ */
+TDM_PRIVATE
+void HssAccTsAllocTableWordsSwap (uint32_t * tableAddr,
+ uint32_t sizeInBytes)
+{
+ unsigned index = 0;
+ for (;index < (sizeInBytes/ICP_HSSACC_WORD_SIZE); index ++)
+ {
+ tableAddr[index] = IX_OSAL_SWAP_BE_SHARED_LONG(tableAddr[index]);
+ }
+}
+#endif
+
+
+
+/**
+ * Function definition: HssAccTsAllocOffsetTableLoad
+ */
+
+TDM_PRIVATE icp_status_t
+HssAccTsAllocOffsetTableLoad (unsigned portId,
+ uint32_t offsetTablePhysAddr,
+ uint8_t messageId,
+ uint8_t messageRespId,
+ icp_hssacc_msg_with_resp_stats_t * stats,
+ icp_boolean_t activeTableLoad)
+{
+ icp_status_t status = ICP_STATUS_SUCCESS;
+ IxPiuMhMessage message;
+ uint8_t activeShadow = 0;
+
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Entering HssAccTsAllocOffsetTableLoad\n");
+
+ /* Translate Active/Shadow, only used for certain types of message
+ of no impact on others */
+ if ( ICP_TRUE == activeTableLoad )
+ {
+ activeShadow = 1;
+ }
+
+ /* Create Message for TDM I/O Unit */
+ HssAccComTdmIOUnitCmd4byte1wordMsgCreate (messageId,
+ 0,
+ portId,
+ activeShadow,
+ offsetTablePhysAddr,
+ &message);
+ /* Send the message */
+ status = HssAccComTdmIOUnitMsgSendAndRecv(message,
+ messageRespId,
+ stats,
+ NULL);
+
+
+ if (ICP_STATUS_SUCCESS != status)
+ {
+ ICP_HSSACC_REPORT_ERROR("HssAccTsAllocOffsetTableLoad - "
+ "Failed communication with TDM I/O Unit "
+ "for Timeslot Allocation\n");
+ }
+
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Exiting HssAccTsAllocOffsetTableLoad\n");
+
+ return status;
+}
+
+
+
+
+/**
+ * Function definition: HssAccTsAllocDummyProvTableCreate
+ * This will create a table with a single channel enabled
+ * with all timeslots assigned
+ */
+void
+HssAccTsAllocDummyProvTableCreate (uint32_t * provTable)
+{
+ unsigned index = 0;
+ for (index = 0; index < ICP_HSSACC_MAX_TIMESLOTS_PER_PORT; index++)
+ {
+ provTable[index] =
+ (ICP_HSSACC_TDM_IO_UNIT_TS_ENABLE <<
+ ICP_HSSACC_TDM_IO_UNIT_TS_EN_BIT_OFFSET);
+ }
+}
+
+
+/*****************************************************************************
+ * Abstract:
+ * Builds a new channel offset table for the TDM I/O unit. Only the offsets
+ * of channels on the specified HSS port will be affected.
+ * Also constructs a new Timeslot provisioning table for the specified port.
+ * When both tables have been built, they are loaded into the TDM I/O unit.
+ *
+ *****************************************************************************/
+icp_status_t
+HssAccTsAllocUpdate(unsigned portId,
+ const icp_hssacc_channel_config_t * hssChannelData)
+{
+ icp_status_t status = ICP_STATUS_SUCCESS;
+ unsigned chanId = 0, hdmaChannelId = 0;
+ unsigned tableProvOffset[ICP_HSSACC_MAX_NUM_PORTS];
+ uint32_t tableOffset = 0;
+ uint16_t *pTdmIoUnitOffsetTable = NULL;
+ uint32_t *pHdmaProvTable = NULL;
+ uint8_t tsIndex, indexOffset = 0;
+ icp_boolean_t noTsUsed = ICP_TRUE;
+ uint32_t hdmaProvTablePhysOffset = 0;
+ uint32_t tdmIoUnitOffsetTablePhysOffset = 0;
+
+ ICP_HSSACC_TRACE_1 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Entering HssAccTsAllocUpdate - "
+ "Configuring timeslots on port %u\n",
+ portId);
+
+ /* Get the base address of the channel offset tables */
+ pTdmIoUnitOffsetTable =
+ (uint16_t *)HssAccTsAllocTdmIoUnitOffsetTableVirtAddrGet();
+
+ pHdmaProvTable =
+ (uint32_t *)HssAccTsAllocHdmaProvTableVirtAddrGet();
+
+ /* Clear the contents of the TDM I/O Unit channe offset table
+ and timeslot provisioning table */
+ memset (pHdmaProvTable, 0, ICP_HSSACC_TDM_IO_UNIT_PROV_TABLE_SZ);
+ memset (pTdmIoUnitOffsetTable, 0, ICP_HSSACC_TDM_IO_UNIT_OFFSET_TABLE_SZ);
+ memset (tableProvOffset, 0, ICP_HSSACC_MAX_NUM_PORTS*sizeof(unsigned));
+ /*
+ * The objective here is to pack the internal TDM I/O Unit memory channel
+ * usage such that the TDM I/O unit's internal memory doesn't become
+ * fragmented from adding/removing channels. This allows us to make maximum
+ * use of the total available memory.
+ *
+ * Two tables need to be updated:
+ * 1) the TDM I/O unit's offset table, which has a 1-to-1 mapping between
+ * MAX_NUM channels and their location in internal memory. Only
+ * channels on the specified port will be updated. The offset of each
+ * channel is relative to the port base address.
+ * 2) the TDM I/O Unit's timeslot proviosining table, which tracks the
+ * offsets of all channels active on that port. The channel ID(s) on a
+ * port differ from that of the TDM I/O unit (since we can't
+ * have MAX_NUM channels per port). For example,
+ * channel 5 (from the perspective of the access layer/TDM I/O unit)
+ * could have a channel ID of 0 on the port where it is active.
+ *
+ * Timeslot aggregation is also performed for all channels on the port.
+ */
+
+ /* The TDM I/O unit offset table has an entry for MAX_NUM channels */
+ for (chanId = 0; chanId < ICP_HSSACC_MAX_NUM_CHANNELS; chanId++)
+ {
+ /*
+ * Only need to update the channels on the specified port, so skip any
+ * that are active on other ports, or inactive.
+ * This preserves the offsets for channels on other HSS ports.
+ */
+ if (hssChannelData[chanId].size > 0)
+ {
+ /* Update the TDM I/O unit offset table for the active
+ channel (byte offset required)*/
+ pTdmIoUnitOffsetTable[ICP_HSSACC_CHAN_OFFS_LOC_IN_TBL(chanId)] =
+ tableProvOffset[hssChannelData[chanId].portId];
+
+ if (hssChannelData[chanId].portId == portId)
+ {
+ noTsUsed = ICP_FALSE;
+ hssAccTsAllocated[portId] = ICP_TRUE;
+
+ /* Calculate the HDMA timeslot index offset */
+ indexOffset = hssChannelData[chanId].lineId *
+ ICP_HSSACC_MAX_TIMESLOTS_PER_TDM_LINE;
+
+
+ /* Enable the timeslots used by this channel */
+ for (tsIndex = 0;
+ tsIndex < ICP_HSSACC_MAX_TIMESLOTS_PER_TDM_LINE;
+ tsIndex ++)
+ {
+ if (hssChannelData[chanId].timeslotMap & BIT_SET(tsIndex))
+ {
+ ICP_HSSACC_TRACE_3 (ICP_HSSACC_DEBUG,
+ "HssAccTsAllocUpdate - Timeslot"
+ " %u is used by chan %u "
+ "on port %u\n",
+ tsIndex,
+ chanId,
+ hssChannelData[chanId].portId);
+ pHdmaProvTable[indexOffset + tsIndex] =
+ (ICP_HSSACC_TDM_IO_UNIT_TS_ENABLE <<
+ ICP_HSSACC_TDM_IO_UNIT_TS_EN_BIT_OFFSET) |
+ (hdmaChannelId << ICP_HSSACC_TDM_IO_UNIT_CHAN_OFFSET);
+ }
+ }
+
+ /*
+ * Must offset by 128 words in order to get to the first channel
+ * configuration word.
+ */
+ indexOffset = ICP_HSSACC_MAX_TIMESLOTS_PER_PORT;
+
+ /* Update the HDMA offset table */
+ pHdmaProvTable[indexOffset + hdmaChannelId] =
+ tableOffset << ICP_HSSACC_TDM_IO_UNIT_CHAN_OFFSET;
+
+ hdmaChannelId ++;
+
+ /* Update the word offset by the size of the channel */
+ tableOffset += hssChannelData[chanId].size;
+ }
+ tableProvOffset[hssChannelData[chanId].portId] +=
+ hssChannelData[chanId].size*ICP_HSSACC_WORD_SIZE;
+
+ }
+ }
+
+ /* if no TS are used for this port, we need to allocate a dummy single
+ channel with all timeslots assigned to keep the TDM I/O Unit from
+ generating errors */
+ if (noTsUsed)
+ {
+ HssAccTsAllocDummyProvTableCreate(pHdmaProvTable);
+ }
+#ifdef SW_SWAPPING
+ HssAccTsAllocTableWordsSwap(pHdmaProvTable,
+ ICP_HSSACC_TDM_IO_UNIT_PROV_TABLE_SZ);
+
+ HssAccTsAllocTableWordsSwap((uint32_t*)pTdmIoUnitOffsetTable,
+ ICP_HSSACC_TDM_IO_UNIT_OFFSET_TABLE_SZ);
+#endif
+
+ /* Flush the new tables to memory */
+ IX_OSAL_CACHE_FLUSH (pHdmaProvTable, ICP_HSSACC_TDM_IO_UNIT_PROV_TABLE_SZ);
+ IX_OSAL_CACHE_FLUSH (pTdmIoUnitOffsetTable,
+ ICP_HSSACC_TDM_IO_UNIT_OFFSET_TABLE_SZ);
+
+ /* Convert virtual addresses to Physical Offsets */
+ hdmaProvTablePhysOffset =
+ HssAccVirtToPhysAddressTranslate(pHdmaProvTable);
+ tdmIoUnitOffsetTablePhysOffset =
+ HssAccVirtToPhysAddressTranslate((uint32_t*)pTdmIoUnitOffsetTable);
+
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_DEBUG,
+ "HssAccTsAllocUpdate - Update HDMA"
+ " provision table\n");
+
+
+ /* Load the new HDMA offset table for this port */
+ status = HssAccTsAllocOffsetTableLoad (
+ portId,
+ hdmaProvTablePhysOffset,
+ ICP_HSSACC_TDM_IO_UNIT_PORT_PROV_TABLE_LOAD,
+ ICP_HSSACC_TDM_IO_UNIT_PORT_PROV_TABLE_LOAD_RESPONSE,
+ &(hssAccTsAllocStats.hssPortProvTableLoad),
+ ICP_FALSE);
+
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_DEBUG,
+ "HssAccTsAllocUpdate - Update offset"
+ " table\n");
+
+ /* Load the new TDM I/O unit offset table */
+ status = HssAccTsAllocOffsetTableLoad(
+ 0,
+ tdmIoUnitOffsetTablePhysOffset,
+ ICP_HSSACC_TDM_IO_UNIT_OFFS_TABLE_LOAD,
+ ICP_HSSACC_TDM_IO_UNIT_OFFS_TABLE_LOAD_RESPONSE,
+ &(hssAccTsAllocStats.chanOffsetTableLoad),
+ ICP_FALSE);
+ }
+
+
+
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ status = HssAccTsAllocTableSwap (portId);
+ }
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Exiting HssAccTsAllocUpdate\n");
+
+ return status;
+}
+
+
+
+/**
+ * Function definition: HssAccTsAllocInitialAllocationUpdate
+ */
+icp_status_t
+HssAccTsAllocInitialAllocationUpdate(unsigned portId)
+
+{
+ icp_status_t status = ICP_STATUS_SUCCESS;
+ uint32_t *pHdmaProvTable = NULL;
+ uint32_t hdmaProvTablePhysOffset = 0;
+
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Entering HssAccTsAllocInitialAllocationUpdate\n");
+ if (ICP_TRUE != hssAccTsAllocated[portId])
+ {
+
+ /* Get the base address of the channel offset tables */
+ pHdmaProvTable =
+ (uint32_t *)HssAccTsAllocHdmaProvTableVirtAddrGet();
+
+ /* Clear the contents of the HDMA offset table */
+ memset (pHdmaProvTable, 0, ICP_HSSACC_TDM_IO_UNIT_PROV_TABLE_SZ);
+
+
+ HssAccTsAllocDummyProvTableCreate(pHdmaProvTable);
+
+#ifdef SW_SWAPPING
+ HssAccTsAllocTableWordsSwap(pHdmaProvTable,
+ ICP_HSSACC_TDM_IO_UNIT_PROV_TABLE_SZ);
+
+#endif
+ /* Flush the new tables to memory */
+ IX_OSAL_CACHE_FLUSH (pHdmaProvTable,
+ ICP_HSSACC_TDM_IO_UNIT_PROV_TABLE_SZ);
+
+
+ /* Convert virtual addresses to Physical Offsets */
+ hdmaProvTablePhysOffset =
+ HssAccVirtToPhysAddressTranslate(pHdmaProvTable);
+
+ ICP_HSSACC_TRACE_0(ICP_HSSACC_DEBUG,
+ "HssAccTsAllocInitialAllocationUpdate - "
+ "Update Timeslot provisioning table\n");
+
+
+ /* Load the new timeslot Provisioning table for this port */
+ status =
+ HssAccTsAllocOffsetTableLoad (
+ portId,
+ hdmaProvTablePhysOffset,
+ ICP_HSSACC_TDM_IO_UNIT_PORT_PROV_TABLE_LOAD,
+ ICP_HSSACC_TDM_IO_UNIT_PORT_PROV_TABLE_LOAD_RESPONSE,
+ &(hssAccTsAllocStats.hssPortProvTableLoad),
+ ICP_TRUE);
+
+ }
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Exiting HssAccTsAllocInitialAllocationUpdate\n");
+ return status;
+}
+
+
+
+
+
+
+
+/**
+ * Function definition: HssAccTsAllocOffsetTableShow
+ */
+TDM_PRIVATE void
+HssAccTsAllocOffsetTableShow (icp_boolean_t readShadowTable)
+{
+ icp_status_t status = ICP_STATUS_SUCCESS;
+ uint32_t offsetTableWord = 0;
+ uint16_t offsetTableOffset = 0;
+ unsigned channelCount = 0;
+
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Entering HssAccTsAllocOffsetTableShow\n");
+
+ for (offsetTableOffset = 0;
+ offsetTableOffset < ICP_HSSACC_TDM_IO_UNIT_OFFSET_TABLE_SZ;
+ offsetTableOffset += ICP_HSSACC_WORD_SIZE)
+ {
+ status = HssAccTsAllocOffsetTableWordRead (readShadowTable,
+ offsetTableOffset,
+ &offsetTableWord);
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ if (0 == (offsetTableOffset % ICP_HSSACC_OFFSET_HALF_WD_PER_LINE))
+ {
+ ixOsalLog(IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT,
+ "%u: ",
+ channelCount,
+ 0, 0, 0, 0, 0);
+ }
+ ixOsalLog(IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT,
+ "0x%04X 0x%04X ",
+ (uint16_t)((offsetTableWord &
+ ICP_HSSACC_TDM_IO_UNIT_SHORT0_MASK) >>
+ ICP_HSSACC_TDM_IO_UNIT_SHORT0_OFFSET),
+ (uint16_t)(offsetTableWord &
+ ICP_HSSACC_TDM_IO_UNIT_SHORT1_MASK),
+ 0, 0, 0, 0);
+ if ((ICP_HSSACC_OFFSET_HALF_WD_PER_LINE - ICP_HSSACC_WORD_SIZE) ==
+ (offsetTableOffset % ICP_HSSACC_OFFSET_HALF_WD_PER_LINE))
+ {
+ ixOsalLog(IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT,
+ "\n", 0, 0, 0, 0, 0, 0);
+ }
+ }
+ else
+ {
+ ICP_HSSACC_REPORT_ERROR ("HssAccTsAllocOffsetTableShow - "
+ "Failed to read "
+ "Channel Offset Table from TDM I/O Unit\n");
+ break;
+ }
+ channelCount += ICP_HSSACC_CHAN_OFFS_PER_WD;
+ }
+
+ ixOsalLog(IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT,
+ "\n", 0, 0, 0, 0, 0, 0);
+
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Exiting HssAccTsAllocOffsetTableShow\n");
+}
+
+
+/**
+ * Function definition: HssAccTsAllocChanOffsetActiveTableShow
+ */
+void HssAccTsAllocChanOffsetActiveTableShow (void)
+{
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Entering HssAccTsAllocChanOffsetActiveTableShow\n");
+
+ ixOsalLog(IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT,
+ "\nTDM I/O Unit Channel Offset ACTIVE Table:\n",
+ 0, 0, 0, 0, 0, 0);
+ ixOsalLog(IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT,
+ "\n----------------------------------------------\n",
+ 0, 0, 0, 0, 0, 0);
+ HssAccTsAllocOffsetTableShow (ICP_FALSE);
+
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Exiting HssAccTsAllocChanOffsetActiveTableShow\n");
+}
+
+
+/**
+ * Function definition: HssAccTsAllocChanOffsetShadowTableShow
+ */
+void HssAccTsAllocChanOffsetShadowTableShow (void)
+{
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Entering HssAccTsAllocChanOffsetShadowTableShow\n");
+
+ ixOsalLog(IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT,
+ "\nTDM I/O Unit Channel Offset SHADOW Table:\n",
+ 0, 0, 0, 0, 0, 0);
+ ixOsalLog(IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT,
+ "\n----------------------------------------\n",
+ 0, 0, 0, 0, 0, 0);
+ HssAccTsAllocOffsetTableShow (ICP_TRUE);
+
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Exiting HssAccTsAllocChanOffsetShadowTableShow\n");
+}
+
+
+
+/**
+ * Function definition: HssAccTsAllocStatsShow
+ */
+void HssAccTsAllocStatsShow (void)
+{
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Entering HssAccTsAllocStatsShow\n");
+
+ ixOsalLog(IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT,
+ "\nTimeslot Allocation Stats:\n",
+ 0, 0, 0, 0, 0, 0);
+ ixOsalLog(IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT,
+ "Stats for TDM I/O Unit channel Offset Table Load messages:\n",
+ 0, 0, 0, 0, 0, 0);
+ HssAccSingleMessageStatsShow(hssAccTsAllocStats.chanOffsetTableLoad);
+ ixOsalLog(IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT,
+ "Stats for Timeslot Provisioning Table Load messages:\n",
+ 0, 0, 0, 0, 0, 0);
+ HssAccSingleMessageStatsShow(hssAccTsAllocStats.hssPortProvTableLoad);
+ ixOsalLog(IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT,
+ "Stats for Timeslot Provisioning Table Swap messages:\n",
+ 0, 0, 0, 0, 0, 0);
+ HssAccSingleMessageStatsShow(hssAccTsAllocStats.hssPortProvTableSwap);
+ ixOsalLog(IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT,
+ "Stats for TDM I/O Unit channel Offset Table Read messages:\n",
+ 0, 0, 0, 0, 0, 0);
+ HssAccSingleMessageStatsShow(hssAccTsAllocStats.chanOffsetTableRead);
+
+ HssAccTsAllocChanOffsetActiveTableShow();
+ HssAccTsAllocChanOffsetShadowTableShow();
+
+
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Exiting HssAccTsAllocStatsShow\n");
+}
diff --git a/Acceleration/library/icp_telephony/tdm_io_access/icp_hssacc_tx_datapath.c b/Acceleration/library/icp_telephony/tdm_io_access/icp_hssacc_tx_datapath.c
new file mode 100644
index 0000000..3f02636
--- /dev/null
+++ b/Acceleration/library/icp_telephony/tdm_io_access/icp_hssacc_tx_datapath.c
@@ -0,0 +1,1023 @@
+/*****************************************************************************
+ * @file icp_hssacc_tx_datapath.c
+ *
+ * @description Contents of this file provide the implementation of the
+ * transmit functionality for the HSS I/O Access component
+ *
+ * @ingroup icp_HssAcc
+ *
+ * @Revision 1.0
+ *
+ * @par
+ * This file is provided under a dual BSD/GPLv2 license. When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * The full GNU General Public License is included in this distribution
+ * in the file called LICENSE.GPL.
+ *
+ * Contact Information:
+ * Intel Corporation
+ *
+ * BSD LICENSE
+ *
+ * Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ *
+ *
+ ******************************************************************************/
+
+#include "IxOsal.h"
+
+
+#include "icp.h"
+#include "icp_hssacc.h"
+#include "icp_hssacc_trace.h"
+#include "icp_hssacc_channel_config.h"
+#include "icp_hssacc_address_translate.h"
+
+#include "icp_hssacc_rings.h"
+#include "icp_hssacc_queues_config.h"
+#include "icp_hssacc_tx_datapath.h"
+#include "icp_hssacc_tdm_io_queue_entry.h"
+#include "IxQMgr.h"
+
+
+/* Mutex which controls access to transmit datapath path functions */
+TDM_PRIVATE IxOsalMutex hssAccTxMutex[ICP_HSSACC_MAX_NUM_CHANNELS];
+
+TDM_PRIVATE icp_hssacc_tx_done_callback_t
+hssAccTxDoneChannelCallbacks[ICP_HSSACC_MAX_NUM_CHANNELS];
+
+TDM_PRIVATE icp_user_context_t
+hssAccTxDoneUserContext[ICP_HSSACC_MAX_NUM_CHANNELS];
+
+TDM_PRIVATE uint32_t
+hssAccTxDatapathNumPendPkts[ICP_HSSACC_MAX_NUM_CHANNELS];
+
+TDM_PRIVATE icp_boolean_t
+hssAccTxDatapathLastSubmitSuccess[ICP_HSSACC_MAX_NUM_CHANNELS];
+
+TDM_PRIVATE icp_boolean_t hssAccTxServiceInitialised = ICP_FALSE;
+
+
+/* Stats */
+#ifndef NDEBUG
+TDM_PRIVATE uint32_t hssAccTxNumPktsSubmissions[ICP_HSSACC_MAX_NUM_CHANNELS];
+TDM_PRIVATE uint32_t
+hssAccTxNumPktsSuccessSubmissions[ICP_HSSACC_MAX_NUM_CHANNELS];
+TDM_PRIVATE uint32_t hssAccTxNumPktsDone[ICP_HSSACC_MAX_NUM_CHANNELS];
+#endif
+
+
+/*
+ * Initialises the service mutex.
+ */
+#define ICP_HSSACC_TX_DP_MUTEX_INIT(channelId) \
+ (ixOsalMutexInit(&hssAccTxMutex[channelId]))
+
+/*
+ * Locks the service mutex.
+ */
+#define ICP_HSSACC_TX_DP_MUTEX_LOCK(channelId) \
+ (ixOsalMutexLock(&hssAccTxMutex[channelId],ICP_HSSACC_MUTEX_TIMEOUT))
+
+/*
+ * Unlocks the service mutex.
+ */
+#define ICP_HSSACC_TX_DP_MUTEX_UNLOCK(channelId) \
+ (ixOsalMutexUnlock(&hssAccTxMutex[channelId]))
+
+/*
+ * Destroys the service mutex.
+ */
+#define ICP_HSSACC_TX_DP_MUTEX_DESTROY(channelId) \
+ (ixOsalMutexDestroy(&hssAccTxMutex[channelId]))
+
+/*
+ * Reset the stats for a channel
+ */
+#ifndef NDEBUG
+#define ICP_HSSACC_TX_DP_CHAN_STATS_RESET(channelId) do { \
+ hssAccTxNumPktsSuccessSubmissions[channelId] = 0; \
+ hssAccTxNumPktsSubmissions[channelId] = 0; \
+ hssAccTxNumPktsDone[channelId] =0; \
+ } while(0);
+#else
+#define ICP_HSSACC_TX_DP_CHAN_STATS_RESET(channelId) do { \
+ } while (0);
+#endif
+
+
+/* Data for the descriptor to mbuf mapping queue */
+TDM_PRIVATE uint32_t
+hssAccDataPlaneTxDescRingData
+[ICP_HSSACC_MAX_NUM_CHANNELS][ICP_HSSACC_TX_QUEUE_DEPTH];
+
+
+TDM_PRIVATE icp_hssacc_dataplane_ring_t
+hssAccDataPlaneTxDescRing[ICP_HSSACC_MAX_NUM_CHANNELS];
+
+TDM_PRIVATE icp_boolean_t hssAccDataPlaneTxBypass[ICP_HSSACC_MAX_NUM_CHANNELS];
+
+
+/*****************************************************************************
+ * Abstract:
+ * Resets the Tx Datapath internal data.
+ *
+ *****************************************************************************/
+TDM_PRIVATE icp_status_t
+HssAccTxDatapathReset(void);
+
+
+
+
+icp_status_t
+HssAccTxDatapathInit(void)
+{
+ uint32_t index = 0;
+ icp_status_t status = ICP_STATUS_SUCCESS;
+ ICP_HSSACC_DP_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Entering HssAccTxDatapathInit\n");
+ if (ICP_TRUE == hssAccTxServiceInitialised)
+ {
+ ICP_HSSACC_REPORT_ERROR("HssAccTxDatapathInit - Tx Datapath sub-component"
+ " already initialised\n");
+ status = ICP_STATUS_RESOURCE;
+ }
+
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ /* We support 1 client only per channel, to protect against corruption
+ we need 1 mutex per channel */
+ for (index = 0;
+ index < ICP_HSSACC_MAX_NUM_CHANNELS;
+ index ++)
+ {
+ if (ICP_STATUS_SUCCESS != ICP_HSSACC_TX_DP_MUTEX_INIT(index))
+ {
+ ICP_HSSACC_REPORT_ERROR_1("HssAccTxDatapathInit - Mutex "
+ "Init Error for channel %d\n",
+ index);
+ status = ICP_STATUS_MUTEX;
+ break;
+ }
+ }
+ status = HssAccTxDatapathReset();
+ }
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ hssAccTxServiceInitialised = ICP_TRUE;
+ }
+ ICP_HSSACC_DP_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Exiting HssAccTxDatapathInit\n");
+ return status;
+}
+
+
+void
+HssAccTxDatapathChanStatsReset(uint32_t channelId)
+{
+ if (ICP_STATUS_SUCCESS == ICP_HSSACC_TX_DP_MUTEX_LOCK(channelId))
+ {
+ ICP_HSSACC_TX_DP_CHAN_STATS_RESET(channelId);
+
+ if (ICP_STATUS_SUCCESS != ICP_HSSACC_TX_DP_MUTEX_UNLOCK(channelId))
+ {
+ ICP_HSSACC_REPORT_ERROR_1("HssAccTxDatapathChanStatsReset - "
+ "Mutex Unlock Error for channel %d\n",
+ channelId);
+ }
+ }
+ else
+ {
+ ICP_HSSACC_REPORT_ERROR_1("HssAccTxDatapathChanStatsReset - "
+ "Mutex Lock Error for channel %d\n",
+ channelId);
+ }
+}
+
+
+void
+HssAccTxDatapathChanStatsShow(uint32_t channelId)
+{
+#ifndef NDEBUG
+ ixOsalLog(IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT,
+ "\nChannel Tx Datapath Statistics\n",
+ 0, 0, 0, 0, 0, 0);
+ ixOsalLog(IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT,
+ "\t\t%d Packets Submitted\n"
+ "\t\t%d Packets Successfully Submitted\n"
+ "\t\t%d Packets Done and Recycled to Client\n",
+ hssAccTxNumPktsSubmissions[channelId],
+ hssAccTxNumPktsSuccessSubmissions[channelId],
+ hssAccTxNumPktsDone[channelId], 0, 0, 0);
+#else
+ ixOsalLog(IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT,
+ "\nChannel Tx Datapath Statistics Not Supported in this Build\n",
+ 0, 0, 0, 0, 0, 0);
+#endif
+}
+
+
+icp_status_t
+HssAccTxDatapathShutdown(void)
+{
+ uint32_t index = 0;
+ icp_status_t status = ICP_STATUS_SUCCESS;
+ ICP_HSSACC_DP_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Entering HssAccTxDatapathShutdown\n");
+ if (ICP_TRUE == hssAccTxServiceInitialised)
+ {
+ status = HssAccTxDatapathReset();
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ for (index = 0; index < ICP_HSSACC_MAX_NUM_CHANNELS; index ++)
+ {
+ if (ICP_STATUS_SUCCESS != ICP_HSSACC_TX_DP_MUTEX_DESTROY(index))
+ {
+ ICP_HSSACC_REPORT_ERROR_1("HssAccTxDatapathShutdown - Mutex "
+ "Destroy Error for channel %d\n",
+ index);
+ status = ICP_STATUS_MUTEX;
+ break;
+ }
+ }
+ }
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ hssAccTxServiceInitialised = ICP_FALSE;
+ }
+ }
+ ICP_HSSACC_DP_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Exiting HssAccTxDatapathShutdown\n");
+ return status;
+}
+
+
+TDM_PRIVATE icp_status_t
+HssAccTxDatapathReset(void)
+{
+ uint32_t index = 0;
+ icp_status_t status = ICP_STATUS_SUCCESS;
+ ICP_HSSACC_DP_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Entering HssAccTxDatapathReset\n");
+ for (index = 0; index < ICP_HSSACC_MAX_NUM_CHANNELS; index ++)
+ {
+ if (ICP_STATUS_SUCCESS == ICP_HSSACC_TX_DP_MUTEX_LOCK(index))
+ {
+ hssAccDataPlaneTxDescRing[index].content =
+ hssAccDataPlaneTxDescRingData[index];
+ hssAccDataPlaneTxDescRing[index].size = ICP_HSSACC_TX_QUEUE_DEPTH;
+ hssAccDataPlaneTxDescRing[index].mask =
+ ICP_HSSACC_TX_QUEUE_DEPTH - 1;
+
+ hssAccDataPlaneTxDescRing[index].tail = 0;
+ hssAccDataPlaneTxDescRing[index].head = 0;
+ hssAccDataPlaneTxBypass[index] = ICP_FALSE;
+ hssAccTxDatapathNumPendPkts[index] = 0;
+ hssAccTxDatapathLastSubmitSuccess[index] = ICP_FALSE;
+ ICP_HSSACC_TX_DP_CHAN_STATS_RESET(index);
+ if (ICP_STATUS_SUCCESS != ICP_HSSACC_TX_DP_MUTEX_UNLOCK(index))
+ {
+ ICP_HSSACC_REPORT_ERROR_1("HssAccTxDatapathReset - "
+ "Mutex Unlock Error for channel %d\n",
+ index);
+ status = ICP_STATUS_MUTEX;
+ break;
+ }
+ }
+ else
+ {
+ ICP_HSSACC_REPORT_ERROR_1("HssAccTxDatapathReset - "
+ "Mutex Lock Error for channel %d\n",
+ index);
+ status = ICP_STATUS_MUTEX;
+ break;
+ }
+ }
+ ICP_HSSACC_DP_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Exiting HssAccTxDatapathReset\n");
+ return status;
+}
+
+
+icp_status_t
+HssAccTxDatapathChanTypeUpdate (uint32_t channelId,
+ icp_hssacc_channel_type_t chanType)
+{
+ icp_status_t status = ICP_STATUS_SUCCESS;
+ ICP_HSSACC_DP_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Entering HssAccTxDatapathChanTypeUpdate\n");
+ if (ICP_STATUS_SUCCESS == ICP_HSSACC_TX_DP_MUTEX_LOCK(channelId))
+ {
+ if (ICP_HSSACC_CHAN_TYPE_HDLC == chanType)
+ {
+ hssAccDataPlaneTxDescRing[channelId].size =
+ ICP_HSSACC_HDLC_TX_QUEUE_DEPTH;
+ hssAccDataPlaneTxDescRing[channelId].mask =
+ ICP_HSSACC_HDLC_TX_QUEUE_DEPTH - 1;
+ }
+ else
+ {
+ hssAccDataPlaneTxDescRing[channelId].size =
+ ICP_HSSACC_VOICE_TX_QUEUE_DEPTH;
+ hssAccDataPlaneTxDescRing[channelId].mask =
+ ICP_HSSACC_VOICE_TX_QUEUE_DEPTH - 1;
+ }
+ if (ICP_STATUS_SUCCESS != ICP_HSSACC_TX_DP_MUTEX_UNLOCK(channelId))
+ {
+ ICP_HSSACC_REPORT_ERROR_1("HssAccTxDatapathChanTypeUpdate - "
+ "Mutex Unlock Error for channel %d\n",
+ channelId);
+ status = ICP_STATUS_MUTEX;
+ }
+ }
+ else
+ {
+ ICP_HSSACC_REPORT_ERROR_1("HssAccTxDatapathChanTypeUpdate - "
+ "Mutex Lock Error for channel %d\n",
+ channelId);
+ status = ICP_STATUS_MUTEX;
+ }
+
+ ICP_HSSACC_DP_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Exiting HssAccTxDatapathChanTypeUpdate\n");
+ return status;
+}
+
+TDM_PRIVATE icp_status_t
+HssAccTxDatapathBufferValidityCheck(const IX_OSAL_MBUF * buffer,
+ icp_hssacc_channel_type_t channelType)
+{
+ icp_status_t status = ICP_STATUS_SUCCESS;
+ ICP_HSSACC_DP_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Entering HssAccTxDatapathBufferValidityCheck\n");
+
+ if ((NULL != IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR(buffer)) ||
+ (NULL != IX_OSAL_MBUF_NEXT_PKT_IN_CHAIN_PTR(buffer)))
+ {
+ ICP_HSSACC_REPORT_ERROR("HssAccTxDatapathBufferValidityCheck - "
+ "Buffer and Packet Chaining not supported "
+ "for Transmission\n");
+ status = ICP_STATUS_INVALID_PARAM;
+ }
+ if ( IX_OSAL_MBUF_PKT_LEN(buffer) != IX_OSAL_MBUF_MLEN(buffer))
+ {
+ ICP_HSSACC_REPORT_ERROR("HssAccTxDatapathBufferValidityCheck - "
+ "Buffer length and Packet Length in OS "
+ "Abstraction Layer Buffer must be equal\n");
+ status = ICP_STATUS_INVALID_PARAM;
+ }
+ if (0 == IX_OSAL_MBUF_PKT_LEN(buffer))
+ {
+ ICP_HSSACC_REPORT_ERROR("HssAccTxDatapathBufferValidityCheck - "
+ "Buffer length cannot be 0\n");
+ status = ICP_STATUS_INVALID_PARAM;
+ }
+ if (NULL == IX_OSAL_MBUF_MDATA(buffer))
+ {
+ ICP_HSSACC_REPORT_ERROR("HssAccTxDatapathBufferValidityCheck - "
+ "Pointer to data cannot be NULL\n");
+ status = ICP_STATUS_INVALID_PARAM;
+ }
+ if (ICP_HSSACC_CHAN_TYPE_VOICE == channelType)
+ {
+ /* voice buffers - check if length is not
+ modulo 4 (using bit comparison) */
+ if (0 != (IX_OSAL_MBUF_PKT_LEN(buffer) &
+ (uint32_t) ICP_HSSACC_TX_VOICE_PACKET_LENGTH_CHECK_MASK))
+ {
+ ICP_HSSACC_REPORT_ERROR_1("HssAccTxDatapathBufferValidityCheck - "
+ "Voice buffer length must be divisible "
+ "by 4 - buffer provided has "
+ "length %d\n",
+ IX_OSAL_MBUF_PKT_LEN(buffer));
+ status = ICP_STATUS_INVALID_PARAM;
+ }
+ }
+
+ ICP_HSSACC_DP_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Exiting HssAccTxDatapathBufferValidityCheck\n");
+ return status;
+}
+
+
+TDM_PRIVATE void
+HssAccTxDatapathBufferTdmSectionUpdate(uint32_t channelId,
+ IX_OSAL_MBUF * buffer)
+{
+ icp_hssacc_osal_mbuf_tdm_io_section_t * pBufferTdmSection =
+ (icp_hssacc_osal_mbuf_tdm_io_section_t*)&(buffer->ix_ne);
+ ICP_HSSACC_DP_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Entering HssAccTxDatapathBufferTdmSectionUpdate\n");
+
+ /* Using the data in the normal section of the OSAL Buffer,
+ we fill the TDM I/O private section of the buffer */
+ ICP_OSAL_MBUF_TDM_SECT_CHANNEL_ID(pBufferTdmSection) = channelId;
+ ICP_OSAL_MBUF_TDM_SECT_STATUS(pBufferTdmSection) = 0;
+
+ ICP_OSAL_MBUF_TDM_SECT_CURR_BUF_LEN_MSB(pBufferTdmSection) =
+ ICP_OSAL_MBUF_PKT_LEN_MSB(IX_OSAL_MBUF_PKT_LEN(buffer));
+
+ ICP_OSAL_MBUF_TDM_SECT_CURR_BUF_LEN_LSB(pBufferTdmSection) =
+ ICP_OSAL_MBUF_PKT_LEN_LSB(IX_OSAL_MBUF_PKT_LEN(buffer));
+
+ ICP_OSAL_MBUF_TDM_SECT_DATA(pBufferTdmSection) = IX_OSAL_MBUF_MDATA(buffer);
+ ICP_OSAL_MBUF_TDM_SECT_PKT_LEN(pBufferTdmSection) = 0;
+
+ ICP_OSAL_MBUF_TDM_SECT_NEXT_BUF(pBufferTdmSection) = NULL;
+ ICP_OSAL_MBUF_TDM_SECT_OSAL_MBUF_START(pBufferTdmSection) = buffer;
+
+ ICP_HSSACC_DP_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Exiting HssAccTxDatapathBufferTdmSectionUpdate\n");
+}
+
+
+
+/* This function requires the OSAL buffer to have been filled
+ with the correct data in the TDM I/O specific section */
+TDM_PRIVATE void
+HssAccTxDatapathQueueEntryCreate(IX_OSAL_MBUF * buffer,
+ icp_hssacc_tdm_io_queue_entry_t * qEntry)
+{
+ /* initialise this pointer to the start of the TDM I/O Private section
+ of the OSAL buffer passed as a parameter */
+ icp_hssacc_osal_mbuf_tdm_io_section_t * pBufferTdmSection =
+ (icp_hssacc_osal_mbuf_tdm_io_section_t*)&(buffer->ix_ne);
+ ICP_HSSACC_DP_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Entering HssAccTxDatapathQueueEntryCreate\n");
+ /* Create the first word of the Q Entry using the first word of the TDM I/O
+ Section of the buffer passed */
+ qEntry->descriptor.word =
+ pBufferTdmSection->tdm_io_entry.descriptor.word;
+
+ /* Endianness Swap done by translation function */
+ ICP_TDM_IO_Q_ENTRY_DATA(qEntry) =
+ (void*)HssAccVirtToPhysAddressTranslateAndSwap(
+ ICP_OSAL_MBUF_TDM_SECT_DATA(pBufferTdmSection));
+
+ /* This field is not used for Tx */
+ ICP_TDM_IO_Q_ENTRY_PKT_LEN(qEntry) = 0;
+
+ ICP_TDM_IO_Q_ENTRY_OSAL_MBUF(qEntry) =
+ (IX_OSAL_MBUF*)HssAccVirtToPhysAddressTranslateAndSwap(buffer);
+
+ ICP_HSSACC_DP_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Exiting HssAccTxDatapathQueueEntryCreate\n");
+}
+
+icp_status_t
+icp_HssAccTransmit (uint32_t channelId,
+ IX_OSAL_MBUF *buffer)
+{
+ icp_status_t status = ICP_STATUS_SUCCESS;
+ icp_hssacc_tdm_io_queue_entry_t qEntry;
+ icp_boolean_t mutexLocked = ICP_FALSE;
+ ICP_HSSACC_DP_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Entering icp_HssAccTransmit\n");
+
+#ifndef NDEBUG
+ if (ICP_TRUE != hssAccTxServiceInitialised)
+ {
+ ICP_HSSACC_REPORT_ERROR("icp_HssAccTransmit - Service not initialised\n");
+ status = ICP_STATUS_FAIL;
+ }
+
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ if (ICP_HSSACC_MAX_NUM_CHANNELS <= channelId)
+ {
+ ICP_HSSACC_REPORT_ERROR("icp_HssAccTransmit - invalid ChannelId\n");
+ status = ICP_STATUS_INVALID_PARAM;
+ }
+ else
+ {
+ hssAccTxNumPktsSubmissions[channelId] ++;
+ }
+ if (NULL == buffer)
+ {
+ ICP_HSSACC_REPORT_ERROR("icp_HssAccTransmit - Invalid Buffer\n");
+ status = ICP_STATUS_INVALID_PARAM;
+ }
+ }
+
+#endif
+
+
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ /* Check the Buffer validity */
+ status =
+ HssAccTxDatapathBufferValidityCheck(buffer,
+ HssAccChannelConfigTypeQuery(
+ channelId));
+ }
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ /* Lock the Datapath on Transmit */
+ if (ICP_STATUS_SUCCESS != ICP_HSSACC_TX_DP_MUTEX_LOCK(channelId))
+ {
+ ICP_HSSACC_REPORT_ERROR_1("icp_HssAccTransmit - "
+ "Mutex Lock Error for channel %d\n",
+ channelId);
+ status = ICP_STATUS_MUTEX;
+ }
+ }
+
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ mutexLocked = ICP_TRUE;
+ if (ICP_TRUE == hssAccDataPlaneTxBypass[channelId])
+ {
+ ICP_HSSACC_REPORT_ERROR_1("icp_HssAccTransmit - "
+ "Tx not allowed, Channel %d is bypassed\n",
+ channelId);
+ status = ICP_STATUS_RESOURCE;
+ }
+ }
+
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ /* Check the Channel Type and Queue Level. reject if above level and
+ previous submission was accepted */
+ if ((ICP_HSSACC_CHAN_TYPE_VOICE ==
+ HssAccChannelConfigTypeQuery(channelId)) &&
+ (ICP_HSSACC_TX_Q_WATERMARK_LEVEL <=
+ hssAccTxDatapathNumPendPkts[channelId]) &&
+ (ICP_TRUE == hssAccTxDatapathLastSubmitSuccess[channelId]))
+ {
+ ICP_HSSACC_DP_TRACE_1 (ICP_HSSACC_DEBUG,
+ "icp_HssAccTransmit - "
+ "Regulating Tx Flow for channel %d\n",
+ channelId);
+ status = ICP_STATUS_OVERFLOW;
+ }
+ }
+
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ HssAccDataEndiannessSwap(buffer);
+ HssAccTxDatapathBufferTdmSectionUpdate(channelId,
+ buffer);
+ /* Create the Queue Entry for the Q */
+ HssAccTxDatapathQueueEntryCreate(buffer,
+ &qEntry);
+ /* Submit the Entry to the Queue */
+ status = ixQMgrQWrite (HssAccQueueIdGet(channelId),
+ (IxQMgrQEntryType *)&qEntry);
+ }
+
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ /* Push the Buffer Ptr onto the Ring */
+ ICP_HSSACC_DATAPLANE_RING_ENTRY_ADD(hssAccDataPlaneTxDescRing[channelId],
+ buffer);
+ hssAccTxDatapathNumPendPkts[channelId] ++;
+ hssAccTxDatapathLastSubmitSuccess[channelId] = ICP_TRUE;
+#ifndef NDEBUG
+ hssAccTxNumPktsSuccessSubmissions[channelId] ++;
+#endif
+ }
+ else
+ {
+ hssAccTxDatapathLastSubmitSuccess[channelId] = ICP_FALSE;
+ }
+
+ /* Unlock the datapath */
+ if (ICP_TRUE == mutexLocked)
+ {
+ if (ICP_STATUS_SUCCESS != ICP_HSSACC_TX_DP_MUTEX_UNLOCK(channelId))
+ {
+ ICP_HSSACC_REPORT_ERROR_1("icp_HssAccTransmit - "
+ "Mutex Unlock Error for channel %d\n",
+ channelId);
+ status = ICP_STATUS_MUTEX;
+ }
+ }
+ ICP_HSSACC_DP_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Exiting icp_HssAccTransmit\n");
+ return status;
+}
+
+
+
+icp_status_t
+icp_HssAccTxDoneRetrieve (uint32_t channelId,
+ IX_OSAL_MBUF **buffer)
+{
+ icp_status_t status = ICP_STATUS_SUCCESS;
+ uint32_t entry = 0;
+ icp_boolean_t mutexLocked = ICP_FALSE;
+ ICP_HSSACC_DP_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Entering icp_HssAccTxDoneRetrieve\n");
+#ifndef NDEBUG
+ if (ICP_TRUE != hssAccTxServiceInitialised)
+ {
+ ICP_HSSACC_REPORT_ERROR("icp_HssAccTxDoneRetrieve - "
+ "Service not initialised\n");
+ status = ICP_STATUS_FAIL;
+ }
+
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ if (ICP_HSSACC_MAX_NUM_CHANNELS <= channelId)
+ {
+ ICP_HSSACC_REPORT_ERROR("icp_HssAccTxDoneRetrieve - "
+ "invalid ChannelId\n");
+ status = ICP_STATUS_INVALID_PARAM;
+ }
+ if (NULL == buffer)
+ {
+ ICP_HSSACC_REPORT_ERROR("icp_HssAccTxDoneRetrieve - "
+ "Invalid Buffer\n");
+ status = ICP_STATUS_INVALID_PARAM;
+ }
+ }
+#endif
+
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ /* Lock the datapath for this Q */
+ if (ICP_STATUS_SUCCESS != ICP_HSSACC_TX_DP_MUTEX_LOCK(channelId))
+ {
+ ICP_HSSACC_REPORT_ERROR_1("icp_HssAccTxDoneRetrieve - "
+ "Mutex Lock Error for channel %d\n",
+ channelId);
+ status = ICP_STATUS_MUTEX;
+ }
+ }
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ mutexLocked = ICP_TRUE;
+ /* The Shadow counter allows us to keep track of the number of
+ transmissions completed by the TDM I/O Unit: real Tail - shadow Tail =
+ number of transmits completed by unit since last servicing. here we are
+ retrieving the oldest completed transmission so increment the shadow
+ counter by 1 */
+ status = ixQMgrShadowAdvance(HssAccQueueIdGet(channelId),
+ IX_QMGR_Q_SHADOW_TAIL_ONLY,
+ 1);
+ }
+
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ /* Get the Buffer Ptr from the Ring */
+ ICP_HSSACC_DATAPLANE_RING_ENTRY_REM(hssAccDataPlaneTxDescRing[channelId],
+ entry);
+ *buffer = (IX_OSAL_MBUF*)entry;
+ hssAccTxDatapathNumPendPkts[channelId] --;
+#ifndef NDEBUG
+ hssAccTxNumPktsDone[channelId] ++;
+#endif
+ }
+
+ /* Unlock datapath */
+ if (ICP_TRUE == mutexLocked)
+ {
+ if (ICP_STATUS_SUCCESS != ICP_HSSACC_TX_DP_MUTEX_UNLOCK(channelId))
+ {
+ ICP_HSSACC_REPORT_ERROR_1("icp_HssAccTxDoneRetrieve - "
+ "Mutex Unlock Error for channel %d\n",
+ channelId);
+ status = ICP_STATUS_MUTEX;
+ }
+ }
+
+ ICP_HSSACC_DP_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Exiting icp_HssAccTxDoneRetrieve\n");
+ return status;
+}
+
+
+
+icp_status_t
+HssAccTxDatapathChanBypassStateSet(uint32_t channelId,
+ icp_boolean_t bypassed)
+{
+ icp_status_t status = ICP_STATUS_SUCCESS;
+ ICP_HSSACC_DP_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Entering HssAccTxDatapathChanBypassedSet\n");
+ /* Lock the Tx Datapath Mutex */
+ if (ICP_STATUS_SUCCESS != ICP_HSSACC_TX_DP_MUTEX_LOCK(channelId))
+ {
+ ICP_HSSACC_REPORT_ERROR_1("HssAccTxDatapathChanBypassSet - "
+ "Mutex Lock Error for channel %d\n",
+ channelId);
+ status = ICP_STATUS_MUTEX;
+ }
+ else
+ {
+ hssAccDataPlaneTxBypass[channelId] = bypassed;
+
+ /* Unlock the mutex */
+ if (ICP_STATUS_SUCCESS != ICP_HSSACC_TX_DP_MUTEX_UNLOCK(channelId))
+ {
+ ICP_HSSACC_REPORT_ERROR_1("HssAccTxDapapathChanBypassedSet - "
+ "Mutex Unlock Error for channel %d\n",
+ channelId);
+ status = ICP_STATUS_MUTEX;
+ }
+ }
+ ICP_HSSACC_DP_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Exiting HssAccTxDatapathChanBypassedSet\n");
+ return status;
+}
+
+
+void
+HssAccTxDatapathChanTxDoneCallbackRegister(
+ uint32_t channelId,
+ icp_hssacc_tx_done_callback_t txDoneCallback,
+ icp_user_context_t userContext)
+{
+ ICP_HSSACC_DP_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Entering HssAccTxDatapathChanTxDoneCallbackRegister\n");
+ hssAccTxDoneChannelCallbacks[channelId] = txDoneCallback;
+ hssAccTxDoneUserContext[channelId] = userContext;
+ ICP_HSSACC_DP_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Exiting HssAccTxDatapathChanTxDoneCallbackRegister\n");
+}
+
+/******************************************************************************
+ * Abstract:
+ * Register rx callback and user context
+ *
+ ******************************************************************************/
+void
+HssAccTxDatapathChanTxDoneCallbackDeregister(uint32_t channelId)
+{
+ ICP_HSSACC_DP_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Entering HssAccChannelRxCallbackDeregister\n");
+
+ hssAccTxDoneChannelCallbacks[channelId] = NULL;
+ hssAccTxDoneUserContext[channelId] = 0;
+
+ ICP_HSSACC_DP_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Exiting HssAccChannelRxCallbackDeregister\n");
+}
+
+
+
+/* Service all channels of the specified channel Type: find any completed
+ transmissions by the TDM I/O Unit and report them to the client */
+icp_status_t
+HssAccTxDatapathService(icp_hssacc_channel_type_t channelType)
+{
+ icp_status_t status = ICP_STATUS_SUCCESS;
+ uint32_t index = 0;
+ uint32_t numEntries = 0;
+ ICP_HSSACC_DP_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Entering HssAccTxDatapathService\n");
+
+ /* cycle through the channels for this service */
+ for (; index < ICP_HSSACC_MAX_NUM_CHANNELS; index ++)
+ {
+ numEntries = 0;
+ /* check if servicing is required on TxDone and use the callback
+ if this is the case */
+ if (channelType == HssAccChannelConfigTypeQuery(index))
+ {
+ if (ICP_HSSACC_CHANNEL_ENABLED !=
+ HssAccChannelConfigStateQuery(index))
+ {
+ /* This channel has been configured for this service but it is
+ not enabled, Datapath functionality is not enabled yet */
+ continue;
+ }
+ status = ixQMgrShadowDeltaGet(HssAccQueueIdGet(index),
+ IX_QMGR_Q_SHADOW_TAIL_ONLY,
+ &numEntries);
+ }
+ if (ICP_STATUS_SUCCESS != status)
+ {
+ ICP_HSSACC_REPORT_ERROR_1 ("HssAccTxDatapathService - "
+ "Couldnt determine Queue level for "
+ "channel %d\n",
+ index);
+ break;
+ }
+ if (0 < numEntries)
+ {
+ if (NULL != hssAccTxDoneChannelCallbacks[index])
+ {
+ hssAccTxDoneChannelCallbacks[index](
+ hssAccTxDoneUserContext[index]);
+ }
+ else
+ {
+ ICP_HSSACC_DP_TRACE_1 (ICP_HSSACC_DEBUG,
+ "HssAccTxDatapathService - "
+ "Channel %d has no TxDone callback\n",
+ index);
+ }
+ ICP_HSSACC_DP_TRACE_1 (ICP_HSSACC_DEBUG,
+ "HssAccTxDatapathService - Channel %d Serviced\n",
+ index);
+ }
+ }
+ ICP_HSSACC_DP_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Exiting HssAccTxDatapathService\n");
+
+ return status;
+}
+
+
+
+/* Retrieve all buffers left over on the specified channel,
+ channel must be disabled */
+icp_status_t
+HssAccTxDatapathChannelBuffersRetrieve(uint32_t channelId,
+ IX_OSAL_MBUF * * startChainBuffer,
+ IX_OSAL_MBUF * * endChainBuffer)
+{
+ icp_status_t status = ICP_STATUS_SUCCESS;
+ uint32_t numEntries = 0;
+ uint32_t entry = 0;
+ IX_OSAL_MBUF * pCurrentBuffer = NULL;
+ icp_boolean_t mutexLocked = ICP_FALSE;
+ icp_boolean_t chainStarted = ICP_FALSE;
+
+ ICP_HSSACC_DP_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Entering HssAccTxDatapathChannelBuffersRetrieve\n");
+
+ /* Lock the datapath for this Q */
+ if (ICP_STATUS_SUCCESS != ICP_HSSACC_TX_DP_MUTEX_LOCK(channelId))
+ {
+ ICP_HSSACC_REPORT_ERROR_1("HssAccTxDatapathChannelBuffersRetrieve - "
+ "Mutex Lock Error for channel %d\n",
+ channelId);
+ status = ICP_STATUS_MUTEX;
+ }
+
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ ICP_HSSACC_DP_TRACE_0 (ICP_HSSACC_DEBUG,
+ "HssAccTxDatapathChannelBuffersRetrieve - "
+ "Recycle Tx Done Buffers\n");
+
+ mutexLocked = ICP_TRUE;
+ status = ixQMgrShadowDeltaGet(HssAccQueueIdGet(channelId),
+ IX_QMGR_Q_SHADOW_TAIL_ONLY,
+ &numEntries);
+
+ if ((ICP_STATUS_SUCCESS == status) &&
+ (0 != numEntries))
+ {
+ ICP_HSSACC_DP_TRACE_0 (ICP_HSSACC_DEBUG,
+ "HssAccTxDatapathChannelBuffersRetrieve - "
+ "Update the QMgr for TxDone\n");
+ status = ixQMgrShadowAdvance(HssAccQueueIdGet(channelId),
+ IX_QMGR_Q_SHADOW_TAIL_ONLY,
+ numEntries);
+
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ numEntries --;
+ ICP_HSSACC_DATAPLANE_RING_ENTRY_REM(
+ hssAccDataPlaneTxDescRing[channelId],
+ entry);
+
+ *startChainBuffer = (IX_OSAL_MBUF*)entry;
+ pCurrentBuffer = (IX_OSAL_MBUF*)entry;
+ chainStarted = ICP_TRUE;
+#ifndef NDEBUG
+ hssAccTxNumPktsDone[channelId] ++;
+#endif
+ }
+ }
+ }
+
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ ICP_HSSACC_DP_TRACE_0 (ICP_HSSACC_DEBUG,
+ "HssAccTxDatapathChannelBuffersRetrieve - "
+ "Create Chain with Tx Done Buffers\n");
+
+ for (; numEntries > 0; numEntries --)
+ {
+ ICP_HSSACC_DATAPLANE_RING_ENTRY_REM(
+ hssAccDataPlaneTxDescRing[channelId],
+ entry);
+
+ IX_OSAL_MBUF_NEXT_PKT_IN_CHAIN_PTR(pCurrentBuffer) =
+ (IX_OSAL_MBUF*)entry;
+ pCurrentBuffer = (IX_OSAL_MBUF*)entry;
+#ifndef NDEBUG
+ hssAccTxNumPktsDone[channelId] ++;
+#endif
+ }
+
+ ICP_HSSACC_DP_TRACE_0 (ICP_HSSACC_DEBUG,
+ "HssAccTxDatapathChannelBuffersRetrieve - "
+ "Recycle Tx Pending Buffers\n");
+
+ status = ixQMgrQNumEntriesGet(HssAccQueueIdGet(channelId),
+ &numEntries);
+ }
+ if ((ICP_STATUS_SUCCESS == status) &&
+ (0 != numEntries))
+ {
+ /* Update Queue Head counter */
+ status = ixQMgrQWriteRollback(HssAccQueueIdGet(channelId),
+ numEntries);
+
+ }
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ ICP_HSSACC_DP_TRACE_0 (ICP_HSSACC_DEBUG,
+ "HssAccTxDatapathChannelBuffersRetrieve - "
+ "Append Chain with Tx Buffers\n");
+ if ((ICP_FALSE == chainStarted) &&
+ (0 != numEntries))
+ {
+ numEntries --;
+ ICP_HSSACC_DATAPLANE_RING_ENTRY_REM(
+ hssAccDataPlaneTxDescRing[channelId],
+ entry);
+
+ *startChainBuffer = (IX_OSAL_MBUF*)entry;
+ pCurrentBuffer = (IX_OSAL_MBUF*)entry;
+#ifndef NDEBUG
+ hssAccTxNumPktsDone[channelId] ++;
+#endif
+ }
+ for (; numEntries > 0; numEntries --)
+ {
+ ICP_HSSACC_DATAPLANE_RING_ENTRY_REM(
+ hssAccDataPlaneTxDescRing[channelId],
+ entry);
+
+ IX_OSAL_MBUF_NEXT_PKT_IN_CHAIN_PTR(pCurrentBuffer) =
+ (IX_OSAL_MBUF*)entry;
+ pCurrentBuffer = (IX_OSAL_MBUF*)entry;
+#ifndef NDEBUG
+ hssAccTxNumPktsDone[channelId] ++;
+#endif
+ }
+
+ *endChainBuffer = pCurrentBuffer;
+ hssAccTxDatapathNumPendPkts[channelId] = 0;
+ }
+
+ /* Unlock datapath */
+ if (ICP_TRUE == mutexLocked)
+ {
+ if (ICP_STATUS_SUCCESS != ICP_HSSACC_TX_DP_MUTEX_UNLOCK(channelId))
+ {
+ ICP_HSSACC_REPORT_ERROR_1("HssAccTxDatapathChannelBuffersRetrieve - "
+ "Mutex Unlock Error for channel %d\n",
+ channelId);
+ status = ICP_STATUS_MUTEX;
+ }
+ }
+
+ ICP_HSSACC_DP_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Exiting HssAccTxDatapathChannelBuffersRetrieve\n");
+ return status;
+}
+
+
diff --git a/Acceleration/library/icp_telephony/tdm_io_access/icp_hssacc_voice_bypass.c b/Acceleration/library/icp_telephony/tdm_io_access/icp_hssacc_voice_bypass.c
new file mode 100644
index 0000000..591b00b
--- /dev/null
+++ b/Acceleration/library/icp_telephony/tdm_io_access/icp_hssacc_voice_bypass.c
@@ -0,0 +1,776 @@
+/******************************************************************************
+ * @file icp_hssacc_timeslot_switching.c
+ *
+ * @description Contents of this file provide the implementation of all
+ * Timeslot switching functionality as described the icp_hssacc.h header file
+ *
+ * @ingroup icp_HssAcc
+ *
+ * @Revision 1.0
+ *
+ * @par
+ * This file is provided under a dual BSD/GPLv2 license. When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * The full GNU General Public License is included in this distribution
+ * in the file called LICENSE.GPL.
+ *
+ * Contact Information:
+ * Intel Corporation
+ *
+ * BSD LICENSE
+ *
+ * Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ *
+ *
+ *****************************************************************************/
+
+#include "IxOsal.h"
+
+#include "icp.h"
+#include "icp_hssacc.h"
+#include "icp_hssacc_trace.h"
+#include "icp_hssacc_common.h"
+#include "icp_hssacc_channel_config.h"
+#include "icp_hssacc_voice_bypass.h"
+#include "icp_hssacc_address_translate.h"
+#include "icp_hssacc_tx_datapath.h"
+
+
+
+/* Stats */
+typedef struct icp_hssacc_bypass_stats_s
+{
+ icp_hssacc_msg_with_resp_stats_t gctLoad;
+ icp_hssacc_msg_with_resp_stats_t gainCfg;
+ icp_hssacc_msg_with_resp_stats_t bypassEnable;
+ icp_hssacc_msg_with_resp_stats_t bypassDisable;
+} icp_hssacc_bypass_stats_t;
+
+
+
+/* Internal GCT info */
+typedef struct icp_hssacc_gct_internal_data_s
+{
+ icp_boolean_t configured;
+ unsigned numBypassUsing;
+} icp_hssacc_gct_internal_data_t;
+
+
+
+/* Internal Timeslot switch info */
+typedef struct icp_hssacc_bypass_internal_data_s
+{
+ icp_boolean_t enabled;
+ unsigned srcChannelId;
+ unsigned destChannelId;
+ unsigned portId;
+ unsigned gctId;
+} icp_hssacc_bypass_internal_data_t;
+
+TDM_PRIVATE icp_hssacc_gct_internal_data_t
+hssAccGctData[ICP_HSSACC_MAX_NUM_VOICE_BYPASS_GCTS];
+
+TDM_PRIVATE icp_hssacc_bypass_internal_data_t
+hssAccBypassData[ICP_HSSACC_MAX_NUM_VOICE_BYPASSES];
+
+TDM_PRIVATE icp_boolean_t channelSwitchModuleInitialised = ICP_FALSE;
+
+TDM_PRIVATE icp_hssacc_bypass_stats_t hssAccBypassStats;
+
+
+
+/******************************************************************************
+ * Abstract:
+ * Initialise the Voice bypass module
+ *
+ *****************************************************************************/
+void
+HssAccVoiceBypassInit(void)
+{
+ unsigned index = 0;
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Entering HssAccVoiceBypassInit\n");
+ if (ICP_TRUE == channelSwitchModuleInitialised)
+ {
+ ICP_HSSACC_REPORT_ERROR("HssAccVoiceBypassInit - module already "
+ "initialised\n");
+ }
+ else
+ {
+
+ for (;index < ICP_HSSACC_MAX_NUM_VOICE_BYPASS_GCTS; index ++)
+ {
+ hssAccGctData[index].configured = ICP_FALSE;
+ hssAccGctData[index].numBypassUsing = 0;
+ }
+
+ for (index = 0; index < ICP_HSSACC_MAX_NUM_VOICE_BYPASSES; index ++)
+ {
+ hssAccBypassData[index].enabled = ICP_FALSE;
+ hssAccBypassData[index].srcChannelId = ICP_HSSACC_MAX_NUM_CHANNELS;
+ hssAccBypassData[index].destChannelId = ICP_HSSACC_MAX_NUM_CHANNELS;
+ hssAccBypassData[index].portId = ICP_HSSACC_MAX_NUM_PORTS;
+ hssAccBypassData[index].gctId = ICP_HSSACC_MAX_NUM_VOICE_BYPASS_GCTS;
+ }
+
+ HssAccBypassStatsReset();
+
+ channelSwitchModuleInitialised = ICP_TRUE;
+ }
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Exiting HssAccVoiceBypassInit\n");
+
+}
+
+
+/******************************************************************************
+ * Abstract:
+ * Shutdown the Voice Bypass module.
+ *
+ *****************************************************************************/
+icp_status_t
+HssAccVoiceBypassShutdown(void)
+{
+ unsigned index = 0;
+ icp_status_t status = ICP_STATUS_SUCCESS;
+
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Entering HssAccVoiceBypassShutdown\n");
+ if (ICP_TRUE != channelSwitchModuleInitialised)
+ {
+ ICP_HSSACC_REPORT_ERROR("HssAccVoiceBypassShutdown - module has not "
+ "already been initialised\n");
+ status = ICP_STATUS_FAIL;
+ }
+
+ for (index = 0; index < ICP_HSSACC_MAX_NUM_VOICE_BYPASSES; index ++)
+ {
+ if (ICP_TRUE == hssAccBypassData[index].enabled)
+ {
+ ICP_HSSACC_REPORT_ERROR_1 ("HssAccVoiceBypassShutdown - "
+ "Bypass %u is still enabled, can't"
+ " shutdown\n",
+ index);
+ status = ICP_STATUS_RESOURCE;
+ }
+ }
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ for (index = 0;index < ICP_HSSACC_MAX_NUM_VOICE_BYPASS_GCTS; index ++)
+ {
+ hssAccGctData[index].configured = ICP_FALSE;
+ hssAccGctData[index].numBypassUsing = 0;
+ }
+ channelSwitchModuleInitialised = ICP_FALSE;
+ }
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Exiting HssAccVoiceBypassShutdown\n");
+ return status;
+}
+
+
+
+/******************************************************************************
+ * Abstract:
+ * Returns the number of supported Gain Control Tables.
+ *
+ *****************************************************************************/
+unsigned
+icp_HssAccNumSupportedGCTsGet ( void )
+{
+ return ICP_HSSACC_MAX_NUM_VOICE_BYPASS_GCTS;
+}
+
+
+/******************************************************************************
+ * Abstract:
+ * returns the number of Voice bypasses supported
+ *
+ *****************************************************************************/
+unsigned
+icp_HssAccNumSupportedVoiceBypassesGet ( void )
+{
+ return ICP_HSSACC_MAX_NUM_VOICE_BYPASSES;
+}
+
+/******************************************************************************
+ * Abstract:
+ * Download the provided Gain Control Table to the TDM I/O Unit.
+ *
+ *****************************************************************************/
+icp_status_t
+icp_HssAccVoiceBypassGctDownload (unsigned voiceBypassGct,
+ uint8_t *gainCtrlTable)
+{
+ icp_status_t status = ICP_STATUS_SUCCESS;
+ uint32_t physAddr = 0;
+ IxPiuMhMessage message;
+ icp_boolean_t mutexLocked = ICP_FALSE;
+ ICP_HSSACC_TRACE_1 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Entering icp_HssAccVoiceBypassGctDownload "
+ "for Table %u\n",
+ voiceBypassGct);
+
+ if (ICP_FALSE == channelSwitchModuleInitialised)
+ {
+ ICP_HSSACC_REPORT_ERROR ("icp_HssAccVoiceBypassGctDownload - "
+ "Service is not Initialised\n");
+ status = ICP_STATUS_FAIL;
+ }
+
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ if ((voiceBypassGct >= ICP_HSSACC_MAX_NUM_VOICE_BYPASS_GCTS)||
+ (NULL == gainCtrlTable))
+ {
+ ICP_HSSACC_REPORT_ERROR ("icp_HssAccVoiceBypassGctDownload - "
+ "invalid parameter\n");
+ status = ICP_STATUS_INVALID_PARAM;
+ }
+ else if (0 !=
+ ((uint32_t)gainCtrlTable & ICP_HSSACC_DBLE_WD_ALIGN_MASK))
+ {
+ ICP_HSSACC_REPORT_ERROR ("icp_HssAccVoiceBypassGctDownload - "
+ "invalid alignment for GCT memory "
+ "location\n");
+ status = ICP_STATUS_INVALID_PARAM;
+ }
+
+ }
+
+
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ /* Grab the HssAcc mutex */
+ if (ICP_STATUS_SUCCESS != ICP_HSSACC_MUTEX_LOCK())
+ {
+ ICP_HSSACC_REPORT_ERROR ("icp_HssAccVoiceBypassGctDownload - "
+ "failed to lock HssAcc Mutex\n");
+ status = ICP_STATUS_MUTEX;
+ }
+ else
+ {
+ mutexLocked = ICP_TRUE;
+ }
+ }
+
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ /* Check if this Gain Control table has already been configured
+ and if it is already in use for a bypass, we only allow configuration
+ of the GCT if it is not in use by any bypass */
+ if (0 != hssAccGctData[voiceBypassGct].numBypassUsing)
+ {
+ ICP_HSSACC_REPORT_ERROR ("icp_HssAccVoiceBypassGctDownload - "
+ "GCT is currently in use by 1 "
+ "or more bypasses\n");
+ status = ICP_STATUS_RESOURCE;
+ }
+ }
+
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ /* Send Configuration to TDM I/O Unit and save it in
+ Access for Stats purposes */
+
+
+ /* Convert the table base address to a physical address */
+ physAddr =
+ HssAccVirtToPhysAddressTranslate(gainCtrlTable);
+
+ /* Construct the message to load the table */
+ HssAccComTdmIOUnitCmd4byte1wordMsgCreate (
+ ICP_HSSACC_TDM_IO_UNIT_GCT_LOAD,
+ 0,
+ 0,
+ voiceBypassGct,
+ physAddr,
+ &message);
+ /* Send the message to the TDM I/O Unit and wait for its reply */
+ status =
+ HssAccComTdmIOUnitMsgSendAndRecv(
+ message,
+ ICP_HSSACC_TDM_IO_UNIT_GCT_LOAD_RESPONSE,
+ &(hssAccBypassStats.gctLoad),
+ NULL);
+
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ hssAccGctData[voiceBypassGct].configured = ICP_TRUE;
+ }
+ else
+ {
+ ICP_HSSACC_REPORT_ERROR("icp_HssAccVoiceBypassGctDownload - "
+ "failed to set Table in TDM I/O Unit\n");
+ }
+
+ }
+ /* Free the HssAcc mutex */
+ if (ICP_TRUE == mutexLocked)
+ {
+ if (ICP_STATUS_SUCCESS != ICP_HSSACC_MUTEX_UNLOCK())
+ {
+ ICP_HSSACC_REPORT_ERROR ("icp_HssAccVoiceBypassGctDownload - "
+ "failed to release HssAcc Mutex\n");
+ status = ICP_STATUS_MUTEX;
+ }
+ }
+
+
+
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Exiting icp_HssAccVoiceBypassGctDownload\n");
+ return status;
+}
+
+
+
+
+
+/******************************************************************************
+ * Abstract:
+ * Enable the specified Voice bypass between the specified source and
+ * destination channels.
+ *
+ *****************************************************************************/
+icp_status_t
+icp_HssAccVoiceBypassEnable (unsigned portId,
+ unsigned voiceBypassId,
+ unsigned voiceBypassGct,
+ unsigned srcChannelId,
+ unsigned destChannelId)
+{
+ icp_status_t status = ICP_STATUS_SUCCESS;
+ IxPiuMhMessage message;
+ icp_boolean_t mutexLocked = ICP_FALSE;
+ unsigned index = 0;
+ ICP_HSSACC_TRACE_2 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Entering icp_HssAccVoiceBypassEnable for Table %u "
+ "on bypass %u\n",
+ voiceBypassGct,
+ voiceBypassId);
+
+ if (ICP_FALSE == channelSwitchModuleInitialised)
+ {
+ ICP_HSSACC_REPORT_ERROR ("icp_HssAccVoiceBypassEnable - "
+ "Service is not Initialised\n");
+ status = ICP_STATUS_FAIL;
+ }
+
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ if ((portId >= ICP_HSSACC_MAX_NUM_PORTS) ||
+ (voiceBypassId >= ICP_HSSACC_MAX_NUM_VOICE_BYPASSES) ||
+ (voiceBypassGct >= ICP_HSSACC_MAX_NUM_VOICE_BYPASS_GCTS))
+ {
+ ICP_HSSACC_REPORT_ERROR ("icp_HssAccVoiceBypassEnable - invalid "
+ "Bypass configuration parameter\n");
+ status = ICP_STATUS_INVALID_PARAM;
+ }
+ }
+
+
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ if ((ICP_HSSACC_MAX_NUM_CHANNELS <= srcChannelId) ||
+ (ICP_HSSACC_MAX_NUM_CHANNELS <= destChannelId))
+ {
+ ICP_HSSACC_REPORT_ERROR ("icp_HssAccVoiceBypassEnable - Channels "
+ "selected for bypass are invalid\n");
+ status = ICP_STATUS_INVALID_PARAM;
+ }
+ }
+
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ /* Grab the HssAcc mutex */
+ if (ICP_STATUS_SUCCESS != ICP_HSSACC_MUTEX_LOCK())
+ {
+ ICP_HSSACC_REPORT_ERROR ("icp_HssAccVoiceBypassEnable - "
+ "failed to lock HssAcc Mutex\n");
+
+ status = ICP_STATUS_MUTEX;
+ }
+ }
+
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ mutexLocked = ICP_TRUE;
+
+ if (ICP_TRUE == hssAccBypassData[voiceBypassId].enabled)
+ {
+ ICP_HSSACC_REPORT_ERROR_1 ("icp_HssAccVoiceBypassEnable - Selected "
+ "bypass (%u) is already enabled; it must "
+ "be disabled first before "
+ "reconfiguring\n",
+ voiceBypassId);
+ status = ICP_STATUS_RESOURCE;
+ }
+ }
+
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ if (ICP_TRUE != hssAccGctData[voiceBypassGct].configured)
+ {
+ ICP_HSSACC_REPORT_ERROR_1 ("icp_HssAccVoiceBypassEnable - Selected "
+ "Gain Control Table (%u) is not "
+ "configured, need to configure it first\n",
+ voiceBypassGct);
+ status = ICP_STATUS_RESOURCE;
+ }
+ }
+
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ for (index = 0; index < ICP_HSSACC_MAX_NUM_VOICE_BYPASSES; index ++)
+ {
+ if ((hssAccBypassData[index].srcChannelId == srcChannelId) ||
+ (hssAccBypassData[index].destChannelId == destChannelId))
+ {
+ ICP_HSSACC_REPORT_ERROR_1("icp_HssAccVoiceBypassEnable - "
+ "One of the channels selected is "
+ "already used in a identical role "
+ "for bypass %u\n",
+ index);
+ status = ICP_STATUS_RESOURCE;
+ break;
+ }
+ }
+ }
+
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ if ( (ICP_FALSE == HssAccChannelConfigValidBypass(srcChannelId,portId)) ||
+ (ICP_FALSE == HssAccChannelConfigValidBypass(destChannelId,portId)))
+ {
+ ICP_HSSACC_REPORT_ERROR ("icp_HssAccVoiceBypassEnable - Channel(s) "
+ "selected for bypass is(are) not "
+ "appropriate (Narrowband Enabled Channels "
+ "only on same port)\n");
+ status = ICP_STATUS_RESOURCE;
+ }
+ }
+
+
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ /* Link the Bypass to the Gain Control Table */
+
+ HssAccComTdmIOUnitCmd4byte1wordMsgCreate (
+ ICP_HSSACC_TDM_IO_UNIT_BYPASS_GAIN_CFG,
+ portId,
+ voiceBypassId,
+ voiceBypassGct,
+ 0,
+ &message);
+
+
+ status =
+ HssAccComTdmIOUnitMsgSendAndRecv(
+ message,
+ ICP_HSSACC_TDM_IO_UNIT_BYPASS_GAIN_CFG_RESPONSE,
+ &(hssAccBypassStats.gainCfg),
+ NULL);
+ if (ICP_STATUS_SUCCESS != status)
+ {
+ ICP_HSSACC_REPORT_ERROR_2("icp_HssAccVoiceBypassEnable - "
+ "Failed to link GCT %u with Voice "
+ "Bypass %u on the TDM I/O Unit\n",
+ voiceBypassGct,
+ voiceBypassId);
+ }
+
+
+
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ /* Configure the Bypass*/
+
+ HssAccComTdmIOUnitCmd8byteMsgCreate (
+ ICP_HSSACC_TDM_IO_UNIT_BYPASS_ENABLE,
+ portId,
+ voiceBypassId,
+ srcChannelId,
+ destChannelId,
+ 0, 0, 0,
+ &message);
+
+
+ status =
+ HssAccComTdmIOUnitMsgSendAndRecv(
+ message,
+ ICP_HSSACC_TDM_IO_UNIT_BYPASS_ENABLE_RESPONSE,
+ &(hssAccBypassStats.bypassEnable),
+ NULL);
+
+ if (ICP_STATUS_SUCCESS != status)
+ {
+ ICP_HSSACC_REPORT_ERROR_1("icp_HssAccVoiceBypassEnable - "
+ "Failed to enable Voice "
+ "Bypass %u on the TDM I/O Unit\n",
+ voiceBypassId);
+ }
+
+ }
+
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ /* Save bypass config and send new channel state to tx */
+ hssAccBypassData[voiceBypassId].enabled = ICP_TRUE;
+ hssAccBypassData[voiceBypassId].portId = portId;
+ hssAccBypassData[voiceBypassId].srcChannelId = srcChannelId;
+ hssAccBypassData[voiceBypassId].destChannelId = destChannelId;
+ hssAccBypassData[voiceBypassId].gctId = voiceBypassGct;
+ hssAccGctData[voiceBypassGct].numBypassUsing ++;
+
+ /* Notify the Tx Datapath and config modules that this channel is
+ bypassed */
+ HssAccTxDatapathChanBypassStateSet(destChannelId,
+ ICP_TRUE);
+ HssAccChannelBypassPairSet(srcChannelId, destChannelId);
+ }
+ }
+
+
+
+ /* Free the HssAcc mutex */
+ if (ICP_TRUE == mutexLocked)
+ {
+ if (ICP_STATUS_SUCCESS != ICP_HSSACC_MUTEX_UNLOCK())
+ {
+ ICP_HSSACC_REPORT_ERROR ("icp_HssAccVoiceBypassEnable - "
+ "failed to release HssAcc Mutex\n");
+ status = ICP_STATUS_MUTEX;
+ }
+ }
+
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Exiting icp_HssAccVoiceBypassEnable\n");
+ return status;
+}
+
+
+
+
+/******************************************************************************
+ * Abstract:
+ * disable the specified Voice bypass.
+ *
+ *****************************************************************************/
+icp_status_t
+icp_HssAccVoiceBypassDisable (unsigned voiceBypassId)
+{
+ icp_status_t status = ICP_STATUS_SUCCESS;
+ IxPiuMhMessage message;
+ icp_boolean_t mutexLocked = ICP_FALSE;
+ unsigned gctId = ICP_HSSACC_MAX_NUM_VOICE_BYPASS_GCTS;
+ ICP_HSSACC_TRACE_1 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Entering icp_HssAccVoiceBypassDisable for Bypass %u\n",
+ voiceBypassId);
+
+ if (ICP_FALSE == channelSwitchModuleInitialised)
+ {
+ ICP_HSSACC_REPORT_ERROR ("icp_HssAccVoiceBypassDisable - "
+ "Service is not Initialised\n");
+ status = ICP_STATUS_FAIL;
+ }
+
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ if (voiceBypassId >= ICP_HSSACC_MAX_NUM_VOICE_BYPASSES)
+ {
+ ICP_HSSACC_REPORT_ERROR ("icp_HssAccVoiceBypassDisable - invalid "
+ "Bypass ID\n");
+ status = ICP_STATUS_INVALID_PARAM;
+ }
+ }
+
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ /* Grab the HssAcc mutex */
+ if (ICP_STATUS_SUCCESS != ICP_HSSACC_MUTEX_LOCK())
+ {
+ ICP_HSSACC_REPORT_ERROR ("icp_HssAccVoiceBypassDisable - "
+ "failed to lock HssAcc Mutex\n");
+
+ status = ICP_STATUS_MUTEX;
+ }
+ }
+
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ mutexLocked = ICP_TRUE;
+
+ if (ICP_TRUE != hssAccBypassData[voiceBypassId].enabled)
+ {
+ ICP_HSSACC_REPORT_ERROR_1 ("icp_HssAccVoiceBypassDisable - Selected "
+ "bypass (%u) is not enabled\n",
+ voiceBypassId);
+ status = ICP_STATUS_RESOURCE;
+ }
+ }
+
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ /* Configure the Bypass*/
+
+ HssAccComTdmIOUnitCmd8byteMsgCreate (
+ ICP_HSSACC_TDM_IO_UNIT_BYPASS_DISABLE,
+ hssAccBypassData[voiceBypassId].portId,
+ voiceBypassId,
+ 0,
+ 0, 0, 0, 0,
+ &message);
+
+
+ status =
+ HssAccComTdmIOUnitMsgSendAndRecv(
+ message,
+ ICP_HSSACC_TDM_IO_UNIT_BYPASS_DISABLE_RESPONSE,
+ &(hssAccBypassStats.bypassDisable),
+ NULL);
+ if (ICP_STATUS_SUCCESS != status)
+ {
+ ICP_HSSACC_REPORT_ERROR_1("icp_HssAccVoiceBypassDisable - "
+ "Failed to disable Voice "
+ "Bypass %u on the TDM I/O Unit\n",
+ voiceBypassId);
+ }
+
+
+ }
+
+ if (ICP_STATUS_SUCCESS == status)
+ {
+ /* Save bypass config and send new channel state to tx */
+ hssAccBypassData[voiceBypassId].enabled = ICP_FALSE;
+ gctId = hssAccBypassData[voiceBypassId].gctId;
+ hssAccBypassData[voiceBypassId].portId = ICP_HSSACC_MAX_NUM_PORTS;
+ hssAccBypassData[voiceBypassId].gctId =
+ ICP_HSSACC_MAX_NUM_VOICE_BYPASS_GCTS;
+ hssAccGctData[gctId].numBypassUsing --;
+
+ /* Notify the Tx Datapath module that this channel is
+ no longer bypassed */
+ HssAccTxDatapathChanBypassStateSet(
+ hssAccBypassData[voiceBypassId].destChannelId,
+ ICP_FALSE);
+
+ HssAccChannelBypassPairClear(
+ hssAccBypassData[voiceBypassId].srcChannelId,
+ hssAccBypassData[voiceBypassId].destChannelId);
+
+ hssAccBypassData[voiceBypassId].srcChannelId =
+ ICP_HSSACC_MAX_NUM_CHANNELS;
+ hssAccBypassData[voiceBypassId].destChannelId =
+ ICP_HSSACC_MAX_NUM_CHANNELS;
+ }
+
+ /* Free the HssAcc mutex */
+ if (ICP_TRUE == mutexLocked)
+ {
+ if (ICP_STATUS_SUCCESS != ICP_HSSACC_MUTEX_UNLOCK())
+ {
+ ICP_HSSACC_REPORT_ERROR ("icp_HssAccVoiceBypassDisable - "
+ "failed to release HssAcc Mutex\n");
+ status = ICP_STATUS_MUTEX;
+ }
+ }
+
+
+
+ ICP_HSSACC_TRACE_0 (ICP_HSSACC_FN_ENTRY_EXIT,
+ "Exiting icp_HssAccVoiceBypassDisable\n");
+ return status;
+}
+
+
+
+/******************************************************************************
+ * Abstract:
+ * Display the stats collected by this sub-module.
+ *
+ *
+ *****************************************************************************/
+void
+HssAccBypassStatsShow (void)
+{
+
+ ixOsalLog(IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT,
+ "\nVoice Channel Bypass Configuration:\n"
+ "Gain Control Table Loading\n",
+ 0, 0, 0, 0, 0, 0);
+ HssAccSingleMessageStatsShow (hssAccBypassStats.gctLoad);
+ ixOsalLog(IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT,
+ "\nBypass Gain Control Config messaging\n",
+ 0, 0, 0, 0, 0, 0);
+ HssAccSingleMessageStatsShow (hssAccBypassStats.gainCfg);
+ ixOsalLog(IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT,
+ "\nBypass Enable messaging\n",
+ 0, 0, 0, 0, 0, 0);
+ HssAccSingleMessageStatsShow (hssAccBypassStats.bypassEnable);
+ ixOsalLog(IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT,
+ "\nBypass Disable messaging\n",
+ 0, 0, 0, 0, 0, 0);
+ HssAccSingleMessageStatsShow (hssAccBypassStats.bypassDisable);
+
+}
+
+/******************************************************************************
+ * Abstract:
+ * Reset the stats collected by this sub-module.
+ *
+ *****************************************************************************/
+void
+HssAccBypassStatsReset (void)
+{
+ memset (&hssAccBypassStats,
+ 0,
+ sizeof(icp_hssacc_bypass_stats_t));
+}
diff --git a/Acceleration/library/icp_telephony/tdm_io_access/include/icp_hssacc_address_translate.h b/Acceleration/library/icp_telephony/tdm_io_access/include/icp_hssacc_address_translate.h
new file mode 100644
index 0000000..df0475d
--- /dev/null
+++ b/Acceleration/library/icp_telephony/tdm_io_access/include/icp_hssacc_address_translate.h
@@ -0,0 +1,142 @@
+/******************************************************************************
+ * @file icp_hssacc_address_translate.h
+ *
+ * @description Content of this file provides the prototypes for address
+ * translation functionality
+ *
+ * @ingroup icp_HssAcc
+ *
+ * @Revision 1.0
+ *
+ * @par
+ * This file is provided under a dual BSD/GPLv2 license. When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * The full GNU General Public License is included in this distribution
+ * in the file called LICENSE.GPL.
+ *
+ * Contact Information:
+ * Intel Corporation
+ *
+ * BSD LICENSE
+ *
+ * Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ *
+ *
+ *****************************************************************************/
+#ifndef ICP_HSSACC_ADDRESS_TRANSLATE_H
+#define ICP_HSSACC_ADDRESS_TRANSLATE_H
+
+#include "icp.h"
+
+
+/*****************************************************************************
+ * Abstract:
+ * Translate a Virtual address to a physical offset, includes Endianness
+ * Swapping if necessary.
+ *
+ *****************************************************************************/
+uint32_t
+HssAccVirtToPhysAddressTranslateAndSwap(void* virtAddr);
+
+
+
+/*****************************************************************************
+ * Abstract:
+ * Translate a physical offset to a virtual address includes endianness
+ * swapping and platform specific bit manipulation where required.
+ *
+ *****************************************************************************/
+void *
+HssAccPhysToVirtAddressSwapAndTranslate(uint32_t physAddr);
+
+
+/*****************************************************************************
+ * Abstract:
+ * Translate a Virtual address to a physical offset.
+ *
+ *****************************************************************************/
+uint32_t
+HssAccVirtToPhysAddressTranslate(void * const virtAddr);
+
+
+
+/*****************************************************************************
+ * Abstract:
+ * Translate a physical offset to a virtual address.
+ *
+ *****************************************************************************/
+void *
+HssAccPhysToVirtAddressTranslate(const uint32_t physAddr);
+
+
+
+/*****************************************************************************
+ * Abstract:
+ * Allocate a chunk of memory for DMA communication with the TDM I/O Unit.
+ * returns the virtual address and the physical offset as an out parameter.
+ * virtual Address will be NULL if allocation failed and physAddr will be
+ * left un-touched.
+ *
+ *****************************************************************************/
+void *
+HssAccDmaMemAllocate(uint32_t sizeBytes,
+ uint32_t * physAddr);
+
+
+
+
+/*****************************************************************************
+ * Abstract:
+ * Swap Endianness on the data of an OSAL Buffer
+ *
+ *****************************************************************************/
+void
+HssAccDataEndiannessSwap(IX_OSAL_MBUF * const buffer);
+
+#endif /* ICP_HSSACC_ADDRESS_TRANSLATE_H */
diff --git a/Acceleration/library/icp_telephony/tdm_io_access/include/icp_hssacc_channel_config.h b/Acceleration/library/icp_telephony/tdm_io_access/include/icp_hssacc_channel_config.h
new file mode 100644
index 0000000..c355b94
--- /dev/null
+++ b/Acceleration/library/icp_telephony/tdm_io_access/include/icp_hssacc_channel_config.h
@@ -0,0 +1,269 @@
+/*******************************************************************************
+ *
+ * @file icp_hssacc_channel_config.h
+ *
+ * @description Content of this file is the Prototype definition of the API for
+ * the Channel Configuration module and all related Data structures shared
+ * by this module.
+ *
+ * @ingroup icp_HssAcc
+ *
+ * @Revision 1.0
+ *
+ * @par
+ * This file is provided under a dual BSD/GPLv2 license. When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * The full GNU General Public License is included in this distribution
+ * in the file called LICENSE.GPL.
+ *
+ * Contact Information:
+ * Intel Corporation
+ *
+ * BSD LICENSE
+ *
+ * Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ *
+ *
+ ******************************************************************************/
+
+
+#ifndef ICP_HSSACCCHANNELCONFIG_H
+#define ICP_HSSACCCHANNELCONFIG_H
+
+#include "icp.h"
+#include "icp_hssacc.h"
+#include "icp_hssacc_port_config.h"
+
+
+#define BIT_SET(index) (1 << index)
+
+
+/*
+ * ----------------------------------------------------------------------------
+ * Enumerated types
+ * ----------------------------------------------------------------------------
+ */
+
+/* Enum for the various states a channel can be in */
+typedef enum
+{
+ ICP_HSSACC_CHANNEL_UNINITIALISED = 0,
+ ICP_HSSACC_CHANNEL_ALLOCATED,
+ ICP_HSSACC_CHANNEL_CONFIGURED,
+ ICP_HSSACC_CHANNEL_SERVICE_CONFIGURED,
+ ICP_HSSACC_CHANNEL_DOWN,
+ ICP_HSSACC_CHANNEL_ENABLED,
+ ICP_HSSACC_CHANNEL_DOWN_TRANSITION
+} icp_hssacc_channel_state_t;
+
+
+
+/*
+ Definition of the structure containing all Channel
+ configuration Data
+*/
+typedef struct icp_hssacc_channel_config_s
+{
+ icp_hssacc_channel_state_t state; /* Current state of the channel */
+ icp_hssacc_channel_type_t type; /* Voice or data */
+ unsigned size; /* Size of the channel in timeslots */
+ unsigned portId; /* HSS port number for the channel */
+ icp_hssacc_line_t lineId; /* TDM line number for the channel */
+ uint32_t timeslotMap; /* Timeslots reserved for the channel */
+ uint32_t sdcCtrlReg; /* Common channel settings */
+ uint32_t rxCfg; /* HDLC Rx settings */
+ uint32_t txCfg; /* HDLC Tx settings */
+ icp_boolean_t dataPolarity; /* polarity of the data */
+ icp_hssacc_bit_endian_t bitEndian; /* specifies endianness of the chan */
+ icp_boolean_t byteSwap; /* byteSwapping on/off */
+ icp_hssacc_robbed_bit_value_t rBitValue; /* value 0/1 of robbed bit */
+ icp_hssacc_robbed_bit_location_t rBitLocation;
+ /* location of the robbed bit in the byte */
+ icp_hssacc_bit_robbing_t bitRobbing; /* bit robbing used or not */
+
+ /* HDLC specific */
+ icp_hssacc_hdlc_sof_flag_type_t sofFlagType; /* start of frame */
+ icp_hssacc_hdlc_idle_pattern_t hdlcTxIdlePattern; /* idle pattern to Tx */
+ icp_hssacc_hdlc_idle_pattern_t hdlcRxIdlePattern; /* expected idle on rx */
+ icp_hssacc_hdlc_crc_bit_width_t hdlcCrcBitWidth; /* CRC size */
+ uint32_t hdlcMaxFrSize; /* maximum frame size on rx */
+
+ /* VOICE specific */
+ uint32_t voiceSampleSize; /* size of voice samples */
+ uint8_t voiceIdlePattern; /* voice silence pattern */
+ icp_hssacc_channel_voice_tx_idle_action_t txIdleAction;
+ /* tx silence or repeat last frame */
+
+ unsigned numBypasses; /* channel can be involved in up to 2 bypasses,
+ one as source, one as destination */
+} icp_hssacc_channel_config_t;
+
+/* ----------------------------------------------------------------------------
+ * Function declarations
+ * ----------------------------------------------------------------------------
+ */
+/*****************************************************************************
+ * Abstract:
+ * Initialise the Channel Configuration module
+ *
+ *****************************************************************************/
+icp_status_t
+HssAccChannelConfigInit(void);
+
+
+/*****************************************************************************
+ * Abstract:
+ * shutdown the Channel Configuration module
+ *
+ *****************************************************************************/
+icp_status_t
+HssAccChannelConfigShutdown(void);
+
+
+
+/*****************************************************************************
+ * Abstract:
+ * Reset the internal stats gathered by this module
+ *
+ *****************************************************************************/
+void
+HssAccChannelConfigStatsReset (void);
+
+
+
+/*****************************************************************************
+ * Abstract:
+ * display all stats gathered by this module.
+ *
+ *****************************************************************************/
+void
+HssAccChannelConfigStatsShow (void);
+
+
+
+/*****************************************************************************
+ * Abstract:
+ * display the state of the specified channel
+ *
+ *****************************************************************************/
+void
+HssAccChannelConfigStateShow (unsigned channelId);
+
+
+/*****************************************************************************
+ * Abstract:
+ * check whether it is valid to configure a bypass on the specified
+ * channel.
+ *
+ *****************************************************************************/
+icp_boolean_t
+HssAccChannelConfigValidBypass(const unsigned channelId,
+ const unsigned portId);
+
+
+/*****************************************************************************
+ * Abstract:
+ * set the 2 specified channels as part of a bypass
+ *
+ *****************************************************************************/
+void
+HssAccChannelBypassPairSet(unsigned srcChannelId,
+ unsigned destChannelId);
+
+
+/*****************************************************************************
+ * Abstract:
+ * clear the 2 specified channels from any bypass connection
+ *
+ *****************************************************************************/
+void
+HssAccChannelBypassPairClear(unsigned srcChannelId,
+ unsigned destChannelId);
+
+
+/*****************************************************************************
+ * Abstract:
+ * query the service to which the specified channel is associated, Voice
+ * or HDLC.
+ *
+ *****************************************************************************/
+icp_hssacc_channel_type_t
+HssAccChannelConfigTypeQuery (unsigned channelId);
+
+
+
+/*****************************************************************************
+ * Abstract:
+ * query the current state of the specified channel.
+ *
+ *****************************************************************************/
+icp_hssacc_channel_state_t
+HssAccChannelConfigStateQuery (unsigned channelId);
+
+
+
+/*****************************************************************************
+ * Abstract:
+ * notify the Channel Configuration module that all buffers associated
+ * with this channel have been retrieved.
+ *
+ *****************************************************************************/
+void
+HssAccChannelConfigBuffersClearedNotify (unsigned channelId);
+
+
+
+/*****************************************************************************
+ * Abstract:
+ * query whether there are any channels allocated on the specified port.
+ *
+ *****************************************************************************/
+icp_boolean_t
+HssAccChannelConfigUsedChansOnPortFind (const unsigned portId);
+#endif /* ICP_HSSACCCHANNELCONFIG_H */
diff --git a/Acceleration/library/icp_telephony/tdm_io_access/include/icp_hssacc_channel_list.h b/Acceleration/library/icp_telephony/tdm_io_access/include/icp_hssacc_channel_list.h
new file mode 100644
index 0000000..df939fc
--- /dev/null
+++ b/Acceleration/library/icp_telephony/tdm_io_access/include/icp_hssacc_channel_list.h
@@ -0,0 +1,137 @@
+/******************************************************************************
+ * @file icp_hssacc_channel_list.h
+ *
+ * @description Content of this file includes the prototypes for channel
+ * list manipulations
+ *
+ * @ingroup icp_HssAcc
+ *
+ * @revision 1.0
+ *
+ * @par
+ * This file is provided under a dual BSD/GPLv2 license. When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * The full GNU General Public License is included in this distribution
+ * in the file called LICENSE.GPL.
+ *
+ * Contact Information:
+ * Intel Corporation
+ *
+ * BSD LICENSE
+ *
+ * Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ *
+ *
+ *****************************************************************************/
+#ifndef ICP_HSSACC_CHANNEL_LIST_H
+#define ICP_HSSACC_CHANNEL_LIST_H
+
+
+#include "icp.h"
+
+/*****************************************************************************
+ * Abstract
+ * Reset All the channels lists
+ *
+ *****************************************************************************/
+void HssAccChannelListsReset (void);
+
+
+/*****************************************************************************
+ * Abstract
+ * Add a channel to one of the lists for processing.
+ *
+ *****************************************************************************/
+icp_status_t HssAccChannelListAdd (unsigned hssPortId,
+ unsigned chanId,
+ unsigned chanSize);
+
+
+
+
+/*****************************************************************************
+ * Abstract
+ * Remove the specified channel from processing lists.
+ *
+ *****************************************************************************/
+icp_status_t HssAccChannelListRemove (unsigned hssPortId,
+ unsigned chanId,
+ unsigned chanSize);
+
+
+/*****************************************************************************
+ * Abstract
+ * Retrieve the ID of the last channel being processed on a specific port
+ * and a specific list
+ *
+ *****************************************************************************/
+unsigned
+HssAccChannelListLastPortChannelGet (unsigned portId,
+ icp_hssacc_channel_list_t listId);
+
+/*****************************************************************************
+ * Abstract
+ * Retrieve the prev channel to processed in the list this channel
+ * belongs to.
+ *
+ *****************************************************************************/
+unsigned
+HssAccChannelListPrevChannelOnListGet(unsigned channelId);
+
+
+/*****************************************************************************
+ * Abstract
+ * Reset the messaging stats for Channel List management.
+ *
+ *****************************************************************************/
+void
+HssAccChannelListsStatsReset (void);
+
+
+#endif
diff --git a/Acceleration/library/icp_telephony/tdm_io_access/include/icp_hssacc_common.h b/Acceleration/library/icp_telephony/tdm_io_access/include/icp_hssacc_common.h
new file mode 100644
index 0000000..c839e53
--- /dev/null
+++ b/Acceleration/library/icp_telephony/tdm_io_access/include/icp_hssacc_common.h
@@ -0,0 +1,978 @@
+/******************************************************************************
+ * @file icp_hssacc_common.h
+ *
+ * @description this file contains value definitions and function prototypes
+ * that are common accross all the HSS Access component
+ *
+ * @revision 1.0
+ *
+ * @par
+ * This file is provided under a dual BSD/GPLv2 license. When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved.
+ * Copyright(c) 2010,2011,2012 Avencall
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * The full GNU General Public License is included in this distribution
+ * in the file called LICENSE.GPL.
+ *
+ * BSD LICENSE
+ *
+ * Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ * Copyright(c) 2010,2011,2012 Avencall
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ *
+ *****************************************************************************/
+
+
+#ifndef ICP_HSSACCCOMMON_H
+#define ICP_HSSACCCOMMON_H
+
+#include "IxOsal.h"
+#include "icp.h"
+#include "IxPiuMh.h"
+#include "IxPiuDl.h"
+#include "icp_hssacc.h"
+
+
+#if !defined(TDM_PRIVATE)
+#define TDM_PRIVATE static
+#else
+#define TDM_PRIVATE
+#endif
+#ifdef IXP23XX
+#define ICP_HSSACC_MAX_NUM_CHANNELS (128)
+#endif
+#ifdef TOLAPAI
+#define ICP_HSSACC_MAX_NUM_CHANNELS (128)
+#endif
+
+
+/*
+ * This macro represents an invalid Channel
+ */
+#define ICP_HSSACC_INVALID_CHAN ICP_HSSACC_MAX_NUM_CHANNELS
+
+
+
+#ifdef TOLAPAI
+#define ICP_HSSACC_MAX_NUM_PORTS 3
+#else
+#ifdef IXP23XX
+#define ICP_HSSACC_MAX_NUM_PORTS 4
+#endif
+#endif
+
+#define ICP_HSSACC_MAX_NUM_VOICE_BYPASS_GCTS 4
+
+#define ICP_HSSACC_MAX_NUM_VOICE_BYPASSES 4
+
+/* ----------------------------------------------------------------------------
+ * Externs
+ * ----------------------------------------------------------------------------
+ */
+/* Mutex which controls access to control path functions */
+extern IxOsalMutex hssAccControlPathMutex;
+
+
+/* ----------------------------------------------------------------------------
+ * Defines and Macros.
+ * ----------------------------------------------------------------------------
+ */
+/*
+ * Timeout value in ms
+ */
+#define ICP_HSSACC_MUTEX_TIMEOUT 10
+
+/*
+ * Initialises the service mutex.
+ */
+#define ICP_HSSACC_MUTEX_INIT() (ixOsalMutexInit(&hssAccControlPathMutex))
+
+/*
+ * Locks the service mutex.
+ */
+#define ICP_HSSACC_MUTEX_LOCK() (ixOsalMutexLock( \
+ &hssAccControlPathMutex,\
+ ICP_HSSACC_MUTEX_TIMEOUT))
+
+/*
+ * Unlocks the service mutex.
+ */
+#define ICP_HSSACC_MUTEX_UNLOCK() (ixOsalMutexUnlock(&hssAccControlPathMutex))
+
+/*
+ * Destroys the service mutex.
+ */
+#define ICP_HSSACC_MUTEX_DESTROY() (\
+ ixOsalMutexDestroy(&hssAccControlPathMutex))
+
+/*
+ * The bit offset for byte 0 in a TDM I/O Unit message
+ */
+#define ICP_HSSACC_TDM_IO_UNIT_BYTE0_OFFSET (24)
+
+/*
+ * The byte mask for byte 0 in a TDM I/O Unit message
+ */
+#define ICP_HSSACC_TDM_IO_UNIT_BYTE0_MASK (0xFF << \
+ ICP_HSSACC_TDM_IO_UNIT_BYTE0_OFFSET)
+
+/*
+ * The bit offset for byte 1 in a TDM I/O Unit message
+ */
+#define ICP_HSSACC_TDM_IO_UNIT_BYTE1_OFFSET (16)
+
+/*
+ * The byte mask for byte 1 in a TDM I/O Unit message
+ */
+#define ICP_HSSACC_TDM_IO_UNIT_BYTE1_MASK (0xFF << \
+ ICP_HSSACC_TDM_IO_UNIT_BYTE1_OFFSET)
+
+/*
+ * The bit offset for byte 2 in a TDM I/O Unit message
+ */
+#define ICP_HSSACC_TDM_IO_UNIT_BYTE2_OFFSET (8)
+
+/*
+ * The byte mask for byte 2 in a TDM I/O Unit message
+ */
+#define ICP_HSSACC_TDM_IO_UNIT_BYTE2_MASK (0xFF << \
+ ICP_HSSACC_TDM_IO_UNIT_BYTE2_OFFSET)
+
+/*
+ * The bit offset for byte 3 in a TDM I/O Unit message
+ */
+#define ICP_HSSACC_TDM_IO_UNIT_BYTE3_OFFSET (0)
+
+/*
+ * The byte mask for byte 3 in a TDM I/O Unit message
+ */
+#define ICP_HSSACC_TDM_IO_UNIT_BYTE3_MASK (0xFF << \
+ ICP_HSSACC_TDM_IO_UNIT_BYTE3_OFFSET)
+
+
+
+/*
+ * The byte offset for Short 0 in a TDM I/O Unit message
+ */
+#define ICP_HSSACC_TDM_IO_UNIT_SHORT0_OFFSET (16)
+
+/*
+ * The byte mask for short 0 in a TDM I/O Unit message
+ */
+#define ICP_HSSACC_TDM_IO_UNIT_SHORT0_MASK (0xFFFF << \
+ ICP_HSSACC_TDM_IO_UNIT_SHORT0_OFFSET)
+
+/*
+ * The byte offset for Short 1 in a TDM I/O Unit message
+ */
+#define ICP_HSSACC_TDM_IO_UNIT_SHORT1_OFFSET 0
+
+/*
+ * The byte mask for Short 1 in a TDM I/O Unit message
+ */
+#define ICP_HSSACC_TDM_IO_UNIT_SHORT1_MASK (0xFFFF << \
+ ICP_HSSACC_TDM_IO_UNIT_SHORT1_OFFSET)
+
+
+/*
+ * The size of a word in bytes
+ */
+#define ICP_HSSACC_WORD_SIZE 4
+
+
+/* Mask to determine whether an address is aligned on a double
+ word boundary or not */
+#define ICP_HSSACC_DBLE_WD_ALIGN_MASK 0x7
+
+
+/*
+ * Mechanism to validate the upper (MAX) and lower (0) bounds
+ * of a positive enumeration
+ *
+ * param int [in] VALUE - the integer value to test
+ * param int [in] MAX - the maximum value to test against
+ *
+ * This macro returns TRUE if the bounds are invalid and FALSE if
+ * they are okay. NOTE: MAX will be an invalid value, so check >=
+ *
+ */
+#define ICP_HSSACC_ENUM_INVALID(VALUE, MAX) ((((VALUE) < 0) || \
+ ((VALUE) >= (MAX))) ? \
+ TRUE : FALSE)
+
+
+/*
+ * TDM I/O Unit message commands
+ */
+/*
+ * HDMA configuration commands
+ */
+
+/*
+ * Port configuration commands
+ */
+#define ICP_HSSACC_TDM_IO_UNIT_PORT_CFG_TABLE_LOAD (0x20)
+#define ICP_HSSACC_TDM_IO_UNIT_PORT_CFG_TABLE_LOAD_RESPONSE \
+ ICP_HSSACC_TDM_IO_UNIT_PORT_CFG_TABLE_LOAD
+#define ICP_HSSACC_TDM_IO_UNIT_PORT_ENABLE (0x21)
+#define ICP_HSSACC_TDM_IO_UNIT_PORT_ENABLE_RESPONSE \
+ ICP_HSSACC_TDM_IO_UNIT_PORT_ENABLE
+#define ICP_HSSACC_TDM_IO_UNIT_PORT_DISABLE (0x22)
+#define ICP_HSSACC_TDM_IO_UNIT_PORT_DISABLE_RESPONSE \
+ ICP_HSSACC_TDM_IO_UNIT_PORT_DISABLE
+#define ICP_HSSACC_TDM_IO_UNIT_PORT_PROV_TABLE_LOAD (0x23)
+#define ICP_HSSACC_TDM_IO_UNIT_PORT_PROV_TABLE_LOAD_RESPONSE \
+ ICP_HSSACC_TDM_IO_UNIT_PORT_PROV_TABLE_LOAD
+#define ICP_HSSACC_TDM_IO_UNIT_PORT_PROV_TABLE_SWAP (0x24)
+#define ICP_HSSACC_TDM_IO_UNIT_PORT_PROV_TABLE_SWAP_DONE \
+ ICP_HSSACC_TDM_IO_UNIT_PORT_PROV_TABLE_SWAP
+#define ICP_HSSACC_TDM_IO_UNIT_PORT_ERROR_READ (0x25)
+#define ICP_HSSACC_TDM_IO_UNIT_PORT_ERROR_READ_RESPONSE \
+ ICP_HSSACC_TDM_IO_UNIT_PORT_ERROR_READ
+#define ICP_HSSACC_TDM_IO_UNIT_PORT_CFG_TABLE_READ (0x26)
+#define ICP_HSSACC_TDM_IO_UNIT_PORT_CFG_TABLE_READ_RESPONSE \
+ ICP_HSSACC_TDM_IO_UNIT_PORT_CFG_TABLE_READ
+#ifdef IXP23XX
+#define ICP_HSSACC_TDM_IO_UNIT_PORT_TS_REMAP_TABLE_LOAD (0x27)
+#define ICP_HSSACC_TDM_IO_UNIT_PORT_TS_REMAP_TABLE_LOAD_RESPONSE \
+ ICP_HSSACC_TDM_IO_UNIT_PORT_TS_REMAP_TABLE_LOAD
+#define ICP_HSSACC_TDM_IO_UNIT_PORT_TS_REMAP_TABLE_READ (0x28)
+#define ICP_HSSACC_TDM_IO_UNIT_PORT_TS_REMAP_TABLE_READ_RESPONSE \
+ ICP_HSSACC_TDM_IO_UNIT_PORT_TS_REMAP_TABLE_READ
+#endif
+
+/*
+ * Queue configuration commands
+ */
+#define ICP_HSSACC_TDM_IO_UNIT_HSS_PORT_CFG (0x40)
+#define ICP_HSSACC_TDM_IO_UNIT_HSS_PORT_CFG_RESPONSE \
+ ICP_HSSACC_TDM_IO_UNIT_HSS_PORT_CFG
+#define ICP_HSSACC_TDM_IO_UNIT_HSS_CHAN_CFG (0x41)
+#define ICP_HSSACC_TDM_IO_UNIT_HSS_CHAN_CFG_RESPONSE \
+ ICP_HSSACC_TDM_IO_UNIT_HSS_CHAN_CFG
+#define ICP_HSSACC_TDM_IO_UNIT_HDLC_CHAN_CFG (0x42)
+#define ICP_HSSACC_TDM_IO_UNIT_HDLC_CHAN_CFG_RESPONSE \
+ ICP_HSSACC_TDM_IO_UNIT_HDLC_CHAN_CFG
+#define ICP_HSSACC_TDM_IO_UNIT_VOICE_CHAN_CFG (0x43)
+#define ICP_HSSACC_TDM_IO_UNIT_VOICE_CHAN_CFG_RESPONSE \
+ ICP_HSSACC_TDM_IO_UNIT_VOICE_CHAN_CFG
+#define ICP_HSSACC_TDM_IO_UNIT_NEXT_CHAN_WRITE (0x44)
+#define ICP_HSSACC_TDM_IO_UNIT_NEXT_CHAN_WRITE_RESPONSE \
+ ICP_HSSACC_TDM_IO_UNIT_NEXT_CHAN_WRITE
+#define ICP_HSSACC_TDM_IO_UNIT_HDLC_CHAN_RX_MAX_SIZE_WR (0x45)
+#define ICP_HSSACC_TDM_IO_UNIT_HDLC_CHAN_RX_MAX_SIZE_WR_RESPONSE \
+ ICP_HSSACC_TDM_IO_UNIT_HDLC_CHAN_RX_MAX_SIZE_WR
+#define ICP_HSSACC_TDM_IO_UNIT_CHAN_FLOW_ENABLE (0x46)
+#define ICP_HSSACC_TDM_IO_UNIT_CHAN_FLOW_ENABLE_RESPONSE \
+ ICP_HSSACC_TDM_IO_UNIT_CHAN_FLOW_ENABLE
+#define ICP_HSSACC_TDM_IO_UNIT_CHAN_FLOW_DISABLE (0x47)
+#define ICP_HSSACC_TDM_IO_UNIT_CHAN_FLOW_DISABLE_RESPONSE \
+ ICP_HSSACC_TDM_IO_UNIT_CHAN_FLOW_DISABLE
+#define ICP_HSSACC_TDM_IO_UNIT_ABT_ALN_ERR_READ (0x48)
+#define ICP_HSSACC_TDM_IO_UNIT_ABT_ALN_ERR_READ_RESPONSE \
+ ICP_HSSACC_TDM_IO_UNIT_ABT_ALN_ERR_READ
+#define ICP_HSSACC_TDM_IO_UNIT_FCS_MAX_ERR_READ (0x49)
+#define ICP_HSSACC_TDM_IO_UNIT_FCS_MAX_ERR_READ_RESPONSE \
+ ICP_HSSACC_TDM_IO_UNIT_FCS_MAX_ERR_READ
+#define ICP_HSSACC_TDM_IO_UNIT_STATS_READ (0x4A)
+#define ICP_HSSACC_TDM_IO_UNIT_STATS_READ_RESPONSE \
+ ICP_HSSACC_TDM_IO_UNIT_STATS_READ
+#define ICP_HSSACC_TDM_IO_UNIT_BYPASS_ENABLE (0x4B)
+#define ICP_HSSACC_TDM_IO_UNIT_BYPASS_ENABLE_RESPONSE \
+ ICP_HSSACC_TDM_IO_UNIT_BYPASS_ENABLE
+#define ICP_HSSACC_TDM_IO_UNIT_BYPASS_DISABLE (0x4C)
+#define ICP_HSSACC_TDM_IO_UNIT_BYPASS_DISABLE_RESPONSE \
+ ICP_HSSACC_TDM_IO_UNIT_BYPASS_DISABLE
+#define ICP_HSSACC_TDM_IO_UNIT_GCT_LOAD (0x4D)
+#define ICP_HSSACC_TDM_IO_UNIT_GCT_LOAD_RESPONSE \
+ ICP_HSSACC_TDM_IO_UNIT_GCT_LOAD
+#define ICP_HSSACC_TDM_IO_UNIT_BYPASS_GAIN_CFG (0x4E)
+#define ICP_HSSACC_TDM_IO_UNIT_BYPASS_GAIN_CFG_RESPONSE \
+ ICP_HSSACC_TDM_IO_UNIT_BYPASS_GAIN_CFG
+#define ICP_HSSACC_TDM_IO_UNIT_TX_CHAN_Q_ADDR_CFG (0x4F)
+#define ICP_HSSACC_TDM_IO_UNIT_TX_CHAN_Q_ADDR_CFG_RESPONSE \
+ ICP_HSSACC_TDM_IO_UNIT_TX_CHAN_Q_ADDR_CFG
+
+
+#define ICP_HSSACC_TDM_IO_UNIT_TX_Q_CFG (0xA0)
+#define ICP_HSSACC_TDM_IO_UNIT_TX_Q_CFG_RESPONSE \
+ ICP_HSSACC_TDM_IO_UNIT_TX_Q_CFG
+#define ICP_HSSACC_TDM_IO_UNIT_HDLC_RX_Q_CFG (0xA1)
+#define ICP_HSSACC_TDM_IO_UNIT_HDLC_RX_Q_CFG_RESPONSE \
+ ICP_HSSACC_TDM_IO_UNIT_HDLC_RX_Q_CFG
+#define ICP_HSSACC_TDM_IO_UNIT_VOICE_RX_Q_CFG (0xA2)
+#define ICP_HSSACC_TDM_IO_UNIT_VOICE_RX_Q_CFG_RESPONSE \
+ ICP_HSSACC_TDM_IO_UNIT_VOICE_RX_Q_CFG
+#define ICP_HSSACC_TDM_IO_UNIT_TX_Q_HEAD_CTR_CFG (0xA3)
+#define ICP_HSSACC_TDM_IO_UNIT_TX_Q_HEAD_CTR_CFG_RESPONSE \
+ ICP_HSSACC_TDM_IO_UNIT_TX_Q_HEAD_CTR_CFG
+#define ICP_HSSACC_TDM_IO_UNIT_TX_Q_TAIL_CTR_CFG (0xA4)
+#define ICP_HSSACC_TDM_IO_UNIT_TX_Q_TAIL_CTR_CFG_RESPONSE \
+ ICP_HSSACC_TDM_IO_UNIT_TX_Q_TAIL_CTR_CFG
+#define ICP_HSSACC_TDM_IO_UNIT_HDLC_RX_Q_READER_CFG (0xA5)
+#define ICP_HSSACC_TDM_IO_UNIT_HDLC_RX_Q_READER_CFG_RESPONSE \
+ ICP_HSSACC_TDM_IO_UNIT_HDLC_RX_Q_READER_CFG
+#define ICP_HSSACC_TDM_IO_UNIT_HDLC_RX_Q_WRITER_CFG (0xA6)
+#define ICP_HSSACC_TDM_IO_UNIT_HDLC_RX_Q_WRITER_CFG_RESPONSE \
+ ICP_HSSACC_TDM_IO_UNIT_HDLC_RX_Q_WRITER_CFG
+#define ICP_HSSACC_TDM_IO_UNIT_VOICE_RX_Q_READER_CFG (0xA7)
+#define ICP_HSSACC_TDM_IO_UNIT_VOICE_RX_Q_READER_CFG_RESPONSE \
+ ICP_HSSACC_TDM_IO_UNIT_VOICE_RX_Q_READER_CFG
+#define ICP_HSSACC_TDM_IO_UNIT_VOICE_RX_Q_WRITER_CFG (0xA8)
+#define ICP_HSSACC_TDM_IO_UNIT_VOICE_RX_Q_WRITER_CFG_RESPONSE \
+ ICP_HSSACC_TDM_IO_UNIT_VOICE_RX_Q_WRITER_CFG
+#define ICP_HSSACC_TDM_IO_UNIT_HSS_INT_CFG (0xA9)
+#define ICP_HSSACC_TDM_IO_UNIT_HSS_INT_CFG_RESPONSE \
+ ICP_HSSACC_TDM_IO_UNIT_HSS_INT_CFG
+#define ICP_HSSACC_TDM_IO_UNIT_HSS_TIMER_CFG (0xAA)
+#define ICP_HSSACC_TDM_IO_UNIT_HSS_TIMER_CFG_RESPONSE \
+ ICP_HSSACC_TDM_IO_UNIT_HSS_TIMER_CFG
+#define ICP_HSSACC_TDM_IO_UNIT_OFFS_TABLE_LOAD (0xAB)
+#define ICP_HSSACC_TDM_IO_UNIT_OFFS_TABLE_LOAD_RESPONSE \
+ ICP_HSSACC_TDM_IO_UNIT_OFFS_TABLE_LOAD
+#define ICP_HSSACC_TDM_IO_UNIT_OFFS_TABLE_READ (0xAC)
+#define ICP_HSSACC_TDM_IO_UNIT_OFFS_TABLE_READ_RESPONSE \
+ ICP_HSSACC_TDM_IO_UNIT_OFFS_TABLE_READ
+
+
+#define ICP_HSSACC_TDM_IO_UNIT_HSS_SW_ERROR_STATUS (0x80)
+#define ICP_HSSACC_TDM_IO_UNIT_HSS_SW_ERROR_READ (0x81)
+#define ICP_HSSACC_TDM_IO_UNIT_HSS_SW_ERROR_READ_RESPONSE \
+ ICP_HSSACC_TDM_IO_UNIT_HSS_SW_ERROR_READ
+
+
+/* interval in TDM I/O Unit cycles at which the TDM I/O Unit is to
+ service the Software Queues */
+#ifdef TOLAPAI
+#define ICP_HSSACC_TDM_IO_UNIT_HSS_TIMER_INTERVAL (133000)
+#else
+#ifdef IXP23XX
+#define ICP_HSSACC_TDM_IO_UNIT_HSS_TIMER_INTERVAL (100000)
+#endif
+#endif
+
+#ifdef TOLAPAI
+#define ICP_HSSACC_TDM_IO_UNIT_MAX_TRANSACTION_SIZE_WRDS (14)
+#else
+#ifdef IXP23XX
+#define ICP_HSSACC_TDM_IO_UNIT_MAX_TRANSACTION_SIZE_WRDS (9)
+#endif
+#endif
+
+#define ICP_HSSACC_TDM_IO_UNIT_HSS_INT_DISABLED (0)
+#define ICP_HSSACC_TDM_IO_UNIT_HSS_INT_ENABLED (1)
+
+/* Channel Stats codes for Stat Read TDM I/O Unit message */
+
+#define ICP_HSSACC_TDM_IO_UNIT_CHAN_STAT_ABT_ALN (0)
+#define ICP_HSSACC_TDM_IO_UNIT_CHAN_STAT_MAX_SIZE (1)
+#define ICP_HSSACC_TDM_IO_UNIT_CHAN_STAT_FCS (2)
+#ifndef NDEBUG
+#define ICP_HSSACC_TDM_IO_UNIT_CHAN_STAT_RX_PKTS (3)
+#define ICP_HSSACC_TDM_IO_UNIT_CHAN_STAT_TX_PKTS (4)
+#endif
+
+#ifdef IXP23XX
+/* LUT defines used in the creation of the timeslot allocation
+ tables to be sent to the TDM I/O Unit */
+#define ICP_HSSACC_TDM_IO_UNIT_WORDS_PER_LUT (8)
+#define ICP_HSSACC_TDM_IO_UNIT_LUT_WORD_FULL_ASSIGNMENT (0x55555555)
+#define ICP_HSSACC_TDM_IO_UNIT_LUT_WORD_T1_ASSIGNMENT (0x5555)
+#define ICP_HSSACC_TDM_IO_UNIT_LUT_E1_SIZE_WRDS (2)
+#define ICP_HSSACC_TDM_IO_UNIT_LUT_DMVIP_SIZE_WRDS (4)
+#define ICP_HSSACC_TDM_IO_UNIT_LUT_QMVIP_SIZE_WRDS (8)
+#endif
+
+
+/* Provision Table defines */
+#define ICP_HSSACC_TDM_IO_UNIT_PROV_TABLE_SZ (0x400)
+#define ICP_HSSACC_TDM_IO_UNIT_TS_ENABLE (1)
+#define ICP_HSSACC_TDM_IO_UNIT_CHAN_OFFSET (16)
+#define ICP_HSSACC_TDM_IO_UNIT_TS_EN_BIT_OFFSET (23)
+#define ICP_HSSACC_TDM_IO_UNIT_OFFSET_TABLE_SZ (0x200)
+
+/* Queue List configuration */
+#define ICP_HSSACC_TDM_IO_UNIT_CHAN_ADD_FLAG (0)
+#define ICP_HSSACC_TDM_IO_UNIT_CHAN_DEL_FLAG (1)
+
+/* When adding/removing channels on a linked list for
+ * a port, these values are used to indicate whether the list is
+ * a Tx list or an Rx list
+ */
+#define IX_HSSACC_TDM_IO_UNIT_LIST_INDICATOR_TX (0)
+#define IX_HSSACC_TDM_IO_UNIT_LIST_INDICATOR_RX (1)
+
+/* Defines for specifying the data flow direction which we are
+ enabling/disabling for this channel */
+#define ICP_HSSACC_TDM_IO_UNIT_FLOW_DIR_NEITHER (0)
+#define ICP_HSSACC_TDM_IO_UNIT_FLOW_DIR_TX_ONLY (1)
+#define ICP_HSSACC_TDM_IO_UNIT_FLOW_DIR_RX_ONLY (2)
+#define ICP_HSSACC_TDM_IO_UNIT_FLOW_DIR_BOTH (3)
+
+
+/* Queue Configuration parameters for QMgr component */
+#define ICP_HSSACC_VOICE_RX_WATERMARK (1)
+#define ICP_HSSACC_HDLC_RX_WATERMARK (1)
+#define ICP_HSSACC_TX_WATERMARK (1)
+
+
+/* SDC Control Register Offset and Masks */
+#define ICP_HSSACC_TDM_IO_UNIT_SDC_CHAN_TYPE_VOICE (2)
+#define ICP_HSSACC_TDM_IO_UNIT_SDC_CHAN_TYPE_HDLC (0)
+
+#define ICP_HSSACC_TDM_IO_UNIT_SDC_BIT_ROBBING_OFFSET (14)
+#define ICP_HSSACC_TDM_IO_UNIT_SDC_RBIT_LOC_OFFSET (12)
+#define ICP_HSSACC_TDM_IO_UNIT_SDC_RBIT_VAL_OFFSET (9)
+#define ICP_HSSACC_TDM_IO_UNIT_SDC_INVERT_OFFSET (8)
+#define ICP_HSSACC_TDM_IO_UNIT_SDC_CHAN_TYPE_OFFSET (6)
+#define ICP_HSSACC_TDM_IO_UNIT_SDC_BIT_REVERSE_OFFSET (5)
+#define ICP_HSSACC_TDM_IO_UNIT_SDC_BYTE_SWAP_OFFSET (4)
+
+#define ICP_HSSACC_TDM_IO_UNIT_SDC_BIT_NO_REVERSE (0)
+#define ICP_HSSACC_TDM_IO_UNIT_SDC_BIT_REVERSE (1)
+#define ICP_HSSACC_TDM_IO_UNIT_SDC_BYTE_NO_SWAP (0)
+#define ICP_HSSACC_TDM_IO_UNIT_SDC_BYTE_SWAP (1)
+#define ICP_HSSACC_TDM_IO_UNIT_SDC_BIT_INVERT_ON (1)
+#define ICP_HSSACC_TDM_IO_UNIT_SDC_BIT_INVERT_OFF (0)
+
+#define ICP_HSSACC_TDM_IO_UNIT_SDC_RBIT_ONE_BIT_ON (1)
+#define ICP_HSSACC_TDM_IO_UNIT_SDC_RBIT_OFF (0)
+
+#define ICP_HSSACC_TDM_IO_UNIT_SDC_RBIT_VALUE_ZERO (0)
+#define ICP_HSSACC_TDM_IO_UNIT_SDC_RBIT_VALUE_ONE (1)
+
+#define ICP_HSSACC_TDM_IO_UNIT_SDC_RBIT_LOC_ZERO (1)
+#define ICP_HSSACC_TDM_IO_UNIT_SDC_RBIT_LOC_SEVEN (0)
+
+#define ICP_HSSACC_TDM_IO_UNIT_HDLC_IDLE_FLAG (0)
+#define ICP_HSSACC_TDM_IO_UNIT_HDLC_IDLE_ONES (1)
+
+#define ICP_HSSACC_TDM_IO_UNIT_HDLC_32_BIT_CRC (1)
+#define ICP_HSSACC_TDM_IO_UNIT_HDLC_16_BIT_CRC (0)
+
+#define ICP_HSSACC_TDM_IO_UNIT_HDLC_SOF_SHARED (0)
+#define ICP_HSSACC_TDM_IO_UNIT_HDLC_SOF_ONE (1)
+#define ICP_HSSACC_TDM_IO_UNIT_HDLC_SOF_TWO (2)
+
+
+
+
+#define ICP_HSSACC_TDM_IO_UNIT_SDC_CTRL_MSB_MASK (0xFF00)
+#define ICP_HSSACC_TDM_IO_UNIT_SDC_CTRL_MSB_OFFSET (8)
+#define ICP_HSSACC_TDM_IO_UNIT_SDC_CTRL_LSB_MASK (0xFF)
+
+
+/* HDLC TX & RX CFG Registers Offsets */
+#define ICP_HSSACC_TDM_IO_UNIT_HDLC_TX_CFG_IM_OFFSET (0)
+#define ICP_HSSACC_TDM_IO_UNIT_HDLC_TX_CFG_FCS_OFFSET (1)
+#define ICP_HSSACC_TDM_IO_UNIT_HDLC_TX_CFG_SF_OFFSET (3)
+#define ICP_HSSACC_TDM_IO_UNIT_HDLC_TX_CFG_POSTBF_OFFSET (5)
+
+#define ICP_HSSACC_TDM_IO_UNIT_HDLC_RX_CFG_IM_OFFSET (0)
+#define ICP_HSSACC_TDM_IO_UNIT_HDLC_RX_CFG_FCS_OFFSET (1)
+#define ICP_HSSACC_TDM_IO_UNIT_HDLC_RX_CFG_PREBF_OFFSET (3)
+
+#define ICP_HSSACC_TDM_IO_UNIT_HDLC_CFG_BIT_FLIP (1)
+#define ICP_HSSACC_TDM_IO_UNIT_HDLC_CFG_NO_BIT_FLIP (0)
+
+
+
+
+/* HDMA Register Offset Definitions */
+/* Port Configuration Register Common Section */
+#define ICP_HSSACC_TDM_IO_UNIT_HDMA_PCR_FT_OFFSET (30)
+#define ICP_HSSACC_TDM_IO_UNIT_HDMA_PCR_FS_OFFSET (28)
+#define ICP_HSSACC_TDM_IO_UNIT_HDMA_PCR_FE_OFFSET (27)
+#define ICP_HSSACC_TDM_IO_UNIT_HDMA_PCR_DE_OFFSET (26)
+#define ICP_HSSACC_TDM_IO_UNIT_HDMA_PCR_CLKDIR_OFFSET (25)
+#define ICP_HSSACC_TDM_IO_UNIT_HDMA_PCR_FR_OFFSET (24)
+#ifdef TOLAPAI
+#define ICP_HSSACC_TDM_IO_UNIT_HDMA_PCR_CS_OFFSET (23)
+#endif
+#define ICP_HSSACC_TDM_IO_UNIT_HDMA_PCR_RATE_OFFSET (21)
+#define ICP_HSSACC_TDM_IO_UNIT_HDMA_PCR_DP_OFFSET (20)
+#define ICP_HSSACC_TDM_IO_UNIT_HDMA_PCR_BITEND_OFFSET (19)
+#ifdef TOLAPAI
+#define ICP_HSSACC_TDM_IO_UNIT_HDMA_PCR_REFF_OFFSET (17)
+#endif
+
+/* Port Configuration Register Tx Section */
+#define ICP_HSSACC_TDM_IO_UNIT_HDMA_PCR_OD_OFFSET (18)
+#define ICP_HSSACC_TDM_IO_UNIT_HDMA_PCR_EN_OFFSET (16)
+#define ICP_HSSACC_TDM_IO_UNIT_HDMA_TX_PCR_LB_OFFSET (15)
+#define ICP_HSSACC_TDM_IO_UNIT_HDMA_PCR_56KTYPE_OFFSET (13)
+#define ICP_HSSACC_TDM_IO_UNIT_HDMA_PCR_UTYPE_OFFSET (11)
+#define ICP_HSSACC_TDM_IO_UNIT_HDMA_PCR_FB_OFFSET (10)
+#define ICP_HSSACC_TDM_IO_UNIT_HDMA_PCR_56KEND_OFFSET (9)
+#define ICP_HSSACC_TDM_IO_UNIT_HDMA_PCR_56KSEL_OFFSET (8)
+
+
+/* Port Configuration Register Rx Section */
+#define ICP_HSSACC_TDM_IO_UNIT_HDMA_RX_PCR_LB_OFFSET (16)
+
+
+#define ICP_HSSACC_TDM_IO_UNIT_HDMA_PCR_LB_ON (1)
+#define ICP_HSSACC_TDM_IO_UNIT_HDMA_PCR_LB_OFF (0)
+
+#define ICP_HSSACC_TDM_IO_UNIT_HDMA_PCR_CLKDIR_INPUT (0)
+#define ICP_HSSACC_TDM_IO_UNIT_HDMA_PCR_CLKDIR_OUTPUT (1)
+#ifdef TOLAPAI
+#define ICP_HSSACC_TDM_IO_UNIT_HDMA_PCR_CS_INT (0)
+#define ICP_HSSACC_TDM_IO_UNIT_HDMA_PCR_CS_EXT_REF (1)
+#endif
+
+
+/* Frame Configuration Register */
+#define ICP_HSSACC_TDM_IO_UNIT_HDMA_FCR_FBIT_OFFSET (31)
+#define ICP_HSSACC_TDM_IO_UNIT_HDMA_FCR_OFFSET_OFFSET (16)
+#define ICP_HSSACC_TDM_IO_UNIT_HDMA_FCR_MVIP_SWITCH_OFFSET (7)
+#define ICP_HSSACC_TDM_IO_UNIT_HDMA_FCR_MVIP_SETTING_OFFSET (6)
+#define ICP_HSSACC_TDM_IO_UNIT_HDMA_FCR_INT_OFFSET (5)
+#define ICP_HSSACC_TDM_IO_UNIT_HDMA_FCR_FRAME_SIZE_OFFSET (0)
+
+#define ICP_HSSACC_TDM_IO_UNIT_HDMA_FCR_FRAME_SIZE_T1_IN_TS (23)
+#define ICP_HSSACC_TDM_IO_UNIT_HDMA_FCR_FRAME_SIZE_E1_IN_TS (31)
+#define ICP_HSSACC_TDM_IO_UNIT_HDMA_FCR_FRAME_SIZE_T1_IN_BITS (193)
+#define ICP_HSSACC_TDM_IO_UNIT_HDMA_FCR_FRAME_SIZE_E1_IN_BITS (256)
+#define ICP_HSSACC_TDM_IO_UNIT_HDMA_FCR_FRAME_SIZE_DUAL_MVIP_IN_BITS \
+ (ICP_HSSACC_TDM_IO_UNIT_HDMA_FCR_FRAME_SIZE_E1_IN_BITS * 2)
+#define ICP_HSSACC_TDM_IO_UNIT_HDMA_FCR_FRAME_SIZE_QUAD_MVIP_IN_BITS \
+ (ICP_HSSACC_TDM_IO_UNIT_HDMA_FCR_FRAME_SIZE_E1_IN_BITS * 4)
+
+/* The HSS co-processor register values to be added to OFFSET in the
+ * case of TX and data in the HSSFCR */
+#define ICP_HSSACC_TDM_IO_UNIT_HDMA_FCR_OFFSET_TX_ADD_CLK_RATE (0x13)
+#define ICP_HSSACC_TDM_IO_UNIT_HDMA_FCR_OFFSET_TX_ADD_HALF_CLK_RATE (0x11)
+
+/* value to be added to OFFSET in the case of FBIT being set in the FCR */
+#define ICP_HSSACC_TDM_IO_UNIT_HDMA_FCR_OFFSET_FBIT_ADDITION (7)
+
+
+/* Image Configuration Register */
+#ifdef IXP23XX
+#define ICP_HSSACC_TDM_IO_UNIT_HDMA_ICR_VOICE_CHANNELISATION_OFFSET (20)
+#define ICP_HSSACC_TDM_IO_UNIT_HDMA_ICR_PINGPONG_OFFSET (19)
+#define ICP_HSSACC_TDM_IO_UNIT_HDMA_ICR_PHO_OFFSET (8)
+/* Ping Pong */
+#define ICP_HSSACC_TDM_IO_UNIT_HSS_PING_PONG_ENABLED (1)
+/* Voice channelisation. */
+#define ICP_HSSACC_TDM_IO_UNIT_HSS_VCH_ENABLED (0)
+#endif
+#define ICP_HSSACC_TDM_IO_UNIT_HDMA_ICR_PID_OFFSET (16)
+#define ICP_HSSACC_TDM_IO_UNIT_HDMA_ICR_PBA_OFFSET (0)
+
+#define ICP_HSSACC_TDM_IO_UNIT_HSS_HDMA_RX_PBA_0 (1)
+#define ICP_HSSACC_TDM_IO_UNIT_HSS_HDMA_RX_PBA_1 (3)
+#define ICP_HSSACC_TDM_IO_UNIT_HSS_HDMA_RX_PBA_2 (5)
+#ifdef IXP23XX
+#define ICP_HSSACC_TDM_IO_UNIT_HSS_HDMA_RX_PBA_3 (7)
+#endif
+#define ICP_HSSACC_TDM_IO_UNIT_HSS_HDMA_TX_PBA_0 (0)
+#define ICP_HSSACC_TDM_IO_UNIT_HSS_HDMA_TX_PBA_1 (2)
+#define ICP_HSSACC_TDM_IO_UNIT_HSS_HDMA_TX_PBA_2 (4)
+#ifdef IXP23XX
+#define ICP_HSSACC_TDM_IO_UNIT_HSS_HDMA_TX_PBA_3 (6)
+#endif
+
+/*The port image depth as a power of 2.
+ The port image depth is always 32*4 = 128 no matter
+ how many timeslots are assigned*/
+#define ICP_HSSACC_TDM_IO_UNIT_HSS_HDMA_PID_SHIFT (7)
+
+/* CLK CR */
+#define ICP_HSSACC_TDM_IO_UNIT_HDMA_CLKCR_MAIN_OFFSET (22)
+#define ICP_HSSACC_TDM_IO_UNIT_HDMA_CLKCR_DENOM_OFFSET (0)
+#define ICP_HSSACC_TDM_IO_UNIT_HDMA_CLKCR_NUM_OFFSET (12)
+
+#ifdef IXP23XX
+/* HCR */
+#define ICP_HSSACC_TDM_IO_UNIT_HSS_SUB_FRAME_DELTA_OFFSET (32)
+#define ICP_HSSACC_TDM_IO_UNIT_HDMA_HCR_FRAME_BASE_OFFSET (8)
+
+/* VCR */
+#define ICP_HSSACC_TDM_IO_UNIT_HDMA_VCR_FRAME_BASE_OFFSET (8)
+#endif
+
+/* CWR */
+#define ICP_HSSACC_TDM_IO_UNIT_HDMA_CWR_TX_CW2_ENABLE_OFFSET (31)
+#define ICP_HSSACC_TDM_IO_UNIT_HDMA_CWR_TX_CW2_ADDRESS_OFFSET (24)
+#define ICP_HSSACC_TDM_IO_UNIT_HDMA_CWR_TX_CW1_ENABLE_OFFSET (23)
+#define ICP_HSSACC_TDM_IO_UNIT_HDMA_CWR_TX_CW1_ADDRESS_OFFSET (16)
+#define ICP_HSSACC_TDM_IO_UNIT_HDMA_CWR_RX_CW2_ENABLE_OFFSET (15)
+#define ICP_HSSACC_TDM_IO_UNIT_HDMA_CWR_RX_CW2_ADDRESS_OFFSET (8)
+#define ICP_HSSACC_TDM_IO_UNIT_HDMA_CWR_RX_CW1_ENABLE_OFFSET (7)
+#define ICP_HSSACC_TDM_IO_UNIT_HDMA_CWR_RX_CW1_ADDRESS_OFFSET (0)
+
+/*
+ Context wakeup Enabling.
+*/
+/* 1 means on. 0 means off */
+#define ICP_HSSACC_TDM_IO_UNIT_HSS_TX_CW1_ENABLED (1)
+#define ICP_HSSACC_TDM_IO_UNIT_HSS_RX_CW1_ENABLED (1)
+#define ICP_HSSACC_TDM_IO_UNIT_HSS_TX_CW1_DISABLED (0)
+#define ICP_HSSACC_TDM_IO_UNIT_HSS_RX_CW1_DISABLED (0)
+#define ICP_HSSACC_TDM_IO_UNIT_HSS_TX_CW2_ENABLED (1)
+#define ICP_HSSACC_TDM_IO_UNIT_HSS_RX_CW2_ENABLED (1)
+#define ICP_HSSACC_TDM_IO_UNIT_HSS_TX_CW2_DISABLED (0)
+#define ICP_HSSACC_TDM_IO_UNIT_HSS_RX_CW2_DISABLED (0)
+
+
+
+/* TDM IO UNIT Software Error codes and Bitmask offsets */
+#define ICP_HSSACC_TDM_IO_UNIT_RX_VOICE_Q_OVERFLOW (0x2)
+#define ICP_HSSACC_TDM_IO_UNIT_RX_HDLC_Q_OVERFLOW (0x3)
+#define ICP_HSSACC_TDM_IO_UNIT_RX_VOICE_FIFO_OVERFLOW (0x4)
+#define ICP_HSSACC_TDM_IO_UNIT_RX_HDLC_FIFO_OVERFLOW (0x5)
+#define ICP_HSSACC_TDM_IO_UNIT_RX_VOICE_FREE_Q_UNDERFLOW (0x6)
+#define ICP_HSSACC_TDM_IO_UNIT_RX_HDLC_FREE_Q_UNDERFLOW (0x7)
+#define ICP_HSSACC_TDM_IO_UNIT_MSG_OUT_FIFO_LP_OVERFLOW (0xa)
+#define ICP_HSSACC_TDM_IO_UNIT_MSG_OUT_FIFO_HP_OVERFLOW (0xb)
+
+/*
+ * Error Bitmask offset definitions
+ */
+#ifdef TOLAPAI
+#define ICP_HSSACC_TDM_IO_UNIT_ERR_BITMSK_PORT_RX_PARITY (5)
+#define ICP_HSSACC_TDM_IO_UNIT_ERR_BITMSK_PORT_TX_PARITY (4)
+#endif
+#define ICP_HSSACC_TDM_IO_UNIT_ERR_BITMSK_PORT_RX_FLOW (3)
+#define ICP_HSSACC_TDM_IO_UNIT_ERR_BITMSK_PORT_TX_FLOW (2)
+#define ICP_HSSACC_TDM_IO_UNIT_ERR_BITMSK_PORT_RX_LOSS (1)
+#define ICP_HSSACC_TDM_IO_UNIT_ERR_BITMSK_PORT_TX_LOSS (0)
+
+
+#ifdef IXP23XX
+#define ICP_HSSACC_TDM_IO_UNIT_ERR_ALL_PORT_MASK (0xFFFFFF)
+#else
+#define ICP_HSSACC_TDM_IO_UNIT_ERR_ALL_PORT_MASK (0x3FFFF)
+#endif
+#define ICP_HSSACC_TDM_IO_UNIT_ERR_SGLE_PORT_MASK (0x3F)
+#define ICP_HSSACC_TDM_IO_UNIT_NEXT_PORT_SHIFT (6)
+
+#define ICP_HSSACC_TDM_IO_UNIT_ERR_BITMSK_MSG_OUT_FIFO_H (23)
+#define ICP_HSSACC_TDM_IO_UNIT_ERR_BITMSK_RX_V_FREE_UNDERF (19)
+#define ICP_HSSACC_TDM_IO_UNIT_ERR_BITMSK_RX_H_FREE_UNDERF (18)
+#define ICP_HSSACC_TDM_IO_UNIT_ERR_BITMSK_RX_V_INT_FIFO_OVERF (17)
+#define ICP_HSSACC_TDM_IO_UNIT_ERR_BITMSK_RX_H_INT_FIFO_OVERF (16)
+#define ICP_HSSACC_TDM_IO_UNIT_ERR_BITMSK_MSG_OUT_FIFO_L (3)
+#define ICP_HSSACC_TDM_IO_UNIT_ERR_BITMSK_RX_H_Q_OVERF (2)
+#define ICP_HSSACC_TDM_IO_UNIT_ERR_BITMSK_RX_V_Q_OVERF (1)
+
+
+/*
+ * The maximum number of timeslots available on a TDM trunk.
+ */
+#define ICP_HSSACC_MAX_TIMESLOTS_PER_TDM_LINE (32)
+#define ICP_HSSACC_TIMESLOTS_PER_T1_LINE (24)
+
+
+/*
+ * The number of TDM trunks per HSS port.
+ */
+#define ICP_HSSACC_MAX_TDM_LINES_PER_PORT (4)
+
+/*
+ * The maximum number of timeslots available on a HSS port.
+ */
+#define ICP_HSSACC_MAX_TIMESLOTS_PER_PORT (\
+ ICP_HSSACC_MAX_TIMESLOTS_PER_TDM_LINE * \
+ ICP_HSSACC_MAX_TDM_LINES_PER_PORT)
+
+
+
+/* System Clock divider definitions for the TDM I/O Unit HDMA coprocessor */
+#ifdef IXP23XX
+#define ICP_HSSACC_HDMA_SYSCLK_1544KHZ { 64,147,197 }
+#define ICP_HSSACC_HDMA_SYSCLK_2048KHZ { 48, 52, 63 }
+#define ICP_HSSACC_HDMA_SYSCLK_8192KHZ { 12, 52,255 }
+#else
+#ifdef TOLAPAI
+#define ICP_HSSACC_HDMA_SYSCLK_1544KHZ { 43,28,192 }
+#define ICP_HSSACC_HDMA_SYSCLK_2048KHZ { 32, 135, 255 }
+#define ICP_HSSACC_HDMA_SYSCLK_8192KHZ { 8, 135,1023 }
+#endif
+#endif
+
+
+
+/* ----------------------------------------------------------------------------
+ * Application Specific Duals
+ * ----------------------------------------------------------------------------
+ */
+#define ICP_HSSACC_TDM_IO_UNIT_CPP_COPROC (0x09)
+#define ICP_HSSACC_TDM_IO_UNIT_SDC_COPROC (0x02)
+#define ICP_HSSACC_TDM_IO_UNIT_SDC_RD_HDLC_INST (0x09)
+#define ICP_HSSACC_TDM_IO_UNIT_SDC_WR_HDLC_INST (0x0C)
+#define ICP_HSSACC_TDM_IO_UNIT_SDC_RD_VOICE_INST (0x12)
+#define ICP_HSSACC_TDM_IO_UNIT_SDC_WR_VOICE_INST (0x02)
+#define ICP_HSSACC_TDM_IO_UNIT_CPP_RD_WORD_INST (0x0C)
+#define ICP_HSSACC_TDM_IO_UNIT_CPP_WR_WORD_INST (0x08)
+
+/* ----------------------------------------------------------------------------
+ * Structure definitions
+ * ----------------------------------------------------------------------------
+ */
+/*
+ * structure of stats for TDM I/O Unit messages with responses
+ */
+typedef struct icp_hssacc_msg_with_resp_stats_s
+{
+ uint32_t numTdmIOUnitMessagesSent;
+ uint32_t numTdmIOUnitRespReceived;
+ uint32_t numTdmIOUnitTimeoutErrs;
+ uint32_t numTdmIOUnitInvalidResp;
+} icp_hssacc_msg_with_resp_stats_t;
+
+
+/* This is a set of identifiers for the
+ * channel linked lists
+ */
+typedef enum icp_hssacc_channel_list_s
+{
+ ICP_HSSACC_CHANNEL_LIST_PRIMARY = 0,
+ ICP_HSSACC_CHANNEL_LIST_SECONDARY_0,
+ ICP_HSSACC_CHANNEL_LIST_SECONDARY_1,
+ ICP_HSSACC_CHANNEL_LIST_DELIMITER
+} icp_hssacc_channel_list_t;
+
+
+/*
+ This is the list of all the channel lists used by the
+ HSS I/O Access library
+*/
+typedef enum icp_hssacc_tdm_io_unit_channel_list_s
+{
+ ICP_HSSACC_TDM_IO_UNIT_LIST_TX_PRIMARY = 0,
+ ICP_HSSACC_TDM_IO_UNIT_LIST_TX_SECONDARY_0,
+ ICP_HSSACC_TDM_IO_UNIT_LIST_TX_SECONDARY_1,
+ ICP_HSSACC_TDM_IO_UNIT_LIST_RX_PRIMARY,
+ ICP_HSSACC_TDM_IO_UNIT_LIST_RX_SECONDARY_0,
+ ICP_HSSACC_TDM_IO_UNIT_LIST_RX_SECONDARY_1,
+ ICP_HSSACC_TDM_IO_UNIT_LIST_DELIMITER
+} icp_hssacc_tdm_io_unit_channel_list_t;
+
+
+/*****************************************************************************
+ * Abstract
+ * HssAcc Receive queue reader counters.
+ * Used by the HssAcc component to access
+ * counters written solely by the TDM I/O unit.
+ *
+ *
+ *****************************************************************************/
+typedef struct icp_hssacc_rx_q_read_counters_s
+{
+ uint32_t rxFreeTail;
+ uint32_t rxHead;
+} __attribute__((packed)) icp_hssacc_rx_q_read_counters_t;
+
+
+/*****************************************************************************
+ * Abstract
+ * HssAcc queue reader counters. Used by the HssAcc component to access
+ * counters written solely by the TDM I/O unit.
+ *
+ * Purpose
+ * Should be used by the access layer to read the counters written by the
+ * TDM I/O unit.
+ *
+ * Fields
+ * txTail - an array of 1-byte counters for each Tx queue.
+ * voiceRxCounters.rxFreeTail - a 4-byte counter for the voice Rx free
+ * tail counter. Only the lower 2 bytes
+ * are used.
+ * voiceRxCounters.rxHead - a 4-byte counter for the voice Rx head
+ * counter. Only the lower 2 bytes are used.
+ * hdlcRxCounters.rxFreeTail - a 4-byte counter for the HDLC Rx free
+ * tail counter. Only the lower 2 bytes
+ * are used.
+ * hdlcRxCounters.rxHead - a 4-byte counter for the HDLC Rx head
+ * counter. Only the lower 2 bytes are used.
+ *
+ *****************************************************************************/
+typedef struct icp_hssacc_queue_reader_counters_s
+{
+ /* The tail counters for each of the Tx queues */
+ uint8_t txTail[ICP_HSSACC_MAX_NUM_CHANNELS];
+
+ /* The voice Rx free tail and rx head counters */
+ icp_hssacc_rx_q_read_counters_t voiceRxCounters;
+
+ /* The HDLC Rx free tail and rx head counters */
+ icp_hssacc_rx_q_read_counters_t hdlcRxCounters;
+} __attribute__((packed,aligned(4))) icp_hssacc_queue_reader_counters_t;
+
+
+
+/*****************************************************************************
+ * Abstract
+ * HssAcc Receive queue writer counters.
+ * These counters are read by the TDM I/O unit
+ * and written by HssAcc.
+ *
+ *****************************************************************************/
+typedef struct icp_hssacc_rx_q_write_counters_s
+{
+ uint32_t rxFreeHead;
+ uint32_t rxTail;
+} __attribute__((packed)) icp_hssacc_rx_q_write_counters_t;
+
+
+
+/*****************************************************************************
+ * Abstract
+ * HssAcc queue writer counters. These counters are read by the TDM I/O unit
+ * and written by HssAcc.
+ *
+ * Purpose
+ * Should be used by the access layer to update the counters read by the
+ * TDM I/O unit.
+ *
+ * Fields
+ * txHeadCounters - an array of 1-byte counters for each Tx queue.
+ * voiceRxCounters.rxFreeHead - a 4-byte counter for the voice Rx free
+ * head counter. Only the lower 2 bytes
+ * are used.
+ * voiceRxCounters.rxTail - a 4-byte counter for the voice Rx tail
+ * counter. Only the lower 2 bytes are used.
+ * hdlcRxCounters.rxFreeHead - a 4-byte counter for the HDLC Rx free
+ * head counter. Only the lower 2 bytes
+ * are used.
+ * hdlcRxCounters.rxTail - a 4-byte counter for the HDLC Rx tail
+ * counter. Only the lower 2 bytes are used.
+ *
+ *****************************************************************************/
+typedef struct icp_hssacc_queue_write_counters_s
+{
+ /* The head counters for all the Tx queues */
+ uint8_t txHead[ICP_HSSACC_MAX_NUM_CHANNELS];
+
+ /* The voice Rx free head and rx tail counters */
+ icp_hssacc_rx_q_write_counters_t voiceRxCounters;
+
+ /* The HDLC Rx free head and rx tail counters */
+ icp_hssacc_rx_q_write_counters_t hdlcRxCounters;
+} __attribute__((packed,aligned(4))) icp_hssacc_queue_write_counters_t;
+
+
+
+/* ----------------------------------------------------------------------------
+ * Function declarations
+ * ----------------------------------------------------------------------------
+ */
+
+/*****************************************************************************
+ * Abstract:
+ * Constructs a 2 word TDM I/O Unit message out of 4 individual bytes
+ * values and a full word value.
+ *
+ *
+ * Side Effects:
+ * The message will be written into pMessage->data[0] & pMessage->data[1].
+ *
+ * Assumptions:
+ * None.
+ *
+ *****************************************************************************/
+void
+HssAccComTdmIOUnitCmd4byte1wordMsgCreate (
+ uint32_t byte0,
+ uint32_t byte1,
+ uint32_t byte2,
+ uint32_t byte3,
+ uint32_t word,
+ IxPiuMhMessage *pMessage);
+
+
+/*****************************************************************************
+ * Abstract:
+ * Constructs a 2 word TDM I/O Unit message out of 8 individual byte values.
+ *
+ * Side Effects:
+ * The message will be written into pMessage->data[0] & pMessage->data[1].
+ *
+ * Assumptions:
+ * None.
+ *
+ *****************************************************************************/
+void
+HssAccComTdmIOUnitCmd8byteMsgCreate (
+ uint32_t byte0,
+ uint32_t byte1,
+ uint32_t byte2,
+ uint32_t byte3,
+ uint32_t byte4,
+ uint32_t byte5,
+ uint32_t byte6,
+ uint32_t byte7,
+ IxPiuMhMessage *pMessage);
+
+
+/*****************************************************************************
+ * Abstract:
+ * Submits a message to the TDM I/O Unit, waits for a response and verifies
+ * that the correct response was received. if responseWord is NULL then
+ * we are not expecting anything more than an ACK.
+ *
+ *
+ *****************************************************************************/
+icp_status_t
+HssAccComTdmIOUnitMsgSendAndRecv(
+ IxPiuMhMessage message,
+ uint8_t response,
+ icp_hssacc_msg_with_resp_stats_t * stats,
+ uint32_t * responseWord);
+
+/*****************************************************************************
+ * Abstract:
+ * Displays Communication Stats relating to a single TDM I/O message
+ *
+ *
+ *****************************************************************************/
+void HssAccSingleMessageStatsShow (icp_hssacc_msg_with_resp_stats_t stat);
+
+#endif /* ICP_HSSACCCOMMON_H */
diff --git a/Acceleration/library/icp_telephony/tdm_io_access/include/icp_hssacc_port_config.h b/Acceleration/library/icp_telephony/tdm_io_access/include/icp_hssacc_port_config.h
new file mode 100644
index 0000000..407ccae
--- /dev/null
+++ b/Acceleration/library/icp_telephony/tdm_io_access/include/icp_hssacc_port_config.h
@@ -0,0 +1,297 @@
+/******************************************************************************
+ * @file icp_hssacc_port_config.h
+ *
+ * @description this contains the data structure definitions and function
+ * prototypes necessary for port configuration
+ *
+ * @ingroup icp_HssAcc
+ *
+ * @revision 1.0
+ *
+ * @par
+ * This file is provided under a dual BSD/GPLv2 license. When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * The full GNU General Public License is included in this distribution
+ * in the file called LICENSE.GPL.
+ *
+ * Contact Information:
+ * Intel Corporation
+ *
+ * BSD LICENSE
+ *
+ * Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ *
+ *
+ *****************************************************************************/
+
+#ifndef ICP_HSSACCPORTCONFIG_H
+#define ICP_HSSACCPORTCONFIG_H
+
+#include "icp_hssacc.h"
+#include "icp_hssacc_common.h"
+
+
+/* Default Frame Pulse Widths for the TDM ports
+ Valid Range for Frame Pulse Width is 1 to 8 */
+#define ICP_HSSACC_RX_DFLT_FRM_PULSE_WIDTH 1
+#define ICP_HSSACC_TX_DFLT_FRM_PULSE_WIDTH 1
+
+/* Enum for the enabled state of a port */
+typedef enum
+{
+ ICP_HSSACC_PORT_UNCONFIGURED = 0 ,
+ ICP_HSSACC_PORT_CONFIGURED,
+ /* config written to memory but not to TDM I/O Unit */
+ ICP_HSSACC_PORT_ENABLED
+ /* config written to TDM I/O Unit, port enabled */
+} icp_hssacc_port_state_t;
+
+/*
+ * Enum for each of the TDM lines on a HSS port
+ */
+typedef enum
+{
+ ICP_HSSACC_LINE_0 = 0,
+ ICP_HSSACC_LINE_1,
+ ICP_HSSACC_LINE_2,
+ ICP_HSSACC_LINE_3,
+ ICP_HSSACC_LINE_DELIMITER
+} icp_hssacc_line_t;
+
+
+/*
+ icp_hssacc_data_rate_t is used to specify the GCI setting of either
+ full line rate or half line rate
+*/
+typedef enum
+ {
+ ICP_HSSACC_DATA_RATE_EQUALS_CLK_RATE = 0,
+ ICP_HSSACC_DATA_RATE_HALF_CLK_RATE,
+ ICP_HSSACC_DATA_RATE_TYPE_DELIMITER
+ } icp_hssacc_data_rate_t;
+
+
+/* list of settings for the Frame Config Register MVIP ON/OFF bit */
+typedef enum
+{
+ ICP_HSSACC_TDM_IO_UNIT_HDMA_FCR_MVIP_SWITCH_OFF = 0,
+ ICP_HSSACC_TDM_IO_UNIT_HDMA_FCR_MVIP_SWITCH_ON,
+ ICP_HSSACC_TDM_IO_UNIT_HDMA_FCR_MVIP_SWITCH_DELIMITER
+} icp_hssacc_hdma_mvip_switch_t;
+
+
+/* list of settings for the Frame Config Register MVIP mode bit */
+typedef enum
+{
+ ICP_HSSACC_TDM_IO_UNIT_HDMA_FCR_MVIP_SETTING_DUAL = 0,
+ ICP_HSSACC_TDM_IO_UNIT_HDMA_FCR_MVIP_SETTING_QUAD,
+ ICP_HSSACC_TDM_IO_UNIT_HDMA_FCR_MVIP_SETTING_DELIMITER
+} icp_hssacc_hdma_mvip_setting_t;
+
+/*
+ icp_hssacc_port_additional_internal_config_t is used to specify the
+ additional port configuration information that is not provided through
+ the HSS I/O Access API
+ */
+typedef struct icp_hssacc_port_additional_internal_config_s
+{
+ icp_hssacc_data_rate_t dataRate;
+ uint32_t frmPulseWidth;
+} icp_hssacc_port_additional_internal_config_t;
+
+/*
+ combines the API provided port configuration data and the
+ internal only configuration
+*/
+typedef struct icp_hssacc_port_full_config_s
+{
+ icp_hssacc_port_config_t cfg; /* Port config from API */
+ icp_hssacc_port_additional_internal_config_t addCfg;
+ /* addtional config params needed internally */
+} icp_hssacc_port_full_config_t;
+
+
+
+/*
+ data structure containing all port registers
+ in the format required by the TDM I/O Unit
+*/
+typedef struct icp_hssacc_hdma_port_config_s
+{
+#ifdef IXP23XX
+ uint32_t tx_LUT[ICP_HSSACC_TDM_IO_UNIT_WORDS_PER_LUT];
+ /* tx LUT for TDM slot assignments */
+ uint32_t rx_LUT[ICP_HSSACC_TDM_IO_UNIT_WORDS_PER_LUT];
+ /* rx LUT for TDM slot assignments */
+#endif
+ uint32_t tx_pcr;
+ uint32_t rx_pcr;
+ uint32_t tx_fcr;
+ uint32_t rx_fcr;
+ uint32_t tx_icr;
+#ifdef IXP23XX
+ uint32_t tx_vcr;
+ uint32_t tx_hcr;
+#endif
+ uint32_t rx_icr;
+#ifdef IXP23XX
+ uint32_t rx_vcr;
+ uint32_t rx_hcr;
+#endif
+ uint32_t clkcr;
+ uint32_t cwr;
+} icp_hssacc_hdma_port_config_t;
+
+
+
+/*
+ internal data structure containing all information
+ related to port configuration
+*/
+typedef struct icp_hssacc_port_internal_config_s
+{
+ icp_hssacc_port_state_t state;
+ icp_hssacc_port_full_config_t rx;
+ icp_hssacc_port_full_config_t tx;
+ icp_hssacc_hdma_port_config_t * hdmaPortCfgTableVirtAddr;
+ /* Virtual address of HDMA port cfg table*/
+ icp_hssacc_clk_speed_t clkSpeed;
+} icp_hssacc_port_internal_config_t;
+
+
+
+/* ----------------------------------------------------------------------------
+ * Function declarations
+ * ----------------------------------------------------------------------------
+ */
+
+/*****************************************************************************
+ * Abstract:
+ * sub-module initialisation function
+ *
+ *****************************************************************************/
+icp_status_t
+HssAccPortConfigInit(void);
+
+
+/*****************************************************************************
+ * Abstract:
+ * sub-module shutdown function.
+ *
+ *****************************************************************************/
+icp_status_t
+HssAccPortConfigShutdown(void);
+
+
+/*****************************************************************************
+ * Abstract:
+ * Check the line, first and last TS position are compatible with the
+ * current port config.
+ *
+ *****************************************************************************/
+icp_status_t
+HssAccPortLineValidCheck (unsigned portId,
+ icp_hssacc_line_t lineId,
+ unsigned firstTsPos,
+ unsigned lastTsPos);
+
+
+
+/*****************************************************************************
+ * Abstract:
+ * Retrieve the current state of the port (configgured/disabled/enabled).
+ *
+ *****************************************************************************/
+icp_hssacc_port_state_t
+HssAccPortStateGet (unsigned portId);
+
+
+
+
+/*****************************************************************************
+ * Abstract:
+ * reset the internal stats of this sub-module
+ *
+ *****************************************************************************/
+void
+HssAccPortConfigStatsReset (void);
+
+
+
+/*****************************************************************************
+ * Abstract:
+ * print out the stats of this sub-module
+ *
+ *****************************************************************************/
+void
+HssAccPortConfigStatsShow (void);
+
+
+
+/*****************************************************************************
+ * Abstract:
+ * check the validity of the specified Tx clk mode depending on
+ * the platform
+ *
+ *****************************************************************************/
+icp_boolean_t
+HssAccPortConfigTxClkModeInvalid(icp_hssacc_clk_mode_t clkMode);
+
+
+
+/*****************************************************************************
+ * Abstract:
+ * check the validity of the specified Rx clk mode depending on
+ * the platform
+ *
+ *****************************************************************************/
+icp_boolean_t
+HssAccPortConfigRxClkModeInvalid(icp_hssacc_clk_mode_t clkMode);
+
+#endif /* ICP_HSSACCPORTCONFIG_H */
diff --git a/Acceleration/library/icp_telephony/tdm_io_access/include/icp_hssacc_port_hdma_reg_mgr.h b/Acceleration/library/icp_telephony/tdm_io_access/include/icp_hssacc_port_hdma_reg_mgr.h
new file mode 100644
index 0000000..0d77dbe
--- /dev/null
+++ b/Acceleration/library/icp_telephony/tdm_io_access/include/icp_hssacc_port_hdma_reg_mgr.h
@@ -0,0 +1,160 @@
+/*******************************************************************************
+ *
+ * @file icp_hssacc_port_hdma_reg_mgr.h
+ *
+ * @description Content of this file is the prototype definitions for the Port
+ * HDMA Register creation module
+ *
+ * @ingroup icp_HssAcc
+ *
+ * @Revision 1.0
+ *
+ * @par
+ * This file is provided under a dual BSD/GPLv2 license. When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * The full GNU General Public License is included in this distribution
+ * in the file called LICENSE.GPL.
+ *
+ * Contact Information:
+ * Intel Corporation
+ *
+ * BSD LICENSE
+ *
+ * Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ *
+ *
+ ******************************************************************************/
+
+#ifndef ICP_HSSACC_PORT_HDMA_REG_MGR_H
+#define ICP_HSSACC_PORT_HDMA_REG_MGR_H
+
+
+#include "icp_hssacc.h"
+
+
+/* icp_hssacc_hdma_reg_trans_t is used to specify register types of Tx or Rx */
+typedef enum
+{
+ ICP_HSSACC_HDMA_RX_REG_TYPE = 0,
+ /* Rx type register for the HSS Port Config registers */
+ ICP_HSSACC_HDMA_TX_REG_TYPE,
+ /* Tx type register for the HSS Port Config registers */
+ ICP_HSSACC_HDMA_REG_TYPE_DELIMITER
+ /* Delimiter for array sizes */
+} icp_hssacc_hdma_reg_trans_t;
+
+
+
+/*****************************************************************************
+ * Abstract:
+ * Create the Port Config Register Value for the TDM I/O Unit.
+ *
+ *****************************************************************************/
+void
+HssAccHdmaMgrPCRCreate (icp_hssacc_hdma_reg_trans_t type,
+ const icp_hssacc_port_full_config_t *portConfig,
+ uint32_t *pcr);
+
+
+
+/*****************************************************************************
+ * Abstract:
+ * Create the Frame Config Register value for the TDM I/O Unit
+ *
+ *****************************************************************************/
+icp_status_t
+HssAccHdmaMgrFCRCreate (icp_hssacc_hdma_reg_trans_t type,
+ icp_hssacc_clk_speed_t clkSpeed,
+ const icp_hssacc_port_full_config_t *portConfig,
+ uint32_t *fcr);
+
+/*****************************************************************************
+ * Abstract:
+ * Create the Image Config Register Value for the TDM I/O Unit.
+ *
+ *****************************************************************************/
+void
+HssAccHdmaMgrICRCreate (icp_hssacc_hdma_reg_trans_t type,
+ unsigned hssPortId,
+ uint32_t *icr);
+
+
+
+/*****************************************************************************
+ * Abstract:
+ * Create the Clock Config Register Value for the TDM I/O Unit.
+ *
+ *****************************************************************************/
+void
+HssAccHdmaMgrClkCRCreate (icp_hssacc_clk_speed_t clkSpeed,
+ uint32_t *clkCR);
+
+
+/*****************************************************************************
+ * Abstract:
+ * Create the Context Wakeup Register for the TDM I/O Unit.
+ *
+ *****************************************************************************/
+void
+HssAccHdmaMgrCWRCreate (icp_hssacc_clk_speed_t clkSpeed,
+ uint32_t *cwr);
+
+
+#ifdef IXP23XX
+/*****************************************************************************
+ * Abstract:
+ * create the Voice Config Regsiter Values for the TDM I/O Unit.
+ *
+ *****************************************************************************/
+void
+HssAccHdmaMgrVCRCreate (uint32_t *vcr);
+#endif
+
+
+#endif /* ICP_HSSACC_PORT_HDMA_REG_MGR_H */
diff --git a/Acceleration/library/icp_telephony/tdm_io_access/include/icp_hssacc_queues_config.h b/Acceleration/library/icp_telephony/tdm_io_access/include/icp_hssacc_queues_config.h
new file mode 100644
index 0000000..936b091
--- /dev/null
+++ b/Acceleration/library/icp_telephony/tdm_io_access/include/icp_hssacc_queues_config.h
@@ -0,0 +1,275 @@
+/*******************************************************************************
+ *
+ * @file icp_hssacc_queues_config.h
+ *
+ * @description Content of this file is the prototype defintions and data
+ * structure definitions for the Queue configuration module
+ *
+ * @ingroup icp_HssAcc
+ *
+ * @Revision 1.0
+ *
+ * @par
+ * This file is provided under a dual BSD/GPLv2 license. When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * The full GNU General Public License is included in this distribution
+ * in the file called LICENSE.GPL.
+ *
+ * Contact Information:
+ * Intel Corporation
+ *
+ * BSD LICENSE
+ *
+ * Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ *
+ *
+ ******************************************************************************/
+#ifndef ICP_HSSACCQUEUESCONFIG_H
+#define ICP_HSSACCQUEUESCONFIG_H
+
+#include "IxQMgr.h"
+#include "icp_hssacc_common.h"
+#define ICP_HSSACC_RX_QUEUE_ENTRY_SIZE_IN_WORDS (1)
+#define ICP_HSSACC_RX_QUEUE_ENTRY_SIZE_IN_BYTES \
+ (ICP_HSSACC_RX_QUEUE_ENTRY_SIZE_IN_WORDS * \
+ ICP_HSSACC_WORD_SIZE)
+
+/* The size of the queue descriptor. This is common to all queues */
+#define ICP_HSSACC_QUEUE_DESC_SIZE_IN_WORDS (4)
+#define ICP_HSSACC_QUEUE_DESC_SIZE_IN_BYTES \
+ (ICP_HSSACC_QUEUE_DESC_SIZE_IN_WORDS * \
+ ICP_HSSACC_WORD_SIZE)
+
+/*
+ * HssAcc transmit queue settings
+ */
+
+#define ICP_HSSACC_TX_QUEUE_DEPTH_POW_2 (7)
+#define ICP_HSSACC_TX_QUEUE_DEPTH (1 << ICP_HSSACC_TX_QUEUE_DEPTH_POW_2)
+
+#define ICP_HSSACC_HDLC_TX_QUEUE_DEPTH_POW_2 (ICP_HSSACC_TX_QUEUE_DEPTH_POW_2)
+#define ICP_HSSACC_HDLC_TX_QUEUE_DEPTH (ICP_HSSACC_TX_QUEUE_DEPTH)
+
+#define ICP_HSSACC_VOICE_TX_QUEUE_DEPTH_POW_2 (4)
+#define ICP_HSSACC_VOICE_TX_QUEUE_DEPTH \
+ (1 << ICP_HSSACC_VOICE_TX_QUEUE_DEPTH_POW_2)
+
+/* The maximum number of bytes required to accomodate one TX queue */
+#define ICP_HSSACC_TX_QUEUE_SIZE_IN_BYTES \
+ ((ICP_HSSACC_TX_QUEUE_DEPTH) * \
+ ICP_HSSACC_QUEUE_DESC_SIZE_IN_BYTES )
+
+
+/*
+ * HssAcc HDLC receive queue settings
+ */
+/* The depth of the HDLC RX queue */
+#define ICP_HSSACC_HDLC_RX_QUEUE_DEPTH_POW_2 (11)
+#define ICP_HSSACC_HDLC_RX_QUEUE_DEPTH \
+ (1 << ICP_HSSACC_HDLC_RX_QUEUE_DEPTH_POW_2)
+
+/* The total number of bytes required to accomodate the HDLC RX queue */
+#define ICP_HSSACC_HDLC_RX_QUEUE_SIZE_IN_BYTES \
+ ((ICP_HSSACC_HDLC_RX_QUEUE_DEPTH) * \
+ ICP_HSSACC_RX_QUEUE_ENTRY_SIZE_IN_BYTES )
+
+
+/*
+ * HssAcc HDLC receive free queue settings
+ */
+/* The depth of the HDLC RX free queue 2048*/
+#define ICP_HSSACC_HDLC_RX_FREE_QUEUE_DEPTH_POW_2 \
+ (ICP_HSSACC_HDLC_RX_QUEUE_DEPTH_POW_2)
+
+#define ICP_HSSACC_HDLC_RX_FREE_QUEUE_DEPTH \
+ (1 << ICP_HSSACC_HDLC_RX_FREE_QUEUE_DEPTH_POW_2)
+
+/* The total number of bytes required to accomodate the HDLC RX free queue */
+#define ICP_HSSACC_HDLC_RX_FREE_QUEUE_SIZE_IN_BYTES \
+ ((ICP_HSSACC_HDLC_RX_FREE_QUEUE_DEPTH) * \
+ ICP_HSSACC_QUEUE_DESC_SIZE_IN_BYTES )
+
+
+/*
+ * HssAcc Voice receive queue settings
+ */
+/* The depth of the voice RX queue */
+#define ICP_HSSACC_VOICE_RX_QUEUE_DEPTH_POW_2 (11)
+#define ICP_HSSACC_VOICE_RX_QUEUE_DEPTH \
+ (1 << ICP_HSSACC_VOICE_RX_QUEUE_DEPTH_POW_2)
+
+/* The total number of bytes required to accomodate the voice RX queue */
+#define ICP_HSSACC_VOICE_RX_QUEUE_SIZE_IN_BYTES \
+ ((ICP_HSSACC_VOICE_RX_QUEUE_DEPTH) * \
+ ICP_HSSACC_RX_QUEUE_ENTRY_SIZE_IN_BYTES )
+
+
+/*
+ * HssAcc Voice receive free queue settings
+ */
+/* The depth of the voice RX free queue, as a power of 2 */
+#define ICP_HSSACC_VOICE_RX_FREE_QUEUE_DEPTH_POW_2 \
+ (ICP_HSSACC_VOICE_RX_QUEUE_DEPTH_POW_2)
+
+#define ICP_HSSACC_VOICE_RX_FREE_QUEUE_DEPTH \
+ (1 << ICP_HSSACC_VOICE_RX_FREE_QUEUE_DEPTH_POW_2)
+
+/* The total number of bytes required to accomodate the voice RX free queue */
+#define ICP_HSSACC_VOICE_RX_FREE_QUEUE_SIZE_IN_BYTES \
+ ((ICP_HSSACC_VOICE_RX_FREE_QUEUE_DEPTH) * \
+ ICP_HSSACC_QUEUE_DESC_SIZE_IN_BYTES )
+
+
+/*
+ List of IDs for Receive Queues used with the TDM I/O Unit
+*/
+
+typedef enum icp_hssacc_receive_queues_e
+ {
+ ICP_HSSACC_VOICE_RX_Q = ICP_HSSACC_MAX_NUM_CHANNELS,
+ ICP_HSSACC_VOICE_RX_FREE_Q,
+ ICP_HSSACC_HDLC_RX_Q,
+ ICP_HSSACC_HDLC_RX_FREE_Q
+ } icp_hssacc_receive_queues_t;
+
+
+#define ICP_HSSACC_NUM_RECEIVE_QS (4)
+
+
+
+/* Stats */
+typedef struct icp_hssacc_queues_config_stats_s
+{
+ icp_hssacc_msg_with_resp_stats_t txQCfg;
+ icp_hssacc_msg_with_resp_stats_t txChanQAddrCfg;
+ icp_hssacc_msg_with_resp_stats_t hdlcRxQCfg;
+ icp_hssacc_msg_with_resp_stats_t voiceRxQCfg;
+ icp_hssacc_msg_with_resp_stats_t txQHeadCfg;
+ icp_hssacc_msg_with_resp_stats_t txQTailCfg;
+ icp_hssacc_msg_with_resp_stats_t voiceRxQReaderCfg;
+ icp_hssacc_msg_with_resp_stats_t voiceRxQWriterCfg;
+ icp_hssacc_msg_with_resp_stats_t hdlcRxQReaderCfg;
+ icp_hssacc_msg_with_resp_stats_t hdlcRxQWriterCfg;
+} icp_hssacc_queues_config_stats_t;
+
+
+
+/* ----------------------------------------------------------------------------
+ * Function declarations
+ * ----------------------------------------------------------------------------
+ */
+/*****************************************************************************
+ * Abstract:
+ * Initialise all the queues used between the access layer and the
+ * TDM I/O Unit
+ *
+ *****************************************************************************/
+icp_status_t
+HssAccQueuesInit(void);
+
+
+/*****************************************************************************
+ * Abstract:
+ * shutdown all the queues used between the access layer and the
+ * TDM I/O Unit
+ *
+ *****************************************************************************/
+icp_status_t
+HssAccQueuesShutdown(void);
+
+
+/*****************************************************************************
+ * Abstract:
+ * Voice and HDLC channels use queues of different sizes so when a
+ * channel gets allocated for a specific service we need to make sure
+ * the size is correct and up to date.
+ *
+ *****************************************************************************/
+icp_status_t
+HssAccQueueConfigQSizeUpdate(uint32_t channelId,
+ icp_hssacc_channel_type_t type);
+
+
+/*****************************************************************************
+ * Abstract:
+ * Reset this modules stats.
+ *
+ *****************************************************************************/
+void
+HssAccQueuesConfigStatsReset (void);
+
+
+/*****************************************************************************
+ * Abstract:
+ * Display all the stats inherent to this module.
+ *
+ *****************************************************************************/
+void
+HssAccQueuesConfigStatsShow (void);
+
+
+/*****************************************************************************
+ * Abstract:
+ * Retrieve the QMgr queue Id using the internal ID (channel number for
+ * Tx or rx queue ID)
+ *
+ *****************************************************************************/
+IxQMgrQId
+HssAccQueueIdGet (uint32_t qIndexId);
+
+/*****************************************************************************
+ * Abstract:
+ * enables the callbacks within the QMgr component.
+ *
+ *****************************************************************************/
+icp_status_t
+HssAccRxQueuesNotificationEnable(void);
+
+
+#endif /* ICP_HSSACCQUEUESCONFIG_H */
diff --git a/Acceleration/library/icp_telephony/tdm_io_access/include/icp_hssacc_rings.h b/Acceleration/library/icp_telephony/tdm_io_access/include/icp_hssacc_rings.h
new file mode 100644
index 0000000..c272757
--- /dev/null
+++ b/Acceleration/library/icp_telephony/tdm_io_access/include/icp_hssacc_rings.h
@@ -0,0 +1,170 @@
+/******************************************************************************
+ * @file icp_hssacc_rings.h
+ *
+ * @description Content of the file provides Ring creation and manipulation
+ * functionality
+ *
+ * @ingroup icp_HssAcc
+ *
+ * @Revision 1.0
+ *
+ * @par
+ * This file is provided under a dual BSD/GPLv2 license. When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * The full GNU General Public License is included in this distribution
+ * in the file called LICENSE.GPL.
+ *
+ * Contact Information:
+ * Intel Corporation
+ *
+ * BSD LICENSE
+ *
+ * Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ *
+ *****************************************************************************/
+
+#ifndef ICP_HSSACC_RINGS_H
+#define ICP_HSSACC_RINGS_H
+
+/* Tx & Rx s/w ring routines */
+typedef struct icp_hssacc_dataplane_ring_s
+{
+ volatile uint32_t *content;
+ uint32_t size;
+ uint32_t mask;
+ volatile uint32_t tail;
+ volatile uint32_t head;
+} icp_hssacc_dataplane_ring_t;
+
+/**
+ * @def IX_HSSACC_DATAPLANE_RING_ENTRY_ADD
+ * @brief puts an entry at the head of the sw ring and increments head
+ * counter
+ */
+#define ICP_HSSACC_DATAPLANE_RING_ENTRY_ADD(ring,entry) do { \
+ icp_hssacc_dataplane_ring_t *pRing = &(ring); \
+ pRing->content[pRing->head & pRing->mask] = ((uint32_t)(entry)); \
+ pRing->head++; \
+ } while (0)
+
+/**
+ * @def ICP_HSSACC_DATAPLANE_RING_ENTRY_REM
+ * @brief gets an entry from the tail of the sw ring and decrements tail
+ * counter
+ */
+#define ICP_HSSACC_DATAPLANE_RING_ENTRY_REM(ring,entry) do { \
+ icp_hssacc_dataplane_ring_t *pRing = &(ring); \
+ entry = pRing->content[pRing->tail & pRing->mask]; \
+ pRing->tail++; \
+ } while (0)
+
+/**
+ * @def ICP_HSSACC_DATAPLANE_RING_TAIL_ENTRY_GET
+ * @brief Get the entry at the tail of a sw Ring
+ */
+#define ICP_HSSACC_DATAPLANE_RING_TAIL_ENTRY_GET(ring) \
+ (ring).content[ICP_HSSACC_DATAPLANE_RING_TAIL(ring)]
+
+/**
+ * @def ICP_HSSACC_DATAPLANE_RING_TAIL
+ * @brief Get the Tail pointer of a ring
+ */
+#define ICP_HSSACC_DATAPLANE_RING_TAIL(ring) \
+ ((ring).tail & (ring).mask)
+
+/**
+ * @def ICP_HSSACC_DATAPLANE_RING_TAIL_INCR
+ * @brief Increment the Tail pointer of a ring
+ */
+#define ICP_HSSACC_DATAPLANE_RING_TAIL_INCR(ring) (ring).tail++
+
+/**
+ * @def ICP_HSSACC_DATAPLANE_RING_HEAD_ENTRY_GET
+ * @brief Get the entry at the head of a sw ring
+ */
+#define ICP_HSSACC_DATAPLANE_RING_HEAD_ENTRY_GET(ring) \
+ (ring).content[ICP_HSSACC_DATAPLANE_RING_HEAD(ring)]
+
+/**
+ * @def ICP_HSSACC_DATAPLANE_RING_HEAD
+ * @brief Get the Head pointer of a sw ring
+ */
+#define ICP_HSSACC_DATAPLANE_RING_HEAD(ring) \
+ ((ring).head & (ring).mask)
+
+/**
+ * @def ICP_HSSACC_DATAPLANE_RING_HEAD_INCR
+ * @brief Increment the Head pointer of a sw ring
+ */
+#define ICP_HSSACC_DATAPLANE_RING_HEAD_INCR(ring) do { \
+ (ring).head++; } while(0)
+
+/**
+ * @def ICP_HSSACC_DATAPLANE_RING_NUM_ENTRIES_GET
+ * @brief gets the number of entries currently in the sw ring
+ */
+#define ICP_HSSACC_DATAPLANE_RING_NUM_ENTRIES_GET(ring) \
+ ((ring).head - (ring).tail)
+
+/**
+ * @def ICP_HSSACC_DATAPLANE_RING_FULL
+ * @brief tests whether the sw ring is full
+ */
+#define ICP_HSSACC_DATAPLANE_RING_FULL(ring) \
+ (((ring).head - (ring).tail) == (ring).size)
+
+/**
+ * @def ICP_HSSACC_DATAPLANE_RING_EMPTY
+ * @brief tests whether the sw ring is empty
+ */
+#define ICP_HSSACC_DATAPLANE_RING_EMPTY(ring) \
+ ((ring).head == (ring).tail)
+
+
+#endif
diff --git a/Acceleration/library/icp_telephony/tdm_io_access/include/icp_hssacc_rx_datapath.h b/Acceleration/library/icp_telephony/tdm_io_access/include/icp_hssacc_rx_datapath.h
new file mode 100644
index 0000000..62d18d3
--- /dev/null
+++ b/Acceleration/library/icp_telephony/tdm_io_access/include/icp_hssacc_rx_datapath.h
@@ -0,0 +1,216 @@
+/******************************************************************************
+ * @file icp_hssacc_rx_datapath.h
+ *
+ * @description Content of this file provides the function prototypes for the
+ * HSS I/O Access receive functionality
+ *
+ * @ingroup icp_HssAcc
+ *
+ * @Revision 1.0
+ *
+ * @par
+ * This file is provided under a dual BSD/GPLv2 license. When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * The full GNU General Public License is included in this distribution
+ * in the file called LICENSE.GPL.
+ *
+ * Contact Information:
+ * Intel Corporation
+ *
+ * BSD LICENSE
+ *
+ * Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ *
+ *****************************************************************************/
+
+#ifndef ICP_HSSACC_RX_DP_H
+#define ICP_HSSACC_RX_DP_H
+
+#include "IxOsal.h"
+#include "icp.h"
+#include "icp_hssacc.h"
+#include "IxQMgr.h"
+
+#define ICP_HSSACC_RX_DP_CHAN_DESC_PTR_RING_SZ (256)
+
+/* Definition of watermark level for pre-emptive Voice traffic flow regulation,
+ this watermark is tuned following performance testing, at this point
+it is assumed that flow regulation should begin early to prevent Speech latency
+build-up. */
+#define ICP_HSSACC_RX_Q_WATERMARK_LEVEL (2)
+
+
+void
+HssAccRxQServiceCallback(IxQMgrQId qId,
+ IxQMgrCallbackId cbId);
+
+/******************************************************************************
+ * Abstract:
+ * Initialise Rx datapath global variables
+ *
+ ******************************************************************************/
+icp_status_t
+HssAccRxDatapathInit(void);
+
+/******************************************************************************
+ * Abstract:
+ * Shut down Rx datapath Module.
+ *
+ *****************************************************************************/
+icp_status_t
+HssAccRxDatapathShutdown(void);
+
+
+/******************************************************************************
+ * Abstract:
+ * Register rx callback and user context
+ *
+ ******************************************************************************/
+void
+HssAccChannelRxCallbackRegister(uint32_t channelId,
+ icp_hssacc_rx_callback_t rxCallback,
+ icp_user_context_t userContext);
+
+/******************************************************************************
+ * Abstract:
+ * Deregister rx callback and user context
+ *
+ ******************************************************************************/
+void
+HssAccChannelRxCallbackDeregister(uint32_t channelId);
+
+/******************************************************************************
+ * Abstract:
+ * Set max frame size for HDLC, must be done at init
+ *
+ *****************************************************************************/
+void
+HssAccRxDatapathHdlcInit(uint32_t maxRxFrameSize);
+
+/******************************************************************************
+ * Abstract:
+ * Set max frame size for voice, must be done at init
+ *
+ *****************************************************************************/
+void
+HssAccRxDatapathVoiceInit(uint32_t maxRxFrameSize);
+
+/******************************************************************************
+ * Abstract:
+ * Function to run the Q Mgr processing function and call
+ * associated callbacks
+ *
+ ******************************************************************************/
+icp_status_t
+HssAccRxDatapathService(icp_hssacc_channel_type_t channelType);
+
+
+
+/******************************************************************************
+ * Abstract:
+ * Retrieve all buffers in an Rx Free Queue if there are no initialized
+ * channels for the corresponding service
+ *
+ *****************************************************************************/
+icp_status_t
+HssAccRxFreeQsBufsRetrieve(IX_OSAL_MBUF * * ppStartChainBuffer,
+ IX_OSAL_MBUF * * ppEndChainBuffer);
+
+/******************************************************************************
+ * Abstract:
+ * Retrieve all buffers in a chain from Rx Ring for a specified channel
+ *
+ *****************************************************************************/
+icp_status_t
+HssAccRxDatapathChanBufsRetrieve(uint32_t channelId,
+ IX_OSAL_MBUF * * startChainBuffer,
+ IX_OSAL_MBUF * * endChainBuffer);
+
+/******************************************************************************
+ * Abstract:
+ * Print out the per-channel statistics
+ *
+ ******************************************************************************/
+void
+HssAccRxDatapathChanStatsShow(uint32_t channelId);
+
+
+/******************************************************************************
+ * Abstract:
+ * Function to print out stats on replenishing
+ *
+ ******************************************************************************/
+void
+HssAccRxDatapathReplenishStatsShow(icp_hssacc_channel_type_t serviceType);
+
+/******************************************************************************
+ * Abstract:
+ * Reset the per-channel statistics
+ ******************************************************************************/
+void
+HssAccRxDatapathChanStatsReset(uint32_t channelId);
+
+
+/******************************************************************************
+ * Abstract:
+ * Function to reset stats on replenishing
+ *
+ *****************************************************************************/
+void
+HssAccRxDatapathReplenishStatsReset(icp_hssacc_channel_type_t serviceType);
+
+
+/******************************************************************************
+ * Abstract:
+ * Return the Max Rx Sample/Frame size configured for the specified Service
+ *
+ *****************************************************************************/
+uint32_t
+HssAccRxDatapathMaxServiceFrameSizeGet(icp_hssacc_channel_type_t servType);
+#endif
diff --git a/Acceleration/library/icp_telephony/tdm_io_access/include/icp_hssacc_tdm_io_queue_entry.h b/Acceleration/library/icp_telephony/tdm_io_access/include/icp_hssacc_tdm_io_queue_entry.h
new file mode 100644
index 0000000..a6a286a
--- /dev/null
+++ b/Acceleration/library/icp_telephony/tdm_io_access/include/icp_hssacc_tdm_io_queue_entry.h
@@ -0,0 +1,193 @@
+/******************************************************************************
+ * @file icp_hssacc_tdm_io_queue_entry.h
+ *
+ * @description Content of this file contains the definition and access
+ * macros for the TDM I/O Queue Entry format
+ *
+ * @ingroup icp_HssAcc
+ *
+ * @Revision 1.0
+ *
+ * @par
+ * This file is provided under a dual BSD/GPLv2 license. When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * The full GNU General Public License is included in this distribution
+ * in the file called LICENSE.GPL.
+ *
+ * Contact Information:
+ * Intel Corporation
+ *
+ * BSD LICENSE
+ *
+ * Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ *
+ *
+ *****************************************************************************/
+
+#ifndef ICP_HSSACC_TDM_IO_QUEUE_ENTRY_H
+#define ICP_HSSACC_TDM_IO_QUEUE_ENTRY_H
+
+
+/*****************************************************************************
+ * Definition of the Channel descriptor format
+ *
+ *****************************************************************************/
+typedef struct icp_hssacc_chan_desc_s
+{
+ /* In order to handle both Little and Big Endianness correctly,
+ this data struct contains the Length split into MSB and LSB fields. */
+ uint8_t currBufLength_LSB;
+ uint8_t currBufLength_MSB;
+ uint8_t status;
+ uint8_t channelId;
+} icp_hssacc_chan_desc_t;
+
+/*****************************************************************************
+ * Definition of the Queue Entry format for Tx and RxFree Queues
+ *
+ *****************************************************************************/
+typedef struct icp_hssacc_tdm_io_queue_entry_s
+{
+ /* this union allows us to manipulate and move around the entire data
+ struct as a single word,thus saving instructions for copies */
+ union {
+ icp_hssacc_chan_desc_t strct;
+ uint32_t word;
+ } descriptor;
+ void * currBufData;
+ uint32_t packetLengthBytes;
+ IX_OSAL_MBUF * currBuf;
+} icp_hssacc_tdm_io_queue_entry_t;
+
+
+
+
+/*****************************************************************************
+ * Definition of the TDM I/O private section of the OSAL Buffer
+ *
+ *****************************************************************************/
+typedef struct icp_hssacc_osal_mbuf_tdm_io_section_s
+{
+ icp_hssacc_tdm_io_queue_entry_t tdm_io_entry;
+ IX_OSAL_MBUF * pNextBuf;
+ uint32_t reserved[3];
+} icp_hssacc_osal_mbuf_tdm_io_section_t;
+
+
+
+/*****************************************************************************
+ * Macros for accessing the different fields of a Queue Entry
+ *
+ *****************************************************************************/
+
+#define ICP_TDM_IO_Q_ENTRY_CHANNEL_ID(entryPtr) \
+ ((entryPtr)->descriptor.strct.channelId)
+
+#define ICP_TDM_IO_Q_ENTRY_STATUS(entryPtr) (entryPtr->descriptor.strct.status)
+
+#define ICP_TDM_IO_Q_ENTRY_CURR_BUF_LEN_MSB(entryPtr) \
+ ((entryPtr)->descriptor.strct.currBufLength_MSB)
+
+#define ICP_TDM_IO_Q_ENTRY_CURR_BUF_LEN_LSB(entryPtr) \
+ ((entryPtr)->descriptor.strct.currBufLength_LSB)
+
+#define ICP_TDM_IO_Q_ENTRY_DATA(entryPtr) ((entryPtr)->currBufData)
+
+#define ICP_TDM_IO_Q_ENTRY_PKT_LEN(entryPtr) ((entryPtr)->packetLengthBytes)
+
+#define ICP_TDM_IO_Q_ENTRY_OSAL_MBUF(entryPtr) ((entryPtr)->currBuf)
+
+
+
+/*****************************************************************************
+ * Macros for accessing the different fields of the TDM I/O Unit private section
+ * of the OSAL Buffer
+ *
+ *****************************************************************************/
+
+#define ICP_OSAL_MBUF_TDM_SECT_CHANNEL_ID(mbufPtr) \
+ (ICP_TDM_IO_Q_ENTRY_CHANNEL_ID((&((mbufPtr)->tdm_io_entry))))
+
+#define ICP_OSAL_MBUF_TDM_SECT_STATUS(mbufPtr) \
+ (ICP_TDM_IO_Q_ENTRY_STATUS((&((mbufPtr)->tdm_io_entry))))
+
+#define ICP_OSAL_MBUF_TDM_SECT_CURR_BUF_LEN_MSB(mbufPtr) \
+ (ICP_TDM_IO_Q_ENTRY_CURR_BUF_LEN_MSB((&((mbufPtr)->tdm_io_entry))))
+
+#define ICP_OSAL_MBUF_TDM_SECT_CURR_BUF_LEN_LSB(mbufPtr) \
+ (ICP_TDM_IO_Q_ENTRY_CURR_BUF_LEN_LSB((&((mbufPtr)->tdm_io_entry))))
+
+#define ICP_OSAL_MBUF_TDM_SECT_DATA(mbufPtr) \
+ (ICP_TDM_IO_Q_ENTRY_DATA((&((mbufPtr)->tdm_io_entry))))
+
+#define ICP_OSAL_MBUF_TDM_SECT_PKT_LEN(mbufPtr) \
+ (ICP_TDM_IO_Q_ENTRY_PKT_LEN((&((mbufPtr)->tdm_io_entry))))
+
+#define ICP_OSAL_MBUF_TDM_SECT_NEXT_BUF(mbufPtr) \
+ ((mbufPtr)->pNextBuf)
+
+#define ICP_OSAL_MBUF_TDM_SECT_OSAL_MBUF_START(mbufPtr) \
+ (ICP_TDM_IO_Q_ENTRY_OSAL_MBUF((&((mbufPtr)->tdm_io_entry))))
+
+
+/*****************************************************************************
+ * Macros for handling the Packet Length field. these are used to manipulate
+ * the endianness of the field.
+ *
+ *****************************************************************************/
+#define ICP_OSAL_MBUF_TDM_SECT_LEN_MASK 0xFF
+#define ICP_OSAL_MBUF_TDM_SECT_LEN_MSB_OFFSET 8
+
+/* These macros will return as a byte number the MSB and LSB
+ respectively of a 2 byte packet length field */
+#define ICP_OSAL_MBUF_PKT_LEN_MSB(len) ((len >> ICP_OSAL_MBUF_TDM_SECT_LEN_MSB_OFFSET) & ICP_OSAL_MBUF_TDM_SECT_LEN_MASK)
+
+#define ICP_OSAL_MBUF_PKT_LEN_LSB(len) (len & ICP_OSAL_MBUF_TDM_SECT_LEN_MASK)
+
+#endif
diff --git a/Acceleration/library/icp_telephony/tdm_io_access/include/icp_hssacc_timeslot_allocation.h b/Acceleration/library/icp_telephony/tdm_io_access/include/icp_hssacc_timeslot_allocation.h
new file mode 100644
index 0000000..815e289
--- /dev/null
+++ b/Acceleration/library/icp_telephony/tdm_io_access/include/icp_hssacc_timeslot_allocation.h
@@ -0,0 +1,260 @@
+/*******************************************************************************
+ *
+ * @file icp_hssacc_timeslot_allocation.h
+ *
+ * @description Content of this file provides the main internal API for the
+ * timeslot allocation module used as part of channel Allocation and Deletion
+ *
+ * @ingroup icp_HssAcc
+ *
+ * @Revision 1.0
+ *
+ * @par
+ * This file is provided under a dual BSD/GPLv2 license. When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * The full GNU General Public License is included in this distribution
+ * in the file called LICENSE.GPL.
+ *
+ * Contact Information:
+ * Intel Corporation
+ *
+ * BSD LICENSE
+ *
+ * Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ *
+ *
+ ******************************************************************************/
+
+#ifndef ICP_HSSACC_TIMESLOT_ALLOCATION_H
+#define ICP_HSSACC_TIMESLOT_ALLOCATION_H
+
+
+
+#include "icp_hssacc_channel_config.h"
+
+
+/*****************************************************************************
+ * Abstract
+ * Platform specific initialisation for this sub-module.
+ *
+ *****************************************************************************/
+icp_status_t HssAccTsAllocPlatformInit (void);
+
+
+
+/*****************************************************************************
+ * Abstract
+ * Initialisation of the sub-module.
+ *
+ *****************************************************************************/
+icp_status_t HssAccTsAllocInit (void);
+
+
+/*****************************************************************************
+ * Abstract
+ * Shutdown this sub-module.
+ *
+ *****************************************************************************/
+void HssAccTsAllocShutdown (void);
+
+/*****************************************************************************
+ * Abstract
+ * Remove the allocation of timeslots associated with the specified
+ * channel.
+ *
+ *****************************************************************************/
+icp_status_t
+HssAccTsAllocDelete (unsigned channelId,
+ icp_hssacc_channel_config_t * hssChannelData);
+
+
+/*****************************************************************************
+ * Abstract
+ * Update the Timeslot provisioning table for the specified port. will
+ * also update the offset table for all ports.
+ *
+ *****************************************************************************/
+icp_status_t
+HssAccTsAllocUpdate(unsigned portId,
+ const icp_hssacc_channel_config_t * hssChannelData);
+
+
+/*****************************************************************************
+ * Abstract
+ * Setup an initial Timeslot allocation for correct behaviour of the
+ * specified port with no channels configured on it.
+ *
+ *****************************************************************************/
+icp_status_t
+HssAccTsAllocInitialAllocationUpdate(unsigned portId);
+
+
+
+
+#ifdef IXP23XX
+/*****************************************************************************
+ * Abstract
+ * Create the Timeslot Look-up Table for the TDM I/O unit.
+ *
+ *****************************************************************************/
+icp_status_t
+HssAccTxAllocLUTCreate (icp_hssacc_clk_speed_t clkSpeed,
+ uint32_t *pHssLUT);
+#endif
+
+/*****************************************************************************
+ * Abstract
+ * Swap the Timeslot provisioning tables within the TDM I/O Unit.
+ *
+ *****************************************************************************/
+icp_status_t HssAccTsAllocTableSwap (unsigned hssPortId);
+
+
+
+
+/*****************************************************************************
+ * Abstract
+ * returns the address of the Memory block allocated for the
+ * Timeslot provisioning Table.
+ *
+ *****************************************************************************/
+void * HssAccTsAllocHdmaProvTableVirtAddrGet (void);
+
+
+/*****************************************************************************
+ * Abstract
+ * Returns the address of the memory block allocated for the timeslot
+ * offset table.
+ *
+ *****************************************************************************/
+void * HssAccTsAllocTdmIoUnitOffsetTableVirtAddrGet (void);
+
+
+/*****************************************************************************
+ * Abstract
+ * Return a pointer to the stats for Swap message.
+ *
+ *****************************************************************************/
+icp_hssacc_msg_with_resp_stats_t * HssAccTsAllocSwapStatsGet(void);
+
+
+/*****************************************************************************
+ * Abstract
+ * return a pointer to the stats for the Offset Table read message.
+ *
+ *****************************************************************************/
+icp_hssacc_msg_with_resp_stats_t * HssAccTsAllocOffsetTableReadStatsGet(void);
+
+
+
+/*****************************************************************************
+ * Abstract
+ * Read one word of the specified table.
+ *
+ *****************************************************************************/
+icp_status_t
+HssAccTsAllocOffsetTableWordRead (icp_boolean_t readShadowTable,
+ uint16_t tableOffset,
+ uint32_t *tableWord);
+
+
+
+
+/*****************************************************************************
+ * Abstract:
+ * Verify that all of the timeslots requested are not already in use.
+ *
+ *****************************************************************************/
+icp_boolean_t
+HssAccTsAvailableVerify(unsigned portId, icp_hssacc_line_t lineId,
+ uint32_t tsMap);
+
+
+
+/*****************************************************************************
+ * Abstract:
+ * Register the timeslots specified for the specified channel.
+ *
+ *****************************************************************************/
+void
+HssAccTsRegister(unsigned channelId,
+ unsigned portId,
+ icp_hssacc_line_t lineId,
+ uint32_t tsMap);
+
+
+/*****************************************************************************
+ * Abstract:
+ * Unregister any timeslots associated with the specified channel.
+ *
+ *****************************************************************************/
+void
+HssAccTsUnregister(unsigned portId,
+ icp_hssacc_line_t lineId,
+ uint32_t tsMap);
+
+/*****************************************************************************
+ * Abstract
+ * Display all the stats collecting within this module.
+ *
+ *****************************************************************************/
+void HssAccTsAllocStatsShow (void);
+
+
+/*****************************************************************************
+ * Abstract
+ * Reset The stats for the Timeslot allocation module.
+ *
+ *****************************************************************************/
+void HssAccTsAllocStatsReset (void);
+
+
+
+
+#endif /* #ifndef ICP_HSSACC_TIMESLOT_ALLOCATION_H */
diff --git a/Acceleration/library/icp_telephony/tdm_io_access/include/icp_hssacc_trace.h b/Acceleration/library/icp_telephony/tdm_io_access/include/icp_hssacc_trace.h
new file mode 100644
index 0000000..703f6e2
--- /dev/null
+++ b/Acceleration/library/icp_telephony/tdm_io_access/include/icp_hssacc_trace.h
@@ -0,0 +1,339 @@
+/*******************************************************************************
+ *
+ * @file icp_hssacc_trace.h
+ *
+ * @description Content of this file provides Trace functionality for the
+ * component
+ *
+ * @ingroup icp_HssAcc
+ *
+ * @Revision 1.0
+ *
+ * @par
+ * This file is provided under a dual BSD/GPLv2 license. When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * The full GNU General Public License is included in this distribution
+ * in the file called LICENSE.GPL.
+ *
+ * Contact Information:
+ * Intel Corporation
+ *
+ * BSD LICENSE
+ *
+ * Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ *
+ *
+ ******************************************************************************/
+
+
+#ifndef ICP_HSSACC_TRACE_H
+#define ICP_HSSACC_TRACE_H
+
+
+/* ----------------------------------------------------------------------------
+ * Includes
+ * ----------------------------------------------------------------------------
+ */
+#include "IxOsal.h"
+
+
+/*
+ * ----------------------------------------------------------------------------
+ * Enumerated types
+ * ----------------------------------------------------------------------------
+ */
+
+/*****************************************************************************
+ * Enumeration defining HssAcc trace levels.
+ *****************************************************************************/
+typedef enum icp_hssacc_trace_level_e
+{
+ ICP_HSSACC_TRACE_OFF = 0, /**< NO TRACE */
+ ICP_HSSACC_DEBUG = 1, /**< Select traces of interest */
+ ICP_HSSACC_FN_ENTRY_EXIT = 2 /**< ALL function entry/exit traces
+ and all traces of interest */
+} icp_hssacc_trace_level_t;
+
+
+/* ----------------------------------------------------------------------------
+ * Defines and Macros.
+ * ----------------------------------------------------------------------------
+ */
+
+/*****************************************************************************
+ * The trace level for the HSS Acc Control path and Datapath blocks
+ *
+ * Description:
+ * This macro turns the debug trace on or off, depending on whether the
+ * code is compiled for debug or release.
+ * There are 3 levels allowed in the current compilation setup:
+ * if NDEBUG is not defined and DEBUG is not defined, then selected tracing
+ * will be done for the control path and the datapath tracing will be off.
+ * if NDEBUG is not defined and DEBUG is defined then all function
+ * entry/exits are on as well selected tracing for control and data paths.
+ * if NDEBUG is defined ALL tracing is off.
+ *
+ *****************************************************************************/
+
+#ifdef DEBUG
+#define ICP_HSSACC_TRACE_LEVEL ICP_HSSACC_FN_ENTRY_EXIT
+#define ICP_HSSACC_DP_TRACE_LEVEL ICP_HSSACC_FN_ENTRY_EXIT
+#else
+#define ICP_HSSACC_TRACE_LEVEL ICP_HSSACC_TRACE_OFF
+#define ICP_HSSACC_DP_TRACE_LEVEL ICP_HSSACC_TRACE_OFF
+#endif
+
+
+
+
+
+/*****************************************************************************
+ * Mechanism for reporting HssAcc software errors
+ *
+ *****************************************************************************/
+#define ICP_HSSACC_REPORT_ERROR(STR) \
+ ixOsalLog (IX_OSAL_LOG_LVL_ERROR, \
+ IX_OSAL_LOG_DEV_STDERR, \
+ STR, 0, 0, 0, 0, 0, 0);
+
+/*****************************************************************************
+ * Mechanism for reporting HssAcc software errors with 1 argument
+ *
+ *****************************************************************************/
+#define ICP_HSSACC_REPORT_ERROR_1(STR,ARG1) \
+ ixOsalLog (IX_OSAL_LOG_LVL_ERROR, \
+ IX_OSAL_LOG_DEV_STDERR, \
+ STR, ARG1, 0, 0, 0, 0, 0);
+
+/*****************************************************************************
+ * Mechanism for reporting HssAcc software errors with 2 arguments
+ *
+ *****************************************************************************/
+#define ICP_HSSACC_REPORT_ERROR_2(STR,ARG1,ARG2) \
+ ixOsalLog (IX_OSAL_LOG_LVL_ERROR, \
+ IX_OSAL_LOG_DEV_STDERR, \
+ STR, ARG1, ARG2, 0, 0, 0, 0);
+
+
+/*****************************************************************************
+ * Mechanism for tracing debug for the HssAcc component, with no arguments
+ *
+ * Note:
+ * This macro executes only in debug versions of the code. It does nothing
+ * in release code.
+ *****************************************************************************/
+#ifndef NDEBUG
+ #define ICP_HSSACC_TRACE_0(LEVEL, STR) \
+ { \
+ if (LEVEL <= ICP_HSSACC_TRACE_LEVEL) \
+ { \
+ ixOsalLog (IX_OSAL_LOG_LVL_MESSAGE, \
+ IX_OSAL_LOG_DEV_STDOUT, \
+ STR, 0, 0, 0, 0, 0, 0); \
+ } \
+ }
+#else
+ #define ICP_HSSACC_TRACE_0(LEVEL, STR) do { /* nothing */ } while(0)
+#endif
+
+/*****************************************************************************
+ * Mechanism for tracing debug for the HssAcc component, with one argument
+ *
+ * Note:
+ * This macro executes only in debug versions of the code. It does nothing
+ * in release code.
+ *****************************************************************************/
+#ifndef NDEBUG
+ #define ICP_HSSACC_TRACE_1(LEVEL, STR, ARG1) \
+ { \
+ if (LEVEL <= ICP_HSSACC_TRACE_LEVEL) \
+ { \
+ ixOsalLog (IX_OSAL_LOG_LVL_MESSAGE, \
+ IX_OSAL_LOG_DEV_STDOUT, \
+ STR, ARG1, 0, 0, 0, 0, 0); \
+ } \
+ }
+#else
+ #define ICP_HSSACC_TRACE_1(LEVEL, STR, ARG1) do { /* nothing */ } while(0)
+#endif
+
+/*****************************************************************************
+ * Mechanism for tracing debug for the HssAcc component, with two arguments
+ *
+ * Note:
+ * This macro executes only in debug versions of the code. It does nothing
+ * in release code.
+ *****************************************************************************/
+#ifndef NDEBUG
+ #define ICP_HSSACC_TRACE_2(LEVEL, STR, ARG1, ARG2) \
+ { \
+ if (LEVEL <= ICP_HSSACC_TRACE_LEVEL) \
+ { \
+ ixOsalLog (IX_OSAL_LOG_LVL_MESSAGE, \
+ IX_OSAL_LOG_DEV_STDOUT, \
+ STR, ARG1, ARG2, 0, 0, 0, 0); \
+ } \
+ }
+#else
+ #define ICP_HSSACC_TRACE_2(LEVEL, STR, ARG1, ARG2) do { } while(0)
+#endif
+
+/*****************************************************************************
+ * Mechanism for tracing debug for the HssAcc component, with three arguments
+ *
+ * Note:
+ * This macro executes only in debug versions of the code. It does nothing
+ * in release code.
+ *
+ *****************************************************************************/
+#ifndef NDEBUG
+ #define ICP_HSSACC_TRACE_3(LEVEL, STR, ARG1, ARG2, ARG3) \
+ { \
+ if (LEVEL <= ICP_HSSACC_TRACE_LEVEL) \
+ { \
+ ixOsalLog (IX_OSAL_LOG_LVL_MESSAGE, \
+ IX_OSAL_LOG_DEV_STDOUT, \
+ STR, ARG1, ARG2, ARG3, 0, 0, 0); \
+ } \
+ }
+#else
+ #define ICP_HSSACC_TRACE_3(LEVEL, STR, ARG1, ARG2, ARG3) do { } while(0)
+#endif
+
+/*****************************************************************************
+ * Mechanism for tracing debug for the HssAcc component, with four arguments
+ *
+ * Note:
+ * This macro executes only in debug versions of the code. It does nothing
+ * in release code.
+ *
+ *****************************************************************************/
+#ifndef NDEBUG
+ #define ICP_HSSACC_TRACE_4(LEVEL, STR, ARG1, ARG2, ARG3, ARG4) \
+ { \
+ if (LEVEL <= ICP_HSSACC_TRACE_LEVEL) \
+ { \
+ ixOsalLog (IX_OSAL_LOG_LVL_MESSAGE, \
+ IX_OSAL_LOG_DEV_STDOUT, \
+ STR, ARG1, ARG2, ARG3, ARG4, 0, 0); \
+ } \
+ }
+#else
+ #define ICP_HSSACC_TRACE_4(LEVEL, STR, ARG1, ARG2, ARG3, ARG4) do { } while(0)
+#endif
+
+
+/*****************************************************************************
+ * Mechanism for tracing debug for the HSS Acc Datapath block component,
+ * with no arguments
+ *
+ * Note:
+ * This macro executes only in debug versions of the code. It does nothing
+ * in release code.
+ *****************************************************************************/
+#ifndef NDEBUG
+ #define ICP_HSSACC_DP_TRACE_0(LEVEL, STR) \
+ { \
+ if (LEVEL <= ICP_HSSACC_DP_TRACE_LEVEL) \
+ { \
+ ixOsalLog (IX_OSAL_LOG_LVL_MESSAGE, \
+ IX_OSAL_LOG_DEV_STDOUT, \
+ STR, 0, 0, 0, 0, 0, 0); \
+ } \
+ }
+#else
+ #define ICP_HSSACC_DP_TRACE_0(LEVEL, STR) do { /* nothing */ } while(0)
+#endif
+
+/*****************************************************************************
+ * Mechanism for tracing debug for the HssAcc Datapath component,
+ * with one argument
+ *
+ * Note:
+ * This macro executes only in debug versions of the code. It does nothing
+ * in release code.
+ *****************************************************************************/
+#ifndef NDEBUG
+ #define ICP_HSSACC_DP_TRACE_1(LEVEL, STR, ARG1) \
+ { \
+ if (LEVEL <= ICP_HSSACC_DP_TRACE_LEVEL) \
+ { \
+ ixOsalLog (IX_OSAL_LOG_LVL_MESSAGE, \
+ IX_OSAL_LOG_DEV_STDOUT, \
+ STR, ARG1, 0, 0, 0, 0, 0); \
+ } \
+ }
+#else
+ #define ICP_HSSACC_DP_TRACE_1(LEVEL, STR, ARG1) do { /* nothing */ } while(0)
+#endif
+
+/*****************************************************************************
+ * Mechanism for tracing debug for the HssAcc Datapath component,
+ * with two arguments
+ *
+ * Note:
+ * This macro executes only in debug versions of the code. It does nothing
+ * in release code.
+ *****************************************************************************/
+#ifndef NDEBUG
+ #define ICP_HSSACC_DP_TRACE_2(LEVEL, STR, ARG1, ARG2) \
+ { \
+ if (LEVEL <= ICP_HSSACC_DP_TRACE_LEVEL) \
+ { \
+ ixOsalLog (IX_OSAL_LOG_LVL_MESSAGE, \
+ IX_OSAL_LOG_DEV_STDOUT, \
+ STR, ARG1, ARG2, 0, 0, 0, 0); \
+ } \
+ }
+#else
+ #define ICP_HSSACC_DP_TRACE_2(LEVEL, STR, ARG1, ARG2) do { } while(0)
+#endif
+
+
+#endif /* ICP_HSSACC_TRACE_H */
diff --git a/Acceleration/library/icp_telephony/tdm_io_access/include/icp_hssacc_tx_datapath.h b/Acceleration/library/icp_telephony/tdm_io_access/include/icp_hssacc_tx_datapath.h
new file mode 100644
index 0000000..4c6c722
--- /dev/null
+++ b/Acceleration/library/icp_telephony/tdm_io_access/include/icp_hssacc_tx_datapath.h
@@ -0,0 +1,191 @@
+/*******************************************************************************
+ *
+ * @file icp_hssacc_tx_datapath.h
+ *
+ * @description Content of this file provides the internal API for the Transmit
+ * datapath module.
+ *
+ * @ingroup icp_HssAcc
+ *
+ * @Revision 1.0
+ *
+ * @par
+ * This file is provided under a dual BSD/GPLv2 license. When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * The full GNU General Public License is included in this distribution
+ * in the file called LICENSE.GPL.
+ *
+ * Contact Information:
+ * Intel Corporation
+ *
+ * BSD LICENSE
+ *
+ * Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ *
+ *
+ ******************************************************************************/
+
+#ifndef ICP_HSSACC_TX_DATAPATH_H
+#define ICP_HSSACC_TX_DATAPATH_H
+
+#include "icp_hssacc.h"
+
+/* Definition of watermark level for pre-emptive Voice traffic flow regulation,
+ this watermark is tuned following performance testing, at this point
+it is assumed that flow regulation should begin early to prevent Speech latency
+build-up. */
+#define ICP_HSSACC_TX_Q_WATERMARK_LEVEL (4)
+
+/* Voice packet length should be modulo 4. A pre-transmit voice buffer check
+will bitwise AND the voice packet length with this value. */
+#define ICP_HSSACC_TX_VOICE_PACKET_LENGTH_CHECK_MASK (0x00000003)
+
+
+/*****************************************************************************
+ * Abstract:
+ * Initialises this subcomponent (mutex...) and Resets the Tx Datapath
+ * internal data.
+ *
+ *****************************************************************************/
+icp_status_t
+HssAccTxDatapathInit(void);
+
+
+/*****************************************************************************
+ * Abstract:
+ * Destroys all allocated memory and mutexes for this component.
+ *
+ *****************************************************************************/
+icp_status_t
+HssAccTxDatapathShutdown(void);
+
+/*****************************************************************************
+ * Abstract:
+ * updates the Type for specified channel,
+ * will potentially trigger a resizing of the Queue associated with this
+ * channel.
+ *
+ *****************************************************************************/
+icp_status_t
+HssAccTxDatapathChanTypeUpdate (uint32_t channelId,
+ icp_hssacc_channel_type_t chanType);
+
+
+/*****************************************************************************
+ * Abstract:
+ * Set or unset the channel as bypassed, will allow the component to prevent
+ * or allow Tx.
+ *
+ *****************************************************************************/
+icp_status_t
+HssAccTxDatapathChanBypassStateSet(uint32_t channelId,
+ icp_boolean_t bypassed);
+
+
+/*****************************************************************************
+ * Abstract:
+ * Register the Tx Done callback
+ *
+ *****************************************************************************/
+void
+HssAccTxDatapathChanTxDoneCallbackRegister(
+ uint32_t channelId,
+ icp_hssacc_tx_done_callback_t txDoneCallback,
+ icp_user_context_t userContext);
+
+/*****************************************************************************
+ * Abstract:
+ * Deregister the Tx Done callback
+ *
+ *****************************************************************************/
+void
+HssAccTxDatapathChanTxDoneCallbackDeregister(uint32_t channelId);
+
+
+/*****************************************************************************
+ * Abstract:
+ * Triggers the servicing of all the Tx Queues, this will trigger TxDone
+ * callbacks when appropriate for each queue of type channelType.
+ *
+ *****************************************************************************/
+icp_status_t
+HssAccTxDatapathService(icp_hssacc_channel_type_t channelType);
+
+
+
+/*****************************************************************************
+ * Abstract:
+ * Retrieve all buffers in the transmit path for specified channel
+ *
+ *****************************************************************************/
+icp_status_t
+HssAccTxDatapathChannelBuffersRetrieve(uint32_t channelId,
+ IX_OSAL_MBUF * * startChainBuffer,
+ IX_OSAL_MBUF * * endChainBuffer);
+
+
+/*****************************************************************************
+ * Abstract:
+ * Reset the stats for specified channel
+ *
+ *****************************************************************************/
+void
+HssAccTxDatapathChanStatsReset(uint32_t channelId);
+
+
+
+/*****************************************************************************
+ * Abstract:
+ * Print out the stats for the specified channel
+ *
+ *****************************************************************************/
+void
+HssAccTxDatapathChanStatsShow(uint32_t channelId);
+
+#endif
diff --git a/Acceleration/library/icp_telephony/tdm_io_access/include/icp_hssacc_voice_bypass.h b/Acceleration/library/icp_telephony/tdm_io_access/include/icp_hssacc_voice_bypass.h
new file mode 100644
index 0000000..e59fec7
--- /dev/null
+++ b/Acceleration/library/icp_telephony/tdm_io_access/include/icp_hssacc_voice_bypass.h
@@ -0,0 +1,115 @@
+/*******************************************************************************
+ *
+ * @file icp_hssacc_voice_bypass.h
+ *
+ * @description Content of this file provides the internal API for the Voice
+ * bypass module
+ *
+ * @ingroup icp_HssAcc
+ *
+ * @Revision 1.0
+ *
+ * @par
+ * This file is provided under a dual BSD/GPLv2 license. When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * The full GNU General Public License is included in this distribution
+ * in the file called LICENSE.GPL.
+ *
+ * Contact Information:
+ * Intel Corporation
+ *
+ * BSD LICENSE
+ *
+ * Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ *
+ *
+ ******************************************************************************/
+
+#ifndef ICP_HSSACC_VOICE_BYPASS_H
+#define ICP_HSSACC_VOICE_BYPASS_H
+
+#include "icp.h"
+
+/*****************************************************************************
+ * Abstract
+ * This function initialises the internals of the Voice Bypass
+ * sub-module. it can only be called once.
+ *
+ *****************************************************************************/
+void
+HssAccVoiceBypassInit(void);
+
+
+/*****************************************************************************
+ * Abstract
+ * This function shuts down the Voice Bypass submodule. the module
+ * must have been initialised beforehand.
+ *
+ *****************************************************************************/
+icp_status_t
+HssAccVoiceBypassShutdown(void);
+
+/*****************************************************************************
+ * Abstract
+ * This function displays the internal gathered by this sub-module.
+ *
+ *****************************************************************************/
+void
+HssAccBypassStatsShow (void);
+
+
+/*****************************************************************************
+ * Abstract
+ * This function resets all the internal stats relating to this sub-module.
+ *
+ *****************************************************************************/
+void
+HssAccBypassStatsReset (void);
+
+#endif
diff --git a/Acceleration/library/icp_telephony/tdm_io_access/linux_2.6_kernel_space.mk b/Acceleration/library/icp_telephony/tdm_io_access/linux_2.6_kernel_space.mk
new file mode 100644
index 0000000..325733d
--- /dev/null
+++ b/Acceleration/library/icp_telephony/tdm_io_access/linux_2.6_kernel_space.mk
@@ -0,0 +1,76 @@
+###################
+# @par
+# This file is provided under a dual BSD/GPLv2 license. When using or
+# redistributing this file, you may do so under either license.
+#
+# GPL LICENSE SUMMARY
+#
+# Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of version 2 of the GNU General Public License as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+# The full GNU General Public License is included in this distribution
+# in the file called LICENSE.GPL.
+#
+# Contact Information:
+# Intel Corporation
+#
+# BSD LICENSE
+#
+# Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+# * Neither the name of Intel Corporation nor the names of its
+# contributors may be used to endorse or promote products derived
+# from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+#
+#
+###################
+
+#specific include directories in kernel space
+INCLUDES+= -I $(ICP_OSAL_DIR)/platforms/EP805XX/include \
+ -I $(ICP_OSAL_DIR)/platforms/EP805XX/os/linux/include \
+ -I $(ICP_OSAL_DIR)/common/os/linux/include/core \
+ -I $(ICP_OSAL_DIR)/common/os/linux/include/modules \
+ -I $(ICP_OSAL_DIR)/common/os/linux/include/modules/ddk \
+ -I $(ICP_OSAL_DIR)/common/os/linux/include/modules/ioMem \
+ -I $(ICP_OSAL_DIR)/common/os/linux/include/modules/bufferMgt
+
+
+#Extra Flags Specific in kernel space e.g. include path or debug flags etc. e.g to add an include path EXTRA_CFLAGS += -I$(src)/../include
+EXTRA_CFLAGS += $(INCLUDES) -DTOLAPAI -D__tolapai -DEP805XX -D__ep805xx -DIX_HW_COHERENT_MEMORY=1
+EXTRA_LDFLAGS+=-whole-archive
+