blob: a8e94625bf9f5487ba1272e77490b3b57251d1d2 [file] [log] [blame]
wdenke537b3b2004-02-23 23:54:43 +00001/* $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}