📄 ixatmdtxcfginfo.c
字号:
vcDescriptor->currentNpeDesc = 0; vcDescriptor->remainingPduCellCount = 0; IX_ATMDACC_FULL_STATS( vcDescriptor->txSubmitOverloadedCount = 0; vcDescriptor->txVcPduSubmitFailureCount = 0; ); /* update the descriptor fields */ for (descCount = 0; returnStatus == IX_SUCCESS && descCount < actualSwQueueSize; descCount++) { IxAtmdAccNpeDescriptor *npeDescriptor; /* get a NPE descriptor */ returnStatus = ixAtmdAccDescNpeDescriptorGet (&npeDescriptor); if (returnStatus == IX_SUCCESS) { IX_ATMDACC_TXQ_ENTRY_IDXSET (txSwQueue, descCount, npeDescriptor); /*fill the NPE descriptor */ npeDescriptor->atmd.connId = connId; npeDescriptor->npe.tx.port = port; npeDescriptor->npe.tx.atmCellHeader = 0; IX_NPE_A_ATMCELLHEADER_VPI_SET(npeDescriptor->npe.tx.atmCellHeader, vpi); IX_NPE_A_ATMCELLHEADER_VCI_SET(npeDescriptor->npe.tx.atmCellHeader, vci); IX_ATMDACC_CONVERT_TO_BIG_ENDIAN( UINT32, npeDescriptor->npe.tx.atmCellHeader); npeDescriptor->npe.tx.aalType = npeAalType; } /* end of if(returnStatus) */ } /* end of for(descCount) */ } /* end of if(returnStatus) */ } /* rollback if error */ if (returnStatus != IX_SUCCESS) { ixAtmdAccTxCfgChannelReset (txId); } return returnStatus;}/* -------------------------------------------------* reset the vc channel structure*/IX_STATUS ixAtmdAccTxCfgChannelReset (unsigned int txId){ unsigned int descCount; unsigned int queueSize; IX_STATUS returnStatus = IX_SUCCESS; IxAtmdAccTxVcDescriptor *vcDescriptor = &ixAtmdAccTxVcDescriptor[txId]; IX_ATMDACC_TX_QUEUE *txSwQueue = &vcDescriptor->queue; /* reset the descriptor parameters */ vcDescriptor->connId = IX_ATMDACC_TX_INVALID_CONNID; /* store an invalid value */ vcDescriptor->port = NPE_INVALID_LOGICAL_PORT; /* store an invalid value */ vcDescriptor->vpi = NPE_INVALID_VPI; /* store an invalid value */ vcDescriptor->vci = NPE_INVALID_VCI; IX_ATMDACC_TXQ_RESET (txSwQueue); /* if any descriptors exist then release them */ if (IX_ATMDACC_TXQ_INITIALISED (txSwQueue)) { queueSize = IX_ATMDACC_TXQ_SIZE (txSwQueue); for (descCount = 0; descCount < queueSize; descCount++) { IxAtmdAccNpeDescriptor *npeDescriptor = IX_ATMDACC_TXQ_ENTRY_IDXGET (txSwQueue, descCount); if (npeDescriptor != NULL) { ixAtmdAccDescNpeDescriptorRelease (npeDescriptor); } } /* end of for(descCount) */ /* release the memory used by the tx software NPE descriptor pointer queue */ IX_ATMDACC_TXQ_RELEASE_RESOURCES (txSwQueue); } /* end of if(IX_ATMDACC_TXQ_INITIALISED) */ return returnStatus;}/* -------------------------------------------------* get the index in the pool of vcs*/IX_STATUSixAtmdAccTxCfgIndexGet (IxAtmConnId connId, unsigned int *txId){ IxAtmdAccTxVcDescriptor *vcDescriptor; IX_STATUS returnStatus = IX_SUCCESS; *txId = IX_ATMDACC_TX_VC_INDEX_GET (connId); vcDescriptor = &ixAtmdAccTxVcDescriptor[*txId]; /* check if the connection ID is valid */ if (vcDescriptor->connId != connId) { /* check if the connection ID has been invalidated */ if (!IX_ATMDACC_TX_DISCONNECTCHECK (connId, vcDescriptor->connId)) { /* the connection ID does not correspond with the expected one */ returnStatus = IX_FAIL; } } /* end of if(vcDescriptor) */ return returnStatus;}/* ----------------------------------------------* Invalidate the connId in the descriptor at this* index in the tx descriptor pool*/voidixAtmdAccTxCfgConnIdInvalidate (unsigned int txId){ IxAtmdAccTxVcDescriptor *vcDescriptor = &ixAtmdAccTxVcDescriptor[txId]; /* check if the connId is already invalidated */ if (!IX_ATMDACC_TX_DISCONNECTED (vcDescriptor->connId)) { vcDescriptor->connId = IX_ATMDACC_TX_DISCONNECTING (vcDescriptor->connId); /* connId is now invalidated : a direct comparison of the connId * passed as a parameter and the connId stored in the structure * will fail */ } return;}/* --------------------------------------------------* check if any tx descriptors are still in use*/BOOLixAtmdAccTxCfgFreeResourcesCheck (unsigned int txId){ BOOL result = TRUE; IxAtmdAccTxVcDescriptor *vcDescriptor = &ixAtmdAccTxVcDescriptor[txId]; IX_ATMDACC_TX_QUEUE *txSwQueue = &vcDescriptor->queue; /* check if resources are all transmitted */ if ((ixAtmdAccPortDescriptor[vcDescriptor->port].status == IX_ATMDACC_PORT_DOWN_PENDING) || IX_ATMDACC_TXQ_SCHEDULE_PENDING (txSwQueue) || IX_ATMDACC_TXQ_RECYCLE_PENDING (txSwQueue)) { /* resources are not all free: everything is not transmitted OR * tx done is not complete */ result = FALSE; } /* end of if(ixAtmdAccPortDescriptor) */ return result;}/* ---------------------------------------------------* store the user callback, and regsiter the corresponding* Atmd callback with Qmgr.*/IX_STATUSixAtmdAccTxCfgTxDoneCallbackRegister (unsigned int thresholdLevel, IxAtmdAccTxDoneDispatcher newCallback){ IX_STATUS returnStatus = IX_SUCCESS; /* check the threshold is less than the queue size */ if (thresholdLevel > (IX_ATMDACC_TXDONE_QUEUE_SIZE / 2)) { returnStatus = IX_FAIL; } else { /* store the new callback before registering * Atmd with Qmgr because this enables interrupts */ ixAtmdAccTxDoneDispatcher = newCallback; /* register with Qmgr */ if(ixAtmdAccUtilQmgrCallbackSet (IX_NPE_A_QMQ_ATM_TX_DONE, thresholdLevel, /* N.B. The NPE reserves the High Watermark for its operation. But it must be set by the Xscale. */ IX_NPE_A_TXDONE_QUEUE_HIGHWATERMARK, IX_QMGR_Q_SOURCE_ID_NOT_NE, ixAtmdAccTxDoneCallBack, (IxQMgrCallbackId)IX_NPE_A_QMQ_ATM_TX_DONE, IX_QMGR_Q_PRIORITY_1) != IX_SUCCESS) { returnStatus = IX_FAIL; } } return returnStatus;}/* ---------------------------------------------------* Disable Notification for IX_NPE_A_QMQ_ATM_TX_DONE Queue.*/voidixAtmdAccTxCfgTxDoneCallbackUnregister (void){ ixQMgrNotificationDisable (IX_NPE_A_QMQ_ATM_TX_DONE);}/* -----------------------------------------------------* store the user callback, and regsiter the corresponding* Atmd callback with Qmgr.*/IX_STATUSixAtmdAccTxCfgTxCallbackRegister (IxAtmLogicalPort port, unsigned int newThresholdLevel, IxAtmdAccPortTxLowCallback newCallback){ IX_STATUS returnStatus = IX_SUCCESS; IxQMgrQId txQueueId = ixAtmdAccPortDescriptor[port].txQueueId; /* check the threshold is less than the queue size */ if (newThresholdLevel > (ixAtmdAccPortDescriptor[port].txQueueSize / 2)) { returnStatus = IX_FAIL; } else { /* store the new callback before registering * Atmd with Qmgr because this enables interrupts */ ixAtmdAccPortDescriptor[port].txLowCallback = newCallback; ixAtmdAccPortDescriptor[port].txQueueThreshold = newThresholdLevel; /* register with Qmgr */ if(ixAtmdAccUtilQmgrCallbackSet (txQueueId, newThresholdLevel, newThresholdLevel, IX_QMGR_Q_SOURCE_ID_NE, ixAtmdAccTxLowCallBack, (IxQMgrCallbackId) port, IX_QMGR_Q_PRIORITY_0) != IX_SUCCESS) { returnStatus = IX_FAIL; } } return returnStatus;}/* ---------------------------------------------------* Disable Notification for IX_NPE_A_QMQ_ATM_TX_DONE Queue.*/voidixAtmdAccTxCfgTxCallbackUnregister (IxAtmLogicalPort port){ IxQMgrQId txQueueId = ixAtmdAccPortDescriptor[port].txQueueId; ixQMgrNotificationDisable (txQueueId);}/* ------------------------------------------------------* dummy scheduler clear callback*/voidixAtmdAccTxDummyDemandClear (IxAtmLogicalPort port, int vcId){ /* nothing to do because the dummy scheduler has no state */ return;}/* -------------------------------------------------------* get the schedluer Id from the dummy scheduler*/IX_STATUSixAtmdAccTxDummyVcIdGet (IxAtmLogicalPort port, unsigned int vpi, unsigned int vci, IxAtmConnId connId, int *vcId){ /* for the dummy scheduler we use the Tx index as the scheduler Id */ *vcId = IX_ATMDACC_TX_VC_INDEX_GET (connId); return IX_SUCCESS;}/* --------------------------------------------------------* store the user scheduler callbacks, for the specified port*/voidixAtmdAccTxCfgSchCallbackRegister (IxAtmLogicalPort port, IxAtmdAccTxVcDemandUpdateCallback demandUpdate, IxAtmdAccTxVcDemandClearCallback demandClear, IxAtmdAccTxSchVcIdGetCallback vcIdGet){ ixAtmdAccPortDescriptor[port].schDemandUpdate = demandUpdate; ixAtmdAccPortDescriptor[port].schDemandClear = demandClear; ixAtmdAccPortDescriptor[port].schVcIdGet = vcIdGet; return;}/* --------------------------------------------------------* Reset the scheduler callbacks, for the specified port*/voidixAtmdAccTxCfgSchCallbackUnregister (IxAtmLogicalPort port){ /* Load dummy callbacks to unregister */ ixAtmdAccPortDescriptor[port].schDemandUpdate = ixAtmdAccTxDummyDemandUpdate; ixAtmdAccPortDescriptor[port].schDemandClear = ixAtmdAccTxDummyDemandClear; ixAtmdAccPortDescriptor[port].schVcIdGet = ixAtmdAccTxDummyVcIdGet;}/* ----------------------------------------------------------* force the NPE tx queue to contain ony idle cells for* this channel*/IX_STATUSixAtmdAccTxCfgPortResourcesRelease (IxAtmConnId connId){ unsigned int txId; IxAtmLogicalPort port; IxAtmdAccTxVcDescriptor *vcDescriptor; IX_ATMDACC_TX_QUEUE *txSwQueue; IxAtmdAccNpeDescriptor *npeDescriptor; IX_OSAL_MBUF *mbufPtr; UINT32 qEntry; IX_STATUS returnStatus = IX_SUCCESS; unsigned int entryIndex = 0; txId = IX_ATMDACC_TX_VC_INDEX_GET (connId); vcDescriptor = &ixAtmdAccTxVcDescriptor[txId]; txSwQueue = &vcDescriptor->queue; port = vcDescriptor->port; if ((ixAtmdAccPortDescriptor[vcDescriptor->port].status == IX_ATMDACC_PORT_DOWN) && (vcDescriptor->pduTransmitInProgress == FALSE) && (ixAtmdAccPortDescriptor[port].schedulingInProgress == FALSE) && (IX_ATMDACC_TXQ_SCHEDULE_PENDING (txSwQueue) || IX_ATMDACC_TXQ_RECYCLE_PENDING (txSwQueue))) { while ((returnStatus == IX_SUCCESS) && (ixQMgrQPeek (ixAtmdAccPortDescriptor[port].txQueueId, entryIndex, &qEntry)== IX_SUCCESS)) { IX_ATMDACC_CONVERT_FROM_BIG_ENDIAN (UINT32, qEntry); if ((qEntry == 0) || ((qEntry & NPE_TX_CELLTYPE_MASK) == NPE_TX_IDLECELL)) { /* idle cell or empty entry, nothing to do */ } else { /* it must be a data cell */ npeDescriptor = (IxAtmdAccNpeDescriptor *) (qEntry & NPE_DESCRIPTOR_MASK); IX_ATMDACC_CONVERT_TO_VIRTUAL_ADDRESS (npeDescriptor); /* check if the cell belong to this channel */ if (npeDescriptor->atmd.connId == connId) { /* force this entry to be an idle cell */ qEntry &= ~NPE_TX_CELLTYPE_MASK; qEntry |= NPE_TX_IDLECELL; IX_ATMDACC_CONVERT_TO_BIG_ENDIAN (UINT32, qEntry); /* write the queue entry */ returnStatus = ixQMgrQPoke (ixAtmdAccPortDescriptor[port].txQueueId, entryIndex, &qEntry); } /* end of if(npeDescriptor) */ } /* end of if-else(qEntry) */ /* check the next entry */ entryIndex++; } /* flush any pending PDUs by making it appear * that they have been scheduled */ while (IX_ATMDACC_TXQ_SCHEDULE_PENDING (txSwQueue)) { IX_ATMDACC_TXQ_TAIL_INCR (txSwQueue); } /* flush any pending PDUs by making it appear * that they have been transmitted */ while (IX_ATMDACC_TXQ_RECYCLE_PENDING (txSwQueue)) { npeDescriptor = IX_ATMDACC_TXQ_HEAD_ENTRY_GET (txSwQueue); mbufPtr = ixAtmdAccUtilMbufFromNpeFormatConvert (npeDescriptor->atmd.pRootMbuf, FALSE); IX_ATMDACC_TXQ_HEAD_INCR (txSwQueue); vcDescriptor->txDoneCallback (vcDescriptor->callbackId, mbufPtr); } } /* end of if(ixAtmdAccPortDescriptor) */ return returnStatus;}/* ----------------------------------------------------------* Handle port state changes initiated by PortMgmt*/IX_STATUSixAtmdAccTxPortStateChangeHandler(IxAtmLogicalPort port, IxAtmdAccPortState requestedState){ IX_STATUS returnStatus = IX_SUCCESS; switch (ixAtmdAccPortDescriptor[port].status) { case IX_ATMDACC_PORT_UP: if (requestedState == IX_ATMD_PORT_DISABLED) { /* set the state to be "down pending". When the acknowledge message will * be received through the tx done queue, the state will be changed * to "down" */ ixAtmdAccPortDescriptor[port].status = IX_ATMDACC_PORT_DOWN_PENDING; if (ixAtmdAccUtilNpeMsgSend(IX_NPE_A_MSSG_ATM_TX_DISABLE, port, NPE_IGNORE) != IX_SUCCESS) { /* rollback the state change */ ixAtmdAccPortDescriptor[port].status = IX_ATMDACC_PORT_UP; returnStatus = IX_FAIL; } /* end of if(ixAtmdAccUtilNpeMsgSend) */ } /* end of if(requestedState) */ else if (requestedState == IX_ATMD_PORT_ENABLED) { returnStatus = IX_ATMDACC_WARNING;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -