📄 ixhssacccodeletpkt.c
字号:
* This function is of type IxHssAccPktTxDoneCallback, the prototype of the * clients function to accept notification of completion with Tx buffers. * * This function is registered through ixHssAccPktPortConnect(). The * callback is invoked to return a transmitted packet back to the client. * <P> * The callback updates TX statistics and returns the mbuf(s) to the TX * pool. */PRIVATEvoidixHssAccCodeletPktTxDoneCallback ( IX_OSAL_MBUF *buffer, unsigned numHssErrs, IxHssAccPktStatus pktStatus, IxHssAccPktUserId txDoneUserId){ ClientInfo *pClientInfo = (ClientInfo *)txDoneUserId; Message *pMessage; /* add message to the head of the message queue */ pMessage = &pClientInfo->messageQ[pClientInfo->qHead++]; pClientInfo->qHead %= NUMELEMS(pClientInfo->messageQ); /* fill in the message */ pMessage->type = TxDoneCallback; pMessage->params.buffer = buffer; pMessage->params.numHssErrs = numHssErrs; pMessage->params.pktStatus = pktStatus; /* wake up the message processing thread */ (void) ixOsalSemaphorePost (&pClientInfo->messageSem);}/* * Function definition: ixHssAccCodeletPktTxDoneCallbackProcess */PRIVATEvoidixHssAccCodeletPktTxDoneCallbackProcess ( IX_OSAL_MBUF *buffer, unsigned numHssErrs, IxHssAccPktStatus pktStatus, ClientInfo *pClientInfo){ IxHssAccHssPort hssPortId = pClientInfo->hssPortId; IxHssAccHdlcPort hdlcPortId = pClientInfo->hdlcPortId; if (pktStatus == IX_HSSACC_PKT_OK) { /* update TX stats */ stats[hssPortId].pkt[hdlcPortId].txPackets++; stats[hssPortId].pkt[hdlcPortId].txBytes += IX_OSAL_MBUF_PKT_LEN(buffer); } /* update error stats */ ixHssAccCodeletNumHssErrorsUpdate (hssPortId, numHssErrs); ixHssAccCodeletPktErrorsUpdate (hssPortId, hdlcPortId, pktStatus); /* free the buffer */ stats[hssPortId].pkt[hdlcPortId].txBufsInUse -= mbufsCount (buffer); ixHssAccCodeletMbufChainFree (buffer);}/* * Function definition: ixHssAccCodeletPktThreadMain */PRIVATEIX_STATUSixHssAccCodeletPktThreadMain ( void* arg, void** ptrRetObj){ ClientInfo *pClientInfo = (ClientInfo *)arg; Message *pMessage; while (1) { (void) ixOsalSemaphoreWait ( &pClientInfo->messageSem, IX_OSAL_WAIT_FOREVER); pMessage = &pClientInfo->messageQ[pClientInfo->qTail++]; pClientInfo->qTail %= NUMELEMS(pClientInfo->messageQ); switch (pMessage->type) { case RxCallback: ixHssAccCodeletPktRxCallbackProcess ( pMessage->params.buffer, pMessage->params.numHssErrs, pMessage->params.pktStatus, pClientInfo); break; case RxFreeLowCallback: ixHssAccCodeletPktRxFreeLowCallbackProcess ( pClientInfo); break; case TxDoneCallback: ixHssAccCodeletPktTxDoneCallbackProcess ( pMessage->params.buffer, pMessage->params.numHssErrs, pMessage->params.pktStatus, pClientInfo); break; } /* switch (pMessage->type) */ } /* while (1) */ return IX_SUCCESS;}/* * Function definition: ixHssAccCodeletPacketisedServiceStart */voidixHssAccCodeletPacketisedServiceStart ( IxHssAccHssPort hssPortId, IxHssAccHdlcPort hdlcPortId){ IX_STATUS status; BOOL hdlcFraming; IxHssAccHdlcMode hdlcMode; BOOL hdlcBitInvert; unsigned blockSizeInWords; UINT32 rawIdleBlockPattern; IxHssAccPktHdlcFraming hdlcTxFraming; IxHssAccPktHdlcFraming hdlcRxFraming; unsigned frmFlagStart; ClientInfo *pClientInfo = &clientInfo[hssPortId][hdlcPortId]; IxOsalThreadAttr ixHssAccCodeletPktThreadAttr; /* initialise client info structure for this client */ pClientInfo->hssPortId = hssPortId; pClientInfo->hdlcPortId = hdlcPortId; /* initialise the tx/rx sample data values (to port number) */ pClientInfo->pktTxSampleData = hdlcPortId + 1; pClientInfo->pktRxSampleData = hdlcPortId + 1; /****************/ /* START THREAD */ /****************/ /* initialise message queue to empty */ pClientInfo->qHead = 0; pClientInfo->qTail = 0; /* initialise the rx semaphore */ (void) ixOsalSemaphoreInit ( &pClientInfo->messageSem, IX_HSSACC_CODELET_SEM_UNAVAILABLE); /* create the thread for processing callbacks */ /* when running both packetised and channelised services, the */ /* channelised service needs to be serviced in a higher priority */ /* thread (high) than the packetised service (low) */ ixHssAccCodeletPktThreadAttr.name = "HSS Codelet Pkt CB"; ixHssAccCodeletPktThreadAttr.stackSize = 10240; ixHssAccCodeletPktThreadAttr.priority = IX_HSSACC_CODELET_THREAD_PRI_MEDIUM; (void) ixOsalThreadCreate ( &pClientInfo->threadId, /* threadId */ &ixHssAccCodeletPktThreadAttr, /* threadAttr */ (IxOsalVoidFnVoidPtr)ixHssAccCodeletPktThreadMain, /* entryPoint */ pClientInfo); /* arg */ /* start the thread for processing callbacks */ (void) ixOsalThreadStart ( &pClientInfo->threadId); /* threadId */ /********************/ /* ALLOCATE BUFFERS */ /********************/ /* initialise the pool */ if (!pClientInfo->mbufPoolInitialised) { ixHssAccCodeletMbufPoolInit ( &pClientInfo->mbufPoolPtr, IX_HSSACC_CODELET_PKT_NUM_BUFS, IX_HSSACC_CODELET_PKT_BUFSIZE); pClientInfo->mbufPoolInitialised = TRUE; } /**********************/ /* CONNECT TO SERVICE */ /**********************/ /* HDLC framing = TRUE/FALSE (clients 0 and 2 will use HDLC mode, */ /* clients 1 and 3 will use RAW mode) */ hdlcFraming = (hdlcPortId % 2 == 0 ? TRUE : FALSE); if (hdlcPortId == IX_HSSACC_CODELET_PKT_56K_HDLC_CLIENT) { /* Client 2 is configured to run in 56Kbps packetised HDLC */ /* mode here. CAS bit is set to be in the LSB position with */ /* bit polarity '1' */ hdlcMode.hdlc56kMode = TRUE; hdlcMode.hdlc56kEndian = IX_HSSACC_56KE_BIT_0_UNUSED; hdlcMode.hdlc56kUnusedBitPolarity0 = FALSE; /* Bit inversion is enabled for client 2 */ hdlcBitInvert = TRUE; } else { /* Client 0, 1 and 3 are running in 64Kbps packetised mode. */ /* hdlcMode.hdlc56kEndian and hdlcMode.hdlc56kUnusedBitPolarity0 */ /* values are ignored by HSS access component in 64Kbps mode */ hdlcMode.hdlc56kMode = FALSE; hdlcMode.hdlc56kEndian = IX_HSSACC_56KE_BIT_7_UNUSED; hdlcMode.hdlc56kUnusedBitPolarity0 = TRUE; /* No bit inversion for client 0, 1 and 3 */ hdlcBitInvert = FALSE; } /* Raw mode block size = 4096 words (i.e. 16K) */ blockSizeInWords = (IX_HSSACC_CODELET_PKT_TX_PKTSIZE / 4); /* Raw mode idle pattern = 0x5F5F5F5F */ rawIdleBlockPattern = IX_HSSACC_CODELET_PKT_RAW_IDLE_PATTERN; /* HDLC idle transmission type = flags */ hdlcTxFraming.hdlcIdleType = IX_HSSACC_HDLC_IDLE_FLAGS; hdlcRxFraming.hdlcIdleType = IX_HSSACC_HDLC_IDLE_FLAGS; /* HDLC data endianness = lsb endian */ hdlcTxFraming.dataEndian = IX_HSSACC_LSB_ENDIAN; hdlcRxFraming.dataEndian = IX_HSSACC_LSB_ENDIAN; /* CRC type (CRC-16 or CRC-32) = CRC-32 */ hdlcTxFraming.crcType = IX_HSSACC_PKT_32_BIT_CRC; hdlcRxFraming.crcType = IX_HSSACC_PKT_32_BIT_CRC; /* Number of flags inserted at start of frame = 1 */ frmFlagStart = 1; /* connect this client to the Packetised Service */ status = ixHssAccPktPortConnect ( hssPortId, /* hssPortId */ hdlcPortId, /* hdlcPortId */ hdlcFraming, /* hdlcFraming */ hdlcMode, /* hdlcMode */ hdlcBitInvert, /* hdlcBitInvert */ blockSizeInWords, /* blockSizeInWords */ rawIdleBlockPattern, /* rawIdleBlockPattern */ hdlcTxFraming, /* hdlcTxFraming */ hdlcRxFraming, /* hdlcRxFraming */ frmFlagStart, /* frmFlagStart */ ixHssAccCodeletPktRxCallback, /* rxCallback */ (IxHssAccPktUserId) pClientInfo, /* rxUserId */ ixHssAccCodeletPktRxFreeLowCallback, /* rxFreeLowCallback */ (IxHssAccPktUserId) pClientInfo, /* rxFreeLowUserId */ ixHssAccCodeletPktTxDoneCallback, /* txDoneCallback */ (IxHssAccPktUserId) pClientInfo); /* txDoneUserId */ /* if there was any problem then update stats */ if (status != IX_SUCCESS) { stats[hssPortId].pkt[hdlcPortId].connectFails++; } /*********************/ /* SUPPLY RX BUFFERS */ /*********************/ /* invoke the free request callback */ ixHssAccCodeletPktRxFreeLowCallbackProcess (pClientInfo); /*****************/ /* START SERVICE */ /*****************/ /* this counter should be reset at port enable */ pClientInfo->staleRawBytesRecieved = 0; /* start the Packetised Service for this client */ status = ixHssAccPktPortEnable (hssPortId, hdlcPortId); /* if there was any problem then update stats */ if (status != IX_SUCCESS) { stats[hssPortId].pkt[hdlcPortId].portEnableFails++; }}/* * Function definition: ixHssAccCodeletPacketisedServiceRun */voidixHssAccCodeletPacketisedServiceRun ( IxHssAccHssPort hssPortId, IxHssAccHdlcPort hdlcPortId){ IX_STATUS status; IX_OSAL_MBUF *txBuffer = NULL; IX_OSAL_MBUF *txBufferChain = NULL; IX_OSAL_MBUF *lastBuffer = NULL; UINT32 txBytes; UINT32 bytes; unsigned byteIndex; ClientInfo *pClientInfo = &clientInfo[hssPortId][hdlcPortId]; /*********************/ /* TRANSMIT A PACKET */ /*********************/ /* if the codelet is acting as data source/sink */ if (!ixHssAccCodeletCodeletLoopbackGet ()) { /* initialise the number of bytes we want to transmit */ txBytes = IX_HSSACC_CODELET_PKT_TX_PKTSIZE; do { /* bytes to transmit in this buffer */ bytes = (txBytes > IX_HSSACC_CODELET_PKT_BUFSIZE ? IX_HSSACC_CODELET_PKT_BUFSIZE : txBytes); /* get a TX buffer */ txBuffer = ixHssAccCodeletMbufGet ( pClientInfo->mbufPoolPtr); /* if we got a buffer ok */ if (txBuffer != NULL) { stats[hssPortId].pkt[hdlcPortId].txBufsInUse++; /* set the data for the current buffer */ IX_OSAL_MBUF_MLEN(txBuffer) = bytes; /* if we're verifying rx data then fill in tx buffer */ if (verify) { for (byteIndex = 0; byteIndex < (UINT32) IX_OSAL_MBUF_MLEN(txBuffer); byteIndex++) { /* get/update the value to transmit */ ((UINT8 *)IX_OSAL_MBUF_MDATA(txBuffer))[byteIndex] = pClientInfo->pktTxSampleData++; } } /* to allow for caching, request a cache flush before tx */ IX_OSAL_CACHE_FLUSH ( IX_OSAL_MBUF_MDATA(txBuffer), IX_OSAL_MBUF_MLEN(txBuffer)); /* chain the buffer to the end of the current chain */ if (txBufferChain == NULL) { txBufferChain = txBuffer; /* set packet header for buffer */ IX_OSAL_MBUF_PKT_LEN(txBufferChain) = 0; } else { IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR(lastBuffer) = txBuffer; } IX_OSAL_MBUF_PKT_LEN(txBufferChain) += IX_OSAL_MBUF_MLEN(txBuffer); IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR(txBuffer) = NULL; lastBuffer = txBuffer; /* decrement bytes left to transmit */ txBytes -= bytes; } else /* no tx buffers available */ { stats[hssPortId].pkt[hdlcPortId].txNoBuffers++; } /* let higher priority tasks run (i.e. channelised service) */ ixOsalYield(); } while ((txBytes > 0) && (txBuffer != NULL)); } /* if (!ixHssAccCodeletCodeletLoopbackGet ()) */ /* if we have a buffer to transmit */ if (txBufferChain != NULL) { /* transmit the packet */ status = ixHssAccPktPortTx (hssPortId, hdlcPortId, txBufferChain); /* if there was any problem then return buffer and update stats */ if (status != IX_SUCCESS) { stats[hssPortId].pkt[hdlcPortId].txBufsInUse -= mbufsCount (txBufferChain); ixHssAccCodeletMbufChainFree (txBufferChain); stats[hssPortId].pkt[hdlcPortId].txFails++; } } /********************/ /* RECEIVE A PACKET */ /********************/ /* nothing to do here - RX happens via callback routines */}/* * Function definition: ixHssAccCodeletPacketisedServiceStop */voidixHssAccCodeletPacketisedServiceStop ( IxHssAccHssPort hssPortId, IxHssAccHdlcPort hdlcPortId){ IX_STATUS status; unsigned elapsedMilliseconds; ClientInfo *pClientInfo = &clientInfo[hssPortId][hdlcPortId]; /****************/ /* STOP SERVICE */ /****************/ /* stop the Packetised Service for the client */ status = ixHssAccPktPortDisable (hssPortId, hdlcPortId); /* if there was any problem then update stats */ if (status != IX_SUCCESS) { stats[hssPortId].pkt[hdlcPortId].portDisableFails++; } /**********************/ /* DISCONNECT SERVICE */ /**********************/ /* disconnect the Packetised Service for the client */ status = ixHssAccPktPortDisconnect (hssPortId, hdlcPortId); /* if the service is in the process of disconnnecting */ if (status == IX_HSSACC_PKT_DISCONNECTING) { elapsedMilliseconds = 0; /* wait for a maximum of 250ms */ while (elapsedMilliseconds < 250) { /* if the disconnect is complete then exit with success */ if (ixHssAccPktPortIsDisconnectComplete ( hssPortId, hdlcPortId)) { status = IX_SUCCESS; break; } /* wait for 50ms */ ixOsalSleep (50); elapsedMilliseconds += 50; } } /* if there was any problem then update stats */ if (status != IX_SUCCESS) { stats[hssPortId].pkt[hdlcPortId].disconnectFails++; } /***************/ /* STOP THREAD */ /***************/ /* wait for thread to finish processing messages */ while (pClientInfo->qTail != pClientInfo->qHead) { /* wait for 50ms */ ixOsalSleep (50); }}/* * Function definition: ixHssAccCodeletPacketisedVerifySet */voidixHssAccCodeletPacketisedVerifySet ( BOOL verifyOn){ verify = verifyOn;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -