📄 zl5011xpla.c
字号:
Inputs:
zl5011xParams Pointer to the structure for this device instance
context which context to collect the
Outputs:
error bits are set to indicate the source of the error
Returns:
zlStatusE
Remarks:
None
*****************************************************************************/
zlStatusE zl5011xPlaGetError(zl5011xParamsS *zl5011xParams,
Uint32T context, Uint32T *error)
{
zlStatusE status = ZL5011X_OK;
Uint32T readValue= ZL5011X_SET_ALL_BITS_MASK;
/* disable interrupts - to avoid conflicts accessing the register */
(void)zl5011xHostInterruptDisable();
status = zl5011xWrite(zl5011xParams, ZL5011X_PLA_TEST_DATA_SEL, ZL5011X_ZERO_ALL );
if (status == ZL5011X_OK)
{
status = zl5011xRead(zl5011xParams,
ZL5011X_PLA_CONTEXT_ERROR + (context * ZL5011X_PLA_CTXT_ERR_SIZE),
&readValue);
}
/* enable interrupts */
(void)zl5011xHostInterruptEnable();
if (status == ZL5011X_OK)
{
*error = readValue & ((ZL5011X_1BIT_MASK << ZL5011X_PLA_QUEUE_ERR) |
(ZL5011X_1BIT_MASK << ZL5011X_PLA_QUEUE_WARN) |
(ZL5011X_1BIT_MASK << ZL5011X_PLA_CACHE_ERR) |
(ZL5011X_1BIT_MASK << ZL5011X_PLA_GRANULE_ERR) |
(ZL5011X_1BIT_MASK << ZL5011X_PLA_FRAME_ERR));
ZL5011X_TRACE(ZL5011X_PLA_FN_ID, "zl5011xPlaGetError: ctxt %3d, flags %X",
context, *error, 0, 0, 0, 0);
}
/* The register is cleared automatically after the read */
return(status);
}
/*****************************************************************************
Function:
zl5011xPlaGetNextError
Description:
This function is called from the interrupt routine to determine which
context caused the error. The error flags are returned.
It is the calling functions responsibility to ensure that there is an
entry on the interrupt queue - this is determined by checking that the
PLA is issuing an interrupt.
Inputs:
zl5011xParams Pointer to the structure for this device instance
Outputs:
context context for which interrupt occured
error bits are set to indicate the source of the error
Returns:
zlStatusE
Remarks:
None
*****************************************************************************/
zlStatusE zl5011xPlaGetNextError(zl5011xParamsS *zl5011xParams,
Uint32T *context, Uint32T *error)
{
zlStatusE status = ZL5011X_OK;
ZL5011X_TRACE(ZL5011X_PLA_FN_ID, "zl5011xPlaGetNextError:", 0, 0, 0, 0, 0, 0);
status = zl5011xPlaGetErroredContext(zl5011xParams, context);
if (status == ZL5011X_OK)
{
status = zl5011xPlaGetError(zl5011xParams, *context, error);
}
return(status);
}
/*******************************************************************************
Function:
zl5011xPlaEnableInterrupts
Description:
This function enables the interrupts in the context memory after first clearing them.
Inputs:
zl5011xParams Pointer to the structure for this device instance
context context number
bits - if a bit is set, then the interrupt is enabled.
Outputs:
None
Returns:
zlStatusE
Remarks:
The interrupt enable cannot be changed if an update or teardown is pending.
It is not safe to write to the register in these instances, since
the device will autonomously do a write to clear the bits at some point
There is another PLA interrupt - the TM intr but this is also registered in the ADM
block as well, so we ignore this one at the PLA level.
*******************************************************************************/
zlStatusE zl5011xPlaEnableInterrupts(zl5011xParamsS *zl5011xParams, Uint32T context,
Uint32T intBits)
{
zlStatusE status = ZL5011X_OK;
Uint32T bitMask, temp;
ZL5011X_TRACE(ZL5011X_PLA_FN_ID, "zl5011xPlaEnableInterrupts: ctxt %3d, mask %08X",
context, intBits, 0, 0, 0, 0);
bitMask = (ZL5011X_1BIT_MASK << ZL5011X_PLA_QUEUE_ERR_INT) |
(ZL5011X_1BIT_MASK << ZL5011X_PLA_QUEUE_WARN_INT) |
(ZL5011X_1BIT_MASK << ZL5011X_PLA_CACHE_ERR_INT) |
(ZL5011X_1BIT_MASK << ZL5011X_PLA_GRANULE_ERR_INT) |
(ZL5011X_1BIT_MASK << ZL5011X_PLA_FRAME_INT);
if ((intBits & ~bitMask) != 0)
{
status = ZL5011X_PARAMETER_INVALID;
}
if (status == ZL5011X_OK)
{
status = zl5011xRead(zl5011xParams,
ZL5011X_PLA_CONTEXT_MEMORY1 + (context * ZL5011X_PLA_CTXT_MEM1_SIZE),
&temp);
}
if (status == ZL5011X_OK)
{
/* check against mask (active LOW) */
if ((( ~temp) & intBits) != intBits)
{
/* the interrupt bits are to be changed, so check that neither
update or teardown are pending */
if ((temp & (ZL5011X_1BIT_MASK << ZL5011X_PLA_UPDATE_BIT)) != 0)
{
status = ZL5011X_CONTEXT_IN_UPDATE;
}
if ((temp & (ZL5011X_1BIT_MASK << ZL5011X_PLA_TEARDOWN_BIT)) != 0)
{
status = ZL5011X_CONTEXT_IN_TEARDOWN;
}
}
}
/* First clear the corresponding interrupt - by setting the error bit */
if(status == ZL5011X_OK)
{
/* clear any interrupt bits before enabling */
status = zl5011xWrite(zl5011xParams,
ZL5011X_PLA_CONTEXT_ERROR + (context * ZL5011X_PLA_CTXT_MEM1_SIZE), intBits);
}
if (status == ZL5011X_OK)
{
/* if don't need to change the interrupt bits then don't */
if ((( ~temp) & intBits) != intBits)
{
status = zl5011xWrite(zl5011xParams,
ZL5011X_PLA_CONTEXT_MEMORY1 + (context * ZL5011X_PLA_CTXT_MEM1_SIZE),
temp & ~intBits);
/* record the state in the device structure */
zl5011xParams->interruptMasks.wanRxMasks[context] = temp & ~intBits;
}
}
return(status);
}
/*******************************************************************************
Function:
zl5011xPlaDisableInterrupts
Description:
This function disables the interrupt sources in context memory.
Inputs:
zl5011xParams Pointer to the structure for this device instance
context context number
bits if a bit is set, then the interrupt is disabled.
Outputs:
None
Returns:
zlStatusE
Remarks:
see zl5011xPlaEnableInterrupts
*******************************************************************************/
zlStatusE zl5011xPlaDisableInterrupts(zl5011xParamsS *zl5011xParams, Uint32T context,
Uint32T intBits)
{
zlStatusE status = ZL5011X_OK;
Uint32T bitMask, temp;
ZL5011X_TRACE(ZL5011X_PLA_FN_ID, "zl5011xPlaDisableInterrupts: disable %08X",
intBits, 0, 0, 0, 0, 0);
bitMask = (ZL5011X_1BIT_MASK << ZL5011X_PLA_QUEUE_ERR_INT) |
(ZL5011X_1BIT_MASK << ZL5011X_PLA_QUEUE_WARN_INT) |
(ZL5011X_1BIT_MASK << ZL5011X_PLA_CACHE_ERR_INT) |
(ZL5011X_1BIT_MASK << ZL5011X_PLA_GRANULE_ERR_INT) |
(ZL5011X_1BIT_MASK << ZL5011X_PLA_FRAME_INT);
if ((intBits & ~bitMask) != 0)
{
status = ZL5011X_PARAMETER_INVALID;
}
if (status == ZL5011X_OK)
{
status = zl5011xRead(zl5011xParams,
ZL5011X_PLA_CONTEXT_MEMORY1 + (context * ZL5011X_PLA_CTXT_MEM1_SIZE),
&temp);
}
if (status == ZL5011X_OK)
{
if ((temp & intBits) != intBits)
{
/* the interrupt bits are to be changed, so check that neither
update or teardown are pending */
if ((temp & (ZL5011X_1BIT_MASK << ZL5011X_PLA_UPDATE_BIT)) != 0)
{
status = ZL5011X_CONTEXT_IN_UPDATE;
}
if ((temp & (ZL5011X_1BIT_MASK << ZL5011X_PLA_TEARDOWN_BIT)) != 0)
{
status = ZL5011X_CONTEXT_IN_TEARDOWN;
}
/* only set the interrupt bits if no update or teardown is pending.
It is not safe to write to the register in these instances, since
the device will autonomously do a write to clear the bits at
some point */
if (status == ZL5011X_OK)
{
status = zl5011xWrite(zl5011xParams,
ZL5011X_PLA_CONTEXT_MEMORY1 + (context * ZL5011X_PLA_CTXT_MEM1_SIZE),
temp | intBits);
/* record the state in the device structure */
zl5011xParams->interruptMasks.wanRxMasks[context] = temp | intBits;
}
}
}
return(status);
}
/*******************************************************************************
Function:
zl5011xPlaEnableTmiOverflowIntr
Description:
This function enables the confusingly named tmi_ovf interrupt. This interrupt
is in PLA register memory as opposed to context memory of the other PLA intrs.
Inputs:
zl5011xParams Pointer to the structure for this device instance
bits if the appropriate bit is set, then the interrupt is enabled.
Outputs:
None
Returns:
zlStatusE
Remarks:
*******************************************************************************/
zlStatusE zl5011xPlaEnableTmiOverflowIntr(zl5011xParamsS *zl5011xParams,
Uint32T bits)
{
zlStatusE status = ZL5011X_OK;
Uint32T bitMask;
ZL5011X_TRACE(ZL5011X_PLA_FN_ID, "zl5011xPlaEnableTmiOverflowIntr: disable %08X",
bits, 0, 0, 0, 0, 0);
bitMask = ZL5011X_1BIT_MASK << ZL5011X_PLA_TMI_OVF_INT;
if ((bits & ~bitMask) > 0)
{
status = ZL5011X_PARAMETER_INVALID;
}
if(status == ZL5011X_OK)
{
/* set the mask bits from the parameter */
status = zl5011xReadModWrite(zl5011xParams, ZL5011X_PLA_TMI_MSK_REG,
bits, bitMask);
}
/* Update the structure */
if( (status == ZL5011X_OK)&& (bits > 0 ))
{
zl5011xParams->interruptMasks.
plaTmiOvfInterruptEnabled= ZL5011X_TRUE;
}
return(status);
}
/*******************************************************************************
Function:
zl5011xPlaDisableTmiOverflowIntr
Description:
This function disables the interrupt
Inputs:
zl5011xParams Pointer to the structure for this device instance
bits if the appropriate bit is set, then the interrupt is disabled.
Outputs:
None
Returns:
zlStatusE
Remarks:
see zl5011xPlaEnableInterrupts
*******************************************************************************/
zlStatusE zl5011xPlaDisableTmiOverflowIntr(zl5011xParamsS *zl5011xParams,
Uint32T bits)
{
zlStatusE status = ZL5011X_OK;
Uint32T bitMask;
ZL5011X_TRACE(ZL5011X_PLA_FN_ID, "zl5011xPlaDisableTmiOverflowIntr: disable %08X",
bits, 0, 0, 0, 0, 0);
bitMask = ZL5011X_1BIT_MASK << ZL5011X_PLA_TMI_OVF_INT;
if ((bits & ~bitMask) > 0)
{
status = ZL5011X_PARAMETER_INVALID;
}
if(status == ZL5011X_OK)
{
/* clear the mask bit */
status = zl5011xReadModWrite(zl5011xParams, ZL5011X_PLA_TMI_MSK_REG,
0, bitMask);
}
/* Update the structure */
if( (status == ZL5011X_OK)&& (bits > 0 ))
{
zl5011xParams->interruptMasks.
plaTmiOvfInterruptEnabled= ZL5011X_FALSE;
}
return(status);
}
/*******************************************************************************
Function:
zl5011xPlaReadModWrite
Description:
Performs a Read / Modify / Write sequence to a single hardware register,
checking that the bits are set as required.
Inputs:
zl5011xParams Pointer to the structure for this device instance
addr Address to be updates
data Value to be written
mask Indicates which bits in the register are to be changed
Ouputs:
None
Returns:
zlStatusE
*******************************************************************************/
static zlStatusE zl5011xPlaReadModWrite(zl5011xParamsS *zl5011xParams, AddressT addr,
Uint32T data, Uint32T mask)
{
zlStatusE status = ZL5011X_OK;
Uint32T loop;
Uint32T readValue, writeValue;
status = zl5011xRead(zl5011xParams, addr, &readValue);
writeValue = (readValue & (~mask)) | (data & mask);
for (loop = 0; loop < ZL5011X_PLA_RETRY_LIMIT; loop++)
{
if (status != ZL5011X_OK)
{
break;
}
status = zl5011xWrite(zl5011xParams, addr, writeValue);
if (status == ZL5011X_OK)
{
status = zl5011xRead(zl5011xParams, addr, &readValue);
if ((readValue & mask) == (data & mask))
{
/* value has been set okay so break out of the loop */
break;
}
}
}
if (status == ZL5011X_OK)
{
/* if there has been no other error, then check that the loop exited
before the timeout */
if (loop == ZL5011X_PLA_RETRY_LIMIT)
{
status = ZL5011X_ERROR;
}
}
return (status);
}
/***************** END ****************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -