Commit | Line | Data |
---|---|---|
b481de9c ZY |
1 | /****************************************************************************** |
2 | * | |
eb7ae89c | 3 | * Copyright(c) 2003 - 2008 Intel Corporation. All rights reserved. |
b481de9c ZY |
4 | * |
5 | * Portions of this file are derived from the ipw3945 project, as well | |
6 | * as portions of the ieee80211 subsystem header files. | |
7 | * | |
8 | * This program is free software; you can redistribute it and/or modify it | |
9 | * under the terms of version 2 of the GNU General Public License as | |
10 | * published by the Free Software Foundation. | |
11 | * | |
12 | * This program is distributed in the hope that it will be useful, but WITHOUT | |
13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | |
15 | * more details. | |
16 | * | |
17 | * You should have received a copy of the GNU General Public License along with | |
18 | * this program; if not, write to the Free Software Foundation, Inc., | |
19 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA | |
20 | * | |
21 | * The full GNU General Public License is included in this distribution in the | |
22 | * file called LICENSE. | |
23 | * | |
24 | * Contact Information: | |
25 | * James P. Ketrenos <ipw2100-admin@linux.intel.com> | |
26 | * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 | |
27 | * | |
28 | *****************************************************************************/ | |
29 | ||
30 | #ifndef __iwl_helpers_h__ | |
31 | #define __iwl_helpers_h__ | |
32 | ||
33 | #include <linux/ctype.h> | |
34 | ||
35 | /* | |
36 | * The structures defined by the hardware/uCode interface | |
37 | * have bit-wise operations. For each bit-field there is | |
38 | * a data symbol in the structure, the start bit position | |
39 | * and the length of the bit-field. | |
40 | * | |
41 | * iwl_get_bits and iwl_set_bits will return or set the | |
42 | * appropriate bits on a 32-bit value. | |
43 | * | |
44 | * IWL_GET_BITS and IWL_SET_BITS use symbol expansion to | |
45 | * expand out to the appropriate call to iwl_get_bits | |
46 | * and iwl_set_bits without having to reference all of the | |
47 | * numerical constants and defines provided in the hardware | |
48 | * definition | |
49 | */ | |
50 | ||
51 | /** | |
52 | * iwl_get_bits - Extract a hardware bit-field value | |
53 | * @src: source hardware value (__le32) | |
54 | * @pos: bit-position (0-based) of first bit of value | |
55 | * @len: length of bit-field | |
56 | * | |
57 | * iwl_get_bits will return the bit-field in cpu endian ordering. | |
58 | * | |
59 | * NOTE: If used from IWL_GET_BITS then pos and len are compile-constants and | |
60 | * will collapse to minimal code by the compiler. | |
61 | */ | |
62 | static inline u32 iwl_get_bits(__le32 src, u8 pos, u8 len) | |
63 | { | |
64 | u32 tmp = le32_to_cpu(src); | |
65 | ||
66 | tmp >>= pos; | |
67 | tmp &= (1UL << len) - 1; | |
68 | return tmp; | |
69 | } | |
70 | ||
71 | /** | |
72 | * iwl_set_bits - Set a hardware bit-field value | |
73 | * @dst: Address of __le32 hardware value | |
74 | * @pos: bit-position (0-based) of first bit of value | |
75 | * @len: length of bit-field | |
76 | * @val: cpu endian value to encode into the bit-field | |
77 | * | |
78 | * iwl_set_bits will encode val into dst, masked to be len bits long at bit | |
79 | * position pos. | |
80 | * | |
81 | * NOTE: If used IWL_SET_BITS pos and len will be compile-constants and | |
82 | * will collapse to minimal code by the compiler. | |
83 | */ | |
84 | static inline void iwl_set_bits(__le32 *dst, u8 pos, u8 len, int val) | |
85 | { | |
86 | u32 tmp = le32_to_cpu(*dst); | |
87 | ||
88 | tmp &= ~(((1UL << len) - 1) << pos); | |
89 | tmp |= (val & ((1UL << len) - 1)) << pos; | |
90 | *dst = cpu_to_le32(tmp); | |
91 | } | |
92 | ||
93 | static inline void iwl_set_bits16(__le16 *dst, u8 pos, u8 len, int val) | |
94 | { | |
95 | u16 tmp = le16_to_cpu(*dst); | |
96 | ||
97 | tmp &= ~((1UL << (pos + len)) - (1UL << pos)); | |
98 | tmp |= (val & ((1UL << len) - 1)) << pos; | |
99 | *dst = cpu_to_le16(tmp); | |
100 | } | |
101 | ||
102 | /* | |
103 | * The bit-field definitions in iwl-xxxx-hw.h are in the form of: | |
104 | * | |
105 | * struct example { | |
106 | * __le32 val1; | |
107 | * #define IWL_name_POS 8 | |
108 | * #define IWL_name_LEN 4 | |
109 | * #define IWL_name_SYM val1 | |
110 | * }; | |
111 | * | |
112 | * The IWL_SET_BITS and IWL_GET_BITS macros are provided to allow the driver | |
113 | * to call: | |
114 | * | |
115 | * struct example bar; | |
116 | * u32 val = IWL_GET_BITS(bar, name); | |
117 | * val = val * 2; | |
118 | * IWL_SET_BITS(bar, name, val); | |
119 | * | |
120 | * All cpu / host ordering, masking, and shifts are performed by the macros | |
121 | * and iwl_{get,set}_bits. | |
122 | * | |
123 | */ | |
124 | #define IWL_SET_BITS(s, sym, v) \ | |
125 | iwl_set_bits(&(s).IWL_ ## sym ## _SYM, IWL_ ## sym ## _POS, \ | |
126 | IWL_ ## sym ## _LEN, (v)) | |
127 | ||
128 | #define IWL_SET_BITS16(s, sym, v) \ | |
129 | iwl_set_bits16(&(s).IWL_ ## sym ## _SYM, IWL_ ## sym ## _POS, \ | |
130 | IWL_ ## sym ## _LEN, (v)) | |
131 | ||
132 | #define IWL_GET_BITS(s, sym) \ | |
133 | iwl_get_bits((s).IWL_ ## sym ## _SYM, IWL_ ## sym ## _POS, \ | |
134 | IWL_ ## sym ## _LEN) | |
135 | ||
136 | ||
137 | #define KELVIN_TO_CELSIUS(x) ((x)-273) | |
138 | #define CELSIUS_TO_KELVIN(x) ((x)+273) | |
da1bc453 TW |
139 | #define IWL_MASK(lo, hi) ((1 << (hi)) | ((1 << (hi)) - (1 << (lo)))) |
140 | ||
b481de9c | 141 | |
b481de9c ZY |
142 | static inline struct ieee80211_conf *ieee80211_get_hw_conf( |
143 | struct ieee80211_hw *hw) | |
144 | { | |
145 | return &hw->conf; | |
146 | } | |
147 | ||
b481de9c ZY |
148 | static inline int iwl_check_bits(unsigned long field, unsigned long mask) |
149 | { | |
150 | return ((field & mask) == mask) ? 1 : 0; | |
151 | } | |
152 | ||
153 | static inline unsigned long elapsed_jiffies(unsigned long start, | |
154 | unsigned long end) | |
155 | { | |
9e7d1a44 | 156 | if (end >= start) |
b481de9c ZY |
157 | return end - start; |
158 | ||
9e7d1a44 | 159 | return end + (MAX_JIFFY_OFFSET - start) + 1; |
b481de9c ZY |
160 | } |
161 | ||
6a218f6f TW |
162 | static inline u8 iwl_get_dma_hi_address(dma_addr_t addr) |
163 | { | |
164 | return sizeof(addr) > sizeof(u32) ? (addr >> 16) >> 16 : 0; | |
165 | } | |
166 | ||
c54b679d TW |
167 | /** |
168 | * iwl_queue_inc_wrap - increment queue index, wrap back to beginning | |
169 | * @index -- current index | |
170 | * @n_bd -- total number of entries in queue (must be power of 2) | |
171 | */ | |
172 | static inline int iwl_queue_inc_wrap(int index, int n_bd) | |
173 | { | |
174 | return ++index & (n_bd - 1); | |
175 | } | |
176 | ||
177 | /** | |
178 | * iwl_queue_dec_wrap - decrement queue index, wrap back to end | |
179 | * @index -- current index | |
180 | * @n_bd -- total number of entries in queue (must be power of 2) | |
181 | */ | |
182 | static inline int iwl_queue_dec_wrap(int index, int n_bd) | |
183 | { | |
184 | return --index & (n_bd - 1); | |
185 | } | |
186 | ||
98c92211 TW |
187 | /* TODO: Move fw_desc functions to iwl-pci.ko */ |
188 | static inline void iwl_free_fw_desc(struct pci_dev *pci_dev, | |
189 | struct fw_desc *desc) | |
190 | { | |
191 | if (desc->v_addr) | |
192 | pci_free_consistent(pci_dev, desc->len, | |
193 | desc->v_addr, desc->p_addr); | |
194 | desc->v_addr = NULL; | |
195 | desc->len = 0; | |
196 | } | |
197 | ||
198 | static inline int iwl_alloc_fw_desc(struct pci_dev *pci_dev, | |
199 | struct fw_desc *desc) | |
200 | { | |
201 | desc->v_addr = pci_alloc_consistent(pci_dev, desc->len, &desc->p_addr); | |
202 | return (desc->v_addr != NULL) ? 0 : -ENOMEM; | |
203 | } | |
204 | ||
b481de9c | 205 | #endif /* __iwl_helpers_h__ */ |