iwl-io.h revision d860965200c867e7e3e81ede8572cffff8c7eb24
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
65static 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
80static 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
90static 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
105static 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
126static 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
131static 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
143static 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
148static 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
160static 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
203static 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
221static 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
230static 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
246static inline u32 _iwl_read_restricted(struct iwl_priv *priv, u32 reg)
247{
248	return _iwl_read32(priv, reg);
249}
250#ifdef CONFIG_IWLWIFI_DEBUG
251static 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
267static 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
273static 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
286static 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
297static 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
313static 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
333static inline u32 _iwl_read_prph(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
339static inline u32 __iwl_read_prph(u32 line, struct iwl_priv *priv, u32 reg)
340{
341	if (!atomic_read(&priv->restrict_refcnt))
342		IWL_ERROR("Unrestricted access from line %d\n", line);
343	return _iwl_read_prph(priv, reg);
344}
345
346#define iwl_read_prph(priv, reg) \
347	__iwl_read_prph(__LINE__, priv, reg)
348#else
349#define iwl_read_prph _iwl_read_prph
350#endif
351
352static inline void _iwl_write_prph(struct iwl_priv *priv,
353					     u32 addr, u32 val)
354{
355	_iwl_write_restricted(priv, HBUS_TARG_PRPH_WADDR,
356			      ((addr & 0x0000FFFF) | (3 << 24)));
357	_iwl_write_restricted(priv, HBUS_TARG_PRPH_WDAT, val);
358}
359#ifdef CONFIG_IWLWIFI_DEBUG
360static inline void __iwl_write_prph(u32 line, struct iwl_priv *priv,
361					      u32 addr, u32 val)
362{
363	if (!atomic_read(&priv->restrict_refcnt))
364		IWL_ERROR("Unrestricted access from line %d\n", line);
365	_iwl_write_prph(priv, addr, val);
366}
367
368#define iwl_write_prph(priv, addr, val) \
369	__iwl_write_prph(__LINE__, priv, addr, val);
370#else
371#define iwl_write_prph _iwl_write_prph
372#endif
373
374#define _iwl_set_bits_prph(priv, reg, mask) \
375	_iwl_write_prph(priv, reg, (_iwl_read_prph(priv, reg) | mask))
376#ifdef CONFIG_IWLWIFI_DEBUG
377static inline void __iwl_set_bits_prph(u32 line, struct iwl_priv *priv,
378					u32 reg, u32 mask)
379{
380	if (!atomic_read(&priv->restrict_refcnt))
381		IWL_ERROR("Unrestricted access from line %d\n", line);
382	_iwl_set_bits_prph(priv, reg, mask);
383}
384#define iwl_set_bits_prph(priv, reg, mask) \
385	__iwl_set_bits_prph(__LINE__, priv, reg, mask)
386#else
387#define iwl_set_bits_prph _iwl_set_bits_prph
388#endif
389
390#define _iwl_set_bits_mask_prph(priv, reg, bits, mask) \
391	_iwl_write_prph(priv, reg, ((_iwl_read_prph(priv, reg) & mask) | bits))
392
393#ifdef CONFIG_IWLWIFI_DEBUG
394static inline void __iwl_set_bits_mask_prph(u32 line,
395		struct iwl_priv *priv, u32 reg, u32 bits, u32 mask)
396{
397	if (!atomic_read(&priv->restrict_refcnt))
398		IWL_ERROR("Unrestricted access from line %d\n", line);
399	_iwl_set_bits_mask_prph(priv, reg, bits, mask);
400}
401#define iwl_set_bits_mask_prph(priv, reg, bits, mask) \
402	__iwl_set_bits_mask_prph(__LINE__, priv, reg, bits, mask)
403#else
404#define iwl_set_bits_mask_prph _iwl_set_bits_mask_prph
405#endif
406
407static inline void iwl_clear_bits_prph(struct iwl_priv
408						 *priv, u32 reg, u32 mask)
409{
410	u32 val = _iwl_read_prph(priv, reg);
411	_iwl_write_prph(priv, reg, (val & ~mask));
412}
413
414static inline u32 iwl_read_restricted_mem(struct iwl_priv *priv, u32 addr)
415{
416	iwl_write_restricted(priv, HBUS_TARG_MEM_RADDR, addr);
417	return iwl_read_restricted(priv, HBUS_TARG_MEM_RDAT);
418}
419
420static inline void iwl_write_restricted_mem(struct iwl_priv *priv, u32 addr,
421					    u32 val)
422{
423	iwl_write_restricted(priv, HBUS_TARG_MEM_WADDR, addr);
424	iwl_write_restricted(priv, HBUS_TARG_MEM_WDAT, val);
425}
426
427static inline void iwl_write_restricted_mems(struct iwl_priv *priv, u32 addr,
428					     u32 len, u32 *values)
429{
430	iwl_write_restricted(priv, HBUS_TARG_MEM_WADDR, addr);
431	for (; 0 < len; len -= sizeof(u32), values++)
432		iwl_write_restricted(priv, HBUS_TARG_MEM_WDAT, *values);
433}
434#endif
435