Zhu Yi | b481de9 | 2007-09-25 17:54:57 -0700 | [diff] [blame] | 1 | /****************************************************************************** |
| 2 | * |
Reinette Chatre | eb7ae89 | 2008-03-11 16:17:17 -0700 | [diff] [blame] | 3 | * Copyright(c) 2003 - 2008 Intel Corporation. All rights reserved. |
Zhu Yi | b481de9 | 2007-09-25 17:54:57 -0700 | [diff] [blame] | 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) |
Tomas Winkler | da1bc45 | 2008-05-29 16:35:00 +0800 | [diff] [blame] | 139 | #define IWL_MASK(lo, hi) ((1 << (hi)) | ((1 << (hi)) - (1 << (lo)))) |
| 140 | |
Zhu Yi | b481de9 | 2007-09-25 17:54:57 -0700 | [diff] [blame] | 141 | |
Zhu Yi | b481de9 | 2007-09-25 17:54:57 -0700 | [diff] [blame] | 142 | static inline struct ieee80211_conf *ieee80211_get_hw_conf( |
| 143 | struct ieee80211_hw *hw) |
| 144 | { |
| 145 | return &hw->conf; |
| 146 | } |
| 147 | |
Zhu Yi | b481de9 | 2007-09-25 17:54:57 -0700 | [diff] [blame] | 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 | { |
Eric Sandeen | 9e7d1a4 | 2008-01-24 15:47:39 -0500 | [diff] [blame] | 156 | if (end >= start) |
Zhu Yi | b481de9 | 2007-09-25 17:54:57 -0700 | [diff] [blame] | 157 | return end - start; |
| 158 | |
Eric Sandeen | 9e7d1a4 | 2008-01-24 15:47:39 -0500 | [diff] [blame] | 159 | return end + (MAX_JIFFY_OFFSET - start) + 1; |
Zhu Yi | b481de9 | 2007-09-25 17:54:57 -0700 | [diff] [blame] | 160 | } |
| 161 | |
Tomas Winkler | 6a218f6 | 2008-01-14 17:46:15 -0800 | [diff] [blame] | 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 | |
Tomas Winkler | c54b679 | 2008-03-06 17:36:53 -0800 | [diff] [blame] | 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 | |
Tomas Winkler | 98c9221 | 2008-01-14 17:46:20 -0800 | [diff] [blame] | 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 | |
Zhu Yi | b481de9 | 2007-09-25 17:54:57 -0700 | [diff] [blame] | 205 | #endif /* __iwl_helpers_h__ */ |