diff options
Diffstat (limited to 'Acceleration/library/icp_telephony/tdm_io_access/icp_hssacc_port_config.c')
-rw-r--r-- | Acceleration/library/icp_telephony/tdm_io_access/icp_hssacc_port_config.c | 1175 |
1 files changed, 1175 insertions, 0 deletions
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"); + +} |