blob: ee6c423a53d98a3a705f79089348788bf6bd5c5d [file] [log] [blame]
Ivo van Doorn95ea3622007-09-25 17:57:13 -07001/*
2 Copyright (C) 2004 - 2007 rt2x00 SourceForge Project
3 <http://rt2x00.serialmonkey.com>
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the
17 Free Software Foundation, Inc.,
18 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 */
20
21/*
22 Module: rt2x00
23 Abstract: rt2x00 ring datastructures and routines
24 */
25
26#ifndef RT2X00RING_H
27#define RT2X00RING_H
28
29/*
Johannes Berg4150c572007-09-17 01:29:23 -040030 * rxdata_entry_desc
31 * Summary of information that has been read from the
32 * RX frame descriptor.
33 */
34struct rxdata_entry_desc {
35 int signal;
36 int rssi;
37 int ofdm;
38 int size;
39 int flags;
40};
41
42/*
43 * txdata_entry_desc
Ivo van Doorn95ea3622007-09-25 17:57:13 -070044 * Summary of information that should be written into the
45 * descriptor for sending a TX frame.
46 */
Johannes Berg4150c572007-09-17 01:29:23 -040047struct txdata_entry_desc {
Ivo van Doorn95ea3622007-09-25 17:57:13 -070048 unsigned long flags;
49#define ENTRY_TXDONE 1
50#define ENTRY_TXD_RTS_FRAME 2
51#define ENTRY_TXD_OFDM_RATE 3
52#define ENTRY_TXD_MORE_FRAG 4
53#define ENTRY_TXD_REQ_TIMESTAMP 5
54#define ENTRY_TXD_BURST 6
55
56/*
57 * Queue ID. ID's 0-4 are data TX rings
58 */
59 int queue;
60#define QUEUE_MGMT 13
61#define QUEUE_RX 14
62#define QUEUE_OTHER 15
63
64 /*
65 * PLCP values.
66 */
67 u16 length_high;
68 u16 length_low;
69 u16 signal;
70 u16 service;
71
72 /*
73 * Timing information
74 */
75 int aifs;
76 int ifs;
77 int cw_min;
78 int cw_max;
79};
80
81/*
82 * data_entry
83 * The data ring is a list of data entries.
84 * Each entry holds a reference to the descriptor
85 * and the data buffer. For TX rings the reference to the
86 * sk_buff of the packet being transmitted is also stored here.
87 */
88struct data_entry {
89 /*
90 * Status flags
91 */
92 unsigned long flags;
93#define ENTRY_OWNER_NIC 1
94
95 /*
96 * Ring we belong to.
97 */
98 struct data_ring *ring;
99
100 /*
101 * sk_buff for the packet which is being transmitted
102 * in this entry (Only used with TX related rings).
103 */
104 struct sk_buff *skb;
105
106 /*
107 * Store a ieee80211_tx_status structure in each
108 * ring entry, this will optimize the txdone
109 * handler.
110 */
111 struct ieee80211_tx_status tx_status;
112
113 /*
114 * private pointer specific to driver.
115 */
116 void *priv;
117
118 /*
119 * Data address for this entry.
120 */
121 void *data_addr;
122 dma_addr_t data_dma;
123};
124
125/*
126 * data_ring
127 * Data rings are used by the device to send and receive packets.
128 * The data_addr is the base address of the data memory.
129 * To determine at which point in the ring we are,
130 * have to use the rt2x00_ring_index_*() functions.
131 */
132struct data_ring {
133 /*
134 * Pointer to main rt2x00dev structure where this
135 * ring belongs to.
136 */
137 struct rt2x00_dev *rt2x00dev;
138
139 /*
140 * Base address for the device specific data entries.
141 */
142 struct data_entry *entry;
143
144 /*
145 * TX queue statistic info.
146 */
147 struct ieee80211_tx_queue_stats_data stats;
148
149 /*
150 * TX Queue parameters.
151 */
152 struct ieee80211_tx_queue_params tx_params;
153
154 /*
155 * Base address for data ring.
156 */
157 dma_addr_t data_dma;
158 void *data_addr;
159
160 /*
161 * Index variables.
162 */
163 u16 index;
164 u16 index_done;
165
166 /*
167 * Size of packet and descriptor in bytes.
168 */
169 u16 data_size;
170 u16 desc_size;
171};
172
173/*
174 * Handlers to determine the address of the current device specific
175 * data entry, where either index or index_done points to.
176 */
177static inline struct data_entry *rt2x00_get_data_entry(struct data_ring *ring)
178{
179 return &ring->entry[ring->index];
180}
181
182static inline struct data_entry *rt2x00_get_data_entry_done(struct data_ring
183 *ring)
184{
185 return &ring->entry[ring->index_done];
186}
187
188/*
189 * Total ring memory
190 */
191static inline int rt2x00_get_ring_size(struct data_ring *ring)
192{
193 return ring->stats.limit * (ring->desc_size + ring->data_size);
194}
195
196/*
197 * Ring index manipulation functions.
198 */
199static inline void rt2x00_ring_index_inc(struct data_ring *ring)
200{
201 ring->index++;
202 if (ring->index >= ring->stats.limit)
203 ring->index = 0;
204 ring->stats.len++;
205}
206
207static inline void rt2x00_ring_index_done_inc(struct data_ring *ring)
208{
209 ring->index_done++;
210 if (ring->index_done >= ring->stats.limit)
211 ring->index_done = 0;
212 ring->stats.len--;
213 ring->stats.count++;
214}
215
216static inline void rt2x00_ring_index_clear(struct data_ring *ring)
217{
218 ring->index = 0;
219 ring->index_done = 0;
220 ring->stats.len = 0;
221 ring->stats.count = 0;
222}
223
224static inline int rt2x00_ring_empty(struct data_ring *ring)
225{
226 return ring->stats.len == 0;
227}
228
229static inline int rt2x00_ring_full(struct data_ring *ring)
230{
231 return ring->stats.len == ring->stats.limit;
232}
233
234static inline int rt2x00_ring_free(struct data_ring *ring)
235{
236 return ring->stats.limit - ring->stats.len;
237}
238
239/*
240 * TX/RX Descriptor access functions.
241 */
Ivo van Doorn4bd7c452008-01-24 00:48:03 -0800242static inline void rt2x00_desc_read(__le32 *desc,
Ivo van Doorn95ea3622007-09-25 17:57:13 -0700243 const u8 word, u32 *value)
244{
Ivo van Doorn4bd7c452008-01-24 00:48:03 -0800245 *value = le32_to_cpu(desc[word]);
Ivo van Doorn95ea3622007-09-25 17:57:13 -0700246}
247
Ivo van Doorn4bd7c452008-01-24 00:48:03 -0800248static inline void rt2x00_desc_write(__le32 *desc,
Ivo van Doorn95ea3622007-09-25 17:57:13 -0700249 const u8 word, const u32 value)
250{
Ivo van Doorn4bd7c452008-01-24 00:48:03 -0800251 desc[word] = cpu_to_le32(value);
Ivo van Doorn95ea3622007-09-25 17:57:13 -0700252}
253
254#endif /* RT2X00RING_H */