📄 atmoc3txcp.c
字号:
/* * atmTx.c * * Transmit side of the ATM cell switch *//* * Copyright (c) 1998,1999,2000,2001,2002 C-Port Corporation * All Rights Reserved * * The information contained in this file is C-Port Corporation confidential and proprietary. * Any reproduction, use or disclosure, in whole or in part, of this * program, including any attempt to obtain a human-readable version of this * program, without the express, prior written consent of C-Port * Corporation or Motorola Incorporated is strictly prohibited. */#include <dcpPduSvcs.h>#include <dcpQueueSvcs.h>#include <dcpKernelSvcs.h>#include <dcpTableSvcs.h>#include <dcpRegisterDefs.h>#include <dcpDiagSvcs.h>#include "atm.h"#include "atmStatus.h"#include "atmPrivate.h"#include "atmCellDesc.h"#include "atmVcTable.h"#include "rcSdpAtmApiIf.h"#include "errorHandling.h"#include "atmIf.h"QsMessage ALIGNED64 atmTxCellDescMsg;extern KsContext atmTxNextContext;/* * Pending transmit buffer storage - used for double * buffering on transmit and double buffer index */BsBufHandle txPendingBuf[MAX_SCOPES];int bufferId;/* static TsEntry txEntry = {0, 8, NULL, REQ_IDX(1), 4}; *//* * atmTx() - dequeue a cell from the Queue Controller and transmit * */int32uatmTx(void* arg){ MergeSpc* mergeSpc; AtmMergeSpc* atmMerge; CellDescriptor* atmTxCellDesc; PduHandle pduHandle; CellHeader egressHdr; QsQueueId myQueue; int32u numQs; TsKey key; int32u keyData; BsBufHandle bufHandle = NULL; /* VpiVci* vpiVci; */ /* init key */ key.keyData = (int32u*)&keyData; key.maskLenBits =0; atmTxCellDesc = qsMessageGetData(&atmTxCellDescMsg); memset(atmTxCellDesc,0,sizeof(CellDescriptor)); /* * Allocate the pending buffers txPendingBuf[0] * and txPendingBuf[1]. */ while(bsError(txPendingBuf[0] = bsBufferAllocate(poolId))); while(bsError(txPendingBuf[1] = bsBufferAllocate(poolId))); qsQueueGet(ksProcIdCreate(ProcCP,0,ksCpGetId()),&myQueue,&numQs); while (1) { MSG_EVENT("CPRC: ATMTX wait for message"); /* * While the cell descriptor queue is empty, yield to another thread * The queue number is derived from the CP id. Each CP has 16 queues * allocated to it, so the first queue is cpId*16, but we use cpId<<4 * since we don't have a multiply instruction. */ while (!qsQueueGetLength(myQueue)) { ksContextSwitch(atmTxNextContext); } /* * There is a cell descriptor in the queue, * dequeue the head of the queue */ qsMessageReceiveStart(myQueue, &atmTxCellDescMsg); while (!qsMessageReceiveComplete(myQueue, &atmTxCellDescMsg)) { ksContextSwitch(atmTxNextContext); } MSG_EVENT("CPRC: ATMTX got message"); if (atmTxCellDesc->MulticastFlag == 0) { egressHdr = atmTxCellDesc->CellHeader; }else { bsBufferFreeReference(atmTxCellDesc->Bh); ksPrintf ("ATM Multi-cast support not provided in aal2Switch app"); continue; /* txEntry.offset = ksCpId<<2; keyData = atmTxCellDesc->VcIndex; tsEntryLookup(TABLE_ID_EGRESS, &key, &txEntry); while (!tsLookupResponseValid(4)) { ksContextSwitch(atmTxNextContext); } vpiVci = (VpiVci*)tsLookupGetResponse(4); vpiVci += (ksCpId&0x01); egressHdr.word = *vpiVci << 4; tsLookupRelease(4); */ } MSG_EVENT("CPRC: ATMTX wait for payload done"); /* * Wait for an opportunity to transmit the cell header */ while ((pduHandle = pduTxAllocate()) == NULL) { ksContextSwitch(atmTxNextContext); } MSG_EVENT("CPRC: ATMTX payload done"); /* * Put the cell header fields into merge register space */ mergeSpc = (MergeSpc*)pduTxHeaderGet(pduHandle); atmMerge = &mergeSpc->atmMergeSpc; atmMerge->cellHeader.word = (egressHdr.word) | getPtiClp(atmTxCellDesc->CellHeader.word); atmMerge->txType = atmTxCellDesc->payloadType; if (atmMerge->txType == atmPayloadTypeSwitched) { atmStatsBuffer.txCells++; } else { atmStatsBuffer.txOamCells++; } MSG_EVENT("CPRC: ATMTX release scope"); /* * Setup the transmit of cell payload on the wire */ pduTxBufHandleSet(pduHandle, atmTxCellDesc->Bh); pduTxLengthSet(pduHandle, 48, 0); /* * Give the header and cell to the DCP SDP for transmit */ pduTxFree(pduHandle); MSG_EVENT("CPRC: ATMTX scope released"); /* * Free the last transmit pending buffer from this scope, * store the current bufHandle and adjust the double buffer * index. */ bufHandle = txPendingBuf[bufferId]; txPendingBuf[bufferId] = atmTxCellDesc->Bh; bufferId ^= (MAX_SCOPES - 1); bsBufferFreeReference(bufHandle); /* * Switch to the Rx thread to prevent starvation under load */ ksContextSwitch(atmTxNextContext); } /* while (1) */}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -