📄 ixhssaccccm.c
字号:
/** * @file IxHssAccCCM.c * * @author Intel Corporation * @date 30-Jan-02 * * @brief HssAccess Channelised Connection Manager Interface * * * @par * IXP400 SW Release version 2.1 * * -- Copyright Notice -- * * @par * Copyright (c) 2001-2005, Intel Corporation. * All rights reserved. * * @par * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. 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. * 3. Neither the name of the 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. * * * @par * 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. * * * @par * -- End of Copyright Notice --*//** * Put the system defined include files required. *//** * Put the user defined include files required. */#include "IxOsal.h"#include "IxHssAccError_p.h"#include "IxQMgr.h"#include "IxNpeA.h"#include "IxHssAccCCM_p.h"#include "IxHssAccPDM_p.h"#include "IxHssAccCommon_p.h"#include "IxHssAccNpeA_p.h"/** * #defines and macros used in this file. */#define IX_HSSACC_BYTE_SIZE 8#define IX_HSSACC_CHAN_GCT_BYTE0_POS 0#define IX_HSSACC_CHAN_GCT_BYTE1_POS 1#define IX_HSSACC_CHAN_GCT_BYTE2_POS 2#define IX_HSSACC_CHAN_GCT_BYTE3_POS 3/* * the value indicating timeslot switching channel not available */#define IX_HSSACC_CHAN_TSLOTSWITCH_BYPASS_NOT_AVAIL (0xFFFFFFFF)/** * Typedefs whose scope is limited to this file. */typedef struct{ unsigned blk1; unsigned blk2;} IxHssAccCCMTxBlkSize;typedef struct{ unsigned connects; unsigned disconnects; unsigned enables; unsigned disables; unsigned rxCallbacks; unsigned emptyRxCallbacks; unsigned bypassChanEnables; unsigned bypassChanDisables; unsigned bypassChanGctDl;} IxHssAccCCMStats;/** * Variable declarations global to this file only. Externs are followed by * static variables. */static IxHssAccCCMParams ixHssAccCCMParams[IX_HSSACC_HSS_PORT_MAX];static IxQMgrQId ixHssAccCCMQids[IX_HSSACC_HSS_PORT_MAX] = { IX_NPE_A_QMQ_HSS0_CHL_RX_TRIG, IX_NPE_A_QMQ_HSS1_CHL_RX_TRIG};static BOOL ixHssAccCCMConnectedState[IX_HSSACC_HSS_PORT_MAX] = { FALSE, FALSE};static BOOL ixHssAccCCMEnabledState[IX_HSSACC_HSS_PORT_MAX] = { FALSE, FALSE};/* * The following array holds the blk1/blk2 combinations for various block sizes, as * required by the NPE */static IxHssAccCCMTxBlkSize ixHssAccCCMTxBlkSize[] = { { 8, 8 }, /* 16 byte blk size */ { 12, 8 }, /* 20 byte blk size */ { 12, 12 }, /* 24 byte blk size */ { 16, 12 }, /* 28 byte blk size */ { 16, 16 }, /* 32 byte blk size */ { 20, 16 }, /* 36 byte blk size */ { 20, 20 }, /* 40 byte blk size */ { 24, 20 }, /* 44 byte blk size */ { 24, 24 } /* 48 byte blk size */};static IxHssAccCCMStats ixHssAccCCMStats;/** * Extern function prototypes. *//** * Static function prototypes. */PRIVATE voidixHssAccCCMEmptyRxCallback (IxHssAccHssPort hssPortId, unsigned rxOffset, unsigned txOffset, unsigned numHssErrs);/** * Function definition: ixHssAccCCMConnect */IX_STATUS ixHssAccCCMConnect (IxHssAccHssPort hssPortId, unsigned bytesPerTSTrigger, UINT8 *rxCircular, unsigned numRxBytesPerTS, UINT32 *txPtrList, unsigned numTxPtrLists, unsigned numTxBytesPerBlk, IxHssAccChanRxCallback rxCallback){ IX_STATUS status = IX_SUCCESS; unsigned index1; unsigned txBlk1Bytes; unsigned txBlk2Bytes; unsigned msgData; UINT32 data = 0; UINT32 bypassNum; IxNpeMhMessage npeMhMsg; IxHssAccChanTsSwitchConf *pConfig = &(ixHssAccCCMParams[hssPortId].tsSwitchConf[0]); IX_HSSACC_TRACE0 (IX_HSSACC_FN_ENTRY_EXIT, "Entering ixHssAccCCMConnect\n"); /* check to see if already connected - one connection per client per port */ if (ixHssAccCCMConnectedState[hssPortId] == TRUE) { /* report the error */ IX_HSSACC_REPORT_ERROR ("ixHssAccCCMConnect - already connected\n"); /* return error */ status = IX_FAIL; } /* save the parameters for reference */ ixHssAccCCMParams[hssPortId].bytesPerTSTrigger = bytesPerTSTrigger; ixHssAccCCMParams[hssPortId].rxCircular = rxCircular; ixHssAccCCMParams[hssPortId].numRxBytesPerTS = numRxBytesPerTS; ixHssAccCCMParams[hssPortId].txPtrList = txPtrList; ixHssAccCCMParams[hssPortId].numTxPtrLists = numTxPtrLists; ixHssAccCCMParams[hssPortId].numTxBytesPerBlk = numTxBytesPerBlk; /* initialising timeslot switching channels' configuration */ for (bypassNum = 0; bypassNum < IX_HSSACC_CHAN_TSLOTSWITCH_NUM_BYPASS_MAX; bypassNum++) { pConfig[bypassNum].bypassEnabledState = FALSE; pConfig[bypassNum].srcTimeslot = 0; pConfig[bypassNum].destTimeslot = 0; } /* ensure tmpRxCallback is not registered to any client callback */ ixHssAccCCMParams[hssPortId].tmpRxCallback = NULL; if (rxCallback != NULL) { ixHssAccCCMParams[hssPortId].rxCallback = rxCallback; if (status == IX_SUCCESS) { /* enable QMgr notifications on the specified QMQ */ status = ixQMgrNotificationEnable (ixHssAccCCMQids[hssPortId], IX_QMGR_Q_SOURCE_ID_NOT_E); if (status != IX_SUCCESS) { /* report the error */ IX_HSSACC_REPORT_ERROR_WITH_ARG ("ixHssAccCCMConnect - " "unexpected behaviour on QMQ notification " "enable: return status = %d\n", status, 0, 0, 0, 0, 0); /* return error */ status = IX_FAIL; } } } /* write the connection configurables to the NPE */ if (status == IX_SUCCESS) { /* the rx buffer address */ ixHssAccComNpeCmdMsgCreate ( IX_NPE_A_MSSG_HSS_CHAN_RX_BUF_ADDR_WRITE, 0, hssPortId, 0, (UINT32) IX_HSSACC_PKT_MMU_VIRT_TO_PHY(rxCircular), &npeMhMsg); status = ixHssAccComNpeCmdMsgSend ( npeMhMsg, FALSE, /* no response expected */ IX_NPE_A_MSSG_HSS_CHAN_RX_BUF_ADDR_WRITE); } if (status == IX_SUCCESS) { /* the rx buffer size and trigger period */ data = (numRxBytesPerTS << IX_HSSACC_NPE_CHAN_RXSIZEB_OFFSET) | ((bytesPerTSTrigger/IX_HSSACC_BYTE_SIZE) << IX_HSSACC_NPE_CHAN_TRIG_OFFSET); ixHssAccComNpeCmdMsgCreate ( IX_NPE_A_MSSG_HSS_CHAN_RX_BUF_CFG_WRITE, 0, hssPortId, 0, data, &npeMhMsg); status = ixHssAccComNpeCmdMsgSend ( npeMhMsg, FALSE, /* no response expected */ IX_NPE_A_MSSG_HSS_CHAN_RX_BUF_CFG_WRITE); } /* * The NPE expects the TX Blk size to be written in blk1/blk2 combination * values, as specified by the NPE. A global array containing the * blk1/blk2 values is indexed through the numTxBytesPerBlk value */ if (status == IX_SUCCESS) { index1 = (numTxBytesPerBlk - IX_HSSACC_CHAN_TXBYTES_PER_BLK_MIN) / IX_HSSACC_CHAN_TXBYTES_PER_BLK_DIV; txBlk1Bytes = ixHssAccCCMTxBlkSize[index1].blk1; txBlk2Bytes = ixHssAccCCMTxBlkSize[index1].blk2; data = (txBlk1Bytes << IX_HSSACC_NPE_CHAN_TXBLK1B_OFFSET) | ((txBlk1Bytes/IX_HSSACC_BYTES_PER_WORD) << IX_HSSACC_NPE_CHAN_TXBLK1W_OFFSET) | (txBlk2Bytes << IX_HSSACC_NPE_CHAN_TXBLK2B_OFFSET) | ((txBlk2Bytes/IX_HSSACC_BYTES_PER_WORD) << IX_HSSACC_NPE_CHAN_TXBLK2W_OFFSET); ixHssAccComNpeCmdMsgCreate ( IX_NPE_A_MSSG_HSS_CHAN_TX_BLK_CFG_WRITE, 0, hssPortId, 0, data, &npeMhMsg); status = ixHssAccComNpeCmdMsgSend ( npeMhMsg, FALSE, /* no response expected */ IX_NPE_A_MSSG_HSS_CHAN_TX_BLK_CFG_WRITE); } if (status == IX_SUCCESS) { /* the tx ptrList address */ ixHssAccComNpeCmdMsgCreate ( IX_NPE_A_MSSG_HSS_CHAN_TX_BUF_ADDR_WRITE, 0, hssPortId, 0, (UINT32) IX_HSSACC_PKT_MMU_VIRT_TO_PHY(txPtrList), &npeMhMsg); status = ixHssAccComNpeCmdMsgSend ( npeMhMsg, FALSE, /* no response expected */ IX_NPE_A_MSSG_HSS_CHAN_TX_BUF_ADDR_WRITE); } if (status == IX_SUCCESS) { msgData = numTxPtrLists << IX_HSSACC_NPE_CHAN_TXBUFSIZE_OFFSET; /* the tx buf size */ ixHssAccComNpeCmdMsgCreate ( IX_NPE_A_MSSG_HSS_CHAN_TX_BUF_SIZE_WRITE, 0, hssPortId, 0, msgData, &npeMhMsg); status = ixHssAccComNpeCmdMsgSend ( npeMhMsg, FALSE, /* no response expected */ IX_NPE_A_MSSG_HSS_CHAN_TX_BUF_SIZE_WRITE); } if (status == IX_SUCCESS) { /* note the active connection */ ixHssAccCCMConnectedState[hssPortId] = TRUE; ixHssAccCCMStats.connects++; } IX_HSSACC_TRACE0 (IX_HSSACC_FN_ENTRY_EXIT, "Exiting ixHssAccCCMConnect\n"); return status;}/** * Function definition: ixHssAccCCMPortEnable */IX_STATUS ixHssAccCCMPortEnable (IxHssAccHssPort hssPortId){ IX_STATUS status = IX_SUCCESS; IxNpeMhMessage message; IX_HSSACC_TRACE0 (IX_HSSACC_FN_ENTRY_EXIT, "Entering ixHssAccCCMPortEnable\n"); /* check to see if already enabled */ if (ixHssAccCCMEnabledState[hssPortId] == TRUE) { /* report the error */ IX_HSSACC_REPORT_ERROR ("ixHssAccCCMPortEnable - already enabled\n"); /* return error */ status = IX_FAIL; } /* check to see if there is a valid connection on the hss port */ if (ixHssAccCCMConnectedState[hssPortId] == FALSE) { /* report the error */ IX_HSSACC_REPORT_ERROR ("ixHssAccCCMPortEnable - no valid connection on specified hssPortId\n"); /* return error */ status = IX_FAIL; } /* enable the npe flow */ if (status == IX_SUCCESS) { /* * check if tmpRxCallback contains any client callback. If any, * this means the client is trying to reenable the service for * the second (or third, fourth, ...) time without disconnecting * the service. Hence, use back the client callback that has been * supplied during ixHssAccCCMConnect */ if (ixHssAccCCMParams[hssPortId].tmpRxCallback != NULL) { ixHssAccCCMParams[hssPortId].rxCallback = ixHssAccCCMParams[hssPortId].tmpRxCallback; } /* create the NpeMh message - NPE_A message format */ ixHssAccComNpeCmdMsgCreate (IX_NPE_A_MSSG_HSS_CHAN_FLOW_ENABLE, 0, hssPortId, 0, 0, &message); /* send the message */ status = ixHssAccComNpeCmdMsgSend (message, FALSE, IX_NPE_A_MSSG_HSS_CHAN_FLOW_ENABLE); if (status == IX_SUCCESS) { ixHssAccCCMEnabledState[hssPortId] = TRUE; ixHssAccCCMStats.enables++; } else { /* report the error */ IX_HSSACC_REPORT_ERROR ("ixHssAccCCMPortEnable - npe flow enable failed\n"); /* ensure not passing another components fail return type */ status = IX_FAIL; } } IX_HSSACC_TRACE0 (IX_HSSACC_FN_ENTRY_EXIT, "Exiting ixHssAccCCMPortEnable\n"); return status;}/** * Function definition: ixHssAccCCMPortDisable */IX_STATUS ixHssAccCCMPortDisable (IxHssAccHssPort hssPortId){ IX_STATUS status = IX_SUCCESS; IxNpeMhMessage message; IxHssAccChanRxCallback currentClientCallback = ixHssAccCCMParams[hssPortId].rxCallback; IX_HSSACC_TRACE0 (IX_HSSACC_FN_ENTRY_EXIT, "Entering ixHssAccCCMPortDisable\n"); /* check to see if enabled */ if (ixHssAccCCMEnabledState[hssPortId] == FALSE) { /* report the error */ IX_HSSACC_REPORT_ERROR ("ixHssAccCCMPortDisable - not enabled\n"); /* return error */ status = IX_FAIL; } /* disable the npe flow */ if (status == IX_SUCCESS) { /* * temporary save client callback just in case client would like to * reenable the service after disabling it for a while */ ixHssAccCCMParams[hssPortId].tmpRxCallback = ixHssAccCCMParams[hssPortId].rxCallback; /* stop client notifications from the sync QMQ - clear client callback */ ixHssAccCCMParams[hssPortId].rxCallback = ixHssAccCCMEmptyRxCallback; /* create the NpeMh message - NPE_A message format */ ixHssAccComNpeCmdMsgCreate (IX_NPE_A_MSSG_HSS_CHAN_FLOW_DISABLE, 0, hssPortId, 0, 0, &message); /* send the message */ status = ixHssAccComNpeCmdMsgSend (message, FALSE, IX_NPE_A_MSSG_HSS_CHAN_FLOW_DISABLE); if (status == IX_SUCCESS) { ixHssAccCCMEnabledState[hssPortId] = FALSE; ixHssAccCCMStats.disables++; } else { /* report the error */ IX_HSSACC_REPORT_ERROR ("ixHssAccCCMPortDisable - npe flow disable failed\n"); /* re-assign the client callback */ ixHssAccCCMParams[hssPortId].rxCallback = currentClientCallback; status = IX_FAIL; } } /* * Note: QMQ notifications will stay enabled. This will help the QMQ * flushing - if an entry gets pushed on the queue during disabling of * the npe flow, the entry will need to be read from the queue. The * hssAccess trigger callback will stay attached. The client callback * will just not be called. */ IX_HSSACC_TRACE0 (IX_HSSACC_FN_ENTRY_EXIT, "Exiting ixHssAccCCMPortDisable\n"); return status;}/** * Function definition: ixHssAccCCMIsPortEnabled * * NOTE: hssPortId should be validated before calling this function */BOOL ixHssAccCCMIsPortEnabled (IxHssAccHssPort hssPortId){ return ixHssAccCCMEnabledState[hssPortId];}/** * Function definition: ixHssAccCCMDisconnect */IX_STATUS ixHssAccCCMDisconnect (IxHssAccHssPort hssPortId){ IX_STATUS status = IX_SUCCESS; IxHssAccChanTsSwitchConf *pConfig = &(ixHssAccCCMParams[hssPortId].tsSwitchConf[0]); UINT32 bypassNum; IX_HSSACC_TRACE0 (IX_HSSACC_FN_ENTRY_EXIT, "Entering ixHssAccCCMDisconnect\n"); /* check to see if connected */ if (ixHssAccCCMConnectedState[hssPortId] == FALSE) { /* report the error */ IX_HSSACC_REPORT_ERROR ("ixHssAccCCMDisconnect - not connected\n"); /* return error */ status = IX_FAIL;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -