4 /* Host/Target Communications for an AR6K Target */
6 /* Number of mailboxes */
7 #define AR6000_MBOX_COUNT 4
9 /* ------ MBOX ID ------ */
20 /* An AR6000 DMA Descriptor. See HTC_descriptor(). */
21 struct AR6000_DMA_desc_s {
24 struct AR6000_DMA_desc_s *dma_next;
29 * Make a Mailbox DMA descriptor available to HTC.
31 * Once made available, there is no way to reclaim this memory.
32 * The caller must guarantee that a descriptor exists for each
33 * buffer that is used to send or receive. It is expected that
34 * the caller will supply a bunch of descriptors once during
35 * initialization, and then forget about them. The number of
36 * buffers given to HTC for send+recv must never exceed the
37 * number of descriptors given to HTC.
39 * HTC accesses descriptors via uncached accesses. The caller
40 * must guarantee not to place any other data in the same cache
41 * line as a DMA descriptor! In practice, this means that the
42 * caller should allocate a block of memory for descriptors,
43 * and the block should include padding at the start and end
44 * to guarantee there will be no other data in the same cache
47 * It would be far preferable to bury descriptors in the bufinfo
48 * structure; but there are practical issues that prevent this.
49 * It turns out that the most efficient way to add descriptors
50 * to an active DMA engine requires HTC to "own and actively
51 * manage" the descriptors. HTC needs to make the association
52 * between descriptors and buffers at the last possible moment.
54 * extern void _HTC_descriptor(struct AR6000_DMA_desc_s *descriptor);
58 * The following interfaces make it easy to allocate suitable
59 * descriptors for HTC. During initialization, simply use the
60 * HTC_DESCRIPTORS_INIT macro and specify the number of descriptors
61 * desired. This number must be a constant, since it is used to
62 * declare a static array!
64 * The descriptor array is padded with a cache line at the start
65 * and another at the end. This avoids false sharing between adjacent
66 * cached data and uncached descriptors.
68 #define HTC_DESCRIPTOR_SPACE_SIZE(ndescs) \
69 (((ndescs) * sizeof(struct AR6000_DMA_desc_s)) + 2*A_CACHE_LINE_SIZE)
71 #define HTC_DESCRIPTORS_INIT(ndescs) \
73 static A_UINT8 HTC_descriptor_space[HTC_DESCRIPTOR_SPACE_SIZE(ndescs)]; \
74 struct AR6000_DMA_desc_s *desc; \
77 A_DATA_CACHE_FLUSH(HTC_descriptor_space, sizeof(HTC_descriptor_space)); \
79 desc = (struct AR6000_DMA_desc_s *) \
80 A_ROUND_UP((A_UINT32)HTC_descriptor_space, A_CACHE_LINE_SIZE); \
82 for (i=0; i<(ndescs); i++) { \
83 HTC_descriptor(desc); \
88 #endif /* __AR6K_HTC_H__ */