iwl-io.h revision 3395f6e9cf48469d7ee05703cad1502002741c16
1/****************************************************************************** 2 * 3 * Copyright(c) 2003 - 2008 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 * and the current line number is printed in addition to any other debug output. 46 * 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 52 * routines, for example _iwl_read_direct32 calls the non-check version of 53 * _iwl_read32.) 54 * 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 62#define _iwl_write32(priv, ofs, val) writel((val), (priv)->hw_base + (ofs)) 63#ifdef CONFIG_IWLWIFI_DEBUG 64static inline void __iwl_write32(const char *f, u32 l, struct iwl_priv *priv, 65 u32 ofs, u32 val) 66{ 67 IWL_DEBUG_IO("write32(0x%08X, 0x%08X) - %s %d\n", ofs, val, f, l); 68 _iwl_write32(priv, ofs, val); 69} 70#define iwl_write32(priv, ofs, val) \ 71 __iwl_write32(__FILE__, __LINE__, priv, ofs, val) 72#else 73#define iwl_write32(priv, ofs, val) _iwl_write32(priv, ofs, val) 74#endif 75 76#define _iwl_read32(priv, ofs) readl((priv)->hw_base + (ofs)) 77#ifdef CONFIG_IWLWIFI_DEBUG 78static inline u32 __iwl_read32(char *f, u32 l, struct iwl_priv *priv, u32 ofs) 79{ 80 IWL_DEBUG_IO("read_direct32(0x%08X) - %s %d\n", ofs, f, l); 81 return _iwl_read32(priv, ofs); 82} 83#define iwl_read32(priv, ofs) __iwl_read32(__FILE__, __LINE__, priv, ofs) 84#else 85#define iwl_read32(p, o) _iwl_read32(p, o) 86#endif 87 88static inline int _iwl_poll_bit(struct iwl_priv *priv, u32 addr, 89 u32 bits, u32 mask, int timeout) 90{ 91 int i = 0; 92 93 do { 94 if ((_iwl_read32(priv, addr) & mask) == (bits & mask)) 95 return i; 96 mdelay(10); 97 i += 10; 98 } while (i < timeout); 99 100 return -ETIMEDOUT; 101} 102#ifdef CONFIG_IWLWIFI_DEBUG 103static inline int __iwl_poll_bit(const char *f, u32 l, 104 struct iwl_priv *priv, u32 addr, 105 u32 bits, u32 mask, int timeout) 106{ 107 int ret = _iwl_poll_bit(priv, addr, bits, mask, timeout); 108 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); 111 return ret; 112} 113#define iwl_poll_bit(priv, addr, bits, mask, timeout) \ 114 __iwl_poll_bit(__FILE__, __LINE__, priv, addr, bits, mask, timeout) 115#else 116#define iwl_poll_bit(p, a, b, m, t) _iwl_poll_bit(p, a, b, m, t) 117#endif 118 119static inline void _iwl_set_bit(struct iwl_priv *priv, u32 reg, u32 mask) 120{ 121 _iwl_write32(priv, reg, _iwl_read32(priv, reg) | mask); 122} 123#ifdef CONFIG_IWLWIFI_DEBUG 124static inline void __iwl_set_bit(const char *f, u32 l, 125 struct iwl_priv *priv, u32 reg, u32 mask) 126{ 127 u32 val = _iwl_read32(priv, reg) | mask; 128 IWL_DEBUG_IO("set_bit(0x%08X, 0x%08X) = 0x%08X\n", reg, mask, val); 129 _iwl_write32(priv, reg, val); 130} 131#define iwl_set_bit(p, r, m) __iwl_set_bit(__FILE__, __LINE__, p, r, m) 132#else 133#define iwl_set_bit(p, r, m) _iwl_set_bit(p, r, m) 134#endif 135 136static inline void _iwl_clear_bit(struct iwl_priv *priv, u32 reg, u32 mask) 137{ 138 _iwl_write32(priv, reg, _iwl_read32(priv, reg) & ~mask); 139} 140#ifdef CONFIG_IWLWIFI_DEBUG 141static inline void __iwl_clear_bit(const char *f, u32 l, 142 struct iwl_priv *priv, u32 reg, u32 mask) 143{ 144 u32 val = _iwl_read32(priv, reg) & ~mask; 145 IWL_DEBUG_IO("clear_bit(0x%08X, 0x%08X) = 0x%08X\n", reg, mask, val); 146 _iwl_write32(priv, reg, val); 147} 148#define iwl_clear_bit(p, r, m) __iwl_clear_bit(__FILE__, __LINE__, p, r, m) 149#else 150#define iwl_clear_bit(p, r, m) _iwl_clear_bit(p, r, m) 151#endif 152 153static inline int _iwl_grab_nic_access(struct iwl_priv *priv) 154{ 155 int ret; 156 u32 gp_ctl; 157 158#ifdef CONFIG_IWLWIFI_DEBUG 159 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 */ 168 gp_ctl = _iwl_read32(priv, CSR_GP_CNTRL); 169 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 */ 179 _iwl_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); 180 ret = _iwl_poll_bit(priv, CSR_GP_CNTRL, 181 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); 184 if (ret < 0) { 185 IWL_ERROR("MAC is in deep sleep!\n"); 186 return -EIO; 187 } 188 189#ifdef CONFIG_IWLWIFI_DEBUG 190 atomic_inc(&priv->restrict_refcnt); 191#endif 192 return 0; 193} 194 195#ifdef CONFIG_IWLWIFI_DEBUG 196static inline int __iwl_grab_nic_access(const char *f, u32 l, 197 struct iwl_priv *priv) 198{ 199 if (atomic_read(&priv->restrict_refcnt)) 200 IWL_DEBUG_INFO("Grabbing access while already held at " 201 "line %d.\n", l); 202 203 IWL_DEBUG_IO("grabbing nic access - %s %d\n", f, l); 204 return _iwl_grab_nic_access(priv); 205} 206#define iwl_grab_nic_access(priv) \ 207 __iwl_grab_nic_access(__FILE__, __LINE__, priv) 208#else 209#define iwl_grab_nic_access(priv) \ 210 _iwl_grab_nic_access(priv) 211#endif 212 213static inline void _iwl_release_nic_access(struct iwl_priv *priv) 214{ 215#ifdef CONFIG_IWLWIFI_DEBUG 216 if (atomic_dec_and_test(&priv->restrict_refcnt)) 217#endif 218 _iwl_clear_bit(priv, CSR_GP_CNTRL, 219 CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); 220} 221#ifdef CONFIG_IWLWIFI_DEBUG 222static inline void __iwl_release_nic_access(const char *f, u32 l, 223 struct iwl_priv *priv) 224{ 225 if (atomic_read(&priv->restrict_refcnt) <= 0) 226 IWL_ERROR("Release unheld nic access at line %d.\n", l); 227 228 IWL_DEBUG_IO("releasing nic access - %s %d\n", f, l); 229 _iwl_release_nic_access(priv); 230} 231#define iwl_release_nic_access(priv) \ 232 __iwl_release_nic_access(__FILE__, __LINE__, priv) 233#else 234#define iwl_release_nic_access(priv) \ 235 _iwl_release_nic_access(priv) 236#endif 237 238static inline u32 _iwl_read_direct32(struct iwl_priv *priv, u32 reg) 239{ 240 return _iwl_read32(priv, reg); 241} 242#ifdef CONFIG_IWLWIFI_DEBUG 243static inline u32 __iwl_read_direct32(const char *f, u32 l, 244 struct iwl_priv *priv, u32 reg) 245{ 246 u32 value = _iwl_read_direct32(priv, reg); 247 if (!atomic_read(&priv->restrict_refcnt)) 248 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, 250 f, l); 251 return value; 252} 253#define iwl_read_direct32(priv, reg) \ 254 __iwl_read_direct32(__FILE__, __LINE__, priv, reg) 255#else 256#define iwl_read_direct32 _iwl_read_direct32 257#endif 258 259static inline void _iwl_write_direct32(struct iwl_priv *priv, 260 u32 reg, u32 value) 261{ 262 _iwl_write32(priv, reg, value); 263} 264#ifdef CONFIG_IWLWIFI_DEBUG 265static void __iwl_write_direct32(u32 line, 266 struct iwl_priv *priv, u32 reg, u32 value) 267{ 268 if (!atomic_read(&priv->restrict_refcnt)) 269 IWL_ERROR("Nic access not held from line %d\n", line); 270 _iwl_write_direct32(priv, reg, value); 271} 272#define iwl_write_direct32(priv, reg, value) \ 273 __iwl_write_direct32(__LINE__, priv, reg, value) 274#else 275#define iwl_write_direct32 _iwl_write_direct32 276#endif 277 278static inline void iwl_write_reg_buf(struct iwl_priv *priv, 279 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++) 285 _iwl_write_direct32(priv, reg, *values); 286 } 287} 288 289static inline int _iwl_poll_direct_bit(struct iwl_priv *priv, 290 u32 addr, u32 mask, int timeout) 291{ 292 int i = 0; 293 294 do { 295 if ((_iwl_read_direct32(priv, addr) & mask) == mask) 296 return i; 297 mdelay(10); 298 i += 10; 299 } while (i < timeout); 300 301 return -ETIMEDOUT; 302} 303 304#ifdef CONFIG_IWLWIFI_DEBUG 305static inline int __iwl_poll_direct_bit(const char *f, u32 l, 306 struct iwl_priv *priv, 307 u32 addr, u32 mask, int timeout) 308{ 309 int ret = _iwl_poll_direct_bit(priv, addr, mask, timeout); 310 311 if (unlikely(ret == -ETIMEDOUT)) 312 IWL_DEBUG_IO("poll_direct_bit(0x%08X, 0x%08X) - " 313 "timedout - %s %d\n", addr, mask, f, l); 314 else 315 IWL_DEBUG_IO("poll_direct_bit(0x%08X, 0x%08X) = 0x%08X " 316 "- %s %d\n", addr, mask, ret, f, l); 317 return ret; 318} 319#define iwl_poll_direct_bit(priv, addr, mask, timeout) \ 320 __iwl_poll_direct_bit(__FILE__, __LINE__, priv, addr, mask, timeout) 321#else 322#define iwl_poll_direct_bit _iwl_poll_direct_bit 323#endif 324 325static inline u32 _iwl_read_prph(struct iwl_priv *priv, u32 reg) 326{ 327 _iwl_write_direct32(priv, HBUS_TARG_PRPH_RADDR, reg | (3 << 24)); 328 return _iwl_read_direct32(priv, HBUS_TARG_PRPH_RDAT); 329} 330#ifdef CONFIG_IWLWIFI_DEBUG 331static inline u32 __iwl_read_prph(u32 line, struct iwl_priv *priv, u32 reg) 332{ 333 if (!atomic_read(&priv->restrict_refcnt)) 334 IWL_ERROR("Nic access not held from line %d\n", line); 335 return _iwl_read_prph(priv, reg); 336} 337 338#define iwl_read_prph(priv, reg) \ 339 __iwl_read_prph(__LINE__, priv, reg) 340#else 341#define iwl_read_prph _iwl_read_prph 342#endif 343 344static inline void _iwl_write_prph(struct iwl_priv *priv, 345 u32 addr, u32 val) 346{ 347 _iwl_write_direct32(priv, HBUS_TARG_PRPH_WADDR, 348 ((addr & 0x0000FFFF) | (3 << 24))); 349 _iwl_write_direct32(priv, HBUS_TARG_PRPH_WDAT, val); 350} 351#ifdef CONFIG_IWLWIFI_DEBUG 352static inline void __iwl_write_prph(u32 line, struct iwl_priv *priv, 353 u32 addr, u32 val) 354{ 355 if (!atomic_read(&priv->restrict_refcnt)) 356 IWL_ERROR("Nic access from line %d\n", line); 357 _iwl_write_prph(priv, addr, val); 358} 359 360#define iwl_write_prph(priv, addr, val) \ 361 __iwl_write_prph(__LINE__, priv, addr, val); 362#else 363#define iwl_write_prph _iwl_write_prph 364#endif 365 366#define _iwl_set_bits_prph(priv, reg, mask) \ 367 _iwl_write_prph(priv, reg, (_iwl_read_prph(priv, reg) | mask)) 368#ifdef CONFIG_IWLWIFI_DEBUG 369static inline void __iwl_set_bits_prph(u32 line, struct iwl_priv *priv, 370 u32 reg, u32 mask) 371{ 372 if (!atomic_read(&priv->restrict_refcnt)) 373 IWL_ERROR("Nic access not held from line %d\n", line); 374 375 _iwl_set_bits_prph(priv, reg, mask); 376} 377#define iwl_set_bits_prph(priv, reg, mask) \ 378 __iwl_set_bits_prph(__LINE__, priv, reg, mask) 379#else 380#define iwl_set_bits_prph _iwl_set_bits_prph 381#endif 382 383#define _iwl_set_bits_mask_prph(priv, reg, bits, mask) \ 384 _iwl_write_prph(priv, reg, ((_iwl_read_prph(priv, reg) & mask) | bits)) 385 386#ifdef CONFIG_IWLWIFI_DEBUG 387static inline void __iwl_set_bits_mask_prph(u32 line, 388 struct iwl_priv *priv, u32 reg, u32 bits, u32 mask) 389{ 390 if (!atomic_read(&priv->restrict_refcnt)) 391 IWL_ERROR("Nic access not held from line %d\n", line); 392 _iwl_set_bits_mask_prph(priv, reg, bits, mask); 393} 394#define iwl_set_bits_mask_prph(priv, reg, bits, mask) \ 395 __iwl_set_bits_mask_prph(__LINE__, priv, reg, bits, mask) 396#else 397#define iwl_set_bits_mask_prph _iwl_set_bits_mask_prph 398#endif 399 400static inline void iwl_clear_bits_prph(struct iwl_priv 401 *priv, u32 reg, u32 mask) 402{ 403 u32 val = _iwl_read_prph(priv, reg); 404 _iwl_write_prph(priv, reg, (val & ~mask)); 405} 406 407static inline u32 iwl_read_targ_mem(struct iwl_priv *priv, u32 addr) 408{ 409 iwl_write_direct32(priv, HBUS_TARG_MEM_RADDR, addr); 410 return iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT); 411} 412 413static inline void iwl_write_targ_mem(struct iwl_priv *priv, u32 addr, u32 val) 414{ 415 iwl_write_direct32(priv, HBUS_TARG_MEM_WADDR, addr); 416 iwl_write_direct32(priv, HBUS_TARG_MEM_WDAT, val); 417} 418 419static inline void iwl_write_targ_mem_buf(struct iwl_priv *priv, u32 addr, 420 u32 len, u32 *values) 421{ 422 iwl_write_direct32(priv, HBUS_TARG_MEM_WADDR, addr); 423 for (; 0 < len; len -= sizeof(u32), values++) 424 iwl_write_direct32(priv, HBUS_TARG_MEM_WDAT, *values); 425} 426#endif 427