[IWLWIFI]: add iwlwifi wireless drivers
[linux-2.6.git] / drivers / net / wireless / iwlwifi / iwl-io.h
1 /******************************************************************************
2  *
3  * Copyright(c) 2003 - 2007 Intel Corporation. All rights reserved.
4  *
5  * Portions of this file are derived from the ipw3945 project.
6  *
7  * This program is free software; you can redistribute it and/or modify it
8  * under the terms of version 2 of the GNU General Public License as
9  * published by the Free Software Foundation.
10  *
11  * This program is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
14  * more details.
15  *
16  * You should have received a copy of the GNU General Public License along with
17  * this program; if not, write to the Free Software Foundation, Inc.,
18  * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19  *
20  * The full GNU General Public License is included in this distribution in the
21  * file called LICENSE.
22  *
23  * Contact Information:
24  * James P. Ketrenos <ipw2100-admin@linux.intel.com>
25  * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
26  *
27  *****************************************************************************/
28
29 #ifndef __iwl_io_h__
30 #define __iwl_io_h__
31
32 #include <linux/io.h>
33
34 #include "iwl-debug.h"
35
36 /*
37  * IO, register, and NIC memory access functions
38  *
39  * NOTE on naming convention and macro usage for these
40  *
41  * A single _ prefix before a an access function means that no state
42  * check or debug information is printed when that function is called.
43  *
44  * A double __ prefix before an access function means that state is checked
45  * (in the case of *restricted calls) and the current line number is printed
46  * in addition to any other debug output.
47  *
48  * The non-prefixed name is the #define that maps the caller into a
49  * #define that provides the caller's __LINE__ to the double prefix version.
50  *
51  * If you wish to call the function without any debug or state checking,
52  * you should use the single _ prefix version (as is used by dependent IO
53  * routines, for example _iwl_read_restricted calls the non-check version of
54  * _iwl_read32.)
55  *
56  * These declarations are *extremely* useful in quickly isolating code deltas
57  * which result in misconfiguring of the hardware I/O.  In combination with
58  * git-bisect and the IO debug level you can quickly determine the specific
59  * commit which breaks the IO sequence to the hardware.
60  *
61  */
62
63 #define _iwl_write32(iwl, ofs, val) writel((val), (iwl)->hw_base + (ofs))
64 #ifdef CONFIG_IWLWIFI_DEBUG
65 static inline void __iwl_write32(const char *f, u32 l, struct iwl_priv *iwl,
66                                  u32 ofs, u32 val)
67 {
68         IWL_DEBUG_IO("write_direct32(0x%08X, 0x%08X) - %s %d\n",
69                      (u32) (ofs), (u32) (val), f, l);
70         _iwl_write32(iwl, ofs, val);
71 }
72 #define iwl_write32(iwl, ofs, val) \
73         __iwl_write32(__FILE__, __LINE__, iwl, ofs, val)
74 #else
75 #define iwl_write32(iwl, ofs, val) _iwl_write32(iwl, ofs, val)
76 #endif
77
78 #define _iwl_read32(iwl, ofs) readl((iwl)->hw_base + (ofs))
79 #ifdef CONFIG_IWLWIFI_DEBUG
80 static inline u32 __iwl_read32(char *f, u32 l, struct iwl_priv *iwl, u32 ofs)
81 {
82         IWL_DEBUG_IO("read_direct32(0x%08X) - %s %d\n", ofs, f, l);
83         return _iwl_read32(iwl, ofs);
84 }
85 #define iwl_read32(iwl, ofs) __iwl_read32(__FILE__, __LINE__, iwl, ofs)
86 #else
87 #define iwl_read32(p, o) _iwl_read32(p, o)
88 #endif
89
90 static inline int _iwl_poll_bit(struct iwl_priv *priv, u32 addr,
91                                 u32 bits, u32 mask, int timeout)
92 {
93         int i = 0;
94
95         do {
96                 if ((_iwl_read32(priv, addr) & mask) == (bits & mask))
97                         return i;
98                 mdelay(10);
99                 i += 10;
100         } while (i < timeout);
101
102         return -ETIMEDOUT;
103 }
104 #ifdef CONFIG_IWLWIFI_DEBUG
105 static inline int __iwl_poll_bit(const char *f, u32 l,
106                                  struct iwl_priv *priv, u32 addr,
107                                  u32 bits, u32 mask, int timeout)
108 {
109         int rc = _iwl_poll_bit(priv, addr, bits, mask, timeout);
110         if (unlikely(rc == -ETIMEDOUT))
111                 IWL_DEBUG_IO
112                     ("poll_bit(0x%08X, 0x%08X, 0x%08X) - timedout - %s %d\n",
113                      addr, bits, mask, f, l);
114         else
115                 IWL_DEBUG_IO
116                     ("poll_bit(0x%08X, 0x%08X, 0x%08X) = 0x%08X - %s %d\n",
117                      addr, bits, mask, rc, f, l);
118         return rc;
119 }
120 #define iwl_poll_bit(iwl, addr, bits, mask, timeout) \
121         __iwl_poll_bit(__FILE__, __LINE__, iwl, addr, bits, mask, timeout)
122 #else
123 #define iwl_poll_bit(p, a, b, m, t) _iwl_poll_bit(p, a, b, m, t)
124 #endif
125
126 static inline void _iwl_set_bit(struct iwl_priv *priv, u32 reg, u32 mask)
127 {
128         _iwl_write32(priv, reg, _iwl_read32(priv, reg) | mask);
129 }
130 #ifdef CONFIG_IWLWIFI_DEBUG
131 static inline void __iwl_set_bit(const char *f, u32 l,
132                                  struct iwl_priv *priv, u32 reg, u32 mask)
133 {
134         u32 val = _iwl_read32(priv, reg) | mask;
135         IWL_DEBUG_IO("set_bit(0x%08X, 0x%08X) = 0x%08X\n", reg, mask, val);
136         _iwl_write32(priv, reg, val);
137 }
138 #define iwl_set_bit(p, r, m) __iwl_set_bit(__FILE__, __LINE__, p, r, m)
139 #else
140 #define iwl_set_bit(p, r, m) _iwl_set_bit(p, r, m)
141 #endif
142
143 static inline void _iwl_clear_bit(struct iwl_priv *priv, u32 reg, u32 mask)
144 {
145         _iwl_write32(priv, reg, _iwl_read32(priv, reg) & ~mask);
146 }
147 #ifdef CONFIG_IWLWIFI_DEBUG
148 static inline void __iwl_clear_bit(const char *f, u32 l,
149                                    struct iwl_priv *priv, u32 reg, u32 mask)
150 {
151         u32 val = _iwl_read32(priv, reg) & ~mask;
152         IWL_DEBUG_IO("clear_bit(0x%08X, 0x%08X) = 0x%08X\n", reg, mask, val);
153         _iwl_write32(priv, reg, val);
154 }
155 #define iwl_clear_bit(p, r, m) __iwl_clear_bit(__FILE__, __LINE__, p, r, m)
156 #else
157 #define iwl_clear_bit(p, r, m) _iwl_clear_bit(p, r, m)
158 #endif
159
160 static inline int _iwl_grab_restricted_access(struct iwl_priv *priv)
161 {
162         int rc;
163         u32 gp_ctl;
164
165 #ifdef CONFIG_IWLWIFI_DEBUG
166         if (atomic_read(&priv->restrict_refcnt))
167                 return 0;
168 #endif
169         if (test_bit(STATUS_RF_KILL_HW, &priv->status) ||
170             test_bit(STATUS_RF_KILL_SW, &priv->status)) {
171                 IWL_WARNING("WARNING: Requesting MAC access during RFKILL "
172                         "wakes up NIC\n");
173
174                 /* 10 msec allows time for NIC to complete its data save */
175                 gp_ctl = _iwl_read32(priv, CSR_GP_CNTRL);
176                 if (gp_ctl & CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY) {
177                         IWL_DEBUG_RF_KILL("Wait for complete power-down, "
178                                 "gpctl = 0x%08x\n", gp_ctl);
179                         mdelay(10);
180                 } else
181                         IWL_DEBUG_RF_KILL("power-down complete, "
182                                           "gpctl = 0x%08x\n", gp_ctl);
183         }
184
185         /* this bit wakes up the NIC */
186         _iwl_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
187         rc = _iwl_poll_bit(priv, CSR_GP_CNTRL,
188                            CSR_GP_CNTRL_REG_VAL_MAC_ACCESS_EN,
189                            (CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY |
190                             CSR_GP_CNTRL_REG_FLAG_GOING_TO_SLEEP), 50);
191         if (rc < 0) {
192                 IWL_ERROR("MAC is in deep sleep!\n");
193                 return -EIO;
194         }
195
196 #ifdef CONFIG_IWLWIFI_DEBUG
197         atomic_inc(&priv->restrict_refcnt);
198 #endif
199         return 0;
200 }
201
202 #ifdef CONFIG_IWLWIFI_DEBUG
203 static inline int __iwl_grab_restricted_access(const char *f, u32 l,
204                                                struct iwl_priv *priv)
205 {
206         if (atomic_read(&priv->restrict_refcnt))
207                 IWL_DEBUG_INFO("Grabbing access while already held at "
208                                "line %d.\n", l);
209
210         IWL_DEBUG_IO("grabbing restricted access - %s %d\n", f, l);
211
212         return _iwl_grab_restricted_access(priv);
213 }
214 #define iwl_grab_restricted_access(priv) \
215         __iwl_grab_restricted_access(__FILE__, __LINE__, priv)
216 #else
217 #define iwl_grab_restricted_access(priv) \
218         _iwl_grab_restricted_access(priv)
219 #endif
220
221 static inline void _iwl_release_restricted_access(struct iwl_priv *priv)
222 {
223 #ifdef CONFIG_IWLWIFI_DEBUG
224         if (atomic_dec_and_test(&priv->restrict_refcnt))
225 #endif
226                 _iwl_clear_bit(priv, CSR_GP_CNTRL,
227                                CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
228 }
229 #ifdef CONFIG_IWLWIFI_DEBUG
230 static inline void __iwl_release_restricted_access(const char *f, u32 l,
231                                                    struct iwl_priv *priv)
232 {
233         if (atomic_read(&priv->restrict_refcnt) <= 0)
234                 IWL_ERROR("Release unheld restricted access at line %d.\n", l);
235
236         IWL_DEBUG_IO("releasing restricted access - %s %d\n", f, l);
237         _iwl_release_restricted_access(priv);
238 }
239 #define iwl_release_restricted_access(priv) \
240         __iwl_release_restricted_access(__FILE__, __LINE__, priv)
241 #else
242 #define iwl_release_restricted_access(priv) \
243         _iwl_release_restricted_access(priv)
244 #endif
245
246 static inline u32 _iwl_read_restricted(struct iwl_priv *priv, u32 reg)
247 {
248         return _iwl_read32(priv, reg);
249 }
250 #ifdef CONFIG_IWLWIFI_DEBUG
251 static inline u32 __iwl_read_restricted(const char *f, u32 l,
252                                         struct iwl_priv *priv, u32 reg)
253 {
254         u32 value = _iwl_read_restricted(priv, reg);
255         if (!atomic_read(&priv->restrict_refcnt))
256                 IWL_ERROR("Unrestricted access from %s %d\n", f, l);
257         IWL_DEBUG_IO("read_restricted(0x%4X) = 0x%08x - %s %d \n", reg, value,
258                      f, l);
259         return value;
260 }
261 #define iwl_read_restricted(priv, reg) \
262         __iwl_read_restricted(__FILE__, __LINE__, priv, reg)
263 #else
264 #define iwl_read_restricted _iwl_read_restricted
265 #endif
266
267 static inline void _iwl_write_restricted(struct iwl_priv *priv,
268                                          u32 reg, u32 value)
269 {
270         _iwl_write32(priv, reg, value);
271 }
272 #ifdef CONFIG_IWLWIFI_DEBUG
273 static void __iwl_write_restricted(u32 line,
274                                    struct iwl_priv *priv, u32 reg, u32 value)
275 {
276         if (!atomic_read(&priv->restrict_refcnt))
277                 IWL_ERROR("Unrestricted access from line %d\n", line);
278         _iwl_write_restricted(priv, reg, value);
279 }
280 #define iwl_write_restricted(priv, reg, value) \
281         __iwl_write_restricted(__LINE__, priv, reg, value)
282 #else
283 #define iwl_write_restricted _iwl_write_restricted
284 #endif
285
286 static inline void iwl_write_buffer_restricted(struct iwl_priv *priv,
287                                                u32 reg, u32 len, u32 *values)
288 {
289         u32 count = sizeof(u32);
290
291         if ((priv != NULL) && (values != NULL)) {
292                 for (; 0 < len; len -= count, reg += count, values++)
293                         _iwl_write_restricted(priv, reg, *values);
294         }
295 }
296
297 static inline int _iwl_poll_restricted_bit(struct iwl_priv *priv,
298                                            u32 addr, u32 mask, int timeout)
299 {
300         int i = 0;
301
302         do {
303                 if ((_iwl_read_restricted(priv, addr) & mask) == mask)
304                         return i;
305                 mdelay(10);
306                 i += 10;
307         } while (i < timeout);
308
309         return -ETIMEDOUT;
310 }
311
312 #ifdef CONFIG_IWLWIFI_DEBUG
313 static inline int __iwl_poll_restricted_bit(const char *f, u32 l,
314                                             struct iwl_priv *priv,
315                                             u32 addr, u32 mask, int timeout)
316 {
317         int rc = _iwl_poll_restricted_bit(priv, addr, mask, timeout);
318
319         if (unlikely(rc == -ETIMEDOUT))
320                 IWL_DEBUG_IO("poll_restricted_bit(0x%08X, 0x%08X) - "
321                              "timedout - %s %d\n", addr, mask, f, l);
322         else
323                 IWL_DEBUG_IO("poll_restricted_bit(0x%08X, 0x%08X) = 0x%08X "
324                              "- %s %d\n", addr, mask, rc, f, l);
325         return rc;
326 }
327 #define iwl_poll_restricted_bit(iwl, addr, mask, timeout) \
328         __iwl_poll_restricted_bit(__FILE__, __LINE__, iwl, addr, mask, timeout)
329 #else
330 #define iwl_poll_restricted_bit _iwl_poll_restricted_bit
331 #endif
332
333 static inline u32 _iwl_read_restricted_reg(struct iwl_priv *priv, u32 reg)
334 {
335         _iwl_write_restricted(priv, HBUS_TARG_PRPH_RADDR, reg | (3 << 24));
336         return _iwl_read_restricted(priv, HBUS_TARG_PRPH_RDAT);
337 }
338 #ifdef CONFIG_IWLWIFI_DEBUG
339 static inline u32 __iwl_read_restricted_reg(u32 line,
340                                             struct iwl_priv *priv, u32 reg)
341 {
342         if (!atomic_read(&priv->restrict_refcnt))
343                 IWL_ERROR("Unrestricted access from line %d\n", line);
344         return _iwl_read_restricted_reg(priv, reg);
345 }
346
347 #define iwl_read_restricted_reg(priv, reg) \
348         __iwl_read_restricted_reg(__LINE__, priv, reg)
349 #else
350 #define iwl_read_restricted_reg _iwl_read_restricted_reg
351 #endif
352
353 static inline void _iwl_write_restricted_reg(struct iwl_priv *priv,
354                                              u32 addr, u32 val)
355 {
356         _iwl_write_restricted(priv, HBUS_TARG_PRPH_WADDR,
357                               ((addr & 0x0000FFFF) | (3 << 24)));
358         _iwl_write_restricted(priv, HBUS_TARG_PRPH_WDAT, val);
359 }
360 #ifdef CONFIG_IWLWIFI_DEBUG
361 static inline void __iwl_write_restricted_reg(u32 line,
362                                               struct iwl_priv *priv,
363                                               u32 addr, u32 val)
364 {
365         if (!atomic_read(&priv->restrict_refcnt))
366                 IWL_ERROR("Unrestricted access from line %d\n", line);
367         _iwl_write_restricted_reg(priv, addr, val);
368 }
369
370 #define iwl_write_restricted_reg(priv, addr, val) \
371         __iwl_write_restricted_reg(__LINE__, priv, addr, val);
372 #else
373 #define iwl_write_restricted_reg _iwl_write_restricted_reg
374 #endif
375
376 #define _iwl_set_bits_restricted_reg(priv, reg, mask) \
377         _iwl_write_restricted_reg(priv, reg, \
378                                   (_iwl_read_restricted_reg(priv, reg) | mask))
379 #ifdef CONFIG_IWLWIFI_DEBUG
380 static inline void __iwl_set_bits_restricted_reg(u32 line, struct iwl_priv
381                                                  *priv, u32 reg, u32 mask)
382 {
383         if (!atomic_read(&priv->restrict_refcnt))
384                 IWL_ERROR("Unrestricted access from line %d\n", line);
385         _iwl_set_bits_restricted_reg(priv, reg, mask);
386 }
387 #define iwl_set_bits_restricted_reg(priv, reg, mask) \
388         __iwl_set_bits_restricted_reg(__LINE__, priv, reg, mask)
389 #else
390 #define iwl_set_bits_restricted_reg _iwl_set_bits_restricted_reg
391 #endif
392
393 #define _iwl_set_bits_mask_restricted_reg(priv, reg, bits, mask) \
394         _iwl_write_restricted_reg( \
395             priv, reg, ((_iwl_read_restricted_reg(priv, reg) & mask) | bits))
396 #ifdef CONFIG_IWLWIFI_DEBUG
397 static inline void __iwl_set_bits_mask_restricted_reg(u32 line,
398                 struct iwl_priv *priv, u32 reg, u32 bits, u32 mask)
399 {
400         if (!atomic_read(&priv->restrict_refcnt))
401                 IWL_ERROR("Unrestricted access from line %d\n", line);
402         _iwl_set_bits_mask_restricted_reg(priv, reg, bits, mask);
403 }
404
405 #define iwl_set_bits_mask_restricted_reg(priv, reg, bits, mask) \
406         __iwl_set_bits_mask_restricted_reg(__LINE__, priv, reg, bits, mask)
407 #else
408 #define iwl_set_bits_mask_restricted_reg _iwl_set_bits_mask_restricted_reg
409 #endif
410
411 static inline void iwl_clear_bits_restricted_reg(struct iwl_priv
412                                                  *priv, u32 reg, u32 mask)
413 {
414         u32 val = _iwl_read_restricted_reg(priv, reg);
415         _iwl_write_restricted_reg(priv, reg, (val & ~mask));
416 }
417
418 static inline u32 iwl_read_restricted_mem(struct iwl_priv *priv, u32 addr)
419 {
420         iwl_write_restricted(priv, HBUS_TARG_MEM_RADDR, addr);
421         return iwl_read_restricted(priv, HBUS_TARG_MEM_RDAT);
422 }
423
424 static inline void iwl_write_restricted_mem(struct iwl_priv *priv, u32 addr,
425                                             u32 val)
426 {
427         iwl_write_restricted(priv, HBUS_TARG_MEM_WADDR, addr);
428         iwl_write_restricted(priv, HBUS_TARG_MEM_WDAT, val);
429 }
430
431 static inline void iwl_write_restricted_mems(struct iwl_priv *priv, u32 addr,
432                                              u32 len, u32 *values)
433 {
434         iwl_write_restricted(priv, HBUS_TARG_MEM_WADDR, addr);
435         for (; 0 < len; len -= sizeof(u32), values++)
436                 iwl_write_restricted(priv, HBUS_TARG_MEM_WDAT, *values);
437 }
438
439 static inline void iwl_write_restricted_regs(struct iwl_priv *priv, u32 reg,
440                                              u32 len, u8 *values)
441 {
442         u32 reg_offset = reg;
443         u32 aligment = reg & 0x3;
444
445         /* write any non-dword-aligned stuff at the beginning */
446         if (len < sizeof(u32)) {
447                 if ((aligment + len) <= sizeof(u32)) {
448                         u8 size;
449                         u32 value = 0;
450                         size = len - 1;
451                         memcpy(&value, values, len);
452                         reg_offset = (reg_offset & 0x0000FFFF);
453
454                         _iwl_write_restricted(priv,
455                                               HBUS_TARG_PRPH_WADDR,
456                                               (reg_offset | (size << 24)));
457                         _iwl_write_restricted(priv, HBUS_TARG_PRPH_WDAT,
458                                               value);
459                 }
460
461                 return;
462         }
463
464         /* now write all the dword-aligned stuff */
465         for (; reg_offset < (reg + len);
466              reg_offset += sizeof(u32), values += sizeof(u32))
467                 _iwl_write_restricted_reg(priv, reg_offset, *((u32 *) values));
468 }
469
470 #endif