diff options
author | Luis R. Rodriguez <lrodriguez@atheros.com> | 2008-08-04 03:16:41 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2008-08-07 09:49:42 -0400 |
commit | f078f209704849c86bd43c0beccfc1f410ed1c66 (patch) | |
tree | 9b965db2c86e7369002a05808f6b418c8a9aa985 /drivers/net/wireless/ath9k/core.h | |
parent | b1a5215004130689aeee9e522585c879d3b71472 (diff) |
ath9k: Add new Atheros IEEE 802.11n driver
This adds the new mac80211 11n ath9k Atheros driver. Only STA support
is currently enabled and tested.
Signed-off-by: Senthil Balasubramanian <senthilkumar@atheros.com>
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
Signed-off-by: Jack Howarth <howarth@bromo.msbb.uc.edu>
Signed-off-by: Jouni Malinen <jouni.malinen@atheros.com>
Signed-off-by: Sujith Manoharan <Sujith.Manoharan@atheros.com>
Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
Signed-off-by: Pavel Roskin <proski@gnu.org>
Signed-off-by: Vasanthakumar Thiagarajan <vasanth@atheros.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/ath9k/core.h')
-rw-r--r-- | drivers/net/wireless/ath9k/core.h | 1097 |
1 files changed, 1097 insertions, 0 deletions
diff --git a/drivers/net/wireless/ath9k/core.h b/drivers/net/wireless/ath9k/core.h new file mode 100644 index 00000000000..cf76b36d175 --- /dev/null +++ b/drivers/net/wireless/ath9k/core.h | |||
@@ -0,0 +1,1097 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2008 Atheros Communications Inc. | ||
3 | * | ||
4 | * Permission to use, copy, modify, and/or distribute this software for any | ||
5 | * purpose with or without fee is hereby granted, provided that the above | ||
6 | * copyright notice and this permission notice appear in all copies. | ||
7 | * | ||
8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
15 | */ | ||
16 | |||
17 | #ifndef CORE_H | ||
18 | #define CORE_H | ||
19 | |||
20 | #include <linux/version.h> | ||
21 | #include <linux/autoconf.h> | ||
22 | #include <linux/kernel.h> | ||
23 | #include <linux/module.h> | ||
24 | #include <linux/spinlock.h> | ||
25 | #include <linux/errno.h> | ||
26 | #include <linux/skbuff.h> | ||
27 | #include <linux/netdevice.h> | ||
28 | #include <linux/etherdevice.h> | ||
29 | #include <linux/ip.h> | ||
30 | #include <linux/tcp.h> | ||
31 | #include <linux/in.h> | ||
32 | #include <linux/delay.h> | ||
33 | #include <linux/wait.h> | ||
34 | #include <linux/pci.h> | ||
35 | #include <linux/interrupt.h> | ||
36 | #include <linux/sched.h> | ||
37 | #include <linux/list.h> | ||
38 | #include <asm/byteorder.h> | ||
39 | #include <linux/scatterlist.h> | ||
40 | #include <asm/page.h> | ||
41 | #include <net/mac80211.h> | ||
42 | |||
43 | #include "ath9k.h" | ||
44 | #include "rc.h" | ||
45 | |||
46 | struct ath_node; | ||
47 | |||
48 | /******************/ | ||
49 | /* Utility macros */ | ||
50 | /******************/ | ||
51 | |||
52 | /* Macro to expand scalars to 64-bit objects */ | ||
53 | |||
54 | #define ito64(x) (sizeof(x) == 8) ? \ | ||
55 | (((unsigned long long int)(x)) & (0xff)) : \ | ||
56 | (sizeof(x) == 16) ? \ | ||
57 | (((unsigned long long int)(x)) & 0xffff) : \ | ||
58 | ((sizeof(x) == 32) ? \ | ||
59 | (((unsigned long long int)(x)) & 0xffffffff) : \ | ||
60 | (unsigned long long int)(x)) | ||
61 | |||
62 | /* increment with wrap-around */ | ||
63 | #define INCR(_l, _sz) do { \ | ||
64 | (_l)++; \ | ||
65 | (_l) &= ((_sz) - 1); \ | ||
66 | } while (0) | ||
67 | |||
68 | /* decrement with wrap-around */ | ||
69 | #define DECR(_l, _sz) do { \ | ||
70 | (_l)--; \ | ||
71 | (_l) &= ((_sz) - 1); \ | ||
72 | } while (0) | ||
73 | |||
74 | #define A_MAX(a, b) ((a) > (b) ? (a) : (b)) | ||
75 | |||
76 | #define ASSERT(exp) do { \ | ||
77 | if (unlikely(!(exp))) { \ | ||
78 | BUG(); \ | ||
79 | } \ | ||
80 | } while (0) | ||
81 | |||
82 | /* XXX: remove */ | ||
83 | #define memzero(_buf, _len) memset(_buf, 0, _len) | ||
84 | |||
85 | #define get_dma_mem_context(var, field) (&((var)->field)) | ||
86 | #define copy_dma_mem_context(dst, src) (*dst = *src) | ||
87 | |||
88 | #define ATH9K_BH_STATUS_INTACT 0 | ||
89 | #define ATH9K_BH_STATUS_CHANGE 1 | ||
90 | |||
91 | #define ATH_TXQ_SETUP(sc, i) ((sc)->sc_txqsetup & (1<<i)) | ||
92 | |||
93 | static inline unsigned long get_timestamp(void) | ||
94 | { | ||
95 | return ((jiffies / HZ) * 1000) + (jiffies % HZ) * (1000 / HZ); | ||
96 | } | ||
97 | |||
98 | /*************/ | ||
99 | /* Debugging */ | ||
100 | /*************/ | ||
101 | |||
102 | enum ATH_DEBUG { | ||
103 | ATH_DBG_RESET = 0x00000001, | ||
104 | ATH_DBG_PHY_IO = 0x00000002, | ||
105 | ATH_DBG_REG_IO = 0x00000004, | ||
106 | ATH_DBG_QUEUE = 0x00000008, | ||
107 | ATH_DBG_EEPROM = 0x00000010, | ||
108 | ATH_DBG_NF_CAL = 0x00000020, | ||
109 | ATH_DBG_CALIBRATE = 0x00000040, | ||
110 | ATH_DBG_CHANNEL = 0x00000080, | ||
111 | ATH_DBG_INTERRUPT = 0x00000100, | ||
112 | ATH_DBG_REGULATORY = 0x00000200, | ||
113 | ATH_DBG_ANI = 0x00000400, | ||
114 | ATH_DBG_POWER_MGMT = 0x00000800, | ||
115 | ATH_DBG_XMIT = 0x00001000, | ||
116 | ATH_DBG_BEACON = 0x00002000, | ||
117 | ATH_DBG_RATE = 0x00004000, | ||
118 | ATH_DBG_CONFIG = 0x00008000, | ||
119 | ATH_DBG_KEYCACHE = 0x00010000, | ||
120 | ATH_DBG_AGGR = 0x00020000, | ||
121 | ATH_DBG_FATAL = 0x00040000, | ||
122 | ATH_DBG_ANY = 0xffffffff | ||
123 | }; | ||
124 | |||
125 | #define DBG_DEFAULT (ATH_DBG_FATAL) | ||
126 | |||
127 | #define DPRINTF(sc, _m, _fmt, ...) do { \ | ||
128 | if (sc->sc_debug & (_m)) \ | ||
129 | printk(_fmt , ##__VA_ARGS__); \ | ||
130 | } while (0) | ||
131 | |||
132 | /***************************/ | ||
133 | /* Load-time Configuration */ | ||
134 | /***************************/ | ||
135 | |||
136 | /* Per-instance load-time (note: NOT run-time) configurations | ||
137 | * for Atheros Device */ | ||
138 | struct ath_config { | ||
139 | u32 ath_aggr_prot; | ||
140 | u16 txpowlimit; | ||
141 | u16 txpowlimit_override; | ||
142 | u8 cabqReadytime; /* Cabq Readytime % */ | ||
143 | u8 swBeaconProcess; /* Process received beacons | ||
144 | in SW (vs HW) */ | ||
145 | }; | ||
146 | |||
147 | /***********************/ | ||
148 | /* Chainmask Selection */ | ||
149 | /***********************/ | ||
150 | |||
151 | #define ATH_CHAINMASK_SEL_TIMEOUT 6000 | ||
152 | /* Default - Number of last RSSI values that is used for | ||
153 | * chainmask selection */ | ||
154 | #define ATH_CHAINMASK_SEL_RSSI_CNT 10 | ||
155 | /* Means use 3x3 chainmask instead of configured chainmask */ | ||
156 | #define ATH_CHAINMASK_SEL_3X3 7 | ||
157 | /* Default - Rssi threshold below which we have to switch to 3x3 */ | ||
158 | #define ATH_CHAINMASK_SEL_UP_RSSI_THRES 20 | ||
159 | /* Default - Rssi threshold above which we have to switch to | ||
160 | * user configured values */ | ||
161 | #define ATH_CHAINMASK_SEL_DOWN_RSSI_THRES 35 | ||
162 | /* Struct to store the chainmask select related info */ | ||
163 | struct ath_chainmask_sel { | ||
164 | struct timer_list timer; | ||
165 | int cur_tx_mask; /* user configured or 3x3 */ | ||
166 | int cur_rx_mask; /* user configured or 3x3 */ | ||
167 | int tx_avgrssi; | ||
168 | u8 switch_allowed:1, /* timer will set this */ | ||
169 | cm_sel_enabled:1; | ||
170 | }; | ||
171 | |||
172 | int ath_chainmask_sel_logic(struct ath_softc *sc, struct ath_node *an); | ||
173 | void ath_update_chainmask(struct ath_softc *sc, int is_ht); | ||
174 | |||
175 | /*************************/ | ||
176 | /* Descriptor Management */ | ||
177 | /*************************/ | ||
178 | |||
179 | /* Number of descriptors per buffer. The only case where we see skbuff | ||
180 | chains is due to FF aggregation in the driver. */ | ||
181 | #define ATH_TXDESC 1 | ||
182 | /* if there's more fragment for this MSDU */ | ||
183 | #define ATH_BF_MORE_MPDU 1 | ||
184 | #define ATH_TXBUF_RESET(_bf) do { \ | ||
185 | (_bf)->bf_status = 0; \ | ||
186 | (_bf)->bf_lastbf = NULL; \ | ||
187 | (_bf)->bf_lastfrm = NULL; \ | ||
188 | (_bf)->bf_next = NULL; \ | ||
189 | memzero(&((_bf)->bf_state), \ | ||
190 | sizeof(struct ath_buf_state)); \ | ||
191 | } while (0) | ||
192 | |||
193 | struct ath_buf_state { | ||
194 | int bfs_nframes; /* # frames in aggregate */ | ||
195 | u16 bfs_al; /* length of aggregate */ | ||
196 | u16 bfs_frmlen; /* length of frame */ | ||
197 | int bfs_seqno; /* sequence number */ | ||
198 | int bfs_tidno; /* tid of this frame */ | ||
199 | int bfs_retries; /* current retries */ | ||
200 | struct ath_rc_series bfs_rcs[4]; /* rate series */ | ||
201 | u8 bfs_isdata:1; /* is a data frame/aggregate */ | ||
202 | u8 bfs_isaggr:1; /* is an aggregate */ | ||
203 | u8 bfs_isampdu:1; /* is an a-mpdu, aggregate or not */ | ||
204 | u8 bfs_ht:1; /* is an HT frame */ | ||
205 | u8 bfs_isretried:1; /* is retried */ | ||
206 | u8 bfs_isxretried:1; /* is excessive retried */ | ||
207 | u8 bfs_shpreamble:1; /* is short preamble */ | ||
208 | u8 bfs_isbar:1; /* is a BAR */ | ||
209 | u8 bfs_ispspoll:1; /* is a PS-Poll */ | ||
210 | u8 bfs_aggrburst:1; /* is a aggr burst */ | ||
211 | u8 bfs_calcairtime:1; /* requests airtime be calculated | ||
212 | when set for tx frame */ | ||
213 | int bfs_rifsburst_elem; /* RIFS burst/bar */ | ||
214 | int bfs_nrifsubframes; /* # of elements in burst */ | ||
215 | /* key type use to encrypt this frame */ | ||
216 | enum ath9k_key_type bfs_keytype; | ||
217 | }; | ||
218 | |||
219 | #define bf_nframes bf_state.bfs_nframes | ||
220 | #define bf_al bf_state.bfs_al | ||
221 | #define bf_frmlen bf_state.bfs_frmlen | ||
222 | #define bf_retries bf_state.bfs_retries | ||
223 | #define bf_seqno bf_state.bfs_seqno | ||
224 | #define bf_tidno bf_state.bfs_tidno | ||
225 | #define bf_rcs bf_state.bfs_rcs | ||
226 | #define bf_isdata bf_state.bfs_isdata | ||
227 | #define bf_isaggr bf_state.bfs_isaggr | ||
228 | #define bf_isampdu bf_state.bfs_isampdu | ||
229 | #define bf_ht bf_state.bfs_ht | ||
230 | #define bf_isretried bf_state.bfs_isretried | ||
231 | #define bf_isxretried bf_state.bfs_isxretried | ||
232 | #define bf_shpreamble bf_state.bfs_shpreamble | ||
233 | #define bf_rifsburst_elem bf_state.bfs_rifsburst_elem | ||
234 | #define bf_nrifsubframes bf_state.bfs_nrifsubframes | ||
235 | #define bf_keytype bf_state.bfs_keytype | ||
236 | #define bf_isbar bf_state.bfs_isbar | ||
237 | #define bf_ispspoll bf_state.bfs_ispspoll | ||
238 | #define bf_aggrburst bf_state.bfs_aggrburst | ||
239 | #define bf_calcairtime bf_state.bfs_calcairtime | ||
240 | |||
241 | /* | ||
242 | * Abstraction of a contiguous buffer to transmit/receive. There is only | ||
243 | * a single hw descriptor encapsulated here. | ||
244 | */ | ||
245 | |||
246 | struct ath_buf { | ||
247 | struct list_head list; | ||
248 | struct list_head *last; | ||
249 | struct ath_buf *bf_lastbf; /* last buf of this unit (a frame or | ||
250 | an aggregate) */ | ||
251 | struct ath_buf *bf_lastfrm; /* last buf of this frame */ | ||
252 | struct ath_buf *bf_next; /* next subframe in the aggregate */ | ||
253 | struct ath_buf *bf_rifslast; /* last buf for RIFS burst */ | ||
254 | void *bf_mpdu; /* enclosing frame structure */ | ||
255 | void *bf_node; /* pointer to the node */ | ||
256 | struct ath_desc *bf_desc; /* virtual addr of desc */ | ||
257 | dma_addr_t bf_daddr; /* physical addr of desc */ | ||
258 | dma_addr_t bf_buf_addr; /* physical addr of data buffer */ | ||
259 | u32 bf_status; | ||
260 | u16 bf_flags; /* tx descriptor flags */ | ||
261 | struct ath_buf_state bf_state; /* buffer state */ | ||
262 | dma_addr_t bf_dmacontext; | ||
263 | }; | ||
264 | |||
265 | /* | ||
266 | * reset the rx buffer. | ||
267 | * any new fields added to the athbuf and require | ||
268 | * reset need to be added to this macro. | ||
269 | * currently bf_status is the only one requires that | ||
270 | * requires reset. | ||
271 | */ | ||
272 | #define ATH_RXBUF_RESET(_bf) ((_bf)->bf_status = 0) | ||
273 | |||
274 | /* hw processing complete, desc processed by hal */ | ||
275 | #define ATH_BUFSTATUS_DONE 0x00000001 | ||
276 | /* hw processing complete, desc hold for hw */ | ||
277 | #define ATH_BUFSTATUS_STALE 0x00000002 | ||
278 | /* Rx-only: OS is done with this packet and it's ok to queued it to hw */ | ||
279 | #define ATH_BUFSTATUS_FREE 0x00000004 | ||
280 | |||
281 | /* DMA state for tx/rx descriptors */ | ||
282 | |||
283 | struct ath_descdma { | ||
284 | const char *dd_name; | ||
285 | struct ath_desc *dd_desc; /* descriptors */ | ||
286 | dma_addr_t dd_desc_paddr; /* physical addr of dd_desc */ | ||
287 | u32 dd_desc_len; /* size of dd_desc */ | ||
288 | struct ath_buf *dd_bufptr; /* associated buffers */ | ||
289 | dma_addr_t dd_dmacontext; | ||
290 | }; | ||
291 | |||
292 | /* Abstraction of a received RX MPDU/MMPDU, or a RX fragment */ | ||
293 | |||
294 | struct ath_rx_context { | ||
295 | struct ath_buf *ctx_rxbuf; /* associated ath_buf for rx */ | ||
296 | }; | ||
297 | #define ATH_RX_CONTEXT(skb) ((struct ath_rx_context *)skb->cb) | ||
298 | |||
299 | int ath_descdma_setup(struct ath_softc *sc, | ||
300 | struct ath_descdma *dd, | ||
301 | struct list_head *head, | ||
302 | const char *name, | ||
303 | int nbuf, | ||
304 | int ndesc); | ||
305 | int ath_desc_alloc(struct ath_softc *sc); | ||
306 | void ath_desc_free(struct ath_softc *sc); | ||
307 | void ath_descdma_cleanup(struct ath_softc *sc, | ||
308 | struct ath_descdma *dd, | ||
309 | struct list_head *head); | ||
310 | |||
311 | /******/ | ||
312 | /* RX */ | ||
313 | /******/ | ||
314 | |||
315 | #define ATH_MAX_ANTENNA 3 | ||
316 | #define ATH_RXBUF 512 | ||
317 | #define ATH_RX_TIMEOUT 40 /* 40 milliseconds */ | ||
318 | #define WME_NUM_TID 16 | ||
319 | #define IEEE80211_BAR_CTL_TID_M 0xF000 /* tid mask */ | ||
320 | #define IEEE80211_BAR_CTL_TID_S 2 /* tid shift */ | ||
321 | |||
322 | enum ATH_RX_TYPE { | ||
323 | ATH_RX_NON_CONSUMED = 0, | ||
324 | ATH_RX_CONSUMED | ||
325 | }; | ||
326 | |||
327 | /* per frame rx status block */ | ||
328 | struct ath_recv_status { | ||
329 | u64 tsf; /* mac tsf */ | ||
330 | int8_t rssi; /* RSSI (noise floor ajusted) */ | ||
331 | int8_t rssictl[ATH_MAX_ANTENNA]; /* RSSI (noise floor ajusted) */ | ||
332 | int8_t rssiextn[ATH_MAX_ANTENNA]; /* RSSI (noise floor ajusted) */ | ||
333 | int8_t abs_rssi; /* absolute RSSI */ | ||
334 | u8 rateieee; /* data rate received (IEEE rate code) */ | ||
335 | u8 ratecode; /* phy rate code */ | ||
336 | int rateKbps; /* data rate received (Kbps) */ | ||
337 | int antenna; /* rx antenna */ | ||
338 | int flags; /* status of associated skb */ | ||
339 | #define ATH_RX_FCS_ERROR 0x01 | ||
340 | #define ATH_RX_MIC_ERROR 0x02 | ||
341 | #define ATH_RX_DECRYPT_ERROR 0x04 | ||
342 | #define ATH_RX_RSSI_VALID 0x08 | ||
343 | /* if any of ctl,extn chainrssis are valid */ | ||
344 | #define ATH_RX_CHAIN_RSSI_VALID 0x10 | ||
345 | /* if extn chain rssis are valid */ | ||
346 | #define ATH_RX_RSSI_EXTN_VALID 0x20 | ||
347 | /* set if 40Mhz, clear if 20Mhz */ | ||
348 | #define ATH_RX_40MHZ 0x40 | ||
349 | /* set if short GI, clear if full GI */ | ||
350 | #define ATH_RX_SHORT_GI 0x80 | ||
351 | }; | ||
352 | |||
353 | struct ath_rxbuf { | ||
354 | struct sk_buff *rx_wbuf; /* buffer */ | ||
355 | unsigned long rx_time; /* system time when received */ | ||
356 | struct ath_recv_status rx_status; /* cached rx status */ | ||
357 | }; | ||
358 | |||
359 | /* Per-TID aggregate receiver state for a node */ | ||
360 | struct ath_arx_tid { | ||
361 | struct ath_node *an; /* parent ath node */ | ||
362 | struct ath_rxbuf *rxbuf; /* re-ordering buffer */ | ||
363 | struct timer_list timer; | ||
364 | spinlock_t tidlock; /* lock to protect this TID structure */ | ||
365 | int baw_head; /* seq_next at head */ | ||
366 | int baw_tail; /* tail of block-ack window */ | ||
367 | int seq_reset; /* need to reset start sequence */ | ||
368 | int addba_exchangecomplete; | ||
369 | u16 seq_next; /* next expected sequence */ | ||
370 | u16 baw_size; /* block-ack window size */ | ||
371 | }; | ||
372 | |||
373 | /* Per-node receiver aggregate state */ | ||
374 | struct ath_arx { | ||
375 | struct ath_arx_tid tid[WME_NUM_TID]; | ||
376 | }; | ||
377 | |||
378 | int ath_startrecv(struct ath_softc *sc); | ||
379 | bool ath_stoprecv(struct ath_softc *sc); | ||
380 | void ath_flushrecv(struct ath_softc *sc); | ||
381 | u32 ath_calcrxfilter(struct ath_softc *sc); | ||
382 | void ath_rx_node_init(struct ath_softc *sc, struct ath_node *an); | ||
383 | void ath_rx_node_free(struct ath_softc *sc, struct ath_node *an); | ||
384 | void ath_rx_node_cleanup(struct ath_softc *sc, struct ath_node *an); | ||
385 | void ath_handle_rx_intr(struct ath_softc *sc); | ||
386 | int ath_rx_init(struct ath_softc *sc, int nbufs); | ||
387 | void ath_rx_cleanup(struct ath_softc *sc); | ||
388 | int ath_rx_tasklet(struct ath_softc *sc, int flush); | ||
389 | int ath_rx_input(struct ath_softc *sc, | ||
390 | struct ath_node *node, | ||
391 | int is_ampdu, | ||
392 | struct sk_buff *skb, | ||
393 | struct ath_recv_status *rx_status, | ||
394 | enum ATH_RX_TYPE *status); | ||
395 | int ath__rx_indicate(struct ath_softc *sc, | ||
396 | struct sk_buff *skb, | ||
397 | struct ath_recv_status *status, | ||
398 | u16 keyix); | ||
399 | int ath_rx_subframe(struct ath_node *an, struct sk_buff *skb, | ||
400 | struct ath_recv_status *status); | ||
401 | |||
402 | /******/ | ||
403 | /* TX */ | ||
404 | /******/ | ||
405 | |||
406 | #define ATH_FRAG_PER_MSDU 1 | ||
407 | #define ATH_TXBUF (512/ATH_FRAG_PER_MSDU) | ||
408 | /* max number of transmit attempts (tries) */ | ||
409 | #define ATH_TXMAXTRY 13 | ||
410 | /* max number of 11n transmit attempts (tries) */ | ||
411 | #define ATH_11N_TXMAXTRY 10 | ||
412 | /* max number of tries for management and control frames */ | ||
413 | #define ATH_MGT_TXMAXTRY 4 | ||
414 | #define WME_BA_BMP_SIZE 64 | ||
415 | #define WME_MAX_BA WME_BA_BMP_SIZE | ||
416 | #define ATH_TID_MAX_BUFS (2 * WME_MAX_BA) | ||
417 | #define TID_TO_WME_AC(_tid) \ | ||
418 | ((((_tid) == 0) || ((_tid) == 3)) ? WME_AC_BE : \ | ||
419 | (((_tid) == 1) || ((_tid) == 2)) ? WME_AC_BK : \ | ||
420 | (((_tid) == 4) || ((_tid) == 5)) ? WME_AC_VI : \ | ||
421 | WME_AC_VO) | ||
422 | |||
423 | |||
424 | /* Wireless Multimedia Extension Defines */ | ||
425 | #define WME_AC_BE 0 /* best effort */ | ||
426 | #define WME_AC_BK 1 /* background */ | ||
427 | #define WME_AC_VI 2 /* video */ | ||
428 | #define WME_AC_VO 3 /* voice */ | ||
429 | #define WME_NUM_AC 4 | ||
430 | |||
431 | enum ATH_SM_PWRSAV{ | ||
432 | ATH_SM_ENABLE, | ||
433 | ATH_SM_PWRSAV_STATIC, | ||
434 | ATH_SM_PWRSAV_DYNAMIC, | ||
435 | }; | ||
436 | |||
437 | /* | ||
438 | * Data transmit queue state. One of these exists for each | ||
439 | * hardware transmit queue. Packets sent to us from above | ||
440 | * are assigned to queues based on their priority. Not all | ||
441 | * devices support a complete set of hardware transmit queues. | ||
442 | * For those devices the array sc_ac2q will map multiple | ||
443 | * priorities to fewer hardware queues (typically all to one | ||
444 | * hardware queue). | ||
445 | */ | ||
446 | struct ath_txq { | ||
447 | u32 axq_qnum; /* hardware q number */ | ||
448 | u32 *axq_link; /* link ptr in last TX desc */ | ||
449 | struct list_head axq_q; /* transmit queue */ | ||
450 | spinlock_t axq_lock; /* lock on q and link */ | ||
451 | unsigned long axq_lockflags; /* intr state when must cli */ | ||
452 | u32 axq_depth; /* queue depth */ | ||
453 | u8 axq_aggr_depth; /* aggregates queued */ | ||
454 | u32 axq_totalqueued;/* total ever queued */ | ||
455 | u32 axq_intrcnt; /* count to determine | ||
456 | if descriptor should generate | ||
457 | int on this txq. */ | ||
458 | bool stopped; /* Is mac80211 queue | ||
459 | stopped ? */ | ||
460 | /* State for patching up CTS when bursting */ | ||
461 | struct ath_buf *axq_linkbuf; /* virtual addr of last buffer*/ | ||
462 | struct ath_desc *axq_lastdsWithCTS; /* first desc of the | ||
463 | last descriptor that contains CTS */ | ||
464 | struct ath_desc *axq_gatingds; /* final desc of the gating desc | ||
465 | * that determines whether lastdsWithCTS has | ||
466 | * been DMA'ed or not */ | ||
467 | struct list_head axq_acq; | ||
468 | }; | ||
469 | |||
470 | /* per TID aggregate tx state for a destination */ | ||
471 | struct ath_atx_tid { | ||
472 | struct list_head list; /* round-robin tid entry */ | ||
473 | struct list_head buf_q; /* pending buffers */ | ||
474 | struct ath_node *an; /* parent node structure */ | ||
475 | struct ath_atx_ac *ac; /* parent access category */ | ||
476 | struct ath_buf *tx_buf[ATH_TID_MAX_BUFS];/* active tx frames */ | ||
477 | u16 seq_start; /* starting seq of BA window */ | ||
478 | u16 seq_next; /* next seq to be used */ | ||
479 | u16 baw_size; /* BA window size */ | ||
480 | int tidno; /* TID number */ | ||
481 | int baw_head; /* first un-acked tx buffer */ | ||
482 | int baw_tail; /* next unused tx buffer slot */ | ||
483 | int sched; /* TID is scheduled */ | ||
484 | int paused; /* TID is paused */ | ||
485 | int cleanup_inprogress; /* aggr of this TID is | ||
486 | being teared down */ | ||
487 | u32 addba_exchangecomplete:1; /* ADDBA state */ | ||
488 | int32_t addba_exchangeinprogress; | ||
489 | int addba_exchangeattempts; | ||
490 | }; | ||
491 | |||
492 | /* per access-category aggregate tx state for a destination */ | ||
493 | struct ath_atx_ac { | ||
494 | int sched; /* dest-ac is scheduled */ | ||
495 | int qnum; /* H/W queue number associated | ||
496 | with this AC */ | ||
497 | struct list_head list; /* round-robin txq entry */ | ||
498 | struct list_head tid_q; /* queue of TIDs with buffers */ | ||
499 | }; | ||
500 | |||
501 | /* per dest tx state */ | ||
502 | struct ath_atx { | ||
503 | struct ath_atx_tid tid[WME_NUM_TID]; | ||
504 | struct ath_atx_ac ac[WME_NUM_AC]; | ||
505 | }; | ||
506 | |||
507 | /* per-frame tx control block */ | ||
508 | struct ath_tx_control { | ||
509 | struct ath_node *an; /* destination to sent to */ | ||
510 | int if_id; /* only valid for cab traffic */ | ||
511 | int qnum; /* h/w queue number */ | ||
512 | u32 ht:1; /* if it can be transmitted using HT */ | ||
513 | u32 ps:1; /* if one or more stations are in PS mode */ | ||
514 | u32 use_minrate:1; /* if this frame should transmitted using | ||
515 | minimum rate */ | ||
516 | enum ath9k_pkt_type atype; /* Atheros packet type */ | ||
517 | enum ath9k_key_type keytype; /* key type */ | ||
518 | u32 flags; /* HAL flags */ | ||
519 | u16 seqno; /* sequence number */ | ||
520 | u16 tidno; /* tid number */ | ||
521 | u16 txpower; /* transmit power */ | ||
522 | u16 frmlen; /* frame length */ | ||
523 | u32 keyix; /* key index */ | ||
524 | int min_rate; /* minimum rate */ | ||
525 | int mcast_rate; /* multicast rate */ | ||
526 | u16 nextfraglen; /* next fragment length */ | ||
527 | /* below is set only by ath_dev */ | ||
528 | struct ath_softc *dev; /* device handle */ | ||
529 | dma_addr_t dmacontext; | ||
530 | }; | ||
531 | |||
532 | /* per frame tx status block */ | ||
533 | struct ath_xmit_status { | ||
534 | int retries; /* number of retries to successufully | ||
535 | transmit this frame */ | ||
536 | int flags; /* status of transmit */ | ||
537 | #define ATH_TX_ERROR 0x01 | ||
538 | #define ATH_TX_XRETRY 0x02 | ||
539 | #define ATH_TX_BAR 0x04 | ||
540 | }; | ||
541 | |||
542 | struct ath_tx_stat { | ||
543 | int rssi; /* RSSI (noise floor ajusted) */ | ||
544 | int rssictl[ATH_MAX_ANTENNA]; /* RSSI (noise floor ajusted) */ | ||
545 | int rssiextn[ATH_MAX_ANTENNA]; /* RSSI (noise floor ajusted) */ | ||
546 | int rateieee; /* data rate xmitted (IEEE rate code) */ | ||
547 | int rateKbps; /* data rate xmitted (Kbps) */ | ||
548 | int ratecode; /* phy rate code */ | ||
549 | int flags; /* validity flags */ | ||
550 | /* if any of ctl,extn chain rssis are valid */ | ||
551 | #define ATH_TX_CHAIN_RSSI_VALID 0x01 | ||
552 | /* if extn chain rssis are valid */ | ||
553 | #define ATH_TX_RSSI_EXTN_VALID 0x02 | ||
554 | u32 airtime; /* time on air per final tx rate */ | ||
555 | }; | ||
556 | |||
557 | struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype); | ||
558 | void ath_tx_cleanupq(struct ath_softc *sc, struct ath_txq *txq); | ||
559 | int ath_tx_setup(struct ath_softc *sc, int haltype); | ||
560 | void ath_draintxq(struct ath_softc *sc, bool retry_tx); | ||
561 | void ath_tx_draintxq(struct ath_softc *sc, | ||
562 | struct ath_txq *txq, bool retry_tx); | ||
563 | void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an); | ||
564 | void ath_tx_node_cleanup(struct ath_softc *sc, | ||
565 | struct ath_node *an, bool bh_flag); | ||
566 | void ath_tx_node_free(struct ath_softc *sc, struct ath_node *an); | ||
567 | void ath_txq_schedule(struct ath_softc *sc, struct ath_txq *txq); | ||
568 | int ath_tx_init(struct ath_softc *sc, int nbufs); | ||
569 | int ath_tx_cleanup(struct ath_softc *sc); | ||
570 | int ath_tx_get_qnum(struct ath_softc *sc, int qtype, int haltype); | ||
571 | int ath_txq_update(struct ath_softc *sc, int qnum, struct ath9k_txq_info *q); | ||
572 | int ath_tx_start(struct ath_softc *sc, struct sk_buff *skb); | ||
573 | void ath_tx_tasklet(struct ath_softc *sc); | ||
574 | u32 ath_txq_depth(struct ath_softc *sc, int qnum); | ||
575 | u32 ath_txq_aggr_depth(struct ath_softc *sc, int qnum); | ||
576 | void ath_notify_txq_status(struct ath_softc *sc, u16 queue_depth); | ||
577 | void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb, | ||
578 | struct ath_xmit_status *tx_status, struct ath_node *an); | ||
579 | |||
580 | /**********************/ | ||
581 | /* Node / Aggregation */ | ||
582 | /**********************/ | ||
583 | |||
584 | /* indicates the node is clened up */ | ||
585 | #define ATH_NODE_CLEAN 0x1 | ||
586 | /* indicates the node is 80211 power save */ | ||
587 | #define ATH_NODE_PWRSAVE 0x2 | ||
588 | |||
589 | #define ADDBA_TIMEOUT 200 /* 200 milliseconds */ | ||
590 | #define ADDBA_EXCHANGE_ATTEMPTS 10 | ||
591 | #define ATH_AGGR_DELIM_SZ 4 /* delimiter size */ | ||
592 | #define ATH_AGGR_MINPLEN 256 /* in bytes, minimum packet length */ | ||
593 | /* number of delimiters for encryption padding */ | ||
594 | #define ATH_AGGR_ENCRYPTDELIM 10 | ||
595 | /* minimum h/w qdepth to be sustained to maximize aggregation */ | ||
596 | #define ATH_AGGR_MIN_QDEPTH 2 | ||
597 | #define ATH_AMPDU_SUBFRAME_DEFAULT 32 | ||
598 | #define IEEE80211_SEQ_SEQ_SHIFT 4 | ||
599 | #define IEEE80211_SEQ_MAX 4096 | ||
600 | #define IEEE80211_MIN_AMPDU_BUF 0x8 | ||
601 | |||
602 | /* return whether a bit at index _n in bitmap _bm is set | ||
603 | * _sz is the size of the bitmap */ | ||
604 | #define ATH_BA_ISSET(_bm, _n) (((_n) < (WME_BA_BMP_SIZE)) && \ | ||
605 | ((_bm)[(_n) >> 5] & (1 << ((_n) & 31)))) | ||
606 | |||
607 | /* return block-ack bitmap index given sequence and starting sequence */ | ||
608 | #define ATH_BA_INDEX(_st, _seq) (((_seq) - (_st)) & (IEEE80211_SEQ_MAX - 1)) | ||
609 | |||
610 | /* returns delimiter padding required given the packet length */ | ||
611 | #define ATH_AGGR_GET_NDELIM(_len) \ | ||
612 | (((((_len) + ATH_AGGR_DELIM_SZ) < ATH_AGGR_MINPLEN) ? \ | ||
613 | (ATH_AGGR_MINPLEN - (_len) - ATH_AGGR_DELIM_SZ) : 0) >> 2) | ||
614 | |||
615 | #define BAW_WITHIN(_start, _bawsz, _seqno) \ | ||
616 | ((((_seqno) - (_start)) & 4095) < (_bawsz)) | ||
617 | |||
618 | #define ATH_DS_BA_SEQ(_ds) ((_ds)->ds_us.tx.ts_seqnum) | ||
619 | #define ATH_DS_BA_BITMAP(_ds) (&(_ds)->ds_us.tx.ba_low) | ||
620 | #define ATH_DS_TX_BA(_ds) ((_ds)->ds_us.tx.ts_flags & ATH9K_TX_BA) | ||
621 | #define ATH_AN_2_TID(_an, _tidno) (&(_an)->an_aggr.tx.tid[(_tidno)]) | ||
622 | |||
623 | enum ATH_AGGR_STATUS { | ||
624 | ATH_AGGR_DONE, | ||
625 | ATH_AGGR_BAW_CLOSED, | ||
626 | ATH_AGGR_LIMITED, | ||
627 | ATH_AGGR_SHORTPKT, | ||
628 | ATH_AGGR_8K_LIMITED, | ||
629 | }; | ||
630 | |||
631 | enum ATH_AGGR_CHECK { | ||
632 | AGGR_NOT_REQUIRED, | ||
633 | AGGR_REQUIRED, | ||
634 | AGGR_CLEANUP_PROGRESS, | ||
635 | AGGR_EXCHANGE_PROGRESS, | ||
636 | AGGR_EXCHANGE_DONE | ||
637 | }; | ||
638 | |||
639 | struct aggr_rifs_param { | ||
640 | int param_max_frames; | ||
641 | int param_max_len; | ||
642 | int param_rl; | ||
643 | int param_al; | ||
644 | struct ath_rc_series *param_rcs; | ||
645 | }; | ||
646 | |||
647 | /* Per-node aggregation state */ | ||
648 | struct ath_node_aggr { | ||
649 | struct ath_atx tx; /* node transmit state */ | ||
650 | struct ath_arx rx; /* node receive state */ | ||
651 | }; | ||
652 | |||
653 | /* driver-specific node state */ | ||
654 | struct ath_node { | ||
655 | struct list_head list; | ||
656 | struct ath_softc *an_sc; /* back pointer */ | ||
657 | atomic_t an_refcnt; | ||
658 | struct ath_chainmask_sel an_chainmask_sel; | ||
659 | struct ath_node_aggr an_aggr; /* A-MPDU aggregation state */ | ||
660 | u8 an_smmode; /* SM Power save mode */ | ||
661 | u8 an_flags; | ||
662 | u8 an_addr[ETH_ALEN]; | ||
663 | }; | ||
664 | |||
665 | void ath_tx_resume_tid(struct ath_softc *sc, | ||
666 | struct ath_atx_tid *tid); | ||
667 | enum ATH_AGGR_CHECK ath_tx_aggr_check(struct ath_softc *sc, | ||
668 | struct ath_node *an, u8 tidno); | ||
669 | void ath_tx_aggr_teardown(struct ath_softc *sc, | ||
670 | struct ath_node *an, u8 tidno); | ||
671 | void ath_rx_aggr_teardown(struct ath_softc *sc, | ||
672 | struct ath_node *an, u8 tidno); | ||
673 | int ath_rx_aggr_start(struct ath_softc *sc, | ||
674 | const u8 *addr, | ||
675 | u16 tid, | ||
676 | u16 *ssn); | ||
677 | int ath_rx_aggr_stop(struct ath_softc *sc, | ||
678 | const u8 *addr, | ||
679 | u16 tid); | ||
680 | int ath_tx_aggr_start(struct ath_softc *sc, | ||
681 | const u8 *addr, | ||
682 | u16 tid, | ||
683 | u16 *ssn); | ||
684 | int ath_tx_aggr_stop(struct ath_softc *sc, | ||
685 | const u8 *addr, | ||
686 | u16 tid); | ||
687 | void ath_newassoc(struct ath_softc *sc, | ||
688 | struct ath_node *node, int isnew, int isuapsd); | ||
689 | struct ath_node *ath_node_attach(struct ath_softc *sc, | ||
690 | u8 addr[ETH_ALEN], int if_id); | ||
691 | void ath_node_detach(struct ath_softc *sc, struct ath_node *an, bool bh_flag); | ||
692 | struct ath_node *ath_node_get(struct ath_softc *sc, u8 addr[ETH_ALEN]); | ||
693 | void ath_node_put(struct ath_softc *sc, struct ath_node *an, bool bh_flag); | ||
694 | struct ath_node *ath_node_find(struct ath_softc *sc, u8 *addr); | ||
695 | |||
696 | /*******************/ | ||
697 | /* Beacon Handling */ | ||
698 | /*******************/ | ||
699 | |||
700 | /* | ||
701 | * Regardless of the number of beacons we stagger, (i.e. regardless of the | ||
702 | * number of BSSIDs) if a given beacon does not go out even after waiting this | ||
703 | * number of beacon intervals, the game's up. | ||
704 | */ | ||
705 | #define BSTUCK_THRESH (9 * ATH_BCBUF) | ||
706 | #define ATH_BCBUF 4 /* number of beacon buffers */ | ||
707 | #define ATH_DEFAULT_BINTVAL 100 /* default beacon interval in TU */ | ||
708 | #define ATH_DEFAULT_BMISS_LIMIT 10 | ||
709 | #define ATH_BEACON_AIFS_DEFAULT 0 /* Default aifs for ap beacon q */ | ||
710 | #define ATH_BEACON_CWMIN_DEFAULT 0 /* Default cwmin for ap beacon q */ | ||
711 | #define ATH_BEACON_CWMAX_DEFAULT 0 /* Default cwmax for ap beacon q */ | ||
712 | #define IEEE80211_MS_TO_TU(x) (((x) * 1000) / 1024) | ||
713 | |||
714 | /* beacon configuration */ | ||
715 | struct ath_beacon_config { | ||
716 | u16 beacon_interval; | ||
717 | u16 listen_interval; | ||
718 | u16 dtim_period; | ||
719 | u16 bmiss_timeout; | ||
720 | u8 dtim_count; | ||
721 | u8 tim_offset; | ||
722 | union { | ||
723 | u64 last_tsf; | ||
724 | u8 last_tstamp[8]; | ||
725 | } u; /* last received beacon/probe response timestamp of this BSS. */ | ||
726 | }; | ||
727 | |||
728 | /* offsets in a beacon frame for | ||
729 | * quick acess of beacon content by low-level driver */ | ||
730 | struct ath_beacon_offset { | ||
731 | u8 *bo_tim; /* start of atim/dtim */ | ||
732 | }; | ||
733 | |||
734 | void ath9k_beacon_tasklet(unsigned long data); | ||
735 | void ath_beacon_config(struct ath_softc *sc, int if_id); | ||
736 | int ath_beaconq_setup(struct ath_hal *ah); | ||
737 | int ath_beacon_alloc(struct ath_softc *sc, int if_id); | ||
738 | void ath_bstuck_process(struct ath_softc *sc); | ||
739 | void ath_beacon_tasklet(struct ath_softc *sc, int *needmark); | ||
740 | void ath_beacon_free(struct ath_softc *sc); | ||
741 | void ath_beacon_return(struct ath_softc *sc, struct ath_vap *avp); | ||
742 | void ath_beacon_sync(struct ath_softc *sc, int if_id); | ||
743 | void ath_update_beacon_info(struct ath_softc *sc, int avgbrssi); | ||
744 | void ath_get_beaconconfig(struct ath_softc *sc, | ||
745 | int if_id, | ||
746 | struct ath_beacon_config *conf); | ||
747 | int ath_update_beacon(struct ath_softc *sc, | ||
748 | int if_id, | ||
749 | struct ath_beacon_offset *bo, | ||
750 | struct sk_buff *skb, | ||
751 | int mcast); | ||
752 | /********/ | ||
753 | /* VAPs */ | ||
754 | /********/ | ||
755 | |||
756 | #define ATH_IF_HW_OFF 0x0001 /* hardware state needs to turn off */ | ||
757 | #define ATH_IF_HW_ON 0x0002 /* hardware state needs to turn on */ | ||
758 | /* STA only: the associated AP is HT capable */ | ||
759 | #define ATH_IF_HT 0x0004 | ||
760 | /* AP/IBSS only: current BSS has privacy on */ | ||
761 | #define ATH_IF_PRIVACY 0x0008 | ||
762 | #define ATH_IF_BEACON_ENABLE 0x0010 /* AP/IBSS only: enable beacon */ | ||
763 | #define ATH_IF_BEACON_SYNC 0x0020 /* IBSS only: need to sync beacon */ | ||
764 | |||
765 | /* | ||
766 | * Define the scheme that we select MAC address for multiple | ||
767 | * BSS on the same radio. The very first VAP will just use the MAC | ||
768 | * address from the EEPROM. For the next 3 VAPs, we set the | ||
769 | * U/L bit (bit 1) in MAC address, and use the next two bits as the | ||
770 | * index of the VAP. | ||
771 | */ | ||
772 | |||
773 | #define ATH_SET_VAP_BSSID_MASK(bssid_mask) \ | ||
774 | ((bssid_mask)[0] &= ~(((ATH_BCBUF-1)<<2)|0x02)) | ||
775 | |||
776 | /* VAP configuration (from protocol layer) */ | ||
777 | struct ath_vap_config { | ||
778 | u32 av_fixed_rateset; | ||
779 | u32 av_fixed_retryset; | ||
780 | }; | ||
781 | |||
782 | /* driver-specific vap state */ | ||
783 | struct ath_vap { | ||
784 | struct ieee80211_vif *av_if_data; /* interface(vap) | ||
785 | instance from 802.11 protocal layer */ | ||
786 | enum ath9k_opmode av_opmode; /* VAP operational mode */ | ||
787 | struct ath_buf *av_bcbuf; /* beacon buffer */ | ||
788 | struct ath_beacon_offset av_boff; /* dynamic update state */ | ||
789 | struct ath_tx_control av_btxctl; /* tx control information | ||
790 | for beacon */ | ||
791 | int av_bslot; /* beacon slot index */ | ||
792 | struct ath_txq av_mcastq; /* multicast | ||
793 | transmit queue */ | ||
794 | struct ath_vap_config av_config; /* vap configuration | ||
795 | parameters from 802.11 protocol layer*/ | ||
796 | struct ath_rate_node *rc_node; | ||
797 | }; | ||
798 | |||
799 | int ath_vap_attach(struct ath_softc *sc, | ||
800 | int if_id, | ||
801 | struct ieee80211_vif *if_data, | ||
802 | enum ath9k_opmode opmode); | ||
803 | int ath_vap_detach(struct ath_softc *sc, int if_id); | ||
804 | int ath_vap_config(struct ath_softc *sc, | ||
805 | int if_id, struct ath_vap_config *if_config); | ||
806 | int ath_vap_listen(struct ath_softc *sc, int if_id); | ||
807 | |||
808 | /*********************/ | ||
809 | /* Antenna diversity */ | ||
810 | /*********************/ | ||
811 | |||
812 | #define ATH_ANT_DIV_MAX_CFG 2 | ||
813 | #define ATH_ANT_DIV_MIN_IDLE_US 1000000 /* us */ | ||
814 | #define ATH_ANT_DIV_MIN_SCAN_US 50000 /* us */ | ||
815 | |||
816 | enum ATH_ANT_DIV_STATE{ | ||
817 | ATH_ANT_DIV_IDLE, | ||
818 | ATH_ANT_DIV_SCAN, /* evaluating antenna */ | ||
819 | }; | ||
820 | |||
821 | struct ath_antdiv { | ||
822 | struct ath_softc *antdiv_sc; | ||
823 | u8 antdiv_start; | ||
824 | enum ATH_ANT_DIV_STATE antdiv_state; | ||
825 | u8 antdiv_num_antcfg; | ||
826 | u8 antdiv_curcfg; | ||
827 | u8 antdiv_bestcfg; | ||
828 | int32_t antdivf_rssitrig; | ||
829 | int32_t antdiv_lastbrssi[ATH_ANT_DIV_MAX_CFG]; | ||
830 | u64 antdiv_lastbtsf[ATH_ANT_DIV_MAX_CFG]; | ||
831 | u64 antdiv_laststatetsf; | ||
832 | u8 antdiv_bssid[ETH_ALEN]; | ||
833 | }; | ||
834 | |||
835 | void ath_slow_ant_div_init(struct ath_antdiv *antdiv, | ||
836 | struct ath_softc *sc, int32_t rssitrig); | ||
837 | void ath_slow_ant_div_start(struct ath_antdiv *antdiv, | ||
838 | u8 num_antcfg, | ||
839 | const u8 *bssid); | ||
840 | void ath_slow_ant_div_stop(struct ath_antdiv *antdiv); | ||
841 | void ath_slow_ant_div(struct ath_antdiv *antdiv, | ||
842 | struct ieee80211_hdr *wh, | ||
843 | struct ath_rx_status *rx_stats); | ||
844 | void ath_setdefantenna(void *sc, u32 antenna); | ||
845 | |||
846 | /********************/ | ||
847 | /* Main driver core */ | ||
848 | /********************/ | ||
849 | |||
850 | /* | ||
851 | * Default cache line size, in bytes. | ||
852 | * Used when PCI device not fully initialized by bootrom/BIOS | ||
853 | */ | ||
854 | #define DEFAULT_CACHELINE 32 | ||
855 | #define ATH_DEFAULT_NOISE_FLOOR -95 | ||
856 | #define ATH_REGCLASSIDS_MAX 10 | ||
857 | #define ATH_CABQ_READY_TIME 80 /* % of beacon interval */ | ||
858 | #define ATH_PREAMBLE_SHORT (1<<0) | ||
859 | #define ATH_PROTECT_ENABLE (1<<1) | ||
860 | #define ATH_MAX_SW_RETRIES 10 | ||
861 | /* Num farmes difference in tx to flip default recv */ | ||
862 | #define ATH_ANTENNA_DIFF 2 | ||
863 | #define ATH_CHAN_MAX 255 | ||
864 | #define IEEE80211_WEP_NKID 4 /* number of key ids */ | ||
865 | #define IEEE80211_RATE_VAL 0x7f | ||
866 | /* | ||
867 | * The key cache is used for h/w cipher state and also for | ||
868 | * tracking station state such as the current tx antenna. | ||
869 | * We also setup a mapping table between key cache slot indices | ||
870 | * and station state to short-circuit node lookups on rx. | ||
871 | * Different parts have different size key caches. We handle | ||
872 | * up to ATH_KEYMAX entries (could dynamically allocate state). | ||
873 | */ | ||
874 | #define ATH_KEYMAX 128 /* max key cache size we handle */ | ||
875 | |||
876 | #define RESET_RETRY_TXQ 0x00000001 | ||
877 | #define ATH_IF_ID_ANY 0xff | ||
878 | |||
879 | #define ATH_TXPOWER_MAX 100 /* .5 dBm units */ | ||
880 | |||
881 | #define RSSI_LPF_THRESHOLD -20 | ||
882 | #define ATH_RSSI_EP_MULTIPLIER (1<<7) /* pow2 to optimize out * and / */ | ||
883 | #define ATH_RATE_DUMMY_MARKER 0 | ||
884 | #define ATH_RSSI_LPF_LEN 10 | ||
885 | #define ATH_RSSI_DUMMY_MARKER 0x127 | ||
886 | |||
887 | #define ATH_EP_MUL(x, mul) ((x) * (mul)) | ||
888 | #define ATH_EP_RND(x, mul) \ | ||
889 | ((((x)%(mul)) >= ((mul)/2)) ? ((x) + ((mul) - 1)) / (mul) : (x)/(mul)) | ||
890 | #define ATH_RSSI_OUT(x) \ | ||
891 | (((x) != ATH_RSSI_DUMMY_MARKER) ? \ | ||
892 | (ATH_EP_RND((x), ATH_RSSI_EP_MULTIPLIER)) : ATH_RSSI_DUMMY_MARKER) | ||
893 | #define ATH_RSSI_IN(x) \ | ||
894 | (ATH_EP_MUL((x), ATH_RSSI_EP_MULTIPLIER)) | ||
895 | #define ATH_LPF_RSSI(x, y, len) \ | ||
896 | ((x != ATH_RSSI_DUMMY_MARKER) ? \ | ||
897 | (((x) * ((len) - 1) + (y)) / (len)) : (y)) | ||
898 | #define ATH_RSSI_LPF(x, y) do { \ | ||
899 | if ((y) >= RSSI_LPF_THRESHOLD) \ | ||
900 | x = ATH_LPF_RSSI((x), \ | ||
901 | ATH_RSSI_IN((y)), ATH_RSSI_LPF_LEN); \ | ||
902 | } while (0) | ||
903 | |||
904 | |||
905 | enum PROT_MODE { | ||
906 | PROT_M_NONE = 0, | ||
907 | PROT_M_RTSCTS, | ||
908 | PROT_M_CTSONLY | ||
909 | }; | ||
910 | |||
911 | enum RATE_TYPE { | ||
912 | NORMAL_RATE = 0, | ||
913 | HALF_RATE, | ||
914 | QUARTER_RATE | ||
915 | }; | ||
916 | |||
917 | struct ath_ht_info { | ||
918 | enum ath9k_ht_macmode tx_chan_width; | ||
919 | u16 maxampdu; | ||
920 | u8 mpdudensity; | ||
921 | u8 ext_chan_offset; | ||
922 | }; | ||
923 | |||
924 | struct ath_softc { | ||
925 | struct ieee80211_hw *hw; /* mac80211 instance */ | ||
926 | struct pci_dev *pdev; /* Bus handle */ | ||
927 | void __iomem *mem; /* address of the device */ | ||
928 | struct tasklet_struct intr_tq; /* General tasklet */ | ||
929 | struct tasklet_struct bcon_tasklet; /* Beacon tasklet */ | ||
930 | struct ath_config sc_config; /* per-instance load-time | ||
931 | parameters */ | ||
932 | int sc_debug; /* Debug masks */ | ||
933 | struct ath_hal *sc_ah; /* HAL Instance */ | ||
934 | struct ath_rate_softc *sc_rc; /* tx rate control support */ | ||
935 | u32 sc_intrstatus; /* HAL_STATUS */ | ||
936 | enum ath9k_opmode sc_opmode; /* current operating mode */ | ||
937 | |||
938 | /* Properties, Config */ | ||
939 | u8 sc_invalid; /* being detached */ | ||
940 | u8 sc_beacons; /* beacons running */ | ||
941 | u8 sc_scanning; /* scanning active */ | ||
942 | u8 sc_txaggr; /* enable 11n tx aggregation */ | ||
943 | u8 sc_rxaggr; /* enable 11n rx aggregation */ | ||
944 | u8 sc_update_chainmask; /* change chain mask */ | ||
945 | u8 sc_full_reset; /* force full reset */ | ||
946 | enum wireless_mode sc_curmode; /* current phy mode */ | ||
947 | u16 sc_curtxpow; /* current tx power limit */ | ||
948 | u16 sc_curaid; /* current association id */ | ||
949 | u8 sc_curbssid[ETH_ALEN]; | ||
950 | u8 sc_myaddr[ETH_ALEN]; | ||
951 | enum PROT_MODE sc_protmode; /* protection mode */ | ||
952 | u8 sc_mcastantenna;/* Multicast antenna number */ | ||
953 | u8 sc_txantenna; /* data tx antenna | ||
954 | (fixed or auto) */ | ||
955 | u8 sc_nbcnvaps; /* # of vaps sending beacons */ | ||
956 | u16 sc_nvaps; /* # of active virtual ap's */ | ||
957 | struct ath_vap *sc_vaps[ATH_BCBUF]; /* interface id | ||
958 | to avp map */ | ||
959 | enum ath9k_int sc_imask; /* interrupt mask copy */ | ||
960 | u8 sc_bssidmask[ETH_ALEN]; | ||
961 | u8 sc_defant; /* current default antenna */ | ||
962 | u8 sc_rxotherant; /* rx's on non-default antenna*/ | ||
963 | u16 sc_cachelsz; /* cache line size */ | ||
964 | int sc_slotupdate; /* slot to next advance fsm */ | ||
965 | int sc_slottime; /* slot time */ | ||
966 | u8 sc_noreset; | ||
967 | int sc_bslot[ATH_BCBUF];/* beacon xmit slots */ | ||
968 | struct ath9k_node_stats sc_halstats; /* station-mode rssi stats */ | ||
969 | struct list_head node_list; | ||
970 | struct ath_ht_info sc_ht_info; | ||
971 | int16_t sc_noise_floor; /* signal noise floor in dBm */ | ||
972 | enum ath9k_ht_extprotspacing sc_ht_extprotspacing; | ||
973 | u8 sc_tx_chainmask; | ||
974 | u8 sc_rx_chainmask; | ||
975 | u8 sc_rxchaindetect_ref; | ||
976 | u8 sc_rxchaindetect_thresh5GHz; | ||
977 | u8 sc_rxchaindetect_thresh2GHz; | ||
978 | u8 sc_rxchaindetect_delta5GHz; | ||
979 | u8 sc_rxchaindetect_delta2GHz; | ||
980 | u32 sc_rtsaggrlimit; /* Chipset specific | ||
981 | aggr limit */ | ||
982 | u32 sc_flags; | ||
983 | #ifdef CONFIG_SLOW_ANT_DIV | ||
984 | /* Slow antenna diversity */ | ||
985 | struct ath_antdiv sc_antdiv; | ||
986 | #endif | ||
987 | enum { | ||
988 | OK, /* no change needed */ | ||
989 | UPDATE, /* update pending */ | ||
990 | COMMIT /* beacon sent, commit change */ | ||
991 | } sc_updateslot; /* slot time update fsm */ | ||
992 | |||
993 | /* Crypto */ | ||
994 | u32 sc_keymax; /* size of key cache */ | ||
995 | DECLARE_BITMAP(sc_keymap, ATH_KEYMAX); /* key use bit map */ | ||
996 | u8 sc_splitmic; /* split TKIP MIC keys */ | ||
997 | int sc_keytype; /* type of the key being used */ | ||
998 | |||
999 | /* RX */ | ||
1000 | struct list_head sc_rxbuf; /* receive buffer */ | ||
1001 | struct ath_descdma sc_rxdma; /* RX descriptors */ | ||
1002 | int sc_rxbufsize; /* rx size based on mtu */ | ||
1003 | u32 *sc_rxlink; /* link ptr in last RX desc */ | ||
1004 | u32 sc_rxflush; /* rx flush in progress */ | ||
1005 | u64 sc_lastrx; /* tsf of last rx'd frame */ | ||
1006 | |||
1007 | /* TX */ | ||
1008 | struct list_head sc_txbuf; /* transmit buffer */ | ||
1009 | struct ath_txq sc_txq[ATH9K_NUM_TX_QUEUES]; | ||
1010 | struct ath_descdma sc_txdma; /* TX descriptors */ | ||
1011 | u32 sc_txqsetup; /* h/w queues setup */ | ||
1012 | u32 sc_txintrperiod;/* tx interrupt batching */ | ||
1013 | int sc_haltype2q[ATH9K_WME_AC_VO+1]; /* HAL WME | ||
1014 | AC -> h/w qnum */ | ||
1015 | u32 sc_ant_tx[8]; /* recent tx frames/antenna */ | ||
1016 | |||
1017 | /* Beacon */ | ||
1018 | struct ath9k_txq_info sc_beacon_qi; /* adhoc only: beacon | ||
1019 | queue parameters */ | ||
1020 | struct ath_descdma sc_bdma; /* beacon descriptors */ | ||
1021 | struct ath_txq *sc_cabq; /* tx q for cab frames */ | ||
1022 | struct list_head sc_bbuf; /* beacon buffers */ | ||
1023 | u32 sc_bhalq; /* HAL q for outgoing beacons */ | ||
1024 | u32 sc_bmisscount; /* missed beacon transmits */ | ||
1025 | u32 ast_be_xmit; /* beacons transmitted */ | ||
1026 | |||
1027 | /* Rate */ | ||
1028 | struct ieee80211_rate rates[IEEE80211_NUM_BANDS][ATH_RATE_MAX]; | ||
1029 | const struct ath9k_rate_table *sc_rates[WIRELESS_MODE_MAX]; | ||
1030 | const struct ath9k_rate_table *sc_currates; /* current rate table */ | ||
1031 | u8 sc_rixmap[256]; /* IEEE to h/w | ||
1032 | rate table ix */ | ||
1033 | u8 sc_minrateix; /* min h/w rate index */ | ||
1034 | u8 sc_protrix; /* protection rate index */ | ||
1035 | struct { | ||
1036 | u32 rateKbps; /* transfer rate in kbs */ | ||
1037 | u8 ieeerate; /* IEEE rate */ | ||
1038 | } sc_hwmap[256]; /* h/w rate ix mappings */ | ||
1039 | |||
1040 | /* Channel, Band */ | ||
1041 | struct ieee80211_channel channels[IEEE80211_NUM_BANDS][ATH_CHAN_MAX]; | ||
1042 | struct ieee80211_supported_band sbands[IEEE80211_NUM_BANDS]; | ||
1043 | struct ath9k_channel sc_curchan; /* current h/w channel */ | ||
1044 | |||
1045 | /* Locks */ | ||
1046 | spinlock_t sc_rxflushlock; /* lock of RX flush */ | ||
1047 | spinlock_t sc_rxbuflock; /* rxbuf lock */ | ||
1048 | spinlock_t sc_txbuflock; /* txbuf lock */ | ||
1049 | spinlock_t sc_resetlock; | ||
1050 | spinlock_t node_lock; | ||
1051 | }; | ||
1052 | |||
1053 | int ath_init(u16 devid, struct ath_softc *sc); | ||
1054 | void ath_deinit(struct ath_softc *sc); | ||
1055 | int ath_open(struct ath_softc *sc, struct ath9k_channel *initial_chan); | ||
1056 | int ath_suspend(struct ath_softc *sc); | ||
1057 | irqreturn_t ath_isr(int irq, void *dev); | ||
1058 | int ath_reset(struct ath_softc *sc); | ||
1059 | void ath_scan_start(struct ath_softc *sc); | ||
1060 | void ath_scan_end(struct ath_softc *sc); | ||
1061 | int ath_set_channel(struct ath_softc *sc, struct ath9k_channel *hchan); | ||
1062 | void ath_setup_rate(struct ath_softc *sc, | ||
1063 | enum wireless_mode wMode, | ||
1064 | enum RATE_TYPE type, | ||
1065 | const struct ath9k_rate_table *rt); | ||
1066 | |||
1067 | /*********************/ | ||
1068 | /* Utility Functions */ | ||
1069 | /*********************/ | ||
1070 | |||
1071 | void ath_key_reset(struct ath_softc *sc, u16 keyix, int freeslot); | ||
1072 | int ath_keyset(struct ath_softc *sc, | ||
1073 | u16 keyix, | ||
1074 | struct ath9k_keyval *hk, | ||
1075 | const u8 mac[ETH_ALEN]); | ||
1076 | int ath_get_hal_qnum(u16 queue, struct ath_softc *sc); | ||
1077 | int ath_get_mac80211_qnum(u32 queue, struct ath_softc *sc); | ||
1078 | void ath_setslottime(struct ath_softc *sc); | ||
1079 | void ath_update_txpow(struct ath_softc *sc); | ||
1080 | int ath_cabq_update(struct ath_softc *); | ||
1081 | void ath_get_currentCountry(struct ath_softc *sc, | ||
1082 | struct ath9k_country_entry *ctry); | ||
1083 | u64 ath_extend_tsf(struct ath_softc *sc, u32 rstamp); | ||
1084 | void ath_internal_reset(struct ath_softc *sc); | ||
1085 | u32 ath_chan2flags(struct ieee80211_channel *chan, struct ath_softc *sc); | ||
1086 | dma_addr_t ath_skb_map_single(struct ath_softc *sc, | ||
1087 | struct sk_buff *skb, | ||
1088 | int direction, | ||
1089 | dma_addr_t *pa); | ||
1090 | void ath_skb_unmap_single(struct ath_softc *sc, | ||
1091 | struct sk_buff *skb, | ||
1092 | int direction, | ||
1093 | dma_addr_t *pa); | ||
1094 | void ath_mcast_merge(struct ath_softc *sc, u32 mfilt[2]); | ||
1095 | enum ath9k_ht_macmode ath_cwm_macmode(struct ath_softc *sc); | ||
1096 | |||
1097 | #endif /* CORE_H */ | ||