linux/drivers/net/wireless/iwlwifi/iwl-io.h
<<
>>
Prefs
   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}
 134static inline void iwl_set_bit(struct iwl_priv *p, u32 r, u32 m)
 135{
 136        unsigned long reg_flags;
 137
 138        spin_lock_irqsave(&p->reg_lock, reg_flags);
 139        __iwl_set_bit(__FILE__, __LINE__, p, r, m);
 140        spin_unlock_irqrestore(&p->reg_lock, reg_flags);
 141}
 142#else
 143static inline void iwl_set_bit(struct iwl_priv *p, u32 r, u32 m)
 144{
 145        unsigned long reg_flags;
 146
 147        spin_lock_irqsave(&p->reg_lock, reg_flags);
 148        _iwl_set_bit(p, r, m);
 149        spin_unlock_irqrestore(&p->reg_lock, reg_flags);
 150}
 151#endif
 152
 153static inline void _iwl_clear_bit(struct iwl_priv *priv, u32 reg, u32 mask)
 154{
 155        _iwl_write32(priv, reg, _iwl_read32(priv, reg) & ~mask);
 156}
 157#ifdef CONFIG_IWLWIFI_DEBUG
 158static inline void __iwl_clear_bit(const char *f, u32 l,
 159                                   struct iwl_priv *priv, u32 reg, u32 mask)
 160{
 161        u32 val = _iwl_read32(priv, reg) & ~mask;
 162        IWL_DEBUG_IO(priv, "clear_bit(0x%08X, 0x%08X) = 0x%08X\n", reg, mask, val);
 163        _iwl_write32(priv, reg, val);
 164}
 165static inline void iwl_clear_bit(struct iwl_priv *p, u32 r, u32 m)
 166{
 167        unsigned long reg_flags;
 168
 169        spin_lock_irqsave(&p->reg_lock, reg_flags);
 170        __iwl_clear_bit(__FILE__, __LINE__, p, r, m);
 171        spin_unlock_irqrestore(&p->reg_lock, reg_flags);
 172}
 173#else
 174static inline void iwl_clear_bit(struct iwl_priv *p, u32 r, u32 m)
 175{
 176        unsigned long reg_flags;
 177
 178        spin_lock_irqsave(&p->reg_lock, reg_flags);
 179        _iwl_clear_bit(p, r, m);
 180        spin_unlock_irqrestore(&p->reg_lock, reg_flags);
 181}
 182#endif
 183
 184static inline int _iwl_grab_nic_access(struct iwl_priv *priv)
 185{
 186        int ret;
 187        u32 val;
 188
 189        /* this bit wakes up the NIC */
 190        _iwl_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
 191        ret = _iwl_poll_bit(priv, CSR_GP_CNTRL,
 192                           CSR_GP_CNTRL_REG_VAL_MAC_ACCESS_EN,
 193                           (CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY |
 194                            CSR_GP_CNTRL_REG_FLAG_GOING_TO_SLEEP), 15000);
 195        if (ret < 0) {
 196                val = _iwl_read32(priv, CSR_GP_CNTRL);
 197                IWL_ERR(priv, "MAC is in deep sleep!.  CSR_GP_CNTRL = 0x%08X\n", val);
 198                _iwl_write32(priv, CSR_RESET, CSR_RESET_REG_FLAG_FORCE_NMI);
 199                return -EIO;
 200        }
 201
 202        return 0;
 203}
 204
 205#ifdef CONFIG_IWLWIFI_DEBUG
 206static inline int __iwl_grab_nic_access(const char *f, u32 l,
 207                                               struct iwl_priv *priv)
 208{
 209        IWL_DEBUG_IO(priv, "grabbing nic access - %s %d\n", f, l);
 210        return _iwl_grab_nic_access(priv);
 211}
 212#define iwl_grab_nic_access(priv) \
 213        __iwl_grab_nic_access(__FILE__, __LINE__, priv)
 214#else
 215#define iwl_grab_nic_access(priv) \
 216        _iwl_grab_nic_access(priv)
 217#endif
 218
 219static inline void _iwl_release_nic_access(struct iwl_priv *priv)
 220{
 221        _iwl_clear_bit(priv, CSR_GP_CNTRL,
 222                        CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
 223}
 224#ifdef CONFIG_IWLWIFI_DEBUG
 225static inline void __iwl_release_nic_access(const char *f, u32 l,
 226                                            struct iwl_priv *priv)
 227{
 228
 229        IWL_DEBUG_IO(priv, "releasing nic access - %s %d\n", f, l);
 230        _iwl_release_nic_access(priv);
 231}
 232#define iwl_release_nic_access(priv) \
 233        __iwl_release_nic_access(__FILE__, __LINE__, priv)
 234#else
 235#define iwl_release_nic_access(priv) \
 236        _iwl_release_nic_access(priv)
 237#endif
 238
 239static inline u32 _iwl_read_direct32(struct iwl_priv *priv, u32 reg)
 240{
 241        return _iwl_read32(priv, reg);
 242}
 243#ifdef CONFIG_IWLWIFI_DEBUG
 244static inline u32 __iwl_read_direct32(const char *f, u32 l,
 245                                        struct iwl_priv *priv, u32 reg)
 246{
 247        u32 value = _iwl_read_direct32(priv, reg);
 248        IWL_DEBUG_IO(priv, "read_direct32(0x%4X) = 0x%08x - %s %d \n", reg, value,
 249                     f, l);
 250        return value;
 251}
 252static inline u32 iwl_read_direct32(struct iwl_priv *priv, u32 reg)
 253{
 254        u32 value;
 255        unsigned long reg_flags;
 256
 257        spin_lock_irqsave(&priv->reg_lock, reg_flags);
 258        iwl_grab_nic_access(priv);
 259        value = __iwl_read_direct32(__FILE__, __LINE__, priv, reg);
 260        iwl_release_nic_access(priv);
 261        spin_unlock_irqrestore(&priv->reg_lock, reg_flags);
 262        return value;
 263}
 264
 265#else
 266static inline u32 iwl_read_direct32(struct iwl_priv *priv, u32 reg)
 267{
 268        u32 value;
 269        unsigned long reg_flags;
 270
 271        spin_lock_irqsave(&priv->reg_lock, reg_flags);
 272        iwl_grab_nic_access(priv);
 273        value = _iwl_read_direct32(priv, reg);
 274        iwl_release_nic_access(priv);
 275        spin_unlock_irqrestore(&priv->reg_lock, reg_flags);
 276        return value;
 277
 278}
 279#endif
 280
 281static inline void _iwl_write_direct32(struct iwl_priv *priv,
 282                                         u32 reg, u32 value)
 283{
 284        _iwl_write32(priv, reg, value);
 285}
 286static inline void iwl_write_direct32(struct iwl_priv *priv, u32 reg, u32 value)
 287{
 288        unsigned long reg_flags;
 289
 290        spin_lock_irqsave(&priv->reg_lock, reg_flags);
 291        if (!iwl_grab_nic_access(priv)) {
 292                _iwl_write_direct32(priv, reg, value);
 293                iwl_release_nic_access(priv);
 294        }
 295        spin_unlock_irqrestore(&priv->reg_lock, reg_flags);
 296}
 297
 298static inline void iwl_write_reg_buf(struct iwl_priv *priv,
 299                                               u32 reg, u32 len, u32 *values)
 300{
 301        u32 count = sizeof(u32);
 302
 303        if ((priv != NULL) && (values != NULL)) {
 304                for (; 0 < len; len -= count, reg += count, values++)
 305                        iwl_write_direct32(priv, reg, *values);
 306        }
 307}
 308
 309static inline int _iwl_poll_direct_bit(struct iwl_priv *priv, u32 addr,
 310                                       u32 mask, int timeout)
 311{
 312        int t = 0;
 313
 314        do {
 315                if ((iwl_read_direct32(priv, addr) & mask) == mask)
 316                        return t;
 317                udelay(IWL_POLL_INTERVAL);
 318                t += IWL_POLL_INTERVAL;
 319        } while (t < timeout);
 320
 321        return -ETIMEDOUT;
 322}
 323
 324#ifdef CONFIG_IWLWIFI_DEBUG
 325static inline int __iwl_poll_direct_bit(const char *f, u32 l,
 326                                            struct iwl_priv *priv,
 327                                            u32 addr, u32 mask, int timeout)
 328{
 329        int ret  = _iwl_poll_direct_bit(priv, addr, mask, timeout);
 330
 331        if (unlikely(ret == -ETIMEDOUT))
 332                IWL_DEBUG_IO(priv, "poll_direct_bit(0x%08X, 0x%08X) - "
 333                             "timedout - %s %d\n", addr, mask, f, l);
 334        else
 335                IWL_DEBUG_IO(priv, "poll_direct_bit(0x%08X, 0x%08X) = 0x%08X "
 336                             "- %s %d\n", addr, mask, ret, f, l);
 337        return ret;
 338}
 339#define iwl_poll_direct_bit(priv, addr, mask, timeout) \
 340        __iwl_poll_direct_bit(__FILE__, __LINE__, priv, addr, mask, timeout)
 341#else
 342#define iwl_poll_direct_bit _iwl_poll_direct_bit
 343#endif
 344
 345static inline u32 _iwl_read_prph(struct iwl_priv *priv, u32 reg)
 346{
 347        _iwl_write_direct32(priv, HBUS_TARG_PRPH_RADDR, reg | (3 << 24));
 348        rmb();
 349        return _iwl_read_direct32(priv, HBUS_TARG_PRPH_RDAT);
 350}
 351static inline u32 iwl_read_prph(struct iwl_priv *priv, u32 reg)
 352{
 353        unsigned long reg_flags;
 354        u32 val;
 355
 356        spin_lock_irqsave(&priv->reg_lock, reg_flags);
 357        iwl_grab_nic_access(priv);
 358        val = _iwl_read_prph(priv, reg);
 359        iwl_release_nic_access(priv);
 360        spin_unlock_irqrestore(&priv->reg_lock, reg_flags);
 361        return val;
 362}
 363
 364static inline void _iwl_write_prph(struct iwl_priv *priv,
 365                                             u32 addr, u32 val)
 366{
 367        _iwl_write_direct32(priv, HBUS_TARG_PRPH_WADDR,
 368                              ((addr & 0x0000FFFF) | (3 << 24)));
 369        wmb();
 370        _iwl_write_direct32(priv, HBUS_TARG_PRPH_WDAT, val);
 371}
 372
 373static inline void iwl_write_prph(struct iwl_priv *priv, u32 addr, u32 val)
 374{
 375        unsigned long reg_flags;
 376
 377        spin_lock_irqsave(&priv->reg_lock, reg_flags);
 378        if (!iwl_grab_nic_access(priv)) {
 379                _iwl_write_prph(priv, addr, val);
 380                iwl_release_nic_access(priv);
 381        }
 382        spin_unlock_irqrestore(&priv->reg_lock, reg_flags);
 383}
 384
 385#define _iwl_set_bits_prph(priv, reg, mask) \
 386        _iwl_write_prph(priv, reg, (_iwl_read_prph(priv, reg) | mask))
 387
 388static inline void iwl_set_bits_prph(struct iwl_priv *priv, u32 reg, u32 mask)
 389{
 390        unsigned long reg_flags;
 391
 392        spin_lock_irqsave(&priv->reg_lock, reg_flags);
 393        iwl_grab_nic_access(priv);
 394        _iwl_set_bits_prph(priv, reg, mask);
 395        iwl_release_nic_access(priv);
 396        spin_unlock_irqrestore(&priv->reg_lock, reg_flags);
 397}
 398
 399#define _iwl_set_bits_mask_prph(priv, reg, bits, mask) \
 400        _iwl_write_prph(priv, reg, ((_iwl_read_prph(priv, reg) & mask) | bits))
 401
 402static inline void iwl_set_bits_mask_prph(struct iwl_priv *priv, u32 reg,
 403                                u32 bits, u32 mask)
 404{
 405        unsigned long reg_flags;
 406
 407        spin_lock_irqsave(&priv->reg_lock, reg_flags);
 408        iwl_grab_nic_access(priv);
 409        _iwl_set_bits_mask_prph(priv, reg, bits, mask);
 410        iwl_release_nic_access(priv);
 411        spin_unlock_irqrestore(&priv->reg_lock, reg_flags);
 412}
 413
 414static inline void iwl_clear_bits_prph(struct iwl_priv
 415                                                 *priv, u32 reg, u32 mask)
 416{
 417        unsigned long reg_flags;
 418        u32 val;
 419
 420        spin_lock_irqsave(&priv->reg_lock, reg_flags);
 421        iwl_grab_nic_access(priv);
 422        val = _iwl_read_prph(priv, reg);
 423        _iwl_write_prph(priv, reg, (val & ~mask));
 424        iwl_release_nic_access(priv);
 425        spin_unlock_irqrestore(&priv->reg_lock, reg_flags);
 426}
 427
 428static inline u32 iwl_read_targ_mem(struct iwl_priv *priv, u32 addr)
 429{
 430        unsigned long reg_flags;
 431        u32 value;
 432
 433        spin_lock_irqsave(&priv->reg_lock, reg_flags);
 434        iwl_grab_nic_access(priv);
 435
 436        _iwl_write_direct32(priv, HBUS_TARG_MEM_RADDR, addr);
 437        rmb();
 438        value = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT);
 439
 440        iwl_release_nic_access(priv);
 441        spin_unlock_irqrestore(&priv->reg_lock, reg_flags);
 442        return value;
 443}
 444
 445static inline void iwl_write_targ_mem(struct iwl_priv *priv, u32 addr, u32 val)
 446{
 447        unsigned long reg_flags;
 448
 449        spin_lock_irqsave(&priv->reg_lock, reg_flags);
 450        if (!iwl_grab_nic_access(priv)) {
 451                _iwl_write_direct32(priv, HBUS_TARG_MEM_WADDR, addr);
 452                wmb();
 453                _iwl_write_direct32(priv, HBUS_TARG_MEM_WDAT, val);
 454                iwl_release_nic_access(priv);
 455        }
 456        spin_unlock_irqrestore(&priv->reg_lock, reg_flags);
 457}
 458
 459static inline void iwl_write_targ_mem_buf(struct iwl_priv *priv, u32 addr,
 460                                          u32 len, u32 *values)
 461{
 462        unsigned long reg_flags;
 463
 464        spin_lock_irqsave(&priv->reg_lock, reg_flags);
 465        if (!iwl_grab_nic_access(priv)) {
 466                _iwl_write_direct32(priv, HBUS_TARG_MEM_WADDR, addr);
 467                wmb();
 468                for (; 0 < len; len -= sizeof(u32), values++)
 469                        _iwl_write_direct32(priv, HBUS_TARG_MEM_WDAT, *values);
 470
 471                iwl_release_nic_access(priv);
 472        }
 473        spin_unlock_irqrestore(&priv->reg_lock, reg_flags);
 474}
 475#endif
 476