iwl-io.h revision 18d426c4a8991d1d6c0dc33a62b610b8a6ffc1d2
1/****************************************************************************** 2 * 3 * Copyright(c) 2003 - 2009 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 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 * and the current line number and caller function name are printed in addition 46 * 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 name and __LINE__ to the double 50 * prefix version. 51 * 52 * If you wish to call the function without any debug or state checking, 53 * you should use the single _ prefix version (as is used by dependent IO 54 * routines, for example _iwl_read_direct32 calls the non-check version of 55 * _iwl_read32.) 56 * 57 * These declarations are *extremely* useful in quickly isolating code deltas 58 * which result in misconfiguration of the hardware I/O. In combination with 59 * git-bisect and the IO debug level you can quickly determine the specific 60 * commit which breaks the IO sequence to the hardware. 61 * 62 */ 63 64#define _iwl_write32(priv, ofs, val) iowrite32((val), (priv)->hw_base + (ofs)) 65#ifdef CONFIG_IWLWIFI_DEBUG 66static inline void __iwl_write32(const char *f, u32 l, struct iwl_priv *priv, 67 u32 ofs, u32 val) 68{ 69 IWL_DEBUG_IO(priv, "write32(0x%08X, 0x%08X) - %s %d\n", ofs, val, f, l); 70 _iwl_write32(priv, ofs, val); 71} 72#define iwl_write32(priv, ofs, val) \ 73 __iwl_write32(__FILE__, __LINE__, priv, ofs, val) 74#else 75#define iwl_write32(priv, ofs, val) _iwl_write32(priv, ofs, val) 76#endif 77 78#define _iwl_read32(priv, ofs) ioread32((priv)->hw_base + (ofs)) 79#ifdef CONFIG_IWLWIFI_DEBUG 80static inline u32 __iwl_read32(char *f, u32 l, struct iwl_priv *priv, u32 ofs) 81{ 82 IWL_DEBUG_IO(priv, "read_direct32(0x%08X) - %s %d\n", ofs, f, l); 83 return _iwl_read32(priv, ofs); 84} 85#define iwl_read32(priv, ofs) __iwl_read32(__FILE__, __LINE__, priv, ofs) 86#else 87#define iwl_read32(p, o) _iwl_read32(p, o) 88#endif 89 90#define IWL_POLL_INTERVAL 10 /* microseconds */ 91static inline int _iwl_poll_bit(struct iwl_priv *priv, u32 addr, 92 u32 bits, u32 mask, int timeout) 93{ 94 int t = 0; 95 96 do { 97 if ((_iwl_read32(priv, addr) & mask) == (bits & mask)) 98 return t; 99 udelay(IWL_POLL_INTERVAL); 100 t += IWL_POLL_INTERVAL; 101 } while (t < timeout); 102 103 return -ETIMEDOUT; 104} 105#ifdef CONFIG_IWLWIFI_DEBUG 106static inline int __iwl_poll_bit(const char *f, u32 l, 107 struct iwl_priv *priv, u32 addr, 108 u32 bits, u32 mask, int timeout) 109{ 110 int ret = _iwl_poll_bit(priv, addr, bits, mask, timeout); 111 IWL_DEBUG_IO(priv, "poll_bit(0x%08X, 0x%08X, 0x%08X) - %s- %s %d\n", 112 addr, bits, mask, 113 unlikely(ret == -ETIMEDOUT) ? "timeout" : "", f, l); 114 return ret; 115} 116#define iwl_poll_bit(priv, addr, bits, mask, timeout) \ 117 __iwl_poll_bit(__FILE__, __LINE__, priv, addr, bits, mask, timeout) 118#else 119#define iwl_poll_bit(p, a, b, m, t) _iwl_poll_bit(p, a, b, m, t) 120#endif 121 122static inline void _iwl_set_bit(struct iwl_priv *priv, u32 reg, u32 mask) 123{ 124 _iwl_write32(priv, reg, _iwl_read32(priv, reg) | mask); 125} 126#ifdef CONFIG_IWLWIFI_DEBUG 127static inline void __iwl_set_bit(const char *f, u32 l, 128 struct iwl_priv *priv, u32 reg, u32 mask) 129{ 130 u32 val = _iwl_read32(priv, reg) | mask; 131 IWL_DEBUG_IO(priv, "set_bit(0x%08X, 0x%08X) = 0x%08X\n", reg, mask, val); 132 _iwl_write32(priv, reg, val); 133} 134#define iwl_set_bit(p, r, m) __iwl_set_bit(__FILE__, __LINE__, p, r, m) 135#else 136#define iwl_set_bit(p, r, m) _iwl_set_bit(p, r, m) 137#endif 138 139static inline void _iwl_clear_bit(struct iwl_priv *priv, u32 reg, u32 mask) 140{ 141 _iwl_write32(priv, reg, _iwl_read32(priv, reg) & ~mask); 142} 143#ifdef CONFIG_IWLWIFI_DEBUG 144static inline void __iwl_clear_bit(const char *f, u32 l, 145 struct iwl_priv *priv, u32 reg, u32 mask) 146{ 147 u32 val = _iwl_read32(priv, reg) & ~mask; 148 IWL_DEBUG_IO(priv, "clear_bit(0x%08X, 0x%08X) = 0x%08X\n", reg, mask, val); 149 _iwl_write32(priv, reg, val); 150} 151#define iwl_clear_bit(p, r, m) __iwl_clear_bit(__FILE__, __LINE__, p, r, m) 152#else 153#define iwl_clear_bit(p, r, m) _iwl_clear_bit(p, r, m) 154#endif 155 156static inline int _iwl_grab_nic_access(struct iwl_priv *priv) 157{ 158 int ret; 159 u32 val; 160#ifdef CONFIG_IWLWIFI_DEBUG 161 if (atomic_read(&priv->restrict_refcnt)) 162 return 0; 163#endif 164 /* this bit wakes up the NIC */ 165 _iwl_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); 166 ret = _iwl_poll_bit(priv, CSR_GP_CNTRL, 167 CSR_GP_CNTRL_REG_VAL_MAC_ACCESS_EN, 168 (CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY | 169 CSR_GP_CNTRL_REG_FLAG_GOING_TO_SLEEP), 15000); 170 if (ret < 0) { 171 val = _iwl_read32(priv, CSR_GP_CNTRL); 172 IWL_ERR(priv, "MAC is in deep sleep!. CSR_GP_CNTRL = 0x%08X\n", val); 173 return -EIO; 174 } 175 176#ifdef CONFIG_IWLWIFI_DEBUG 177 atomic_inc(&priv->restrict_refcnt); 178#endif 179 return 0; 180} 181 182#ifdef CONFIG_IWLWIFI_DEBUG 183static inline int __iwl_grab_nic_access(const char *f, u32 l, 184 struct iwl_priv *priv) 185{ 186 if (atomic_read(&priv->restrict_refcnt)) 187 IWL_ERR(priv, "Grabbing access while already held %s %d.\n", f, l); 188 189 IWL_DEBUG_IO(priv, "grabbing nic access - %s %d\n", f, l); 190 return _iwl_grab_nic_access(priv); 191} 192#define iwl_grab_nic_access(priv) \ 193 __iwl_grab_nic_access(__FILE__, __LINE__, priv) 194#else 195#define iwl_grab_nic_access(priv) \ 196 _iwl_grab_nic_access(priv) 197#endif 198 199static inline void _iwl_release_nic_access(struct iwl_priv *priv) 200{ 201#ifdef CONFIG_IWLWIFI_DEBUG 202 if (atomic_dec_and_test(&priv->restrict_refcnt)) 203#endif 204 _iwl_clear_bit(priv, CSR_GP_CNTRL, 205 CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); 206} 207#ifdef CONFIG_IWLWIFI_DEBUG 208static inline void __iwl_release_nic_access(const char *f, u32 l, 209 struct iwl_priv *priv) 210{ 211 if (atomic_read(&priv->restrict_refcnt) <= 0) 212 IWL_ERR(priv, "Release unheld nic access at line %s %d.\n", f, l); 213 214 IWL_DEBUG_IO(priv, "releasing nic access - %s %d\n", f, l); 215 _iwl_release_nic_access(priv); 216} 217#define iwl_release_nic_access(priv) \ 218 __iwl_release_nic_access(__FILE__, __LINE__, priv) 219#else 220#define iwl_release_nic_access(priv) \ 221 _iwl_release_nic_access(priv) 222#endif 223 224static inline u32 _iwl_read_direct32(struct iwl_priv *priv, u32 reg) 225{ 226 return _iwl_read32(priv, reg); 227} 228#ifdef CONFIG_IWLWIFI_DEBUG 229static inline u32 __iwl_read_direct32(const char *f, u32 l, 230 struct iwl_priv *priv, u32 reg) 231{ 232 u32 value = _iwl_read_direct32(priv, reg); 233 if (!atomic_read(&priv->restrict_refcnt)) 234 IWL_ERR(priv, "Nic access not held from %s %d\n", f, l); 235 IWL_DEBUG_IO(priv, "read_direct32(0x%4X) = 0x%08x - %s %d \n", reg, value, 236 f, l); 237 return value; 238} 239#define iwl_read_direct32(priv, reg) \ 240 __iwl_read_direct32(__FILE__, __LINE__, priv, reg) 241#else 242#define iwl_read_direct32 _iwl_read_direct32 243#endif 244 245static inline void _iwl_write_direct32(struct iwl_priv *priv, 246 u32 reg, u32 value) 247{ 248 _iwl_write32(priv, reg, value); 249} 250#ifdef CONFIG_IWLWIFI_DEBUG 251static void __iwl_write_direct32(const char *f , u32 line, 252 struct iwl_priv *priv, u32 reg, u32 value) 253{ 254 if (!atomic_read(&priv->restrict_refcnt)) 255 IWL_ERR(priv, "Nic access not held from %s line %d\n", f, line); 256 _iwl_write_direct32(priv, reg, value); 257} 258#define iwl_write_direct32(priv, reg, value) \ 259 __iwl_write_direct32(__func__, __LINE__, priv, reg, value) 260#else 261#define iwl_write_direct32 _iwl_write_direct32 262#endif 263 264static inline void iwl_write_reg_buf(struct iwl_priv *priv, 265 u32 reg, u32 len, u32 *values) 266{ 267 u32 count = sizeof(u32); 268 269 if ((priv != NULL) && (values != NULL)) { 270 for (; 0 < len; len -= count, reg += count, values++) 271 _iwl_write_direct32(priv, reg, *values); 272 } 273} 274 275static inline int _iwl_poll_direct_bit(struct iwl_priv *priv, u32 addr, 276 u32 mask, int timeout) 277{ 278 return _iwl_poll_bit(priv, addr, mask, mask, timeout); 279} 280 281#ifdef CONFIG_IWLWIFI_DEBUG 282static inline int __iwl_poll_direct_bit(const char *f, u32 l, 283 struct iwl_priv *priv, 284 u32 addr, u32 mask, int timeout) 285{ 286 int ret = _iwl_poll_direct_bit(priv, addr, mask, timeout); 287 288 if (unlikely(ret == -ETIMEDOUT)) 289 IWL_DEBUG_IO(priv, "poll_direct_bit(0x%08X, 0x%08X) - " 290 "timedout - %s %d\n", addr, mask, f, l); 291 else 292 IWL_DEBUG_IO(priv, "poll_direct_bit(0x%08X, 0x%08X) = 0x%08X " 293 "- %s %d\n", addr, mask, ret, f, l); 294 return ret; 295} 296#define iwl_poll_direct_bit(priv, addr, mask, timeout) \ 297 __iwl_poll_direct_bit(__FILE__, __LINE__, priv, addr, mask, timeout) 298#else 299#define iwl_poll_direct_bit _iwl_poll_direct_bit 300#endif 301 302static inline u32 _iwl_read_prph(struct iwl_priv *priv, u32 reg) 303{ 304 _iwl_write_direct32(priv, HBUS_TARG_PRPH_RADDR, reg | (3 << 24)); 305 rmb(); 306 return _iwl_read_direct32(priv, HBUS_TARG_PRPH_RDAT); 307} 308#ifdef CONFIG_IWLWIFI_DEBUG 309static inline u32 __iwl_read_prph(const char *f, u32 line, 310 struct iwl_priv *priv, u32 reg) 311{ 312 if (!atomic_read(&priv->restrict_refcnt)) 313 IWL_ERR(priv, "Nic access not held from %s line %d\n", f, line); 314 return _iwl_read_prph(priv, reg); 315} 316 317#define iwl_read_prph(priv, reg) \ 318 __iwl_read_prph(__func__, __LINE__, priv, reg) 319#else 320#define iwl_read_prph _iwl_read_prph 321#endif 322 323static inline void _iwl_write_prph(struct iwl_priv *priv, 324 u32 addr, u32 val) 325{ 326 _iwl_write_direct32(priv, HBUS_TARG_PRPH_WADDR, 327 ((addr & 0x0000FFFF) | (3 << 24))); 328 wmb(); 329 _iwl_write_direct32(priv, HBUS_TARG_PRPH_WDAT, val); 330} 331#ifdef CONFIG_IWLWIFI_DEBUG 332static inline void __iwl_write_prph(const char *f, u32 line, 333 struct iwl_priv *priv, u32 addr, u32 val) 334{ 335 if (!atomic_read(&priv->restrict_refcnt)) 336 IWL_ERR(priv, "Nic access not held from %s line %d\n", f, line); 337 _iwl_write_prph(priv, addr, val); 338} 339 340#define iwl_write_prph(priv, addr, val) \ 341 __iwl_write_prph(__func__, __LINE__, priv, addr, val); 342#else 343#define iwl_write_prph _iwl_write_prph 344#endif 345 346#define _iwl_set_bits_prph(priv, reg, mask) \ 347 _iwl_write_prph(priv, reg, (_iwl_read_prph(priv, reg) | mask)) 348#ifdef CONFIG_IWLWIFI_DEBUG 349static inline void __iwl_set_bits_prph(const char *f, u32 line, 350 struct iwl_priv *priv, 351 u32 reg, u32 mask) 352{ 353 if (!atomic_read(&priv->restrict_refcnt)) 354 IWL_ERR(priv, "Nic access not held from %s line %d\n", f, line); 355 356 _iwl_set_bits_prph(priv, reg, mask); 357} 358#define iwl_set_bits_prph(priv, reg, mask) \ 359 __iwl_set_bits_prph(__func__, __LINE__, priv, reg, mask) 360#else 361#define iwl_set_bits_prph _iwl_set_bits_prph 362#endif 363 364#define _iwl_set_bits_mask_prph(priv, reg, bits, mask) \ 365 _iwl_write_prph(priv, reg, ((_iwl_read_prph(priv, reg) & mask) | bits)) 366 367#ifdef CONFIG_IWLWIFI_DEBUG 368static inline void __iwl_set_bits_mask_prph(const char *f, u32 line, 369 struct iwl_priv *priv, u32 reg, u32 bits, u32 mask) 370{ 371 if (!atomic_read(&priv->restrict_refcnt)) 372 IWL_ERR(priv, "Nic access not held from %s line %d\n", f, line); 373 _iwl_set_bits_mask_prph(priv, reg, bits, mask); 374} 375#define iwl_set_bits_mask_prph(priv, reg, bits, mask) \ 376 __iwl_set_bits_mask_prph(__func__, __LINE__, priv, reg, bits, mask) 377#else 378#define iwl_set_bits_mask_prph _iwl_set_bits_mask_prph 379#endif 380 381static inline void iwl_clear_bits_prph(struct iwl_priv 382 *priv, u32 reg, u32 mask) 383{ 384 u32 val = _iwl_read_prph(priv, reg); 385 _iwl_write_prph(priv, reg, (val & ~mask)); 386} 387 388static inline u32 iwl_read_targ_mem(struct iwl_priv *priv, u32 addr) 389{ 390 iwl_write_direct32(priv, HBUS_TARG_MEM_RADDR, addr); 391 rmb(); 392 return iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT); 393} 394 395static inline void iwl_write_targ_mem(struct iwl_priv *priv, u32 addr, u32 val) 396{ 397 iwl_write_direct32(priv, HBUS_TARG_MEM_WADDR, addr); 398 wmb(); 399 iwl_write_direct32(priv, HBUS_TARG_MEM_WDAT, val); 400} 401 402static inline void iwl_write_targ_mem_buf(struct iwl_priv *priv, u32 addr, 403 u32 len, u32 *values) 404{ 405 iwl_write_direct32(priv, HBUS_TARG_MEM_WADDR, addr); 406 wmb(); 407 for (; 0 < len; len -= sizeof(u32), values++) 408 iwl_write_direct32(priv, HBUS_TARG_MEM_WDAT, *values); 409} 410#endif 411