blob: 0b94751146183f20d2eb3e5c3bc7e4c309fa843e [file] [log] [blame]
Zhu Yib481de92007-09-25 17:54:57 -07001/******************************************************************************
2 *
Reinette Chatreeb7ae892008-03-11 16:17:17 -07003 * Copyright(c) 2003 - 2008 Intel Corporation. All rights reserved.
Zhu Yib481de92007-09-25 17:54:57 -07004 *
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
Christoph Hellwigbb8c0932008-01-27 16:41:47 -080029#ifndef __iwl3945_io_h__
30#define __iwl3945_io_h__
Zhu Yib481de92007-09-25 17:54:57 -070031
32#include <linux/io.h>
33
Christoph Hellwig5d08cd12007-10-25 17:15:50 +080034#include "iwl-3945-debug.h"
Zhu Yib481de92007-09-25 17:54:57 -070035
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
Tomas Winklerac17a942007-10-25 17:15:37 +080045 * and the current line number is printed in addition to any other debug output.
Zhu Yib481de92007-09-25 17:54:57 -070046 *
47 * The non-prefixed name is the #define that maps the caller into a
48 * #define that provides the caller's __LINE__ to the double prefix version.
49 *
50 * If you wish to call the function without any debug or state checking,
51 * you should use the single _ prefix version (as is used by dependent IO
Christoph Hellwigbb8c0932008-01-27 16:41:47 -080052 * routines, for example _iwl3945_read_direct32 calls the non-check version of
53 * _iwl3945_read32.)
Zhu Yib481de92007-09-25 17:54:57 -070054 *
55 * These declarations are *extremely* useful in quickly isolating code deltas
56 * which result in misconfiguring of the hardware I/O. In combination with
57 * git-bisect and the IO debug level you can quickly determine the specific
58 * commit which breaks the IO sequence to the hardware.
59 *
60 */
61
Tomas Winkler5c1b0952008-02-13 11:32:30 -080062#define _iwl3945_write32(priv, ofs, val) writel((val), (priv)->hw_base + (ofs))
Christoph Hellwigc8b0e6e2007-10-25 17:15:51 +080063#ifdef CONFIG_IWL3945_DEBUG
Tomas Winkler5c1b0952008-02-13 11:32:30 -080064static inline void __iwl3945_write32(const char *f, u32 l, struct iwl3945_priv *priv,
Zhu Yib481de92007-09-25 17:54:57 -070065 u32 ofs, u32 val)
66{
Tomas Winklerac17a942007-10-25 17:15:37 +080067 IWL_DEBUG_IO("write32(0x%08X, 0x%08X) - %s %d\n", ofs, val, f, l);
Tomas Winkler5c1b0952008-02-13 11:32:30 -080068 _iwl3945_write32(priv, ofs, val);
Zhu Yib481de92007-09-25 17:54:57 -070069}
Tomas Winkler5c1b0952008-02-13 11:32:30 -080070#define iwl3945_write32(priv, ofs, val) \
71 __iwl3945_write32(__FILE__, __LINE__, priv, ofs, val)
Zhu Yib481de92007-09-25 17:54:57 -070072#else
Tomas Winkler5c1b0952008-02-13 11:32:30 -080073#define iwl3945_write32(priv, ofs, val) _iwl3945_write32(priv, ofs, val)
Zhu Yib481de92007-09-25 17:54:57 -070074#endif
75
Tomas Winkler5c1b0952008-02-13 11:32:30 -080076#define _iwl3945_read32(priv, ofs) readl((priv)->hw_base + (ofs))
Christoph Hellwigc8b0e6e2007-10-25 17:15:51 +080077#ifdef CONFIG_IWL3945_DEBUG
Tomas Winkler5c1b0952008-02-13 11:32:30 -080078static inline u32 __iwl3945_read32(char *f, u32 l, struct iwl3945_priv *priv, u32 ofs)
Zhu Yib481de92007-09-25 17:54:57 -070079{
80 IWL_DEBUG_IO("read_direct32(0x%08X) - %s %d\n", ofs, f, l);
Tomas Winkler5c1b0952008-02-13 11:32:30 -080081 return _iwl3945_read32(priv, ofs);
Zhu Yib481de92007-09-25 17:54:57 -070082}
Tomas Winkler5c1b0952008-02-13 11:32:30 -080083#define iwl3945_read32(priv, ofs) __iwl3945_read32(__FILE__, __LINE__, priv, ofs)
Zhu Yib481de92007-09-25 17:54:57 -070084#else
Christoph Hellwigbb8c0932008-01-27 16:41:47 -080085#define iwl3945_read32(p, o) _iwl3945_read32(p, o)
Zhu Yib481de92007-09-25 17:54:57 -070086#endif
87
Christoph Hellwigbb8c0932008-01-27 16:41:47 -080088static inline int _iwl3945_poll_bit(struct iwl3945_priv *priv, u32 addr,
Zhu Yib481de92007-09-25 17:54:57 -070089 u32 bits, u32 mask, int timeout)
90{
91 int i = 0;
92
93 do {
Christoph Hellwigbb8c0932008-01-27 16:41:47 -080094 if ((_iwl3945_read32(priv, addr) & mask) == (bits & mask))
Zhu Yib481de92007-09-25 17:54:57 -070095 return i;
96 mdelay(10);
97 i += 10;
98 } while (i < timeout);
99
100 return -ETIMEDOUT;
101}
Christoph Hellwigc8b0e6e2007-10-25 17:15:51 +0800102#ifdef CONFIG_IWL3945_DEBUG
Christoph Hellwigbb8c0932008-01-27 16:41:47 -0800103static inline int __iwl3945_poll_bit(const char *f, u32 l,
104 struct iwl3945_priv *priv, u32 addr,
Zhu Yib481de92007-09-25 17:54:57 -0700105 u32 bits, u32 mask, int timeout)
106{
Christoph Hellwigbb8c0932008-01-27 16:41:47 -0800107 int ret = _iwl3945_poll_bit(priv, addr, bits, mask, timeout);
Tomas Winkler5c1b0952008-02-13 11:32:30 -0800108 IWL_DEBUG_IO("poll_bit(0x%08X, 0x%08X, 0x%08X) - %s- %s %d\n",
109 addr, bits, mask,
110 unlikely(ret == -ETIMEDOUT)?"timeout":"", f, l);
Tomas Winklerac17a942007-10-25 17:15:37 +0800111 return ret;
Zhu Yib481de92007-09-25 17:54:57 -0700112}
Tomas Winkler5c1b0952008-02-13 11:32:30 -0800113#define iwl3945_poll_bit(priv, addr, bits, mask, timeout) \
114 __iwl3945_poll_bit(__FILE__, __LINE__, priv, addr, bits, mask, timeout)
Zhu Yib481de92007-09-25 17:54:57 -0700115#else
Christoph Hellwigbb8c0932008-01-27 16:41:47 -0800116#define iwl3945_poll_bit(p, a, b, m, t) _iwl3945_poll_bit(p, a, b, m, t)
Zhu Yib481de92007-09-25 17:54:57 -0700117#endif
118
Christoph Hellwigbb8c0932008-01-27 16:41:47 -0800119static inline void _iwl3945_set_bit(struct iwl3945_priv *priv, u32 reg, u32 mask)
Zhu Yib481de92007-09-25 17:54:57 -0700120{
Christoph Hellwigbb8c0932008-01-27 16:41:47 -0800121 _iwl3945_write32(priv, reg, _iwl3945_read32(priv, reg) | mask);
Zhu Yib481de92007-09-25 17:54:57 -0700122}
Christoph Hellwigc8b0e6e2007-10-25 17:15:51 +0800123#ifdef CONFIG_IWL3945_DEBUG
Christoph Hellwigbb8c0932008-01-27 16:41:47 -0800124static inline void __iwl3945_set_bit(const char *f, u32 l,
125 struct iwl3945_priv *priv, u32 reg, u32 mask)
Zhu Yib481de92007-09-25 17:54:57 -0700126{
Christoph Hellwigbb8c0932008-01-27 16:41:47 -0800127 u32 val = _iwl3945_read32(priv, reg) | mask;
Zhu Yib481de92007-09-25 17:54:57 -0700128 IWL_DEBUG_IO("set_bit(0x%08X, 0x%08X) = 0x%08X\n", reg, mask, val);
Christoph Hellwigbb8c0932008-01-27 16:41:47 -0800129 _iwl3945_write32(priv, reg, val);
Zhu Yib481de92007-09-25 17:54:57 -0700130}
Christoph Hellwigbb8c0932008-01-27 16:41:47 -0800131#define iwl3945_set_bit(p, r, m) __iwl3945_set_bit(__FILE__, __LINE__, p, r, m)
Zhu Yib481de92007-09-25 17:54:57 -0700132#else
Christoph Hellwigbb8c0932008-01-27 16:41:47 -0800133#define iwl3945_set_bit(p, r, m) _iwl3945_set_bit(p, r, m)
Zhu Yib481de92007-09-25 17:54:57 -0700134#endif
135
Christoph Hellwigbb8c0932008-01-27 16:41:47 -0800136static inline void _iwl3945_clear_bit(struct iwl3945_priv *priv, u32 reg, u32 mask)
Zhu Yib481de92007-09-25 17:54:57 -0700137{
Christoph Hellwigbb8c0932008-01-27 16:41:47 -0800138 _iwl3945_write32(priv, reg, _iwl3945_read32(priv, reg) & ~mask);
Zhu Yib481de92007-09-25 17:54:57 -0700139}
Christoph Hellwigc8b0e6e2007-10-25 17:15:51 +0800140#ifdef CONFIG_IWL3945_DEBUG
Christoph Hellwigbb8c0932008-01-27 16:41:47 -0800141static inline void __iwl3945_clear_bit(const char *f, u32 l,
142 struct iwl3945_priv *priv, u32 reg, u32 mask)
Zhu Yib481de92007-09-25 17:54:57 -0700143{
Christoph Hellwigbb8c0932008-01-27 16:41:47 -0800144 u32 val = _iwl3945_read32(priv, reg) & ~mask;
Zhu Yib481de92007-09-25 17:54:57 -0700145 IWL_DEBUG_IO("clear_bit(0x%08X, 0x%08X) = 0x%08X\n", reg, mask, val);
Christoph Hellwigbb8c0932008-01-27 16:41:47 -0800146 _iwl3945_write32(priv, reg, val);
Zhu Yib481de92007-09-25 17:54:57 -0700147}
Christoph Hellwigbb8c0932008-01-27 16:41:47 -0800148#define iwl3945_clear_bit(p, r, m) __iwl3945_clear_bit(__FILE__, __LINE__, p, r, m)
Zhu Yib481de92007-09-25 17:54:57 -0700149#else
Christoph Hellwigbb8c0932008-01-27 16:41:47 -0800150#define iwl3945_clear_bit(p, r, m) _iwl3945_clear_bit(p, r, m)
Zhu Yib481de92007-09-25 17:54:57 -0700151#endif
152
Christoph Hellwigbb8c0932008-01-27 16:41:47 -0800153static inline int _iwl3945_grab_nic_access(struct iwl3945_priv *priv)
Zhu Yib481de92007-09-25 17:54:57 -0700154{
Tomas Winklerac17a942007-10-25 17:15:37 +0800155 int ret;
Zhu Yib481de92007-09-25 17:54:57 -0700156 u32 gp_ctl;
157
Christoph Hellwigc8b0e6e2007-10-25 17:15:51 +0800158#ifdef CONFIG_IWL3945_DEBUG
Zhu Yib481de92007-09-25 17:54:57 -0700159 if (atomic_read(&priv->restrict_refcnt))
160 return 0;
161#endif
162 if (test_bit(STATUS_RF_KILL_HW, &priv->status) ||
163 test_bit(STATUS_RF_KILL_SW, &priv->status)) {
164 IWL_WARNING("WARNING: Requesting MAC access during RFKILL "
165 "wakes up NIC\n");
166
167 /* 10 msec allows time for NIC to complete its data save */
Christoph Hellwigbb8c0932008-01-27 16:41:47 -0800168 gp_ctl = _iwl3945_read32(priv, CSR_GP_CNTRL);
Zhu Yib481de92007-09-25 17:54:57 -0700169 if (gp_ctl & CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY) {
170 IWL_DEBUG_RF_KILL("Wait for complete power-down, "
171 "gpctl = 0x%08x\n", gp_ctl);
172 mdelay(10);
173 } else
174 IWL_DEBUG_RF_KILL("power-down complete, "
175 "gpctl = 0x%08x\n", gp_ctl);
176 }
177
178 /* this bit wakes up the NIC */
Christoph Hellwigbb8c0932008-01-27 16:41:47 -0800179 _iwl3945_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
180 ret = _iwl3945_poll_bit(priv, CSR_GP_CNTRL,
Zhu Yib481de92007-09-25 17:54:57 -0700181 CSR_GP_CNTRL_REG_VAL_MAC_ACCESS_EN,
182 (CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY |
183 CSR_GP_CNTRL_REG_FLAG_GOING_TO_SLEEP), 50);
Tomas Winklerac17a942007-10-25 17:15:37 +0800184 if (ret < 0) {
Zhu Yib481de92007-09-25 17:54:57 -0700185 IWL_ERROR("MAC is in deep sleep!\n");
186 return -EIO;
187 }
188
Christoph Hellwigc8b0e6e2007-10-25 17:15:51 +0800189#ifdef CONFIG_IWL3945_DEBUG
Zhu Yib481de92007-09-25 17:54:57 -0700190 atomic_inc(&priv->restrict_refcnt);
191#endif
192 return 0;
193}
194
Christoph Hellwigc8b0e6e2007-10-25 17:15:51 +0800195#ifdef CONFIG_IWL3945_DEBUG
Christoph Hellwigbb8c0932008-01-27 16:41:47 -0800196static inline int __iwl3945_grab_nic_access(const char *f, u32 l,
197 struct iwl3945_priv *priv)
Zhu Yib481de92007-09-25 17:54:57 -0700198{
199 if (atomic_read(&priv->restrict_refcnt))
200 IWL_DEBUG_INFO("Grabbing access while already held at "
201 "line %d.\n", l);
202
Tomas Winklerac17a942007-10-25 17:15:37 +0800203 IWL_DEBUG_IO("grabbing nic access - %s %d\n", f, l);
Christoph Hellwigbb8c0932008-01-27 16:41:47 -0800204 return _iwl3945_grab_nic_access(priv);
Zhu Yib481de92007-09-25 17:54:57 -0700205}
Christoph Hellwigbb8c0932008-01-27 16:41:47 -0800206#define iwl3945_grab_nic_access(priv) \
207 __iwl3945_grab_nic_access(__FILE__, __LINE__, priv)
Zhu Yib481de92007-09-25 17:54:57 -0700208#else
Christoph Hellwigbb8c0932008-01-27 16:41:47 -0800209#define iwl3945_grab_nic_access(priv) \
210 _iwl3945_grab_nic_access(priv)
Zhu Yib481de92007-09-25 17:54:57 -0700211#endif
212
Christoph Hellwigbb8c0932008-01-27 16:41:47 -0800213static inline void _iwl3945_release_nic_access(struct iwl3945_priv *priv)
Zhu Yib481de92007-09-25 17:54:57 -0700214{
Christoph Hellwigc8b0e6e2007-10-25 17:15:51 +0800215#ifdef CONFIG_IWL3945_DEBUG
Zhu Yib481de92007-09-25 17:54:57 -0700216 if (atomic_dec_and_test(&priv->restrict_refcnt))
217#endif
Christoph Hellwigbb8c0932008-01-27 16:41:47 -0800218 _iwl3945_clear_bit(priv, CSR_GP_CNTRL,
Zhu Yib481de92007-09-25 17:54:57 -0700219 CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
220}
Christoph Hellwigc8b0e6e2007-10-25 17:15:51 +0800221#ifdef CONFIG_IWL3945_DEBUG
Christoph Hellwigbb8c0932008-01-27 16:41:47 -0800222static inline void __iwl3945_release_nic_access(const char *f, u32 l,
223 struct iwl3945_priv *priv)
Zhu Yib481de92007-09-25 17:54:57 -0700224{
225 if (atomic_read(&priv->restrict_refcnt) <= 0)
Tomas Winklerac17a942007-10-25 17:15:37 +0800226 IWL_ERROR("Release unheld nic access at line %d.\n", l);
Zhu Yib481de92007-09-25 17:54:57 -0700227
Tomas Winklerac17a942007-10-25 17:15:37 +0800228 IWL_DEBUG_IO("releasing nic access - %s %d\n", f, l);
Christoph Hellwigbb8c0932008-01-27 16:41:47 -0800229 _iwl3945_release_nic_access(priv);
Zhu Yib481de92007-09-25 17:54:57 -0700230}
Christoph Hellwigbb8c0932008-01-27 16:41:47 -0800231#define iwl3945_release_nic_access(priv) \
232 __iwl3945_release_nic_access(__FILE__, __LINE__, priv)
Zhu Yib481de92007-09-25 17:54:57 -0700233#else
Christoph Hellwigbb8c0932008-01-27 16:41:47 -0800234#define iwl3945_release_nic_access(priv) \
235 _iwl3945_release_nic_access(priv)
Zhu Yib481de92007-09-25 17:54:57 -0700236#endif
237
Christoph Hellwigbb8c0932008-01-27 16:41:47 -0800238static inline u32 _iwl3945_read_direct32(struct iwl3945_priv *priv, u32 reg)
Zhu Yib481de92007-09-25 17:54:57 -0700239{
Christoph Hellwigbb8c0932008-01-27 16:41:47 -0800240 return _iwl3945_read32(priv, reg);
Zhu Yib481de92007-09-25 17:54:57 -0700241}
Christoph Hellwigc8b0e6e2007-10-25 17:15:51 +0800242#ifdef CONFIG_IWL3945_DEBUG
Christoph Hellwigbb8c0932008-01-27 16:41:47 -0800243static inline u32 __iwl3945_read_direct32(const char *f, u32 l,
244 struct iwl3945_priv *priv, u32 reg)
Zhu Yib481de92007-09-25 17:54:57 -0700245{
Christoph Hellwigbb8c0932008-01-27 16:41:47 -0800246 u32 value = _iwl3945_read_direct32(priv, reg);
Zhu Yib481de92007-09-25 17:54:57 -0700247 if (!atomic_read(&priv->restrict_refcnt))
Tomas Winklerac17a942007-10-25 17:15:37 +0800248 IWL_ERROR("Nic access not held from %s %d\n", f, l);
249 IWL_DEBUG_IO("read_direct32(0x%4X) = 0x%08x - %s %d \n", reg, value,
Zhu Yib481de92007-09-25 17:54:57 -0700250 f, l);
251 return value;
252}
Christoph Hellwigbb8c0932008-01-27 16:41:47 -0800253#define iwl3945_read_direct32(priv, reg) \
254 __iwl3945_read_direct32(__FILE__, __LINE__, priv, reg)
Zhu Yib481de92007-09-25 17:54:57 -0700255#else
Christoph Hellwigbb8c0932008-01-27 16:41:47 -0800256#define iwl3945_read_direct32 _iwl3945_read_direct32
Zhu Yib481de92007-09-25 17:54:57 -0700257#endif
258
Christoph Hellwigbb8c0932008-01-27 16:41:47 -0800259static inline void _iwl3945_write_direct32(struct iwl3945_priv *priv,
Zhu Yib481de92007-09-25 17:54:57 -0700260 u32 reg, u32 value)
261{
Christoph Hellwigbb8c0932008-01-27 16:41:47 -0800262 _iwl3945_write32(priv, reg, value);
Zhu Yib481de92007-09-25 17:54:57 -0700263}
Christoph Hellwigc8b0e6e2007-10-25 17:15:51 +0800264#ifdef CONFIG_IWL3945_DEBUG
Christoph Hellwigbb8c0932008-01-27 16:41:47 -0800265static void __iwl3945_write_direct32(u32 line,
266 struct iwl3945_priv *priv, u32 reg, u32 value)
Zhu Yib481de92007-09-25 17:54:57 -0700267{
268 if (!atomic_read(&priv->restrict_refcnt))
Tomas Winklerac17a942007-10-25 17:15:37 +0800269 IWL_ERROR("Nic access not held from line %d\n", line);
Christoph Hellwigbb8c0932008-01-27 16:41:47 -0800270 _iwl3945_write_direct32(priv, reg, value);
Zhu Yib481de92007-09-25 17:54:57 -0700271}
Christoph Hellwigbb8c0932008-01-27 16:41:47 -0800272#define iwl3945_write_direct32(priv, reg, value) \
273 __iwl3945_write_direct32(__LINE__, priv, reg, value)
Zhu Yib481de92007-09-25 17:54:57 -0700274#else
Christoph Hellwigbb8c0932008-01-27 16:41:47 -0800275#define iwl3945_write_direct32 _iwl3945_write_direct32
Zhu Yib481de92007-09-25 17:54:57 -0700276#endif
277
Christoph Hellwigbb8c0932008-01-27 16:41:47 -0800278static inline void iwl3945_write_reg_buf(struct iwl3945_priv *priv,
Zhu Yib481de92007-09-25 17:54:57 -0700279 u32 reg, u32 len, u32 *values)
280{
281 u32 count = sizeof(u32);
282
283 if ((priv != NULL) && (values != NULL)) {
284 for (; 0 < len; len -= count, reg += count, values++)
Christoph Hellwigbb8c0932008-01-27 16:41:47 -0800285 _iwl3945_write_direct32(priv, reg, *values);
Zhu Yib481de92007-09-25 17:54:57 -0700286 }
287}
288
Christoph Hellwigbb8c0932008-01-27 16:41:47 -0800289static inline int _iwl3945_poll_direct_bit(struct iwl3945_priv *priv,
Zhu Yib481de92007-09-25 17:54:57 -0700290 u32 addr, u32 mask, int timeout)
291{
292 int i = 0;
293
294 do {
Christoph Hellwigbb8c0932008-01-27 16:41:47 -0800295 if ((_iwl3945_read_direct32(priv, addr) & mask) == mask)
Zhu Yib481de92007-09-25 17:54:57 -0700296 return i;
297 mdelay(10);
298 i += 10;
299 } while (i < timeout);
300
301 return -ETIMEDOUT;
302}
303
Christoph Hellwigc8b0e6e2007-10-25 17:15:51 +0800304#ifdef CONFIG_IWL3945_DEBUG
Christoph Hellwigbb8c0932008-01-27 16:41:47 -0800305static inline int __iwl3945_poll_direct_bit(const char *f, u32 l,
306 struct iwl3945_priv *priv,
Zhu Yib481de92007-09-25 17:54:57 -0700307 u32 addr, u32 mask, int timeout)
308{
Christoph Hellwigbb8c0932008-01-27 16:41:47 -0800309 int ret = _iwl3945_poll_direct_bit(priv, addr, mask, timeout);
Zhu Yib481de92007-09-25 17:54:57 -0700310
Tomas Winklerac17a942007-10-25 17:15:37 +0800311 if (unlikely(ret == -ETIMEDOUT))
312 IWL_DEBUG_IO("poll_direct_bit(0x%08X, 0x%08X) - "
Zhu Yib481de92007-09-25 17:54:57 -0700313 "timedout - %s %d\n", addr, mask, f, l);
314 else
Tomas Winklerac17a942007-10-25 17:15:37 +0800315 IWL_DEBUG_IO("poll_direct_bit(0x%08X, 0x%08X) = 0x%08X "
316 "- %s %d\n", addr, mask, ret, f, l);
317 return ret;
Zhu Yib481de92007-09-25 17:54:57 -0700318}
Tomas Winkler5c1b0952008-02-13 11:32:30 -0800319#define iwl3945_poll_direct_bit(priv, addr, mask, timeout) \
320 __iwl3945_poll_direct_bit(__FILE__, __LINE__, priv, addr, mask, timeout)
Zhu Yib481de92007-09-25 17:54:57 -0700321#else
Christoph Hellwigbb8c0932008-01-27 16:41:47 -0800322#define iwl3945_poll_direct_bit _iwl3945_poll_direct_bit
Zhu Yib481de92007-09-25 17:54:57 -0700323#endif
324
Christoph Hellwigbb8c0932008-01-27 16:41:47 -0800325static inline u32 _iwl3945_read_prph(struct iwl3945_priv *priv, u32 reg)
Zhu Yib481de92007-09-25 17:54:57 -0700326{
Christoph Hellwigbb8c0932008-01-27 16:41:47 -0800327 _iwl3945_write_direct32(priv, HBUS_TARG_PRPH_RADDR, reg | (3 << 24));
328 return _iwl3945_read_direct32(priv, HBUS_TARG_PRPH_RDAT);
Zhu Yib481de92007-09-25 17:54:57 -0700329}
Christoph Hellwigc8b0e6e2007-10-25 17:15:51 +0800330#ifdef CONFIG_IWL3945_DEBUG
Christoph Hellwigbb8c0932008-01-27 16:41:47 -0800331static inline u32 __iwl3945_read_prph(u32 line, struct iwl3945_priv *priv, u32 reg)
Zhu Yib481de92007-09-25 17:54:57 -0700332{
333 if (!atomic_read(&priv->restrict_refcnt))
Tomas Winklerac17a942007-10-25 17:15:37 +0800334 IWL_ERROR("Nic access not held from line %d\n", line);
Christoph Hellwigbb8c0932008-01-27 16:41:47 -0800335 return _iwl3945_read_prph(priv, reg);
Zhu Yib481de92007-09-25 17:54:57 -0700336}
337
Christoph Hellwigbb8c0932008-01-27 16:41:47 -0800338#define iwl3945_read_prph(priv, reg) \
339 __iwl3945_read_prph(__LINE__, priv, reg)
Zhu Yib481de92007-09-25 17:54:57 -0700340#else
Christoph Hellwigbb8c0932008-01-27 16:41:47 -0800341#define iwl3945_read_prph _iwl3945_read_prph
Zhu Yib481de92007-09-25 17:54:57 -0700342#endif
343
Christoph Hellwigbb8c0932008-01-27 16:41:47 -0800344static inline void _iwl3945_write_prph(struct iwl3945_priv *priv,
Zhu Yib481de92007-09-25 17:54:57 -0700345 u32 addr, u32 val)
346{
Christoph Hellwigbb8c0932008-01-27 16:41:47 -0800347 _iwl3945_write_direct32(priv, HBUS_TARG_PRPH_WADDR,
Zhu Yib481de92007-09-25 17:54:57 -0700348 ((addr & 0x0000FFFF) | (3 << 24)));
Christoph Hellwigbb8c0932008-01-27 16:41:47 -0800349 _iwl3945_write_direct32(priv, HBUS_TARG_PRPH_WDAT, val);
Zhu Yib481de92007-09-25 17:54:57 -0700350}
Christoph Hellwigc8b0e6e2007-10-25 17:15:51 +0800351#ifdef CONFIG_IWL3945_DEBUG
Christoph Hellwigbb8c0932008-01-27 16:41:47 -0800352static inline void __iwl3945_write_prph(u32 line, struct iwl3945_priv *priv,
Zhu Yib481de92007-09-25 17:54:57 -0700353 u32 addr, u32 val)
354{
355 if (!atomic_read(&priv->restrict_refcnt))
Tomas Winklerac17a942007-10-25 17:15:37 +0800356 IWL_ERROR("Nic access from line %d\n", line);
Christoph Hellwigbb8c0932008-01-27 16:41:47 -0800357 _iwl3945_write_prph(priv, addr, val);
Zhu Yib481de92007-09-25 17:54:57 -0700358}
359
Christoph Hellwigbb8c0932008-01-27 16:41:47 -0800360#define iwl3945_write_prph(priv, addr, val) \
361 __iwl3945_write_prph(__LINE__, priv, addr, val);
Zhu Yib481de92007-09-25 17:54:57 -0700362#else
Christoph Hellwigbb8c0932008-01-27 16:41:47 -0800363#define iwl3945_write_prph _iwl3945_write_prph
Zhu Yib481de92007-09-25 17:54:57 -0700364#endif
365
Christoph Hellwigbb8c0932008-01-27 16:41:47 -0800366#define _iwl3945_set_bits_prph(priv, reg, mask) \
367 _iwl3945_write_prph(priv, reg, (_iwl3945_read_prph(priv, reg) | mask))
Christoph Hellwigc8b0e6e2007-10-25 17:15:51 +0800368#ifdef CONFIG_IWL3945_DEBUG
Christoph Hellwigbb8c0932008-01-27 16:41:47 -0800369static inline void __iwl3945_set_bits_prph(u32 line, struct iwl3945_priv *priv,
Tomas Winklerd8609652007-10-25 17:15:35 +0800370 u32 reg, u32 mask)
Zhu Yib481de92007-09-25 17:54:57 -0700371{
372 if (!atomic_read(&priv->restrict_refcnt))
Tomas Winklerac17a942007-10-25 17:15:37 +0800373 IWL_ERROR("Nic access not held from line %d\n", line);
374
Christoph Hellwigbb8c0932008-01-27 16:41:47 -0800375 _iwl3945_set_bits_prph(priv, reg, mask);
Zhu Yib481de92007-09-25 17:54:57 -0700376}
Christoph Hellwigbb8c0932008-01-27 16:41:47 -0800377#define iwl3945_set_bits_prph(priv, reg, mask) \
378 __iwl3945_set_bits_prph(__LINE__, priv, reg, mask)
Zhu Yib481de92007-09-25 17:54:57 -0700379#else
Christoph Hellwigbb8c0932008-01-27 16:41:47 -0800380#define iwl3945_set_bits_prph _iwl3945_set_bits_prph
Zhu Yib481de92007-09-25 17:54:57 -0700381#endif
382
Christoph Hellwigbb8c0932008-01-27 16:41:47 -0800383#define _iwl3945_set_bits_mask_prph(priv, reg, bits, mask) \
384 _iwl3945_write_prph(priv, reg, ((_iwl3945_read_prph(priv, reg) & mask) | bits))
Tomas Winklerd8609652007-10-25 17:15:35 +0800385
Christoph Hellwigc8b0e6e2007-10-25 17:15:51 +0800386#ifdef CONFIG_IWL3945_DEBUG
Christoph Hellwigbb8c0932008-01-27 16:41:47 -0800387static inline void __iwl3945_set_bits_mask_prph(u32 line,
388 struct iwl3945_priv *priv, u32 reg, u32 bits, u32 mask)
Zhu Yib481de92007-09-25 17:54:57 -0700389{
390 if (!atomic_read(&priv->restrict_refcnt))
Tomas Winklerac17a942007-10-25 17:15:37 +0800391 IWL_ERROR("Nic access not held from line %d\n", line);
Christoph Hellwigbb8c0932008-01-27 16:41:47 -0800392 _iwl3945_set_bits_mask_prph(priv, reg, bits, mask);
Zhu Yib481de92007-09-25 17:54:57 -0700393}
Christoph Hellwigbb8c0932008-01-27 16:41:47 -0800394#define iwl3945_set_bits_mask_prph(priv, reg, bits, mask) \
395 __iwl3945_set_bits_mask_prph(__LINE__, priv, reg, bits, mask)
Zhu Yib481de92007-09-25 17:54:57 -0700396#else
Christoph Hellwigbb8c0932008-01-27 16:41:47 -0800397#define iwl3945_set_bits_mask_prph _iwl3945_set_bits_mask_prph
Zhu Yib481de92007-09-25 17:54:57 -0700398#endif
399
Christoph Hellwigbb8c0932008-01-27 16:41:47 -0800400static inline void iwl3945_clear_bits_prph(struct iwl3945_priv
Zhu Yib481de92007-09-25 17:54:57 -0700401 *priv, u32 reg, u32 mask)
402{
Christoph Hellwigbb8c0932008-01-27 16:41:47 -0800403 u32 val = _iwl3945_read_prph(priv, reg);
404 _iwl3945_write_prph(priv, reg, (val & ~mask));
Zhu Yib481de92007-09-25 17:54:57 -0700405}
406
Christoph Hellwigbb8c0932008-01-27 16:41:47 -0800407static inline u32 iwl3945_read_targ_mem(struct iwl3945_priv *priv, u32 addr)
Zhu Yib481de92007-09-25 17:54:57 -0700408{
Christoph Hellwigbb8c0932008-01-27 16:41:47 -0800409 iwl3945_write_direct32(priv, HBUS_TARG_MEM_RADDR, addr);
410 return iwl3945_read_direct32(priv, HBUS_TARG_MEM_RDAT);
Zhu Yib481de92007-09-25 17:54:57 -0700411}
412
Christoph Hellwigbb8c0932008-01-27 16:41:47 -0800413static inline void iwl3945_write_targ_mem(struct iwl3945_priv *priv, u32 addr, u32 val)
Zhu Yib481de92007-09-25 17:54:57 -0700414{
Christoph Hellwigbb8c0932008-01-27 16:41:47 -0800415 iwl3945_write_direct32(priv, HBUS_TARG_MEM_WADDR, addr);
416 iwl3945_write_direct32(priv, HBUS_TARG_MEM_WDAT, val);
Zhu Yib481de92007-09-25 17:54:57 -0700417}
418
Christoph Hellwigbb8c0932008-01-27 16:41:47 -0800419static inline void iwl3945_write_targ_mem_buf(struct iwl3945_priv *priv, u32 addr,
Tomas Winkleraf7cca22007-10-25 17:15:36 +0800420 u32 len, u32 *values)
Zhu Yib481de92007-09-25 17:54:57 -0700421{
Christoph Hellwigbb8c0932008-01-27 16:41:47 -0800422 iwl3945_write_direct32(priv, HBUS_TARG_MEM_WADDR, addr);
Zhu Yib481de92007-09-25 17:54:57 -0700423 for (; 0 < len; len -= sizeof(u32), values++)
Christoph Hellwigbb8c0932008-01-27 16:41:47 -0800424 iwl3945_write_direct32(priv, HBUS_TARG_MEM_WDAT, *values);
Zhu Yib481de92007-09-25 17:54:57 -0700425}
Zhu Yib481de92007-09-25 17:54:57 -0700426#endif