update madwifi
[linux-2.6/zen-sources.git] / drivers / net / wireless / madwifi / ath_hal / ah_os.h
blob0b35f489085d2e6f828f7b57a6cbf67b655f4ec2
1 /*-
2 * Copyright (c) 2002-2006 Sam Leffler, Errno Consulting
3 * All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer,
10 * without modification.
11 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
12 * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
13 * redistribution must be conditioned upon including a substantially
14 * similar Disclaimer requirement for further binary redistribution.
15 * 3. Neither the names of the above-listed copyright holders nor the names
16 * of any contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
19 * Alternatively, this software may be distributed under the terms of the
20 * GNU General Public License ("GPL") version 2 as published by the Free
21 * Software Foundation.
23 * NO WARRANTY
24 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
25 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
26 * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
27 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
28 * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
29 * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
30 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
31 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
32 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
33 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
34 * THE POSSIBILITY OF SUCH DAMAGES.
36 * $Id: ah_os.h 3731 2008-06-19 00:22:42Z mentor $
38 #ifndef _ATH_AH_OS_H_
39 #define _ATH_AH_OS_H_
42 * Atheros Hardware Access Layer (HAL) OS Dependent Definitions.
46 MadWifi safe register operations:
48 When hacking on registers directly, we need to use the macros below to
49 avoid concurrent PCI access and abort mode errors.
51 * ath_reg_read
52 * ATH_REG_WRITE
54 HAL-ONLY register operations:
56 * _OS_REG_READ
57 * _OS_REG_WRITE
58 * OS_REG_READ
59 * OS_REG_WRITE
60 * ath_hal_reg_read.
61 * ath_hal_reg_write
63 When compiled in HAL:
64 * We don't require locking overhead and function call except for
65 debugging.
66 * All HAL operations are executed in the context of a MadWifi wrapper
67 call that holds the HAL lock.
68 * Normally HAL is built with the non-modified version of this file, so
69 it doesn't have our funny macros anyway.
71 When compiled in MadWifi:
72 * The HAL wrapper API takes the HAL lock before invoking the HAL.
73 * HAL access is already protected, and MadWifi must NOT access the
74 functions listed above.
78 * When building the HAL proper, we use no GPL-licensed include files and must
79 * define Linux types ourselves. Please note that the definitions below don't
80 * exactly match those in <linux/types.h>
82 #ifndef _LINUX_TYPES_H
83 /* NB: ARM defaults to unsigned, so be explicit */
84 typedef signed char int8_t;
85 typedef short int16_t;
86 typedef int int32_t;
87 typedef long long int64_t;
89 typedef unsigned char u_int8_t;
90 typedef unsigned short u_int16_t;
91 typedef unsigned int u_int32_t;
92 typedef unsigned long long u_int64_t;
94 typedef unsigned int size_t;
95 typedef unsigned int u_int;
96 typedef void* va_list;
97 #endif /* !_LINUX_TYPES_H */
99 struct ath_hal;
101 extern int ath_hal_dma_beacon_response_time;
102 extern int ath_hal_sw_beacon_response_time;
103 extern int ath_hal_additional_swba_backoff;
105 void __ahdecl ath_hal_printf(struct ath_hal *ah, HAL_BOOL prefer_alq, const char *fmt, ...)
106 __attribute__ ((__format__ (__printf__, 3, 4)));
107 #ifdef AH_DEBUG_ALQ
108 void __ahdecl ath_hal_logprintf(struct ath_hal *ah, const char *fmt, ...)
109 __attribute__ ((__format__ (__printf__, 2, 3)));
110 #endif
112 int __ahdecl ath_hal_memcmp(const void *a, const void *b, size_t n);
113 void *__ahdecl ath_hal_malloc(size_t size);
114 void __ahdecl ath_hal_free(void *p);
116 /* Delay n microseconds. */
117 extern void __ahdecl ath_hal_delay(int);
118 #define OS_DELAY(_n) ath_hal_delay(_n)
120 #define OS_MEMZERO(_a, _n) ath_hal_memzero((_a), (_n))
121 extern void __ahdecl ath_hal_memzero(void *, size_t);
122 #define OS_MEMCPY(_d, _s, _n) ath_hal_memcpy(_d,_s,_n)
123 extern void *__ahdecl ath_hal_memcpy(void *, const void *, size_t);
125 #ifndef abs
126 #define abs(_a) __builtin_abs(_a)
127 #endif
129 #ifndef labs
130 #define labs(_a) __builtin_labs(_a)
131 #endif
133 /* Byte order/swapping support. */
134 #define AH_LITTLE_ENDIAN 1234
135 #define AH_BIG_ENDIAN 4321
137 #ifndef AH_BYTE_ORDER
139 * When the .inc file is not available (e.g. when building in the kernel source
140 * tree), look for some other way to determine the host byte order.
142 #ifdef __LITTLE_ENDIAN
143 #define AH_BYTE_ORDER AH_LITTLE_ENDIAN
144 #endif
145 #ifdef __BIG_ENDIAN
146 #define AH_BYTE_ORDER AH_BIG_ENDIAN
147 #endif
148 #ifndef AH_BYTE_ORDER
149 #error "Do not know host byte order"
150 #endif
151 #endif /* AH_BYTE_ORDER */
154 * The HAL programs big-endian platforms to use byte-swapped hardware registers.
155 * This is done to avoid the byte swapping needed to access PCI devices.
157 * Many big-endian architectures provide I/O functions that avoid byte swapping.
158 * We use them when possible. Otherwise, we provide replacements. The downside
159 * or the replacements is that we may be byte-swapping data twice, so we try to
160 * avoid it.
162 * We use raw access for Linux prior to 2.6.12. For newer version, we need to
163 * use ioread32() and iowrite32(), which would take care of indirect access to
164 * the registers.
166 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,12)) && \
167 (AH_BYTE_ORDER == AH_BIG_ENDIAN) && \
168 !defined(CONFIG_GENERIC_IOMAP) && \
169 !defined(CONFIG_PARISC) && \
170 !(defined(CONFIG_PPC64) && \
171 (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,14))) && \
172 !defined(CONFIG_PPC_MERGE) && \
173 !(defined(CONFIG_MIPS) && \
174 (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21)))
175 # ifndef iowrite32be
176 # define iowrite32be(_val, _addr) iowrite32(swab32((_val)), (_addr))
177 # endif
178 # ifndef ioread32be
179 # define ioread32be(_addr) swab32(ioread32((_addr)))
180 # endif
181 #endif
184 * The register accesses are done using target-specific functions when
185 * debugging is enabled (AH_DEBUG) or it's explicitly requested for the target.
187 * The hardware registers use little-endian byte order natively. Big-endian
188 * systems are configured by HAL to byte-swap of register reads and writes.
189 * However, the registers in the areas 0x4000-0x4fff and 0x7000-0x7fff are not
190 * byte swapped!
192 * Since Linux I/O primitives default to little-endian operations, we only
193 * need to suppress byte-swapping on big-endian systems outside the area used
194 * by the PCI clock domain registers.
196 #if (AH_BYTE_ORDER == AH_BIG_ENDIAN)
197 # define is_reg_le(__reg) ((0x4000 <= (__reg) && (__reg) < 0x5000) || \
198 (0x7000 <= (__reg) && (__reg) < 0x8000))
199 # if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,12)
200 # define _OS_REG_WRITE(_ah, _reg, _val) do { \
201 is_reg_le(_reg) ? \
202 iowrite32((_val), (_ah)->ah_sh + (_reg)) : \
203 iowrite32be((_val), (_ah)->ah_sh + (_reg)); \
204 } while (0)
205 # define _OS_REG_READ(_ah, _reg) \
206 (is_reg_le(_reg) ? \
207 ioread32((_ah)->ah_sh + (_reg)) : \
208 ioread32be((_ah)->ah_sh + (_reg)))
209 # else /* Linux < 2.6.12 */
210 # define _OS_REG_WRITE(_ah, _reg, _val) do { \
211 writel(is_reg_le(_reg) ? \
212 (_val) : cpu_to_le32(_val), \
213 (_ah)->ah_sh + (_reg)); \
214 } while (0)
215 # define _OS_REG_READ(_ah, _reg) \
216 (is_reg_le(_reg) ? \
217 readl((_ah)->ah_sh + (_reg)) : \
218 cpu_to_le32(readl((_ah)->ah_sh + (_reg))))
219 # endif /* Linux < 2.6.12 */
220 #else /* Little endian */
221 # if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,12)
222 # define _OS_REG_WRITE(_ah, _reg, _val) do { \
223 iowrite32((_val), (_ah)->ah_sh + (_reg)); \
224 } while (0)
225 # define _OS_REG_READ(_ah, _reg) \
226 ioread32((_ah)->ah_sh + (_reg))
227 # else /* Linux < 2.6.12 */
228 # define _OS_REG_WRITE(_ah, _reg, _val) do { \
229 writel((_val), (_ah)->ah_sh + (_reg)); \
230 } while (0)
231 # define _OS_REG_READ(_ah, _reg) \
232 readl((_ah)->ah_sh + (_reg))
233 # endif /* Linux < 2.6.12 */
234 #endif /* Little endian */
236 #define HAL_DEBUG_OFF 0
237 /* Show register accesses */
238 #define HAL_DEBUG_REGOPS 1
239 /* Show decoded register dump (include name, etc) */
240 #define HAL_DEBUG_REGOPS_DECODED 2
241 /* Show bit-fields where we put decode logic in */
242 #define HAL_DEBUG_REGOPS_BITFIELDS 3
243 /* Add a read before a write to show 'changes', may have side-effects */
244 #define HAL_DEBUG_REGOPS_DELTAS 4
247 * The functions in this section are not intended to be invoked by MadWifi
248 * driver code, but by the HAL. They are NOT safe to call directly when the
249 * sc->sc_hal_lock is not held. Use ath_reg_read and ATH_REG_WRITE instead!
251 #if defined(AH_DEBUG) || defined(AH_REGOPS_FUNC) || defined(AH_DEBUG_ALQ)
252 #define OS_REG_WRITE(_ah, _reg, _val) ath_hal_reg_write(_ah, _reg, _val)
253 #define OS_REG_READ(_ah, _reg) ath_hal_reg_read(_ah, _reg)
254 extern void __ahdecl ath_hal_reg_write(struct ath_hal *ah, u_int reg,
255 u_int32_t val);
256 extern u_int32_t __ahdecl ath_hal_reg_read(struct ath_hal *ah, u_int reg);
257 #else
258 #define OS_REG_WRITE(_ah, _reg, _val) _OS_REG_WRITE(_ah, _reg, _val)
259 #define OS_REG_READ(_ah, _reg) _OS_REG_READ(_ah, _reg)
260 #endif /* AH_DEBUG || AH_REGFUNC || AH_DEBUG_ALQ */
262 /* XXX: This should be stored per-device for proper multi-radio support */
263 extern const char *ath_hal_func;
264 extern const char *ath_hal_device;
265 extern int ath_hal_debug;
266 static inline void ath_hal_set_function(const char *name)
268 #ifdef AH_DEBUG
269 ath_hal_func = name;
270 #endif
272 static inline void ath_hal_set_device(const char *name)
274 #ifdef AH_DEBUG
275 ath_hal_device = name;
276 #endif
279 #ifdef AH_DEBUG_ALQ
280 extern void __ahdecl OS_MARK(struct ath_hal *, u_int id, u_int32_t value);
281 #else
282 #define OS_MARK(_ah, _id, _v)
283 #endif
286 * Linux-specific attach/detach methods needed for module reference counting.
288 * NB: These are intentionally not marked __ahdecl since they are
289 * compiled with the default calling convention and are not called
290 * from within the HAL.
292 extern struct ath_hal *_ath_hal_attach(u_int16_t devid, HAL_SOFTC,
293 HAL_BUS_TAG, HAL_BUS_HANDLE,
294 HAL_STATUS *);
295 extern void _ath_hal_detach(struct ath_hal *);
297 void
298 ath_hal_print_decoded_register(struct ath_hal *ah,
299 const char *device_name,
300 u_int32_t address, u_int32_t oldval,
301 u_int32_t newval, HAL_BOOL bitfields);
302 void
303 ath_hal_print_register(struct ath_hal *ah,
304 const char *device_name,
305 u_int32_t address, u_int32_t value);
307 HAL_BOOL
308 ath_hal_lookup_register_name(struct ath_hal *ah, char *buf, int buflen,
309 u_int32_t address);
311 #endif /* _ATH_AH_OSDEP_H_ */