2 * Copyright (c) 2002-2006 Sam Leffler, Errno Consulting
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
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.
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 $
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.
54 HAL-ONLY register operations:
64 * We don't require locking overhead and function call except for
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;
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 */
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)));
108 void __ahdecl
ath_hal_logprintf(struct ath_hal
*ah
, const char *fmt
, ...)
109 __attribute__ ((__format__ (__printf__
, 2, 3)));
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);
126 #define abs(_a) __builtin_abs(_a)
130 #define labs(_a) __builtin_labs(_a)
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
146 #define AH_BYTE_ORDER AH_BIG_ENDIAN
148 #ifndef AH_BYTE_ORDER
149 #error "Do not know host byte order"
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
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
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)))
176 # define iowrite32be(_val, _addr) iowrite32(swab32((_val)), (_addr))
179 # define ioread32be(_addr) swab32(ioread32((_addr)))
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
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 { \
202 iowrite32((_val), (_ah)->ah_sh + (_reg)) : \
203 iowrite32be((_val), (_ah)->ah_sh + (_reg)); \
205 # define _OS_REG_READ(_ah, _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)); \
215 # define _OS_REG_READ(_ah, _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)); \
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)); \
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
,
256 extern u_int32_t __ahdecl
ath_hal_reg_read(struct ath_hal
*ah
, u_int reg
);
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
)
272 static inline void ath_hal_set_device(const char *name
)
275 ath_hal_device
= name
;
280 extern void __ahdecl
OS_MARK(struct ath_hal
*, u_int id
, u_int32_t value
);
282 #define OS_MARK(_ah, _id, _v)
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
,
295 extern void _ath_hal_detach(struct ath_hal
*);
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
);
303 ath_hal_print_register(struct ath_hal
*ah
,
304 const char *device_name
,
305 u_int32_t address
, u_int32_t value
);
308 ath_hal_lookup_register_name(struct ath_hal
*ah
, char *buf
, int buflen
,
311 #endif /* _ATH_AH_OSDEP_H_ */