blob: 1caa6d688c402f74f4244a1ec0365d3f7096880f [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/*
Ivo van Doorn08992f72008-01-24 01:56:25 -080030 * skb_desc
31 * Descriptor information for the skb buffer
32 */
33struct skb_desc {
34 unsigned int frame_type;
35
36 unsigned int desc_len;
37 unsigned int data_len;
38
39 void *desc;
40 void *data;
41
42 struct data_ring *ring;
43 struct data_entry *entry;
44};
45
46static inline struct skb_desc* get_skb_desc(struct sk_buff *skb)
47{
48 return (struct skb_desc*)&skb->cb[0];
49}
50
51/*
Johannes Berg4150c572007-09-17 01:29:23 -040052 * rxdata_entry_desc
53 * Summary of information that has been read from the
54 * RX frame descriptor.
55 */
56struct rxdata_entry_desc {
57 int signal;
58 int rssi;
59 int ofdm;
60 int size;
61 int flags;
Ivo van Doorn7e56d382008-01-06 23:41:28 +010062 int my_bss;
Johannes Berg4150c572007-09-17 01:29:23 -040063};
64
65/*
66 * txdata_entry_desc
Ivo van Doorn95ea3622007-09-25 17:57:13 -070067 * Summary of information that should be written into the
68 * descriptor for sending a TX frame.
69 */
Johannes Berg4150c572007-09-17 01:29:23 -040070struct txdata_entry_desc {
Ivo van Doorn95ea3622007-09-25 17:57:13 -070071 unsigned long flags;
72#define ENTRY_TXDONE 1
73#define ENTRY_TXD_RTS_FRAME 2
74#define ENTRY_TXD_OFDM_RATE 3
75#define ENTRY_TXD_MORE_FRAG 4
76#define ENTRY_TXD_REQ_TIMESTAMP 5
77#define ENTRY_TXD_BURST 6
Mattias Nissler2700f8b2007-10-27 13:43:49 +020078#define ENTRY_TXD_ACK 7
Ivo van Doorn95ea3622007-09-25 17:57:13 -070079
80/*
81 * Queue ID. ID's 0-4 are data TX rings
82 */
83 int queue;
84#define QUEUE_MGMT 13
85#define QUEUE_RX 14
86#define QUEUE_OTHER 15
87
88 /*
89 * PLCP values.
90 */
91 u16 length_high;
92 u16 length_low;
93 u16 signal;
94 u16 service;
95
96 /*
97 * Timing information
98 */
99 int aifs;
100 int ifs;
101 int cw_min;
102 int cw_max;
103};
104
105/*
106 * data_entry
107 * The data ring is a list of data entries.
108 * Each entry holds a reference to the descriptor
109 * and the data buffer. For TX rings the reference to the
110 * sk_buff of the packet being transmitted is also stored here.
111 */
112struct data_entry {
113 /*
114 * Status flags
115 */
116 unsigned long flags;
117#define ENTRY_OWNER_NIC 1
118
119 /*
120 * Ring we belong to.
121 */
122 struct data_ring *ring;
123
124 /*
125 * sk_buff for the packet which is being transmitted
126 * in this entry (Only used with TX related rings).
127 */
128 struct sk_buff *skb;
129
130 /*
131 * Store a ieee80211_tx_status structure in each
132 * ring entry, this will optimize the txdone
133 * handler.
134 */
135 struct ieee80211_tx_status tx_status;
136
137 /*
138 * private pointer specific to driver.
139 */
140 void *priv;
141
142 /*
143 * Data address for this entry.
144 */
145 void *data_addr;
146 dma_addr_t data_dma;
Ivo van Doorn04267102008-01-06 23:39:25 +0100147
148 /*
149 * Entry identification number (index).
150 */
151 unsigned int entry_idx;
Ivo van Doorn95ea3622007-09-25 17:57:13 -0700152};
153
154/*
155 * data_ring
156 * Data rings are used by the device to send and receive packets.
157 * The data_addr is the base address of the data memory.
158 * To determine at which point in the ring we are,
159 * have to use the rt2x00_ring_index_*() functions.
160 */
161struct data_ring {
162 /*
163 * Pointer to main rt2x00dev structure where this
164 * ring belongs to.
165 */
166 struct rt2x00_dev *rt2x00dev;
167
168 /*
169 * Base address for the device specific data entries.
170 */
171 struct data_entry *entry;
172
173 /*
174 * TX queue statistic info.
175 */
176 struct ieee80211_tx_queue_stats_data stats;
177
178 /*
179 * TX Queue parameters.
180 */
181 struct ieee80211_tx_queue_params tx_params;
182
183 /*
184 * Base address for data ring.
185 */
186 dma_addr_t data_dma;
187 void *data_addr;
188
189 /*
Ivo van Doorn04267102008-01-06 23:39:25 +0100190 * Queue identification number:
191 * RX: 0
192 * TX: IEEE80211_TX_*
193 */
194 unsigned int queue_idx;
195
196 /*
Ivo van Doorn95ea3622007-09-25 17:57:13 -0700197 * Index variables.
198 */
199 u16 index;
200 u16 index_done;
201
202 /*
203 * Size of packet and descriptor in bytes.
204 */
205 u16 data_size;
206 u16 desc_size;
207};
208
209/*
210 * Handlers to determine the address of the current device specific
211 * data entry, where either index or index_done points to.
212 */
213static inline struct data_entry *rt2x00_get_data_entry(struct data_ring *ring)
214{
215 return &ring->entry[ring->index];
216}
217
218static inline struct data_entry *rt2x00_get_data_entry_done(struct data_ring
219 *ring)
220{
221 return &ring->entry[ring->index_done];
222}
223
224/*
225 * Total ring memory
226 */
227static inline int rt2x00_get_ring_size(struct data_ring *ring)
228{
229 return ring->stats.limit * (ring->desc_size + ring->data_size);
230}
231
232/*
233 * Ring index manipulation functions.
234 */
235static inline void rt2x00_ring_index_inc(struct data_ring *ring)
236{
237 ring->index++;
238 if (ring->index >= ring->stats.limit)
239 ring->index = 0;
240 ring->stats.len++;
241}
242
243static inline void rt2x00_ring_index_done_inc(struct data_ring *ring)
244{
245 ring->index_done++;
246 if (ring->index_done >= ring->stats.limit)
247 ring->index_done = 0;
248 ring->stats.len--;
249 ring->stats.count++;
250}
251
252static inline void rt2x00_ring_index_clear(struct data_ring *ring)
253{
254 ring->index = 0;
255 ring->index_done = 0;
256 ring->stats.len = 0;
257 ring->stats.count = 0;
258}
259
260static inline int rt2x00_ring_empty(struct data_ring *ring)
261{
262 return ring->stats.len == 0;
263}
264
265static inline int rt2x00_ring_full(struct data_ring *ring)
266{
267 return ring->stats.len == ring->stats.limit;
268}
269
270static inline int rt2x00_ring_free(struct data_ring *ring)
271{
272 return ring->stats.limit - ring->stats.len;
273}
274
275/*
276 * TX/RX Descriptor access functions.
277 */
Ivo van Doorn4bd7c452008-01-24 00:48:03 -0800278static inline void rt2x00_desc_read(__le32 *desc,
Ivo van Doorn95ea3622007-09-25 17:57:13 -0700279 const u8 word, u32 *value)
280{
Ivo van Doorn4bd7c452008-01-24 00:48:03 -0800281 *value = le32_to_cpu(desc[word]);
Ivo van Doorn95ea3622007-09-25 17:57:13 -0700282}
283
Ivo van Doorn4bd7c452008-01-24 00:48:03 -0800284static inline void rt2x00_desc_write(__le32 *desc,
Ivo van Doorn95ea3622007-09-25 17:57:13 -0700285 const u8 word, const u32 value)
286{
Ivo van Doorn4bd7c452008-01-24 00:48:03 -0800287 desc[word] = cpu_to_le32(value);
Ivo van Doorn95ea3622007-09-25 17:57:13 -0700288}
289
290#endif /* RT2X00RING_H */