blob: 831a4869fd4a1e48980f62a346d7fb12a1d370f8 [file] [log] [blame]
/* eip202_rdr_dscr.c
*
* EIP-202 Ring Control Driver Library
* 1) Descriptor I/O Driver Library API implementation
* 2) Internal Result Descriptor interface implementation
*/
/* -------------------------------------------------------------------------- */
/* */
/* Module : ddk197 */
/* Version : 5.6.1 */
/* Configuration : DDK-197-GPL */
/* */
/* Date : 2022-Dec-16 */
/* */
/* Copyright (c) 2008-2022 by Rambus, Inc. and/or its subsidiaries. */
/* */
/* This program is free software: you can redistribute it and/or modify */
/* it under the terms of the GNU General Public License as published by */
/* the Free Software Foundation, either version 2 of the License, or */
/* any later version. */
/* */
/* This program is distributed in the hope that it will be useful, */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
/* GNU General Public License for more details. */
/* */
/* You should have received a copy of the GNU General Public License */
/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* -------------------------------------------------------------------------- */
/*----------------------------------------------------------------------------
* This module implements (provides) the following interface(s):
*/
// Descriptor I/O Driver Library API implementation
#include "eip202_rdr.h"
// Internal Result Descriptor interface
#include "eip202_rdr_dscr.h"
/*----------------------------------------------------------------------------
* This module uses (requires) the following interface(s):
*/
// Default configuration
#include "c_eip202_ring.h"
// EIP-202 Ring Control Driver Library Internal interfaces
#include "eip202_ring_internal.h"
#include "eip202_rdr_level0.h" // EIP-202 Level 0 macros
#include "eip202_rdr_fsm.h" // RDR State machine
#include "eip202_rd_format.h" // RD Format API
// Driver Framework Basic Definitions API
#include "basic_defs.h" // IDENTIFIER_NOT_USED, bool, uint32_t
// Driver Framework DMA Resource API
#include "dmares_types.h" // types of the DMA resource API
#include "dmares_rw.h" // read/write of the DMA resource API.
// Standard IOToken API
#include "iotoken.h"
/*----------------------------------------------------------------------------
* Definitions and macros
*/
// EIP-202 HW limit for the number of packets to acknowledge at once
#define EIP202_RING_MAX_RD_PACKET_COUNT 127
/*----------------------------------------------------------------------------
* Local variables
*/
/*----------------------------------------------------------------------------
* EIP202Lib_RDR_Prepared_FillLevel_Get
*/
static EIP202_Ring_Error_t
EIP202Lib_RDR_Prepared_FillLevel_Get(
const Device_Handle_t Device,
volatile EIP202_RDR_True_IOArea_t * const TrueIOArea_p,
unsigned int * const FillLevelDscrCount_p)
{
unsigned int RDWordCount;
EIP202_Ring_Error_t rv;
EIP202_RDR_PREP_COUNT_RD(Device, (uint32_t*)&RDWordCount);
// Remain in the current state
rv = EIP202_RDR_State_Set((volatile EIP202_RDR_State_t*)&TrueIOArea_p->State,
(EIP202_RDR_State_t)TrueIOArea_p->State);
if(rv != EIP202_RING_NO_ERROR)
return EIP202_RING_ILLEGAL_IN_STATE;
*FillLevelDscrCount_p = RDWordCount /
(unsigned int)TrueIOArea_p->DescOffsWordCount;
if(RDWordCount < (unsigned int)TrueIOArea_p->RingSizeWordCount)
(*FillLevelDscrCount_p)++;
return EIP202_RING_NO_ERROR;
}
/*----------------------------------------------------------------------------
* EIP202Lib_RDR_Processed_FillLevel_Finalize
*/
static EIP202_Ring_Error_t
EIP202Lib_RDR_Processed_FillLevel_Finalize(
const unsigned int RDWordCount,
const unsigned int PktCount,
volatile EIP202_RDR_True_IOArea_t * const TrueIOArea_p,
unsigned int * const FillLevelDscrCount_p,
unsigned int * const FillLevelPktCount_p)
{
#ifdef EIP202_RING_DEBUG_FSM
EIP202_Ring_Error_t rv;
if(RDWordCount == 0)
// CD Ring is empty
rv = EIP202_RDR_State_Set((volatile EIP202_RDR_State_t*)&TrueIOArea_p->State,
EIP202_RDR_STATE_INITIALIZED);
else if(RDWordCount > 0 &&
RDWordCount < (unsigned int)TrueIOArea_p->RingSizeWordCount)
// CD Ring is free
rv = EIP202_RDR_State_Set((volatile EIP202_RDR_State_t*)&TrueIOArea_p->State,
EIP202_RDR_STATE_FREE);
else if(RDWordCount == (unsigned int)TrueIOArea_p->RingSizeWordCount)
// CD Ring is full
rv = EIP202_RDR_State_Set((volatile EIP202_RDR_State_t*)&TrueIOArea_p->State,
EIP202_RDR_STATE_FULL);
else
rv = EIP202_RING_ILLEGAL_IN_STATE;
if(rv != EIP202_RING_NO_ERROR)
return EIP202_RING_ILLEGAL_IN_STATE;
#endif
*FillLevelDscrCount_p = RDWordCount /
(unsigned int)TrueIOArea_p->DescOffsWordCount;
*FillLevelPktCount_p = PktCount;
return EIP202_RING_NO_ERROR;
}
/*----------------------------------------------------------------------------
Internal Result Descriptor interface
---------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------
* EIP202_RDR_WriteCB
*/
int
EIP202_RDR_WriteCB(
void * const CallbackParam1_p,
const int CallbackParam2,
const unsigned int WriteIndex,
const unsigned int WriteCount,
const unsigned int TotalWriteLimit,
const void * Descriptors_p,
const int DescriptorCount,
const unsigned int DescriptorSkipCount)
{
Device_Handle_t Device;
unsigned int i, DescOffsetWordCount;
unsigned int nWritten = 0;
volatile EIP202_RDR_True_IOArea_t * const TrueIOArea_p =
RDRIOAREA(CallbackParam1_p);
if(CallbackParam1_p == NULL || Descriptors_p == NULL)
return -1;
IDENTIFIER_NOT_USED(CallbackParam2);
IDENTIFIER_NOT_USED(DescriptorCount);
IDENTIFIER_NOT_USED(TotalWriteLimit);
Device = TrueIOArea_p->Device;
DescOffsetWordCount = (unsigned int)TrueIOArea_p->DescOffsWordCount;
// Write descriptors to RDR
for(i = WriteIndex; i < WriteIndex + WriteCount; i++)
{
EIP202_Prepared_Write(
TrueIOArea_p->RingHandle,
i * DescOffsetWordCount,
((const EIP202_ARM_PreparedDescriptor_t *)Descriptors_p) +
DescriptorSkipCount + nWritten);
nWritten++;
}
if (nWritten > 0)
{
// Call PreDMA to prepared descriptors in Ring DMA buffer for handover
// to the Device (the EIP-202 DMA Master)
DMAResource_PreDMA(TrueIOArea_p->RingHandle,
WriteIndex *
DescOffsetWordCount *
(unsigned int)sizeof(uint32_t),
nWritten *
DescOffsetWordCount *
(unsigned int)sizeof(uint32_t));
// CDS point: hand over written Prepared Descriptors to the Device
EIP202_RDR_PREP_COUNT_WR(Device,
(uint16_t)(nWritten * DescOffsetWordCount),
false);
}
return (int)nWritten;
}
/*----------------------------------------------------------------------------
* EIP202_RDR_ReadCB
*/
int
EIP202_RDR_ReadCB(
void * const CallbackParam1_p,
const int CallbackParam2,
const unsigned int ReadIndex,
const unsigned int ReadLimit,
void * Descriptors_p,
const unsigned int DescriptorSkipCount)
{
Device_Handle_t Device;
unsigned int i, DescOffsetWordCount;
bool fGotDescriptor, fLastSegment = false, fFirstSegment = false;
unsigned int GotDscrCount = 0, GotPktCount = 0;
volatile EIP202_RDR_True_IOArea_t * const TrueIOArea_p =
RDRIOAREA(CallbackParam1_p);
if(CallbackParam1_p == NULL || Descriptors_p == NULL)
return -1;
IDENTIFIER_NOT_USED(CallbackParam2);
Device = TrueIOArea_p->Device;
DescOffsetWordCount = (unsigned int )TrueIOArea_p->DescOffsWordCount;
// Read descriptors from RDR
for(i = ReadIndex; i < ReadIndex + ReadLimit; i++)
{
EIP202_ARM_ResultDescriptor_t * CurrentResultDesc_p =
((EIP202_ARM_ResultDescriptor_t *)Descriptors_p) +
DescriptorSkipCount + GotDscrCount;
#define EIP202_RING_RDR_ALL_DESCRIPTORS_TO_GET_DONE \
(TrueIOArea_p->AcknowledgedRDCount + GotDscrCount >= \
TrueIOArea_p->RDToGetCount)
// This can be true only if the PktRequestedCount parameter in
// the EIP202_RDR_Descriptor_Get() function is set to a non-zero value
#define EIP202_RING_RDR_ALL_PACKETS_TO_GET_DONE \
(TrueIOArea_p->PktToGetCount > 0 && \
TrueIOArea_p->AcknowledgedPktCount + GotPktCount >= \
TrueIOArea_p->PktToGetCount)
// Stop reading the descriptors if all the requested
// descriptors and packet chains have been read
if(EIP202_RING_RDR_ALL_PACKETS_TO_GET_DONE)
{
if(EIP202_RING_RDR_ALL_DESCRIPTORS_TO_GET_DONE)
break; // for
}
// Call PostDMA before reading descriptors from
// the EIP-202 DMA Master
DMAResource_PostDMA(TrueIOArea_p->RingHandle,
i * DescOffsetWordCount *
(unsigned int)sizeof(uint32_t),
DescOffsetWordCount *
(unsigned int)sizeof(uint32_t));
// Check if a processed result descriptor is received
#if defined(EIP202_RDR_OWNERSHIP_WORD_ENABLE)
{
uint32_t OwnershipWord =
DMAResource_Read32(TrueIOArea_p->RingHandle,
i * DescOffsetWordCount +
DescOffsetWordCount - 1);
fGotDescriptor =
(OwnershipWord == EIP202_RDR_OWNERSHIP_WORD_PATTERN);
#ifdef EIP202_RING_BUS_KEEPALIVE_WORKAROUND
// Read from the device to solve a keep-alive problem in some
// bus environments.
Device_Read32(Device,0);
#endif
}
#elif defined(EIP202_RING_ANTI_DMA_RACE_CONDITION_CDS)
CurrentResultDesc_p->Token_p[IOToken_OutMarkOffset_Get()] =
DMAResource_Read32(TrueIOArea_p->RingHandle,
i * DescOffsetWordCount +
TrueIOArea_p->TokenOffsetWordCount +
IOToken_OutMarkOffset_Get());
fGotDescriptor = (IOToken_Mark_Check(CurrentResultDesc_p->Token_p) == 0);
#else
fGotDescriptor = true; // according to EIP202_RDR_PROC_COUNT_RD()
#endif
if (fGotDescriptor)
{
// Read Result Descriptor
EIP202_ReadDescriptor(CurrentResultDesc_p,
TrueIOArea_p->RingHandle,
i * DescOffsetWordCount,
DescOffsetWordCount,
TrueIOArea_p->TokenOffsetWordCount,
&fLastSegment,
&fFirstSegment);
// Stop reading the descriptors if all the requested
// packet chains have been read and a new processed packet descriptor
// chain is detected
if(fFirstSegment && EIP202_RING_RDR_ALL_PACKETS_TO_GET_DONE)
break; // for
if (fFirstSegment)
TrueIOArea_p->PacketFound = true;
GotDscrCount++;
if(TrueIOArea_p->PacketFound && fLastSegment)
{
GotPktCount++;
TrueIOArea_p->PacketFound = false;
}
#if defined(EIP202_RING_ANTI_DMA_RACE_CONDITION_CDS) || \
defined(EIP202_RDR_OWNERSHIP_WORD_ENABLE)
// Clear this descriptor
EIP202_ClearDescriptor(CurrentResultDesc_p,
TrueIOArea_p->RingHandle,
i * DescOffsetWordCount,
TrueIOArea_p->TokenOffsetWordCount,
DescOffsetWordCount);
// Ensure next PostDMA does not undo the clear operation above
DMAResource_PreDMA(
TrueIOArea_p->RingHandle,
i * DescOffsetWordCount * (unsigned int)sizeof(uint32_t),
DescOffsetWordCount * (unsigned int)sizeof(uint32_t));
#endif
}
else
{
// The fGotDescriptor is set in EIP202_ReadDescriptor() and
// depends on the Application ID field in the result descriptor
// when EIP202_RING_ANTI_DMA_RACE_CONDITION_CDS is defined.
// In case of a packet descriptor chain the Engine writes the
// Application ID field for the last segment descriptor only
// but we need to acknowledge all the descriptors of the chain
break; // for
}
} // for
// Check if there are processed result descriptors and packets
// that must be acknowledged
if (GotDscrCount > 0)
{
unsigned int NewGotPktCount;
#if EIP202_RING_RD_INTERRUPTS_PER_PACKET_FLAG != 1
GotPktCount = 0;
#endif
// EIP-202 HW limits the number of packets to acknowledge at once to
// EIP202_RING_MAX_RD_PACKET_COUNT packets
NewGotPktCount = MIN(GotPktCount, EIP202_RING_MAX_RD_PACKET_COUNT);
// CDS point: hand over read Result Descriptors to the Device
EIP202_RDR_PROC_COUNT_WR(
Device,
(uint16_t)(GotDscrCount * DescOffsetWordCount),
(uint8_t)NewGotPktCount,
false);
}
// Update acknowledged packets counter
TrueIOArea_p->AcknowledgedPktCount += GotPktCount;
// Update acknowledged descriptors counter
TrueIOArea_p->AcknowledgedRDCount += GotDscrCount;
return (int)GotDscrCount;
}
/*----------------------------------------------------------------------------
* EIP202_RDR_StatusCB
*/
int
EIP202_RDR_StatusCB(
void * const CallbackParam1_p,
const int CallbackParam2,
int * const DeviceReadPos_p)
{
IDENTIFIER_NOT_USED(CallbackParam1_p);
IDENTIFIER_NOT_USED(CallbackParam2);
*DeviceReadPos_p = -1; // not used
return 0;
}
/*----------------------------------------------------------------------------
Descriptor I/O Driver Library API implementation
---------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------
* EIP202_RDR_FillLevel_Get
*/
EIP202_Ring_Error_t
EIP202_RDR_FillLevel_Get(
EIP202_Ring_IOArea_t * const IOArea_p,
unsigned int * FillLevelDscrCount_p)
{
int FillLevel;
volatile EIP202_RDR_True_IOArea_t * const TrueIOArea_p = RDRIOAREA(IOArea_p);
EIP202_RING_CHECK_POINTER(IOArea_p);
EIP202_RING_CHECK_POINTER(FillLevelDscrCount_p);
FillLevel = RingHelper_FillLevel_Get(
(volatile RingHelper_t*)&TrueIOArea_p->RingHelper);
if(FillLevel < 0)
return EIP202_RING_UNSUPPORTED_FEATURE_ERROR;
else
{
*FillLevelDscrCount_p = (unsigned int)FillLevel;
return EIP202_RING_NO_ERROR;
}
}
/*----------------------------------------------------------------------------
* EIP202_RDR_Prepared_FillLevel_Get
*/
EIP202_Ring_Error_t
EIP202_RDR_Prepared_FillLevel_Get(
EIP202_Ring_IOArea_t * const IOArea_p,
unsigned int * FillLevelDscrCount_p)
{
Device_Handle_t Device;
volatile EIP202_RDR_True_IOArea_t * const TrueIOArea_p = RDRIOAREA(IOArea_p);
EIP202_RING_CHECK_POINTER(IOArea_p);
EIP202_RING_CHECK_POINTER(FillLevelDscrCount_p);
Device = TrueIOArea_p->Device;
return EIP202Lib_RDR_Prepared_FillLevel_Get(Device,
TrueIOArea_p,
FillLevelDscrCount_p);
}
/*----------------------------------------------------------------------------
* EIP202_RDR_Write_Prepared_ControlWord
*
* This helper function returns the control word that can be written to
* the logical prepared descriptor.
*
* This function is re-entrant.
*
*/
uint32_t
EIP202_RDR_Write_Prepared_ControlWord(
const EIP202_RDR_Prepared_Control_t * const PreparedCtrl_p)
{
return EIP202_RD_Make_ControlWord(PreparedCtrl_p->ExpectedResultWordCount,
PreparedCtrl_p->PrepSegmentByteCount,
PreparedCtrl_p->fFirstSegment,
PreparedCtrl_p->fLastSegment);
}
/*----------------------------------------------------------------------------
* EIP202_RDR_Descriptor_Prepare
*/
EIP202_Ring_Error_t
EIP202_RDR_Descriptor_Prepare(
EIP202_Ring_IOArea_t * const IOArea_p,
const EIP202_ARM_PreparedDescriptor_t * PreparedDscr_p,
const unsigned int DscrRequestedCount,
unsigned int * const DscrPreparedCount_p,
unsigned int * FillLevelDscrCount_p)
{
int res, FillLevel;
unsigned int RDWordCount, RDFreeCount, DscrNewRequestedCount;
volatile EIP202_RDR_True_IOArea_t * const TrueIOArea_p = RDRIOAREA(IOArea_p);
EIP202_RING_CHECK_POINTER(IOArea_p);
EIP202_RING_CHECK_POINTER(PreparedDscr_p);
EIP202_RING_CHECK_POINTER(DscrPreparedCount_p);
EIP202_RING_CHECK_POINTER(FillLevelDscrCount_p);
// Check how many more descriptors can be added (prepared) to RDR
FillLevel = RingHelper_FillLevel_Get(
(volatile RingHelper_t*)&TrueIOArea_p->RingHelper);
if(FillLevel < 0)
return EIP202_RING_ARGUMENT_ERROR; // Error, RDR admin corrupted
// Check if RDR is full
RDWordCount = ((unsigned int)FillLevel *
(unsigned int)TrueIOArea_p->DescOffsWordCount);
if(RDWordCount == (unsigned int)TrueIOArea_p->RingSizeWordCount)
{
// RD Ring is full
*FillLevelDscrCount_p = (unsigned int)FillLevel;
*DscrPreparedCount_p = 0;
// Remain in the current state
return EIP202_RDR_State_Set((volatile EIP202_RDR_State_t*)&TrueIOArea_p->State,
(EIP202_RDR_State_t)TrueIOArea_p->State);
}
// Calculate the maximum number of descriptors that can be added to RDR
RDFreeCount =
((unsigned int)TrueIOArea_p->RingSizeWordCount - RDWordCount) /
(unsigned int)TrueIOArea_p->DescOffsWordCount;
DscrNewRequestedCount = MIN(RDFreeCount, DscrRequestedCount);
res = RingHelper_Put((volatile RingHelper_t*)&TrueIOArea_p->RingHelper,
PreparedDscr_p,
(int)DscrNewRequestedCount);
if(res >= 0)
*DscrPreparedCount_p = (unsigned int)res;
else
return EIP202_RING_ARGUMENT_ERROR;
// Get the current RDR fill level
FillLevel = RingHelper_FillLevel_Get(
(volatile RingHelper_t*)&TrueIOArea_p->RingHelper);
if(FillLevel < 0)
return EIP202_RING_ARGUMENT_ERROR; // Error, RDR admin corrupted
else
{
*FillLevelDscrCount_p = (unsigned int)FillLevel;
return EIP202_RING_NO_ERROR;
}
}
/*----------------------------------------------------------------------------
* EIP202_RDR_Processed_FillLevel_Get
*/
EIP202_Ring_Error_t
EIP202_RDR_Processed_FillLevel_Get(
EIP202_Ring_IOArea_t * const IOArea_p,
unsigned int * FillLevelDscrCount_p,
unsigned int * FillLevelPktCount_p)
{
// If configured then the driver cannot rely on the register counter
#if defined(EIP202_RING_ANTI_DMA_RACE_CONDITION_CDS) || \
defined(EIP202_RDR_OWNERSHIP_WORD_ENABLE)
IDENTIFIER_NOT_USED(FillLevelDscrCount_p);
IDENTIFIER_NOT_USED(FillLevelPktCount_p);
IDENTIFIER_NOT_USED(IOArea_p);
return EIP202_RING_UNSUPPORTED_FEATURE_ERROR;
#else
Device_Handle_t Device;
unsigned int RDWordCount, PktCount;
volatile EIP202_RDR_True_IOArea_t * const TrueIOArea_p = RDRIOAREA(IOArea_p);
EIP202_RING_CHECK_POINTER(IOArea_p);
EIP202_RING_CHECK_POINTER(FillLevelDscrCount_p);
EIP202_RING_CHECK_POINTER(FillLevelPktCount_p);
Device = TrueIOArea_p->Device;
{
uint8_t Value8;
uint32_t Value32;
EIP202_RDR_PROC_COUNT_RD(Device, &Value32, &Value8);
RDWordCount = (unsigned int)Value32;
PktCount = (unsigned int)Value8;
}
return EIP202Lib_RDR_Processed_FillLevel_Finalize(RDWordCount,
PktCount,
TrueIOArea_p,
FillLevelDscrCount_p,
FillLevelPktCount_p);
#endif // EIP202_RING_ANTI_DMA_RACE_CONDITION_CDS
}
/*----------------------------------------------------------------------------
* EIP202_RDR_Read_Processed_ControlWord
*/
void
EIP202_RDR_Read_Processed_ControlWord(
EIP202_ARM_ResultDescriptor_t * const ResDscr_p,
EIP202_RDR_Result_Control_t * const RDControl_p,
EIP202_RDR_Result_Token_t * const ResToken_p)
{
IDENTIFIER_NOT_USED(ResToken_p);
EIP202_RD_Read_ControlWord(ResDscr_p->ProcControlWord,
NULL,
RDControl_p,
NULL);
return;
}
/*----------------------------------------------------------------------------
* EIP202_RDR_Read_Processed_BypassData
*/
void
EIP202_RDR_Read_Processed_BypassData(
const EIP202_RDR_Result_Token_t * const ResToken_p,
EIP202_RDR_BypassData_t * const BD_p)
{
EIP202_RD_Read_BypassData(ResToken_p->BypassData_p,
ResToken_p->BypassWordCount,
BD_p);
return;
}
/*----------------------------------------------------------------------------
* EIP202_RDR_Descriptor_Get
*/
EIP202_Ring_Error_t
EIP202_RDR_Descriptor_Get(
EIP202_Ring_IOArea_t * const IOArea_p,
EIP202_ARM_ResultDescriptor_t * ResultDscr_p,
const unsigned int PktRequestedCount,
const unsigned int DscrRequestedCount,
unsigned int * const DscrDoneCount_p,
unsigned int * FillLevelDscrCount_p)
{
Device_Handle_t Device;
int res;
unsigned int RDWordCount, ProcDsrcCount, ProcPktCount;
volatile EIP202_RDR_True_IOArea_t * const TrueIOArea_p = RDRIOAREA(IOArea_p);
EIP202_RING_CHECK_POINTER(IOArea_p);
EIP202_RING_CHECK_POINTER(ResultDscr_p);
EIP202_RING_CHECK_POINTER(DscrDoneCount_p);
EIP202_RING_CHECK_POINTER(FillLevelDscrCount_p);
if(DscrRequestedCount == 0)
return EIP202_RING_ARGUMENT_ERROR;
Device = TrueIOArea_p->Device;
// Check how many descriptors can be obtained
{
uint8_t Value8;
uint32_t Value32;
#ifdef EIP202_RDR_OWNERSHIP_WORD_ENABLE
Value32 = MIN(PktRequestedCount, DscrRequestedCount);
Value8 = MIN(EIP202_RING_MAX_RD_PACKET_COUNT, Value32);
Value32 = Value8 * TrueIOArea_p->DescOffsWordCount;
IDENTIFIER_NOT_USED(Device);
#else
EIP202_RDR_PROC_COUNT_RD(Device, &Value32, &Value8);
#endif
RDWordCount = (unsigned int)Value32;
ProcPktCount = (unsigned int)Value8;
}
// Check if RDR is empty or
// if RDR has no fully processed packet descriptor chain
if(RDWordCount == 0 ||
(PktRequestedCount != 0 && ProcPktCount == 0))
{
// Nothing to do
*FillLevelDscrCount_p = 0;
*DscrDoneCount_p = 0;
return EIP202_RDR_State_Set((volatile EIP202_RDR_State_t*)&TrueIOArea_p->State,
EIP202_RDR_STATE_INITIALIZED);
}
ProcDsrcCount = RDWordCount /
(unsigned int)TrueIOArea_p->DescOffsWordCount;
TrueIOArea_p->AcknowledgedRDCount = 0;
TrueIOArea_p->AcknowledgedPktCount = 0;
TrueIOArea_p->RDToGetCount = MIN(ProcDsrcCount, DscrRequestedCount);
TrueIOArea_p->PktToGetCount = MIN(ProcPktCount, PktRequestedCount);
// Get processed (result) descriptors
res = RingHelper_Get((volatile RingHelper_t*)&TrueIOArea_p->RingHelper,
// If configured then the driver cannot rely on the register counter
#if defined(EIP202_RING_ANTI_DMA_RACE_CONDITION_CDS) || \
defined(EIP202_RDR_OWNERSHIP_WORD_ENABLE)
-1, // Certainly available RD count unknown
#else
(int)TrueIOArea_p->RDToGetCount,
#endif // EIP202_RING_ANTI_DMA_RACE_CONDITION_CDS
ResultDscr_p,
(int)DscrRequestedCount);
if(res >= 0)
*DscrDoneCount_p = (unsigned int)res;
else
return EIP202_RING_ARGUMENT_ERROR;
// Increase the fill level by the number of successfully got descriptors
RDWordCount -= ((unsigned int)res *
(unsigned int)TrueIOArea_p->DescOffsWordCount);
// Increase the fill level by the number of acknowledged packets
ProcPktCount -= TrueIOArea_p->AcknowledgedPktCount;
return EIP202Lib_RDR_Processed_FillLevel_Finalize(RDWordCount,
ProcPktCount,
TrueIOArea_p,
FillLevelDscrCount_p,
&ProcPktCount);
}
/* end of file eip202_rdr_dscr.c */