📄 ixatmdrxcfginfo.c
字号:
/* compute a hash value */ npeVcid = ixAtmdAccUtilHashVc (port, vpi, vci) % IX_ATM_MAX_NUM_AAL_VCS; /* find a free channel, starting from the hash value * iterate until the first available channel is found * and stop iterate when all channels are checked */ for (limit = 0; (limit < IX_ATM_MAX_NUM_AAL_VCS) && IX_ATMDACC_RX_VC_INUSE (ixAtmdAccRxVcDescriptor[npeVcid].connId); limit++) { npeVcid = npeVcid + 1; npeVcid = (npeVcid % IX_ATM_MAX_NUM_AAL_VCS); } /* check upperbound condition */ if (limit >= IX_ATM_MAX_NUM_AAL_VCS) { /* no channel available */ returnStatus = IX_ATMDACC_BUSY; } break; case IX_ATMDACC_OAM: /* allocate a fixed channel outside the hashing range for OAM */ npeVcid = IX_ATM_MAX_NUM_AAL_OAM_RX_VCS-1; break; default: /* Params were checked on API this should be impossible */ IX_ATMDACC_ENSURE(0,"Bad serviceType"); break; } if (returnStatus == IX_SUCCESS) { /* the channel is available */ *npeVcIdPtr = npeVcid; /* the connection Id is constructed from the NpeVcId, * and an unique ID. This allow to quickly retrieve * the channel from a connection ID and also to avoid * connection ID garbage from the user. A flag is * also merged in the connection ID to quickly detect * race conditions (e.g. disconnect in progress). This is * done to improve performances of happy day scenarios */ *connIdPtr = npeVcid + (ixAtmdAccUtilUniqueIdGet () * IX_ATM_MAX_NUM_AAL_OAM_RX_VCS); } /* end of if-else(limit) */ return returnStatus;}/* ---------------------------------------------------------* search the smallest available RxFree queue*/IX_STATUSixAtmdAccRxCfgFreeQueueGet (IxAtmdAccAalType aalServiceType, unsigned int minimumQueueSize, unsigned int npeVcId){ unsigned int optimumQueueSize = IX_QMGR_Q_SIZE_INVALID; unsigned int optimumQueueIdx = IX_QMGR_QUEUE_INVALID; unsigned int queueIdx; IX_STATUS returnStatus = IX_SUCCESS; switch( aalServiceType ) { case IX_ATMDACC_AAL5: case IX_ATMDACC_AAL0_48: case IX_ATMDACC_AAL0_52: /* find the smallest rx free queue */ for (queueIdx = 0; queueIdx < ixAtmdAccRxFreeQueueCount; queueIdx++) { /* check if the queue is unused */ if (ixAtmdAccRxFreeQueueTable[queueIdx].used == FALSE) { unsigned int qSize = ixAtmdAccRxFreeQueueTable[queueIdx].rxFreeQueueSize; /* search the smallest queue * - if no size is required, get the smallest queue * - if a size is required, get the queue which size is the * closest to the requested queue size */ if (((minimumQueueSize == IX_ATMDACC_DEFAULT_REPLENISH_COUNT) && (qSize < optimumQueueSize)) || ((minimumQueueSize != IX_ATMDACC_DEFAULT_REPLENISH_COUNT) && (qSize >= minimumQueueSize) && (qSize < optimumQueueSize))) { /* this queue is the smallest queue larger than * required */ optimumQueueSize = qSize; optimumQueueIdx = queueIdx; } /* end of if(minimumQueueSize) */ } /* end of if(ixAtmdAccRxFreeQueueTable) */ } /* end of for(queueIdx) */ if (optimumQueueSize == IX_QMGR_Q_SIZE_INVALID) { /* queue with appropriate size not found */ returnStatus = IX_FAIL; } else { /* update the internal structure */ ixAtmdAccRxVcDescriptor[npeVcId].rxFreeQueueId = ixAtmdAccRxFreeQueueTable[optimumQueueIdx].rxFreeQueueId; ixAtmdAccRxVcDescriptor[npeVcId].rxFreeQueueSize = optimumQueueSize; ixAtmdAccRxFreeQueueTable[optimumQueueIdx].used = TRUE; } /* end of if-else(optimumQueueSize) */ break; case IX_ATMDACC_OAM: /* Note that the input parameter minimum queue size is ignore doe OAM * because only one fixed OAM free queue exists */ ixAtmdAccRxVcDescriptor[npeVcId].rxFreeQueueId = IX_NPE_A_QMQ_OAM_FREE_VC; ixAtmdAccRxVcDescriptor[npeVcId].rxFreeQueueSize = IX_ATMDACC_QMGR_OAM_FREE_QUEUE_SIZE; break; default: /* param is checked on API, should never happen */ IX_OSAL_ENSURE(0,"Bad Service type"); returnStatus = IX_FAIL; break; } return returnStatus;} /* ---------------------------------------------------------* set all channels parameters*/IX_STATUSixAtmdAccRxCfgChannelSet (IxAtmConnId connId, unsigned int npeVcId, IxAtmLogicalPort port, unsigned int vpi, unsigned int vci, IxAtmdAccAalType aalServiceType, IxAtmRxQueueId rxQueueId, IxAtmdAccUserId userId, IxAtmdAccRxVcRxCallback rxDoneCallback){ UINT8 timeLimit = 0; unsigned int queueSize = 0; unsigned int descCount; IX_STATUS returnStatus = IX_SUCCESS; IxAtmdAccRxVcDescriptor *vcDescriptor; IX_ATMDACC_RX_QUEUE *rxSwQueue; IxAtmdAccNpeDescriptor *npeDescriptor; vcDescriptor = &ixAtmdAccRxVcDescriptor[npeVcId]; rxSwQueue = &vcDescriptor->queue; /* fill the descriptors parameters */ vcDescriptor->connId = connId; vcDescriptor->port = port; vcDescriptor->vpi = vpi; vcDescriptor->vci = vci; vcDescriptor->callbackId = userId; vcDescriptor->rxDoneCallback = rxDoneCallback; vcDescriptor->rxStreamId = rxQueueId; vcDescriptor->rxFreeNotification = ixAtmdAccRxFreeDummyNotification; /* service specific initializations */ switch( aalServiceType ) { case IX_ATMDACC_AAL5: vcDescriptor->npeAalType = NPE_AAL5_TYPE; vcDescriptor->cellSize = IX_ATM_CELL_PAYLOAD_SIZE; vcDescriptor->pduValidStatusCode = IX_ATMDACC_AAL5_VALID; vcDescriptor->pduInvalidStatusCode = IX_ATMDACC_AAL5_CRC_ERROR; /* the sw queue size is based on the rxFree qmgr queue size * (there is 1 descriptor per mbuf) plus the descriptors needed by * the NPE to build a 64Kb PDU, plus the descriptors needed to hold * a certain amount of PDUs in the RX queue. */ queueSize = vcDescriptor->rxFreeQueueSize + IX_ATMDACC_RX_NUMBER_OF_DESCRIPTORS; /* check the sw queue does not reach NPE limits (the NPE is unable * to chain more than 256 mbufs. The way to prevent it is to ensure * that there is less than 256 mbufs provided to the npe for 1 channel. * This is done by limitation of the sw queue size. */ if(queueSize > IX_NPE_A_CHAIN_DESC_COUNT_MAX) { queueSize = IX_NPE_A_CHAIN_DESC_COUNT_MAX; } break; case IX_ATMDACC_AAL0_48: vcDescriptor->npeAalType = NPE_AAL0_48_TYPE; vcDescriptor->cellSize = IX_ATM_AAL0_48_CELL_PAYLOAD_SIZE; vcDescriptor->pduValidStatusCode = IX_ATMDACC_AAL0_VALID; vcDescriptor->pduInvalidStatusCode = IX_ATMDACC_AAL0_VALID; timeLimit = IX_ATMDACC_AAL0_RX_TIMEOUT + 1; /* the sw queue size is based on the rxFree qmgr queue size * ( there is 1 descriptor per mbuf), plus the descriptors needed to hold * a certain amount of PDUs in the RX queue. There is no rx chaining, */ queueSize = vcDescriptor->rxFreeQueueSize + IX_ATMDACC_MAX_RX_PDU_PENDING; break; case IX_ATMDACC_AAL0_52: vcDescriptor->npeAalType = NPE_AAL0_52_TYPE; vcDescriptor->cellSize = IX_ATM_AAL0_52_CELL_SIZE_NO_HEC; vcDescriptor->pduValidStatusCode = IX_ATMDACC_AAL0_VALID; vcDescriptor->pduInvalidStatusCode = IX_ATMDACC_AAL0_VALID; timeLimit = IX_ATMDACC_AAL0_RX_TIMEOUT + 1; /* the sw queue size is based on the rxFree qmgr queue size * ( there is 1 descriptor per mbuf), plus the descriptors needed to hold * a certain amount of PDUs in the RX queue. There is no rx chaining, */ queueSize = vcDescriptor->rxFreeQueueSize + IX_ATMDACC_MAX_RX_PDU_PENDING; break; case IX_ATMDACC_OAM: vcDescriptor->npeAalType = NPE_OAM_TYPE; vcDescriptor->cellSize = IX_ATM_AAL0_52_CELL_SIZE_NO_HEC; vcDescriptor->pduValidStatusCode = IX_ATMDACC_OAM_VALID; vcDescriptor->pduInvalidStatusCode = IX_ATMDACC_OAM_VALID; /* the sw queue size is based on the rxFree qmgr queue size * ( there is 1 descriptor per mbuf), plus the descriptors needed to hold * a certain amount of PDUs in the RX queue. There is no rx chaining, */ queueSize = vcDescriptor->rxFreeQueueSize + IX_ATMDACC_MAX_RX_PDU_PENDING; break; default: /* Params are checked on API, so this should never happen */ IX_ATMDACC_ENSURE(0,"Bad service type"); break; } /* Initialise the RX Queue */ IX_ATMDACC_RXQ_INIT(rxSwQueue,queueSize, vcDescriptor->swQueueBuffer); /* check if the initialisation is complete */ if(!IX_ATMDACC_RXQ_INITIALISED(rxSwQueue)) { returnStatus = IX_FAIL; } if(returnStatus == IX_SUCCESS) { /* convert from the atmd rx queueId to the qmgr rx queue id */ returnStatus = ixAtmdAccUtilQmgrQIdGet (vcDescriptor->rxStreamId, &vcDescriptor->rxQueueId); } if (returnStatus == IX_SUCCESS) { for (descCount = 0; (returnStatus == IX_SUCCESS) && (descCount < IX_ATMDACC_RXQ_SIZE(rxSwQueue)); descCount++) { /* get a NPE descriptor and indicate how many descriptors * will be required for this queue, to anticipate allocation */ returnStatus = ixAtmdAccDescNpeDescriptorGet (&npeDescriptor); IX_ATMDACC_ENSURE (npeDescriptor != 0, "Unable to allocate a descriptor"); if (returnStatus == IX_SUCCESS) { /* allocation is sucessful */ IX_ATMDACC_RXQ_ENTRY_IDXSET(rxSwQueue, descCount, npeDescriptor); /* update the descriptor fields */ npeDescriptor->atmd.connId = connId; IX_NPE_A_RXBITFIELD_PORT_SET(npeDescriptor->npe.rx.rxBitField, port); IX_ATMDACC_CONVERT_TO_BIG_ENDIAN(UINT32, npeDescriptor->npe.rx.rxBitField); npeDescriptor->npe.rx.atmCellHeader = 0; IX_NPE_A_ATMCELLHEADER_GFC_SET(npeDescriptor->npe.rx.atmCellHeader, 0); IX_NPE_A_ATMCELLHEADER_VPI_SET(npeDescriptor->npe.rx.atmCellHeader, vpi); IX_NPE_A_ATMCELLHEADER_VCI_SET(npeDescriptor->npe.rx.atmCellHeader, vci); IX_ATMDACC_CONVERT_TO_BIG_ENDIAN(UINT32, npeDescriptor->npe.rx.atmCellHeader); npeDescriptor->npe.rx.timeLimit = timeLimit; } /* end of if(returnStatus) */ } /* end of for(descCount) */ } /* end of if(returnStatus) */ if (returnStatus != IX_SUCCESS) { /* rollback if error */ ixAtmdAccRxCfgChannelReset (npeVcId); } return returnStatus;}/* ----------------------------------------* disble the rxfree threshold events*/IX_STATUS ixAtmdAccRxCfgRxFreeCallbackDisable (unsigned int npeVcId){ IX_STATUS returnStatus = IX_SUCCESS; IxAtmdAccRxVcDescriptor *descriptor; descriptor = &ixAtmdAccRxVcDescriptor[npeVcId]; /* check if notifications are enabled */ if (descriptor->rxFreeNotification != ixAtmdAccRxFreeDummyNotification) { /* disable interrupts */ returnStatus = ixQMgrNotificationDisable (descriptor->rxFreeQueueId); if (returnStatus != IX_SUCCESS) { returnStatus = IX_FAIL; } else { /* move the queue priority to low */ returnStatus = ixQMgrDispatcherPrioritySet (descriptor->rxFreeQueueId, IX_QMGR_Q_PRIORITY_2); if (returnStatus != IX_SUCCESS) { returnStatus = IX_FAIL; } } /* mark the rx free notifications as * disabled (regardless of the qmgr status) */ descriptor->rxFreeNotification = ixAtmdAccRxFreeDummyNotification; } return returnStatus;}/* ----------------------------------------* reset the channel parameters*/IX_STATUS ixAtmdAccRxCfgChannelReset (unsigned int npeVcId){ unsigned int descCount; unsigned int queueIdx; IX_STATUS returnStatus = IX_SUCCESS; IxAtmdAccRxVcDescriptor *descriptor; IX_ATMDACC_RX_QUEUE *rxSwQueue; BOOL queueFound = FALSE; descriptor = &ixAtmdAccRxVcDescriptor[npeVcId]; rxSwQueue = &descriptor->queue; /* Reset the channel and the channel's data to default * (unalloacted) state */ ixAtmdAccRxCfgChannelIdReset(descriptor); descriptor->rxQueueId = IX_QMGR_QUEUE_INVALID; /* set the rx free queue to idle */ for (queueIdx = 0; (queueFound == FALSE) && (queueIdx < ixAtmdAccRxFreeQueueCount); queueIdx++) { if (ixAtmdAccRxFreeQueueTable[queueIdx].rxFreeQueueId == descriptor->rxFreeQueueId) { ixAtmdAccRxFreeQueueTable[queueIdx].used = FALSE; queueFound = TRUE; } } /* end of for(queueIdx) */ descriptor->rxFreeQueueId = IX_QMGR_QUEUE_INVALID; descriptor->rxFreeQueueSize = IX_QMGR_Q_SIZE_INVALID; descriptor->rxFreeNotification = ixAtmdAccRxFreeDummyNotification; /* reinitialize the array of descriptor pointers */ if (IX_ATMDACC_RXQ_INITIALISED(rxSwQueue)) { for (descCount = 0; descCount < IX_ATMDACC_RXQ_SIZE(rxSwQueue); descCount++) { IxAtmdAccNpeDescriptor *npeDescriptor = IX_ATMDACC_RXQ_ENTRY_IDXGET(rxSwQueue,descCount); if (npeDescriptor != NULL) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -