zl5011xtfm.c
来自「Zalink50114----TDMoIP芯片驱动源码」· C语言 代码 · 共 1,986 行 · 第 1/5 页
C
1,986 行
if (status == ZL5011X_OK)
{
zl5011xParams->wanIf.tfmCurrent.context[context].numChannels--;
bits = 0;
bitMask = (ZL5011X_1BIT_MASK << ZL5011X_TFM_NEW_FIRST_CHAN_BIT) |
(ZL5011X_1BIT_MASK << ZL5011X_TFM_NEW_VALID_CHAN_BIT);
status = zl5011xReadModWrite(zl5011xParams,
ZL5011X_TFM_CONTEXT_LOOKUP + (chanIndex * ZL5011X_TFM_LKUP_MEM_SIZE),
bits, bitMask);
/* update the structure */
zl5011xParams->wanIf.tfmCurrent.channel[chanIndex].context = (Uint32T)ZL5011X_INVALID_CONTEXT;
if (zl5011xParams->wanIf.tfmCurrent.context[context].firstChannelIndex == chanIndex)
{
zl5011xParams->wanIf.tfmCurrent.context[context].firstChannelIndex = (Uint32T)ZL5011X_INVALID_CHANNEL;
}
}
return(status);
}
/*******************************************************************************
Function:
zl5011xTfmSetChanUnderrun
Description:
Sets the underrun mode and byte for the channel. This takes effect
immediately, is context independent and does not require an update.
Inputs:
zl5011xParams Pointer to the structure for this device instance
tdm stream / channel to set the underrun for
underrunByte 8 bits to be used for underrun
mode controls whether the underrun byte is taken from the passed
in parameter, or is simply a repeat of the last byte.
Outputs:
None
Returns:
zlStatusE
Remarks:
None
*******************************************************************************/
zlStatusE zl5011xTfmSetChanUnderrun(zl5011xParamsS *zl5011xParams,
zl5011xWanChannelS tdm, Uint8T underrunByte, zl5011xWanIfUnderrunModeE mode)
{
zlStatusE status = ZL5011X_OK;
Uint32T bits;
Uint32T bitMask;
Uint32T chanIndex;
status = ZL5011X_CHECK_WAN_IF_UNDERRUN_MODE(mode);
if (status == ZL5011X_OK)
{
status = zl5011xCalcChanIndex(zl5011xParams, tdm, &chanIndex);
}
if (status == ZL5011X_OK)
{
ZL5011X_TRACE_CONTEXT(ZL5011X_TFM_FN_ID, zl5011xParams->wanIf.tfmCurrent.channel[chanIndex].context,
"zl5011xTfmSetChanUnderrun: context %3d, stream %2d, chan %2d, mode = %d, byte = %d",
zl5011xParams->wanIf.tfmCurrent.channel[chanIndex].context,
tdm.stream, tdm.channel, (Uint32T)mode, underrunByte, 0);
/* set the bits in the register */
bits = (underrunByte << ZL5011X_TFM_UNDERRUN_BYTE_BITS)
| (mode << ZL5011X_TFM_UNDERRUN_MODE_BIT);
bitMask = (ZL5011X_TFM_UNDERRUN_BYTE_MASK << ZL5011X_TFM_UNDERRUN_BYTE_BITS)
| (ZL5011X_1BIT_MASK << ZL5011X_TFM_UNDERRUN_MODE_BIT);
status = zl5011xReadModWrite(zl5011xParams,
ZL5011X_TFM_CONTEXT_LOOKUP + (chanIndex * ZL5011X_TFM_LKUP_MEM_SIZE),
bits, bitMask);
/* save the settings in the device structure */
zl5011xParams->wanIf.tfmCurrent.channel[chanIndex].underrunMode = mode;
zl5011xParams->wanIf.tfmCurrent.channel[chanIndex].underrunByte = underrunByte;
}
return(status);
}
/*******************************************************************************
Function:
zl5011xTfmUpdateFirstChan
Description:
The first channel must be identified correctly before a context is updated.
This function scans the current structure to find the first channel. If the
first channel is no longer correct, then the new first channel is identified
to the device.
Inputs:
zl5011xParams Pointer to the structure for this device instance
context which context to do the first channel update for
Outputs:
None
Returns:
zlStatusE
Remarks:
In any add / remove channel operations the first channel is not tracked.
*******************************************************************************/
zlStatusE zl5011xTfmUpdateFirstChan(zl5011xParamsS *zl5011xParams,
Uint32T context)
{
zlStatusE status = ZL5011X_OK;
zl5011xBooleanE foundFirst = ZL5011X_FALSE;
zl5011xWanChannelS tdm;
Uint32T chanIndex, loop, activeChannels;
ZL5011X_TRACE_CONTEXT(ZL5011X_TFM_FN_ID, context,
"zl5011xTfmUpdateFirstChan: context %3d",
context, 0, 0, 0, 0, 0);
/* the loops are arranged to represent the order in which the device does
the search for the first channel -
i.e. channel 0 stream 0
channel 0 stream 1
channel 0 stream 2 etc. */
for (tdm.channel = 0; ((tdm.channel < zl5011xParams->wanIf.wanNumChannels ) &&
(foundFirst == ZL5011X_FALSE)); tdm.channel++)
{
/* Iterate around all possible streams. This allows non-contiguous stream numbers to be used */
for (tdm.stream = 0; ((tdm.stream < ZL5011X_MAX_NUMBER_STREAMS) &&
(foundFirst == ZL5011X_FALSE)); tdm.stream++)
{
if (status != ZL5011X_OK)
{
break;
}
/* Check that this stream is valid for this device. */
if (zl5011xCheckStreamRange(zl5011xParams, tdm.stream) == ZL5011X_OK)
{
status = zl5011xCalcChanIndex(zl5011xParams, tdm, &chanIndex);
if (status == ZL5011X_OK)
{
if (zl5011xParams->wanIf.tfmCurrent.channel[chanIndex].context == context)
{
foundFirst = ZL5011X_TRUE;
}
}
}
}
}
if (status == ZL5011X_OK)
{
/* if we have not found any channels, then something has gone seriously wrong */
if (foundFirst != ZL5011X_TRUE)
{
status = ZL5011X_CTXT_NO_CHANNELS;
}
}
if (status == ZL5011X_OK)
{
/* check that the number of channels is not being exceeded */
activeChannels = 0;
/* count the number of channels used by other contexts */
for (loop = 0; loop < ZL5011X_MAX_NUMBER_CHANNELS; loop++)
{
Uint32T tempContext;
/* check if a valid context number is specified in the active device copy */
tempContext = zl5011xParams->wanIf.tfmActive.channel[loop].context;
if (tempContext == (Uint32T)ZL5011X_INVALID_CONTEXT)
{
/* active context for this channel, so check in the modification copy */
tempContext = zl5011xParams->wanIf.tfmCurrent.channel[loop].context;
}
if ((tempContext != (Uint32T)ZL5011X_INVALID_CONTEXT) && (tempContext != context))
{
/* got a context for this channel and it's not the one we are updating */
switch (zl5011xParams->wanIf.tfmCurrent.context[tempContext].state)
{
case ZL5011X_STATE_TAKEN :
case ZL5011X_STATE_ACTIVE :
if (zl5011xParams->wanIf.tfmActive.channel[loop].context != (Uint32T)ZL5011X_INVALID_CONTEXT)
{
/* the device usage for the state is represented in the active device copy */
activeChannels++;
}
break;
case ZL5011X_STATE_UPDATING :
if (zl5011xParams->wanIf.tfmCurrent.channel[loop].context != (Uint32T)ZL5011X_INVALID_CONTEXT)
{
/* the device usage for the state is represented in the current device copy, that is
a change has been requested and the device is in the process of switching */
activeChannels++;
}
break;
case ZL5011X_STATE_NOT_IN_USE :
case ZL5011X_STATE_INIT :
case ZL5011X_STATE_TEARING_DOWN :
default :
/* channel not active */
break;
}
}
}
activeChannels += zl5011xParams->wanIf.tfmCurrent.context[context].numChannels;
if (activeChannels > zl5011xParams->devLimits.numChannels)
{
status = ZL5011X_CHANNEL_CAPACITY;
}
}
if (status == ZL5011X_OK)
{
if (zl5011xParams->wanIf.tfmCurrent.context[context].firstChannelIndex !=
chanIndex)
{
/* we have a new first channel, so reset the first bit in the old one */
status = zl5011xTfmClearFirstChan(zl5011xParams, context);
/* and set the first bit in the new one */
if (status == ZL5011X_OK)
{
status = zl5011xTfmSetFirstChan(zl5011xParams, context, chanIndex);
}
}
}
return status;
}
/*******************************************************************************
Function:
zl5011xTfmClearFirstChan
Description:
Clears the first channel for the context. Clears the bit in the channel mapping
for the device and sets the first channel in the context structure to invalid.
If the previous value was valid, then checks that it was in bounds.
Inputs:
zl5011xParams Pointer to the structure for this device instance
context context to reset the first channel for.
Outputs:
None
Returns:
zlStatusE
Remarks:
None
*******************************************************************************/
zlStatusE zl5011xTfmClearFirstChan(zl5011xParamsS *zl5011xParams, Uint32T context)
{
zlStatusE status = ZL5011X_OK;
Uint32T tempFirstIndex;
ZL5011X_TRACE_CONTEXT(ZL5011X_TFM_FN_ID, context,
"zl5011xTfmClearFirstChan: ctxt %4X",
context, 0, 0, 0, 0, 0);
tempFirstIndex = zl5011xParams->wanIf.tfmCurrent.context[context].firstChannelIndex;
/* if there wasn't a valid first channel, then just exit with OK, since
this is to be expected */
if (tempFirstIndex != (Uint32T)ZL5011X_INVALID_CHANNEL)
{
if (tempFirstIndex >= ZL5011X_MAX_NUMBER_CHANNELS)
{
status = ZL5011X_WAN_INVALID_FIRST_CHANNEL;
}
else
{
status = zl5011xReadModWrite(zl5011xParams,
ZL5011X_TFM_CONTEXT_LOOKUP + (tempFirstIndex * ZL5011X_TFM_LKUP_MEM_SIZE),
0,
ZL5011X_1BIT_MASK << ZL5011X_TFM_NEW_FIRST_CHAN_BIT);
zl5011xParams->wanIf.tfmCurrent.context[context].firstChannelIndex = (Uint32T)ZL5011X_INVALID_CHANNEL;
}
}
return(status);
}
/*******************************************************************************
Function:
zl5011xTfmSetFirstChan
Description:
Sets the first channel for the context. Sets the bit in the channel mapping
for the device and sets the first channel in the context structure to
the context.
Inputs:
zl5011xParams Pointer to the structure for this device instance
context context to set the first channel for.
chanIndex index into the array for the new first channel
Outputs:
None
Returns:
zlStatusE
Remarks:
None
*******************************************************************************/
zlStatusE zl5011xTfmSetFirstChan(zl5011xParamsS *zl5011xParams,
Uint32T context, Uint32T chanIndex)
{
zlStatusE status = ZL5011X_OK;
ZL5011X_TRACE_CONTEXT(ZL5011X_TFM_FN_ID, context,
"zl5011xTfmSetFirstChan: ctxt %4X, lkup %4X",
context, chanIndex, 0, 0, 0, 0);
status = zl5011xReadModWrite(zl5011xParams,
ZL5011X_TFM_CONTEXT_LOOKUP + (chanIndex * ZL5011X_TFM_LKUP_MEM_SIZE),
ZL5011X_1BIT_MASK << ZL5011X_TFM_NEW_FIRST_CHAN_BIT,
ZL5011X_1BIT_MASK << ZL5011X_TFM_NEW_FIRST_CHAN_BIT);
zl5011xParams->wanIf.tfmCurrent.context[context].firstChannelIndex = chanIndex;
return(status);
}
/*****************************************************************************
Function:
zl5011xTfmCheckChan
Description:
Checks if a channel is in use. If the channel is in use, then the context
number that it is attached to is returned.
If that context is in update or teardown, then a check is made to see if
the operation has finished. If it has, then the active and current structures
are updated.
Inputs:
zl5011xParams Pointer to the structure for this device instance
chanIndex Index used to represent the channel
Outputs:
context Use to pass back the context associated with the channel.
Can be either a channel or invalid if the channel is free.
Returns:
zlStatusE
*****************************************************************************/
zlStatusE zl5011xTfmCheckChan(zl5011xParamsS *zl5011xParams,
Uint32T *context, Uint32T chanIndex)
{
zlStatusE status = ZL5011X_OK;
Uint32T tempContext;
ZL5011X_TRACE(ZL5011X_TFM_FN_ID, "zl5011xTfmCheckChan: lkup %4X",
chanIndex, 0, 0, 0, 0, 0);
/* determine if the channel is associated with a context */
tempContext = zl5011xParams->wanIf.tfmActive.channel[chanIndex].context;
/* check the modification buffer if active is unused */
if (tempContext == (Uint32T)ZL5011X_INVALID_CONTEXT)
{
tempContext = zl5011xParams->wanIf.tfmCurrent.channel[chanIndex].context;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?