source: SVN/rincon/u-boot/board/xilinx/common/xdma_channel_sg.c @ 55

Last change on this file since 55 was 55, checked in by Tim Harvey, 22 months ago

rincon: added latest u-boot source

restored form server backup

Signed-off-by: Tim Harvey <tharvey@…>

File size: 48.2 KB
Line 
1/* $Id: xdma_channel_sg.c,v 1.6 2003/02/03 19:50:33 moleres Exp $ */
2/******************************************************************************
3*
4*     Author: Xilinx, Inc.
5*
6*
7*     This program is free software; you can redistribute it and/or modify it
8*     under the terms of the GNU General Public License as published by the
9*     Free Software Foundation; either version 2 of the License, or (at your
10*     option) any later version.
11*
12*
13*     XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
14*     COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
15*     ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR STANDARD,
16*     XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION IS FREE
17*     FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE FOR OBTAINING
18*     ANY THIRD PARTY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
19*     XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
20*     THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY
21*     WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM
22*     CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND
23*     FITNESS FOR A PARTICULAR PURPOSE.
24*
25*
26*     Xilinx hardware products are not intended for use in life support
27*     appliances, devices, or systems. Use in such applications is
28*     expressly prohibited.
29*
30*
31*     (c) Copyright 2002-2004 Xilinx Inc.
32*     All rights reserved.
33*
34*
35*     You should have received a copy of the GNU General Public License along
36*     with this program; if not, write to the Free Software Foundation, Inc.,
37*     675 Mass Ave, Cambridge, MA 02139, USA.
38*
39* FILENAME:
40*
41* xdma_channel_sg.c
42*
43* DESCRIPTION:
44*
45* This file contains the implementation of the XDmaChannel component which is
46* related to scatter gather operations.
47*
48* Scatter Gather Operations
49*
50* The DMA channel may support scatter gather operations. A scatter gather
51* operation automates the DMA channel such that multiple buffers can be
52* sent or received with minimal software interaction with the hardware.  Buffer
53* descriptors, contained in the XBufDescriptor component, are used by the
54* scatter gather operations of the DMA channel to describe the buffers to be
55* processed.
56*
57* Scatter Gather List Operations
58*
59* A scatter gather list may be supported by each DMA channel.  The scatter
60* gather list allows buffer descriptors to be put into the list by a device
61* driver which requires scatter gather.  The hardware processes the buffer
62* descriptors which are contained in the list and modifies the buffer
63* descriptors to reflect the status of the DMA operations.  The device driver
64* is notified by interrupt that specific DMA events occur including scatter
65* gather events.  The device driver removes the completed buffer descriptors
66* from the scatter gather list to evaluate the status of each DMA operation.
67*
68* The scatter gather list is created and buffer descriptors are inserted into
69* the list.  Buffer descriptors are never removed from the list after it's
70* creation such that a put operation copies from a temporary buffer descriptor
71* to a buffer descriptor in the list.  Get operations don't copy from the list
72* to a temporary, but return a pointer to the buffer descriptor in the list.
73* A buffer descriptor in the list may be locked to prevent it from being
74* overwritten by a put operation.  This allows the device driver to get a
75* descriptor from a scatter gather list and prevent it from being overwritten
76* until the buffer associated with the buffer descriptor has been processed.
77*
78* The get and put functions only operate on the list and are asynchronous from
79* the hardware which may be using the list of descriptors.  This is important
80* because there are no checks in the get and put functions to ensure that the
81* hardware has processed the descriptors.  This must be handled by the driver
82* using the DMA scatter gather channel through the use of the other functions.
83* When a scatter gather operation is started, the start function does ensure
84* that the descriptor to start has not already been processed by the hardware
85* and is not the first of a series of descriptors that have not been committed
86* yet.
87*
88* Descriptors are put into the list but not marked as ready to use by the
89* hardware until a commit operation is done.  This allows multiple descriptors
90* which may contain a single packet of information for a protocol to be
91* guaranteed not to cause any underflow conditions during transmission. The
92* hardware design only allows descriptors to cause it to stop after a descriptor
93* has been processed rather than before it is processed.  A series of
94* descriptors are put into the list followed by a commit operation, or each
95* descriptor may be commited.  A commit operation is performed by changing a
96* single descriptor, the first of the series of puts, to indicate that the
97* hardware may now use all descriptors after it.  The last descriptor in the
98* list is always set to cause the hardware to stop after it is processed.
99*
100* Typical Scatter Gather Processing
101*
102* The following steps illustrate the typical processing to use the
103* scatter gather features of a DMA channel.
104*
105* 1. Create a scatter gather list for the DMA channel which puts empty buffer
106*    descriptors into the list.
107* 2. Create buffer descriptors which describe the buffers to be filled with
108*    receive data or the buffers which contain data to be sent.
109* 3. Put buffer descriptors into the DMA channel scatter list such that scatter
110*    gather operations are requested.
111* 4. Commit the buffer descriptors in the list such that they are ready to be
112*    used by the DMA channel hardware.
113* 5. Start the scatter gather operations of the DMA channel.
114* 6. Process any interrupts which occur as a result of the scatter gather
115*    operations or poll the DMA channel to determine the status.  This may
116*    be accomplished by getting the packet count for the channel and then
117*    getting the appropriate number of descriptors from the list for that
118*    number of packets.
119*
120* Minimizing Interrupts
121*
122* The Scatter Gather operating mode is designed to reduce the amount of CPU
123* throughput necessary to manage the hardware for devices. A key to the CPU
124* throughput is the number and rate of interrupts that the CPU must service.
125* Devices with higher data rates can cause larger numbers of interrupts and
126* higher frequency interrupts. Ideally the number of interrupts can be reduced
127* by only generating an interrupt when a specific amount of data has been
128* received from the interface. This design suffers from a lack of interrupts
129* when the amount of data received is less than the specified amount of data
130* to generate an interrupt. In order to help minimize the number of interrupts
131* which the CPU must service, an algorithm referred to as "interrupt coalescing"
132* is utilized.
133*
134* Interrupt Coalescing
135*
136* The principle of interrupt coalescing is to wait before generating an
137* interrupt until a certain number of packets have been received or sent. An
138* interrupt is also generated if a smaller number of packets have been received
139* followed by a certain period of time with no packet reception. This is a
140* trade-off of latency for bandwidth and is accomplished using several
141* mechanisms of the hardware including a counter for packets received or
142* transmitted and a packet timer. These two hardware mechanisms work in
143* combination to allow a reduction in the number of interrupts processed by the
144* CPU for packet reception.
145*
146* Unserviced Packet Count
147*
148* The purpose of the packet counter is to count the number of packets received
149* or transmitted and provide an interrupt when a specific number of packets
150* have been processed by the hardware. An interrupt is generated whenever the
151* counter is greater than or equal to the Packet Count Threshold. This counter
152* contains an accurate count of the number of packets that the hardware has
153* processed, either received or transmitted, and the software has not serviced.
154*
155* The packet counter allows the number of interrupts to be reduced by waiting
156* to generate an interrupt until enough packets are received. For packet
157* reception, packet counts of less than the number to generate an interrupt
158* would not be serviced without the addition of a packet timer. This counter is
159* continuously updated by the hardware, not latched to the value at the time
160* the interrupt occurred.
161*
162* The packet counter can be used within the interrupt service routine for the
163* device to reduce the number of interrupts. The interrupt service routine
164* loops while performing processing for each packet which has been received or
165* transmitted and decrements the counter by a specified value. At the same time,
166* the hardware is possibly continuing to receive or transmit more packets such
167* that the software may choose, based upon the value in the packet counter, to
168* remain in the interrupt service routine rather than exiting and immediately
169* returning. This feature should be used with caution as reducing the number of
170* interrupts is beneficial, but unbounded interrupt processing is not desirable.
171*
172* Since the hardware may be incrementing the packet counter simultaneously
173* with the software decrementing the counter, there is a need for atomic
174* operations. The hardware ensures that the operation is atomic such that
175* simultaneous accesses are properly handled.
176*
177* Packet Wait Bound
178*
179* The purpose of the packet wait bound is to augment the unserviced packet
180* count. Whenever there is no pending interrupt for the channel and the
181* unserviced packet count is non-zero, a timer starts counting timeout at the
182* value contained the the packet wait bound register.  If the timeout is
183* reached, an interrupt is generated such that the software may service the
184* data which was buffered.
185*
186* NOTES:
187*
188* Special Test Conditions:
189*
190* The scatter gather list processing must be thoroughly tested if changes are
191* made.  Testing should include putting and committing single descriptors and
192* putting multiple descriptors followed by a single commit.  There are some
193* conditions in the code which handle the exception conditions.
194*
195* The Put Pointer points to the next location in the descriptor list to copy
196* in a new descriptor. The Get Pointer points to the next location in the
197* list to get a descriptor from.  The Get Pointer only allows software to
198* have a traverse the list after the hardware has finished processing some
199* number of descriptors.  The Commit Pointer points to the descriptor in the
200* list which is to be committed.  It is also used to determine that no
201* descriptor is waiting to be commited (NULL).  The Last Pointer points to
202* the last descriptor that was put into the list.  It typically points
203* to the previous descriptor to the one pointed to by the Put Pointer.
204* Comparisons are done between these pointers to determine when the following
205* special conditions exist.
206
207* Single Put And Commit
208*
209* The buffer descriptor is ready to be used by the hardware so it is important
210* for the descriptor to not appear to be waiting to be committed.  The commit
211* pointer is reset when a commit is done indicating there are no descriptors
212* waiting to be committed.  In all cases but this one, the descriptor is
213* changed to cause the hardware to go to the next descriptor after processing
214* this one.  But in this case, this is the last descriptor in the list such
215* that it must not be changed.
216*
217* 3 Or More Puts And Commit
218*
219* A series of 3 or more puts followed by a single commit is different in that
220* only the 1st descriptor put into the list is changed when the commit is done.
221* This requires each put starting on the 3rd to change the previous descriptor
222* so that it allows the hardware to continue to the next descriptor in the list.
223*
224* The 1st Put Following A Commit
225*
226* The commit caused the commit pointer to be NULL indicating that there are no
227* descriptors waiting to be committed.  It is necessary for the next put to set
228* the commit pointer so that a commit must follow the put for the hardware to
229* use the descriptor.
230*
231* <pre>
232* MODIFICATION HISTORY:
233*
234* Ver   Who  Date     Changes
235* ----- ---- -------- ------------------------------------------------------
236* 1.00a rpm  02/03/03 Removed the XST_DMA_SG_COUNT_EXCEEDED return code
237*                     from SetPktThreshold.
238* </pre>
239*
240******************************************************************************/
241
242/***************************** Include Files *********************************/
243
244#include "xdma_channel.h"
245#include "xbasic_types.h"
246#include "xio.h"
247#include "xbuf_descriptor.h"
248#include "xstatus.h"
249
250/************************** Constant Definitions *****************************/
251
252#define XDC_SWCR_SG_ENABLE_MASK 0x80000000UL    /* scatter gather enable */
253
254/**************************** Type Definitions *******************************/
255
256/***************** Macros (Inline Functions) Definitions *********************/
257
258/* the following macro copies selected fields of a buffer descriptor to another
259 * buffer descriptor, this was provided by the buffer descriptor component but
260 * was moved here since it is only used internally to this component and since
261 * it does not copy all fields
262 */
263#define CopyBufferDescriptor(InstancePtr, DestinationPtr)          \
264{                                                                  \
265    *((u32 *)DestinationPtr + XBD_CONTROL_OFFSET) =            \
266        *((u32 *)InstancePtr + XBD_CONTROL_OFFSET);            \
267    *((u32 *)DestinationPtr + XBD_SOURCE_OFFSET) =             \
268        *((u32 *)InstancePtr + XBD_SOURCE_OFFSET);             \
269    *((u32 *)DestinationPtr + XBD_DESTINATION_OFFSET) =        \
270        *((u32 *)InstancePtr + XBD_DESTINATION_OFFSET);        \
271    *((u32 *)DestinationPtr + XBD_LENGTH_OFFSET) =             \
272        *((u32 *)InstancePtr + XBD_LENGTH_OFFSET);             \
273    *((u32 *)DestinationPtr + XBD_STATUS_OFFSET) =             \
274        *((u32 *)InstancePtr + XBD_STATUS_OFFSET);             \
275    *((u32 *)DestinationPtr + XBD_DEVICE_STATUS_OFFSET) =      \
276        *((u32 *)InstancePtr + XBD_DEVICE_STATUS_OFFSET);      \
277    *((u32 *)DestinationPtr + XBD_ID_OFFSET) =                 \
278        *((u32 *)InstancePtr + XBD_ID_OFFSET);                 \
279    *((u32 *)DestinationPtr + XBD_FLAGS_OFFSET) =              \
280        *((u32 *)InstancePtr + XBD_FLAGS_OFFSET);              \
281    *((u32 *)DestinationPtr + XBD_RQSTED_LENGTH_OFFSET) =      \
282        *((u32 *)InstancePtr + XBD_RQSTED_LENGTH_OFFSET);      \
283}
284
285/************************** Variable Definitions *****************************/
286
287/************************** Function Prototypes ******************************/
288
289/******************************************************************************
290*
291* FUNCTION:
292*
293* XDmaChannel_SgStart
294*
295* DESCRIPTION:
296*
297* This function starts a scatter gather operation for a scatter gather
298* DMA channel.  The first buffer descriptor in the buffer descriptor list
299* will be started with the scatter gather operation.  A scatter gather list
300* should have previously been created for the DMA channel and buffer
301* descriptors put into the scatter gather list such that there are scatter
302* operations ready to be performed.
303*
304* ARGUMENTS:
305*
306* InstancePtr contains a pointer to the DMA channel to operate on.  The DMA
307* channel should be configured to use scatter gather in order for this function
308* to be called.
309*
310* RETURN VALUE:
311*
312* A status containing XST_SUCCESS if scatter gather was started successfully
313* for the DMA channel.
314*
315* A value of XST_DMA_SG_NO_LIST indicates the scatter gather list has not
316* been created.
317*
318* A value of XST_DMA_SG_LIST_EMPTY indicates scatter gather was not started
319* because the scatter gather list of the DMA channel does not contain any
320* buffer descriptors that are ready to be processed by the hardware.
321*
322* A value of XST_DMA_SG_IS_STARTED indicates scatter gather was not started
323* because the scatter gather was not stopped, but was already started.
324*
325* A value of XST_DMA_SG_BD_NOT_COMMITTED indicates the buffer descriptor of
326* scatter gather list which was to be started is not committed to the list.
327* This status is more likely if this function is being called from an ISR
328* and non-ISR processing is putting descriptors into the list.
329*
330* A value of XST_DMA_SG_NO_DATA indicates that the buffer descriptor of the
331* scatter gather list which was to be started had already been used by the
332* hardware for a DMA transfer that has been completed.
333*
334* NOTES:
335*
336* It is the responsibility of the caller to get all the buffer descriptors
337* after performing a stop operation and before performing a start operation.
338* If buffer descriptors are not retrieved between stop and start operations,
339* buffer descriptors may be processed by the hardware more than once.
340*
341******************************************************************************/
342XStatus
343XDmaChannel_SgStart(XDmaChannel * InstancePtr)
344{
345        u32 Register;
346        XBufDescriptor *LastDescriptorPtr;
347
348        /* assert to verify input arguments */
349
350        XASSERT_NONVOID(InstancePtr != NULL);
351        XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
352
353        /* if a scatter gather list has not been created yet, return a status */
354
355        if (InstancePtr->TotalDescriptorCount == 0) {
356                return XST_DMA_SG_NO_LIST;
357        }
358
359        /* if the scatter gather list exists but is empty then return a status */
360
361        if (XDmaChannel_IsSgListEmpty(InstancePtr)) {
362                return XST_DMA_SG_LIST_EMPTY;
363        }
364
365        /* if scatter gather is busy for the DMA channel, return a status because
366         * restarting it could lose data
367         */
368
369        Register = XIo_In32(InstancePtr->RegBaseAddress + XDC_DMAS_REG_OFFSET);
370        if (Register & XDC_DMASR_SG_BUSY_MASK) {
371                return XST_DMA_SG_IS_STARTED;
372        }
373
374        /* get the address of the last buffer descriptor which the DMA hardware
375         * finished processing
376         */
377        LastDescriptorPtr =
378            (XBufDescriptor *) XIo_In32(InstancePtr->RegBaseAddress +
379                                        XDC_BDA_REG_OFFSET);
380
381        /* setup the first buffer descriptor that will be sent when the scatter
382         * gather channel is enabled, this is only necessary one time since
383         * the BDA register of the channel maintains the last buffer descriptor
384         * processed
385         */
386        if (LastDescriptorPtr == NULL) {
387                XIo_Out32(InstancePtr->RegBaseAddress + XDC_BDA_REG_OFFSET,
388                          (u32) InstancePtr->GetPtr);
389        } else {
390                XBufDescriptor *NextDescriptorPtr;
391
392                /* get the next descriptor to be started, if the status indicates it
393                 * hasn't already been used by the h/w, then it's OK to start it,
394                 * s/w sets the status of each descriptor to busy and then h/w clears
395                 * the busy when it is complete
396                 */
397                NextDescriptorPtr =
398                    XBufDescriptor_GetNextPtr(LastDescriptorPtr);
399
400                if ((XBufDescriptor_GetStatus(NextDescriptorPtr) &
401                     XDC_DMASR_BUSY_MASK) == 0) {
402                        return XST_DMA_SG_NO_DATA;
403                }
404                /* don't start the DMA SG channel if the descriptor to be processed
405                 * by h/w is to be committed by the s/w, this function can be called
406                 * such that it interrupts a thread that was putting into the list
407                 */
408                if (NextDescriptorPtr == InstancePtr->CommitPtr) {
409                        return XST_DMA_SG_BD_NOT_COMMITTED;
410                }
411        }
412
413        /* start the scatter gather operation by clearing the stop bit in the
414         * control register and setting the enable bit in the s/w control register,
415         * both of these are necessary to cause it to start, right now the order of
416         * these statements is important, the software control register should be
417         * set 1st.  The other order can cause the CPU to have a loss of sync
418         * because it cannot read/write the register while the DMA operation is
419         * running
420         */
421
422        Register = XIo_In32(InstancePtr->RegBaseAddress + XDC_SWCR_REG_OFFSET);
423
424        XIo_Out32(InstancePtr->RegBaseAddress + XDC_SWCR_REG_OFFSET,
425                  Register | XDC_SWCR_SG_ENABLE_MASK);
426
427        Register = XIo_In32(InstancePtr->RegBaseAddress + XDC_DMAC_REG_OFFSET);
428
429        XIo_Out32(InstancePtr->RegBaseAddress + XDC_DMAC_REG_OFFSET,
430                  Register & ~XDC_DMACR_SG_DISABLE_MASK);
431
432        /* indicate the DMA channel scatter gather operation was started
433         * successfully
434         */
435        return XST_SUCCESS;
436}
437
438/******************************************************************************
439*
440* FUNCTION:
441*
442* XDmaChannel_SgStop
443*
444* DESCRIPTION:
445*
446* This function stops a scatter gather operation for a scatter gather
447* DMA channel. This function starts the process of stopping a scatter
448* gather operation that is in progress and waits for the stop to be completed.
449* Since it waits for the operation to stopped before returning, this function
450* could take an amount of time relative to the size of the DMA scatter gather
451* operation which is in progress.  The scatter gather list of the DMA channel
452* is not modified by this function such that starting the scatter gather
453* channel after stopping it will cause it to resume.  This operation is
454* considered to be a graceful stop in that the scatter gather operation
455* completes the current buffer descriptor before stopping.
456*
457* If the interrupt is enabled, an interrupt will be generated when the
458* operation is stopped and the caller is responsible for handling the
459* interrupt.
460*
461* ARGUMENTS:
462*
463* InstancePtr contains a pointer to the DMA channel to operate on.  The DMA
464* channel should be configured to use scatter gather in order for this function
465* to be called.
466*
467* BufDescriptorPtr is also a return value which contains a pointer to the
468* buffer descriptor which the scatter gather operation completed when it
469* was stopped.
470*
471* RETURN VALUE:
472*
473* A status containing XST_SUCCESS if scatter gather was stopped successfully
474* for the DMA channel.
475*
476* A value of XST_DMA_SG_IS_STOPPED indicates scatter gather was not stoppped
477* because the scatter gather is not started, but was already stopped.
478*
479* BufDescriptorPtr contains a pointer to the buffer descriptor which was
480* completed when the operation was stopped.
481*
482* NOTES:
483*
484* This function implements a loop which polls the hardware for an infinite
485* amount of time. If the hardware is not operating correctly, this function
486* may never return.
487*
488******************************************************************************/
489XStatus
490XDmaChannel_SgStop(XDmaChannel * InstancePtr,
491                   XBufDescriptor ** BufDescriptorPtr)
492{
493        u32 Register;
494
495        /* assert to verify input arguments */
496
497        XASSERT_NONVOID(InstancePtr != NULL);
498        XASSERT_NONVOID(BufDescriptorPtr != NULL);
499        XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
500
501        /* get the contents of the software control register, if scatter gather is not
502         * enabled (started), then return a status because the disable acknowledge
503         * would not be generated
504         */
505        Register = XIo_In32(InstancePtr->RegBaseAddress + XDC_SWCR_REG_OFFSET);
506
507        if ((Register & XDC_SWCR_SG_ENABLE_MASK) == 0) {
508                return XST_DMA_SG_IS_STOPPED;
509        }
510
511        /* Ensure the interrupt status for the scatter gather is cleared such
512         * that this function will wait til the disable has occurred, writing
513         * a 1 to only that bit in the register will clear only it
514         */
515        XIo_Out32(InstancePtr->RegBaseAddress + XDC_IS_REG_OFFSET,
516                  XDC_IXR_SG_DISABLE_ACK_MASK);
517
518        /* disable scatter gather by writing to the software control register
519         * without modifying any other bits of the register
520         */
521        XIo_Out32(InstancePtr->RegBaseAddress + XDC_SWCR_REG_OFFSET,
522                  Register & ~XDC_SWCR_SG_ENABLE_MASK);
523
524        /* scatter gather does not disable immediately, but after the current
525         * buffer descriptor is complete, so wait for the DMA channel to indicate
526         * the disable is complete
527         */
528        do {
529                Register =
530                    XIo_In32(InstancePtr->RegBaseAddress + XDC_IS_REG_OFFSET);
531        } while ((Register & XDC_IXR_SG_DISABLE_ACK_MASK) == 0);
532
533        /* Ensure the interrupt status for the scatter gather disable is cleared,
534         * writing a 1 to only that bit in the register will clear only it
535         */
536        XIo_Out32(InstancePtr->RegBaseAddress + XDC_IS_REG_OFFSET,
537                  XDC_IXR_SG_DISABLE_ACK_MASK);
538
539        /* set the specified buffer descriptor pointer to point to the buffer
540         * descriptor that the scatter gather DMA channel was processing
541         */
542        *BufDescriptorPtr =
543            (XBufDescriptor *) XIo_In32(InstancePtr->RegBaseAddress +
544                                        XDC_BDA_REG_OFFSET);
545
546        return XST_SUCCESS;
547}
548
549/******************************************************************************
550*
551* FUNCTION:
552*
553* XDmaChannel_CreateSgList
554*
555* DESCRIPTION:
556*
557* This function creates a scatter gather list in the DMA channel.  A scatter
558* gather list consists of a list of buffer descriptors that are available to
559* be used for scatter gather operations.  Buffer descriptors are put into the
560* list to request a scatter gather operation to be performed.
561*
562* A number of buffer descriptors are created from the specified memory and put
563* into a buffer descriptor list as empty buffer descriptors. This function must
564* be called before non-empty buffer descriptors may be put into the DMA channel
565* to request scatter gather operations.
566*
567* ARGUMENTS:
568*
569* InstancePtr contains a pointer to the DMA channel to operate on.  The DMA
570* channel should be configured to use scatter gather in order for this function
571* to be called.
572*
573* MemoryPtr contains a pointer to the memory which is to be used for buffer
574* descriptors and must not be cached.
575*
576* ByteCount contains the number of bytes for the specified memory to be used
577* for buffer descriptors.
578*
579* RETURN VALUE:
580*
581* A status contains XST_SUCCESS if the scatter gather list was successfully
582* created.
583*
584* A value of XST_DMA_SG_LIST_EXISTS indicates that the scatter gather list
585* was not created because the list has already been created.
586*
587* NOTES:
588*
589* None.
590*
591******************************************************************************/
592XStatus
593XDmaChannel_CreateSgList(XDmaChannel * InstancePtr,
594                         u32 * MemoryPtr, u32 ByteCount)
595{
596        XBufDescriptor *BufferDescriptorPtr = (XBufDescriptor *) MemoryPtr;
597        XBufDescriptor *PreviousDescriptorPtr = NULL;
598        XBufDescriptor *StartOfListPtr = BufferDescriptorPtr;
599        u32 UsedByteCount;
600
601        /* assert to verify valid input arguments, alignment for those
602         * arguments that have alignment restrictions, and at least enough
603         * memory for one buffer descriptor
604         */
605        XASSERT_NONVOID(InstancePtr != NULL);
606        XASSERT_NONVOID(MemoryPtr != NULL);
607        XASSERT_NONVOID(((u32) MemoryPtr & 3) == 0);
608        XASSERT_NONVOID(ByteCount != 0);
609        XASSERT_NONVOID(ByteCount >= sizeof (XBufDescriptor));
610        XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
611
612        /* if the scatter gather list has already been created, then return
613         * with a status
614         */
615        if (InstancePtr->TotalDescriptorCount != 0) {
616                return XST_DMA_SG_LIST_EXISTS;
617        }
618
619        /* loop thru the specified memory block and create as many buffer
620         * descriptors as possible putting each into the list which is
621         * implemented as a ring buffer, make sure not to use any memory which
622         * is not large enough for a complete buffer descriptor
623         */
624        UsedByteCount = 0;
625        while ((UsedByteCount + sizeof (XBufDescriptor)) <= ByteCount) {
626                /* setup a pointer to the next buffer descriptor in the memory and
627                 * update # of used bytes to know when all of memory is used
628                 */
629                BufferDescriptorPtr = (XBufDescriptor *) ((u32) MemoryPtr +
630                                                          UsedByteCount);
631
632                /* initialize the new buffer descriptor such that it doesn't contain
633                 * garbage which could be used by the DMA hardware
634                 */
635                XBufDescriptor_Initialize(BufferDescriptorPtr);
636
637                /* if this is not the first buffer descriptor to be created,
638                 * then link it to the last created buffer descriptor
639                 */
640                if (PreviousDescriptorPtr != NULL) {
641                        XBufDescriptor_SetNextPtr(PreviousDescriptorPtr,
642                                                  BufferDescriptorPtr);
643                }
644
645                /* always keep a pointer to the last created buffer descriptor such
646                 * that they can be linked together in the ring buffer
647                 */
648                PreviousDescriptorPtr = BufferDescriptorPtr;
649
650                /* keep a count of the number of descriptors in the list to allow
651                 * error processing to be performed
652                 */
653                InstancePtr->TotalDescriptorCount++;
654
655                UsedByteCount += sizeof (XBufDescriptor);
656        }
657
658        /* connect the last buffer descriptor created and inserted in the list
659         * to the first such that a ring buffer is created
660         */
661        XBufDescriptor_SetNextPtr(BufferDescriptorPtr, StartOfListPtr);
662
663        /* initialize the ring buffer to indicate that there are no
664         * buffer descriptors in the list which point to valid data buffers
665         */
666        InstancePtr->PutPtr = BufferDescriptorPtr;
667        InstancePtr->GetPtr = BufferDescriptorPtr;
668        InstancePtr->CommitPtr = NULL;
669        InstancePtr->LastPtr = BufferDescriptorPtr;
670        InstancePtr->ActiveDescriptorCount = 0;
671
672        /* indicate the scatter gather list was successfully created */
673
674        return XST_SUCCESS;
675}
676
677/******************************************************************************
678*
679* FUNCTION:
680*
681* XDmaChannel_IsSgListEmpty
682*
683* DESCRIPTION:
684*
685* This function determines if the scatter gather list of a DMA channel is
686* empty with regard to buffer descriptors which are pointing to buffers to be
687* used for scatter gather operations.
688*
689* ARGUMENTS:
690*
691* InstancePtr contains a pointer to the DMA channel to operate on.  The DMA
692* channel should be configured to use scatter gather in order for this function
693* to be called.
694*
695* RETURN VALUE:
696*
697* A value of TRUE if the scatter gather list is empty, otherwise a value of
698* FALSE.
699*
700* NOTES:
701*
702* None.
703*
704******************************************************************************/
705u32
706XDmaChannel_IsSgListEmpty(XDmaChannel * InstancePtr)
707{
708        /* assert to verify valid input arguments */
709
710        XASSERT_NONVOID(InstancePtr != NULL);
711        XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
712
713        /* if the number of descriptors which are being used in the list is zero
714         * then the list is empty
715         */
716        return (InstancePtr->ActiveDescriptorCount == 0);
717}
718
719/******************************************************************************
720*
721* FUNCTION:
722*
723* XDmaChannel_PutDescriptor
724*
725* DESCRIPTION:
726*
727* This function puts a buffer descriptor into the DMA channel scatter
728* gather list. A DMA channel maintains a list of buffer descriptors which are
729* to be processed.  This function puts the specified buffer descriptor
730* at the next location in the list.  Note that since the list is already intact,
731* the information in the parameter is copied into the list (rather than modify
732* list pointers on the fly).
733*
734* After buffer descriptors are put into the list, they must also be committed
735* by calling another function.  This allows multiple buffer descriptors which
736* span a single packet to be put into the list while preventing the hardware
737* from starting the first buffer descriptor of the packet.
738*
739* ARGUMENTS:
740*
741* InstancePtr contains a pointer to the DMA channel to operate on.  The DMA
742* channel should be configured to use scatter gather in order for this function
743* to be called.
744*
745* BufferDescriptorPtr is a pointer to the buffer descriptor to be put into
746* the next available location of the scatter gather list.
747*
748* RETURN VALUE:
749*
750* A status which indicates XST_SUCCESS if the buffer descriptor was
751* successfully put into the scatter gather list.
752*
753* A value of XST_DMA_SG_NO_LIST indicates the scatter gather list has not
754* been created.
755*
756* A value of XST_DMA_SG_LIST_FULL indicates the buffer descriptor was not
757* put into the list because the list was full.
758*
759* A value of XST_DMA_SG_BD_LOCKED indicates the buffer descriptor was not
760* put into the list because the buffer descriptor in the list which is to
761* be overwritten was locked.  A locked buffer descriptor indicates the higher
762* layered software is still using the buffer descriptor.
763*
764* NOTES:
765*
766* It is necessary to create a scatter gather list for a DMA channel before
767* putting buffer descriptors into it.
768*
769******************************************************************************/
770XStatus
771XDmaChannel_PutDescriptor(XDmaChannel * InstancePtr,
772                          XBufDescriptor * BufferDescriptorPtr)
773{
774        u32 Control;
775
776        /* assert to verify valid input arguments and alignment for those
777         * arguments that have alignment restrictions
778         */
779        XASSERT_NONVOID(InstancePtr != NULL);
780        XASSERT_NONVOID(BufferDescriptorPtr != NULL);
781        XASSERT_NONVOID(((u32) BufferDescriptorPtr & 3) == 0);
782        XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
783
784        /* if a scatter gather list has not been created yet, return a status */
785
786        if (InstancePtr->TotalDescriptorCount == 0) {
787                return XST_DMA_SG_NO_LIST;
788        }
789
790        /* if the list is full because all descriptors are pointing to valid
791         * buffers, then indicate an error, this code assumes no list or an
792         * empty list is detected above
793         */
794        if (InstancePtr->ActiveDescriptorCount ==
795            InstancePtr->TotalDescriptorCount) {
796                return XST_DMA_SG_LIST_FULL;
797        }
798
799        /* if the buffer descriptor in the list which is to be overwritten is
800         * locked, then don't overwrite it and return a status
801         */
802        if (XBufDescriptor_IsLocked(InstancePtr->PutPtr)) {
803                return XST_DMA_SG_BD_LOCKED;
804        }
805
806        /* set the scatter gather stop bit in the control word of the descriptor
807         * to cause the h/w to stop after it processes this descriptor since it
808         * will be the last in the list
809         */
810        Control = XBufDescriptor_GetControl(BufferDescriptorPtr);
811        XBufDescriptor_SetControl(BufferDescriptorPtr,
812                                  Control | XDC_DMACR_SG_DISABLE_MASK);
813
814        /* set both statuses in the descriptor so we tell if they are updated with
815         * the status of the transfer, the hardware should change the busy in the
816         * DMA status to be false when it completes
817         */
818        XBufDescriptor_SetStatus(BufferDescriptorPtr, XDC_DMASR_BUSY_MASK);
819        XBufDescriptor_SetDeviceStatus(BufferDescriptorPtr, 0);
820
821        /* copy the descriptor into the next position in the list so it's ready to
822         * be used by the h/w, this assumes the descriptor in the list prior to this
823         * one still has the stop bit in the control word set such that the h/w
824         * use this one yet
825         */
826        CopyBufferDescriptor(BufferDescriptorPtr, InstancePtr->PutPtr);
827
828        /* only the last in the list and the one to be committed have scatter gather
829         * disabled in the control word, a commit requires only one descriptor
830         * to be changed, when # of descriptors to commit > 2 all others except the
831         * 1st and last have scatter gather enabled
832         */
833        if ((InstancePtr->CommitPtr != InstancePtr->LastPtr) &&
834            (InstancePtr->CommitPtr != NULL)) {
835                Control = XBufDescriptor_GetControl(InstancePtr->LastPtr);
836                XBufDescriptor_SetControl(InstancePtr->LastPtr,
837                                          Control & ~XDC_DMACR_SG_DISABLE_MASK);
838        }
839
840        /* update the list data based upon putting a descriptor into the list,
841         * these operations must be last
842         */
843        InstancePtr->ActiveDescriptorCount++;
844
845        /* only update the commit pointer if it is not already active, this allows
846         * it to be deactivated after every commit such that a single descriptor
847         * which is committed does not appear to be waiting to be committed
848         */
849        if (InstancePtr->CommitPtr == NULL) {
850                InstancePtr->CommitPtr = InstancePtr->LastPtr;
851        }
852
853        /* these updates MUST BE LAST after the commit pointer update in order for
854         * the commit pointer to track the correct descriptor to be committed
855         */
856        InstancePtr->LastPtr = InstancePtr->PutPtr;
857        InstancePtr->PutPtr = XBufDescriptor_GetNextPtr(InstancePtr->PutPtr);
858
859        return XST_SUCCESS;
860}
861
862/******************************************************************************
863*
864* FUNCTION:
865*
866* XDmaChannel_CommitPuts
867*
868* DESCRIPTION:
869*
870* This function commits the buffer descriptors which have been put into the
871* scatter list for the DMA channel since the last commit operation was
872* performed.  This enables the calling functions to put several buffer
873* descriptors into the list (e.g.,a packet's worth) before allowing the scatter
874* gather operations to start.  This prevents the DMA channel hardware from
875* starting to use the buffer descriptors in the list before they are ready
876* to be used (multiple buffer descriptors for a single packet).
877*
878* ARGUMENTS:
879*
880* InstancePtr contains a pointer to the DMA channel to operate on.  The DMA
881* channel should be configured to use scatter gather in order for this function
882* to be called.
883*
884* RETURN VALUE:
885*
886* A status indicating XST_SUCCESS if the buffer descriptors of the list were
887* successfully committed.
888*
889* A value of XST_DMA_SG_NOTHING_TO_COMMIT indicates that the buffer descriptors
890* were not committed because there was nothing to commit in the list.  All the
891* buffer descriptors which are in the list are commited.
892*
893* NOTES:
894*
895* None.
896*
897******************************************************************************/
898XStatus
899XDmaChannel_CommitPuts(XDmaChannel * InstancePtr)
900{
901        /* assert to verify input arguments */
902
903        XASSERT_NONVOID(InstancePtr != NULL);
904        XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
905
906        /* if the buffer descriptor to be committed is already committed or
907         * the list is empty (none have been put in), then indicate an error
908         */
909        if ((InstancePtr->CommitPtr == NULL) ||
910            XDmaChannel_IsSgListEmpty(InstancePtr)) {
911                return XST_DMA_SG_NOTHING_TO_COMMIT;
912        }
913
914        /* last descriptor in the list must have scatter gather disabled so the end
915         * of the list is hit by h/w, if descriptor to commit is not last in list,
916         * commit descriptors by enabling scatter gather in the descriptor
917         */
918        if (InstancePtr->CommitPtr != InstancePtr->LastPtr) {
919                u32 Control;
920
921                Control = XBufDescriptor_GetControl(InstancePtr->CommitPtr);
922                XBufDescriptor_SetControl(InstancePtr->CommitPtr, Control &
923                                          ~XDC_DMACR_SG_DISABLE_MASK);
924        }
925        /* Update the commit pointer to indicate that there is nothing to be
926         * committed, this state is used by start processing to know that the
927         * buffer descriptor to start is not waiting to be committed
928         */
929        InstancePtr->CommitPtr = NULL;
930
931        return XST_SUCCESS;
932}
933
934/******************************************************************************
935*
936* FUNCTION:
937*
938* XDmaChannel_GetDescriptor
939*
940* DESCRIPTION:
941*
942* This function gets a buffer descriptor from the scatter gather list of the
943* DMA channel. The buffer descriptor is retrieved from the scatter gather list
944* and the scatter gather list is updated to not include the retrieved buffer
945* descriptor.  This is typically done after a scatter gather operation
946* completes indicating that a data buffer has been successfully sent or data
947* has been received into the data buffer. The purpose of this function is to
948* allow the device using the scatter gather operation to get the results of the
949* operation.
950*
951* ARGUMENTS:
952*
953* InstancePtr contains a pointer to the DMA channel to operate on.  The DMA
954* channel should be configured to use scatter gather in order for this function
955* to be called.
956*
957* BufDescriptorPtr is a pointer to a pointer to the buffer descriptor which
958* was retrieved from the list.  The buffer descriptor is not really removed
959* from the list, but it is changed to a state such that the hardware will not
960* use it again until it is put into the scatter gather list of the DMA channel.
961*
962* RETURN VALUE:
963*
964* A status indicating XST_SUCCESS if a buffer descriptor was retrieved from
965* the scatter gather list of the DMA channel.
966*
967* A value of XST_DMA_SG_NO_LIST indicates the scatter gather list has not
968* been created.
969*
970* A value of XST_DMA_SG_LIST_EMPTY indicates no buffer descriptor was
971* retrieved from the list because there are no buffer descriptors to be
972* processed in the list.
973*
974* BufDescriptorPtr is updated to point to the buffer descriptor which was
975* retrieved from the list if the status indicates success.
976*
977* NOTES:
978*
979* None.
980*
981******************************************************************************/
982XStatus
983XDmaChannel_GetDescriptor(XDmaChannel * InstancePtr,
984                          XBufDescriptor ** BufDescriptorPtr)
985{
986        u32 Control;
987
988        /* assert to verify input arguments */
989
990        XASSERT_NONVOID(InstancePtr != NULL);
991        XASSERT_NONVOID(BufDescriptorPtr != NULL);
992        XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
993
994        /* if a scatter gather list has not been created yet, return a status */
995
996        if (InstancePtr->TotalDescriptorCount == 0) {
997                return XST_DMA_SG_NO_LIST;
998        }
999
1000        /* if the buffer descriptor list is empty, then indicate an error */
1001
1002        if (XDmaChannel_IsSgListEmpty(InstancePtr)) {
1003                return XST_DMA_SG_LIST_EMPTY;
1004        }
1005
1006        /* retrieve the next buffer descriptor which is ready to be processed from
1007         * the buffer descriptor list for the DMA channel, set the control word
1008         * such that hardware will stop after the descriptor has been processed
1009         */
1010        Control = XBufDescriptor_GetControl(InstancePtr->GetPtr);
1011        XBufDescriptor_SetControl(InstancePtr->GetPtr,
1012                                  Control | XDC_DMACR_SG_DISABLE_MASK);
1013
1014        /* set the input argument, which is also an output, to point to the
1015         * buffer descriptor which is to be retrieved from the list
1016         */
1017        *BufDescriptorPtr = InstancePtr->GetPtr;
1018
1019        /* update the pointer of the DMA channel to reflect the buffer descriptor
1020         * was retrieved from the list by setting it to the next buffer descriptor
1021         * in the list and indicate one less descriptor in the list now
1022         */
1023        InstancePtr->GetPtr = XBufDescriptor_GetNextPtr(InstancePtr->GetPtr);
1024        InstancePtr->ActiveDescriptorCount--;
1025
1026        return XST_SUCCESS;
1027}
1028
1029/*********************** Interrupt Collescing Functions **********************/
1030
1031/******************************************************************************
1032*
1033* FUNCTION:
1034*
1035* XDmaChannel_GetPktCount
1036*
1037* DESCRIPTION:
1038*
1039* This function returns the value of the unserviced packet count register of
1040* the DMA channel.  This count represents the number of packets that have been
1041* sent or received by the hardware, but not processed by software.
1042*
1043* ARGUMENTS:
1044*
1045* InstancePtr contains a pointer to the DMA channel to operate on.  The DMA
1046* channel should be configured to use scatter gather in order for this function
1047* to be called.
1048*
1049* RETURN VALUE:
1050*
1051* The unserviced packet counter register contents for the DMA channel.
1052*
1053* NOTES:
1054*
1055* None.
1056*
1057******************************************************************************/
1058u32
1059XDmaChannel_GetPktCount(XDmaChannel * InstancePtr)
1060{
1061        /* assert to verify input arguments */
1062
1063        XASSERT_NONVOID(InstancePtr != NULL);
1064        XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
1065
1066        /* get the unserviced packet count from the register and return it */
1067
1068        return XIo_In32(InstancePtr->RegBaseAddress + XDC_UPC_REG_OFFSET);
1069}
1070
1071/******************************************************************************
1072*
1073* FUNCTION:
1074*
1075* XDmaChannel_DecrementPktCount
1076*
1077* DESCRIPTION:
1078*
1079* This function decrements the value of the unserviced packet count register.
1080* This informs the hardware that the software has processed a packet.  The
1081* unserviced packet count register may only be decremented by one in the
1082* hardware.
1083*
1084* ARGUMENTS:
1085*
1086* InstancePtr contains a pointer to the DMA channel to operate on.  The DMA
1087* channel should be configured to use scatter gather in order for this function
1088* to be called.
1089*
1090* RETURN VALUE:
1091*
1092* None.
1093*
1094* NOTES:
1095*
1096* None.
1097*
1098******************************************************************************/
1099void
1100XDmaChannel_DecrementPktCount(XDmaChannel * InstancePtr)
1101{
1102        u32 Register;
1103
1104        /* assert to verify input arguments */
1105
1106        XASSERT_VOID(InstancePtr != NULL);
1107        XASSERT_VOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
1108
1109        /* if the unserviced packet count register can be decremented (rather
1110         * than rolling over) decrement it by writing a 1 to the register,
1111         * this is the only valid write to the register as it serves as an
1112         * acknowledge that a packet was handled by the software
1113         */
1114        Register = XIo_In32(InstancePtr->RegBaseAddress + XDC_UPC_REG_OFFSET);
1115        if (Register > 0) {
1116                XIo_Out32(InstancePtr->RegBaseAddress + XDC_UPC_REG_OFFSET,
1117                          1UL);
1118        }
1119}
1120
1121/******************************************************************************
1122*
1123* FUNCTION:
1124*
1125* XDmaChannel_SetPktThreshold
1126*
1127* DESCRIPTION:
1128*
1129* This function sets the value of the packet count threshold register of the
1130* DMA channel.  It reflects the number of packets that must be sent or
1131* received before generating an interrupt.  This value helps implement
1132* a concept called "interrupt coalescing", which is used to reduce the number
1133* of interrupts from devices with high data rates.
1134*
1135* ARGUMENTS:
1136*
1137* InstancePtr contains a pointer to the DMA channel to operate on.  The DMA
1138* channel should be configured to use scatter gather in order for this function
1139* to be called.
1140*
1141* Threshold is the value that is written to the threshold register of the
1142* DMA channel.
1143*
1144* RETURN VALUE:
1145*
1146* A status containing XST_SUCCESS if the packet count threshold was
1147* successfully set.
1148*
1149* NOTES:
1150*
1151* The packet threshold could be set to larger than the number of descriptors
1152* allocated to the DMA channel. In this case, the wait bound will take over
1153* and always indicate data arrival. There was a check in this function that
1154* returned an error if the treshold was larger than the number of descriptors,
1155* but that was removed because users would then have to set the threshold
1156* only after they set descriptor space, which is an order dependency that
1157* caused confustion.
1158*
1159******************************************************************************/
1160XStatus
1161XDmaChannel_SetPktThreshold(XDmaChannel * InstancePtr, u8 Threshold)
1162{
1163        /* assert to verify input arguments, don't assert the threshold since
1164         * it's range is unknown
1165         */
1166        XASSERT_NONVOID(InstancePtr != NULL);
1167        XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
1168
1169        /* set the packet count threshold in the register such that an interrupt
1170         * may be generated, if enabled, when the packet count threshold is
1171         * reached or exceeded
1172         */
1173        XIo_Out32(InstancePtr->RegBaseAddress + XDC_PCT_REG_OFFSET,
1174                  (u32) Threshold);
1175
1176        /* indicate the packet count threshold was successfully set */
1177
1178        return XST_SUCCESS;
1179}
1180
1181/******************************************************************************
1182*
1183* FUNCTION:
1184*
1185* XDmaChannel_GetPktThreshold
1186*
1187* DESCRIPTION:
1188*
1189* This function gets the value of the packet count threshold register of the
1190* DMA channel.  This value reflects the number of packets that must be sent or
1191* received before generating an interrupt.  This value helps implement a concept
1192* called "interrupt coalescing", which is used to reduce the number of
1193* interrupts from devices with high data rates.
1194*
1195* ARGUMENTS:
1196*
1197* InstancePtr contains a pointer to the DMA channel to operate on.  The DMA
1198* channel should be configured to use scatter gather in order for this function
1199* to be called.
1200*
1201* RETURN VALUE:
1202*
1203* The packet threshold register contents for the DMA channel and is a value in
1204* the range 0 - 1023.  A value of 0 indicates the packet wait bound timer is
1205* disabled.
1206*
1207* NOTES:
1208*
1209* None.
1210*
1211******************************************************************************/
1212u8
1213XDmaChannel_GetPktThreshold(XDmaChannel * InstancePtr)
1214{
1215        /* assert to verify input arguments */
1216
1217        XASSERT_NONVOID(InstancePtr != NULL);
1218        XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
1219
1220        /* get the packet count threshold from the register and return it,
1221         * since only 8 bits are used, cast it to return only those bits */
1222
1223        return (u8) XIo_In32(InstancePtr->RegBaseAddress + XDC_PCT_REG_OFFSET);
1224}
1225
1226/******************************************************************************
1227*
1228* FUNCTION:
1229*
1230* XDmaChannel_SetPktWaitBound
1231*
1232* DESCRIPTION:
1233*
1234* This function sets the value of the packet wait bound register of the
1235* DMA channel.  This value reflects the timer value used to trigger an
1236* interrupt when not enough packets have been received to reach the packet
1237* count threshold.
1238*
1239* The timer is in millisecond units with +/- 33% accuracy.
1240*
1241* ARGUMENTS:
1242*
1243* InstancePtr contains a pointer to the DMA channel to operate on.  The DMA
1244* channel should be configured to use scatter gather in order for this function
1245* to be called.
1246*
1247* WaitBound is the value, in milliseconds, to be stored in the wait bound
1248* register of the DMA channel and is a value in the range 0  - 1023.  A value
1249* of 0 disables the packet wait bound timer.
1250*
1251* RETURN VALUE:
1252*
1253* None.
1254*
1255* NOTES:
1256*
1257* None.
1258*
1259******************************************************************************/
1260void
1261XDmaChannel_SetPktWaitBound(XDmaChannel * InstancePtr, u32 WaitBound)
1262{
1263        /* assert to verify input arguments */
1264
1265        XASSERT_VOID(InstancePtr != NULL);
1266        XASSERT_VOID(WaitBound < 1024);
1267        XASSERT_VOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
1268
1269        /* set the packet wait bound in the register such that interrupt may be
1270         * generated, if enabled, when packets have not been handled for a specific
1271         * amount of time
1272         */
1273        XIo_Out32(InstancePtr->RegBaseAddress + XDC_PWB_REG_OFFSET, WaitBound);
1274}
1275
1276/******************************************************************************
1277*
1278* FUNCTION:
1279*
1280* XDmaChannel_GetPktWaitBound
1281*
1282* DESCRIPTION:
1283*
1284* This function gets the value of the packet wait bound register of the
1285* DMA channel.  This value contains the timer value used to trigger an
1286* interrupt when not enough packets have been received to reach the packet
1287* count threshold.
1288*
1289* The timer is in millisecond units with +/- 33% accuracy.
1290*
1291* ARGUMENTS:
1292*
1293* InstancePtr contains a pointer to the DMA channel to operate on.  The DMA
1294* channel should be configured to use scatter gather in order for this function
1295* to be called.
1296*
1297* RETURN VALUE:
1298*
1299* The packet wait bound register contents for the DMA channel.
1300*
1301* NOTES:
1302*
1303* None.
1304*
1305******************************************************************************/
1306u32
1307XDmaChannel_GetPktWaitBound(XDmaChannel * InstancePtr)
1308{
1309        /* assert to verify input arguments */
1310
1311        XASSERT_NONVOID(InstancePtr != NULL);
1312        XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
1313
1314        /* get the packet wait bound from the register and return it */
1315
1316        return XIo_In32(InstancePtr->RegBaseAddress + XDC_PWB_REG_OFFSET);
1317}
Note: See TracBrowser for help on using the repository browser.