2 * Copyright (c) 2013 Qualcomm Atheros, Inc.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted (subject to the limitations in the
7 * disclaimer below) provided that the following conditions are met:
9 * * Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
12 * * Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the
17 * * Neither the name of Qualcomm Atheros nor the names of its
18 * contributors may be used to endorse or promote products derived
19 * from this software without specific prior written permission.
21 * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE
22 * GRANTED BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT
23 * HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
24 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
25 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
26 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
27 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
28 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
29 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
30 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
31 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
32 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
33 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35 #ifndef __AR6K_HTC_H__
36 #define __AR6K_HTC_H__
38 /* Host/Target Communications for an AR6K Target */
40 /* Number of mailboxes */
41 #define AR6000_MBOX_COUNT 4
43 /* ------ MBOX ID ------ */
54 /* An AR6000 DMA Descriptor. See HTC_descriptor(). */
55 struct AR6000_DMA_desc_s {
58 struct AR6000_DMA_desc_s *dma_next;
63 * Make a Mailbox DMA descriptor available to HTC.
65 * Once made available, there is no way to reclaim this memory.
66 * The caller must guarantee that a descriptor exists for each
67 * buffer that is used to send or receive. It is expected that
68 * the caller will supply a bunch of descriptors once during
69 * initialization, and then forget about them. The number of
70 * buffers given to HTC for send+recv must never exceed the
71 * number of descriptors given to HTC.
73 * HTC accesses descriptors via uncached accesses. The caller
74 * must guarantee not to place any other data in the same cache
75 * line as a DMA descriptor! In practice, this means that the
76 * caller should allocate a block of memory for descriptors,
77 * and the block should include padding at the start and end
78 * to guarantee there will be no other data in the same cache
81 * It would be far preferable to bury descriptors in the bufinfo
82 * structure; but there are practical issues that prevent this.
83 * It turns out that the most efficient way to add descriptors
84 * to an active DMA engine requires HTC to "own and actively
85 * manage" the descriptors. HTC needs to make the association
86 * between descriptors and buffers at the last possible moment.
88 * extern void _HTC_descriptor(struct AR6000_DMA_desc_s *descriptor);
92 * The following interfaces make it easy to allocate suitable
93 * descriptors for HTC. During initialization, simply use the
94 * HTC_DESCRIPTORS_INIT macro and specify the number of descriptors
95 * desired. This number must be a constant, since it is used to
96 * declare a static array!
98 * The descriptor array is padded with a cache line at the start
99 * and another at the end. This avoids false sharing between adjacent
100 * cached data and uncached descriptors.
102 #define HTC_DESCRIPTOR_SPACE_SIZE(ndescs) \
103 (((ndescs) * sizeof(struct AR6000_DMA_desc_s)) + 2*A_CACHE_LINE_SIZE)
105 #define HTC_DESCRIPTORS_INIT(ndescs) \
107 static A_UINT8 HTC_descriptor_space[HTC_DESCRIPTOR_SPACE_SIZE(ndescs)]; \
108 struct AR6000_DMA_desc_s *desc; \
111 A_DATA_CACHE_FLUSH(HTC_descriptor_space, sizeof(HTC_descriptor_space)); \
113 desc = (struct AR6000_DMA_desc_s *) \
114 A_ROUND_UP((A_UINT32)HTC_descriptor_space, A_CACHE_LINE_SIZE); \
116 for (i=0; i<(ndescs); i++) { \
117 HTC_descriptor(desc); \
122 #endif /* __AR6K_HTC_H__ */