blob: ebeb6e2aa6e7d5ea1ca596539d57d4ac6526a470 [file] [log] [blame]
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001/******************************************************************************
2 *
3 * Copyright(c) 2003 - 2011 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 * Intel Linux Wireless <ilw@linux.intel.com>
25 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
26 *
27 *****************************************************************************/
28
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +020029#ifndef __il_io_h__
30#define __il_io_h__
Wey-Yi Guybe663ab2011-02-21 11:27:26 -080031
32#include <linux/io.h>
33
34#include "iwl-dev.h"
35#include "iwl-debug.h"
Wey-Yi Guybe663ab2011-02-21 11:27:26 -080036
37/*
38 * IO, register, and NIC memory access functions
39 *
40 * NOTE on naming convention and macro usage for these
41 *
42 * A single _ prefix before a an access function means that no state
43 * check or debug information is printed when that function is called.
44 *
45 * A double __ prefix before an access function means that state is checked
46 * and the current line number and caller function name are printed in addition
47 * to any other debug output.
48 *
49 * The non-prefixed name is the #define that maps the caller into a
50 * #define that provides the caller's name and __LINE__ to the double
51 * prefix version.
52 *
53 * If you wish to call the function without any debug or state checking,
54 * you should use the single _ prefix version (as is used by dependent IO
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +020055 * routines, for example _il_read_direct32 calls the non-check version of
56 * _il_read32.)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -080057 *
58 * These declarations are *extremely* useful in quickly isolating code deltas
59 * which result in misconfiguration of the hardware I/O. In combination with
60 * git-bisect and the IO debug level you can quickly determine the specific
61 * commit which breaks the IO sequence to the hardware.
62 *
63 */
64
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +020065static inline void _il_write8(struct il_priv *priv, u32 ofs, u8 val)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -080066{
Wey-Yi Guybe663ab2011-02-21 11:27:26 -080067 iowrite8(val, priv->hw_base + ofs);
68}
69
70#ifdef CONFIG_IWLWIFI_LEGACY_DEBUG
71static inline void
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +020072__il_write8(const char *f, u32 l, struct il_priv *priv,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -080073 u32 ofs, u8 val)
74{
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +020075 IL_DEBUG_IO(priv, "write8(0x%08X, 0x%02X) - %s %d\n", ofs, val, f, l);
76 _il_write8(priv, ofs, val);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -080077}
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +020078#define il_write8(priv, ofs, val) \
79 __il_write8(__FILE__, __LINE__, priv, ofs, val)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -080080#else
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +020081#define il_write8(priv, ofs, val) _il_write8(priv, ofs, val)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -080082#endif
83
84
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +020085static inline void _il_write32(struct il_priv *priv, u32 ofs, u32 val)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -080086{
Wey-Yi Guybe663ab2011-02-21 11:27:26 -080087 iowrite32(val, priv->hw_base + ofs);
88}
89
90#ifdef CONFIG_IWLWIFI_LEGACY_DEBUG
91static inline void
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +020092__il_write32(const char *f, u32 l, struct il_priv *priv,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -080093 u32 ofs, u32 val)
94{
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +020095 IL_DEBUG_IO(priv, "write32(0x%08X, 0x%08X) - %s %d\n", ofs, val, f, l);
96 _il_write32(priv, ofs, val);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -080097}
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +020098#define il_write32(priv, ofs, val) \
99 __il_write32(__FILE__, __LINE__, priv, ofs, val)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800100#else
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200101#define il_write32(priv, ofs, val) _il_write32(priv, ofs, val)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800102#endif
103
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200104static inline u32 _il_read32(struct il_priv *priv, u32 ofs)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800105{
106 u32 val = ioread32(priv->hw_base + ofs);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800107 return val;
108}
109
110#ifdef CONFIG_IWLWIFI_LEGACY_DEBUG
111static inline u32
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200112__il_read32(char *f, u32 l, struct il_priv *priv, u32 ofs)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800113{
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200114 IL_DEBUG_IO(priv, "read_direct32(0x%08X) - %s %d\n", ofs, f, l);
115 return _il_read32(priv, ofs);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800116}
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200117#define il_read32(priv, ofs) __il_read32(__FILE__, __LINE__, priv, ofs)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800118#else
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200119#define il_read32(p, o) _il_read32(p, o)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800120#endif
121
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200122#define IL_POLL_INTERVAL 10 /* microseconds */
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800123static inline int
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200124_il_poll_bit(struct il_priv *priv, u32 addr,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800125 u32 bits, u32 mask, int timeout)
126{
127 int t = 0;
128
129 do {
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200130 if ((_il_read32(priv, addr) & mask) == (bits & mask))
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800131 return t;
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200132 udelay(IL_POLL_INTERVAL);
133 t += IL_POLL_INTERVAL;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800134 } while (t < timeout);
135
136 return -ETIMEDOUT;
137}
138#ifdef CONFIG_IWLWIFI_LEGACY_DEBUG
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200139static inline int __il_poll_bit(const char *f, u32 l,
140 struct il_priv *priv, u32 addr,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800141 u32 bits, u32 mask, int timeout)
142{
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200143 int ret = _il_poll_bit(priv, addr, bits, mask, timeout);
144 IL_DEBUG_IO(priv, "poll_bit(0x%08X, 0x%08X, 0x%08X) - %s- %s %d\n",
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800145 addr, bits, mask,
146 unlikely(ret == -ETIMEDOUT) ? "timeout" : "", f, l);
147 return ret;
148}
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200149#define il_poll_bit(priv, addr, bits, mask, timeout) \
150 __il_poll_bit(__FILE__, __LINE__, priv, addr, \
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800151 bits, mask, timeout)
152#else
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200153#define il_poll_bit(p, a, b, m, t) _il_poll_bit(p, a, b, m, t)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800154#endif
155
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200156static inline void _il_set_bit(struct il_priv *priv, u32 reg, u32 mask)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800157{
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200158 _il_write32(priv, reg, _il_read32(priv, reg) | mask);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800159}
160#ifdef CONFIG_IWLWIFI_LEGACY_DEBUG
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200161static inline void __il_set_bit(const char *f, u32 l,
162 struct il_priv *priv, u32 reg, u32 mask)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800163{
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200164 u32 val = _il_read32(priv, reg) | mask;
165 IL_DEBUG_IO(priv, "set_bit(0x%08X, 0x%08X) = 0x%08X\n", reg,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800166 mask, val);
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200167 _il_write32(priv, reg, val);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800168}
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200169static inline void il_set_bit(struct il_priv *p, u32 r, u32 m)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800170{
171 unsigned long reg_flags;
172
173 spin_lock_irqsave(&p->reg_lock, reg_flags);
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200174 __il_set_bit(__FILE__, __LINE__, p, r, m);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800175 spin_unlock_irqrestore(&p->reg_lock, reg_flags);
176}
177#else
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200178static inline void il_set_bit(struct il_priv *p, u32 r, u32 m)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800179{
180 unsigned long reg_flags;
181
182 spin_lock_irqsave(&p->reg_lock, reg_flags);
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200183 _il_set_bit(p, r, m);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800184 spin_unlock_irqrestore(&p->reg_lock, reg_flags);
185}
186#endif
187
188static inline void
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200189_il_clear_bit(struct il_priv *priv, u32 reg, u32 mask)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800190{
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200191 _il_write32(priv, reg, _il_read32(priv, reg) & ~mask);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800192}
193#ifdef CONFIG_IWLWIFI_LEGACY_DEBUG
194static inline void
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200195__il_clear_bit(const char *f, u32 l,
196 struct il_priv *priv, u32 reg, u32 mask)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800197{
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200198 u32 val = _il_read32(priv, reg) & ~mask;
199 IL_DEBUG_IO(priv, "clear_bit(0x%08X, 0x%08X) = 0x%08X\n", reg, mask, val);
200 _il_write32(priv, reg, val);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800201}
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200202static inline void il_clear_bit(struct il_priv *p, u32 r, u32 m)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800203{
204 unsigned long reg_flags;
205
206 spin_lock_irqsave(&p->reg_lock, reg_flags);
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200207 __il_clear_bit(__FILE__, __LINE__, p, r, m);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800208 spin_unlock_irqrestore(&p->reg_lock, reg_flags);
209}
210#else
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200211static inline void il_clear_bit(struct il_priv *p, u32 r, u32 m)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800212{
213 unsigned long reg_flags;
214
215 spin_lock_irqsave(&p->reg_lock, reg_flags);
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200216 _il_clear_bit(p, r, m);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800217 spin_unlock_irqrestore(&p->reg_lock, reg_flags);
218}
219#endif
220
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200221static inline int _il_grab_nic_access(struct il_priv *priv)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800222{
223 int ret;
224 u32 val;
225
226 /* this bit wakes up the NIC */
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200227 _il_set_bit(priv, CSR_GP_CNTRL,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800228 CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
229
230 /*
231 * These bits say the device is running, and should keep running for
232 * at least a short while (at least as long as MAC_ACCESS_REQ stays 1),
233 * but they do not indicate that embedded SRAM is restored yet;
234 * 3945 and 4965 have volatile SRAM, and must save/restore contents
235 * to/from host DRAM when sleeping/waking for power-saving.
236 * Each direction takes approximately 1/4 millisecond; with this
237 * overhead, it's a good idea to grab and hold MAC_ACCESS_REQUEST if a
238 * series of register accesses are expected (e.g. reading Event Log),
239 * to keep device from sleeping.
240 *
241 * CSR_UCODE_DRV_GP1 register bit MAC_SLEEP == 0 indicates that
242 * SRAM is okay/restored. We don't check that here because this call
243 * is just for hardware register access; but GP1 MAC_SLEEP check is a
244 * good idea before accessing 3945/4965 SRAM (e.g. reading Event Log).
245 *
246 */
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200247 ret = _il_poll_bit(priv, CSR_GP_CNTRL,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800248 CSR_GP_CNTRL_REG_VAL_MAC_ACCESS_EN,
249 (CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY |
250 CSR_GP_CNTRL_REG_FLAG_GOING_TO_SLEEP), 15000);
251 if (ret < 0) {
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200252 val = _il_read32(priv, CSR_GP_CNTRL);
253 IL_ERR(priv,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800254 "MAC is in deep sleep!. CSR_GP_CNTRL = 0x%08X\n", val);
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200255 _il_write32(priv, CSR_RESET,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800256 CSR_RESET_REG_FLAG_FORCE_NMI);
257 return -EIO;
258 }
259
260 return 0;
261}
262
263#ifdef CONFIG_IWLWIFI_LEGACY_DEBUG
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200264static inline int __il_grab_nic_access(const char *f, u32 l,
265 struct il_priv *priv)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800266{
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200267 IL_DEBUG_IO(priv, "grabbing nic access - %s %d\n", f, l);
268 return _il_grab_nic_access(priv);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800269}
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200270#define il_grab_nic_access(priv) \
271 __il_grab_nic_access(__FILE__, __LINE__, priv)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800272#else
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200273#define il_grab_nic_access(priv) \
274 _il_grab_nic_access(priv)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800275#endif
276
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200277static inline void _il_release_nic_access(struct il_priv *priv)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800278{
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200279 _il_clear_bit(priv, CSR_GP_CNTRL,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800280 CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
281}
282#ifdef CONFIG_IWLWIFI_LEGACY_DEBUG
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200283static inline void __il_release_nic_access(const char *f, u32 l,
284 struct il_priv *priv)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800285{
286
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200287 IL_DEBUG_IO(priv, "releasing nic access - %s %d\n", f, l);
288 _il_release_nic_access(priv);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800289}
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200290#define il_release_nic_access(priv) \
291 __il_release_nic_access(__FILE__, __LINE__, priv)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800292#else
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200293#define il_release_nic_access(priv) \
294 _il_release_nic_access(priv)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800295#endif
296
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200297static inline u32 _il_read_direct32(struct il_priv *priv, u32 reg)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800298{
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200299 return _il_read32(priv, reg);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800300}
301#ifdef CONFIG_IWLWIFI_LEGACY_DEBUG
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200302static inline u32 __il_read_direct32(const char *f, u32 l,
303 struct il_priv *priv, u32 reg)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800304{
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200305 u32 value = _il_read_direct32(priv, reg);
306 IL_DEBUG_IO(priv,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800307 "read_direct32(0x%4X) = 0x%08x - %s %d\n", reg, value,
308 f, l);
309 return value;
310}
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200311static inline u32 il_read_direct32(struct il_priv *priv, u32 reg)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800312{
313 u32 value;
314 unsigned long reg_flags;
315
316 spin_lock_irqsave(&priv->reg_lock, reg_flags);
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200317 il_grab_nic_access(priv);
318 value = __il_read_direct32(__FILE__, __LINE__, priv, reg);
319 il_release_nic_access(priv);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800320 spin_unlock_irqrestore(&priv->reg_lock, reg_flags);
321 return value;
322}
323
324#else
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200325static inline u32 il_read_direct32(struct il_priv *priv, u32 reg)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800326{
327 u32 value;
328 unsigned long reg_flags;
329
330 spin_lock_irqsave(&priv->reg_lock, reg_flags);
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200331 il_grab_nic_access(priv);
332 value = _il_read_direct32(priv, reg);
333 il_release_nic_access(priv);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800334 spin_unlock_irqrestore(&priv->reg_lock, reg_flags);
335 return value;
336
337}
338#endif
339
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200340static inline void _il_write_direct32(struct il_priv *priv,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800341 u32 reg, u32 value)
342{
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200343 _il_write32(priv, reg, value);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800344}
345static inline void
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200346il_write_direct32(struct il_priv *priv, u32 reg, u32 value)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800347{
348 unsigned long reg_flags;
349
350 spin_lock_irqsave(&priv->reg_lock, reg_flags);
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200351 if (!il_grab_nic_access(priv)) {
352 _il_write_direct32(priv, reg, value);
353 il_release_nic_access(priv);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800354 }
355 spin_unlock_irqrestore(&priv->reg_lock, reg_flags);
356}
357
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200358static inline void il_write_reg_buf(struct il_priv *priv,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800359 u32 reg, u32 len, u32 *values)
360{
361 u32 count = sizeof(u32);
362
363 if ((priv != NULL) && (values != NULL)) {
364 for (; 0 < len; len -= count, reg += count, values++)
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200365 il_write_direct32(priv, reg, *values);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800366 }
367}
368
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200369static inline int _il_poll_direct_bit(struct il_priv *priv, u32 addr,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800370 u32 mask, int timeout)
371{
372 int t = 0;
373
374 do {
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200375 if ((il_read_direct32(priv, addr) & mask) == mask)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800376 return t;
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200377 udelay(IL_POLL_INTERVAL);
378 t += IL_POLL_INTERVAL;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800379 } while (t < timeout);
380
381 return -ETIMEDOUT;
382}
383
384#ifdef CONFIG_IWLWIFI_LEGACY_DEBUG
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200385static inline int __il_poll_direct_bit(const char *f, u32 l,
386 struct il_priv *priv,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800387 u32 addr, u32 mask, int timeout)
388{
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200389 int ret = _il_poll_direct_bit(priv, addr, mask, timeout);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800390
391 if (unlikely(ret == -ETIMEDOUT))
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200392 IL_DEBUG_IO(priv, "poll_direct_bit(0x%08X, 0x%08X) - "
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800393 "timedout - %s %d\n", addr, mask, f, l);
394 else
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200395 IL_DEBUG_IO(priv, "poll_direct_bit(0x%08X, 0x%08X) = 0x%08X "
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800396 "- %s %d\n", addr, mask, ret, f, l);
397 return ret;
398}
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200399#define il_poll_direct_bit(priv, addr, mask, timeout) \
400__il_poll_direct_bit(__FILE__, __LINE__, priv, addr, mask, timeout)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800401#else
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200402#define il_poll_direct_bit _il_poll_direct_bit
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800403#endif
404
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200405static inline u32 _il_read_prph(struct il_priv *priv, u32 reg)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800406{
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200407 _il_write_direct32(priv, HBUS_TARG_PRPH_RADDR, reg | (3 << 24));
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800408 rmb();
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200409 return _il_read_direct32(priv, HBUS_TARG_PRPH_RDAT);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800410}
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200411static inline u32 il_read_prph(struct il_priv *priv, u32 reg)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800412{
413 unsigned long reg_flags;
414 u32 val;
415
416 spin_lock_irqsave(&priv->reg_lock, reg_flags);
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200417 il_grab_nic_access(priv);
418 val = _il_read_prph(priv, reg);
419 il_release_nic_access(priv);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800420 spin_unlock_irqrestore(&priv->reg_lock, reg_flags);
421 return val;
422}
423
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200424static inline void _il_write_prph(struct il_priv *priv,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800425 u32 addr, u32 val)
426{
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200427 _il_write_direct32(priv, HBUS_TARG_PRPH_WADDR,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800428 ((addr & 0x0000FFFF) | (3 << 24)));
429 wmb();
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200430 _il_write_direct32(priv, HBUS_TARG_PRPH_WDAT, val);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800431}
432
433static inline void
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200434il_write_prph(struct il_priv *priv, u32 addr, u32 val)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800435{
436 unsigned long reg_flags;
437
438 spin_lock_irqsave(&priv->reg_lock, reg_flags);
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200439 if (!il_grab_nic_access(priv)) {
440 _il_write_prph(priv, addr, val);
441 il_release_nic_access(priv);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800442 }
443 spin_unlock_irqrestore(&priv->reg_lock, reg_flags);
444}
445
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200446#define _il_set_bits_prph(priv, reg, mask) \
447_il_write_prph(priv, reg, (_il_read_prph(priv, reg) | mask))
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800448
449static inline void
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200450il_set_bits_prph(struct il_priv *priv, u32 reg, u32 mask)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800451{
452 unsigned long reg_flags;
453
454 spin_lock_irqsave(&priv->reg_lock, reg_flags);
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200455 il_grab_nic_access(priv);
456 _il_set_bits_prph(priv, reg, mask);
457 il_release_nic_access(priv);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800458 spin_unlock_irqrestore(&priv->reg_lock, reg_flags);
459}
460
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200461#define _il_set_bits_mask_prph(priv, reg, bits, mask) \
462_il_write_prph(priv, reg, \
463 ((_il_read_prph(priv, reg) & mask) | bits))
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800464
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200465static inline void il_set_bits_mask_prph(struct il_priv *priv, u32 reg,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800466 u32 bits, u32 mask)
467{
468 unsigned long reg_flags;
469
470 spin_lock_irqsave(&priv->reg_lock, reg_flags);
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200471 il_grab_nic_access(priv);
472 _il_set_bits_mask_prph(priv, reg, bits, mask);
473 il_release_nic_access(priv);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800474 spin_unlock_irqrestore(&priv->reg_lock, reg_flags);
475}
476
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200477static inline void il_clear_bits_prph(struct il_priv
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800478 *priv, u32 reg, u32 mask)
479{
480 unsigned long reg_flags;
481 u32 val;
482
483 spin_lock_irqsave(&priv->reg_lock, reg_flags);
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200484 il_grab_nic_access(priv);
485 val = _il_read_prph(priv, reg);
486 _il_write_prph(priv, reg, (val & ~mask));
487 il_release_nic_access(priv);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800488 spin_unlock_irqrestore(&priv->reg_lock, reg_flags);
489}
490
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200491static inline u32 il_read_targ_mem(struct il_priv *priv, u32 addr)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800492{
493 unsigned long reg_flags;
494 u32 value;
495
496 spin_lock_irqsave(&priv->reg_lock, reg_flags);
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200497 il_grab_nic_access(priv);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800498
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200499 _il_write_direct32(priv, HBUS_TARG_MEM_RADDR, addr);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800500 rmb();
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200501 value = _il_read_direct32(priv, HBUS_TARG_MEM_RDAT);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800502
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200503 il_release_nic_access(priv);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800504 spin_unlock_irqrestore(&priv->reg_lock, reg_flags);
505 return value;
506}
507
508static inline void
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200509il_write_targ_mem(struct il_priv *priv, u32 addr, u32 val)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800510{
511 unsigned long reg_flags;
512
513 spin_lock_irqsave(&priv->reg_lock, reg_flags);
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200514 if (!il_grab_nic_access(priv)) {
515 _il_write_direct32(priv, HBUS_TARG_MEM_WADDR, addr);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800516 wmb();
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200517 _il_write_direct32(priv, HBUS_TARG_MEM_WDAT, val);
518 il_release_nic_access(priv);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800519 }
520 spin_unlock_irqrestore(&priv->reg_lock, reg_flags);
521}
522
523static inline void
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200524il_write_targ_mem_buf(struct il_priv *priv, u32 addr,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800525 u32 len, u32 *values)
526{
527 unsigned long reg_flags;
528
529 spin_lock_irqsave(&priv->reg_lock, reg_flags);
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200530 if (!il_grab_nic_access(priv)) {
531 _il_write_direct32(priv, HBUS_TARG_MEM_WADDR, addr);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800532 wmb();
533 for (; 0 < len; len -= sizeof(u32), values++)
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200534 _il_write_direct32(priv,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800535 HBUS_TARG_MEM_WDAT, *values);
536
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200537 il_release_nic_access(priv);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800538 }
539 spin_unlock_irqrestore(&priv->reg_lock, reg_flags);
540}
541#endif